jiskattema/spot

View on GitHub

Showing 2,641 of 2,641 total issues

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["index"],{0:function(t,n,l){l("a26e"),t.exports=l("9218")},"035a":function(module,exports,__webpack_require__){eval("var app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar Spot = __webpack_require__(/*! spot-framework */ \"3b07\");\n\nvar BaseWidget = __webpack_require__(/*! ./base-widget */ \"26ef\"); // var Vis = require('vis');\n\n\nvar Vis = __webpack_require__(/*! visGraph3d */ \"5bf9\");\n\nvar colors = __webpack_require__(/*! ../../colors */ \"eb63\");\n\nvar misval = Spot.util.misval;\n\nvar util = __webpack_require__(/*! ./util */ \"2b41\");\n\nfunction _deinitChart(view) {\n  if (view._graph3d) {\n    delete view._graph3d;\n  }\n\n  view.isInitialized = false;\n}\n\nfunction _initChart(view) {\n  // Configure plot\n  view._config = view.model.scatterConfig();\n  var filter = view.model.filter;\n  var primary = filter.partitions.get(1, 'rank');\n  var secondary = filter.partitions.get(2, 'rank');\n  var tertiary = filter.partitions.get(3, 'rank'); // axes labels\n\n  if (primary.showLabel) {\n    view._config.xLabel = primary.label;\n  } else {\n    view._config.xLabel = '';\n  }\n\n  if (secondary.showLabel) {\n    view._config.yLabel = secondary.label;\n  } else {\n    view._config.yLabel = '';\n  }\n\n  if (tertiary.showLabel) {\n    view._config.zLabel = tertiary.label;\n  } else {\n    view._config.zLabel = '';\n  } // set ranges\n\n\n  view._config.xMin = primary.minval;\n  view._config.xMax = primary.maxval;\n  view._config.yMin = secondary.minval;\n  view._config.yMax = secondary.maxval;\n  view._config.zMin = tertiary.minval;\n  view._config.zMax = tertiary.maxval; // force a square full size plot\n\n  var width = view.el.offsetWidth;\n  var height = view.el.offsetHeight;\n  view._config.width = width + 'px';\n  view._config.height = height + 'px'; // click callback\n\n  view._config.onclick = function (point) {\n    var groupx = primary.groups.models[point.i];\n    primary.updateSelection(groupx);\n    var groupy = secondary.groups.models[point.j];\n    secondary.updateSelection(groupy);\n    var groupz = tertiary.groups.models[point.k];\n    tertiary.updateSelection(groupz);\n    view.model.filter.updateDataFilter();\n    app.me.dataview.getData();\n  }; // add dummy data point\n\n\n  var visData = new Vis.DataSet();\n  visData.add({\n    x: 0,\n    y: 0,\n    z: 0,\n    style: colors.unselectedColor.hex()\n  }); // add plot to the DOM\n\n  view._graph3d = new Vis.Graph3d(view.el, visData, view._config); // monkeypatch the float -> color function to use our own scale\n  // This probably breaks Visjs but not the parts we use\n\n  view._graph3d._hsv2rgb = function (h, s, v) {\n    // is called for hue in [0, 240]\n    return colors.getColorFloat(h / 240.0).hex();\n  };\n\n  view.isInitialized = true;\n}\n\nfunction _update(view) {\n  if (!view.isInitialized) {\n    return;\n  }\n\n  var filter = view.model.filter;\n  var primary = filter.partitions.get(1, 'rank');\n  var secondary = filter.partitions.get(2, 'rank');\n  var tertiary = filter.partitions.get(3, 'rank');\n\n  var valueFn = function valueFn(group) {\n    if (group.count !== misval) {\n      return parseFloat(group.count) || null;\n    }\n\n    return null;\n  };\n\n  var colorFn;\n  var dataMin = 0;\n  var dataMax = 1;\n  var aggregate = filter.aggregates.get(1, 'rank');\n\n  if (aggregate) {\n    dataMin = filter.data.reduce(function (prev, curr) {\n      if (prev.aa === misval || curr.aa === misval) {\n        return curr;\n      }\n\n      return prev.aa < curr.aa ? prev : curr;\n    }).aa;\n    dataMax = filter.data.reduce(function (prev, curr) {\n      if (prev.aa === misval || curr.aa === misval) {\n        return curr;\n      }\n\n      return prev.aa < curr.aa ? curr : prev;\n    }).aa;\n\n    colorFn = function colorFn(aa) {\n      if (aa !== misval) {\n        var c = parseFloat(aa) || 0;\n        c = (c - dataMin) / (dataMax - dataMin);\n        return colors.getColorFloat(c).hex();\n      }\n\n      return 0;\n    }; // update Vis.Graph3d config\n    // BUG: the legend leads to inifite loop in step.next() (or so) when manully forcing the colors in data.style\n\n\n    view._graph3d.defaultValueMin = dataMin;\n    view._graph3d.defaultValueMax = dataMax; // update Vis.Graph3d config\n    // TODO: view._graph3d.showLegend = true;\n  } else {\n    colorFn = function colorFn(group) {\n      return colors.getColor(0).hex();\n    }; // update Vis.Graph3d config\n\n\n    view._graph3d.showLegend = false;\n  } // update the data\n\n\n  var visData = new Vis.DataSet();\n  var Fx = primary.filterFunction();\n  var Fy = secondary.filterFunction();\n  var Fz = tertiary.filterFunction();\n\n  var dotColor = function dotColor(group) {\n    if (Fx(group.a) && Fy(group.b) && Fz(group.c)) {\n      return colorFn(group.aa);\n    } else {\n      return colors.unselectedColor.hex();\n    }\n  };\n\n  filter.data.forEach(function (group) {\n    if (valueFn(group)) {\n      var i = util.partitionValueToIndex(primary, group.a);\n      var j = util.partitionValueToIndex(secondary, group.b);\n      var k = util.partitionValueToIndex(tertiary, group.c);\n\n      if (i >= 0 && j >= 0 && k >= 0) {\n        visData.add({\n          x: primary.groups.models[i].value,\n          y: secondary.groups.models[j].value,\n          z: tertiary.groups.models[k].value,\n          style: dotColor(group),\n          i: i,\n          j: j,\n          k: k\n        });\n      }\n    }\n  });\n\n  view._graph3d.setData(visData);\n\n  view._graph3d.valueRange.min = dataMin;\n  view._graph3d.valueRange.max = dataMax;\n\n  view._graph3d.redraw();\n}\n\nmodule.exports = BaseWidget.extend({\n  template: '<div class=\"widgetInner mdl-card__media\"></div>',\n  update: function update() {\n    _update(this);\n  },\n  initChart: function initChart() {\n    _initChart(this);\n  },\n  deinitChart: function deinitChart() {\n    _deinitChart(this);\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDM1YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL3ZpZXdzL3NjYXR0ZXIuanM/MTBhZCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYXBwID0gcmVxdWlyZSgnYW1wZXJzYW5kLWFwcCcpO1xudmFyIFNwb3QgPSByZXF1aXJlKCdzcG90LWZyYW1ld29yaycpO1xudmFyIEJhc2VXaWRnZXQgPSByZXF1aXJlKCcuL2Jhc2Utd2lkZ2V0Jyk7XG4vLyB2YXIgVmlzID0gcmVxdWlyZSgndmlzJyk7XG52YXIgVmlzID0gcmVxdWlyZSgndmlzR3JhcGgzZCcpO1xudmFyIGNvbG9ycyA9IHJlcXVpcmUoJy4uLy4uL2NvbG9ycycpO1xudmFyIG1pc3ZhbCA9IFNwb3QudXRpbC5taXN2YWw7XG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpO1xuXG5mdW5jdGlvbiBkZWluaXRDaGFydCAodmlldykge1xuICBpZiAodmlldy5fZ3JhcGgzZCkge1xuICAgIGRlbGV0ZSB2aWV3Ll9ncmFwaDNkO1xuICB9XG4gIHZpZXcuaXNJbml0aWFsaXplZCA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBpbml0Q2hhcnQgKHZpZXcpIHtcbiAgLy8gQ29uZmlndXJlIHBsb3RcbiAgdmlldy5fY29uZmlnID0gdmlldy5tb2RlbC5zY2F0dGVyQ29uZmlnKCk7XG5cbiAgdmFyIGZpbHRlciA9IHZpZXcubW9kZWwuZmlsdGVyO1xuICB2YXIgcHJpbWFyeSA9IGZpbHRlci5wYXJ0aXRpb25zLmdldCgxLCAncmFuaycpO1xuICB2YXIgc2Vjb25kYXJ5ID0gZmlsdGVyLnBhcnRpdGlvbnMuZ2V0KDIsICdyYW5rJyk7XG4gIHZhciB0ZXJ0aWFyeSA9IGZpbHRlci5wYXJ0aXRpb25zLmdldCgzLCAncmFuaycpO1xuXG4gIC8vIGF4ZXMgbGFiZWxzXG4gIGlmIChwcmltYXJ5LnNob3dMYWJlbCkge1xuICAgIHZpZXcuX2NvbmZpZy54TGFiZWwgPSBwcmltYXJ5LmxhYmVsO1xuICB9IGVsc2Uge1xuICAgIHZpZXcuX2NvbmZpZy54TGFiZWwgPSAnJztcbiAgfVxuICBpZiAoc2Vjb25kYXJ5LnNob3dMYWJlbCkge1xuICAgIHZpZXcuX2NvbmZpZy55TGFiZWwgPSBzZWNvbmRhcnkubGFiZWw7XG4gIH0gZWxzZSB7XG4gICAgdmlldy5fY29uZmlnLnlMYWJlbCA9ICcnO1xuICB9XG4gIGlmICh0ZXJ0aWFyeS5zaG93TGFiZWwpIHtcbiAgICB2aWV3Ll9jb25maWcuekxhYmVsID0gdGVydGlhcnkubGFiZWw7XG4gIH0gZWxzZSB7XG4gICAgdmlldy5fY29uZmlnLnpMYWJlbCA9ICcnO1xuICB9XG5cbiAgLy8gc2V0IHJhbmdlc1xuICB2aWV3Ll9jb25maWcueE1pbiA9IHByaW1hcnkubWludmFsO1xuICB2aWV3Ll9jb25maWcueE1heCA9IHByaW1hcnkubWF4dmFsO1xuICB2aWV3Ll9jb25maWcueU1pbiA9IHNlY29uZGFyeS5taW52YWw7XG4gIHZpZXcuX2NvbmZpZy55TWF4ID0gc2Vjb25kYXJ5Lm1heHZhbDtcbiAgdmlldy5fY29uZmlnLnpNaW4gPSB0ZXJ0aWFyeS5taW52YWw7XG4gIHZpZXcuX2NvbmZpZy56TWF4ID0gdGVydGlhcnkubWF4dmFsO1xuXG4gIC8vIGZvcmNlIGEgc3F1YXJlIGZ1bGwgc2l6ZSBwbG90XG4gIHZhciB3aWR0aCA9IHZpZXcuZWwub2Zmc2V0V2lkdGg7XG4gIHZhciBoZWlnaHQgPSB2aWV3LmVsLm9mZnNldEhlaWdodDtcblxuICB2aWV3Ll9jb25maWcud2lkdGggPSB3aWR0aCArICdweCc7XG4gIHZpZXcuX2NvbmZpZy5oZWlnaHQgPSBoZWlnaHQgKyAncHgnO1xuXG4gIC8vIGNsaWNrIGNhbGxiYWNrXG4gIHZpZXcuX2NvbmZpZy5vbmNsaWNrID0gZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgdmFyIGdyb3VweCA9IHByaW1hcnkuZ3JvdXBzLm1vZGVsc1twb2ludC5pXTtcbiAgICBwcmltYXJ5LnVwZGF0ZVNlbGVjdGlvbihncm91cHgpO1xuXG4gICAgdmFyIGdyb3VweSA9IHNlY29uZGFyeS5ncm91cHMubW9kZWxzW3BvaW50LmpdO1xuICAgIHNlY29uZGFyeS51cGRhdGVTZWxlY3Rpb24oZ3JvdXB5KTtcblxuICAgIHZhciBncm91cHogPSB0ZXJ0aWFyeS5ncm91cHMubW9kZWxzW3BvaW50LmtdO1xuICAgIHRlcnRpYXJ5LnVwZGF0ZVNlbGVjdGlvbihncm91cHopO1xuXG4gICAgdmlldy5tb2RlbC5maWx0ZXIudXBkYXRlRGF0YUZpbHRlcigpO1xuICAgIGFwcC5tZS5kYXRhdmlldy5nZXREYXRhKCk7XG4gIH07XG5cbiAgLy8gYWRkIGR1bW15IGRhdGEgcG9pbnRcbiAgdmFyIHZpc0RhdGEgPSBuZXcgVmlzLkRhdGFTZXQoKTtcbiAgdmlzRGF0YS5hZGQoe3g6IDAsIHk6IDAsIHo6IDAsIHN0eWxlOiBjb2xvcnMudW5zZWxlY3RlZENvbG9yLmhleCgpfSk7XG5cbiAgLy8gYWRkIHBsb3QgdG8gdGhlIERPTVxuICB2aWV3Ll9ncmFwaDNkID0gbmV3IFZpcy5HcmFwaDNkKHZpZXcuZWwsIHZpc0RhdGEsIHZpZXcuX2NvbmZpZyk7XG5cbiAgLy8gbW9ua2V5cGF0Y2ggdGhlIGZsb2F0IC0+IGNvbG9yIGZ1bmN0aW9uIHRvIHVzZSBvdXIgb3duIHNjYWxlXG4gIC8vIFRoaXMgcHJvYmFibHkgYnJlYWtzIFZpc2pzIGJ1dCBub3QgdGhlIHBhcnRzIHdlIHVzZVxuICB2aWV3Ll9ncmFwaDNkLl9oc3YycmdiID0gZnVuY3Rpb24gKGgsIHMsIHYpIHtcbiAgICAvLyBpcyBjYWxsZWQgZm9yIGh1ZSBpbiBbMCwgMjQwXVxuICAgIHJldHVybiBjb2xvcnMuZ2V0Q29sb3JGbG9hdChoIC8gMjQwLjApLmhleCgpO1xuICB9O1xuXG4gIHZpZXcuaXNJbml0aWFsaXplZCA9IHRydWU7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZSAodmlldykge1xuICBpZiAoIXZpZXcuaXNJbml0aWFsaXplZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBmaWx0ZXIgPSB2aWV3Lm1vZGVsLmZpbHRlcjtcblxuICB2YXIgcHJpbWFyeSA9IGZpbHRlci5wYXJ0aXRpb25zLmdldCgxLCAncmFuaycpO1xuICB2YXIgc2Vjb25kYXJ5ID0gZmlsdGVyLnBhcnRpdGlvbnMuZ2V0KDIsICdyYW5rJyk7XG4gIHZhciB0ZXJ0aWFyeSA9IGZpbHRlci5wYXJ0aXRpb25zLmdldCgzLCAncmFuaycpO1xuXG4gIHZhciB2YWx1ZUZuID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgaWYgKGdyb3VwLmNvdW50ICE9PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiBwYXJzZUZsb2F0KGdyb3VwLmNvdW50KSB8fCBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICB2YXIgY29sb3JGbjtcbiAgdmFyIGRhdGFNaW4gPSAwO1xuICB2YXIgZGF0YU1heCA9IDE7XG4gIHZhciBhZ2dyZWdhdGUgPSBmaWx0ZXIuYWdncmVnYXRlcy5nZXQoMSwgJ3JhbmsnKTtcbiAgaWYgKGFnZ3JlZ2F0ZSkge1xuICAgIGRhdGFNaW4gPSBmaWx0ZXIuZGF0YS5yZWR1Y2UoZnVuY3Rpb24gKHByZXYsIGN1cnIpIHtcbiAgICAgIGlmIChwcmV2LmFhID09PSBtaXN2YWwgfHwgY3Vyci5hYSA9PT0gbWlzdmFsKSB7XG4gICAgICAgIHJldHVybiBjdXJyO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHByZXYuYWEgPCBjdXJyLmFhID8gcHJldiA6IGN1cnI7XG4gICAgfSkuYWE7XG5cbiAgICBkYXRhTWF4ID0gZmlsdGVyLmRhdGEucmVkdWNlKGZ1bmN0aW9uIChwcmV2LCBjdXJyKSB7XG4gICAgICBpZiAocHJldi5hYSA9PT0gbWlzdmFsIHx8IGN1cnIuYWEgPT09IG1pc3ZhbCkge1xuICAgICAgICByZXR1cm4gY3VycjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwcmV2LmFhIDwgY3Vyci5hYSA/IGN1cnIgOiBwcmV2O1xuICAgIH0pLmFhO1xuXG4gICAgY29sb3JGbiA9IGZ1bmN0aW9uIChhYSkge1xuICAgICAgaWYgKGFhICE9PSBtaXN2YWwpIHtcbiAgICAgICAgdmFyIGMgPSBwYXJzZUZsb2F0KGFhKSB8fCAwO1xuICAgICAgICBjID0gKGMgLSBkYXRhTWluKSAvIChkYXRhTWF4IC0gZGF0YU1pbik7XG4gICAgICAgIHJldHVybiBjb2xvcnMuZ2V0Q29sb3JGbG9hdChjKS5oZXgoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAwO1xuICAgIH07XG5cbiAgICAvLyB1cGRhdGUgVmlzLkdyYXBoM2QgY29uZmlnXG4gICAgLy8gQlVHOiB0aGUgbGVnZW5kIGxlYWRzIHRvIGluaWZpdGUgbG9vcCBpbiBzdGVwLm5leHQoKSAob3Igc28pIHdoZW4gbWFudWxseSBmb3JjaW5nIHRoZSBjb2xvcnMgaW4gZGF0YS5zdHlsZVxuICAgIHZpZXcuX2dyYXBoM2QuZGVmYXVsdFZhbHVlTWluID0gZGF0YU1pbjtcbiAgICB2aWV3Ll9ncmFwaDNkLmRlZmF1bHRWYWx1ZU1heCA9IGRhdGFNYXg7XG5cbiAgICAvLyB1cGRhdGUgVmlzLkdyYXBoM2QgY29uZmlnXG4gICAgLy8gVE9ETzogdmlldy5fZ3JhcGgzZC5zaG93TGVnZW5kID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICBjb2xvckZuID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICByZXR1cm4gY29sb3JzLmdldENvbG9yKDApLmhleCgpO1xuICAgIH07XG5cbiAgICAvLyB1cGRhdGUgVmlzLkdyYXBoM2QgY29uZmlnXG4gICAgdmlldy5fZ3JhcGgzZC5zaG93TGVnZW5kID0gZmFsc2U7XG4gIH1cblxuICAvLyB1cGRhdGUgdGhlIGRhdGFcbiAgdmFyIHZpc0RhdGEgPSBuZXcgVmlzLkRhdGFTZXQoKTtcblxuICB2YXIgRnggPSBwcmltYXJ5LmZpbHRlckZ1bmN0aW9uKCk7XG4gIHZhciBGeSA9IHNlY29uZGFyeS5maWx0ZXJGdW5jdGlvbigpO1xuICB2YXIgRnogPSB0ZXJ0aWFyeS5maWx0ZXJGdW5jdGlvbigpO1xuXG4gIHZhciBkb3RDb2xvciA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgIGlmIChGeChncm91cC5hKSAmJiBGeShncm91cC5iKSAmJiBGeihncm91cC5jKSkge1xuICAgICAgcmV0dXJuIGNvbG9yRm4oZ3JvdXAuYWEpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY29sb3JzLnVuc2VsZWN0ZWRDb2xvci5oZXgoKTtcbiAgICB9XG4gIH07XG5cbiAgZmlsdGVyLmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICBpZiAodmFsdWVGbihncm91cCkpIHtcbiAgICAgIHZhciBpID0gdXRpbC5wYXJ0aXRpb25WYWx1ZVRvSW5kZXgocHJpbWFyeSwgZ3JvdXAuYSk7XG4gICAgICB2YXIgaiA9IHV0aWwucGFydGl0aW9uVmFsdWVUb0luZGV4KHNlY29uZGFyeSwgZ3JvdXAuYik7XG4gICAgICB2YXIgayA9IHV0aWwucGFydGl0aW9uVmFsdWVUb0luZGV4KHRlcnRpYXJ5LCBncm91cC5jKTtcblxuICAgICAgaWYgKGkgPj0gMCAmJiBqID49IDAgJiYgayA+PSAwKSB7XG4gICAgICAgIHZpc0RhdGEuYWRkKHtcbiAgICAgICAgICB4OiBwcmltYXJ5Lmdyb3Vwcy5tb2RlbHNbaV0udmFsdWUsXG4gICAgICAgICAgeTogc2Vjb25kYXJ5Lmdyb3Vwcy5tb2RlbHNbal0udmFsdWUsXG4gICAgICAgICAgejogdGVydGlhcnkuZ3JvdXBzLm1vZGVsc1trXS52YWx1ZSxcbiAgICAgICAgICBzdHlsZTogZG90Q29sb3IoZ3JvdXApLFxuICAgICAgICAgIGk6IGksXG4gICAgICAgICAgajogaixcbiAgICAgICAgICBrOiBrXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHZpZXcuX2dyYXBoM2Quc2V0RGF0YSh2aXNEYXRhKTtcbiAgdmlldy5fZ3JhcGgzZC52YWx1ZVJhbmdlLm1pbiA9IGRhdGFNaW47XG4gIHZpZXcuX2dyYXBoM2QudmFsdWVSYW5nZS5tYXggPSBkYXRhTWF4O1xuICB2aWV3Ll9ncmFwaDNkLnJlZHJhdygpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VXaWRnZXQuZXh0ZW5kKHtcbiAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwid2lkZ2V0SW5uZXIgbWRsLWNhcmRfX21lZGlhXCI+PC9kaXY+JyxcblxuICB1cGRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICB1cGRhdGUodGhpcyk7XG4gIH0sXG5cbiAgaW5pdENoYXJ0OiBmdW5jdGlvbiAoKSB7XG4gICAgaW5pdENoYXJ0KHRoaXMpO1xuICB9LFxuXG4gIGRlaW5pdENoYXJ0OiBmdW5jdGlvbiAoKSB7XG4gICAgZGVpbml0Q2hhcnQodGhpcyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBR0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFEQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUEE7QUFTQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBYkEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///035a\n")},"0b9a":function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nmodule.exports = View.extend({\n  template: templates.configurePartition.group,\n  bindings: {\n    'model.label': {\n      type: 'text',\n      hook: 'group-label'\n    },\n    'model.count': {\n      type: 'text',\n      hook: 'group-count'\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMGI5YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtcGFydGl0aW9uL2dyb3VwLmpzP2JjOTMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL3RlbXBsYXRlcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZXcuZXh0ZW5kKHtcbiAgdGVtcGxhdGU6IHRlbXBsYXRlcy5jb25maWd1cmVQYXJ0aXRpb24uZ3JvdXAsXG4gIGJpbmRpbmdzOiB7XG4gICAgJ21vZGVsLmxhYmVsJzoge1xuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgaG9vazogJ2dyb3VwLWxhYmVsJ1xuICAgIH0sXG4gICAgJ21vZGVsLmNvdW50Jzoge1xuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgaG9vazogJ2dyb3VwLWNvdW50J1xuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFGQTtBQUxBO0FBRkEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///0b9a\n")},"0b9d":function(module,exports,__webpack_require__){eval("/**\n * @classdesc Radar Chart class\n * @class RadarChart\n * @augments BaseChart\n */\nvar BaseChart = __webpack_require__(/*! ./base-chart */ \"6339\");\n\nmodule.exports = BaseChart.extend({\n  initialize: function initialize() {\n    this.slots.reset([{\n      description: 'Group by',\n      type: 'partition',\n      rank: 1,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }]);\n  },\n  chartjsConfig: function chartjsConfig() {\n    return {\n      type: 'radar',\n      data: {\n        datasets: [],\n        labels: []\n      },\n      options: {\n        title: {\n          display: true,\n          position: 'top'\n        },\n        tooltips: {}\n      }\n    };\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMGI5ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL21vZGVscy9yYWRhcmNoYXJ0LmpzP2ZjNTQiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAY2xhc3NkZXNjIFJhZGFyIENoYXJ0IGNsYXNzXG4gKiBAY2xhc3MgUmFkYXJDaGFydFxuICogQGF1Z21lbnRzIEJhc2VDaGFydFxuICovXG5cbnZhciBCYXNlQ2hhcnQgPSByZXF1aXJlKCcuL2Jhc2UtY2hhcnQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlQ2hhcnQuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc2xvdHMucmVzZXQoW1xuICAgICAge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ0dyb3VwIGJ5JyxcbiAgICAgICAgdHlwZTogJ3BhcnRpdGlvbicsXG4gICAgICAgIHJhbms6IDEsXG4gICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICBzdXBwb3J0ZWRGYWNldHM6IFsnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICdjb250aW51b3VzJywgJ3RleHQnXVxuICAgICAgfVxuICAgIF0pO1xuICB9LFxuICBjaGFydGpzQ29uZmlnOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdyYWRhcicsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIGRhdGFzZXRzOiBbXSxcbiAgICAgICAgbGFiZWxzOiBbXVxuICAgICAgfSxcbiAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICAgIHBvc2l0aW9uOiAndG9wJ1xuICAgICAgICB9LFxuICAgICAgICB0b29sdGlwczoge1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBOzs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBTEE7QUFOQTtBQWVBO0FBNUJBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0b9d\n")},"0d07":function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nvar TimeZonesSelect = __webpack_require__(/*! ../configure-facet/time-zones-select */ \"f3d5\");\n\nmodule.exports = View.extend({\n  template: templates.configurePartition.partitionDatetime,\n  derived: {\n    minvalAsText: {\n      deps: ['model.minval', 'model.isDatetime'],\n      fn: function fn() {\n        if (this.model.isDatetime) {\n          return this.model.minval.toISOString();\n        } else {\n          return 'not a date';\n        }\n      }\n    },\n    maxvalAsText: {\n      deps: ['model.maxval', 'model.isDatetime'],\n      fn: function fn() {\n        if (this.model.isDatetime) {\n          return this.model.maxval.toISOString();\n        } else {\n          return 'not a date';\n        }\n      }\n    }\n  },\n  bindings: {\n    'model.isDatetime': {\n      type: 'toggle',\n      hook: 'group-datetime-panel'\n    },\n    'minvalAsText': {\n      type: 'value',\n      hook: 'group-startdate-input'\n    },\n    'maxvalAsText': {\n      type: 'value',\n      hook: 'group-enddate-input'\n    }\n  },\n  events: {\n    'change [data-hook=time-units]': function changeDataHookTimeUnits() {\n      var value = this.queryByHook('time-units').value;\n      this.model.groupingDatetime = value;\n    },\n    'click [data-hook~=group-datetimerange-button]': function clickDataHookGroupDatetimerangeButton() {\n      var partition = this.model;\n      partition.reset();\n      this.queryByHook('group-startdate-input').dispatchEvent(new window.Event('input'));\n      this.queryByHook('group-enddate-input').dispatchEvent(new window.Event('input'));\n      this.parent.resetFilter = true;\n    },\n    'change [data-hook~=group-startdate-input]': function changeDataHookGroupStartdateInput() {\n      var d = moment(this.queryByHook('group-startdate-input').value);\n\n      if (d.isValid()) {\n        this.model.minval = d;\n      }\n\n      this.parent.resetFilter = true;\n    },\n    'change [data-hook~=group-enddate-input]': function changeDataHookGroupEnddateInput() {\n      var d = moment(this.queryByHook('group-enddate-input').value);\n\n      if (d.isValid()) {\n        this.model.maxval = d;\n      }\n\n      this.parent.resetFilter = true;\n    }\n  },\n  subviews: {\n    timeZones: {\n      hook: 'time-zones',\n      prepareView: function prepareView(el) {\n        return new TimeZonesSelect({\n          el: el,\n          field: 'zone',\n          model: this.model\n        });\n      }\n    }\n  },\n  render: function render() {\n    this.renderWithTemplate(this);\n    this.queryByHook('time-units').value = this.model.groupingDatetime;\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMGQwNy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtcGFydGl0aW9uL3BhcnRpdGlvbi1kYXRldGltZS5qcz82ZDk2Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBWaWV3ID0gcmVxdWlyZSgnYW1wZXJzYW5kLXZpZXcnKTtcbnZhciB0ZW1wbGF0ZXMgPSByZXF1aXJlKCcuLi8uLi90ZW1wbGF0ZXMnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciBUaW1lWm9uZXNTZWxlY3QgPSByZXF1aXJlKCcuLi9jb25maWd1cmUtZmFjZXQvdGltZS16b25lcy1zZWxlY3QnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMuY29uZmlndXJlUGFydGl0aW9uLnBhcnRpdGlvbkRhdGV0aW1lLFxuICBkZXJpdmVkOiB7XG4gICAgbWludmFsQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ21vZGVsLm1pbnZhbCcsICdtb2RlbC5pc0RhdGV0aW1lJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5tb2RlbC5pc0RhdGV0aW1lKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwubWludmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICdub3QgYSBkYXRlJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgbWF4dmFsQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ21vZGVsLm1heHZhbCcsICdtb2RlbC5pc0RhdGV0aW1lJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5tb2RlbC5pc0RhdGV0aW1lKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwubWF4dmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICdub3QgYSBkYXRlJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgYmluZGluZ3M6IHtcbiAgICAnbW9kZWwuaXNEYXRldGltZSc6IHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgaG9vazogJ2dyb3VwLWRhdGV0aW1lLXBhbmVsJ1xuICAgIH0sXG5cbiAgICAnbWludmFsQXNUZXh0Jzoge1xuICAgICAgdHlwZTogJ3ZhbHVlJyxcbiAgICAgIGhvb2s6ICdncm91cC1zdGFydGRhdGUtaW5wdXQnXG4gICAgfSxcbiAgICAnbWF4dmFsQXNUZXh0Jzoge1xuICAgICAgdHlwZTogJ3ZhbHVlJyxcbiAgICAgIGhvb2s6ICdncm91cC1lbmRkYXRlLWlucHV0J1xuICAgIH1cblxuICB9LFxuICBldmVudHM6IHtcbiAgICAnY2hhbmdlIFtkYXRhLWhvb2s9dGltZS11bml0c10nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWUgPSB0aGlzLnF1ZXJ5QnlIb29rKCd0aW1lLXVuaXRzJykudmFsdWU7XG4gICAgICB0aGlzLm1vZGVsLmdyb3VwaW5nRGF0ZXRpbWUgPSB2YWx1ZTtcbiAgICB9LFxuICAgICdjbGljayBbZGF0YS1ob29rfj1ncm91cC1kYXRldGltZXJhbmdlLWJ1dHRvbl0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgcGFydGl0aW9uID0gdGhpcy5tb2RlbDtcbiAgICAgIHBhcnRpdGlvbi5yZXNldCgpO1xuXG4gICAgICB0aGlzLnF1ZXJ5QnlIb29rKCdncm91cC1zdGFydGRhdGUtaW5wdXQnKS5kaXNwYXRjaEV2ZW50KG5ldyB3aW5kb3cuRXZlbnQoJ2lucHV0JykpO1xuICAgICAgdGhpcy5xdWVyeUJ5SG9vaygnZ3JvdXAtZW5kZGF0ZS1pbnB1dCcpLmRpc3BhdGNoRXZlbnQobmV3IHdpbmRvdy5FdmVudCgnaW5wdXQnKSk7XG4gICAgICB0aGlzLnBhcmVudC5yZXNldEZpbHRlciA9IHRydWU7XG4gICAgfSxcbiAgICAnY2hhbmdlIFtkYXRhLWhvb2t+PWdyb3VwLXN0YXJ0ZGF0ZS1pbnB1dF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgZCA9IG1vbWVudCh0aGlzLnF1ZXJ5QnlIb29rKCdncm91cC1zdGFydGRhdGUtaW5wdXQnKS52YWx1ZSk7XG4gICAgICBpZiAoZC5pc1ZhbGlkKCkpIHtcbiAgICAgICAgdGhpcy5tb2RlbC5taW52YWwgPSBkO1xuICAgICAgfVxuICAgICAgdGhpcy5wYXJlbnQucmVzZXRGaWx0ZXIgPSB0cnVlO1xuICAgIH0sXG4gICAgJ2NoYW5nZSBbZGF0YS1ob29rfj1ncm91cC1lbmRkYXRlLWlucHV0XSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBkID0gbW9tZW50KHRoaXMucXVlcnlCeUhvb2soJ2dyb3VwLWVuZGRhdGUtaW5wdXQnKS52YWx1ZSk7XG4gICAgICBpZiAoZC5pc1ZhbGlkKCkpIHtcbiAgICAgICAgdGhpcy5tb2RlbC5tYXh2YWwgPSBkO1xuICAgICAgfVxuICAgICAgdGhpcy5wYXJlbnQucmVzZXRGaWx0ZXIgPSB0cnVlO1xuICAgIH1cbiAgfSxcbiAgc3Vidmlld3M6IHtcbiAgICB0aW1lWm9uZXM6IHtcbiAgICAgIGhvb2s6ICd0aW1lLXpvbmVzJyxcbiAgICAgIHByZXBhcmVWaWV3OiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaW1lWm9uZXNTZWxlY3Qoe1xuICAgICAgICAgIGVsOiBlbCxcbiAgICAgICAgICBmaWVsZDogJ3pvbmUnLFxuICAgICAgICAgIG1vZGVsOiB0aGlzLm1vZGVsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZW5kZXJXaXRoVGVtcGxhdGUodGhpcyk7XG5cbiAgICB0aGlzLnF1ZXJ5QnlIb29rKCd0aW1lLXVuaXRzJykudmFsdWUgPSB0aGlzLm1vZGVsLmdyb3VwaW5nRGF0ZXRpbWU7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUkE7QUFVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFSQTtBQVhBO0FBc0JBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUZBO0FBVkE7QUFnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBMUJBO0FBNEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBUkE7QUFEQTtBQVlBO0FBQ0E7QUFFQTtBQUNBO0FBcEZBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0d07\n")},1:function(module,exports){eval("/* (ignored) *///# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy93cyAoaWdub3JlZCk/MDU3NyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiAoaWdub3JlZCkgKi8iXSwibWFwcGluZ3MiOiJBQUFBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1\n")},1002:function(module,exports,__webpack_require__){eval('var View = __webpack_require__(/*! ampersand-view */ "2883");\n\nvar templates = __webpack_require__(/*! ../../templates */ "4324");\n\nvar app = __webpack_require__(/*! ampersand-app */ "fcbc");\n\nvar DatasetView = __webpack_require__(/*! ./dataset */ "5eb6");\n\nmodule.exports = View.extend({\n  template: templates.datasets.datasetCollection,\n  render: function render() {\n    this.renderWithTemplate(this);\n    this.renderCollection(app.me.datasets, DatasetView, this.queryByHook(\'items\'));\n    return this;\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTAwMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9kYXRhc2V0cy9kYXRhc2V0LWNvbGxlY3Rpb24uanM/OTQ4MyJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgVmlldyA9IHJlcXVpcmUoJ2FtcGVyc2FuZC12aWV3Jyk7XG52YXIgdGVtcGxhdGVzID0gcmVxdWlyZSgnLi4vLi4vdGVtcGxhdGVzJyk7XG52YXIgYXBwID0gcmVxdWlyZSgnYW1wZXJzYW5kLWFwcCcpO1xuXG52YXIgRGF0YXNldFZpZXcgPSByZXF1aXJlKCcuL2RhdGFzZXQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMuZGF0YXNldHMuZGF0YXNldENvbGxlY3Rpb24sXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVuZGVyV2l0aFRlbXBsYXRlKHRoaXMpO1xuICAgIHRoaXMucmVuZGVyQ29sbGVjdGlvbihhcHAubWUuZGF0YXNldHMsIERhdGFzZXRWaWV3LCB0aGlzLnF1ZXJ5QnlIb29rKCdpdGVtcycpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU5BIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1002\n')},"1c81":function(module,exports,__webpack_require__){eval("/**\n * @classdesc Extends the Chart base class, and adds configuration.\n * @class HorizontalBarChart\n * @augments BaseChart\n */\nvar BaseChart = __webpack_require__(/*! ./base-chart */ \"6339\");\n\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nmodule.exports = BaseChart.extend({\n  initialize: function initialize() {\n    this.slots.reset([{\n      description: 'Group by',\n      type: 'partition',\n      rank: 1,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Subdivide by',\n      type: 'partition',\n      rank: 2,\n      required: false,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Bar height',\n      type: 'aggregate',\n      rank: 1,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }, {\n      description: 'Error bar',\n      type: 'aggregate',\n      rank: 2,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }]);\n  },\n  chartjsConfig: function chartjsConfig() {\n    return {\n      type: 'horizontalBarError',\n      data: {\n        datasets: [],\n        labels: []\n      },\n      options: {\n        title: {\n          display: true,\n          position: 'top'\n        },\n        scales: {\n          xAxes: [{\n            ticks: {\n              beginAtZero: true\n            },\n            stacked: true,\n            display: false,\n            scaleLabel: {\n              display: true\n            },\n            time: {\n              parser: function parser(label) {\n                return moment(label, moment.ISO_8601);\n              }\n            }\n          }],\n          yAxes: [{\n            ticks: {\n              mirror: true\n            },\n            gridLines: {\n              display: false\n            },\n            scaleLabel: {\n              display: true\n            },\n            stacked: true,\n            time: {\n              parser: function parser(label) {\n                return moment(label, moment.ISO_8601);\n              }\n            }\n          }]\n        },\n        tooltips: {}\n      }\n    };\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMWM4MS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL21vZGVscy9ob3Jpem9udGFsYmFyY2hhcnQuanM/YmFkYyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBjbGFzc2Rlc2MgRXh0ZW5kcyB0aGUgQ2hhcnQgYmFzZSBjbGFzcywgYW5kIGFkZHMgY29uZmlndXJhdGlvbi5cbiAqIEBjbGFzcyBIb3Jpem9udGFsQmFyQ2hhcnRcbiAqIEBhdWdtZW50cyBCYXNlQ2hhcnRcbiAqL1xuXG52YXIgQmFzZUNoYXJ0ID0gcmVxdWlyZSgnLi9iYXNlLWNoYXJ0Jyk7XG52YXIgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50LXRpbWV6b25lJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZUNoYXJ0LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNsb3RzLnJlc2V0KFtcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdHcm91cCBieScsXG4gICAgICAgIHR5cGU6ICdwYXJ0aXRpb24nLFxuICAgICAgICByYW5rOiAxLFxuICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NhdGVnb3JpYWwnLCAnZGF0ZXRpbWUnLCAnZHVyYXRpb24nLCAnY29udGludW91cycsICd0ZXh0J11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnU3ViZGl2aWRlIGJ5JyxcbiAgICAgICAgdHlwZTogJ3BhcnRpdGlvbicsXG4gICAgICAgIHJhbms6IDIsXG4gICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NhdGVnb3JpYWwnLCAnZGF0ZXRpbWUnLCAnZHVyYXRpb24nLCAnY29udGludW91cycsICd0ZXh0J11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnQmFyIGhlaWdodCcsXG4gICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICByYW5rOiAxLFxuICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIHN1cHBvcnRlZEZhY2V0czogWydjb250aW51b3VzJywgJ2R1cmF0aW9uJ11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnRXJyb3IgYmFyJyxcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIHJhbms6IDIsXG4gICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NvbnRpbnVvdXMnLCAnZHVyYXRpb24nXVxuICAgICAgfVxuICAgIF0pO1xuICB9LFxuICBjaGFydGpzQ29uZmlnOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdob3Jpem9udGFsQmFyRXJyb3InLFxuICAgICAgZGF0YToge1xuICAgICAgICBkYXRhc2V0czogW10sXG4gICAgICAgIGxhYmVsczogW11cbiAgICAgIH0sXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICBwb3NpdGlvbjogJ3RvcCdcbiAgICAgICAgfSxcbiAgICAgICAgc2NhbGVzOiB7XG4gICAgICAgICAgeEF4ZXM6IFt7XG4gICAgICAgICAgICB0aWNrczoge1xuICAgICAgICAgICAgICBiZWdpbkF0WmVybzogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN0YWNrZWQ6IHRydWUsXG4gICAgICAgICAgICBkaXNwbGF5OiBmYWxzZSxcbiAgICAgICAgICAgIHNjYWxlTGFiZWw6IHtcbiAgICAgICAgICAgICAgZGlzcGxheTogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRpbWU6IHtcbiAgICAgICAgICAgICAgcGFyc2VyOiBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbW9tZW50KGxhYmVsLCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfV0sXG4gICAgICAgICAgeUF4ZXM6IFt7XG4gICAgICAgICAgICB0aWNrczoge1xuICAgICAgICAgICAgICBtaXJyb3I6IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBncmlkTGluZXM6IHtcbiAgICAgICAgICAgICAgZGlzcGxheTogZmFsc2VcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzY2FsZUxhYmVsOiB7XG4gICAgICAgICAgICAgIGRpc3BsYXk6IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdGFja2VkOiB0cnVlLFxuICAgICAgICAgICAgdGltZToge1xuICAgICAgICAgICAgICBwYXJzZXI6IGZ1bmN0aW9uIChsYWJlbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtb21lbnQobGFiZWwsIG1vbWVudC5JU09fODYwMSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XVxuICAgICAgICB9LFxuICAgICAgICB0b29sdGlwczoge1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBOzs7OztBQU1BO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFUQTtBQWVBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBWEE7QUFoQkE7QUFrQ0E7QUF2Q0E7QUFOQTtBQWlEQTtBQW5GQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1c81\n")},2:function(module,exports){eval("/* (ignored) *///# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy91dGlsIChpZ25vcmVkKT9hNTE1Il0sInNvdXJjZXNDb250ZW50IjpbIi8qIChpZ25vcmVkKSAqLyJdLCJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2\n")},"22e9":function(module,exports,__webpack_require__){eval("var app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar $ = __webpack_require__(/*! jquery */ \"802c\");\n\nvar PageView = __webpack_require__(/*! ./base */ \"b966\");\n\nvar templates = __webpack_require__(/*! ../templates */ \"4324\");\n\nvar WidgetFrameView = __webpack_require__(/*! ./analyze/widget-frame */ \"5122\");\n\nvar FacetbarItemView = __webpack_require__(/*! ./analyze/facetbar-item */ \"6b2d\");\n\nvar sortablejs = __webpack_require__(/*! sortablejs */ \"4776\");\n\nvar AnalyzeHelp = __webpack_require__(/*! ./help/analyze */ \"b43e\"); // NOTE: gridster does not work properly with require()\n// workaround via browserify-shim (configured in package.json)\n\n\n__webpack_require__(/*! gridster */ \"cc37\");\n\nfunction _initializeCharts(view) {\n  var gridster = view._widgetsGridster; // BUGFIX: can sometimes get called before gridster is fully initialized\n\n  if (!gridster) {\n    return;\n  }\n\n  var i;\n\n  for (i = 0; i < gridster.$widgets.length; i++) {\n    var chartView = $(gridster.$widgets[i]).data('spotWidgetFrameView')._subviews[0];\n\n    chartView.model.updateConfiguration();\n\n    if (chartView.model.isConfigured) {\n      if (!chartView.model.filter.isInitialized) {\n        if (chartView.isInitialized) {\n          chartView.deinitChart(); // deininit charts that had a filter released\n        }\n\n        chartView.model.filter.initDataFilter();\n      }\n\n      if (chartView.isInitialized) {// noop\n      } else {\n        chartView.initChart();\n      }\n    } else {\n      if (chartView.isInitialized) {\n        chartView.deinitChart();\n      }\n\n      if (chartView.model.filter.isInitialized) {\n        chartView.model.filter.releaseDataFilter();\n      }\n    }\n  }\n}\n\nfunction _deinitializeCharts(view) {\n  var gridster = view._widgetsGridster;\n  var i;\n\n  for (i = 0; i < gridster.$widgets.length; i++) {\n    var chartView = $(gridster.$widgets[i]).data('spotWidgetFrameView')._subviews[0];\n\n    if (chartView.isInitialized) {\n      chartView.deinitChart();\n    }\n\n    if (chartView.model.isConfigured) {\n      chartView.model.filter.releaseDataFilter();\n    }\n  }\n}\n\nfunction _updateCharts(view) {\n  var gridster = view._widgetsGridster;\n  var i;\n\n  for (i = 0; i < gridster.$widgets.length; i++) {\n    var chartView = $(gridster.$widgets[i]).data('spotWidgetFrameView')._subviews[0];\n\n    if (chartView.isInitialized) {\n      chartView.update();\n    }\n  }\n}\n/**\n * Add a widget to the analyze page for the given filter\n *\n * view {View}             Ampersand View instance of the analyze page\n * filter {Filter}         Spot filter instance to create the widget for\n * editModeHint {boolean}  Try to start plot in editMode (ie. accepts dnd of facets) [true] or in interaction mode (false)\n */\n\n\nfunction addWidgetForFilter(view, filter, editModeHint) {\n  var gridster = view._widgetsGridster;\n  var row = filter.row || 1;\n  var col = filter.col || 1;\n  var sizeX = filter.size_x || 3;\n  var sizeY = filter.size_y || 3;\n  var el = gridster.add_widget('<div class=\"widgetOuterFrame\"></div>', sizeX, sizeY, col, row);\n  var frameView = new WidgetFrameView({\n    model: filter\n  }); // render, and render content of widget frame\n\n  view.renderSubview(frameView, el[0]);\n  frameView.renderContent(); // link element and view so we can:\n  // a) on remove, get to the HTMLElement from the WidgetFrameView\n  // b) on resize, get to the WidgetFrameView from the HTMLElement\n\n  frameView.gridsterHook = el[0];\n  $(el[0]).data('spotWidgetFrameView', frameView); // try to initialize and render possibly present data\n  // only follow editModeHint when the widget is configured, default to true\n\n  var chartView = frameView.widget;\n  chartView.model.updateConfiguration();\n\n  if (chartView.model.isConfigured) {\n    if (!filter.isInitialized) {\n      filter.initDataFilter();\n    }\n\n    if (!chartView.isInitialized) {\n      chartView.initChart();\n    }\n\n    chartView.update();\n    frameView.editMode = editModeHint;\n  } else {\n    // widget is not configured, ignore editModeHint\n    // and always go to edit mode\n    frameView.editMode = true;\n  }\n\n  filter.on('newData', function () {\n    chartView.update();\n  });\n}\n\nmodule.exports = PageView.extend({\n  template: templates.analyze.page,\n  session: {\n    fullscreenMode: ['boolean', true, true]\n  },\n  initialize: function initialize() {\n    this.pageName = 'analyze';\n    this.fullscreenMode = app.fullscreenMode; // this.helpTemplate = templates.help.analyze;\n\n    this.helpSteps = AnalyzeHelp.steps;\n    this.helpHints = AnalyzeHelp.hints; // // show existing dataset list\n    // app.me.datasets.forEach(function (dataset, i) {\n    //   if (dataset.isActive) {\n    //     console.log('dataset: ', dataset);\n    //     dataset.facets.forEach(function (facet, j) {\n    //       console.log('facet: ', facet);\n    //     });\n    //   }\n    // });\n\n    app.on('refresh', function () {\n      _initializeCharts(this);\n\n      app.me.dataview.getData();\n    }, this);\n    this.once('remove', function () {\n      // remove callbacks for 'app#refresh'\n      app.off('refresh'); // remove callbacks for 'filter#newData'\n\n      app.me.dataview.filters.forEach(function (filter) {\n        filter.off('newData');\n      });\n    });\n\n    if (app.me.dataview.datasetIds.length === 0) {\n      app.message({\n        text: 'No data to analyze, please upload and/or select some datasets',\n        type: 'ok'\n      });\n    }\n  },\n  derived: {\n    dataString: {\n      deps: ['model.dataTotal', 'model.dataSelected'],\n      fn: function fn() {\n        var percentage;\n\n        if (this.model.dataTotal > 0) {\n          percentage = 100.0 * this.model.dataSelected / this.model.dataTotal;\n        } else {\n          percentage = 0;\n        }\n\n        return this.model.dataTotal + ' total, ' + this.model.dataSelected + ' selected (' + percentage.toPrecision(3) + '%)';\n      }\n    }\n  },\n  bindings: {\n    'fullscreenMode': [{\n      type: 'toggle',\n      hook: 'chart-bar',\n      invert: true\n    }, {\n      type: 'toggle',\n      hook: 'facet-bar',\n      invert: true\n    }],\n    'dataString': {\n      type: 'text',\n      hook: 'data-string'\n    }\n  },\n  events: {\n    'click #viewAll': 'viewAll',\n    'click #fullscreenButton': 'toggleFullscreen',\n    'click #resetFiltersButton': 'resetFilters',\n    'click #saveSessionButton': 'saveSession',\n    'click .widgetIcon': 'addChart'\n  },\n  saveSession: function saveSession() {\n    app.saveCurrentSession();\n  },\n  addChart: function addChart(ev) {\n    // what icon was clicked?\n    var target = ev.target || ev.srcElement;\n    var id = target.id;\n    var filter = this.model.filters.add({\n      chartType: id\n    });\n    addWidgetForFilter(this, filter, true);\n  },\n  toggleFullscreen: function toggleFullscreen() {\n    app.fullscreenMode = !app.fullscreenMode;\n    this.fullscreenMode = app.fullscreenMode;\n  },\n  resetFilters: function resetFilters() {\n    app.me.dataview.pause();\n    app.me.dataview.filters.forEach(function (filter) {\n      // undo drill downs\n      while (filter.zoomHistory.length > 0) {\n        filter.zoomOut();\n      } // and clear possible selection\n\n\n      filter.zoomOut();\n    });\n    app.me.dataview.play();\n    app.me.dataview.getData();\n    app.message({\n      text: 'Reselected all data',\n      type: 'ok'\n    });\n  },\n  viewAll: function viewAll() {\n    this._subviews.forEach(function (v) {\n      if (v._values && v._values.hasOwnProperty('editMode')) {\n        v.editMode = false;\n      }\n    });\n  },\n  render: function render(opts) {\n    this.renderWithTemplate(this);\n    this.renderCollection(this.model.facets, FacetbarItemView, this.queryByHook('facet-bar-items'), {\n      filter: function filter(m) {\n        return m.isActive;\n      }\n    });\n    return this;\n  },\n  renderContent: function renderContent() {\n    var widgetNeedsData = false;\n    var el = document.getElementById('facetBar');\n    this._facetsSortable = sortablejs.create(el, {\n      draggable: '.mdl-chip',\n      dataIdAttr: 'data-id',\n      sort: false,\n      group: {\n        name: 'facets',\n        pull: 'clone',\n        put: false\n      },\n      onStart: function onStart(evt) {\n        var item = evt.item;\n        var facetId = item.getAttribute('data-id');\n        var facet = app.me.dataview.facets.get(facetId);\n        app.trigger('dragStart', facet.type);\n      },\n      onEnd: function onEnd(evt) {\n        app.trigger('dragEnd');\n      },\n      onAdd: function onAdd(evt) {\n        var item = evt.item;\n        item.remove();\n      }\n    });\n    this._widgetsGridster = $('[id~=widgets]').gridster({\n      widget_base_dimensions: [100, 100],\n      min_cols: 1,\n      max_cols: 20,\n      avoid_overlapped_widgets: false,\n      widget_selector: 'div',\n      draggable: {\n        enabled: true,\n        handle: '.widgetDragBar',\n        stop: function stop() {\n          var widgets = this.$widgets;\n          var i = 0;\n\n          for (i = 0; i < widgets.length; i++) {\n            // $.each\n            var widget = widgets[i];\n            var data = $(widget).data();\n            var filter = data['spotWidgetFrameView'].model.filter;\n            var grid = data['coords'].grid;\n            filter.row = grid.row;\n            filter.col = grid.col;\n            filter.size_x = grid.size_x;\n            filter.size_y = grid.size_y;\n          }\n        }\n      },\n      resize: {\n        enabled: true,\n        start: function start(e, ui, widget) {\n          var view = widget.data('spotWidgetFrameView')._subviews[0];\n\n          view.deinitChart();\n        },\n        stop: function stop(e, ui, widget) {\n          var view = widget.data('spotWidgetFrameView')._subviews[0];\n\n          var filter = view.model.filter;\n\n          if (view.isInitialized) {\n            view.update();\n          } // keep track of the position of the chart\n\n\n          var info = widget.data('coords').grid;\n          filter.row = info.row;\n          filter.col = info.col;\n          filter.size_x = info.size_x;\n          filter.size_y = info.size_y;\n\n          if (view.model.isConfigured) {\n            view.initChart();\n          }\n\n          if (view.isInitialized) {\n            view.update();\n          }\n        }\n      }\n    }).data('gridster');\n    this.on('remove', function () {\n      this._facetsSortable.destroy();\n\n      this._widgetsGridster.destroy();\n    }); // pause dataset to prevent needless data updates\n\n    this.model.pause(); // add widgets for each filter to the page\n\n    this.model.filters.forEach(function (filter) {\n      addWidgetForFilter(this, filter, false);\n\n      if (!filter.data || filter.data.length === 0) {\n        widgetNeedsData = true;\n      }\n    }, this); // done, unpause the dataset\n\n    this.model.play();\n\n    if (widgetNeedsData) {\n      app.me.dataview.getData();\n    } // do a last pass to render data\n\n\n    _updateCharts(this);\n  },\n  initializeCharts: function initializeCharts() {\n    _initializeCharts(this);\n  },\n  deinitializeCharts: function deinitializeCharts() {\n    _deinitializeCharts(this);\n  },\n  updateCharts: function updateCharts() {\n    _updateCharts(this);\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjJlOS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9hbmFseXplLmpzPzI1YTMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGFwcCA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1hcHAnKTtcbnZhciAkID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG52YXIgUGFnZVZpZXcgPSByZXF1aXJlKCcuL2Jhc2UnKTtcbnZhciB0ZW1wbGF0ZXMgPSByZXF1aXJlKCcuLi90ZW1wbGF0ZXMnKTtcbnZhciBXaWRnZXRGcmFtZVZpZXcgPSByZXF1aXJlKCcuL2FuYWx5emUvd2lkZ2V0LWZyYW1lJyk7XG52YXIgRmFjZXRiYXJJdGVtVmlldyA9IHJlcXVpcmUoJy4vYW5hbHl6ZS9mYWNldGJhci1pdGVtJyk7XG52YXIgc29ydGFibGVqcyA9IHJlcXVpcmUoJ3NvcnRhYmxlanMnKTtcblxudmFyIEFuYWx5emVIZWxwID0gcmVxdWlyZSgnLi9oZWxwL2FuYWx5emUnKTtcblxuLy8gTk9URTogZ3JpZHN0ZXIgZG9lcyBub3Qgd29yayBwcm9wZXJseSB3aXRoIHJlcXVpcmUoKVxuLy8gd29ya2Fyb3VuZCB2aWEgYnJvd3NlcmlmeS1zaGltIChjb25maWd1cmVkIGluIHBhY2thZ2UuanNvbilcbnJlcXVpcmUoJ2dyaWRzdGVyJyk7XG5cbmZ1bmN0aW9uIGluaXRpYWxpemVDaGFydHMgKHZpZXcpIHtcbiAgdmFyIGdyaWRzdGVyID0gdmlldy5fd2lkZ2V0c0dyaWRzdGVyO1xuXG4gIC8vIEJVR0ZJWDogY2FuIHNvbWV0aW1lcyBnZXQgY2FsbGVkIGJlZm9yZSBncmlkc3RlciBpcyBmdWxseSBpbml0aWFsaXplZFxuICBpZiAoIWdyaWRzdGVyKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBncmlkc3Rlci4kd2lkZ2V0cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBjaGFydFZpZXcgPSAkKGdyaWRzdGVyLiR3aWRnZXRzW2ldKS5kYXRhKCdzcG90V2lkZ2V0RnJhbWVWaWV3JykuX3N1YnZpZXdzWzBdO1xuICAgIGNoYXJ0Vmlldy5tb2RlbC51cGRhdGVDb25maWd1cmF0aW9uKCk7XG5cbiAgICBpZiAoY2hhcnRWaWV3Lm1vZGVsLmlzQ29uZmlndXJlZCkge1xuICAgICAgaWYgKCFjaGFydFZpZXcubW9kZWwuZmlsdGVyLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgaWYgKGNoYXJ0Vmlldy5pc0luaXRpYWxpemVkKSB7XG4gICAgICAgICAgY2hhcnRWaWV3LmRlaW5pdENoYXJ0KCk7IC8vIGRlaW5pbml0IGNoYXJ0cyB0aGF0IGhhZCBhIGZpbHRlciByZWxlYXNlZFxuICAgICAgICB9XG4gICAgICAgIGNoYXJ0Vmlldy5tb2RlbC5maWx0ZXIuaW5pdERhdGFGaWx0ZXIoKTtcbiAgICAgIH1cbiAgICAgIGlmIChjaGFydFZpZXcuaXNJbml0aWFsaXplZCkge1xuICAgICAgICAvLyBub29wXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGFydFZpZXcuaW5pdENoYXJ0KCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChjaGFydFZpZXcuaXNJbml0aWFsaXplZCkge1xuICAgICAgICBjaGFydFZpZXcuZGVpbml0Q2hhcnQoKTtcbiAgICAgIH1cbiAgICAgIGlmIChjaGFydFZpZXcubW9kZWwuZmlsdGVyLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgY2hhcnRWaWV3Lm1vZGVsLmZpbHRlci5yZWxlYXNlRGF0YUZpbHRlcigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkZWluaXRpYWxpemVDaGFydHMgKHZpZXcpIHtcbiAgdmFyIGdyaWRzdGVyID0gdmlldy5fd2lkZ2V0c0dyaWRzdGVyO1xuXG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgZ3JpZHN0ZXIuJHdpZGdldHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgY2hhcnRWaWV3ID0gJChncmlkc3Rlci4kd2lkZ2V0c1tpXSkuZGF0YSgnc3BvdFdpZGdldEZyYW1lVmlldycpLl9zdWJ2aWV3c1swXTtcbiAgICBpZiAoY2hhcnRWaWV3LmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIGNoYXJ0Vmlldy5kZWluaXRDaGFydCgpO1xuICAgIH1cbiAgICBpZiAoY2hhcnRWaWV3Lm1vZGVsLmlzQ29uZmlndXJlZCkge1xuICAgICAgY2hhcnRWaWV3Lm1vZGVsLmZpbHRlci5yZWxlYXNlRGF0YUZpbHRlcigpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB1cGRhdGVDaGFydHMgKHZpZXcpIHtcbiAgdmFyIGdyaWRzdGVyID0gdmlldy5fd2lkZ2V0c0dyaWRzdGVyO1xuXG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgZ3JpZHN0ZXIuJHdpZGdldHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgY2hhcnRWaWV3ID0gJChncmlkc3Rlci4kd2lkZ2V0c1tpXSkuZGF0YSgnc3BvdFdpZGdldEZyYW1lVmlldycpLl9zdWJ2aWV3c1swXTtcbiAgICBpZiAoY2hhcnRWaWV3LmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIGNoYXJ0Vmlldy51cGRhdGUoKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQWRkIGEgd2lkZ2V0IHRvIHRoZSBhbmFseXplIHBhZ2UgZm9yIHRoZSBnaXZlbiBmaWx0ZXJcbiAqXG4gKiB2aWV3IHtWaWV3fSAgICAgICAgICAgICBBbXBlcnNhbmQgVmlldyBpbnN0YW5jZSBvZiB0aGUgYW5hbHl6ZSBwYWdlXG4gKiBmaWx0ZXIge0ZpbHRlcn0gICAgICAgICBTcG90IGZpbHRlciBpbnN0YW5jZSB0byBjcmVhdGUgdGhlIHdpZGdldCBmb3JcbiAqIGVkaXRNb2RlSGludCB7Ym9vbGVhbn0gIFRyeSB0byBzdGFydCBwbG90IGluIGVkaXRNb2RlIChpZS4gYWNjZXB0cyBkbmQgb2YgZmFjZXRzKSBbdHJ1ZV0gb3IgaW4gaW50ZXJhY3Rpb24gbW9kZSAoZmFsc2UpXG4gKi9cbmZ1bmN0aW9uIGFkZFdpZGdldEZvckZpbHRlciAodmlldywgZmlsdGVyLCBlZGl0TW9kZUhpbnQpIHtcbiAgdmFyIGdyaWRzdGVyID0gdmlldy5fd2lkZ2V0c0dyaWRzdGVyO1xuICB2YXIgcm93ID0gZmlsdGVyLnJvdyB8fCAxO1xuICB2YXIgY29sID0gZmlsdGVyLmNvbCB8fCAxO1xuICB2YXIgc2l6ZVggPSBmaWx0ZXIuc2l6ZV94IHx8IDM7XG4gIHZhciBzaXplWSA9IGZpbHRlci5zaXplX3kgfHwgMztcblxuICB2YXIgZWwgPSBncmlkc3Rlci5hZGRfd2lkZ2V0KCc8ZGl2IGNsYXNzPVwid2lkZ2V0T3V0ZXJGcmFtZVwiPjwvZGl2PicsIHNpemVYLCBzaXplWSwgY29sLCByb3cpO1xuICB2YXIgZnJhbWVWaWV3ID0gbmV3IFdpZGdldEZyYW1lVmlldyh7XG4gICAgbW9kZWw6IGZpbHRlclxuICB9KTtcblxuICAvLyByZW5kZXIsIGFuZCByZW5kZXIgY29udGVudCBvZiB3aWRnZXQgZnJhbWVcbiAgdmlldy5yZW5kZXJTdWJ2aWV3KGZyYW1lVmlldywgZWxbMF0pO1xuICBmcmFtZVZpZXcucmVuZGVyQ29udGVudCgpO1xuXG4gIC8vIGxpbmsgZWxlbWVudCBhbmQgdmlldyBzbyB3ZSBjYW46XG4gIC8vIGEpIG9uIHJlbW92ZSwgZ2V0IHRvIHRoZSBIVE1MRWxlbWVudCBmcm9tIHRoZSBXaWRnZXRGcmFtZVZpZXdcbiAgLy8gYikgb24gcmVzaXplLCBnZXQgdG8gdGhlIFdpZGdldEZyYW1lVmlldyBmcm9tIHRoZSBIVE1MRWxlbWVudFxuICBmcmFtZVZpZXcuZ3JpZHN0ZXJIb29rID0gZWxbMF07XG4gICQoZWxbMF0pLmRhdGEoJ3Nwb3RXaWRnZXRGcmFtZVZpZXcnLCBmcmFtZVZpZXcpO1xuXG4gIC8vIHRyeSB0byBpbml0aWFsaXplIGFuZCByZW5kZXIgcG9zc2libHkgcHJlc2VudCBkYXRhXG4gIC8vIG9ubHkgZm9sbG93IGVkaXRNb2RlSGludCB3aGVuIHRoZSB3aWRnZXQgaXMgY29uZmlndXJlZCwgZGVmYXVsdCB0byB0cnVlXG4gIHZhciBjaGFydFZpZXcgPSBmcmFtZVZpZXcud2lkZ2V0O1xuICBjaGFydFZpZXcubW9kZWwudXBkYXRlQ29uZmlndXJhdGlvbigpO1xuICBpZiAoY2hhcnRWaWV3Lm1vZGVsLmlzQ29uZmlndXJlZCkge1xuICAgIGlmICghZmlsdGVyLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIGZpbHRlci5pbml0RGF0YUZpbHRlcigpO1xuICAgIH1cbiAgICBpZiAoIWNoYXJ0Vmlldy5pc0luaXRpYWxpemVkKSB7XG4gICAgICBjaGFydFZpZXcuaW5pdENoYXJ0KCk7XG4gICAgfVxuICAgIGNoYXJ0Vmlldy51cGRhdGUoKTtcblxuICAgIGZyYW1lVmlldy5lZGl0TW9kZSA9IGVkaXRNb2RlSGludDtcbiAgfSBlbHNlIHtcbiAgICAvLyB3aWRnZXQgaXMgbm90IGNvbmZpZ3VyZWQsIGlnbm9yZSBlZGl0TW9kZUhpbnRcbiAgICAvLyBhbmQgYWx3YXlzIGdvIHRvIGVkaXQgbW9kZVxuICAgIGZyYW1lVmlldy5lZGl0TW9kZSA9IHRydWU7XG4gIH1cblxuICBmaWx0ZXIub24oJ25ld0RhdGEnLCBmdW5jdGlvbiAoKSB7XG4gICAgY2hhcnRWaWV3LnVwZGF0ZSgpO1xuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBQYWdlVmlldy5leHRlbmQoe1xuICB0ZW1wbGF0ZTogdGVtcGxhdGVzLmFuYWx5emUucGFnZSxcbiAgc2Vzc2lvbjoge1xuICAgIGZ1bGxzY3JlZW5Nb2RlOiBbJ2Jvb2xlYW4nLCB0cnVlLCB0cnVlXVxuICB9LFxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5wYWdlTmFtZSA9ICdhbmFseXplJztcbiAgICB0aGlzLmZ1bGxzY3JlZW5Nb2RlID0gYXBwLmZ1bGxzY3JlZW5Nb2RlO1xuICAgIC8vIHRoaXMuaGVscFRlbXBsYXRlID0gdGVtcGxhdGVzLmhlbHAuYW5hbHl6ZTtcbiAgICB0aGlzLmhlbHBTdGVwcyA9IEFuYWx5emVIZWxwLnN0ZXBzO1xuICAgIHRoaXMuaGVscEhpbnRzID0gQW5hbHl6ZUhlbHAuaGludHM7XG5cblxuXG5cbiAgICAvLyAvLyBzaG93IGV4aXN0aW5nIGRhdGFzZXQgbGlzdFxuICAgIC8vIGFwcC5tZS5kYXRhc2V0cy5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhc2V0LCBpKSB7XG4gICAgLy8gICBpZiAoZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vICAgICBjb25zb2xlLmxvZygnZGF0YXNldDogJywgZGF0YXNldCk7XG4gICAgLy8gICAgIGRhdGFzZXQuZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGZhY2V0LCBqKSB7XG4gICAgLy8gICAgICAgY29uc29sZS5sb2coJ2ZhY2V0OiAnLCBmYWNldCk7XG4gICAgLy8gICAgIH0pO1xuICAgIC8vICAgfVxuICAgIC8vIH0pO1xuXG5cblxuXG4gICAgYXBwLm9uKCdyZWZyZXNoJywgZnVuY3Rpb24gKCkge1xuICAgICAgaW5pdGlhbGl6ZUNoYXJ0cyh0aGlzKTtcbiAgICAgIGFwcC5tZS5kYXRhdmlldy5nZXREYXRhKCk7XG4gICAgfSwgdGhpcyk7XG5cbiAgICB0aGlzLm9uY2UoJ3JlbW92ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHJlbW92ZSBjYWxsYmFja3MgZm9yICdhcHAjcmVmcmVzaCdcbiAgICAgIGFwcC5vZmYoJ3JlZnJlc2gnKTtcblxuICAgICAgLy8gcmVtb3ZlIGNhbGxiYWNrcyBmb3IgJ2ZpbHRlciNuZXdEYXRhJ1xuICAgICAgYXBwLm1lLmRhdGF2aWV3LmZpbHRlcnMuZm9yRWFjaChmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgICAgIGZpbHRlci5vZmYoJ25ld0RhdGEnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaWYgKGFwcC5tZS5kYXRhdmlldy5kYXRhc2V0SWRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgYXBwLm1lc3NhZ2Uoe1xuICAgICAgICB0ZXh0OiAnTm8gZGF0YSB0byBhbmFseXplLCBwbGVhc2UgdXBsb2FkIGFuZC9vciBzZWxlY3Qgc29tZSBkYXRhc2V0cycsXG4gICAgICAgIHR5cGU6ICdvaydcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbiAgZGVyaXZlZDoge1xuICAgIGRhdGFTdHJpbmc6IHtcbiAgICAgIGRlcHM6IFsnbW9kZWwuZGF0YVRvdGFsJywgJ21vZGVsLmRhdGFTZWxlY3RlZCddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBlcmNlbnRhZ2U7XG4gICAgICAgIGlmICh0aGlzLm1vZGVsLmRhdGFUb3RhbCA+IDApIHtcbiAgICAgICAgICBwZXJjZW50YWdlID0gMTAwLjAgKiB0aGlzLm1vZGVsLmRhdGFTZWxlY3RlZCAvIHRoaXMubW9kZWwuZGF0YVRvdGFsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBlcmNlbnRhZ2UgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLm1vZGVsLmRhdGFUb3RhbCArXG4gICAgICAgICAgJyB0b3RhbCwgJyArXG4gICAgICAgICAgdGhpcy5tb2RlbC5kYXRhU2VsZWN0ZWQgK1xuICAgICAgICAgICcgc2VsZWN0ZWQgKCcgK1xuICAgICAgICAgIHBlcmNlbnRhZ2UudG9QcmVjaXNpb24oMykgK1xuICAgICAgICAgICclKSc7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBiaW5kaW5nczoge1xuICAgICdmdWxsc2NyZWVuTW9kZSc6IFtcbiAgICAgIHsgdHlwZTogJ3RvZ2dsZScsIGhvb2s6ICdjaGFydC1iYXInLCBpbnZlcnQ6IHRydWUgfSxcbiAgICAgIHsgdHlwZTogJ3RvZ2dsZScsIGhvb2s6ICdmYWNldC1iYXInLCBpbnZlcnQ6IHRydWUgfVxuICAgIF0sXG4gICAgJ2RhdGFTdHJpbmcnOiB7XG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBob29rOiAnZGF0YS1zdHJpbmcnXG4gICAgfVxuICB9LFxuICBldmVudHM6IHtcbiAgICAnY2xpY2sgI3ZpZXdBbGwnOiAndmlld0FsbCcsXG4gICAgJ2NsaWNrICNmdWxsc2NyZWVuQnV0dG9uJzogJ3RvZ2dsZUZ1bGxzY3JlZW4nLFxuICAgICdjbGljayAjcmVzZXRGaWx0ZXJzQnV0dG9uJzogJ3Jlc2V0RmlsdGVycycsXG4gICAgJ2NsaWNrICNzYXZlU2Vzc2lvbkJ1dHRvbic6ICdzYXZlU2Vzc2lvbicsXG4gICAgJ2NsaWNrIC53aWRnZXRJY29uJzogJ2FkZENoYXJ0J1xuICB9LFxuICBzYXZlU2Vzc2lvbjogZnVuY3Rpb24gKCkge1xuICAgIGFwcC5zYXZlQ3VycmVudFNlc3Npb24oKTtcbiAgfSxcbiAgYWRkQ2hhcnQ6IGZ1bmN0aW9uIChldikge1xuICAgIC8vIHdoYXQgaWNvbiB3YXMgY2xpY2tlZD9cbiAgICB2YXIgdGFyZ2V0ID0gZXYudGFyZ2V0IHx8IGV2LnNyY0VsZW1lbnQ7XG4gICAgdmFyIGlkID0gdGFyZ2V0LmlkO1xuXG4gICAgdmFyIGZpbHRlciA9IHRoaXMubW9kZWwuZmlsdGVycy5hZGQoeyBjaGFydFR5cGU6IGlkIH0pO1xuICAgIGFkZFdpZGdldEZvckZpbHRlcih0aGlzLCBmaWx0ZXIsIHRydWUpO1xuICB9LFxuICB0b2dnbGVGdWxsc2NyZWVuOiBmdW5jdGlvbiAoKSB7XG4gICAgYXBwLmZ1bGxzY3JlZW5Nb2RlID0gIWFwcC5mdWxsc2NyZWVuTW9kZTtcbiAgICB0aGlzLmZ1bGxzY3JlZW5Nb2RlID0gYXBwLmZ1bGxzY3JlZW5Nb2RlO1xuICB9LFxuICByZXNldEZpbHRlcnM6IGZ1bmN0aW9uICgpIHtcbiAgICBhcHAubWUuZGF0YXZpZXcucGF1c2UoKTtcbiAgICBhcHAubWUuZGF0YXZpZXcuZmlsdGVycy5mb3JFYWNoKGZ1bmN0aW9uIChmaWx0ZXIpIHtcbiAgICAgIC8vIHVuZG8gZHJpbGwgZG93bnNcbiAgICAgIHdoaWxlIChmaWx0ZXIuem9vbUhpc3RvcnkubGVuZ3RoID4gMCkge1xuICAgICAgICBmaWx0ZXIuem9vbU91dCgpO1xuICAgICAgfVxuICAgICAgLy8gYW5kIGNsZWFyIHBvc3NpYmxlIHNlbGVjdGlvblxuICAgICAgZmlsdGVyLnpvb21PdXQoKTtcbiAgICB9KTtcbiAgICBhcHAubWUuZGF0YXZpZXcucGxheSgpO1xuICAgIGFwcC5tZS5kYXRhdmlldy5nZXREYXRhKCk7XG4gICAgYXBwLm1lc3NhZ2Uoe1xuICAgICAgdGV4dDogJ1Jlc2VsZWN0ZWQgYWxsIGRhdGEnLFxuICAgICAgdHlwZTogJ29rJ1xuICAgIH0pO1xuICB9LFxuICB2aWV3QWxsOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fc3Vidmlld3MuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgICAgaWYgKHYuX3ZhbHVlcyAmJiB2Ll92YWx1ZXMuaGFzT3duUHJvcGVydHkoJ2VkaXRNb2RlJykpIHtcbiAgICAgICAgdi5lZGl0TW9kZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgdGhpcy5yZW5kZXJXaXRoVGVtcGxhdGUodGhpcyk7XG5cbiAgICB0aGlzLnJlbmRlckNvbGxlY3Rpb24odGhpcy5tb2RlbC5mYWNldHMsIEZhY2V0YmFySXRlbVZpZXcsIHRoaXMucXVlcnlCeUhvb2soJ2ZhY2V0LWJhci1pdGVtcycpLCB7XG4gICAgICBmaWx0ZXI6IGZ1bmN0aW9uIChtKSB7XG4gICAgICAgIHJldHVybiBtLmlzQWN0aXZlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG4gIHJlbmRlckNvbnRlbnQ6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgd2lkZ2V0TmVlZHNEYXRhID0gZmFsc2U7XG5cbiAgICB2YXIgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmFjZXRCYXInKTtcbiAgICB0aGlzLl9mYWNldHNTb3J0YWJsZSA9IHNvcnRhYmxlanMuY3JlYXRlKGVsLCB7XG4gICAgICBkcmFnZ2FibGU6ICcubWRsLWNoaXAnLFxuICAgICAgZGF0YUlkQXR0cjogJ2RhdGEtaWQnLFxuICAgICAgc29ydDogZmFsc2UsXG4gICAgICBncm91cDoge1xuICAgICAgICBuYW1lOiAnZmFjZXRzJyxcbiAgICAgICAgcHVsbDogJ2Nsb25lJyxcbiAgICAgICAgcHV0OiBmYWxzZVxuICAgICAgfSxcbiAgICAgIG9uU3RhcnQ6IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgdmFyIGl0ZW0gPSBldnQuaXRlbTtcbiAgICAgICAgdmFyIGZhY2V0SWQgPSBpdGVtLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpO1xuICAgICAgICB2YXIgZmFjZXQgPSBhcHAubWUuZGF0YXZpZXcuZmFjZXRzLmdldChmYWNldElkKTtcbiAgICAgICAgYXBwLnRyaWdnZXIoJ2RyYWdTdGFydCcsIGZhY2V0LnR5cGUpO1xuICAgICAgfSxcbiAgICAgIG9uRW5kOiBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIGFwcC50cmlnZ2VyKCdkcmFnRW5kJyk7XG4gICAgICB9LFxuICAgICAgb25BZGQ6IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgdmFyIGl0ZW0gPSBldnQuaXRlbTtcbiAgICAgICAgaXRlbS5yZW1vdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLl93aWRnZXRzR3JpZHN0ZXIgPSAkKCdbaWR+PXdpZGdldHNdJykuZ3JpZHN0ZXIoe1xuICAgICAgd2lkZ2V0X2Jhc2VfZGltZW5zaW9uczogWzEwMCwgMTAwXSxcbiAgICAgIG1pbl9jb2xzOiAxLFxuICAgICAgbWF4X2NvbHM6IDIwLFxuICAgICAgYXZvaWRfb3ZlcmxhcHBlZF93aWRnZXRzOiBmYWxzZSxcbiAgICAgIHdpZGdldF9zZWxlY3RvcjogJ2RpdicsXG4gICAgICBkcmFnZ2FibGU6IHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgaGFuZGxlOiAnLndpZGdldERyYWdCYXInLFxuICAgICAgICBzdG9wOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdmFyIHdpZGdldHMgPSB0aGlzLiR3aWRnZXRzO1xuICAgICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgd2lkZ2V0cy5sZW5ndGg7IGkrKykgeyAvLyAkLmVhY2hcbiAgICAgICAgICAgIHZhciB3aWRnZXQgPSB3aWRnZXRzW2ldO1xuICAgICAgICAgICAgdmFyIGRhdGEgPSAkKHdpZGdldCkuZGF0YSgpO1xuICAgICAgICAgICAgdmFyIGZpbHRlciA9IGRhdGFbJ3Nwb3RXaWRnZXRGcmFtZVZpZXcnXS5tb2RlbC5maWx0ZXI7XG4gICAgICAgICAgICB2YXIgZ3JpZCA9IGRhdGFbJ2Nvb3JkcyddLmdyaWQ7XG5cbiAgICAgICAgICAgIGZpbHRlci5yb3cgPSBncmlkLnJvdztcbiAgICAgICAgICAgIGZpbHRlci5jb2wgPSBncmlkLmNvbDtcbiAgICAgICAgICAgIGZpbHRlci5zaXplX3ggPSBncmlkLnNpemVfeDtcbiAgICAgICAgICAgIGZpbHRlci5zaXplX3kgPSBncmlkLnNpemVfeTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICByZXNpemU6IHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgc3RhcnQ6IGZ1bmN0aW9uIChlLCB1aSwgd2lkZ2V0KSB7XG4gICAgICAgICAgdmFyIHZpZXcgPSB3aWRnZXQuZGF0YSgnc3BvdFdpZGdldEZyYW1lVmlldycpLl9zdWJ2aWV3c1swXTtcbiAgICAgICAgICB2aWV3LmRlaW5pdENoYXJ0KCk7XG4gICAgICAgIH0sXG4gICAgICAgIHN0b3A6IGZ1bmN0aW9uIChlLCB1aSwgd2lkZ2V0KSB7XG4gICAgICAgICAgdmFyIHZpZXcgPSB3aWRnZXQuZGF0YSgnc3BvdFdpZGdldEZyYW1lVmlldycpLl9zdWJ2aWV3c1swXTtcbiAgICAgICAgICB2YXIgZmlsdGVyID0gdmlldy5tb2RlbC5maWx0ZXI7XG4gICAgICAgICAgaWYgKHZpZXcuaXNJbml0aWFsaXplZCkge1xuICAgICAgICAgICAgdmlldy51cGRhdGUoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBrZWVwIHRyYWNrIG9mIHRoZSBwb3NpdGlvbiBvZiB0aGUgY2hhcnRcbiAgICAgICAgICB2YXIgaW5mbyA9IHdpZGdldC5kYXRhKCdjb29yZHMnKS5ncmlkO1xuICAgICAgICAgIGZpbHRlci5yb3cgPSBpbmZvLnJvdztcbiAgICAgICAgICBmaWx0ZXIuY29sID0gaW5mby5jb2w7XG4gICAgICAgICAgZmlsdGVyLnNpemVfeCA9IGluZm8uc2l6ZV94O1xuICAgICAgICAgIGZpbHRlci5zaXplX3kgPSBpbmZvLnNpemVfeTtcbiAgICAgICAgICBpZiAodmlldy5tb2RlbC5pc0NvbmZpZ3VyZWQpIHtcbiAgICAgICAgICAgIHZpZXcuaW5pdENoYXJ0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh2aWV3LmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgIHZpZXcudXBkYXRlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSkuZGF0YSgnZ3JpZHN0ZXInKTtcblxuICAgIHRoaXMub24oJ3JlbW92ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuX2ZhY2V0c1NvcnRhYmxlLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMuX3dpZGdldHNHcmlkc3Rlci5kZXN0cm95KCk7XG4gICAgfSk7XG5cbiAgICAvLyBwYXVzZSBkYXRhc2V0IHRvIHByZXZlbnQgbmVlZGxlc3MgZGF0YSB1cGRhdGVzXG4gICAgdGhpcy5tb2RlbC5wYXVzZSgpO1xuXG4gICAgLy8gYWRkIHdpZGdldHMgZm9yIGVhY2ggZmlsdGVyIHRvIHRoZSBwYWdlXG4gICAgdGhpcy5tb2RlbC5maWx0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpbHRlcikge1xuICAgICAgYWRkV2lkZ2V0Rm9yRmlsdGVyKHRoaXMsIGZpbHRlciwgZmFsc2UpO1xuXG4gICAgICBpZiAoIWZpbHRlci5kYXRhIHx8IGZpbHRlci5kYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB3aWRnZXROZWVkc0RhdGEgPSB0cnVlO1xuICAgICAgfVxuICAgIH0sIHRoaXMpO1xuXG4gICAgLy8gZG9uZSwgdW5wYXVzZSB0aGUgZGF0YXNldFxuICAgIHRoaXMubW9kZWwucGxheSgpO1xuXG4gICAgaWYgKHdpZGdldE5lZWRzRGF0YSkge1xuICAgICAgYXBwLm1lLmRhdGF2aWV3LmdldERhdGEoKTtcbiAgICB9XG5cbiAgICAvLyBkbyBhIGxhc3QgcGFzcyB0byByZW5kZXIgZGF0YVxuICAgIHVwZGF0ZUNoYXJ0cyh0aGlzKTtcbiAgfSxcbiAgaW5pdGlhbGl6ZUNoYXJ0czogZnVuY3Rpb24gKCkge1xuICAgIGluaXRpYWxpemVDaGFydHModGhpcyk7XG4gIH0sXG4gIGRlaW5pdGlhbGl6ZUNoYXJ0czogZnVuY3Rpb24gKCkge1xuICAgIGRlaW5pdGlhbGl6ZUNoYXJ0cyh0aGlzKTtcbiAgfSxcbiAgdXBkYXRlQ2hhcnRzOiBmdW5jdGlvbiAoKSB7XG4gICAgdXBkYXRlQ2hhcnRzKHRoaXMpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7O0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBREE7QUFDQTtBQUlBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBR0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBTUE7QUFmQTtBQURBO0FBbUJBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBRkE7QUFMQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBckJBO0FBdUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBakJBO0FBbUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBekJBO0FBekJBO0FBc0RBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBNVBBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///22e9\n")},2413:function(module,exports,__webpack_require__){eval("/**\n * @classdesc pie chart class\n * @class PieChart\n * @augments BaseChart\n */\nvar BaseChart = __webpack_require__(/*! ./base-chart */ \"6339\");\n\nmodule.exports = BaseChart.extend({\n  initialize: function initialize() {\n    this.slots.reset([{\n      description: 'Group by',\n      type: 'partition',\n      rank: 1,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Pie size',\n      type: 'aggregate',\n      rank: 1,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }]);\n  },\n  chartjsConfig: function chartjsConfig() {\n    return {\n      type: 'pie',\n      data: {\n        datasets: [],\n        labels: []\n      },\n      options: {\n        title: {\n          display: true,\n          position: 'top'\n        },\n        tooltips: {}\n      }\n    };\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQxMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL21vZGVscy9waWVjaGFydC5qcz9mMzE5Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGNsYXNzZGVzYyBwaWUgY2hhcnQgY2xhc3NcbiAqIEBjbGFzcyBQaWVDaGFydFxuICogQGF1Z21lbnRzIEJhc2VDaGFydFxuICovXG5cbnZhciBCYXNlQ2hhcnQgPSByZXF1aXJlKCcuL2Jhc2UtY2hhcnQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlQ2hhcnQuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc2xvdHMucmVzZXQoW1xuICAgICAge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ0dyb3VwIGJ5JyxcbiAgICAgICAgdHlwZTogJ3BhcnRpdGlvbicsXG4gICAgICAgIHJhbms6IDEsXG4gICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICBzdXBwb3J0ZWRGYWNldHM6IFsnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICdjb250aW51b3VzJywgJ3RleHQnXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdQaWUgc2l6ZScsXG4gICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICByYW5rOiAxLFxuICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIHN1cHBvcnRlZEZhY2V0czogWydjb250aW51b3VzJywgJ2R1cmF0aW9uJ11cbiAgICAgIH1cbiAgICBdKTtcbiAgfSxcbiAgY2hhcnRqc0NvbmZpZzogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAncGllJyxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgZGF0YXNldHM6IFtdLFxuICAgICAgICBsYWJlbHM6IFtdXG4gICAgICB9LFxuICAgICAgb3B0aW9uczoge1xuICAgICAgICB0aXRsZToge1xuICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgcG9zaXRpb246ICd0b3AnXG4gICAgICAgIH0sXG4gICAgICAgIHRvb2x0aXBzOiB7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFMQTtBQU5BO0FBZUE7QUFuQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2413\n")},"26ef":function(module,exports,__webpack_require__){eval("/**\n * Base Widget\n *\n * Base class to hold widget interaction. Extend and override properties for each chart.\n * @class BaseWidget\n */\nvar AmpersandView = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nmodule.exports = AmpersandView.extend({\n  props: {\n    /**\n     * Boolean indicating if a chart has been added to the DOM\n     */\n    isInitialized: {\n      type: 'boolean',\n      required: true,\n      default: false\n    }\n  },\n\n  /**\n   * Initialize the chart and add it to the DOM\n   * Override for your specific widget.\n   */\n  initChart: function initChart() {\n    console.error('Can not call virtual method');\n  },\n\n  /**\n   * Update the widget\n   * Override for your specific widget.\n   */\n  update: function update() {\n    console.error('Can not call virtual method');\n  },\n\n  /**\n   * Remove the widget from the DOM and free any associated data\n   * Override for your specific widget.\n   */\n  deinitChart: function deinitChart() {\n    console.error('Can not call virtual method');\n  },\n  renderContent: function renderContent() {}\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjZlZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL3ZpZXdzL2Jhc2Utd2lkZ2V0LmpzPzc2OGQiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCYXNlIFdpZGdldFxuICpcbiAqIEJhc2UgY2xhc3MgdG8gaG9sZCB3aWRnZXQgaW50ZXJhY3Rpb24uIEV4dGVuZCBhbmQgb3ZlcnJpZGUgcHJvcGVydGllcyBmb3IgZWFjaCBjaGFydC5cbiAqIEBjbGFzcyBCYXNlV2lkZ2V0XG4gKi9cbnZhciBBbXBlcnNhbmRWaWV3ID0gcmVxdWlyZSgnYW1wZXJzYW5kLXZpZXcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBBbXBlcnNhbmRWaWV3LmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogQm9vbGVhbiBpbmRpY2F0aW5nIGlmIGEgY2hhcnQgaGFzIGJlZW4gYWRkZWQgdG8gdGhlIERPTVxuICAgICAqL1xuICAgIGlzSW5pdGlhbGl6ZWQ6IHtcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogZmFsc2VcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGhlIGNoYXJ0IGFuZCBhZGQgaXQgdG8gdGhlIERPTVxuICAgKiBPdmVycmlkZSBmb3IgeW91ciBzcGVjaWZpYyB3aWRnZXQuXG4gICAqL1xuICBpbml0Q2hhcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICBjb25zb2xlLmVycm9yKCdDYW4gbm90IGNhbGwgdmlydHVhbCBtZXRob2QnKTtcbiAgfSxcblxuICAvKipcbiAgICogVXBkYXRlIHRoZSB3aWRnZXRcbiAgICogT3ZlcnJpZGUgZm9yIHlvdXIgc3BlY2lmaWMgd2lkZ2V0LlxuICAgKi9cbiAgdXBkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5lcnJvcignQ2FuIG5vdCBjYWxsIHZpcnR1YWwgbWV0aG9kJyk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlbW92ZSB0aGUgd2lkZ2V0IGZyb20gdGhlIERPTSBhbmQgZnJlZSBhbnkgYXNzb2NpYXRlZCBkYXRhXG4gICAqIE92ZXJyaWRlIGZvciB5b3VyIHNwZWNpZmljIHdpZGdldC5cbiAgICovXG4gIGRlaW5pdENoYXJ0OiBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5lcnJvcignQ2FuIG5vdCBjYWxsIHZpcnR1YWwgbWV0aG9kJyk7XG4gIH0sXG5cbiAgcmVuZGVyQ29udGVudDogZnVuY3Rpb24gKCkge1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFKQTtBQUNBO0FBVUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUVBO0FBcENBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///26ef\n")},2960:function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar TimeZonesSelect = __webpack_require__(/*! ./time-zones-select */ \"f3d5\");\n\nvar DurationUnitsSelect = __webpack_require__(/*! ./duration-units-select */ \"4916\");\n\nmodule.exports = View.extend({\n  template: templates.configureFacet.facetTransformDuration,\n  bindings: {\n    'model.transformedReference': {\n      type: 'value',\n      hook: 'transform-duration-transformedreference-input'\n    }\n  },\n  events: {\n    'change [data-hook~=transform-duration-transformedreference-input]': function changeDataHookTransformDurationTransformedreferenceInput() {\n      this.model.transformedReference = this.queryByHook('transform-duration-transformedreference-input').value;\n    }\n  },\n  subviews: {\n    durationUnits: {\n      hook: 'duration-units',\n      prepareView: function prepareView(el) {\n        return new DurationUnitsSelect({\n          el: el,\n          field: 'units',\n          model: this.model\n        });\n      }\n    },\n    transformedDurationUnits: {\n      hook: 'transformed-duration-units',\n      prepareView: function prepareView(el) {\n        return new DurationUnitsSelect({\n          el: el,\n          field: 'transformedUnits',\n          model: this.model\n        });\n      }\n    },\n    timeZones: {\n      hook: 'transformed-duration-zone',\n      prepareView: function prepareView(el) {\n        return new TimeZonesSelect({\n          el: el,\n          field: 'transformedZone',\n          model: this.model\n        });\n      }\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjk2MC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZmFjZXQvZmFjZXQtdHJhbnNmb3JtLWR1cmF0aW9uLmpzPzQyMGYiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL3RlbXBsYXRlcycpO1xudmFyIFRpbWVab25lc1NlbGVjdCA9IHJlcXVpcmUoJy4vdGltZS16b25lcy1zZWxlY3QnKTtcbnZhciBEdXJhdGlvblVuaXRzU2VsZWN0ID0gcmVxdWlyZSgnLi9kdXJhdGlvbi11bml0cy1zZWxlY3QnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMuY29uZmlndXJlRmFjZXQuZmFjZXRUcmFuc2Zvcm1EdXJhdGlvbixcbiAgYmluZGluZ3M6IHtcbiAgICAnbW9kZWwudHJhbnNmb3JtZWRSZWZlcmVuY2UnOiB7XG4gICAgICB0eXBlOiAndmFsdWUnLFxuICAgICAgaG9vazogJ3RyYW5zZm9ybS1kdXJhdGlvbi10cmFuc2Zvcm1lZHJlZmVyZW5jZS1pbnB1dCdcbiAgICB9XG4gIH0sXG4gIGV2ZW50czoge1xuICAgICdjaGFuZ2UgW2RhdGEtaG9va349dHJhbnNmb3JtLWR1cmF0aW9uLXRyYW5zZm9ybWVkcmVmZXJlbmNlLWlucHV0XSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwudHJhbnNmb3JtZWRSZWZlcmVuY2UgPSB0aGlzLnF1ZXJ5QnlIb29rKCd0cmFuc2Zvcm0tZHVyYXRpb24tdHJhbnNmb3JtZWRyZWZlcmVuY2UtaW5wdXQnKS52YWx1ZTtcbiAgICB9XG4gIH0sXG4gIHN1YnZpZXdzOiB7XG4gICAgZHVyYXRpb25Vbml0czoge1xuICAgICAgaG9vazogJ2R1cmF0aW9uLXVuaXRzJyxcbiAgICAgIHByZXBhcmVWaWV3OiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEdXJhdGlvblVuaXRzU2VsZWN0KHtcbiAgICAgICAgICBlbDogZWwsXG4gICAgICAgICAgZmllbGQ6ICd1bml0cycsXG4gICAgICAgICAgbW9kZWw6IHRoaXMubW9kZWxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgICB0cmFuc2Zvcm1lZER1cmF0aW9uVW5pdHM6IHtcbiAgICAgIGhvb2s6ICd0cmFuc2Zvcm1lZC1kdXJhdGlvbi11bml0cycsXG4gICAgICBwcmVwYXJlVmlldzogZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgIHJldHVybiBuZXcgRHVyYXRpb25Vbml0c1NlbGVjdCh7XG4gICAgICAgICAgZWw6IGVsLFxuICAgICAgICAgIGZpZWxkOiAndHJhbnNmb3JtZWRVbml0cycsXG4gICAgICAgICAgbW9kZWw6IHRoaXMubW9kZWxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgICB0aW1lWm9uZXM6IHtcbiAgICAgIGhvb2s6ICd0cmFuc2Zvcm1lZC1kdXJhdGlvbi16b25lJyxcbiAgICAgIHByZXBhcmVWaWV3OiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaW1lWm9uZXNTZWxlY3Qoe1xuICAgICAgICAgIGVsOiBlbCxcbiAgICAgICAgICBmaWVsZDogJ3RyYW5zZm9ybWVkWm9uZScsXG4gICAgICAgICAgbW9kZWw6IHRoaXMubW9kZWxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBREE7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFSQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQVJBO0FBVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBUkE7QUFyQkE7QUFiQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2960\n")},"2b41":function(module,exports,__webpack_require__){eval("var colors = __webpack_require__(/*! ../../colors */ \"eb63\");\n/**\n * Get the index in chartjs datastructures from the group value\n * with proper fallbacks\n * @params {Partition} partition (optional)\n * @params {Object} value value\n * @returns {number|null} index\n */\n\n\nfunction partitionValueToIndex(partition, value) {\n  var group;\n\n  if (!partition) {\n    // no(sub)partitioning return first element\n    return 0;\n  } // with (sub)partitioning\n\n\n  group = partition.groups.get(value, 'value');\n\n  if (group) {\n    // string in partition\n    return group.groupIndex;\n  } else {\n    // string not in partition\n    return -1;\n  }\n}\n/**\n * prepare data structure, reuse as much of the previous data arrays as possible\n * to prevent massive animations on every update\n * @params{ChartJSData} chartData ChartJS data structure\n * @params{Partition} partitionA X-axis\n * @params{Partition} partitionB Y-axis\n * @params{Object} options Options: perItem, multiDimensional, doubleDatasets\n */\n\n\nfunction resizeChartjsData(chartData, partitionA, partitionB, options) {\n  var x = partitionA ? partitionA.groups.length : 1;\n  var y = partitionB ? partitionB.groups.length : 1;\n  options = options || {};\n  var perItem = options.perItem || false;\n  var multiDimensional = options.multiDimensional || false;\n  var doubleDatasets = options.doubleDatasets || false;\n  var totalDatasets = doubleDatasets ? 2 * y : y;\n  var i;\n  var j;\n  var cut; // match the number of labels needed\n\n  cut = chartData.labels.length - x;\n\n  if (cut > 0) {\n    chartData.labels.splice(0, cut);\n  } // labels on the primary axis\n\n\n  for (i = 0; i < x; i++) {\n    chartData.labels[i] = partitionA.groups.models[i].label;\n  } // match the number of datasets needed\n\n\n  cut = chartData.datasets.length - totalDatasets;\n\n  if (cut > 0) {\n    // BUGFIX: weird behavious for linechart selections and plots\n    // when we remove datasets from the front, everything shifts one place to the 'left',\n    // which will cause issues for linecharts where we use an extra dataset at the back for selections.\n    //\n    // Solution: remove from the back\n    chartData.datasets.splice(chartData.datasets.length, cut);\n  }\n\n  for (j = 0; j < totalDatasets; j++) {\n    // update or assign data structure:\n    chartData.datasets[j] = chartData.datasets[j] || {\n      data: [],\n      error: []\n    }; // match the existing number of groups to the updated number of groups\n\n    cut = chartData.datasets[j].data.length - x;\n\n    if (cut > 0) {\n      chartData.datasets[j].data.splice(0, cut);\n    }\n\n    cut = chartData.datasets[j].error.length - x;\n\n    if (cut > 0) {\n      chartData.datasets[j].error.splice(0, cut);\n    } // clear out old data / pre-allocate new data\n\n\n    for (i = 0; i < x; i++) {\n      if (multiDimensional) {\n        chartData.datasets[j].data[i] = {};\n        chartData.datasets[j].error[i] = {};\n      } else {\n        chartData.datasets[j].data[i] = 0;\n        chartData.datasets[j].error[i] = 0;\n      }\n    }\n  } // set metadata for main datasets\n\n\n  for (j = 0; j < y; j++) {\n    // set dataset color\n    if (perItem) {\n      chartData.datasets[j].backgroundColor = [];\n      chartData.datasets[j].borderColor = [];\n\n      for (i = 0; i < x; i++) {\n        chartData.datasets[j].backgroundColor[i] = colors.getColor(0).css(); // chartData.datasets[j].borderColor[i] = colors.getColor(0).css();\n      }\n    } else {\n      chartData.datasets[j].backgroundColor = colors.getColor(j).css();\n      chartData.datasets[j].borderColor = colors.getColor(j).css();\n      chartData.datasets[j].fill = false;\n    } // add a legend entry\n\n\n    if (partitionB) {\n      chartData.datasets[j].label = partitionB.groups.models[j].label;\n    }\n  }\n\n  if (!doubleDatasets) {\n    return;\n  } // set metadata for doubled datasets\n\n\n  for (j = y; j < 2 * y; j++) {\n    chartData.datasets[j].borderDash = [15, 5]; // striped lines\n\n    chartData.datasets[j].borderWidth = 1; // thin lines\n\n    chartData.datasets[j].pointRadius = 0; // no points\n\n    chartData.datasets[j].fill = false; // set dataset color\n\n    if (perItem) {\n      chartData.datasets[j].backgroundColor = [];\n      chartData.datasets[j].borderColor = [];\n\n      for (i = 0; i < x; i++) {\n        chartData.datasets[j].backgroundColor[i] = colors.getColor(0).css(); // chartData.datasets[j].borderColor[i] = colors.getColor(0).css();\n      }\n    } else {\n      chartData.datasets[j].backgroundColor = colors.getColor(j - y).css();\n      chartData.datasets[j].borderColor = colors.getColor(j - y).css();\n    } // add a legend entry\n\n\n    if (partitionB) {\n      chartData.datasets[j].label = partitionB.groups.models[j - y].label;\n    }\n  }\n}\n\nmodule.exports = {\n  partitionValueToIndex: partitionValueToIndex,\n  resizeChartjsData: resizeChartjsData\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMmI0MS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL3ZpZXdzL3V0aWwuanM/YmRjOCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgY29sb3JzID0gcmVxdWlyZSgnLi4vLi4vY29sb3JzJyk7XG5cbi8qKlxuICogR2V0IHRoZSBpbmRleCBpbiBjaGFydGpzIGRhdGFzdHJ1Y3R1cmVzIGZyb20gdGhlIGdyb3VwIHZhbHVlXG4gKiB3aXRoIHByb3BlciBmYWxsYmFja3NcbiAqIEBwYXJhbXMge1BhcnRpdGlvbn0gcGFydGl0aW9uIChvcHRpb25hbClcbiAqIEBwYXJhbXMge09iamVjdH0gdmFsdWUgdmFsdWVcbiAqIEByZXR1cm5zIHtudW1iZXJ8bnVsbH0gaW5kZXhcbiAqL1xuZnVuY3Rpb24gcGFydGl0aW9uVmFsdWVUb0luZGV4IChwYXJ0aXRpb24sIHZhbHVlKSB7XG4gIHZhciBncm91cDtcblxuICBpZiAoIXBhcnRpdGlvbikge1xuICAgIC8vIG5vKHN1YilwYXJ0aXRpb25pbmcgcmV0dXJuIGZpcnN0IGVsZW1lbnRcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIC8vIHdpdGggKHN1YilwYXJ0aXRpb25pbmdcbiAgZ3JvdXAgPSBwYXJ0aXRpb24uZ3JvdXBzLmdldCh2YWx1ZSwgJ3ZhbHVlJyk7XG5cbiAgaWYgKGdyb3VwKSB7XG4gICAgLy8gc3RyaW5nIGluIHBhcnRpdGlvblxuICAgIHJldHVybiBncm91cC5ncm91cEluZGV4O1xuICB9IGVsc2Uge1xuICAgIC8vIHN0cmluZyBub3QgaW4gcGFydGl0aW9uXG4gICAgcmV0dXJuIC0xO1xuICB9XG59XG5cbi8qKlxuICogcHJlcGFyZSBkYXRhIHN0cnVjdHVyZSwgcmV1c2UgYXMgbXVjaCBvZiB0aGUgcHJldmlvdXMgZGF0YSBhcnJheXMgYXMgcG9zc2libGVcbiAqIHRvIHByZXZlbnQgbWFzc2l2ZSBhbmltYXRpb25zIG9uIGV2ZXJ5IHVwZGF0ZVxuICogQHBhcmFtc3tDaGFydEpTRGF0YX0gY2hhcnREYXRhIENoYXJ0SlMgZGF0YSBzdHJ1Y3R1cmVcbiAqIEBwYXJhbXN7UGFydGl0aW9ufSBwYXJ0aXRpb25BIFgtYXhpc1xuICogQHBhcmFtc3tQYXJ0aXRpb259IHBhcnRpdGlvbkIgWS1heGlzXG4gKiBAcGFyYW1ze09iamVjdH0gb3B0aW9ucyBPcHRpb25zOiBwZXJJdGVtLCBtdWx0aURpbWVuc2lvbmFsLCBkb3VibGVEYXRhc2V0c1xuICovXG5mdW5jdGlvbiByZXNpemVDaGFydGpzRGF0YSAoY2hhcnREYXRhLCBwYXJ0aXRpb25BLCBwYXJ0aXRpb25CLCBvcHRpb25zKSB7XG4gIHZhciB4ID0gcGFydGl0aW9uQSA/IHBhcnRpdGlvbkEuZ3JvdXBzLmxlbmd0aCA6IDE7XG4gIHZhciB5ID0gcGFydGl0aW9uQiA/IHBhcnRpdGlvbkIuZ3JvdXBzLmxlbmd0aCA6IDE7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciBwZXJJdGVtID0gb3B0aW9ucy5wZXJJdGVtIHx8IGZhbHNlO1xuICB2YXIgbXVsdGlEaW1lbnNpb25hbCA9IG9wdGlvbnMubXVsdGlEaW1lbnNpb25hbCB8fCBmYWxzZTtcbiAgdmFyIGRvdWJsZURhdGFzZXRzID0gb3B0aW9ucy5kb3VibGVEYXRhc2V0cyB8fCBmYWxzZTtcblxuICB2YXIgdG90YWxEYXRhc2V0cyA9IGRvdWJsZURhdGFzZXRzID8gMiAqIHkgOiB5O1xuXG4gIHZhciBpO1xuICB2YXIgajtcbiAgdmFyIGN1dDtcblxuICAvLyBtYXRjaCB0aGUgbnVtYmVyIG9mIGxhYmVscyBuZWVkZWRcbiAgY3V0ID0gY2hhcnREYXRhLmxhYmVscy5sZW5ndGggLSB4O1xuICBpZiAoY3V0ID4gMCkge1xuICAgIGNoYXJ0RGF0YS5sYWJlbHMuc3BsaWNlKDAsIGN1dCk7XG4gIH1cblxuICAvLyBsYWJlbHMgb24gdGhlIHByaW1hcnkgYXhpc1xuICBmb3IgKGkgPSAwOyBpIDwgeDsgaSsrKSB7XG4gICAgY2hhcnREYXRhLmxhYmVsc1tpXSA9IHBhcnRpdGlvbkEuZ3JvdXBzLm1vZGVsc1tpXS5sYWJlbDtcbiAgfVxuXG4gIC8vIG1hdGNoIHRoZSBudW1iZXIgb2YgZGF0YXNldHMgbmVlZGVkXG4gIGN1dCA9IGNoYXJ0RGF0YS5kYXRhc2V0cy5sZW5ndGggLSB0b3RhbERhdGFzZXRzO1xuICBpZiAoY3V0ID4gMCkge1xuICAgIC8vIEJVR0ZJWDogd2VpcmQgYmVoYXZpb3VzIGZvciBsaW5lY2hhcnQgc2VsZWN0aW9ucyBhbmQgcGxvdHNcbiAgICAvLyB3aGVuIHdlIHJlbW92ZSBkYXRhc2V0cyBmcm9tIHRoZSBmcm9udCwgZXZlcnl0aGluZyBzaGlmdHMgb25lIHBsYWNlIHRvIHRoZSAnbGVmdCcsXG4gICAgLy8gd2hpY2ggd2lsbCBjYXVzZSBpc3N1ZXMgZm9yIGxpbmVjaGFydHMgd2hlcmUgd2UgdXNlIGFuIGV4dHJhIGRhdGFzZXQgYXQgdGhlIGJhY2sgZm9yIHNlbGVjdGlvbnMuXG4gICAgLy9cbiAgICAvLyBTb2x1dGlvbjogcmVtb3ZlIGZyb20gdGhlIGJhY2tcbiAgICBjaGFydERhdGEuZGF0YXNldHMuc3BsaWNlKGNoYXJ0RGF0YS5kYXRhc2V0cy5sZW5ndGgsIGN1dCk7XG4gIH1cblxuICBmb3IgKGogPSAwOyBqIDwgdG90YWxEYXRhc2V0czsgaisrKSB7XG4gICAgLy8gdXBkYXRlIG9yIGFzc2lnbiBkYXRhIHN0cnVjdHVyZTpcbiAgICBjaGFydERhdGEuZGF0YXNldHNbal0gPSBjaGFydERhdGEuZGF0YXNldHNbal0gfHwge2RhdGE6IFtdLCBlcnJvcjogW119O1xuXG4gICAgLy8gbWF0Y2ggdGhlIGV4aXN0aW5nIG51bWJlciBvZiBncm91cHMgdG8gdGhlIHVwZGF0ZWQgbnVtYmVyIG9mIGdyb3Vwc1xuICAgIGN1dCA9IGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5kYXRhLmxlbmd0aCAtIHg7XG4gICAgaWYgKGN1dCA+IDApIHtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5kYXRhLnNwbGljZSgwLCBjdXQpO1xuICAgIH1cbiAgICBjdXQgPSBjaGFydERhdGEuZGF0YXNldHNbal0uZXJyb3IubGVuZ3RoIC0geDtcbiAgICBpZiAoY3V0ID4gMCkge1xuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzW2pdLmVycm9yLnNwbGljZSgwLCBjdXQpO1xuICAgIH1cblxuICAgIC8vIGNsZWFyIG91dCBvbGQgZGF0YSAvIHByZS1hbGxvY2F0ZSBuZXcgZGF0YVxuICAgIGZvciAoaSA9IDA7IGkgPCB4OyBpKyspIHtcbiAgICAgIGlmIChtdWx0aURpbWVuc2lvbmFsKSB7XG4gICAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5kYXRhW2ldID0ge307XG4gICAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5lcnJvcltpXSA9IHt9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2hhcnREYXRhLmRhdGFzZXRzW2pdLmRhdGFbaV0gPSAwO1xuICAgICAgICBjaGFydERhdGEuZGF0YXNldHNbal0uZXJyb3JbaV0gPSAwO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIHNldCBtZXRhZGF0YSBmb3IgbWFpbiBkYXRhc2V0c1xuICBmb3IgKGogPSAwOyBqIDwgeTsgaisrKSB7XG4gICAgLy8gc2V0IGRhdGFzZXQgY29sb3JcbiAgICBpZiAocGVySXRlbSkge1xuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzW2pdLmJhY2tncm91bmRDb2xvciA9IFtdO1xuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzW2pdLmJvcmRlckNvbG9yID0gW107XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgeDsgaSsrKSB7XG4gICAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5iYWNrZ3JvdW5kQ29sb3JbaV0gPSBjb2xvcnMuZ2V0Q29sb3IoMCkuY3NzKCk7XG4gICAgICAgIC8vIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5ib3JkZXJDb2xvcltpXSA9IGNvbG9ycy5nZXRDb2xvcigwKS5jc3MoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzW2pdLmJhY2tncm91bmRDb2xvciA9IGNvbG9ycy5nZXRDb2xvcihqKS5jc3MoKTtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5ib3JkZXJDb2xvciA9IGNvbG9ycy5nZXRDb2xvcihqKS5jc3MoKTtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5maWxsID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gYWRkIGEgbGVnZW5kIGVudHJ5XG4gICAgaWYgKHBhcnRpdGlvbkIpIHtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5sYWJlbCA9IHBhcnRpdGlvbkIuZ3JvdXBzLm1vZGVsc1tqXS5sYWJlbDtcbiAgICB9XG4gIH1cblxuICBpZiAoIWRvdWJsZURhdGFzZXRzKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gc2V0IG1ldGFkYXRhIGZvciBkb3VibGVkIGRhdGFzZXRzXG4gIGZvciAoaiA9IHk7IGogPCAyICogeTsgaisrKSB7XG4gICAgY2hhcnREYXRhLmRhdGFzZXRzW2pdLmJvcmRlckRhc2ggPSBbMTUsIDVdOyAvLyBzdHJpcGVkIGxpbmVzXG4gICAgY2hhcnREYXRhLmRhdGFzZXRzW2pdLmJvcmRlcldpZHRoID0gMTsgLy8gdGhpbiBsaW5lc1xuICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5wb2ludFJhZGl1cyA9IDA7IC8vIG5vIHBvaW50c1xuICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5maWxsID0gZmFsc2U7XG5cbiAgICAvLyBzZXQgZGF0YXNldCBjb2xvclxuICAgIGlmIChwZXJJdGVtKSB7XG4gICAgICBjaGFydERhdGEuZGF0YXNldHNbal0uYmFja2dyb3VuZENvbG9yID0gW107XG4gICAgICBjaGFydERhdGEuZGF0YXNldHNbal0uYm9yZGVyQ29sb3IgPSBbXTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCB4OyBpKyspIHtcbiAgICAgICAgY2hhcnREYXRhLmRhdGFzZXRzW2pdLmJhY2tncm91bmRDb2xvcltpXSA9IGNvbG9ycy5nZXRDb2xvcigwKS5jc3MoKTtcbiAgICAgICAgLy8gY2hhcnREYXRhLmRhdGFzZXRzW2pdLmJvcmRlckNvbG9yW2ldID0gY29sb3JzLmdldENvbG9yKDApLmNzcygpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjaGFydERhdGEuZGF0YXNldHNbal0uYmFja2dyb3VuZENvbG9yID0gY29sb3JzLmdldENvbG9yKGogLSB5KS5jc3MoKTtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5ib3JkZXJDb2xvciA9IGNvbG9ycy5nZXRDb2xvcihqIC0geSkuY3NzKCk7XG4gICAgfVxuXG4gICAgLy8gYWRkIGEgbGVnZW5kIGVudHJ5XG4gICAgaWYgKHBhcnRpdGlvbkIpIHtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5sYWJlbCA9IHBhcnRpdGlvbkIuZ3JvdXBzLm1vZGVsc1tqIC0geV0ubGFiZWw7XG4gICAgfVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBwYXJ0aXRpb25WYWx1ZVRvSW5kZXg6IHBhcnRpdGlvblZhbHVlVG9JbmRleCxcbiAgcmVzaXplQ2hhcnRqc0RhdGE6IHJlc2l6ZUNoYXJ0anNEYXRhXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUVBOzs7Ozs7Ozs7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7Ozs7O0FBUUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2b41\n")},3:function(module,exports){eval("/* (ignored) *///# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy91dGlsIChpZ25vcmVkKT9iYmZmIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIChpZ25vcmVkKSAqLyJdLCJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3\n")},"37f6":function(module,exports,__webpack_require__){eval("/**\n * @classdesc Scatter Chart class\n * @class ScatterChart\n * @augments BaseChart\n */\nvar BaseChart = __webpack_require__(/*! ./base-chart */ \"6339\");\n\nmodule.exports = BaseChart.extend({\n  initialize: function initialize() {\n    this.slots.reset([{\n      description: 'X axis',\n      type: 'partition',\n      rank: 1,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Y axis',\n      type: 'partition',\n      rank: 2,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Z axis',\n      type: 'partition',\n      rank: 3,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Color by',\n      type: 'aggregate',\n      rank: 1,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }]);\n  },\n  scatterConfig: function scatterConfig() {\n    return {\n      width: '600px',\n      height: '600px',\n      style: 'dot-color',\n      tooltip: true,\n      tooltipStyle: {\n        dot: {\n          border: 'none',\n          borderRadius: '0px'\n        }\n      },\n      showPerspective: true,\n      showGrid: true,\n      showShadow: false,\n      showLegend: false,\n      keepAspectRatio: false,\n      verticalRatio: 1\n    };\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzdmNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL21vZGVscy9zY2F0dGVyLmpzPzc5NjQiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAY2xhc3NkZXNjIFNjYXR0ZXIgQ2hhcnQgY2xhc3NcbiAqIEBjbGFzcyBTY2F0dGVyQ2hhcnRcbiAqIEBhdWdtZW50cyBCYXNlQ2hhcnRcbiAqL1xuXG52YXIgQmFzZUNoYXJ0ID0gcmVxdWlyZSgnLi9iYXNlLWNoYXJ0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZUNoYXJ0LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNsb3RzLnJlc2V0KFtcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdYIGF4aXMnLFxuICAgICAgICB0eXBlOiAncGFydGl0aW9uJyxcbiAgICAgICAgcmFuazogMSxcbiAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIHN1cHBvcnRlZEZhY2V0czogWydjYXRlZ29yaWFsJywgJ2RhdGV0aW1lJywgJ2R1cmF0aW9uJywgJ2NvbnRpbnVvdXMnLCAndGV4dCddXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1kgYXhpcycsXG4gICAgICAgIHR5cGU6ICdwYXJ0aXRpb24nLFxuICAgICAgICByYW5rOiAyLFxuICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NhdGVnb3JpYWwnLCAnZGF0ZXRpbWUnLCAnZHVyYXRpb24nLCAnY29udGludW91cycsICd0ZXh0J11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnWiBheGlzJyxcbiAgICAgICAgdHlwZTogJ3BhcnRpdGlvbicsXG4gICAgICAgIHJhbms6IDMsXG4gICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICBzdXBwb3J0ZWRGYWNldHM6IFsnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICdjb250aW51b3VzJywgJ3RleHQnXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdDb2xvciBieScsXG4gICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICByYW5rOiAxLFxuICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIHN1cHBvcnRlZEZhY2V0czogWydjb250aW51b3VzJywgJ2R1cmF0aW9uJ11cbiAgICAgIH1cbiAgICBdKTtcbiAgfSxcbiAgc2NhdHRlckNvbmZpZzogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB7XG4gICAgICB3aWR0aDogJzYwMHB4JyxcbiAgICAgIGhlaWdodDogJzYwMHB4JyxcbiAgICAgIHN0eWxlOiAnZG90LWNvbG9yJyxcbiAgICAgIHRvb2x0aXA6IHRydWUsXG4gICAgICB0b29sdGlwU3R5bGU6IHtcbiAgICAgICAgZG90OiB7XG4gICAgICAgICAgYm9yZGVyOiAnbm9uZScsXG4gICAgICAgICAgYm9yZGVyUmFkaXVzOiAnMHB4J1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgc2hvd1BlcnNwZWN0aXZlOiB0cnVlLFxuICAgICAgc2hvd0dyaWQ6IHRydWUsXG4gICAgICBzaG93U2hhZG93OiBmYWxzZSxcbiAgICAgIHNob3dMZWdlbmQ6IGZhbHNlLFxuICAgICAga2VlcEFzcGVjdFJhdGlvOiBmYWxzZSxcbiAgICAgIHZlcnRpY2FsUmF0aW86IDFcbiAgICB9O1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQURBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBaEJBO0FBa0JBO0FBcERBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///37f6\n")},"3f86":function(module,exports,__webpack_require__){eval("// This app view is responsible for rendering all content that goes into\n// <html>. It's initted right away and renders itself on DOM ready.\nvar app = __webpack_require__(/*! ampersand-app */ \"fcbc\"); // var setFavicon = require('favicon-setter');\n\n\nvar View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar ViewSwitcher = __webpack_require__(/*! ampersand-view-switcher */ \"253d\");\n\nvar localLinks = __webpack_require__(/*! local-links */ \"a238\");\n\nvar domify = __webpack_require__(/*! domify */ \"2d1c\");\n\nvar templates = __webpack_require__(/*! ../templates */ \"4324\");\n\nfunction checkConnection(model) {\n  if (model.sessionType === 'server' && !model.isConnected) {\n    app.message({\n      text: 'Trying to connect to database ' + window.location.hostname,\n      type: 'error'\n    });\n  } // retry\n\n\n  window.setTimeout(function () {\n    checkConnection(model);\n  }, 4000);\n}\n/**\n * [exports description]\n * @module pages/main\n */\n\n\nmodule.exports = View.extend({\n  /**\n   * [template description]\n   * @type {any}\n   */\n  template: templates.main,\n  autoRender: true,\n  initialize: function initialize() {\n    this.pageName = 'main'; // this marks the correct nav item selected\n\n    this.listenTo(app, 'page', this.handleNewPage); // periodically check database connection\n\n    checkConnection(this.model);\n    this.model.on('change:isConnected', function () {\n      if (this.model.isConnected) {\n        app.message({\n          text: 'Connected to  ' + window.location.hostname,\n          type: 'ok'\n        });\n      }\n    }, this);\n  },\n  events: {\n    'click a[href]': 'handleLinkClick',\n    'click [data-hook~=help-button]': 'startHelp',\n    'click [data-hook~=menu-button]': 'handleMenu',\n    'click .mdl-menu__item': 'menuAction'\n  },\n  menuAction: function menuAction(item) {\n    var id = item.target.id;\n    console.log('pressed', id, 'button');\n    app.navigate(id); // switch(id) {\n    //   case 'home':\n    //     console.log('pressed home button');\n    //     app.navigate(id);\n    //     break;\n    //   case 'share':\n    //     console.log('pressed share button');\n    //     app.navigate(id);\n    //     break;\n    //   default:\n    //     // code block\n    // }\n  },\n  startHelp: function startHelp() {\n    app.startHelp();\n  },\n  render: function render() {\n    // some additional stuff we want to add to the document head\n    document.head.appendChild(domify(templates.head()));\n    document.title = 'Spot'; // main renderer\n\n    this.renderWithTemplate(this); // init and configure our page switcher\n\n    this.pageSwitcher = new ViewSwitcher(this.queryByHook('page-container'), {\n      show: function show(newView, oldView) {\n        document.scrollTop = 0; // store an additional reference, just because\n\n        app.currentPage = newView;\n      }\n    }); // setting a favicon for fun (note, it's dynamic)\n    // setFavicon('/favicon.ico');\n\n    return this;\n  },\n  handleNewPage: function handleNewPage(view) {\n    // tell the view switcher to render the new page\n    this.pageSwitcher.set(view); // update responsive layout (Material Design)\n\n    window.componentHandler.upgradeDom(); // second rendering pass; absolute sizes in pixels is now available for\n    // widgets that need them (ie. the SVG elements)\n\n    if (view.renderContent) {\n      view.renderContent();\n    }\n  },\n  // Handles all `<a>` clicks in the app not handled\n  // by another view. This lets us determine if this is\n  // a click that should be handled internally by the app.\n  handleLinkClick: function handleLinkClick(e) {\n    // This module determines whether a click event is\n    // a local click (making sure the for modifier keys, etc)\n    // and dealing with browser quirks to determine if this\n    // event was from clicking an internal link. That we should\n    // treat like local navigation.\n    var localPath = localLinks.pathname(e); // fixes navigation problem on Windows platform\n\n    if (navigator.platform === 'Win32') {\n      localPath = localPath.replace('/C:', '');\n    }\n\n    if (localPath) {\n      e.preventDefault();\n      app.navigate(localPath);\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiM2Y4Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9tYWluLmpzP2VhNjciXSwic291cmNlc0NvbnRlbnQiOlsiLy8gVGhpcyBhcHAgdmlldyBpcyByZXNwb25zaWJsZSBmb3IgcmVuZGVyaW5nIGFsbCBjb250ZW50IHRoYXQgZ29lcyBpbnRvXG4vLyA8aHRtbD4uIEl0J3MgaW5pdHRlZCByaWdodCBhd2F5IGFuZCByZW5kZXJzIGl0c2VsZiBvbiBET00gcmVhZHkuXG52YXIgYXBwID0gcmVxdWlyZSgnYW1wZXJzYW5kLWFwcCcpO1xuLy8gdmFyIHNldEZhdmljb24gPSByZXF1aXJlKCdmYXZpY29uLXNldHRlcicpO1xudmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIFZpZXdTd2l0Y2hlciA9IHJlcXVpcmUoJ2FtcGVyc2FuZC12aWV3LXN3aXRjaGVyJyk7XG52YXIgbG9jYWxMaW5rcyA9IHJlcXVpcmUoJ2xvY2FsLWxpbmtzJyk7XG52YXIgZG9taWZ5ID0gcmVxdWlyZSgnZG9taWZ5Jyk7XG52YXIgdGVtcGxhdGVzID0gcmVxdWlyZSgnLi4vdGVtcGxhdGVzJyk7XG5cbmZ1bmN0aW9uIGNoZWNrQ29ubmVjdGlvbiAobW9kZWwpIHtcbiAgaWYgKG1vZGVsLnNlc3Npb25UeXBlID09PSAnc2VydmVyJyAmJiAhbW9kZWwuaXNDb25uZWN0ZWQpIHtcbiAgICBhcHAubWVzc2FnZSh7XG4gICAgICB0ZXh0OiAnVHJ5aW5nIHRvIGNvbm5lY3QgdG8gZGF0YWJhc2UgJyArIHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSxcbiAgICAgIHR5cGU6ICdlcnJvcidcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHJldHJ5XG4gIHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBjaGVja0Nvbm5lY3Rpb24obW9kZWwpO1xuICB9LCA0MDAwKTtcbn1cblxuLyoqXG4gKiBbZXhwb3J0cyBkZXNjcmlwdGlvbl1cbiAqIEBtb2R1bGUgcGFnZXMvbWFpblxuICovXG5tb2R1bGUuZXhwb3J0cyA9IFZpZXcuZXh0ZW5kKHtcbiAgLyoqXG4gICAqIFt0ZW1wbGF0ZSBkZXNjcmlwdGlvbl1cbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMubWFpbixcbiAgYXV0b1JlbmRlcjogdHJ1ZSxcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucGFnZU5hbWUgPSAnbWFpbic7XG4gICAgLy8gdGhpcyBtYXJrcyB0aGUgY29ycmVjdCBuYXYgaXRlbSBzZWxlY3RlZFxuICAgIHRoaXMubGlzdGVuVG8oYXBwLCAncGFnZScsIHRoaXMuaGFuZGxlTmV3UGFnZSk7XG5cbiAgICAvLyBwZXJpb2RpY2FsbHkgY2hlY2sgZGF0YWJhc2UgY29ubmVjdGlvblxuICAgIGNoZWNrQ29ubmVjdGlvbih0aGlzLm1vZGVsKTtcblxuICAgIHRoaXMubW9kZWwub24oJ2NoYW5nZTppc0Nvbm5lY3RlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICh0aGlzLm1vZGVsLmlzQ29ubmVjdGVkKSB7XG4gICAgICAgIGFwcC5tZXNzYWdlKHtcbiAgICAgICAgICB0ZXh0OiAnQ29ubmVjdGVkIHRvICAnICsgd2luZG93LmxvY2F0aW9uLmhvc3RuYW1lLFxuICAgICAgICAgIHR5cGU6ICdvaydcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSwgdGhpcyk7XG4gIH0sXG4gIGV2ZW50czoge1xuICAgICdjbGljayBhW2hyZWZdJzogJ2hhbmRsZUxpbmtDbGljaycsXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWhlbHAtYnV0dG9uXSc6ICdzdGFydEhlbHAnLFxuICAgICdjbGljayBbZGF0YS1ob29rfj1tZW51LWJ1dHRvbl0nOiAnaGFuZGxlTWVudScsXG4gICAgJ2NsaWNrIC5tZGwtbWVudV9faXRlbSc6ICdtZW51QWN0aW9uJ1xuICB9LFxuICBtZW51QWN0aW9uOiBmdW5jdGlvbihpdGVtKXtcbiAgICB2YXIgaWQgPSBpdGVtLnRhcmdldC5pZDtcbiAgICBjb25zb2xlLmxvZygncHJlc3NlZCcsIGlkLCAnYnV0dG9uJyk7XG4gICAgYXBwLm5hdmlnYXRlKGlkKTtcbiAgICAvLyBzd2l0Y2goaWQpIHtcbiAgICAvLyAgIGNhc2UgJ2hvbWUnOlxuICAgIC8vICAgICBjb25zb2xlLmxvZygncHJlc3NlZCBob21lIGJ1dHRvbicpO1xuICAgIC8vICAgICBhcHAubmF2aWdhdGUoaWQpO1xuICAgIC8vICAgICBicmVhaztcbiAgICAvLyAgIGNhc2UgJ3NoYXJlJzpcbiAgICAvLyAgICAgY29uc29sZS5sb2coJ3ByZXNzZWQgc2hhcmUgYnV0dG9uJyk7XG4gICAgLy8gICAgIGFwcC5uYXZpZ2F0ZShpZCk7XG4gICAgLy8gICAgIGJyZWFrO1xuICAgIC8vICAgZGVmYXVsdDpcbiAgICAvLyAgICAgLy8gY29kZSBibG9ja1xuICAgIC8vIH1cbiAgfSwgIFxuICBzdGFydEhlbHA6IGZ1bmN0aW9uICgpIHtcbiAgICBhcHAuc3RhcnRIZWxwKCk7XG4gIH0sXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgIC8vIHNvbWUgYWRkaXRpb25hbCBzdHVmZiB3ZSB3YW50IHRvIGFkZCB0byB0aGUgZG9jdW1lbnQgaGVhZFxuICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoZG9taWZ5KHRlbXBsYXRlcy5oZWFkKCkpKTtcbiAgICBkb2N1bWVudC50aXRsZSA9ICdTcG90JztcblxuICAgIC8vIG1haW4gcmVuZGVyZXJcbiAgICB0aGlzLnJlbmRlcldpdGhUZW1wbGF0ZSh0aGlzKTtcblxuICAgIC8vIGluaXQgYW5kIGNvbmZpZ3VyZSBvdXIgcGFnZSBzd2l0Y2hlclxuICAgIHRoaXMucGFnZVN3aXRjaGVyID0gbmV3IFZpZXdTd2l0Y2hlcih0aGlzLnF1ZXJ5QnlIb29rKCdwYWdlLWNvbnRhaW5lcicpLCB7XG4gICAgICBzaG93OiBmdW5jdGlvbiAobmV3Vmlldywgb2xkVmlldykge1xuICAgICAgICBkb2N1bWVudC5zY3JvbGxUb3AgPSAwO1xuXG4gICAgICAgIC8vIHN0b3JlIGFuIGFkZGl0aW9uYWwgcmVmZXJlbmNlLCBqdXN0IGJlY2F1c2VcbiAgICAgICAgYXBwLmN1cnJlbnRQYWdlID0gbmV3VmlldztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIHNldHRpbmcgYSBmYXZpY29uIGZvciBmdW4gKG5vdGUsIGl0J3MgZHluYW1pYylcbiAgICAvLyBzZXRGYXZpY29uKCcvZmF2aWNvbi5pY28nKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBoYW5kbGVOZXdQYWdlOiBmdW5jdGlvbiAodmlldykge1xuICAgIC8vIHRlbGwgdGhlIHZpZXcgc3dpdGNoZXIgdG8gcmVuZGVyIHRoZSBuZXcgcGFnZVxuICAgIHRoaXMucGFnZVN3aXRjaGVyLnNldCh2aWV3KTtcblxuICAgIC8vIHVwZGF0ZSByZXNwb25zaXZlIGxheW91dCAoTWF0ZXJpYWwgRGVzaWduKVxuICAgIHdpbmRvdy5jb21wb25lbnRIYW5kbGVyLnVwZ3JhZGVEb20oKTtcblxuICAgIC8vIHNlY29uZCByZW5kZXJpbmcgcGFzczsgYWJzb2x1dGUgc2l6ZXMgaW4gcGl4ZWxzIGlzIG5vdyBhdmFpbGFibGUgZm9yXG4gICAgLy8gd2lkZ2V0cyB0aGF0IG5lZWQgdGhlbSAoaWUuIHRoZSBTVkcgZWxlbWVudHMpXG4gICAgaWYgKHZpZXcucmVuZGVyQ29udGVudCkge1xuICAgICAgdmlldy5yZW5kZXJDb250ZW50KCk7XG4gICAgfVxuICB9LFxuICAvLyBIYW5kbGVzIGFsbCBgPGE+YCBjbGlja3MgaW4gdGhlIGFwcCBub3QgaGFuZGxlZFxuICAvLyBieSBhbm90aGVyIHZpZXcuIFRoaXMgbGV0cyB1cyBkZXRlcm1pbmUgaWYgdGhpcyBpc1xuICAvLyBhIGNsaWNrIHRoYXQgc2hvdWxkIGJlIGhhbmRsZWQgaW50ZXJuYWxseSBieSB0aGUgYXBwLlxuICBoYW5kbGVMaW5rQ2xpY2s6IGZ1bmN0aW9uIChlKSB7XG4gICAgLy8gVGhpcyBtb2R1bGUgZGV0ZXJtaW5lcyB3aGV0aGVyIGEgY2xpY2sgZXZlbnQgaXNcbiAgICAvLyBhIGxvY2FsIGNsaWNrIChtYWtpbmcgc3VyZSB0aGUgZm9yIG1vZGlmaWVyIGtleXMsIGV0YylcbiAgICAvLyBhbmQgZGVhbGluZyB3aXRoIGJyb3dzZXIgcXVpcmtzIHRvIGRldGVybWluZSBpZiB0aGlzXG4gICAgLy8gZXZlbnQgd2FzIGZyb20gY2xpY2tpbmcgYW4gaW50ZXJuYWwgbGluay4gVGhhdCB3ZSBzaG91bGRcbiAgICAvLyB0cmVhdCBsaWtlIGxvY2FsIG5hdmlnYXRpb24uXG4gICAgdmFyIGxvY2FsUGF0aCA9IGxvY2FsTGlua3MucGF0aG5hbWUoZSk7XG5cbiAgICAvLyBmaXhlcyBuYXZpZ2F0aW9uIHByb2JsZW0gb24gV2luZG93cyBwbGF0Zm9ybVxuICAgIGlmIChuYXZpZ2F0b3IucGxhdGZvcm0gPT09ICdXaW4zMicpIHtcbiAgICAgIGxvY2FsUGF0aCA9IGxvY2FsUGF0aC5yZXBsYWNlKCcvQzonLCAnJyk7XG4gICAgfVxuXG4gICAgaWYgKGxvY2FsUGF0aCkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgYXBwLm5hdmlnYXRlKGxvY2FsUGF0aCk7XG4gICAgfVxuICB9XG5cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOzs7Ozs7QUFJQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFKQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFOQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUdBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUExR0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3f86\n")},4324:function(module,exports,__webpack_require__){eval('var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\n;\n\n(function (root, factory) {\n  if (true) {\n    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === \'function\' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n  } else {}\n})(this, function () {\n  function pug_classes_object(val) {\n    var classString = \'\',\n        padding = \'\';\n\n    for (var key in val) {\n      if (key && val[key] && pug_has_own_property.call(val, key)) {\n        var classString = classString + padding + key;\n        var padding = \' \';\n      }\n    }\n\n    return classString;\n  }\n\n  function pug_classes_array(val, escaping) {\n    var classString = \'\',\n        className,\n        padding = \'\',\n        escapeEnabled = Array.isArray(escaping);\n\n    for (var i = 0; i < val.length; i++) {\n      var className = pug_classes(val[i]);\n      if (!className) continue;\n      escapeEnabled && escaping[i] && (className = pug_escape(className));\n      var classString = classString + padding + className;\n      var padding = \' \';\n    }\n\n    return classString;\n  }\n\n  function pug_merge(e, r) {\n    if (1 === arguments.length) {\n      for (var t = e[0], g = 1; g < e.length; g++) {\n        t = pug_merge(t, e[g]);\n      }\n\n      return t;\n    }\n\n    for (var n in r) {\n      if ("class" === n) {\n        var a = e[n] || [];\n        e[n] = (Array.isArray(a) ? a : [a]).concat(r[n] || []);\n      } else if ("style" === n) {\n        var a = pug_style(e[n]);\n        a = a && ";" !== a[a.length - 1] ? a + ";" : a;\n        var l = pug_style(r[n]);\n        l = l && ";" !== l[l.length - 1] ? l + ";" : l, e[n] = a + l;\n      } else e[n] = r[n];\n    }\n\n    return e;\n  }\n\n  function pug_classes(s, r) {\n    return Array.isArray(s) ? pug_classes_array(s, r) : s && "object" == _typeof(s) ? pug_classes_object(s) : s || "";\n  }\n\n  function pug_style(r) {\n    if (!r) return "";\n\n    if ("object" == _typeof(r)) {\n      var t = "";\n\n      for (var e in r) {\n        pug_has_own_property.call(r, e) && (t = t + e + ":" + r[e] + ";");\n      }\n\n      return t;\n    }\n\n    return r + "";\n  }\n\n  function pug_attr(t, e, n, f) {\n    return e !== !1 && null != e && (e || "class" !== t && "style" !== t) ? e === !0 ? " " + (f ? t : t + \'="\' + t + \'"\') : ("function" == typeof e.toJSON && (e = e.toJSON()), "string" == typeof e || (e = JSON.stringify(e), n || -1 === e.indexOf(\'"\')) ? (n && (e = pug_escape(e)), " " + t + \'="\' + e + \'"\') : " " + t + "=\'" + e.replace(/\'/g, "&#39;") + "\'") : "";\n  }\n\n  function pug_attrs(t, r) {\n    var a = "";\n\n    for (var s in t) {\n      if (pug_has_own_property.call(t, s)) {\n        var u = t[s];\n\n        if ("class" === s) {\n          u = pug_classes(u), a = pug_attr(s, u, !1, r) + a;\n          continue;\n        }\n\n        "style" === s && (u = pug_style(u)), a += pug_attr(s, u, !1, r);\n      }\n    }\n\n    return a;\n  }\n\n  function pug_escape(e) {\n    var a = "" + e,\n        t = /["&<>]/.exec(a);\n    if (!t) return e;\n    var r,\n        c,\n        n,\n        s = "";\n\n    for (r = t.index, c = 0; r < a.length; r++) {\n      switch (a.charCodeAt(r)) {\n        case 34:\n          n = "&quot;";\n          break;\n\n        case 38:\n          n = "&amp;";\n          break;\n\n        case 60:\n          n = "&lt;";\n          break;\n\n        case 62:\n          n = "&gt;";\n          break;\n\n        default:\n          continue;\n      }\n\n      c !== r && (s += a.substring(c, r)), c = r + 1, s += n;\n    }\n\n    return c !== r ? s + a.substring(c, r) : s;\n  }\n\n  function pug_rethrow(n, e, r, t) {\n    if (!(n instanceof Error)) throw n;\n    if (!("undefined" == typeof window && e || t)) throw n.message += " on line " + r, n;\n\n    try {\n      t = t || __webpack_require__(/*! fs */ "9412").readFileSync(e, "utf8");\n    } catch (i) {\n      pug_rethrow(n, null, r);\n    }\n\n    var a = 3,\n        o = t.split("\\n"),\n        h = Math.max(r - a, 0),\n        s = Math.min(o.length, r + a),\n        a = o.slice(h, s).map(function (n, e) {\n      var t = e + h + 1;\n      return (t == r ? "  > " : "    ") + t + "| " + n;\n    }).join("\\n");\n    throw n.path = e, n.message = (e || "Pug") + ":" + r + "\\n" + a + "\\n\\n" + n.message, n;\n  }\n\n  var pug = {\n    merge: function pug_merge(e, r) {\n      if (1 === arguments.length) {\n        for (var t = e[0], g = 1; g < e.length; g++) {\n          t = pug_merge(t, e[g]);\n        }\n\n        return t;\n      }\n\n      for (var n in r) {\n        if ("class" === n) {\n          var a = e[n] || [];\n          e[n] = (Array.isArray(a) ? a : [a]).concat(r[n] || []);\n        } else if ("style" === n) {\n          var a = pug_style(e[n]);\n          a = a && ";" !== a[a.length - 1] ? a + ";" : a;\n          var l = pug_style(r[n]);\n          l = l && ";" !== l[l.length - 1] ? l + ";" : l, e[n] = a + l;\n        } else e[n] = r[n];\n      }\n\n      return e;\n    },\n    classes: function pug_classes(s, r) {\n      return Array.isArray(s) ? pug_classes_array(s, r) : s && "object" == _typeof(s) ? pug_classes_object(s) : s || "";\n    },\n    style: function pug_style(r) {\n      if (!r) return "";\n\n      if ("object" == _typeof(r)) {\n        var t = "";\n\n        for (var e in r) {\n          pug_has_own_property.call(r, e) && (t = t + e + ":" + r[e] + ";");\n        }\n\n        return t;\n      }\n\n      return r + "";\n    },\n    attr: function pug_attr(t, e, n, f) {\n      return e !== !1 && null != e && (e || "class" !== t && "style" !== t) ? e === !0 ? " " + (f ? t : t + \'="\' + t + \'"\') : ("function" == typeof e.toJSON && (e = e.toJSON()), "string" == typeof e || (e = JSON.stringify(e), n || -1 === e.indexOf(\'"\')) ? (n && (e = pug_escape(e)), " " + t + \'="\' + e + \'"\') : " " + t + "=\'" + e.replace(/\'/g, "&#39;") + "\'") : "";\n    },\n    attrs: function pug_attrs(t, r) {\n      var a = "";\n\n      for (var s in t) {\n        if (pug_has_own_property.call(t, s)) {\n          var u = t[s];\n\n          if ("class" === s) {\n            u = pug_classes(u), a = pug_attr(s, u, !1, r) + a;\n            continue;\n          }\n\n          "style" === s && (u = pug_style(u)), a += pug_attr(s, u, !1, r);\n        }\n      }\n\n      return a;\n    },\n    escape: function pug_escape(e) {\n      var a = "" + e,\n          t = /["&<>]/.exec(a);\n      if (!t) return e;\n      var r,\n          c,\n          n,\n          s = "";\n\n      for (r = t.index, c = 0; r < a.length; r++) {\n        switch (a.charCodeAt(r)) {\n          case 34:\n            n = "&quot;";\n            break;\n\n          case 38:\n            n = "&amp;";\n            break;\n\n          case 60:\n            n = "&lt;";\n            break;\n\n          case 62:\n            n = "&gt;";\n            break;\n\n          default:\n            continue;\n        }\n\n        c !== r && (s += a.substring(c, r)), c = r + 1, s += n;\n      }\n\n      return c !== r ? s + a.substring(c, r) : s;\n    },\n    rethrow: function pug_rethrow(n, e, r, t) {\n      if (!(n instanceof Error)) throw n;\n      if (!("undefined" == typeof window && e || t)) throw n.message += " on line " + r, n;\n\n      try {\n        t = t || __webpack_require__(/*! fs */ "9412").readFileSync(e, "utf8");\n      } catch (i) {\n        pug_rethrow(n, null, r);\n      }\n\n      var a = 3,\n          o = t.split("\\n"),\n          h = Math.max(r - a, 0),\n          s = Math.min(o.length, r + a),\n          a = o.slice(h, s).map(function (n, e) {\n        var t = e + h + 1;\n        return (t == r ? "  > " : "    ") + t + "| " + n;\n      }).join("\\n");\n      throw n.path = e, n.message = (e || "Pug") + ":" + r + "\\n" + a + "\\n\\n" + n.message, n;\n    }\n  };\n  var puglatizer = {};\n  puglatizer["analyze"] = {};\n\n  puglatizer["analyze"]["facetbarItem"] = function template(a) {\n    var t,\n        e,\n        c = "";\n\n    try {\n      e = 1, c += \'<span class="mdl-chip variableChip" data-hook="facet-bar-item" id="">\', e = 2, c += \'<span class="mdl-chip__text" data-hook="facet-bar-item-button"></span></span>\';\n    } catch (p) {\n      pug.rethrow(p, t, e);\n    }\n\n    return c;\n  };\n\n  puglatizer["analyze"]["page"] = function template(t) {\n    var a,\n        o,\n        l = "";\n\n    try {\n      o = 1, l += \'<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">\', o = 2, l += \'<main class="mdl-layout__content" style="background-color: white;">\', o = 3, l += \'<header class="demo-header mdl-layout__header spot-color-top-bar mdl-color-text--grey-600">\', o = 5, l += \'<div class="mdl-layout__header-row">\', o = 6, l += \'<span class="mdl-layout-title unselectable">\', o = 6, l += "Analyze</span>", o = 8, l += \'<div class="mdl-layout-spacer"></div>\', o = 10, l += \'<span class="unselectable" data-hook="data-string"></span>\', o = 12, l += \'<div class="mdl-layout-spacer"></div>\', o = 14, l += \'<span data-position="bottom" data-step="0" data-hint=""></span>\', o = 16, l += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" id="saveSessionButton" data-hintPosition="bottom" data-position="bottom" data-hint="This buttons saves the current session.">\', o = 17, l += \'<i class="material-icons">\', o = 17, l += "save</i></button>", o = 18, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="saveSessionButton">\', o = 19, l += "Save the session</div>", o = 21, l += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" id="resetFiltersButton" data-position="bottom" data-step="1" data-hint="This button clears all existing filters.">\', o = 22, l += \'<i class="material-icons">\', o = 22, l += "clear_all</i></button>", o = 23, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="resetFiltersButton">\', o = 24, l += "Clear all filters of all plots</div>", o = 26, l += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" id="viewAll" data-position="bottom" data-step="2" data-hint="This button closes all configuration windows">\', o = 27, l += \'<i class="material-icons">\', o = 27, l += "crop_original</i></button>", o = 28, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="viewAll">\', o = 29, l += "Close all configuration windows</div>", o = 31, l += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" id="fullscreenButton" data-position="bottom" data-step="3" data-hint="This button hides facet and chart bars.">\', o = 32, l += \'<i class="material-icons">\', o = 32, l += "fullscreen</i></button>", o = 33, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="fullscreenButton">\', o = 34, l += "Show or hide chart and facet bars</div></div>", o = 36, l += \'<div class="chartBar spot-color-top-bar mdl-color-text--grey-600" data-hook="chart-bar" data-position="bottom" data-step="4" data-hint="These are the available chart types. If you want to add a chart, just &lt;b&gt;click&lt;/b&gt; on its icon and it will be created! Simple, right? ">\', o = 37, l += \'<span class="chartBarText">\', o = 37, l += "Click on a chart icon to start a new plot</span>", o = 39, l += \'<div class="mdl-cell mdl-cell--12-col horizontalbarchartIcon widgetIcon" data-hook="horizontalbarchart" id="horizontalbarchart" data-position="bottom" data-step="5" data-hint="This adds a horizontal bar chart(histogram). This is good for categorical facets."></div>\', o = 40, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="horizontalbarchart">\', o = 41, l += "Click to add a horizontal bar chart</div>", o = 43, l += \'<div class="mdl-cell mdl-cell--12-col barchartIcon widgetIcon" data-hook="barchart" id="barchart" data-position="bottom" data-step="6" data-hint="This adds a vertical bar chart."></div>\', o = 44, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="barchart">\', o = 45, l += "Click to add a bar chart</div>", o = 47, l += \'<div class="mdl-cell mdl-cell--12-col linechartIcon widgetIcon" data-hook="linechart" id="linechart" data-position="bottom" data-step="7" data-hint="This adds a line chart."></div>\', o = 48, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="linechart">\', o = 49, l += "Click to add a line chart</div>", o = 51, l += \'<div class="mdl-cell mdl-cell--12-col piechartIcon widgetIcon" data-hook="piechart" id="piechart" data-position="bottom" data-step="8" data-hint="This adds a pie chart."></div>\', o = 52, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="piechart">\', o = 53, l += "Click to add a pie chart</div>", o = 55, l += \'<div class="mdl-cell mdl-cell--12-col bubbleplotIcon widgetIcon" data-hook="bubbleplot" id="bubbleplot" data-position="bottom" data-step="9" data-hint="This adds a buble chart."></div>\', o = 56, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="bubbleplot">\', o = 57, l += "Click to add a bubbleplot chart</div>", o = 59, l += \'<div class="mdl-cell mdl-cell--12-col scatterchartIcon widgetIcon" data-hook="scatterchart" id="scatterchart" data-position="bottom" data-step="10" data-hint="This adds a 3D scatter chart."></div>\', o = 60, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="scatterchart">\', o = 61, l += "Click to add a 3d scatter chart</div>", o = 63, l += \'<div class="mdl-cell mdl-cell--12-col radarchartIcon widgetIcon" data-hook="radarchart" id="radarchart" data-position="bottom" data-step="11" data-hint="This adds a radar chart."></div>\', o = 64, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="radarchart">\', o = 65, l += "Click to add a radar chart</div>", o = 67, l += \'<div class="mdl-cell mdl-cell--12-col networkchartIcon widgetIcon" data-hook="networkchart" id="networkchart" data-position="bottom" data-step="12" data-hint="This adds a network chart."></div>\', o = 68, l += \'<div class="mdl-tooltip mdl-tooltip--large" for="networkchart">\', o = 69, l += "Click to add a network chart</div></div>", o = 71, l += \'<div class="facetBar spot-color-top-bar" data-hook="facet-bar" id="facet-bar" data-position="bottom" data-step="13" data-hint="This is where you will have your variables(facets). Just &lt;b&gt;drag and drop&lt;/b&gt; these facets to field of the charts to visualize.">\', o = 72, l += \'<span class="facetBarText">\', o = 72, l += "Drop variable on a chart, or click to edit</span>", o = 73, l += \'<div class="facetBarItems" data-hook="facet-bar-items" id="facetBar"></div></div>\', o = 74, l += \'<div class="mdl-tooltip mdl-tooltip--large" id="facet-bar-tooltip" for="facet-bar">\', o = 75, l += "Drop variable on a chart, or click to edit</div></header>", o = 77, l += \'<div class="widgetDropZone" id="widgets" data-hook="widgets"></div></main></div>\';\n    } catch (i) {\n      pug.rethrow(i, a, o);\n    }\n\n    return l;\n  };\n\n  puglatizer["analyze"]["slot"] = function template(t) {\n    var o,\n        a,\n        d = "";\n\n    try {\n      a = 1, d += \'<div class="slot mdl-shadow--2dp" data-hook="slot">\', a = 2, d += \'<div class="slotText clickTarget">\', a = 3, d += \'<b data-hook="description"></b>\', a = 4, d += "<br/>", a = 5, d += \'<i data-hook="required"></i></div>\', a = 6, d += \'<div class="slotChip clickTarget" data-hook="drop-zone">\', a = 7, d += \'<span data-hook="chip-text"></span></div>\', a = 8, d += \'<div class="slotButton" data-hook="button-div">\', a = 9, d += \'<button class="mdl-button mdl-js-button mdl-button--icon" data-hook="delete">\', a = 10, d += \'<i class="material-icons">\', a = 10, d += "delete</i></button></div></div>";\n    } catch (i) {\n      pug.rethrow(i, o, a);\n    }\n\n    return d;\n  };\n\n  puglatizer["analyze"]["widgetFrame"] = function template(t) {\n    var o,\n        l,\n        i = "";\n\n    try {\n      l = 1, i += \'<div class="widgetFrame mdl-color--white mdl-shadow--2dp">\', l = 3, i += \'<div class="configView" data-hook="config-view">\', l = 4, i += \'<div class="widgetDragBar">\', l = 5, i += \'<button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" data-hook="close" id="chartDeleteButton2">\', l = 6, i += \'<i class="material-icons">\', l = 6, i += "delete</i></button>", l = 7, i += \'<div class="mdl-tooltip mdl-tooltip--large" for="chartDeleteButton2">\', l = 8, i += "Delete this chart</div>", l = 9, i += \'<span class="widgetHeader" data-hook="widgetHeader"></span>\', l = 10, i += \'<div class="mdl-layout-spacer"></div>\', l = 11, i += \'<button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" data-hook="edit" style="float: right" id="chartDoneButton">\', l = 12, i += \'<i class="material-icons">\', l = 12, i += "done</i></button>", l = 13, i += \'<div class="mdl-tooltip mdl-tooltip--large" for="chartDoneButton">\', l = 14, i += "Close configuration view</div></div>", l = 16, i += \'<div class="slots" data-hook="slots"></div></div>\', l = 18, i += \'<div class="widgetView" data-hook="widget"></div>\', l = 20, i += \'<div class="plotMenu" data-hook="plot-menu" style="width: 100%;">\', l = 21, i += \'<div class="widgetDragBar">\', l = 22, i += \'<button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" data-hook="close" id="chartDeleteButton1">\', l = 23, i += \'<i class="material-icons">\', l = 23, i += "delete</i></button>", l = 24, i += \'<div class="mdl-tooltip mdl-tooltip--large" for="chartDeleteButton1">\', l = 25, i += "Delete this chart</div>", l = 26, i += \'<button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" data-hook="zoom-out" id="chartUndoButton">\', l = 27, i += \'<i class="material-icons">\', l = 27, i += "undo</i></button>", l = 28, i += \'<div class="mdl-tooltip mdl-tooltip--large" for="chartUndoButton">\', l = 29, i += "Undo selection</div>", l = 30, i += \'<button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" data-hook="zoom-in" id="chartZoomButton">\', l = 31, i += \'<i class="material-icons">\', l = 31, i += "zoom_in</i></button>", l = 32, i += \'<div class="mdl-tooltip mdl-tooltip--large" for="chartZoomButton">\', l = 33, i += "Zoom into selected region</div>", l = 34, i += \'<button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" data-hook="save" id="chartSave">\', l = 35, i += \'<i class="material-icons">\', l = 35, i += "save</i></button>", l = 36, i += \'<div class="mdl-tooltip mdl-tooltip--large" for="chartSave">\', l = 37, i += "Save this chart</div>", l = 38, i += \'<div class="mdl-layout-spacer"></div>\', l = 39, i += \'<button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" data-hook="edit" style="float: right;" id="chartConfButton">\', l = 40, i += \'<i class="material-icons">\', l = 40, i += "create</i></button>", l = 41, i += \'<div class="mdl-tooltip mdl-tooltip--large" for="chartConfButton">\', l = 42, i += "Open configuration view</div></div></div></div>";\n    } catch (a) {\n      pug.rethrow(a, o, l);\n    }\n\n    return i;\n  };\n\n  puglatizer["configureDataset"] = {};\n\n  puglatizer["configureDataset"]["facet"] = function template(t) {\n    var l,\n        a,\n        d = "";\n\n    try {\n      a = 1, d += \'<div class="mdl-card mdl-shadow--2dp" data-hook="fullitem" style="min-height: inherit">\', a = 2, d += \'<div class="mdl-card__title">\', a = 3, d += \'<h2 class="mdl-card__title-text" data-hook="name"></h2></div>\', a = 5, d += \'<div class="mdl-card__supporting-text" data-hook="description"></div>\', a = 7, d += \'<div class="mdl-card__actions mdl-card--border" data-hook="actions">\', a = 8, d += \'<button class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect unselectable" data-hook="removeFacet">\', a = 9, d += "Delete</button>", a = 10, d += \'<button class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect unselectable" data-hook="duplicateFacet">\', a = 11, d += "Copy </button>", a = 12, d += \'<button class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect unselectable" data-hook="configureFacet" style="float: right">\', a = 13, d += \'<i class="material-icons">\', a = 13, d += "settings</i></button></div>", a = 15, d += \'<div class="mdl-card__menu">\', a = 16, d += "<span>", a = 17, d += \'<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" data-hook="cblabel" for="">\', a = 18, d += \'<input class="mdl-switch__input" data-hook="cb" type="checkbox" id=""/></label>\', a = 19, d += \'<span class="mdl-switch__label"></span></span></div></div>\';\n    } catch (e) {\n      pug.rethrow(e, l, a);\n    }\n\n    return d;\n  };\n\n  puglatizer["configureDataset"]["page"] = function template(t) {\n    var l,\n        a,\n        d = "";\n\n    try {\n      a = 1, d += \'<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">\', a = 2, d += \'<main class="mdl-layout__content" style="background-color: white;">\', a = 3, d += \'<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">\', a = 4, d += \'<header class="demo-header mdl-layout__header mdl-color--grey-100 mdl-color-text--grey-600">\', a = 5, d += \'<div class="mdl-layout__header-row">\', a = 6, d += \'<span class="mdl-layout-title">\', a = 6, d += "Configure dataset</span>", a = 8, d += \'<div class="mdl-layout-spacer"></div>\', a = 10, d += \'<span class="unselectable" data-hook="data-string">\', a = 11, d += "Select and configure facets</span>", a = 13, d += \'<div class="mdl-layout-spacer"></div>\', a = 15, d += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" data-hook="enable-all-button" id="eab">\', a = 16, d += \'<i class="material-icons">\', a = 16, d += "check_box</i></button>", a = 17, d += \'<div class="mdl-tooltip mdl-tooltip--large" for="eab">\', a = 18, d += "Enable all facets</div>", a = 20, d += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" data-hook="disable-all-button" id="dab">\', a = 21, d += \'<i class="material-icons">\', a = 21, d += "check_box_outline_blank</i></button>", a = 22, d += \'<div class="mdl-tooltip mdl-tooltip--large" for="dab">\', a = 23, d += "Disable all facets</div>", a = 25, d += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" data-hook="add-button" id="tt2">\', a = 26, d += \'<i class="material-icons">\', a = 26, d += "add</i></button>", a = 27, d += \'<div class="mdl-tooltip mdl-tooltip--large" for="tt2">\', a = 28, d += "Add a new facet</div>", a = 30, d += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" data-hook="rescan-button" id="tt1">\', a = 31, d += \'<i class="material-icons">\', a = 31, d += "autorenew</i></button>", a = 32, d += \'<div class="mdl-tooltip mdl-tooltip--large" for="tt1">\', a = 33, d += "Analyze data and autoconfigure facets</div>", a = 35, d += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" data-hook="search-button" id="tt3">\', a = 36, d += \'<i class="material-icons">\', a = 36, d += "search</i></button>", a = 37, d += \'<div class="mdl-tooltip mdl-tooltip--large" for="tt3">\', a = 38, d += "Show or hide search bar</div></div>", a = 40, d += \'<div class="mdl-layout__header-row" data-hook="search-bar">\', a = 41, d += \'<div class="mdl-layout-spacer"></div>\', a = 42, d += \'<span class="mdl-color--white mdl-color-text--primary searchBar">\', a = 44, d += \'<span class="mdl-textfield searchBar">\', a = 45, d += \'<input class="mdl-textfield__input searchBar" data-hook="facet-selector" type="text" id="tt5"/>\', a = 46, d += \'<div class="mdl-tooltip mdl-tooltip--large" for="tt5">\', a = 47, d += "Search facet name and description</div></span>", a = 49, d += "<span>", a = 50, d += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" data-hook="clear-button" id="tt4">\', a = 51, d += \'<i class="material-icons">\', a = 51, d += "close</i></button>", a = 52, d += \'<div class="mdl-tooltip mdl-tooltip--large" for="tt4">\', a = 53, d += "Clear search</div></span></span>", a = 54, d += \'<div class="mdl-layout-spacer"></div></div></header>\', a = 56, d += \'<div data-hook="widgets">\', a = 58, d += \'<div class="mdl-grid">\', a = 59, d += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--4-col">\', a = 60, d += \'<input class="mdl-textfield__input" type="text" id="name"/>\', a = 61, d += \'<label class="mdl-textfield__label" for="name">\', a = 62, d += "Dataset name</label></div>", a = 64, d += \'<div class="mdl-textfield mdl-js-textfield mdl-cell mdl-cell mdl-cell--7-col">\', a = 65, d += \'<textarea class="mdl-textfield__input" type="text" rows="3" id="description"></textarea>\', a = 66, d += \'<label class="mdl-textfield__label" for="description">\', a = 67, d += "Dataset description</label></div></div>", a = 69, d += \'<div class="mdl-grid" data-hook="facet-list"></div></div></div></main></div>\';\n    } catch (e) {\n      pug.rethrow(e, l, a);\n    }\n\n    return d;\n  };\n\n  puglatizer["configureFacet"] = {};\n\n  puglatizer["configureFacet"]["categorialRule"] = function template(t) {\n    var e,\n        o,\n        a = "";\n\n    try {\n      o = 1, a += "<tr>", o = 2, a += "<td>", o = 3, a += \'<input class="mdl-textfield__input" data-hook="category-expression-input" type="text"/></td>\', o = 4, a += "<td>", o = 5, a += \'<input class="mdl-textfield__input" data-hook="category-group-input" type="text"/></td>\', o = 6, a += \'<td data-hook="category-value-count"></td>\', o = 7, a += "<td>", o = 8, a += \'<button class="mdl-button mdl-js-button mdl-js-ripple-effect" data-hook="category-remove">\', o = 9, a += \'<i class="material-icons">\', o = 9, a += "remove</i></button></td></tr>";\n    } catch (d) {\n      pug.rethrow(d, e, o);\n    }\n\n    return a;\n  };\n\n  puglatizer["configureFacet"]["categorialtransform"] = function template(t) {\n    var r,\n        e,\n        a = "";\n\n    try {} catch (c) {\n      pug.rethrow(c, r, e);\n    }\n\n    return a;\n  };\n\n  puglatizer["configureFacet"]["continuousRule"] = function template(t) {\n    var o,\n        e,\n        n = "";\n\n    try {\n      e = 1, n += "<tr>", e = 2, n += "<td>", e = 3, n += \'<input class="mdl-textfield__input" data-hook="continuous-x-input" type="text"/></td>\', e = 4, n += "<td>", e = 5, n += \'<input class="mdl-textfield__input" data-hook="continuous-fx-input" type="text"/></td>\', e = 6, n += "<td>", e = 7, n += \'<button class="mdl-button mdl-js-button mdl-js-ripple-effect" data-hook="continuous-remove">\', e = 8, n += \'<i class="material-icons">\', e = 8, n += "remove</i></button></td></tr>";\n    } catch (u) {\n      pug.rethrow(u, o, e);\n    }\n\n    return n;\n  };\n\n  puglatizer["configureFacet"]["facetDefine"] = function template(l) {\n    var e,\n        d,\n        i = "";\n\n    try {\n      d = 1, i += \'<div class="mdl-grid">\', d = 2, i += \'<div class="mdl-cell mdl-cell--12-col mdl-grid">\', d = 3, i += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetInfoIcon"></div>\', d = 4, i += \'<div class="mdl-cell mdl-cell--1-col"></div>\', d = 5, i += \'<div class="mdl-cell mdl-cell--8-col">\', d = 6, i += \'<div class="mdl-grid">\', d = 8, i += \'<div class="mdl-cell mdl-cell--12-col" id="define-name-div">\', d = 9, i += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label fullwidth">\', d = 10, i += \'<input class="mdl-textfield__input" id="define-name" data-hook="define-name-input" type="text"/>\', d = 14, i += \'<label class="mdl-textfield__label" for="define-name">\', d = 14, i += "Name</label></div></div>", d = 15, i += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="define-name-div">\', d = 16, i += "Set a descriptive name for this facet. The name is used to identify this facet on plots and in menus. </div>", d = 18, i += \'<div class="mdl-cell mdl-cell--12-col" id="define-units-div">\', d = 19, i += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label fullwidth">\', d = 20, i += \'<input class="mdl-textfield__input" id="define-units" data-hook="define-units-input" type="text"/>\', d = 24, i += \'<label class="mdl-textfield__label" for="define-units">\', d = 24, i += "Units</label></div></div>", d = 25, i += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="define-units-div">\', d = 26, i += "Set units for this facet. Units are printed on plots where applicable.</div>", d = 28, i += \'<div class="mdl-cell mdl-cell--12-col" id="define-description-div">\', d = 29, i += \'<div class="mdl-textfield mdl-js-textfield mdl textfield--floating-label fullwidth">\', d = 30, i += \'<textarea class="mdl-textfield__input" id="define-description" data-hook="define-description-input" type="text" rows="5">\', d = 34, i += " </textarea>", d = 35, i += \'<label class="mdl-textfield__label" for="define-description">\', d = 35, i += "Description</label></div></div>", d = 36, i += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="define-description-div">\', d = 37, i += "Give a description of the facet. What do its values mean? How are they calculated?</div></div></div>", d = 39, i += \'<div class="mdl-cell mdl-cell--2-col"></div></div>\', d = 41, i += \'<div class="mdl-cell mdl-cell--12-col mdl-grid">\', d = 42, i += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetTypeIcon"></div>\', d = 43, i += \'<div class="mdl-cell mdl-cell--1-col"></div>\', d = 44, i += \'<div class="mdl-cell mdl-cell--8-col">\', d = 46, i += \'<div class="mdl-grid mdl-cell mdl-cell--12-col">\', d = 48, i += \'<div class="mdl-grid mdl-cell mdl-cell--12-col" id="define-type-div">\', d = 49, i += \'<div class="mdl-cell mdl-cell--3-col">\', d = 50, i += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="define-type-categorial">\', d = 51, i += \'<input class="mdl-radio__button" id="define-type-categorial" data-hook="define-type-categorial" type="radio" name="type" value="categorial"/>\', d = 57, i += \'<span class="mdl-radio__label">\', d = 57, i += "Categorial</span></label></div>", d = 59, i += \'<div class="mdl-cell mdl-cell--3-col">\', d = 60, i += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="define-type-continuous">\', d = 61, i += \'<input class="mdl-radio__button" id="define-type-continuous" data-hook="define-type-continuous" type="radio" name="type" value="continuous"/>\', d = 67, i += \'<span class="mdl-radio__label">\', d = 67, i += "Continuous</span></label></div>", d = 69, i += \'<div class="mdl-cell mdl-cell--3-col">\', d = 70, i += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="define-type-datetime">\', d = 71, i += \'<input class="mdl-radio__button" id="define-type-datetime" data-hook="define-type-datetime" type="radio" name="type" value="datetime"/>\', d = 77, i += \'<span class="mdl-radio__label">\', d = 77, i += "Datetime</span></label></div>", d = 79, i += \'<div class="mdl-cell mdl-cell--3-col">\', d = 80, i += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="define-type-duration">\', d = 81, i += \'<input class="mdl-radio__button" id="define-type-duration" data-hook="define-type-duration" type="radio" name="type" value="duration"/>\', d = 87, i += \'<span class="mdl-radio__label">\', d = 87, i += "Duration</span></label></div>", d = 89, i += \'<div class="mdl-cell mdl-cell--3-col">\', d = 90, i += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="define-type-text">\', d = 91, i += \'<input class="mdl-radio__button" id="define-type-text" data-hook="define-type-text" type="radio" name="type" value="text"/>\', d = 97, i += \'<span class="mdl-radio__label">\', d = 97, i += "Text</span></label></div></div>", d = 99, i += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="define-type-div">\', d = 100, i += "What values does this facet take? Is it a continuous value (length, weight, amount)? Or a label, category (\'important\', \'urgent\', or a day of the week, ...). Or is it a date, time or duration? Or arbitrary text?</div></div></div>", d = 102, i += \'<div class="mdl-cell mdl-cell--2-col"></div></div>\', d = 104, i += \'<div class="mdl-cell mdl-cell--12-col mdl-grid">\', d = 105, i += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetBaseValueIcon"></div>\', d = 106, i += \'<div class="mdl-cell mdl-cell--1-col"></div>\', d = 107, i += \'<div class="mdl-cell mdl-cell--8-col">\', d = 109, i += \'<div class="mdl-grid mdl-cell mdl-cell--12-col">\', d = 111, i += \'<div class="mdl-cell mdl-cell--12-col" id="define-missing-div">\', d = 112, i += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label fullwidth">\', d = 113, i += \'<input class="mdl-textfield__input" id="define-missing-input" data-hook="define-missing-input" type="text"/>\', d = 117, i += \'<label class="mdl-textfield__label" for="define-missing-input">\', d = 117, i += "Missing data indicator</label></div></div>", d = 118, i += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="define-missing-div">\', d = 119, i += "Invalid, undefined, or missing data are dealt with automatically, but sometimes a special value is used to indicate the data is missing. Enter those values here. Example: 999, \'x\', \'missing\'</div>", d = 122, i += \'<div class="mdl-cell mdl-cell--12-col" id="define-accessor-div">\', d = 123, i += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label fullwidth">\', d = 124, i += \'<input class="mdl-textfield__input" id="define-accessor-input" data-hook="define-accessor-input" type="text"/>\', d = 128, i += \'<label class="mdl-textfield__label" for="define-accessor-input">\', d = 128, i += "Property name or index</label></div></div>", d = 129, i += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="define-accessor-div">\', d = 130, i += "How we derive the facet value from a data object? Enter a property name (for JSON or SQL columns), or index (for arrays). Use \'.\' notation to access nested properties.</div>", d = 133, i += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="define-rescan-div">\', d = 134, i += \'<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent" data-hook="define-rescan-button">\', d = 134, i += "Scan dataset</button></div>", d = 137, i += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="define-minimum-div" data-hook="define-minimum-div">\', d = 138, i += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--10-col" id="define-minimum-div">\', d = 139, i += \'<input class="mdl-textfield__input" id="define-minimum" data-hook="define-minimum-input" type="text"/>\', d = 143, i += \'<label class="mdl-textfield__label" for="sample4">\', d = 143, i += "Minimum value</label></div>", d = 145, i += \'<div class="mdl-cell mdl-cell--1-col">\', d = 146, i += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored" data-hook="button-minval-missing">\', d = 147, i += \'<i class="material-icons">\', d = 147, i += "cancel</i></button></div>", d = 149, i += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="define-minimum-div">\', d = 150, i += "Set minimum value.</div></div>", d = 153, i += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="define-maximum-div" data-hook="define-maximum-div">\', d = 154, i += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--10-col" id="define-maximum-div">\', d = 155, i += \'<input class="mdl-textfield__input" id="define-maximum" data-hook="define-maximum-input" type="text"/>\', d = 159, i += \'<label class="mdl-textfield__label" for="sample4">\', d = 159, i += "Maximum value</label></div>", d = 161, i += \'<div class="mdl-cell mdl-cell--1-col">\', d = 162, i += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored" data-hook="button-maxval-missing">\', d = 163, i += \'<i class="material-icons">\', d = 163, i += "cancel</i></button></div>", d = 165, i += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="define-maximum-div">\', d = 166, i += "Set maximum value.</div></div></div></div>", d = 168, i += \'<div class="mdl-cell mdl-cell--2-col"></div></div></div>\';\n    } catch (t) {\n      pug.rethrow(t, e, d);\n    }\n\n    return i;\n  };\n\n  puglatizer["configureFacet"]["facetTransformCategorial"] = function template(l) {\n    var t,\n        d,\n        o = "";\n\n    try {\n      d = 1, o += \'<div class="mdl-grid" data-hook="transform-categorial-panel">\', d = 3, o += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetCategorialIcon"></div>\', d = 5, o += \'<div class="mdl-cell mdl-cell--1-col"></div>\', d = 7, o += \'<div class="mdl-cell mdl-cell--8-col">\', d = 8, o += \'<div class="mdl-grid" id="transform-categorial-div">\', d = 10, o += \'<div class="mdl-cell mdl-cell--4-col" data-hook="categorial-addone-button">\', d = 11, o += \'<button class="mdl-button mdl-js-button mdl-js-ripple-effect">\', d = 11, o += "Add a rule</button></div>", d = 13, o += \'<div class="mdl-cell mdl-cell--4-col" data-hook="categorial-removeall-button">\', d = 14, o += \'<button class="mdl-button mdl-js-button mdl-js-ripple-effect">\', d = 14, o += "Remove all rules</button></div>", d = 16, o += \'<div class="mdl-cell mdl-cell--12-col">\', d = 17, o += "<table>", d = 18, o += "<thead>", d = 19, o += "<tr>", d = 20, o += "<th>", d = 20, o += "Text</th>", d = 21, o += "<th>", d = 21, o += "Group</th>", d = 22, o += "<th>", d = 22, o += "Count</th>", d = 23, o += "<th>", d = 23, o += "Remove</th></tr></thead>", d = 24, o += \'<tbody data-hook="categorial-rules-table"></tbody></table></div></div>\', d = 26, o += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="transform-categorial-div">\', d = 26, o += " ", d = 27, o += "Assign facet values to grous.</div></div>", d = 29, o += \'<div class="mdl-cell mdl-cell--2-col"></div></div>\';\n    } catch (a) {\n      pug.rethrow(a, t, d);\n    }\n\n    return o;\n  };\n\n  puglatizer["configureFacet"]["facetTransformContinuous"] = function template(l) {\n    var e,\n        d,\n        a = "";\n\n    try {\n      d = 1, a += \'<div class="mdl-grid" data-hook="transform-continuous-panel">\', d = 3, a += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetContinuousIcon"></div>\', d = 5, a += \'<div class="mdl-cell mdl-cell--1-col"></div>\', d = 7, a += \'<div class="mdl-cell mdl-cell--8-col mdl-grid">\', d = 9, a += \'<div class="mdl-cell mdl-cell--4-col">\', d = 10, a += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="define-transform-none">\', d = 11, a += \'<input class="mdl-radio__button" id="define-transform-none" data-hook="define-transform-none" type="radio" name="transformtype" value="none"/>\', d = 17, a += \'<span class="mdl-radio__label">\', d = 17, a += "No transform</span></label></div>", d = 19, a += \'<div class="mdl-cell mdl-cell--4-col">\', d = 20, a += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="define-transform-percentiles">\', d = 21, a += \'<input class="mdl-radio__button" id="define-transform-percentiles" data-hook="define-transform-percentiles" type="radio" name="transformtype" value="percentiles"/>\', d = 27, a += \'<span class="mdl-radio__label">\', d = 27, a += "Percentiles</span></label></div></div>", d = 29, a += \'<div class="mdl-cell mdl-cell--2-col"></div></div>\';\n    } catch (s) {\n      pug.rethrow(s, e, d);\n    }\n\n    return a;\n  };\n\n  puglatizer["configureFacet"]["facetTransformDatetime"] = function template(l) {\n    var e,\n        d,\n        t = "";\n\n    try {\n      d = 1, t += \'<div class="mdl-grid" data-hook="transform-time-panel">\', d = 3, t += \'<div class="mdl-grid mdl-cell mdl-cell--12-col">\', d = 4, t += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetTimeIcon"></div>\', d = 5, t += \'<div class="mdl-cell mdl-cell--1-col"></div>\', d = 7, t += \'<div class="mdl-cell mdl-cell--8-col mdl-grid">\', d = 9, t += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="transform-time-format-div">\', d = 10, t += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--6-col">\', d = 11, t += \'<input class="mdl-textfield__input" id="transform-time-format" data-hook="transform-time-format-input" type="text"/>\', d = 15, t += \'<label class="mdl-textfield__label" for="transform-time-format">\', d = 15, t += "Input time format</label></div>", d = 17, t += \'<div class="mdl-cell mdl-cell--6-col" data-hook="time-zones"></div></div>\', d = 19, t += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="transform-time-transformedformat-div">\', d = 20, t += \'<div class="mdl-cell mdl-cell--6-col">\', d = 21, t += "Select datetime part</div>", d = 22, t += \'<div class="mdl-cell mdl-cell--6-col" data-hook="time-parts"></div></div>\', d = 24, t += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="transform-time-transformedreference-div">\', d = 25, t += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--6-col">\', d = 26, t += \'<input class="mdl-textfield__input" id="transform-time-transformedreference" data-hook="transform-time-transformedreference-input" type="text"/>\', d = 30, t += \'<label class="mdl-textfield__label" for="transform-time-transformedreference">\', d = 30, t += "Add/subtract reference time</label></div>", d = 32, t += \'<div class="mdl-cell mdl-cell--6-col" data-hook="transformed-time-zones"></div></div></div>\', d = 34, t += \'<div class="mdl-cell mdl-cell--2-col"></div></div></div>\';\n    } catch (m) {\n      pug.rethrow(m, e, d);\n    }\n\n    return t;\n  };\n\n  puglatizer["configureFacet"]["facetTransformDuration"] = function template(l) {\n    var d,\n        e,\n        c = "";\n\n    try {\n      e = 1, c += \'<div class="mdl-grid" data-hook="transform-duration-panel">\', e = 3, c += \'<div class="mdl-grid mdl-cell mdl-cell--12-col">\', e = 4, c += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetTimeIcon"></div>\', e = 5, c += \'<div class="mdl-cell mdl-cell--1-col"></div>\', e = 7, c += \'<div class="mdl-cell mdl-cell--8-col mdl-grid">\', e = 9, c += \'<div class="mdl-cell mdl-cell--12-col mdl-grid">\', e = 10, c += \'<div class="mdl-cell mdl-cell--6-col">\', e = 11, c += "Input units </div>", e = 12, c += \'<div class="mdl-cell mdl-cell--6-col" data-hook="duration-units"></div></div>\', e = 14, c += \'<div class="mdl-cell mdl-cell--12-col mdl-grid">\', e = 15, c += \'<div class="mdl-cell mdl-cell--6-col">\', e = 16, c += "Output units</div>", e = 17, c += \'<div class="mdl-cell mdl-cell--6-col" data-hook="transformed-duration-units"></div></div>\', e = 19, c += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="transform-duration-transformedreference-div">\', e = 20, c += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--6-col">\', e = 21, c += \'<input class="mdl-textfield__input" id="transform-duration-transformedreference" data-hook="transform-duration-transformedreference-input" type="text"/>\', e = 25, c += \'<label class="mdl-textfield__label" for="transform-duration-transformedreference">\', e = 25, c += "Add/subtract reference time</label></div>", e = 27, c += \'<div class="mdl-cell mdl-cell--6-col" data-hook="transformed-duration-zone"></div></div></div>\', e = 29, c += \'<div class="mdl-cell mdl-cell--2-col"></div></div></div>\';\n    } catch (i) {\n      pug.rethrow(i, d, e);\n    }\n\n    return c;\n  };\n\n  puglatizer["configureFacet"]["page"] = function template(a) {\n    var d,\n        t,\n        o = "";\n\n    try {\n      t = 1, o += \'<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">\', t = 2, o += \'<main class="mdl-layout__content" style="background-color: white;">\', t = 3, o += \'<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">\', t = 4, o += \'<header class="demo-header mdl-layout__header mdl-color--grey-100 mdl-color-text--grey-600">\', t = 5, o += \'<div class="mdl-layout__header-row">\', t = 6, o += \'<span class="mdl-layout-title">\', t = 6, o += "Configure facet</span></div></header>", t = 8, o += "<main>", t = 9, o += \'<div data-hook="facet-define"></div>\', t = 11, o += \'<div data-hook="transform-categorial-panel">\', t = 12, o += \'<div data-hook="facet-transform-categorial"></div></div>\', t = 13, o += \'<div data-hook="transform-continuous-panel">\', t = 14, o += \'<div data-hook="facet-transform-continuous"></div></div>\', t = 15, o += \'<div data-hook="transform-datetime-panel">\', t = 16, o += \'<div data-hook="facet-transform-datetime"></div></div>\', t = 17, o += \'<div data-hook="transform-duration-panel">\', t = 18, o += \'<div data-hook="facet-transform-duration"></div></div></main></div></main></div>\';\n    } catch (e) {\n      pug.rethrow(e, d, t);\n    }\n\n    return o;\n  };\n\n  puglatizer["configurePartition"] = {};\n\n  puglatizer["configurePartition"]["group"] = function template(t) {\n    var r,\n        o,\n        a = "";\n\n    try {\n      o = 1, a += "<tr>", o = 2, a += \'<td data-hook="group-label"></td>\', o = 3, a += \'<td data-hook="group-count"></td></tr>\';\n    } catch (d) {\n      pug.rethrow(d, r, o);\n    }\n\n    return a;\n  };\n\n  puglatizer["configurePartition"]["page"] = function template(l) {\n    var d,\n        t,\n        i = "";\n\n    try {\n      t = 1, i += \'<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">\', t = 2, i += \'<main class="mdl-layout__content" style="background-color: white;">\', t = 4, i += \'<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">\', t = 5, i += \'<header class="demo-header mdl-layout__header mdl-color--grey-100 mdl-color-text--grey-600">\', t = 6, i += \'<div class="mdl-layout__header-row">\', t = 7, i += \'<span class="mdl-layout-title">\', t = 7, i += "Configure partition</span></div></header>", t = 9, i += "<main>", t = 10, i += \'<div class="mdl-grid" data-hook="partition-general">\', t = 11, i += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetInfoIcon"></div>\', t = 12, i += \'<div class="mdl-cell mdl-cell--1-col"></div>\', t = 13, i += \'<div class="mdl-cell mdl-cell--8-col">\', t = 14, i += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="partition-label-div">\', t = 15, i += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--12-col">\', t = 16, i += \'<input class="mdl-textfield__input" id="partition-title" data-hook="partition-title-input" type="text"/>\', t = 20, i += \'<label class="mdl-textfield__label" for="">\', t = 20, i += "Label</label></div></div>", t = 22, i += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="partition-label-div">\', t = 23, i += "The label along this axis</div>", t = 25, i += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="partition-options-div">\', t = 26, i += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--3-col">\', t = 27, i += \'<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="partition-cb1">\', t = 28, i += \'<input class="mdl-checkbox__input" type="checkbox" id="partition-cb1" data-hook="show-label"/>\', t = 29, i += \'<span class="mdl-checkbox__label">\', t = 29, i += "Show label</span></label></div>", t = 31, i += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--3-col">\', t = 32, i += \'<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="partition-cb2">\', t = 33, i += \'<input class="mdl-checkbox__input" type="checkbox" id="partition-cb2" data-hook="show-legend"/>\', t = 34, i += \'<span class="mdl-checkbox__label">\', t = 34, i += "Show legend</span></label></div>", t = 36, i += "\x3c!-- div.mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label.mdl-cell.mdl-cell--3-col--\x3e", t = 37, i += \'\x3c!--   label(for="partition-cb3").mdl-checkbox.mdl-js-checkbox.mdl-js-ripple-effect--\x3e\', t = 38, i += \'\x3c!--     input(type="checkbox" id="partition-cb3" data-hook="accumulative").mdl-checkbox__input--\x3e\', t = 39, i += "\x3c!--     span.mdl-checkbox__label Accumulative--\x3e", t = 41, i += "\x3c!-- div.mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label.mdl-cell.mdl-cell--3-col--\x3e", t = 42, i += \'\x3c!--   label(for="partition-cb4").mdl-checkbox.mdl-js-checkbox.mdl-js-ripple-effect--\x3e\', t = 43, i += \'\x3c!--     input(type="checkbox" id="partition-cb4" data-hook="relative").mdl-checkbox__input--\x3e\', t = 44, i += "\x3c!--     span.mdl-checkbox__label Relative--\x3e</div>", t = 46, i += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="partition-options-div">\', t = 47, i += "Set various options for this partition</div></div>", t = 49, i += \'<div class="mdl-cell mdl-cell--2-col"></div></div>\', t = 51, i += \'<div class="mdl-grid" data-hook="partition-continuous"></div>\', t = 52, i += \'<div class="mdl-grid" data-hook="partition-categorial"></div>\', t = 53, i += \'<div class="mdl-grid" data-hook="partition-datetime"></div>\', t = 54, i += \'<div class="mdl-grid" data-hook="partition-duration"></div>\', t = 55, i += \'<div class="mdl-grid" data-hook="partition-text"></div></main></div></main></div>\';\n    } catch (e) {\n      pug.rethrow(e, d, t);\n    }\n\n    return i;\n  };\n\n  puglatizer["configurePartition"]["partitionCategorial"] = function template(l) {\n    var t,\n        d,\n        o = "";\n\n    try {\n      d = 1, o += \'<div class="mdl-grid" data-hook="group-categorial-panel">\', d = 2, o += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetCategorialIcon"></div>\', d = 3, o += \'<div class="mdl-cell mdl-cell--1-col"></div>\', d = 4, o += \'<div class="mdl-cell mdl-cell--8-col">\', d = 5, o += \'<div class="mdl-cell mdl-cell--12-col">\', d = 6, o += \'<table style="width: 100%">\', d = 7, o += "<thead>", d = 8, o += "<tr>", d = 9, o += "<th>", d = 10, o += \'<button class="mdl-button mdl-js-button" data-hook="group-order-abc">\', d = 10, o += "label</button></th>", d = 11, o += "<th>", d = 12, o += \'<button class="mdl-button mdl-js-button" data-hook="group-order-count">\', d = 12, o += "count</button></th></tr></thead>", d = 13, o += \'<tbody data-hook="groups-table"></tbody></table></div></div>\', d = 14, o += \'<div class="mdl-cell mdl-cell--2-col"></div></div>\';\n    } catch (c) {\n      pug.rethrow(c, t, d);\n    }\n\n    return o;\n  };\n\n  puglatizer["configurePartition"]["partitionContinuous"] = function template(l) {\n    var d,\n        i,\n        e = "";\n\n    try {\n      i = 1, e += \'<div class="mdl-grid" data-hook="group-continuous-panel">\', i = 2, e += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetContinuousIcon"></div>\', i = 3, e += \'<div class="mdl-cell mdl-cell--1-col"></div>\', i = 4, e += \'<div class="mdl-cell mdl-cell--8-col">\', i = 5, e += \'<div class="mdl-grid mdl-cell mdl-cell--12-col">\', i = 7, e += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="group-range-div">\', i = 8, e += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--4-col">\', i = 9, e += \'<input class="mdl-textfield__input" id="group-minimum" data-hook="group-minimum-input" type="text" pattern="-?[0-9]*(.[0-9]+)?(e[+-][0-9]+)?"/>\', i = 14, e += \'<label class="mdl-textfield__label" for="group-minimum">\', i = 14, e += "Minimum value</label>", i = 15, e += \'<span class="mdl-textfield__error">\', i = 15, e += "Input is not a number!</span></div>", i = 17, e += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--4-col">\', i = 18, e += \'<input class="mdl-textfield__input" id="group-maximum" data-hook="group-maximum-input" type="text" pattern="-?[0-9]*(.[0-9]+)?(e[+-][0-9]+)?"/>\', i = 23, e += \'<label class="mdl-textfield__label" for="group-maximum">\', i = 23, e += "Maximum value</label>", i = 24, e += \'<span class="mdl-textfield__error">\', i = 24, e += "Input is not a number!</span></div>", i = 26, e += \'<div class="mdl-cell mdl-cell--4-col" data-hook="group-range-button">\', i = 27, e += \'<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">\', i = 27, e += "Reset ranges</button></div></div>", i = 29, e += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="group-range-div">\', i = 30, e += "Reset mininum and maximum values.</div>", i = 33, e += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="group-param-div">\', i = 34, e += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--12-col">\', i = 35, e += \'<input class="mdl-textfield__input" id="group-param" data-hook="group-param-input" type="text" pattern="-?[0-9]*(.[0-9]+)?"/>\', i = 40, e += \'<label class="mdl-textfield__label" for="sample4">\', i = 40, e += "Number of bins or binsize</label>", i = 41, e += \'<span class="mdl-textfield__error">\', i = 41, e += "Input is not a number!</span></div></div>", i = 43, e += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="group-param-div">\', i = 44, e += "Set the number of bins, or the bin size</div>", i = 47, e += \'<div class="mdl-grid mdl-cell mdl-cell--12-col" id="group-distribution-div">\', i = 49, e += \'<div class="mdl-cell mdl-cell--3-col">\', i = 50, e += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="group-fixedn">\', i = 51, e += \'<input class="mdl-radio__button" id="group-fixedn" data-hook="group-fixedn-input" type="radio" name="group-distribution" value="fixedn"/>\', i = 57, e += \'<span class="mdl-radio__label">\', i = 57, e += "Fixed number of bins</span></label></div>", i = 59, e += \'<div class="mdl-cell mdl-cell--3-col">\', i = 60, e += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="group-fixedsc">\', i = 61, e += \'<input class="mdl-radio__button" id="group-fixedsc" data-hook="group-fixedsc-input" type="radio" name="group-distribution" value="fixedsc"/>\', i = 67, e += \'<span class="mdl-radio__label">\', i = 67, e += "Fixed bin size (centered)</span></label></div>", i = 69, e += \'<div class="mdl-cell mdl-cell--3-col">\', i = 70, e += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="group-fixeds">\', i = 71, e += \'<input class="mdl-radio__button" id="group-fixeds" data-hook="group-fixeds-input" type="radio" name="group-distribution" value="fixeds"/>\', i = 77, e += \'<span class="mdl-radio__label">\', i = 77, e += "Fixed bin size</span></label></div>", i = 79, e += \'<div class="mdl-cell mdl-cell--3-col">\', i = 80, e += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="group-log">\', i = 81, e += \'<input class="mdl-radio__button" id="group-log" data-hook="group-log-input" type="radio" name="group-distribution" value="log"/>\', i = 87, e += \'<span class="mdl-radio__label">\', i = 87, e += "Logarithmic</span></label></div></div></div></div>", i = 89, e += \'<div class="mdl-cell mdl-cell--2-col"></div></div>\';\n    } catch (a) {\n      pug.rethrow(a, d, i);\n    }\n\n    return e;\n  };\n\n  puglatizer["configurePartition"]["partitionDatetime"] = function template(l) {\n    var t,\n        e,\n        d = "";\n\n    try {\n      e = 1, d += \'<div class="mdl-grid" data-hook="group-datetime-panel">\', e = 2, d += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetTimeIcon"></div>\', e = 3, d += \'<div class="mdl-cell mdl-cell--1-col"></div>\', e = 4, d += \'<div class="mdl-cell mdl-cell--8-col mdl-grid">\', e = 5, d += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="group-datetimerange-div">\', e = 6, d += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--3-col">\', e = 7, d += \'<input class="mdl-textfield__input" id="group-startdate" data-hook="group-startdate-input" type="text"/>\', e = 11, d += \'<label class="mdl-textfield__label" for="group-startdate">\', e = 11, d += "Start date</label></div>", e = 13, d += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--3-col">\', e = 14, d += \'<input class="mdl-textfield__input" id="group-enddate" data-hook="group-enddate-input" type="text"/>\', e = 18, d += \'<label class="mdl-textfield__label" for="group-enddate">\', e = 18, d += "End date</label></div>", e = 20, d += \'<div class="mdl-cell mdl-cell--3-col">\', e = 21, d += \'<div data-hook="time-zones"></div></div>\', e = 23, d += \'<div class="mdl-cell mdl-cell--3-col">\', e = 24, d += \'<select data-hook="time-units">\', e = 25, d += \'<option value="auto">\', e = 25, d += "auto</option>", e = 26, d += \'<option value="milliseconds">\', e = 26, d += "milliseconds</option>", e = 27, d += \'<option value="seconds">\', e = 27, d += "seconds</option>", e = 28, d += \'<option value="minutes">\', e = 28, d += "minutes</option>", e = 29, d += \'<option value="hours">\', e = 29, d += "hours</option>", e = 30, d += \'<option value="days">\', e = 30, d += "days</option>", e = 31, d += \'<option value="weeks">\', e = 31, d += "weeks</option>", e = 32, d += \'<option value="months">\', e = 32, d += "months</option>", e = 33, d += \'<option value="years">\', e = 33, d += "years</option></select></div></div>", e = 35, d += \'<div class="mdl-cell mdl-cell--12-col" data-hook="group-datetimerange-button">\', e = 36, d += \'<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">\', e = 36, d += "Reset ranges</button></div></div>", e = 38, d += \'<div class="mdl-cell mdl-cell--2-col"></div></div>\';\n    } catch (o) {\n      pug.rethrow(o, t, e);\n    }\n\n    return d;\n  };\n\n  puglatizer["configurePartition"]["partitionDuration"] = function template(l) {\n    var d,\n        t,\n        e = "";\n\n    try {\n      t = 1, e += \'<div class="mdl-grid" data-hook="group-duration-panel">\', t = 2, e += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetTimeIcon"></div>\', t = 3, e += \'<div class="mdl-cell mdl-cell--1-col"></div>\', t = 4, e += \'<div class="mdl-cell mdl-cell--8-col">\', t = 5, e += \'<div class="mdl-grid mdl-cell mdl-cell--12-col">\', t = 7, e += \'<div class="mdl-cell mdl-cell--12-col mdl-grid" id="group-durationrange-div">\', t = 8, e += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--4-col">\', t = 9, e += \'<input class="mdl-textfield__input" id="group-startduration" data-hook="group-startduration-input" type="text"/>\', t = 13, e += \'<label class="mdl-textfield__label" for="group-startduration">\', t = 13, e += "Start interval</label></div>", t = 15, e += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--4-col">\', t = 16, e += \'<input class="mdl-textfield__input" id="group-endduration" data-hook="group-endduration-input" type="text"/>\', t = 20, e += \'<label class="mdl-textfield__label" for="group-endduration">\', t = 20, e += "End interval</label></div>", t = 22, e += \'<div class="mdl-cell mdl-cell--4-col" data-hook="group-durationrange-button">\', t = 23, e += \'<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">\', t = 23, e += "Reset ranges</button></div></div>", t = 25, e += \'<div class="mdl-tooltip mdl-tooltip--large mdl-tooltip--right" for="group-durationrange-div">\', t = 26, e += "Reset start and end interval</div></div></div>", t = 28, e += \'<div class="mdl-cell mdl-cell--2-col"></div></div>\';\n    } catch (i) {\n      pug.rethrow(i, d, t);\n    }\n\n    return e;\n  };\n\n  puglatizer["configurePartition"]["partitionText"] = function template(l) {\n    var d,\n        c,\n        t = "";\n\n    try {\n      c = 1, t += \'<div class="mdl-grid" data-hook="group-text-panel">\', c = 2, t += \'<div class="mdl-cell mdl-cell--1-col facetIcon facetTextIcon"></div>\', c = 3, t += \'<div class="mdl-cell mdl-cell--1-col"></div>\', c = 4, t += \'<div class="mdl-cell mdl-cell--8-col">\', c = 5, t += \'<div class="mdl-grid mdl-cell mdl-cell--12-col">\', c = 7, t += \'<div class="mdl-cell mdl-cell--3-col" data-hook="group-order-abc">\', c = 8, t += \'<button class="mdl-button mdl-js-button mdl-js-ripple-effect">\', c = 8, t += "Order alfabetically</button></div>", c = 10, t += \'<div class="mdl-cell mdl-cell--3-col" data-hook="group-order-count">\', c = 11, t += \'<button class="mdl-button mdl-js-button mdl-js-ripple-effect">\', c = 11, t += "Order by count</button></div></div></div></div>";\n    } catch (e) {\n      pug.rethrow(e, d, c);\n    }\n\n    return t;\n  };\n\n  puglatizer["datasets"] = {};\n\n  puglatizer["datasets"]["dataset"] = function template(t) {\n    var a,\n        d,\n        l = "";\n\n    try {\n      d = 1, l += \'<div class="mdl-card mdl-shadow--2dp" data-hook="dataset" style="min-height: inherit">\', d = 2, l += \'<div class="mdl-card__title">\', d = 3, l += \'<h2 class="mdl-card__title-text" data-hook="name"></h2></div>\', d = 5, l += \'<div class="mdl-card__supporting-text" data-hook="description"></div>\', d = 7, l += \'<div class="mdl-card__actions mdl-card--border">\', d = 8, l += \'<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect" data-hook="delete">\', d = 9, l += "Delete</a>", d = 10, l += \'<button class="mdl-button mdl-js button mdl-button--icon mdl-button--colored" data-hook="settings" style="float: right">\', d = 11, l += \'<i class="material-icons">\', d = 11, l += "settings</i></button></div>", d = 13, l += \'<div class="mdl-card__menu">\', d = 14, l += \'<span class="mdl-spinner mdl-js-spinner is-active" data-hook="cbspinner"></span>\', d = 15, l += \'<span data-hook="cbtoggle">\', d = 16, l += \'<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" data-hook="cblabel" for="">\', d = 17, l += \'<input class="mdl-switch__input" data-hook="cb" type="checkbox" id=""/></label>\', d = 18, l += \'<span class="mdl-switch__label"></span></span></div></div>\';\n    } catch (s) {\n      pug.rethrow(s, a, d);\n    }\n\n    return l;\n  };\n\n  puglatizer["datasets"]["datasetCollection"] = function template(t) {\n    var a,\n        e,\n        r = "";\n\n    try {\n      e = 1, r += \'<div data-hook="items" style="display: flex; flex-wrap: wrap;"></div>\';\n    } catch (i) {\n      pug.rethrow(i, a, e);\n    }\n\n    return r;\n  };\n\n  puglatizer["datasets"]["page"] = function template(t) {\n    var a,\n        l,\n        d = "";\n\n    try {\n      l = 1, d += \'<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">\', l = 2, d += \'<main class="mdl-layout__content" style="background-color: white;">\', l = 3, d += "<div>", l = 5, d += \'<div class="mdl-grid">\', l = 6, d += \'<dialog class="mdl-dialog" data-hook="CSV-settings">\', l = 7, d += \'<div class="mdl-dialog__content">\', l = 8, d += \'<section class="mdl-grid" id="csv-settings-table" name="csv-settings-table">\', l = 9, d += "<div>", l = 10, d += \'<table class="mdl-data-table mdl-js-data-table">\', l = 11, d += "<tbody>", l = 12, d += "<tr>", l = 13, d += "<td>", l = 13, d += "Headers</td>", l = 14, d += "<td>", l = 15, d += "<span>", l = 16, d += \'<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="CSV-header-columns">\', l = 17, d += "Enable", l = 18, d += \'<input class="mdl-checkbox__input" type="checkbox" id="CSV-header-columns"/></label></span></td></tr>\', l = 19, d += "<tr>", l = 20, d += "<td>", l = 20, d += "Delimiter</td>", l = 21, d += "<td>", l = 22, d += "<span>", l = 23, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-separator-comma">\', l = 24, d += \'<input class="mdl-radio__button" type="radio" id="CSV-separator-comma" name="CSV-separator-options" value="comma"/></label></span>\', l = 25, d += \'<span class="mdl-typography--title-color-contrast">\', l = 26, d += ",</span></td>", l = 27, d += "<td>", l = 28, d += "<span>", l = 29, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-separator-colon">\', l = 30, d += \'<input class="mdl-radio__button" type="radio" id="CSV-separator-colon" name="CSV-separator-options" value="colon"/></label></span>\', l = 31, d += \'<span class="mdl-typography--title-color-contrast">\', l = 32, d += ":</span></td>", l = 33, d += "<td>", l = 34, d += "<span>", l = 35, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-separator-semicolon">\', l = 36, d += \'<input class="mdl-radio__button" type="radio" id="CSV-separator-semicolon" name="CSV-separator-options" value="semicolon"/></label></span>\', l = 37, d += \'<span class="mdl-typography--title-color-contrast">\', l = 38, d += ";</span></td>", l = 39, d += "<td>", l = 40, d += "<span>", l = 41, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-separator-pipe">\', l = 42, d += \'<input class="mdl-radio__button" type="radio" id="CSV-separator-pipe" name="CSV-separator-options" value="pipe"/></label></span>\', l = 43, d += \'<span class="mdl-typography--title-color-contrast">\', l = 44, d += "|</span></td>", l = 45, d += "<td>", l = 46, d += "<span>", l = 47, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-separator-tab">\', l = 48, d += \'<input class="mdl-radio__button" type="radio" id="CSV-separator-tab" name="CSV-separator-options" value="tab"/></label></span>\', l = 49, d += "<span>", l = 50, d += "Tab</span></td>", l = 51, d += "<td>", l = 52, d += "<span>", l = 53, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-separator-other">\', l = 54, d += \'<input class="mdl-radio__button" type="radio" data-hook="CSV-separator-other" id="CSV-separator-other" name="CSV-separator-options" value="other"/></label></span>\', l = 55, d += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label" style="width: fit-content;">\', l = 56, d += \'<input class="mdl-textfield__input" data-hook="CSV-separator-other-input" type="text" id="CSV-separator-other-input" name="CSV-separator-other-input"/>\', l = 57, d += \'<label class="mdl-textfield__label" for="CSV-separator-other-input">\', l = 58, d += "Other</label></div></td></tr>", l = 59, d += "<tr>", l = 60, d += "<td>", l = 60, d += "Quoting</td>", l = 61, d += "<td>", l = 62, d += "<span>", l = 63, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-quote-none">\', l = 64, d += \'<input class="mdl-radio__button" type="radio" id="CSV-quote-none" name="CSV-quote" value="none"/></label></span>\', l = 65, d += "<span>", l = 66, d += "None</span></td>", l = 67, d += "<td>", l = 68, d += "<span>", l = 69, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-quote-single">\', l = 70, d += \'<input class="mdl-radio__button" type="radio" id="CSV-quote-single" name="CSV-quote" value="single"/></label></span>\', l = 71, d += \'<span class="mdl-typography--title-color-contrast">\', l = 72, d += "\'</span></td>", l = 73, d += "<td>", l = 74, d += "<span>", l = 75, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-quote-double">\', l = 76, d += \'<input class="mdl-radio__button" type="radio" id="CSV-quote-double" name="CSV-quote" value="double"/></label></span>\', l = 77, d += \'<span class="mdl-typography--title-color-contrast">\', l = 78, d += \'"</span></td></tr>\', l = 79, d += "<tr>", l = 80, d += "<td>", l = 80, d += "Comments</td>", l = 81, d += "<td>", l = 82, d += "<span>", l = 83, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-comment-pound">\', l = 84, d += \'<input class="mdl-radio__button" type="radio" id="CSV-comment-pound" name="CSV-comment" value="pound"/></label></span>\', l = 85, d += \'<span class="mdl-typography--title-color-contrast">\', l = 86, d += "#</span></td>", l = 87, d += "<td>", l = 88, d += "<span>", l = 89, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-comment-exclamation">\', l = 90, d += \'<input class="mdl-radio__button" type="radio" id="CSV-comment-exclamation" name="CSV-comment" value="exclamation"/></label></span>\', l = 91, d += \'<span class="mdl-typography--title-color-contrast">\', l = 92, d += "!</span></td>", l = 93, d += "<td>", l = 94, d += "<span>", l = 95, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-comment-slash">\', l = 96, d += \'<input class="mdl-radio__button" type="radio" id="CSV-comment-slash" name="CSV-comment" value="slash"/></label></span>\', l = 97, d += \'<span class="mdl-typography--title-color-contrast">\', l = 98, d += "/</span></td>", l = 99, d += "<td>", l = 100, d += "<span>", l = 101, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-comment-dash">\', l = 102, d += \'<input class="mdl-radio__button" type="radio" id="CSV-comment-dash" name="CSV-comment" value="dash"/></label></span>\', l = 103, d += \'<span class="mdl-typography--title-color-contrast">\', l = 104, d += "-</span></td>", l = 105, d += "<td>", l = 106, d += "<span>", l = 107, d += \'<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="CSV-comment-percent">\', l = 108, d += \'<input class="mdl-radio__button" type="radio" id="CSV-comment-percent" name="CSV-comment" value="percent"/></label></span>\', l = 109, d += \'<span class="mdl-typography--title-color-contrast">\', l = 110, d += "%</span></td></tr></tbody></table></div></section>", l = 112, d += \'<div class="mdl-dialog__actions mdl-dialog__actions">\', l = 114, d += \'<button class="mdl-button close" data-hook="CSV-settings-close" type="button">\', l = 114, d += "Close</button></div></div></dialog></div>", l = 116, d += \'<dialog class="mdl-dialog" data-hook="session-download-cloud">\', l = 117, d += \'<div class="mdl-dialog__content">\', l = 118, d += "<p></p>", l = 119, d += "Enter the url of the session. <br/>Make sure that you saved your current session!", l = 120, d += \'<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label mdl-cell mdl-cell--12-col">\', l = 121, d += \'<input class="mdl-textfield__input" id="session-import-remote-link" data-hook="session-import-remote-link" type="text"/></div></div>\', l = 122, d += \'<div class="mdl-dialog__actions mdl-dialog__actions">\', l = 123, d += \'<button class="mdl-button" data-hook="session-download-cloud-get" type="button">\', l = 123, d += "Import</button>", l = 124, d += \'<button class="mdl-button close" data-hook="session-download-cloud-close-button" type="button">\', l = 124, d += "Cancel</button></div></dialog>", l = 127, d += \'<header class="mdl-layout__header mdl-color--grey-100 mdl-color-text--grey-600">\', l = 128, d += \'<div class="mdl-layout__header-row">\', l = 129, d += \'<span class="mdl-layout-title" style="padding: 0; text-align: center;">\', l = 129, d += "Datasets</span>", l = 131, d += \'<div class="mdl-layout-spacer"></div>\', l = 133, d += \'<button class="mdl-button mdl-js-button mdl-button--icon mdl-js-ripple-effect" data-hook="search-button" id="tt3" data-position="bottom" data-step="1" data-intro="You can search available datasets here.">\', l = 134, d += \'<i class="material-icons">\', l = 134, d += "search</i></button>", l = 136, d += \'<div class="mdl-tooltip mdl-tooltip--large" for="tt3">\', l = 137, d += "Show or hide search bar</div></div>", l = 139, d += \'<div class="mdl-layout__header-row" data-hook="search-bar">\', l = 140, d += \'<div class="mdl-layout-spacer"></div>\', l = 141, d += \'<span class="mdl-color--white mdl-color-text--primary searchBar">\', l = 143, d += \'<span class="mdl-textfield searchBar">\', l = 144, d += \'<input class="mdl-textfield__input searchBar" data-hook="dataset-selector" type="text" id="tt5"/>\', l = 145, d += \'<div class="mdl-tooltip mdl-tooltip--large" for="tt5">\', l = 146, d += "Search facet name and description</div></span></span></div>", l = 148, d += \'<div data-hook="add-datasets-div" id="add-datasets-div">\', l = 149, d += \'<div style="display: flex; align-items: center; justify-content: center;">\', l = 150, d += \'<div class="data-page-card-button mdl-card mdl-shadow--2dp">\', l = 151, d += \'<div class="mdl-card__title">\', l = 152, d += \'<button class="mdl-button mdl-js-button mdl-button--raised mdl-color--blue-grey-900 mdl-color-text--white mdl-js-ripple-effect serverconnect-btn" data-hook="server-connect" id="serverButton">\', l = 153, d += "Connect</button></div>", l = 154, d += \'<div class="mdl-card__supporting-text">\', l = 155, d += "Connect to a PostgreSQL server.</div></div>", l = 157, d += \'<div class="data-page-card-button mdl-card mdl-shadow--2dp">\', l = 158, d += \'<div class="mdl-card__title">\', l = 159, d += \'<label class="mdl-button mdl-js-button mdl-button--raised mdl-color--blue-grey-900 mdl-color-text--white mdl-js-ripple-effect jsonupload-btn" for="jsonuploadBtn" id="jsonUploadLabel">\', l = 160, d += "Import JSON</label>", l = 161, d += \'<input class="fileBtn" type="file" accept=".json" data-hook="json-upload-input" id="jsonuploadBtn"/></div>\', l = 162, d += \'<div class="mdl-card__supporting-text">\', l = 163, d += "Import a JSON file from your computer.</div></div>", l = 165, d += \'<div class="data-page-card-button mdl-card mdl-shadow--2dp">\', l = 166, d += \'<div class="mdl-card__title">\', l = 167, d += \'<label class="mdl-button mdl-js-button mdl-button--raised mdl-color--blue-grey-900 mdl-color-text--white mdl-js-ripple-effect csvupload-btn" for="csvuploadBtn">\', l = 168, d += "Import CSV</label>", l = 169, d += \'<input class="fileBtn" type="file" accept=".csv,.txt,.tsv" data-hook="csv-upload-input" id="csvuploadBtn"/></div>\', l = 170, d += \'<div class="mdl-card__supporting-text">\', l = 171, d += "Import a CSV file from your computer.</div>", l = 172, d += \'<div class="mdl-card__menu">\', l = 173, d += \'<button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" data-hook="CSV-settings-button" id="csv-settings-button">\', l = 174, d += \'<i class="material-icons">\', l = 174, d += "settings</i></button></div></div>", l = 176, d += \'<div class="data-page-card-button mdl-card mdl-shadow--2dp">\', l = 177, d += \'<div class="mdl-card__title">\', l = 178, d += \'<label class="mdl-button mdl-js-button mdl-button--raised mdl-color--blue-grey-900 mdl-color-text--white mdl-js-ripple-effect datadownload-btn" for="dataDownloadBtn">\', l = 179, d += "Download data</label>", l = 180, d += \'<a class="fileBtn" data-hook="data-download" id="dataDownloadBtn" download="download"></a></div>\', l = 181, d += \'<div class="mdl-card__supporting-text">\', l = 182, d += "Download the current data to your computer.</div></div></div></div>", l = 184, d += \'<div data-hook="dataset-items" style="width: 100%"></div></header>\', l = 187, d += \'<header class="mdl-layout__header mdl-color--grey-100 mdl-color-text--grey-600">\', l = 188, d += \'<div class="mdl-layout__header-row">\', l = 189, d += \'<span class="mdl-layout-title" style="padding: 0; text-align: center;">\', l = 189, d += "Sessions</span></div>", l = 191, d += \'<div data-hook="add-sessions-div" style="display: flex; align-items: center; justify-content: center;">\', l = 192, d += \'<div class="data-page-card-button mdl-card mdl-shadow--2dp">\', l = 193, d += \'<div class="mdl-card__title">\', l = 194, d += \'<a class="mdl-button mdl-js-button mdl-button--raised mdl-color--blue-grey-900 mdl-color-text--white mdl-js-ripple-effect sessiondownload-btn" data-hook="session-download" download="download">\', l = 195, d += "Export session</a></div>", l = 196, d += \'<div class="mdl-card__supporting-text">\', l = 197, d += "Save the current dashboard to your computer.</div></div>", l = 199, d += \'<div class="data-page-card-button mdl-card mdl-shadow--2dp">\', l = 200, d += \'<div class="mdl-card__title">\', l = 201, d += \'<label class="mdl-button mdl-js-button mdl-button--raised mdl-color--blue-grey-900 mdl-color-text--white mdl-js-ripple-effect sessionupload-btn" for="sessionuploadBtn" data-hook="session-upload">\', l = 202, d += "Import session</label>", l = 203, d += \'<input class="fileBtn" type="file" accept=".json" data-hook="session-upload-input" id="sessionuploadBtn"/></div>\', l = 204, d += \'<div class="mdl-card__supporting-text">\', l = 205, d += "Import a saved dashboard from your computer.</div></div>", l = 207, d += \'<div class="data-page-card-button mdl-card mdl-shadow--2dp">\', l = 208, d += \'<div class="mdl-card__title">\', l = 209, d += \'<a class="mdl-button mdl-js-button mdl-button--raised mdl-color--blue-grey-900 mdl-color-text--white mdl-js-ripple-effect sessionclouddown-btn" data-hook="session-cloud-download" cloud-download="cloud-download">\', l = 210, d += "Session by URL</a></div>", l = 211, d += \'<div class="mdl-card__supporting-text">\', l = 212, d += "Import a dashboard using URL.</div></div></div>", l = 214, d += \'<div data-hook="session-items" style="width: 100%"></div></header></div></main></div>\';\n    } catch (o) {\n      pug.rethrow(o, a, l);\n    }\n\n    return d;\n  };\n\n  puglatizer["datasets"]["session"] = function template(a) {\n    var d,\n        s,\n        t = "";\n\n    try {\n      s = 1, t += \'<div class="mdl-card mdl-shadow--2dp" data-hook="session" style="min-height: inherit">\', s = 2, t += \'<div class="mdl-card__title">\', s = 3, t += \'<h2 class="mdl-card__title-text" data-hook="date"></h2></div>\', s = 5, t += \'<div class="mdl-card__supporting-text" data-hook="description"></div>\', s = 7, t += \'<div class="mdl-card__actions mdl-card--border">\', s = 8, t += \'<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect" data-hook="delete">\', s = 9, t += "Delete</a></div>", s = 11, t += \'<div class="mdl-card__menu">\', s = 12, t += \'<span class="mdl-spinner mdl-js-spinner is-active" data-hook="cbspinner"></span>\', s = 13, t += \'<span data-hook="cbtoggle">\', s = 14, t += \'<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" data-hook="cblabel" for="">\', s = 15, t += \'<input class="mdl-switch__input" data-hook="cb" type="checkbox" id=""/></label>\', s = 16, t += \'<span class="mdl-switch__label"></span></span></div></div>\';\n    } catch (l) {\n      pug.rethrow(l, d, s);\n    }\n\n    return t;\n  };\n\n  puglatizer["datasets"]["sessionCollection"] = function template(t) {\n    var e,\n        a,\n        r = "";\n\n    try {\n      a = 1, r += \'<div data-hook="session-collection-items" style="display: flex; flex-wrap: wrap;"></div>\';\n    } catch (i) {\n      pug.rethrow(i, e, a);\n    }\n\n    return r;\n  };\n\n  puglatizer["head"] = function template(e) {\n    var t,\n        a,\n        n = "";\n\n    try {\n      a = 1, n += "<head>", a = 2, n += \'<meta charset="utf-8"/>\', a = 3, n += \'<meta http-equiv="X-UA-Compatible" content="IE=edge"/>\', a = 4, n += \'<meta name="description" content="Spot - extensible facet browser"/>\', a = 5, n += \'<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"/>\', a = 6, n += "<title>", a = 7, n += "Spot</title>", a = 9, n += "\x3c!-- Add to homescreen for Chrome on Android --\x3e", a = 10, n += \'<meta name="mobile-web-app-capable" content="yes"/>\', a = 13, n += "\x3c!-- Add to homescreen for Safari on iOS --\x3e", a = 14, n += \'<meta name="apple-mobile-web-app-capable" content="yes"/>\', a = 15, n += \'<meta name="apple-mobile-web-app-status-bar-style" content="black"/>\', a = 16, n += \'<meta name="apple-mobile-web-app-title" content="Spot"/>\', a = 19, n += "\x3c!-- Tile icon for Win8 (144x144 + tile color) --\x3e", a = 21, n += \'<meta name="msapplication-TileColor" content="#3372DF"/></head>\';\n    } catch (o) {\n      pug.rethrow(o, t, a);\n    }\n\n    return n;\n  };\n\n  puglatizer["help"] = {};\n\n  puglatizer["help"]["analyze"] = function template(a) {\n    var e,\n        t,\n        p = "";\n\n    try {\n      t = 1, p += \'<div data-hook="analyze-help" id="analyze-help" data-position="bottom" data-step="1">\', t = 2, p += "<h4>", t = 2, p += "Analyze page Help</h4>", t = 3, p += "<p></p>", t = 4, p += "Text here<br />", t = 5, p += "\\n", t = 5, p += "<br /></div>";\n    } catch (r) {\n      pug.rethrow(r, e, t);\n    }\n\n    return p;\n  };\n\n  puglatizer["help"]["menuButtons"] = function template(e) {\n    var t,\n        a,\n        o = "";\n\n    try {\n      a = 1, o += \'<div data-hook="welcome-info" id="welcome-info" data-position="bottom" data-step="1">\', a = 2, o += "<p></p>", a = 3, o += "<h6>", a = 3, o += "You will find the following buttons on the left menu:</h6>", a = 4, o += "<lu>", a = 5, o += "<li>", a = 6, o += \'<i class="material-icons" role="presentation">\', a = 6, o += "menu</i>", a = 7, o += "button controls the menu drawer.</li>", a = 8, o += "<li>", a = 9, o += \'<i class="material-icons" role="presentation">\', a = 9, o += "home</i>", a = 10, o += "button opens the homepage. This is where you are at now.</li>", a = 11, o += "<li>", a = 12, o += \'<i class="material-icons" role="presentation">\', a = 12, o += "storage</i>", a = 13, o += "button takes you to Datasets page. In Datasets page, you can upload your dataset or use existing datasets. You can also configure your datasets.</li>", a = 14, o += "<li>", a = 15, o += \'<i class="material-icons" role="presentation">\', a = 15, o += "insert_chart</i>", a = 16, o += "button takes you to Analyze page. In Analyze page, you can create your dashboard in a few clicks by creating new charts.</li>", a = 17, o += "<li>", a = 18, o += \'<i class="material-icons" role="presentation">\', a = 18, o += "share</i>", a = 19, o += "button takes you to Share page. In share page, you can share your current session or load the session which is shared with you.</li>", a = 20, o += "<li>", a = 21, o += \'<i class="material-icons" role="presentation">\', a = 21, o += "help</i>", a = 22, o += "button guides you about the user interface.</li></lu></div>";\n    } catch (i) {\n      pug.rethrow(i, t, a);\n    }\n\n    return o;\n  };\n\n  puglatizer["help"]["welcome"] = function template(e) {\n    var t,\n        a,\n        o = "";\n\n    try {\n      a = 1, o += \'<div data-hook="welcome-info" id="welcome-info" data-position="bottom" data-step="1">\', a = 2, o += "<h4>", a = 2, o += "Welcome to SPOT!</h4>", a = 3, o += "<p></p>", a = 4, o += \'This software is being developed by the  <a href="https://www.esciencecenter.nl" target="_blank">Netherlands eScience Center</a>.<br />\', a = 5, o += "\\n", a = 5, o += "<br />", a = 6, o += "\\n", a = 6, o += \'SPOT is a free and an open source software. The license of the SPOT is  <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache 2.0</a>.<br />\', a = 7, o += "\\n", a = 7, o += "<br />", a = 8, o += "\\n", a = 8, o += \'For the online tutorial of SPOT, please check <a href="https://nlesc.github.io/spot-tutorial/tutorial" target="_blank">this link</a>.<br />\', a = 9, o += "\\n", a = 9, o += "<br />", a = 10, o += "\\n", a = 10, o += "<br />", a = 11, o += "\\n", a = 11, o += \'The desktop version of SPOT can be downloaded from <a href="https://github.com/NLeSC/spot-desktop-app/releases" target="_blank">this link</a>.<br />\', a = 12, o += "\\n", a = 12, o += "<br>", a = 13, o += "\\n", a = 13, o += "You can click the button below to start a demo session. The demo session has <b>Kaggle Titanic Survival</b> dataset.", a = 15, o += "\\n", a = 15, o += "<br><br> Happy SPOTTING!<br></div>";\n    } catch (n) {\n      pug.rethrow(n, t, a);\n    }\n\n    return o;\n  };\n\n  puglatizer["home"] = function template(s) {\n    var a,\n        l,\n        e = "";\n\n    try {\n      l = 1, e += \'<main class="mdl-layout__content home-content bgspotImage">\', l = 2, e += \'<div class="content-grid mdl-grid mdl-cell--middle">\', l = 4, e += \'<div class="mdl-cell mdl-cell--12-col mdl-cell--0-offset mdl-shadow--2dp spot-cell spot-trans spot-color4">\', l = 6, e += \'<span class="cardTitleText material-icons menuIcon">\', l = 6, e += "explore</span>", l = 7, e += \'<span class="cardTitleText">\', l = 7, e += " SPOT: interactive, fast facet browser</span>", l = 8, e += "<ul>", l = 9, e += "<li>", l = 10, e += \'<p class="cardText">\', l = 10, e += "SPOT is an interactive, fast data visualization tool. It was primarily designed as data exploration and analysis tool for complex multi-dimensional datasets. Users can visualize the data only with a few clicks. SPOT can be used to compare different datasets. It is also possible to connect to a Postresql server to analyze big datasets.</p></li></ul></div>", l = 12, e += \'<div class="mdl-cell mdl-cell--4-col spot-cell spot-trans spot-color4">\', l = 13, e += \'<span class="cardTitleText material-icons menuIcon">\', l = 13, e += "merge_type</span>", l = 14, e += \'<span class="cardTitleText">\', l = 14, e += "Highlights</span>", l = 15, e += "<ul>", l = 16, e += "<li>", l = 17, e += \'<div class="cardText">\', l = 17, e += "Specifically designed for scientific data visualization</div></li>", l = 18, e += "<li>", l = 19, e += \'<div class="cardText">\', l = 19, e += "Fully animated and interactive charts</div></li>", l = 20, e += "<li>", l = 21, e += \'<div class="cardText">\', l = 21, e += "Exploration sessions can be saved</div></li>", l = 22, e += "<li>", l = 23, e += \'<div class="cardText">\', l = 23, e += "Database connection (Postgresql)</div></li></ul></div>", l = 25, e += \'<div class="mdl-cell mdl-cell--4-col spot-cell spot-trans spot-color4">\', l = 26, e += \'<span class="cardTitleText material-icons menuIcon">\', l = 26, e += "extension</span>", l = 27, e += \'<span class="cardTitleText">\', l = 27, e += "  Modern tools</span>", l = 28, e += "<ul>", l = 29, e += "<li>", l = 30, e += \'<div class="cardText">\', l = 30, e += "Viewer is fully standalone (no server required)</div></li>", l = 31, e += "<li>", l = 32, e += \'<div class="cardText">\', l = 32, e += "Responsive interface: material design lite</div></li>", l = 33, e += "<li>", l = 34, e += \'<div class="cardText">\', l = 34, e += "Fast filtering (~1M data points in ~30ms)</div></li>", l = 35, e += "<li>", l = 36, e += \'<div class="cardText">\', l = 36, e += "Cross platform (desktop, mobile and tablet)</div></li></ul></div>", l = 38, e += \'<div class="mdl-cell mdl-cell--4-col mdl-shadow--2dp spot-cell spot-trans spot-color4">\', l = 39, e += \'<span class="cardTitleText material-icons menuIcon">\', l = 39, e += "lock_open</span>", l = 40, e += \'<span class="cardTitleText">\', l = 40, e += "  Open Source</span>", l = 41, e += "<ul>", l = 42, e += "<li>", l = 43, e += \'<div class="cardText">\', l = 43, e += "Permissive Open source Licence (Apache 2.0)</div></li>", l = 44, e += "<li>", l = 45, e += \'<div class="cardText">\', l = 45, e += "Continuous Integration</div></li>", l = 46, e += "<li>", l = 47, e += \'<div class="cardText">\', l = 47, e += "Documented (jsdoc) and tested (jasmine)</div></li>", l = 48, e += "<li>", l = 49, e += \'<div class="cardText">\', l = 49, e += "Generic tool to be useful in any scientific project</div></li></ul></div></div>", l = 51, e += \'<div class="mdl-layout-spacer"></div>\', l = 53, e += \'<footer class="mdl-mega-footer spot-cell spot-trans spot-color4">\', l = 54, e += \'<div class="spot-footer">\', l = 58, e += \'<div class="spot-footer-item">\', l = 59, e += \'<a class="spotlink" data-hook="demo-session" href="">\', l = 60, e += \'<span class="footerImg material-icons menuIcon">\', l = 60, e += "ondemand_video</span>", l = 61, e += \'<span class="footerItem">\', l = 61, e += "Demo</span></a></div>", l = 62, e += \'<div class="spot-footer-item">\', l = 63, e += \'<a class="spotlink" data-hook="tutorialpage" href="https://nlesc.github.io/spot-tutorial/tutorial" target="_blank">\', l = 64, e += \'<span class="footerImg material-icons menuIcon">\', l = 64, e += "link</span>", l = 65, e += \'<span class="footerItem">\', l = 65, e += "Tutorial</span></a></div>", l = 66, e += \'<div class="spot-footer-item">\', l = 67, e += \'<a class="spotlink" data-hook="githubpage" href="https://github.com/NLeSC/spot" target="_blank">\', l = 68, e += \'<span class="footerImg material-icons menuIcon">\', l = 68, e += "link</span>", l = 69, e += \'<span class="footerItem">\', l = 69, e += "Project</span></a></div></div>", l = 70, e += \'<div class="spot-footer">\', l = 71, e += \'<span class="versionText">\', l = 71, e += "Version 0.2.0</span></div></footer></main>";\n    } catch (t) {\n      pug.rethrow(t, a, l);\n    }\n\n    return e;\n  };\n\n  puglatizer["main"] = function template(a) {\n    var l,\n        s,\n        t = "";\n\n    try {\n      s = 1, t += "<body>", s = 2, t += \'<div class="mdl-layout mdl-js-layout" data-hook="test">\', s = 4, t += \'<div class="mdl-layout__header-row mdl-color--blue-grey-900">\', s = 5, t += "\x3c!-- Title--\x3e", s = 6, t += \'<span class="mdl-layout-title mdl-layout--large-screen-only">\', s = 7, t += \'<a data-hook="nlescpage" href="https://www.esciencecenter.nl" target="_blank">\', s = 8, t += \'<div class="demo-avatar"></div></a></span>\', s = 9, t += "\x3c!-- Add spacer, to align navigation to the right--\x3e", s = 10, t += \'<div class="mdl-layout-spacer"></div>\', s = 11, t += "\x3c!-- Navigation. We hide it in small screens.--\x3e", s = 12, t += \'<nav class="mdl-navigation mdl-layout--large-screen-only">\', s = 13, t += \'<a class="mdl-navigation__link" href="/home">\', s = 13, t += "Home</a>", s = 14, t += \'<a class="mdl-navigation__link" href="/datasets">\', s = 14, t += "Data</a>", s = 15, t += \'<a class="mdl-navigation__link" href="/analyze">\', s = 15, t += "Analysis</a>", s = 16, t += \'<a class="mdl-navigation__link" href="#" data-hook="help-button" id="help-button">\', s = 17, t += \'<i class="material-icons">\', s = 17, t += "help</i></a></nav></div>", s = 24, t += \'<div class="mdl-drawer mdl-layout__drawer mdl-color--blue-grey-900 mdl-layout--small-screen-only">\', s = 25, t += \'<span class="mdl-layout-title">\', s = 27, t += \'<a data-hook="nlescpage" href="https://www.esciencecenter.nl" target="_blank">\', s = 28, t += \'<div class="demo-avatar" style="margin-top: 20px; margin-bottom: 50px;"></div></a></span>\', s = 29, t += \'<nav class="mdl-navigation">\', s = 30, t += \'<a class="mdl-navigation__link" href="/home">\', s = 30, t += "Home</a>", s = 31, t += \'<a class="mdl-navigation__link" href="/datasets">\', s = 31, t += "Data</a>", s = 32, t += \'<a class="mdl-navigation__link" href="/analyze">\', s = 32, t += "Dashboard</a>", s = 33, t += \'<a class="mdl-navigation__link" href="#" data-hook="help-button" id="help-button">\', s = 34, t += \'<i class="material-icons">\', s = 34, t += "help</i>", s = 35, t += "<span>", s = 35, t += "Help</span></a></nav>", s = 37, t += \'<div class="mdl-drawer-separator"></div>\', s = 38, t += \'<div class="mdl-layout-spacer" style="margin-top: 20px;"></div>\', s = 40, t += \'<nav class="mdl-navigation">\', s = 41, t += \'<a class="mdl-navigation__link" href="https://nlesc.github.io/spot-tutorial/tutorial">\', s = 41, t += "Tutorial</a>", s = 42, t += \'<a class="mdl-navigation__link" href="https://github.com/NLeSC/spot">\', s = 42, t += "Github</a></nav>", s = 44, t += \'<div class="mdl-drawer-separator"></div>\', s = 45, t += \'<div class="mdl-layout-spacer" style="margin-bottom: 20px;"></div>\', s = 46, t += \'<span class="versionText">\', s = 46, t += "Version 0.2.0</span></div>", s = 49, t += \'<div class="mdl-grid">\', s = 50, t += \'<dialog class="mdl-dialog" data-hook="main-dialog" id="main-dialog" style="border: none; width: min-content; background: transparent;">\', s = 51, t += \'<div class="mdl-dialog__content">\', s = 53, t += \'<p2 class="mdl-progress mdl-js-progress mdl-progress__indeterminate"></p2></div></dialog></div>\', s = 58, t += \'<main class="mdl-layout__content" data-hook="page-container"></main>\', s = 60, t += \'<div class="mdl-progress mdl-js-progress" id="progress-bar" style="width: 100%; height: 5%; display: none"></div>\', s = 62, t += \'<div class="mdl-js-snackbar mdl-snackbar" id="snack-bar" aria-live="assertive" aria-atomic="true" aria-relevant="text">\', s = 63, t += \'<div class="mdl-snackbar__text"></div>\', s = 64, t += \'<button class="mdl-snackbar__action" type="button"></button></div></div></body>\';\n    } catch (i) {\n      pug.rethrow(i, l, s);\n    }\n\n    return t;\n  };\n\n  return puglatizer;\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMyNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy90ZW1wbGF0ZXMuanM/ODI2MiJdLCJzb3VyY2VzQ29udGVudCI6WyI7KGZ1bmN0aW9uKHJvb3QsZmFjdG9yeSl7XHJcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XHJcbiAgICAgICAgZGVmaW5lKFtdLCBmYWN0b3J5KTtcclxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKSB7XHJcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICh0eXBlb2Ygcm9vdCA9PT0gJ3VuZGVmaW5lZCcgfHwgcm9vdCAhPT0gT2JqZWN0KHJvb3QpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigncHVnbGF0aXplcjogd2luZG93IGRvZXMgbm90IGV4aXN0IG9yIGlzIG5vdCBhbiBvYmplY3QnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcm9vdC5wdWdsYXRpemVyID0gZmFjdG9yeSgpO1xyXG4gICAgfVxyXG59KHRoaXMsIGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIHB1Z19jbGFzc2VzX29iamVjdCh2YWwpIHsgdmFyIGNsYXNzU3RyaW5nID0gJycsIHBhZGRpbmcgPSAnJzsgZm9yICh2YXIga2V5IGluIHZhbCkgeyBpZiAoa2V5ICYmIHZhbFtrZXldICYmIHB1Z19oYXNfb3duX3Byb3BlcnR5LmNhbGwodmFsLCBrZXkpKSB7IHZhciBjbGFzc1N0cmluZyA9IGNsYXNzU3RyaW5nICsgcGFkZGluZyArIGtleTsgdmFyIHBhZGRpbmcgPSAnICc7IH0gfSByZXR1cm4gY2xhc3NTdHJpbmc7IH0gICAgZnVuY3Rpb24gcHVnX2NsYXNzZXNfYXJyYXkodmFsLCBlc2NhcGluZykgeyB2YXIgY2xhc3NTdHJpbmcgPSAnJywgY2xhc3NOYW1lLCBwYWRkaW5nID0gJycsIGVzY2FwZUVuYWJsZWQgPSBBcnJheS5pc0FycmF5KGVzY2FwaW5nKTsgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWwubGVuZ3RoOyBpKyspIHsgdmFyIGNsYXNzTmFtZSA9IHB1Z19jbGFzc2VzKHZhbFtpXSk7IGlmICghY2xhc3NOYW1lKSBjb250aW51ZTsgZXNjYXBlRW5hYmxlZCAmJiBlc2NhcGluZ1tpXSAmJiAoY2xhc3NOYW1lID0gcHVnX2VzY2FwZShjbGFzc05hbWUpKTsgdmFyIGNsYXNzU3RyaW5nID0gY2xhc3NTdHJpbmcgKyBwYWRkaW5nICsgY2xhc3NOYW1lOyB2YXIgcGFkZGluZyA9ICcgJzsgfSByZXR1cm4gY2xhc3NTdHJpbmc7IH0gICAgZnVuY3Rpb24gcHVnX21lcmdlKGUscil7aWYoMT09PWFyZ3VtZW50cy5sZW5ndGgpe2Zvcih2YXIgdD1lWzBdLGc9MTtnPGUubGVuZ3RoO2crKyl0PXB1Z19tZXJnZSh0LGVbZ10pO3JldHVybiB0fWZvcih2YXIgbiBpbiByKWlmKFwiY2xhc3NcIj09PW4pe3ZhciBhPWVbbl18fFtdO2Vbbl09KEFycmF5LmlzQXJyYXkoYSk/YTpbYV0pLmNvbmNhdChyW25dfHxbXSl9ZWxzZSBpZihcInN0eWxlXCI9PT1uKXt2YXIgYT1wdWdfc3R5bGUoZVtuXSk7YT1hJiZcIjtcIiE9PWFbYS5sZW5ndGgtMV0/YStcIjtcIjphO3ZhciBsPXB1Z19zdHlsZShyW25dKTtsPWwmJlwiO1wiIT09bFtsLmxlbmd0aC0xXT9sK1wiO1wiOmwsZVtuXT1hK2x9ZWxzZSBlW25dPXJbbl07cmV0dXJuIGV9XHJcbiAgICBmdW5jdGlvbiBwdWdfY2xhc3NlcyhzLHIpe3JldHVybiBBcnJheS5pc0FycmF5KHMpP3B1Z19jbGFzc2VzX2FycmF5KHMscik6cyYmXCJvYmplY3RcIj09dHlwZW9mIHM/cHVnX2NsYXNzZXNfb2JqZWN0KHMpOnN8fFwiXCJ9XHJcbiAgICBmdW5jdGlvbiBwdWdfc3R5bGUocil7aWYoIXIpcmV0dXJuXCJcIjtpZihcIm9iamVjdFwiPT10eXBlb2Ygcil7dmFyIHQ9XCJcIjtmb3IodmFyIGUgaW4gcilwdWdfaGFzX293bl9wcm9wZXJ0eS5jYWxsKHIsZSkmJih0PXQrZStcIjpcIityW2VdK1wiO1wiKTtyZXR1cm4gdH1yZXR1cm4gcitcIlwifVxyXG4gICAgZnVuY3Rpb24gcHVnX2F0dHIodCxlLG4sZil7cmV0dXJuIGUhPT0hMSYmbnVsbCE9ZSYmKGV8fFwiY2xhc3NcIiE9PXQmJlwic3R5bGVcIiE9PXQpP2U9PT0hMD9cIiBcIisoZj90OnQrJz1cIicrdCsnXCInKTooXCJmdW5jdGlvblwiPT10eXBlb2YgZS50b0pTT04mJihlPWUudG9KU09OKCkpLFwic3RyaW5nXCI9PXR5cGVvZiBlfHwoZT1KU09OLnN0cmluZ2lmeShlKSxufHwtMT09PWUuaW5kZXhPZignXCInKSk/KG4mJihlPXB1Z19lc2NhcGUoZSkpLFwiIFwiK3QrJz1cIicrZSsnXCInKTpcIiBcIit0K1wiPSdcIitlLnJlcGxhY2UoLycvZyxcIiYjMzk7XCIpK1wiJ1wiKTpcIlwifVxyXG4gICAgZnVuY3Rpb24gcHVnX2F0dHJzKHQscil7dmFyIGE9XCJcIjtmb3IodmFyIHMgaW4gdClpZihwdWdfaGFzX293bl9wcm9wZXJ0eS5jYWxsKHQscykpe3ZhciB1PXRbc107aWYoXCJjbGFzc1wiPT09cyl7dT1wdWdfY2xhc3Nlcyh1KSxhPXB1Z19hdHRyKHMsdSwhMSxyKSthO2NvbnRpbnVlfVwic3R5bGVcIj09PXMmJih1PXB1Z19zdHlsZSh1KSksYSs9cHVnX2F0dHIocyx1LCExLHIpfXJldHVybiBhfVxyXG4gICAgZnVuY3Rpb24gcHVnX2VzY2FwZShlKXt2YXIgYT1cIlwiK2UsdD0oL1tcIiY8Pl0vKS5leGVjKGEpO2lmKCF0KXJldHVybiBlO3ZhciByLGMsbixzPVwiXCI7Zm9yKHI9dC5pbmRleCxjPTA7cjxhLmxlbmd0aDtyKyspe3N3aXRjaChhLmNoYXJDb2RlQXQocikpe2Nhc2UgMzQ6bj1cIiZxdW90O1wiO2JyZWFrO2Nhc2UgMzg6bj1cIiZhbXA7XCI7YnJlYWs7Y2FzZSA2MDpuPVwiJmx0O1wiO2JyZWFrO2Nhc2UgNjI6bj1cIiZndDtcIjticmVhaztkZWZhdWx0OmNvbnRpbnVlfWMhPT1yJiYocys9YS5zdWJzdHJpbmcoYyxyKSksYz1yKzEscys9bn1yZXR1cm4gYyE9PXI/cythLnN1YnN0cmluZyhjLHIpOnN9XHJcbiAgICBmdW5jdGlvbiBwdWdfcmV0aHJvdyhuLGUscix0KXtpZighKG4gaW5zdGFuY2VvZiBFcnJvcikpdGhyb3cgbjtpZighKFwidW5kZWZpbmVkXCI9PXR5cGVvZiB3aW5kb3cmJmV8fHQpKXRocm93IG4ubWVzc2FnZSs9XCIgb24gbGluZSBcIityLG47dHJ5e3Q9dHx8cmVxdWlyZShcImZzXCIpLnJlYWRGaWxlU3luYyhlLFwidXRmOFwiKX1jYXRjaChpKXtwdWdfcmV0aHJvdyhuLG51bGwscil9dmFyIGE9MyxvPXQuc3BsaXQoXCJcXG5cIiksaD1NYXRoLm1heChyLWEsMCkscz1NYXRoLm1pbihvLmxlbmd0aCxyK2EpLGE9by5zbGljZShoLHMpLm1hcChmdW5jdGlvbihuLGUpe3ZhciB0PWUraCsxO3JldHVybih0PT1yP1wiICA+IFwiOlwiICAgIFwiKSt0K1wifCBcIitufSkuam9pbihcIlxcblwiKTt0aHJvdyBuLnBhdGg9ZSxuLm1lc3NhZ2U9KGV8fFwiUHVnXCIpK1wiOlwiK3IrXCJcXG5cIithK1wiXFxuXFxuXCIrbi5tZXNzYWdlLG59XHJcbiAgICB2YXIgcHVnID0ge1xyXG4gICAgXHRtZXJnZTpmdW5jdGlvbiBwdWdfbWVyZ2UoZSxyKXtpZigxPT09YXJndW1lbnRzLmxlbmd0aCl7Zm9yKHZhciB0PWVbMF0sZz0xO2c8ZS5sZW5ndGg7ZysrKXQ9cHVnX21lcmdlKHQsZVtnXSk7cmV0dXJuIHR9Zm9yKHZhciBuIGluIHIpaWYoXCJjbGFzc1wiPT09bil7dmFyIGE9ZVtuXXx8W107ZVtuXT0oQXJyYXkuaXNBcnJheShhKT9hOlthXSkuY29uY2F0KHJbbl18fFtdKX1lbHNlIGlmKFwic3R5bGVcIj09PW4pe3ZhciBhPXB1Z19zdHlsZShlW25dKTthPWEmJlwiO1wiIT09YVthLmxlbmd0aC0xXT9hK1wiO1wiOmE7dmFyIGw9cHVnX3N0eWxlKHJbbl0pO2w9bCYmXCI7XCIhPT1sW2wubGVuZ3RoLTFdP2wrXCI7XCI6bCxlW25dPWErbH1lbHNlIGVbbl09cltuXTtyZXR1cm4gZX0sXHJcbiAgICBcdGNsYXNzZXM6ZnVuY3Rpb24gcHVnX2NsYXNzZXMocyxyKXtyZXR1cm4gQXJyYXkuaXNBcnJheShzKT9wdWdfY2xhc3Nlc19hcnJheShzLHIpOnMmJlwib2JqZWN0XCI9PXR5cGVvZiBzP3B1Z19jbGFzc2VzX29iamVjdChzKTpzfHxcIlwifSxcclxuICAgIFx0c3R5bGU6ZnVuY3Rpb24gcHVnX3N0eWxlKHIpe2lmKCFyKXJldHVyblwiXCI7aWYoXCJvYmplY3RcIj09dHlwZW9mIHIpe3ZhciB0PVwiXCI7Zm9yKHZhciBlIGluIHIpcHVnX2hhc19vd25fcHJvcGVydHkuY2FsbChyLGUpJiYodD10K2UrXCI6XCIrcltlXStcIjtcIik7cmV0dXJuIHR9cmV0dXJuIHIrXCJcIn0sXHJcbiAgICBcdGF0dHI6ZnVuY3Rpb24gcHVnX2F0dHIodCxlLG4sZil7cmV0dXJuIGUhPT0hMSYmbnVsbCE9ZSYmKGV8fFwiY2xhc3NcIiE9PXQmJlwic3R5bGVcIiE9PXQpP2U9PT0hMD9cIiBcIisoZj90OnQrJz1cIicrdCsnXCInKTooXCJmdW5jdGlvblwiPT10eXBlb2YgZS50b0pTT04mJihlPWUudG9KU09OKCkpLFwic3RyaW5nXCI9PXR5cGVvZiBlfHwoZT1KU09OLnN0cmluZ2lmeShlKSxufHwtMT09PWUuaW5kZXhPZignXCInKSk/KG4mJihlPXB1Z19lc2NhcGUoZSkpLFwiIFwiK3QrJz1cIicrZSsnXCInKTpcIiBcIit0K1wiPSdcIitlLnJlcGxhY2UoLycvZyxcIiYjMzk7XCIpK1wiJ1wiKTpcIlwifSxcclxuICAgIFx0YXR0cnM6ZnVuY3Rpb24gcHVnX2F0dHJzKHQscil7dmFyIGE9XCJcIjtmb3IodmFyIHMgaW4gdClpZihwdWdfaGFzX293bl9wcm9wZXJ0eS5jYWxsKHQscykpe3ZhciB1PXRbc107aWYoXCJjbGFzc1wiPT09cyl7dT1wdWdfY2xhc3Nlcyh1KSxhPXB1Z19hdHRyKHMsdSwhMSxyKSthO2NvbnRpbnVlfVwic3R5bGVcIj09PXMmJih1PXB1Z19zdHlsZSh1KSksYSs9cHVnX2F0dHIocyx1LCExLHIpfXJldHVybiBhfSxcclxuICAgIFx0ZXNjYXBlOmZ1bmN0aW9uIHB1Z19lc2NhcGUoZSl7dmFyIGE9XCJcIitlLHQ9KC9bXCImPD5dLykuZXhlYyhhKTtpZighdClyZXR1cm4gZTt2YXIgcixjLG4scz1cIlwiO2ZvcihyPXQuaW5kZXgsYz0wO3I8YS5sZW5ndGg7cisrKXtzd2l0Y2goYS5jaGFyQ29kZUF0KHIpKXtjYXNlIDM0Om49XCImcXVvdDtcIjticmVhaztjYXNlIDM4Om49XCImYW1wO1wiO2JyZWFrO2Nhc2UgNjA6bj1cIiZsdDtcIjticmVhaztjYXNlIDYyOm49XCImZ3Q7XCI7YnJlYWs7ZGVmYXVsdDpjb250aW51ZX1jIT09ciYmKHMrPWEuc3Vic3RyaW5nKGMscikpLGM9cisxLHMrPW59cmV0dXJuIGMhPT1yP3MrYS5zdWJzdHJpbmcoYyxyKTpzfSxcclxuICAgIFx0cmV0aHJvdzpmdW5jdGlvbiBwdWdfcmV0aHJvdyhuLGUscix0KXtpZighKG4gaW5zdGFuY2VvZiBFcnJvcikpdGhyb3cgbjtpZighKFwidW5kZWZpbmVkXCI9PXR5cGVvZiB3aW5kb3cmJmV8fHQpKXRocm93IG4ubWVzc2FnZSs9XCIgb24gbGluZSBcIityLG47dHJ5e3Q9dHx8cmVxdWlyZShcImZzXCIpLnJlYWRGaWxlU3luYyhlLFwidXRmOFwiKX1jYXRjaChpKXtwdWdfcmV0aHJvdyhuLG51bGwscil9dmFyIGE9MyxvPXQuc3BsaXQoXCJcXG5cIiksaD1NYXRoLm1heChyLWEsMCkscz1NYXRoLm1pbihvLmxlbmd0aCxyK2EpLGE9by5zbGljZShoLHMpLm1hcChmdW5jdGlvbihuLGUpe3ZhciB0PWUraCsxO3JldHVybih0PT1yP1wiICA+IFwiOlwiICAgIFwiKSt0K1wifCBcIitufSkuam9pbihcIlxcblwiKTt0aHJvdyBuLnBhdGg9ZSxuLm1lc3NhZ2U9KGV8fFwiUHVnXCIpK1wiOlwiK3IrXCJcXG5cIithK1wiXFxuXFxuXCIrbi5tZXNzYWdlLG59XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHB1Z2xhdGl6ZXIgPSB7fVxyXG4gICAgcHVnbGF0aXplcltcImFuYWx5emVcIl0gPSB7fVxyXG4gICAgcHVnbGF0aXplcltcImFuYWx5emVcIl1bXCJmYWNldGJhckl0ZW1cIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZShhKXt2YXIgdCxlLGM9XCJcIjt0cnl7ZT0xLGMrPSc8c3BhbiBjbGFzcz1cIm1kbC1jaGlwIHZhcmlhYmxlQ2hpcFwiIGRhdGEtaG9vaz1cImZhY2V0LWJhci1pdGVtXCIgaWQ9XCJcIj4nLGU9MixjKz0nPHNwYW4gY2xhc3M9XCJtZGwtY2hpcF9fdGV4dFwiIGRhdGEtaG9vaz1cImZhY2V0LWJhci1pdGVtLWJ1dHRvblwiPjwvc3Bhbj48L3NwYW4+J31jYXRjaChwKXtwdWcucmV0aHJvdyhwLHQsZSl9cmV0dXJuIGN9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJhbmFseXplXCJdW1wicGFnZVwiXSA9IGZ1bmN0aW9uIHRlbXBsYXRlKHQpe3ZhciBhLG8sbD1cIlwiO3RyeXtvPTEsbCs9JzxkaXYgY2xhc3M9XCJtZGwtbGF5b3V0IG1kbC1qcy1sYXlvdXQgbWRsLWxheW91dC0tZml4ZWQtaGVhZGVyXCI+JyxvPTIsbCs9JzxtYWluIGNsYXNzPVwibWRsLWxheW91dF9fY29udGVudFwiIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XCI+JyxvPTMsbCs9JzxoZWFkZXIgY2xhc3M9XCJkZW1vLWhlYWRlciBtZGwtbGF5b3V0X19oZWFkZXIgc3BvdC1jb2xvci10b3AtYmFyIG1kbC1jb2xvci10ZXh0LS1ncmV5LTYwMFwiPicsbz01LGwrPSc8ZGl2IGNsYXNzPVwibWRsLWxheW91dF9faGVhZGVyLXJvd1wiPicsbz02LGwrPSc8c3BhbiBjbGFzcz1cIm1kbC1sYXlvdXQtdGl0bGUgdW5zZWxlY3RhYmxlXCI+JyxvPTYsbCs9XCJBbmFseXplPC9zcGFuPlwiLG89OCxsKz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQtc3BhY2VyXCI+PC9kaXY+JyxvPTEwLGwrPSc8c3BhbiBjbGFzcz1cInVuc2VsZWN0YWJsZVwiIGRhdGEtaG9vaz1cImRhdGEtc3RyaW5nXCI+PC9zcGFuPicsbz0xMixsKz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQtc3BhY2VyXCI+PC9kaXY+JyxvPTE0LGwrPSc8c3BhbiBkYXRhLXBvc2l0aW9uPVwiYm90dG9tXCIgZGF0YS1zdGVwPVwiMFwiIGRhdGEtaGludD1cIlwiPjwvc3Bhbj4nLG89MTYsbCs9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWJ1dHRvbi0taWNvbiBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGlkPVwic2F2ZVNlc3Npb25CdXR0b25cIiBkYXRhLWhpbnRQb3NpdGlvbj1cImJvdHRvbVwiIGRhdGEtcG9zaXRpb249XCJib3R0b21cIiBkYXRhLWhpbnQ9XCJUaGlzIGJ1dHRvbnMgc2F2ZXMgdGhlIGN1cnJlbnQgc2Vzc2lvbi5cIj4nLG89MTcsbCs9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj4nLG89MTcsbCs9XCJzYXZlPC9pPjwvYnV0dG9uPlwiLG89MTgsbCs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJzYXZlU2Vzc2lvbkJ1dHRvblwiPicsbz0xOSxsKz1cIlNhdmUgdGhlIHNlc3Npb248L2Rpdj5cIixvPTIxLGwrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtanMtYnV0dG9uIG1kbC1idXR0b24tLWljb24gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIiBpZD1cInJlc2V0RmlsdGVyc0J1dHRvblwiIGRhdGEtcG9zaXRpb249XCJib3R0b21cIiBkYXRhLXN0ZXA9XCIxXCIgZGF0YS1oaW50PVwiVGhpcyBidXR0b24gY2xlYXJzIGFsbCBleGlzdGluZyBmaWx0ZXJzLlwiPicsbz0yMixsKz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPicsbz0yMixsKz1cImNsZWFyX2FsbDwvaT48L2J1dHRvbj5cIixvPTIzLGwrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlXCIgZm9yPVwicmVzZXRGaWx0ZXJzQnV0dG9uXCI+JyxvPTI0LGwrPVwiQ2xlYXIgYWxsIGZpbHRlcnMgb2YgYWxsIHBsb3RzPC9kaXY+XCIsbz0yNixsKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWpzLWJ1dHRvbiBtZGwtYnV0dG9uLS1pY29uIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgaWQ9XCJ2aWV3QWxsXCIgZGF0YS1wb3NpdGlvbj1cImJvdHRvbVwiIGRhdGEtc3RlcD1cIjJcIiBkYXRhLWhpbnQ9XCJUaGlzIGJ1dHRvbiBjbG9zZXMgYWxsIGNvbmZpZ3VyYXRpb24gd2luZG93c1wiPicsbz0yNyxsKz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPicsbz0yNyxsKz1cImNyb3Bfb3JpZ2luYWw8L2k+PC9idXR0b24+XCIsbz0yOCxsKz0nPGRpdiBjbGFzcz1cIm1kbC10b29sdGlwIG1kbC10b29sdGlwLS1sYXJnZVwiIGZvcj1cInZpZXdBbGxcIj4nLG89MjksbCs9XCJDbG9zZSBhbGwgY29uZmlndXJhdGlvbiB3aW5kb3dzPC9kaXY+XCIsbz0zMSxsKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWpzLWJ1dHRvbiBtZGwtYnV0dG9uLS1pY29uIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgaWQ9XCJmdWxsc2NyZWVuQnV0dG9uXCIgZGF0YS1wb3NpdGlvbj1cImJvdHRvbVwiIGRhdGEtc3RlcD1cIjNcIiBkYXRhLWhpbnQ9XCJUaGlzIGJ1dHRvbiBoaWRlcyBmYWNldCBhbmQgY2hhcnQgYmFycy5cIj4nLG89MzIsbCs9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj4nLG89MzIsbCs9XCJmdWxsc2NyZWVuPC9pPjwvYnV0dG9uPlwiLG89MzMsbCs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJmdWxsc2NyZWVuQnV0dG9uXCI+JyxvPTM0LGwrPVwiU2hvdyBvciBoaWRlIGNoYXJ0IGFuZCBmYWNldCBiYXJzPC9kaXY+PC9kaXY+XCIsbz0zNixsKz0nPGRpdiBjbGFzcz1cImNoYXJ0QmFyIHNwb3QtY29sb3ItdG9wLWJhciBtZGwtY29sb3ItdGV4dC0tZ3JleS02MDBcIiBkYXRhLWhvb2s9XCJjaGFydC1iYXJcIiBkYXRhLXBvc2l0aW9uPVwiYm90dG9tXCIgZGF0YS1zdGVwPVwiNFwiIGRhdGEtaGludD1cIlRoZXNlIGFyZSB0aGUgYXZhaWxhYmxlIGNoYXJ0IHR5cGVzLiBJZiB5b3Ugd2FudCB0byBhZGQgYSBjaGFydCwganVzdCAmbHQ7YiZndDtjbGljayZsdDsvYiZndDsgb24gaXRzIGljb24gYW5kIGl0IHdpbGwgYmUgY3JlYXRlZCEgU2ltcGxlLCByaWdodD8gXCI+JyxvPTM3LGwrPSc8c3BhbiBjbGFzcz1cImNoYXJ0QmFyVGV4dFwiPicsbz0zNyxsKz1cIkNsaWNrIG9uIGEgY2hhcnQgaWNvbiB0byBzdGFydCBhIG5ldyBwbG90PC9zcGFuPlwiLG89MzksbCs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sIGhvcml6b250YWxiYXJjaGFydEljb24gd2lkZ2V0SWNvblwiIGRhdGEtaG9vaz1cImhvcml6b250YWxiYXJjaGFydFwiIGlkPVwiaG9yaXpvbnRhbGJhcmNoYXJ0XCIgZGF0YS1wb3NpdGlvbj1cImJvdHRvbVwiIGRhdGEtc3RlcD1cIjVcIiBkYXRhLWhpbnQ9XCJUaGlzIGFkZHMgYSBob3Jpem9udGFsIGJhciBjaGFydChoaXN0b2dyYW0pLiBUaGlzIGlzIGdvb2QgZm9yIGNhdGVnb3JpY2FsIGZhY2V0cy5cIj48L2Rpdj4nLG89NDAsbCs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJob3Jpem9udGFsYmFyY2hhcnRcIj4nLG89NDEsbCs9XCJDbGljayB0byBhZGQgYSBob3Jpem9udGFsIGJhciBjaGFydDwvZGl2PlwiLG89NDMsbCs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sIGJhcmNoYXJ0SWNvbiB3aWRnZXRJY29uXCIgZGF0YS1ob29rPVwiYmFyY2hhcnRcIiBpZD1cImJhcmNoYXJ0XCIgZGF0YS1wb3NpdGlvbj1cImJvdHRvbVwiIGRhdGEtc3RlcD1cIjZcIiBkYXRhLWhpbnQ9XCJUaGlzIGFkZHMgYSB2ZXJ0aWNhbCBiYXIgY2hhcnQuXCI+PC9kaXY+JyxvPTQ0LGwrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlXCIgZm9yPVwiYmFyY2hhcnRcIj4nLG89NDUsbCs9XCJDbGljayB0byBhZGQgYSBiYXIgY2hhcnQ8L2Rpdj5cIixvPTQ3LGwrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbCBsaW5lY2hhcnRJY29uIHdpZGdldEljb25cIiBkYXRhLWhvb2s9XCJsaW5lY2hhcnRcIiBpZD1cImxpbmVjaGFydFwiIGRhdGEtcG9zaXRpb249XCJib3R0b21cIiBkYXRhLXN0ZXA9XCI3XCIgZGF0YS1oaW50PVwiVGhpcyBhZGRzIGEgbGluZSBjaGFydC5cIj48L2Rpdj4nLG89NDgsbCs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJsaW5lY2hhcnRcIj4nLG89NDksbCs9XCJDbGljayB0byBhZGQgYSBsaW5lIGNoYXJ0PC9kaXY+XCIsbz01MSxsKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xMi1jb2wgcGllY2hhcnRJY29uIHdpZGdldEljb25cIiBkYXRhLWhvb2s9XCJwaWVjaGFydFwiIGlkPVwicGllY2hhcnRcIiBkYXRhLXBvc2l0aW9uPVwiYm90dG9tXCIgZGF0YS1zdGVwPVwiOFwiIGRhdGEtaGludD1cIlRoaXMgYWRkcyBhIHBpZSBjaGFydC5cIj48L2Rpdj4nLG89NTIsbCs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJwaWVjaGFydFwiPicsbz01MyxsKz1cIkNsaWNrIHRvIGFkZCBhIHBpZSBjaGFydDwvZGl2PlwiLG89NTUsbCs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sIGJ1YmJsZXBsb3RJY29uIHdpZGdldEljb25cIiBkYXRhLWhvb2s9XCJidWJibGVwbG90XCIgaWQ9XCJidWJibGVwbG90XCIgZGF0YS1wb3NpdGlvbj1cImJvdHRvbVwiIGRhdGEtc3RlcD1cIjlcIiBkYXRhLWhpbnQ9XCJUaGlzIGFkZHMgYSBidWJsZSBjaGFydC5cIj48L2Rpdj4nLG89NTYsbCs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJidWJibGVwbG90XCI+JyxvPTU3LGwrPVwiQ2xpY2sgdG8gYWRkIGEgYnViYmxlcGxvdCBjaGFydDwvZGl2PlwiLG89NTksbCs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sIHNjYXR0ZXJjaGFydEljb24gd2lkZ2V0SWNvblwiIGRhdGEtaG9vaz1cInNjYXR0ZXJjaGFydFwiIGlkPVwic2NhdHRlcmNoYXJ0XCIgZGF0YS1wb3NpdGlvbj1cImJvdHRvbVwiIGRhdGEtc3RlcD1cIjEwXCIgZGF0YS1oaW50PVwiVGhpcyBhZGRzIGEgM0Qgc2NhdHRlciBjaGFydC5cIj48L2Rpdj4nLG89NjAsbCs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJzY2F0dGVyY2hhcnRcIj4nLG89NjEsbCs9XCJDbGljayB0byBhZGQgYSAzZCBzY2F0dGVyIGNoYXJ0PC9kaXY+XCIsbz02MyxsKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xMi1jb2wgcmFkYXJjaGFydEljb24gd2lkZ2V0SWNvblwiIGRhdGEtaG9vaz1cInJhZGFyY2hhcnRcIiBpZD1cInJhZGFyY2hhcnRcIiBkYXRhLXBvc2l0aW9uPVwiYm90dG9tXCIgZGF0YS1zdGVwPVwiMTFcIiBkYXRhLWhpbnQ9XCJUaGlzIGFkZHMgYSByYWRhciBjaGFydC5cIj48L2Rpdj4nLG89NjQsbCs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJyYWRhcmNoYXJ0XCI+JyxvPTY1LGwrPVwiQ2xpY2sgdG8gYWRkIGEgcmFkYXIgY2hhcnQ8L2Rpdj5cIixvPTY3LGwrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbCBuZXR3b3JrY2hhcnRJY29uIHdpZGdldEljb25cIiBkYXRhLWhvb2s9XCJuZXR3b3JrY2hhcnRcIiBpZD1cIm5ldHdvcmtjaGFydFwiIGRhdGEtcG9zaXRpb249XCJib3R0b21cIiBkYXRhLXN0ZXA9XCIxMlwiIGRhdGEtaGludD1cIlRoaXMgYWRkcyBhIG5ldHdvcmsgY2hhcnQuXCI+PC9kaXY+JyxvPTY4LGwrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlXCIgZm9yPVwibmV0d29ya2NoYXJ0XCI+JyxvPTY5LGwrPVwiQ2xpY2sgdG8gYWRkIGEgbmV0d29yayBjaGFydDwvZGl2PjwvZGl2PlwiLG89NzEsbCs9JzxkaXYgY2xhc3M9XCJmYWNldEJhciBzcG90LWNvbG9yLXRvcC1iYXJcIiBkYXRhLWhvb2s9XCJmYWNldC1iYXJcIiBpZD1cImZhY2V0LWJhclwiIGRhdGEtcG9zaXRpb249XCJib3R0b21cIiBkYXRhLXN0ZXA9XCIxM1wiIGRhdGEtaGludD1cIlRoaXMgaXMgd2hlcmUgeW91IHdpbGwgaGF2ZSB5b3VyIHZhcmlhYmxlcyhmYWNldHMpLiBKdXN0ICZsdDtiJmd0O2RyYWcgYW5kIGRyb3AmbHQ7L2ImZ3Q7IHRoZXNlIGZhY2V0cyB0byBmaWVsZCBvZiB0aGUgY2hhcnRzIHRvIHZpc3VhbGl6ZS5cIj4nLG89NzIsbCs9JzxzcGFuIGNsYXNzPVwiZmFjZXRCYXJUZXh0XCI+JyxvPTcyLGwrPVwiRHJvcCB2YXJpYWJsZSBvbiBhIGNoYXJ0LCBvciBjbGljayB0byBlZGl0PC9zcGFuPlwiLG89NzMsbCs9JzxkaXYgY2xhc3M9XCJmYWNldEJhckl0ZW1zXCIgZGF0YS1ob29rPVwiZmFjZXQtYmFyLWl0ZW1zXCIgaWQ9XCJmYWNldEJhclwiPjwvZGl2PjwvZGl2Picsbz03NCxsKz0nPGRpdiBjbGFzcz1cIm1kbC10b29sdGlwIG1kbC10b29sdGlwLS1sYXJnZVwiIGlkPVwiZmFjZXQtYmFyLXRvb2x0aXBcIiBmb3I9XCJmYWNldC1iYXJcIj4nLG89NzUsbCs9XCJEcm9wIHZhcmlhYmxlIG9uIGEgY2hhcnQsIG9yIGNsaWNrIHRvIGVkaXQ8L2Rpdj48L2hlYWRlcj5cIixvPTc3LGwrPSc8ZGl2IGNsYXNzPVwid2lkZ2V0RHJvcFpvbmVcIiBpZD1cIndpZGdldHNcIiBkYXRhLWhvb2s9XCJ3aWRnZXRzXCI+PC9kaXY+PC9tYWluPjwvZGl2Pid9Y2F0Y2goaSl7cHVnLnJldGhyb3coaSxhLG8pfXJldHVybiBsfTtcclxuXHJcbiAgICBwdWdsYXRpemVyW1wiYW5hbHl6ZVwiXVtcInNsb3RcIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZSh0KXt2YXIgbyxhLGQ9XCJcIjt0cnl7YT0xLGQrPSc8ZGl2IGNsYXNzPVwic2xvdCBtZGwtc2hhZG93LS0yZHBcIiBkYXRhLWhvb2s9XCJzbG90XCI+JyxhPTIsZCs9JzxkaXYgY2xhc3M9XCJzbG90VGV4dCBjbGlja1RhcmdldFwiPicsYT0zLGQrPSc8YiBkYXRhLWhvb2s9XCJkZXNjcmlwdGlvblwiPjwvYj4nLGE9NCxkKz1cIjxici8+XCIsYT01LGQrPSc8aSBkYXRhLWhvb2s9XCJyZXF1aXJlZFwiPjwvaT48L2Rpdj4nLGE9NixkKz0nPGRpdiBjbGFzcz1cInNsb3RDaGlwIGNsaWNrVGFyZ2V0XCIgZGF0YS1ob29rPVwiZHJvcC16b25lXCI+JyxhPTcsZCs9JzxzcGFuIGRhdGEtaG9vaz1cImNoaXAtdGV4dFwiPjwvc3Bhbj48L2Rpdj4nLGE9OCxkKz0nPGRpdiBjbGFzcz1cInNsb3RCdXR0b25cIiBkYXRhLWhvb2s9XCJidXR0b24tZGl2XCI+JyxhPTksZCs9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWJ1dHRvbi0taWNvblwiIGRhdGEtaG9vaz1cImRlbGV0ZVwiPicsYT0xMCxkKz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPicsYT0xMCxkKz1cImRlbGV0ZTwvaT48L2J1dHRvbj48L2Rpdj48L2Rpdj5cIn1jYXRjaChpKXtwdWcucmV0aHJvdyhpLG8sYSl9cmV0dXJuIGR9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJhbmFseXplXCJdW1wid2lkZ2V0RnJhbWVcIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZSh0KXt2YXIgbyxsLGk9XCJcIjt0cnl7bD0xLGkrPSc8ZGl2IGNsYXNzPVwid2lkZ2V0RnJhbWUgbWRsLWNvbG9yLS13aGl0ZSBtZGwtc2hhZG93LS0yZHBcIj4nLGw9MyxpKz0nPGRpdiBjbGFzcz1cImNvbmZpZ1ZpZXdcIiBkYXRhLWhvb2s9XCJjb25maWctdmlld1wiPicsbD00LGkrPSc8ZGl2IGNsYXNzPVwid2lkZ2V0RHJhZ0JhclwiPicsbD01LGkrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtYnV0dG9uLS1pY29uIG1kbC1qcy1idXR0b24gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIiBkYXRhLWhvb2s9XCJjbG9zZVwiIGlkPVwiY2hhcnREZWxldGVCdXR0b24yXCI+JyxsPTYsaSs9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj4nLGw9NixpKz1cImRlbGV0ZTwvaT48L2J1dHRvbj5cIixsPTcsaSs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJjaGFydERlbGV0ZUJ1dHRvbjJcIj4nLGw9OCxpKz1cIkRlbGV0ZSB0aGlzIGNoYXJ0PC9kaXY+XCIsbD05LGkrPSc8c3BhbiBjbGFzcz1cIndpZGdldEhlYWRlclwiIGRhdGEtaG9vaz1cIndpZGdldEhlYWRlclwiPjwvc3Bhbj4nLGw9MTAsaSs9JzxkaXYgY2xhc3M9XCJtZGwtbGF5b3V0LXNwYWNlclwiPjwvZGl2PicsbD0xMSxpKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWJ1dHRvbi0taWNvbiBtZGwtanMtYnV0dG9uIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZGF0YS1ob29rPVwiZWRpdFwiIHN0eWxlPVwiZmxvYXQ6IHJpZ2h0XCIgaWQ9XCJjaGFydERvbmVCdXR0b25cIj4nLGw9MTIsaSs9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj4nLGw9MTIsaSs9XCJkb25lPC9pPjwvYnV0dG9uPlwiLGw9MTMsaSs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJjaGFydERvbmVCdXR0b25cIj4nLGw9MTQsaSs9XCJDbG9zZSBjb25maWd1cmF0aW9uIHZpZXc8L2Rpdj48L2Rpdj5cIixsPTE2LGkrPSc8ZGl2IGNsYXNzPVwic2xvdHNcIiBkYXRhLWhvb2s9XCJzbG90c1wiPjwvZGl2PjwvZGl2PicsbD0xOCxpKz0nPGRpdiBjbGFzcz1cIndpZGdldFZpZXdcIiBkYXRhLWhvb2s9XCJ3aWRnZXRcIj48L2Rpdj4nLGw9MjAsaSs9JzxkaXYgY2xhc3M9XCJwbG90TWVudVwiIGRhdGEtaG9vaz1cInBsb3QtbWVudVwiIHN0eWxlPVwid2lkdGg6IDEwMCU7XCI+JyxsPTIxLGkrPSc8ZGl2IGNsYXNzPVwid2lkZ2V0RHJhZ0JhclwiPicsbD0yMixpKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWJ1dHRvbi0taWNvbiBtZGwtanMtYnV0dG9uIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZGF0YS1ob29rPVwiY2xvc2VcIiBpZD1cImNoYXJ0RGVsZXRlQnV0dG9uMVwiPicsbD0yMyxpKz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPicsbD0yMyxpKz1cImRlbGV0ZTwvaT48L2J1dHRvbj5cIixsPTI0LGkrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlXCIgZm9yPVwiY2hhcnREZWxldGVCdXR0b24xXCI+JyxsPTI1LGkrPVwiRGVsZXRlIHRoaXMgY2hhcnQ8L2Rpdj5cIixsPTI2LGkrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtYnV0dG9uLS1pY29uIG1kbC1qcy1idXR0b24gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIiBkYXRhLWhvb2s9XCJ6b29tLW91dFwiIGlkPVwiY2hhcnRVbmRvQnV0dG9uXCI+JyxsPTI3LGkrPSc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+JyxsPTI3LGkrPVwidW5kbzwvaT48L2J1dHRvbj5cIixsPTI4LGkrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlXCIgZm9yPVwiY2hhcnRVbmRvQnV0dG9uXCI+JyxsPTI5LGkrPVwiVW5kbyBzZWxlY3Rpb248L2Rpdj5cIixsPTMwLGkrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtYnV0dG9uLS1pY29uIG1kbC1qcy1idXR0b24gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIiBkYXRhLWhvb2s9XCJ6b29tLWluXCIgaWQ9XCJjaGFydFpvb21CdXR0b25cIj4nLGw9MzEsaSs9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj4nLGw9MzEsaSs9XCJ6b29tX2luPC9pPjwvYnV0dG9uPlwiLGw9MzIsaSs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJjaGFydFpvb21CdXR0b25cIj4nLGw9MzMsaSs9XCJab29tIGludG8gc2VsZWN0ZWQgcmVnaW9uPC9kaXY+XCIsbD0zNCxpKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWJ1dHRvbi0taWNvbiBtZGwtanMtYnV0dG9uIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZGF0YS1ob29rPVwic2F2ZVwiIGlkPVwiY2hhcnRTYXZlXCI+JyxsPTM1LGkrPSc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+JyxsPTM1LGkrPVwic2F2ZTwvaT48L2J1dHRvbj5cIixsPTM2LGkrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlXCIgZm9yPVwiY2hhcnRTYXZlXCI+JyxsPTM3LGkrPVwiU2F2ZSB0aGlzIGNoYXJ0PC9kaXY+XCIsbD0zOCxpKz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQtc3BhY2VyXCI+PC9kaXY+JyxsPTM5LGkrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtYnV0dG9uLS1pY29uIG1kbC1qcy1idXR0b24gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIiBkYXRhLWhvb2s9XCJlZGl0XCIgc3R5bGU9XCJmbG9hdDogcmlnaHQ7XCIgaWQ9XCJjaGFydENvbmZCdXR0b25cIj4nLGw9NDAsaSs9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj4nLGw9NDAsaSs9XCJjcmVhdGU8L2k+PC9idXR0b24+XCIsbD00MSxpKz0nPGRpdiBjbGFzcz1cIm1kbC10b29sdGlwIG1kbC10b29sdGlwLS1sYXJnZVwiIGZvcj1cImNoYXJ0Q29uZkJ1dHRvblwiPicsbD00MixpKz1cIk9wZW4gY29uZmlndXJhdGlvbiB2aWV3PC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+XCJ9Y2F0Y2goYSl7cHVnLnJldGhyb3coYSxvLGwpfXJldHVybiBpfTtcclxuXHJcbiAgICBwdWdsYXRpemVyW1wiY29uZmlndXJlRGF0YXNldFwiXSA9IHt9XHJcbiAgICBwdWdsYXRpemVyW1wiY29uZmlndXJlRGF0YXNldFwiXVtcImZhY2V0XCJdID0gZnVuY3Rpb24gdGVtcGxhdGUodCl7dmFyIGwsYSxkPVwiXCI7dHJ5e2E9MSxkKz0nPGRpdiBjbGFzcz1cIm1kbC1jYXJkIG1kbC1zaGFkb3ctLTJkcFwiIGRhdGEtaG9vaz1cImZ1bGxpdGVtXCIgc3R5bGU9XCJtaW4taGVpZ2h0OiBpbmhlcml0XCI+JyxhPTIsZCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fdGl0bGVcIj4nLGE9MyxkKz0nPGgyIGNsYXNzPVwibWRsLWNhcmRfX3RpdGxlLXRleHRcIiBkYXRhLWhvb2s9XCJuYW1lXCI+PC9oMj48L2Rpdj4nLGE9NSxkKz0nPGRpdiBjbGFzcz1cIm1kbC1jYXJkX19zdXBwb3J0aW5nLXRleHRcIiBkYXRhLWhvb2s9XCJkZXNjcmlwdGlvblwiPjwvZGl2PicsYT03LGQrPSc8ZGl2IGNsYXNzPVwibWRsLWNhcmRfX2FjdGlvbnMgbWRsLWNhcmQtLWJvcmRlclwiIGRhdGEtaG9vaz1cImFjdGlvbnNcIj4nLGE9OCxkKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWJ1dHRvbi0tY29sb3JlZCBtZGwtanMtYnV0dG9uIG1kbC1qcy1yaXBwbGUtZWZmZWN0IHVuc2VsZWN0YWJsZVwiIGRhdGEtaG9vaz1cInJlbW92ZUZhY2V0XCI+JyxhPTksZCs9XCJEZWxldGU8L2J1dHRvbj5cIixhPTEwLGQrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtYnV0dG9uLS1jb2xvcmVkIG1kbC1qcy1idXR0b24gbWRsLWpzLXJpcHBsZS1lZmZlY3QgdW5zZWxlY3RhYmxlXCIgZGF0YS1ob29rPVwiZHVwbGljYXRlRmFjZXRcIj4nLGE9MTEsZCs9XCJDb3B5IDwvYnV0dG9uPlwiLGE9MTIsZCs9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1idXR0b24tLWNvbG9yZWQgbWRsLWpzLWJ1dHRvbiBtZGwtanMtcmlwcGxlLWVmZmVjdCB1bnNlbGVjdGFibGVcIiBkYXRhLWhvb2s9XCJjb25maWd1cmVGYWNldFwiIHN0eWxlPVwiZmxvYXQ6IHJpZ2h0XCI+JyxhPTEzLGQrPSc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+JyxhPTEzLGQrPVwic2V0dGluZ3M8L2k+PC9idXR0b24+PC9kaXY+XCIsYT0xNSxkKz0nPGRpdiBjbGFzcz1cIm1kbC1jYXJkX19tZW51XCI+JyxhPTE2LGQrPVwiPHNwYW4+XCIsYT0xNyxkKz0nPGxhYmVsIGNsYXNzPVwibWRsLXN3aXRjaCBtZGwtanMtc3dpdGNoIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZGF0YS1ob29rPVwiY2JsYWJlbFwiIGZvcj1cIlwiPicsYT0xOCxkKz0nPGlucHV0IGNsYXNzPVwibWRsLXN3aXRjaF9faW5wdXRcIiBkYXRhLWhvb2s9XCJjYlwiIHR5cGU9XCJjaGVja2JveFwiIGlkPVwiXCIvPjwvbGFiZWw+JyxhPTE5LGQrPSc8c3BhbiBjbGFzcz1cIm1kbC1zd2l0Y2hfX2xhYmVsXCI+PC9zcGFuPjwvc3Bhbj48L2Rpdj48L2Rpdj4nfWNhdGNoKGUpe3B1Zy5yZXRocm93KGUsbCxhKX1yZXR1cm4gZH07XHJcblxyXG4gICAgcHVnbGF0aXplcltcImNvbmZpZ3VyZURhdGFzZXRcIl1bXCJwYWdlXCJdID0gZnVuY3Rpb24gdGVtcGxhdGUodCl7dmFyIGwsYSxkPVwiXCI7dHJ5e2E9MSxkKz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQgbWRsLWpzLWxheW91dCBtZGwtbGF5b3V0LS1maXhlZC1oZWFkZXJcIj4nLGE9MixkKz0nPG1haW4gY2xhc3M9XCJtZGwtbGF5b3V0X19jb250ZW50XCIgc3R5bGU9XCJiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTtcIj4nLGE9MyxkKz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQgbWRsLWpzLWxheW91dCBtZGwtbGF5b3V0LS1maXhlZC1oZWFkZXJcIj4nLGE9NCxkKz0nPGhlYWRlciBjbGFzcz1cImRlbW8taGVhZGVyIG1kbC1sYXlvdXRfX2hlYWRlciBtZGwtY29sb3ItLWdyZXktMTAwIG1kbC1jb2xvci10ZXh0LS1ncmV5LTYwMFwiPicsYT01LGQrPSc8ZGl2IGNsYXNzPVwibWRsLWxheW91dF9faGVhZGVyLXJvd1wiPicsYT02LGQrPSc8c3BhbiBjbGFzcz1cIm1kbC1sYXlvdXQtdGl0bGVcIj4nLGE9NixkKz1cIkNvbmZpZ3VyZSBkYXRhc2V0PC9zcGFuPlwiLGE9OCxkKz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQtc3BhY2VyXCI+PC9kaXY+JyxhPTEwLGQrPSc8c3BhbiBjbGFzcz1cInVuc2VsZWN0YWJsZVwiIGRhdGEtaG9vaz1cImRhdGEtc3RyaW5nXCI+JyxhPTExLGQrPVwiU2VsZWN0IGFuZCBjb25maWd1cmUgZmFjZXRzPC9zcGFuPlwiLGE9MTMsZCs9JzxkaXYgY2xhc3M9XCJtZGwtbGF5b3V0LXNwYWNlclwiPjwvZGl2PicsYT0xNSxkKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWpzLWJ1dHRvbiBtZGwtYnV0dG9uLS1pY29uIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZGF0YS1ob29rPVwiZW5hYmxlLWFsbC1idXR0b25cIiBpZD1cImVhYlwiPicsYT0xNixkKz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPicsYT0xNixkKz1cImNoZWNrX2JveDwvaT48L2J1dHRvbj5cIixhPTE3LGQrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlXCIgZm9yPVwiZWFiXCI+JyxhPTE4LGQrPVwiRW5hYmxlIGFsbCBmYWNldHM8L2Rpdj5cIixhPTIwLGQrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtanMtYnV0dG9uIG1kbC1idXR0b24tLWljb24gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIiBkYXRhLWhvb2s9XCJkaXNhYmxlLWFsbC1idXR0b25cIiBpZD1cImRhYlwiPicsYT0yMSxkKz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPicsYT0yMSxkKz1cImNoZWNrX2JveF9vdXRsaW5lX2JsYW5rPC9pPjwvYnV0dG9uPlwiLGE9MjIsZCs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJkYWJcIj4nLGE9MjMsZCs9XCJEaXNhYmxlIGFsbCBmYWNldHM8L2Rpdj5cIixhPTI1LGQrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtanMtYnV0dG9uIG1kbC1idXR0b24tLWljb24gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIiBkYXRhLWhvb2s9XCJhZGQtYnV0dG9uXCIgaWQ9XCJ0dDJcIj4nLGE9MjYsZCs9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj4nLGE9MjYsZCs9XCJhZGQ8L2k+PC9idXR0b24+XCIsYT0yNyxkKz0nPGRpdiBjbGFzcz1cIm1kbC10b29sdGlwIG1kbC10b29sdGlwLS1sYXJnZVwiIGZvcj1cInR0MlwiPicsYT0yOCxkKz1cIkFkZCBhIG5ldyBmYWNldDwvZGl2PlwiLGE9MzAsZCs9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWJ1dHRvbi0taWNvbiBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGRhdGEtaG9vaz1cInJlc2Nhbi1idXR0b25cIiBpZD1cInR0MVwiPicsYT0zMSxkKz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPicsYT0zMSxkKz1cImF1dG9yZW5ldzwvaT48L2J1dHRvbj5cIixhPTMyLGQrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlXCIgZm9yPVwidHQxXCI+JyxhPTMzLGQrPVwiQW5hbHl6ZSBkYXRhIGFuZCBhdXRvY29uZmlndXJlIGZhY2V0czwvZGl2PlwiLGE9MzUsZCs9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWJ1dHRvbi0taWNvbiBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGRhdGEtaG9vaz1cInNlYXJjaC1idXR0b25cIiBpZD1cInR0M1wiPicsYT0zNixkKz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPicsYT0zNixkKz1cInNlYXJjaDwvaT48L2J1dHRvbj5cIixhPTM3LGQrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlXCIgZm9yPVwidHQzXCI+JyxhPTM4LGQrPVwiU2hvdyBvciBoaWRlIHNlYXJjaCBiYXI8L2Rpdj48L2Rpdj5cIixhPTQwLGQrPSc8ZGl2IGNsYXNzPVwibWRsLWxheW91dF9faGVhZGVyLXJvd1wiIGRhdGEtaG9vaz1cInNlYXJjaC1iYXJcIj4nLGE9NDEsZCs9JzxkaXYgY2xhc3M9XCJtZGwtbGF5b3V0LXNwYWNlclwiPjwvZGl2PicsYT00MixkKz0nPHNwYW4gY2xhc3M9XCJtZGwtY29sb3ItLXdoaXRlIG1kbC1jb2xvci10ZXh0LS1wcmltYXJ5IHNlYXJjaEJhclwiPicsYT00NCxkKz0nPHNwYW4gY2xhc3M9XCJtZGwtdGV4dGZpZWxkIHNlYXJjaEJhclwiPicsYT00NSxkKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXQgc2VhcmNoQmFyXCIgZGF0YS1ob29rPVwiZmFjZXQtc2VsZWN0b3JcIiB0eXBlPVwidGV4dFwiIGlkPVwidHQ1XCIvPicsYT00NixkKz0nPGRpdiBjbGFzcz1cIm1kbC10b29sdGlwIG1kbC10b29sdGlwLS1sYXJnZVwiIGZvcj1cInR0NVwiPicsYT00NyxkKz1cIlNlYXJjaCBmYWNldCBuYW1lIGFuZCBkZXNjcmlwdGlvbjwvZGl2Pjwvc3Bhbj5cIixhPTQ5LGQrPVwiPHNwYW4+XCIsYT01MCxkKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWpzLWJ1dHRvbiBtZGwtYnV0dG9uLS1pY29uIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZGF0YS1ob29rPVwiY2xlYXItYnV0dG9uXCIgaWQ9XCJ0dDRcIj4nLGE9NTEsZCs9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj4nLGE9NTEsZCs9XCJjbG9zZTwvaT48L2J1dHRvbj5cIixhPTUyLGQrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlXCIgZm9yPVwidHQ0XCI+JyxhPTUzLGQrPVwiQ2xlYXIgc2VhcmNoPC9kaXY+PC9zcGFuPjwvc3Bhbj5cIixhPTU0LGQrPSc8ZGl2IGNsYXNzPVwibWRsLWxheW91dC1zcGFjZXJcIj48L2Rpdj48L2Rpdj48L2hlYWRlcj4nLGE9NTYsZCs9JzxkaXYgZGF0YS1ob29rPVwid2lkZ2V0c1wiPicsYT01OCxkKz0nPGRpdiBjbGFzcz1cIm1kbC1ncmlkXCI+JyxhPTU5LGQrPSc8ZGl2IGNsYXNzPVwibWRsLXRleHRmaWVsZCBtZGwtanMtdGV4dGZpZWxkIG1kbC10ZXh0ZmllbGQtLWZsb2F0aW5nLWxhYmVsIG1kbC1jZWxsIG1kbC1jZWxsLS00LWNvbFwiPicsYT02MCxkKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiB0eXBlPVwidGV4dFwiIGlkPVwibmFtZVwiLz4nLGE9NjEsZCs9JzxsYWJlbCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2xhYmVsXCIgZm9yPVwibmFtZVwiPicsYT02MixkKz1cIkRhdGFzZXQgbmFtZTwvbGFiZWw+PC9kaXY+XCIsYT02NCxkKz0nPGRpdiBjbGFzcz1cIm1kbC10ZXh0ZmllbGQgbWRsLWpzLXRleHRmaWVsZCBtZGwtY2VsbCBtZGwtY2VsbCBtZGwtY2VsbC0tNy1jb2xcIj4nLGE9NjUsZCs9Jzx0ZXh0YXJlYSBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2lucHV0XCIgdHlwZT1cInRleHRcIiByb3dzPVwiM1wiIGlkPVwiZGVzY3JpcHRpb25cIj48L3RleHRhcmVhPicsYT02NixkKz0nPGxhYmVsIGNsYXNzPVwibWRsLXRleHRmaWVsZF9fbGFiZWxcIiBmb3I9XCJkZXNjcmlwdGlvblwiPicsYT02NyxkKz1cIkRhdGFzZXQgZGVzY3JpcHRpb248L2xhYmVsPjwvZGl2PjwvZGl2PlwiLGE9NjksZCs9JzxkaXYgY2xhc3M9XCJtZGwtZ3JpZFwiIGRhdGEtaG9vaz1cImZhY2V0LWxpc3RcIj48L2Rpdj48L2Rpdj48L2Rpdj48L21haW4+PC9kaXY+J31jYXRjaChlKXtwdWcucmV0aHJvdyhlLGwsYSl9cmV0dXJuIGR9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJjb25maWd1cmVGYWNldFwiXSA9IHt9XHJcbiAgICBwdWdsYXRpemVyW1wiY29uZmlndXJlRmFjZXRcIl1bXCJjYXRlZ29yaWFsUnVsZVwiXSA9IGZ1bmN0aW9uIHRlbXBsYXRlKHQpe3ZhciBlLG8sYT1cIlwiO3RyeXtvPTEsYSs9XCI8dHI+XCIsbz0yLGErPVwiPHRkPlwiLG89MyxhKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiBkYXRhLWhvb2s9XCJjYXRlZ29yeS1leHByZXNzaW9uLWlucHV0XCIgdHlwZT1cInRleHRcIi8+PC90ZD4nLG89NCxhKz1cIjx0ZD5cIixvPTUsYSs9JzxpbnB1dCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2lucHV0XCIgZGF0YS1ob29rPVwiY2F0ZWdvcnktZ3JvdXAtaW5wdXRcIiB0eXBlPVwidGV4dFwiLz48L3RkPicsbz02LGErPSc8dGQgZGF0YS1ob29rPVwiY2F0ZWdvcnktdmFsdWUtY291bnRcIj48L3RkPicsbz03LGErPVwiPHRkPlwiLG89OCxhKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWpzLWJ1dHRvbiBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGRhdGEtaG9vaz1cImNhdGVnb3J5LXJlbW92ZVwiPicsbz05LGErPSc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+JyxvPTksYSs9XCJyZW1vdmU8L2k+PC9idXR0b24+PC90ZD48L3RyPlwifWNhdGNoKGQpe3B1Zy5yZXRocm93KGQsZSxvKX1yZXR1cm4gYX07XHJcblxyXG4gICAgcHVnbGF0aXplcltcImNvbmZpZ3VyZUZhY2V0XCJdW1wiY2F0ZWdvcmlhbHRyYW5zZm9ybVwiXSA9IGZ1bmN0aW9uIHRlbXBsYXRlKHQpe3ZhciByLGUsYT1cIlwiO3RyeXt9Y2F0Y2goYyl7cHVnLnJldGhyb3coYyxyLGUpfXJldHVybiBhfTtcclxuXHJcbiAgICBwdWdsYXRpemVyW1wiY29uZmlndXJlRmFjZXRcIl1bXCJjb250aW51b3VzUnVsZVwiXSA9IGZ1bmN0aW9uIHRlbXBsYXRlKHQpe3ZhciBvLGUsbj1cIlwiO3RyeXtlPTEsbis9XCI8dHI+XCIsZT0yLG4rPVwiPHRkPlwiLGU9MyxuKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiBkYXRhLWhvb2s9XCJjb250aW51b3VzLXgtaW5wdXRcIiB0eXBlPVwidGV4dFwiLz48L3RkPicsZT00LG4rPVwiPHRkPlwiLGU9NSxuKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiBkYXRhLWhvb2s9XCJjb250aW51b3VzLWZ4LWlucHV0XCIgdHlwZT1cInRleHRcIi8+PC90ZD4nLGU9NixuKz1cIjx0ZD5cIixlPTcsbis9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIiBkYXRhLWhvb2s9XCJjb250aW51b3VzLXJlbW92ZVwiPicsZT04LG4rPSc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+JyxlPTgsbis9XCJyZW1vdmU8L2k+PC9idXR0b24+PC90ZD48L3RyPlwifWNhdGNoKHUpe3B1Zy5yZXRocm93KHUsbyxlKX1yZXR1cm4gbn07XHJcblxyXG4gICAgcHVnbGF0aXplcltcImNvbmZpZ3VyZUZhY2V0XCJdW1wiZmFjZXREZWZpbmVcIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZShsKXt2YXIgZSxkLGk9XCJcIjt0cnl7ZD0xLGkrPSc8ZGl2IGNsYXNzPVwibWRsLWdyaWRcIj4nLGQ9MixpKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xMi1jb2wgbWRsLWdyaWRcIj4nLGQ9MyxpKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xLWNvbCBmYWNldEljb24gZmFjZXRJbmZvSWNvblwiPjwvZGl2PicsZD00LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEtY29sXCI+PC9kaXY+JyxkPTUsaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tOC1jb2xcIj4nLGQ9NixpKz0nPGRpdiBjbGFzcz1cIm1kbC1ncmlkXCI+JyxkPTgsaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sXCIgaWQ9XCJkZWZpbmUtbmFtZS1kaXZcIj4nLGQ9OSxpKz0nPGRpdiBjbGFzcz1cIm1kbC10ZXh0ZmllbGQgbWRsLWpzLXRleHRmaWVsZCBtZGwtdGV4dGZpZWxkLS1mbG9hdGluZy1sYWJlbCBmdWxsd2lkdGhcIj4nLGQ9MTAsaSs9JzxpbnB1dCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2lucHV0XCIgaWQ9XCJkZWZpbmUtbmFtZVwiIGRhdGEtaG9vaz1cImRlZmluZS1uYW1lLWlucHV0XCIgdHlwZT1cInRleHRcIi8+JyxkPTE0LGkrPSc8bGFiZWwgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19sYWJlbFwiIGZvcj1cImRlZmluZS1uYW1lXCI+JyxkPTE0LGkrPVwiTmFtZTwvbGFiZWw+PC9kaXY+PC9kaXY+XCIsZD0xNSxpKz0nPGRpdiBjbGFzcz1cIm1kbC10b29sdGlwIG1kbC10b29sdGlwLS1sYXJnZSBtZGwtdG9vbHRpcC0tcmlnaHRcIiBmb3I9XCJkZWZpbmUtbmFtZS1kaXZcIj4nLGQ9MTYsaSs9XCJTZXQgYSBkZXNjcmlwdGl2ZSBuYW1lIGZvciB0aGlzIGZhY2V0LiBUaGUgbmFtZSBpcyB1c2VkIHRvIGlkZW50aWZ5IHRoaXMgZmFjZXQgb24gcGxvdHMgYW5kIGluIG1lbnVzLiA8L2Rpdj5cIixkPTE4LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbFwiIGlkPVwiZGVmaW5lLXVuaXRzLWRpdlwiPicsZD0xOSxpKz0nPGRpdiBjbGFzcz1cIm1kbC10ZXh0ZmllbGQgbWRsLWpzLXRleHRmaWVsZCBtZGwtdGV4dGZpZWxkLS1mbG9hdGluZy1sYWJlbCBmdWxsd2lkdGhcIj4nLGQ9MjAsaSs9JzxpbnB1dCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2lucHV0XCIgaWQ9XCJkZWZpbmUtdW5pdHNcIiBkYXRhLWhvb2s9XCJkZWZpbmUtdW5pdHMtaW5wdXRcIiB0eXBlPVwidGV4dFwiLz4nLGQ9MjQsaSs9JzxsYWJlbCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2xhYmVsXCIgZm9yPVwiZGVmaW5lLXVuaXRzXCI+JyxkPTI0LGkrPVwiVW5pdHM8L2xhYmVsPjwvZGl2PjwvZGl2PlwiLGQ9MjUsaSs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2UgbWRsLXRvb2x0aXAtLXJpZ2h0XCIgZm9yPVwiZGVmaW5lLXVuaXRzLWRpdlwiPicsZD0yNixpKz1cIlNldCB1bml0cyBmb3IgdGhpcyBmYWNldC4gVW5pdHMgYXJlIHByaW50ZWQgb24gcGxvdHMgd2hlcmUgYXBwbGljYWJsZS48L2Rpdj5cIixkPTI4LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbFwiIGlkPVwiZGVmaW5lLWRlc2NyaXB0aW9uLWRpdlwiPicsZD0yOSxpKz0nPGRpdiBjbGFzcz1cIm1kbC10ZXh0ZmllbGQgbWRsLWpzLXRleHRmaWVsZCBtZGwgdGV4dGZpZWxkLS1mbG9hdGluZy1sYWJlbCBmdWxsd2lkdGhcIj4nLGQ9MzAsaSs9Jzx0ZXh0YXJlYSBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2lucHV0XCIgaWQ9XCJkZWZpbmUtZGVzY3JpcHRpb25cIiBkYXRhLWhvb2s9XCJkZWZpbmUtZGVzY3JpcHRpb24taW5wdXRcIiB0eXBlPVwidGV4dFwiIHJvd3M9XCI1XCI+JyxkPTM0LGkrPVwiIDwvdGV4dGFyZWE+XCIsZD0zNSxpKz0nPGxhYmVsIGNsYXNzPVwibWRsLXRleHRmaWVsZF9fbGFiZWxcIiBmb3I9XCJkZWZpbmUtZGVzY3JpcHRpb25cIj4nLGQ9MzUsaSs9XCJEZXNjcmlwdGlvbjwvbGFiZWw+PC9kaXY+PC9kaXY+XCIsZD0zNixpKz0nPGRpdiBjbGFzcz1cIm1kbC10b29sdGlwIG1kbC10b29sdGlwLS1sYXJnZSBtZGwtdG9vbHRpcC0tcmlnaHRcIiBmb3I9XCJkZWZpbmUtZGVzY3JpcHRpb24tZGl2XCI+JyxkPTM3LGkrPVwiR2l2ZSBhIGRlc2NyaXB0aW9uIG9mIHRoZSBmYWNldC4gV2hhdCBkbyBpdHMgdmFsdWVzIG1lYW4/IEhvdyBhcmUgdGhleSBjYWxjdWxhdGVkPzwvZGl2PjwvZGl2PjwvZGl2PlwiLGQ9MzksaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMi1jb2xcIj48L2Rpdj48L2Rpdj4nLGQ9NDEsaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sIG1kbC1ncmlkXCI+JyxkPTQyLGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEtY29sIGZhY2V0SWNvbiBmYWNldFR5cGVJY29uXCI+PC9kaXY+JyxkPTQzLGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEtY29sXCI+PC9kaXY+JyxkPTQ0LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTgtY29sXCI+JyxkPTQ2LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWdyaWQgbWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbFwiPicsZD00OCxpKz0nPGRpdiBjbGFzcz1cIm1kbC1ncmlkIG1kbC1jZWxsIG1kbC1jZWxsLS0xMi1jb2xcIiBpZD1cImRlZmluZS10eXBlLWRpdlwiPicsZD00OSxpKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0zLWNvbFwiPicsZD01MCxpKz0nPGxhYmVsIGNsYXNzPVwibWRsLXJhZGlvIG1kbC1qcy1yYWRpbyBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGZvcj1cImRlZmluZS10eXBlLWNhdGVnb3JpYWxcIj4nLGQ9NTEsaSs9JzxpbnB1dCBjbGFzcz1cIm1kbC1yYWRpb19fYnV0dG9uXCIgaWQ9XCJkZWZpbmUtdHlwZS1jYXRlZ29yaWFsXCIgZGF0YS1ob29rPVwiZGVmaW5lLXR5cGUtY2F0ZWdvcmlhbFwiIHR5cGU9XCJyYWRpb1wiIG5hbWU9XCJ0eXBlXCIgdmFsdWU9XCJjYXRlZ29yaWFsXCIvPicsZD01NyxpKz0nPHNwYW4gY2xhc3M9XCJtZGwtcmFkaW9fX2xhYmVsXCI+JyxkPTU3LGkrPVwiQ2F0ZWdvcmlhbDwvc3Bhbj48L2xhYmVsPjwvZGl2PlwiLGQ9NTksaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMy1jb2xcIj4nLGQ9NjAsaSs9JzxsYWJlbCBjbGFzcz1cIm1kbC1yYWRpbyBtZGwtanMtcmFkaW8gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIiBmb3I9XCJkZWZpbmUtdHlwZS1jb250aW51b3VzXCI+JyxkPTYxLGkrPSc8aW5wdXQgY2xhc3M9XCJtZGwtcmFkaW9fX2J1dHRvblwiIGlkPVwiZGVmaW5lLXR5cGUtY29udGludW91c1wiIGRhdGEtaG9vaz1cImRlZmluZS10eXBlLWNvbnRpbnVvdXNcIiB0eXBlPVwicmFkaW9cIiBuYW1lPVwidHlwZVwiIHZhbHVlPVwiY29udGludW91c1wiLz4nLGQ9NjcsaSs9JzxzcGFuIGNsYXNzPVwibWRsLXJhZGlvX19sYWJlbFwiPicsZD02NyxpKz1cIkNvbnRpbnVvdXM8L3NwYW4+PC9sYWJlbD48L2Rpdj5cIixkPTY5LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCI+JyxkPTcwLGkrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiZGVmaW5lLXR5cGUtZGF0ZXRpbWVcIj4nLGQ9NzEsaSs9JzxpbnB1dCBjbGFzcz1cIm1kbC1yYWRpb19fYnV0dG9uXCIgaWQ9XCJkZWZpbmUtdHlwZS1kYXRldGltZVwiIGRhdGEtaG9vaz1cImRlZmluZS10eXBlLWRhdGV0aW1lXCIgdHlwZT1cInJhZGlvXCIgbmFtZT1cInR5cGVcIiB2YWx1ZT1cImRhdGV0aW1lXCIvPicsZD03NyxpKz0nPHNwYW4gY2xhc3M9XCJtZGwtcmFkaW9fX2xhYmVsXCI+JyxkPTc3LGkrPVwiRGF0ZXRpbWU8L3NwYW4+PC9sYWJlbD48L2Rpdj5cIixkPTc5LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCI+JyxkPTgwLGkrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiZGVmaW5lLXR5cGUtZHVyYXRpb25cIj4nLGQ9ODEsaSs9JzxpbnB1dCBjbGFzcz1cIm1kbC1yYWRpb19fYnV0dG9uXCIgaWQ9XCJkZWZpbmUtdHlwZS1kdXJhdGlvblwiIGRhdGEtaG9vaz1cImRlZmluZS10eXBlLWR1cmF0aW9uXCIgdHlwZT1cInJhZGlvXCIgbmFtZT1cInR5cGVcIiB2YWx1ZT1cImR1cmF0aW9uXCIvPicsZD04NyxpKz0nPHNwYW4gY2xhc3M9XCJtZGwtcmFkaW9fX2xhYmVsXCI+JyxkPTg3LGkrPVwiRHVyYXRpb248L3NwYW4+PC9sYWJlbD48L2Rpdj5cIixkPTg5LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCI+JyxkPTkwLGkrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiZGVmaW5lLXR5cGUtdGV4dFwiPicsZD05MSxpKz0nPGlucHV0IGNsYXNzPVwibWRsLXJhZGlvX19idXR0b25cIiBpZD1cImRlZmluZS10eXBlLXRleHRcIiBkYXRhLWhvb2s9XCJkZWZpbmUtdHlwZS10ZXh0XCIgdHlwZT1cInJhZGlvXCIgbmFtZT1cInR5cGVcIiB2YWx1ZT1cInRleHRcIi8+JyxkPTk3LGkrPSc8c3BhbiBjbGFzcz1cIm1kbC1yYWRpb19fbGFiZWxcIj4nLGQ9OTcsaSs9XCJUZXh0PC9zcGFuPjwvbGFiZWw+PC9kaXY+PC9kaXY+XCIsZD05OSxpKz0nPGRpdiBjbGFzcz1cIm1kbC10b29sdGlwIG1kbC10b29sdGlwLS1sYXJnZSBtZGwtdG9vbHRpcC0tcmlnaHRcIiBmb3I9XCJkZWZpbmUtdHlwZS1kaXZcIj4nLGQ9MTAwLGkrPVwiV2hhdCB2YWx1ZXMgZG9lcyB0aGlzIGZhY2V0IHRha2U/IElzIGl0IGEgY29udGludW91cyB2YWx1ZSAobGVuZ3RoLCB3ZWlnaHQsIGFtb3VudCk/IE9yIGEgbGFiZWwsIGNhdGVnb3J5ICgnaW1wb3J0YW50JywgJ3VyZ2VudCcsIG9yIGEgZGF5IG9mIHRoZSB3ZWVrLCAuLi4pLiBPciBpcyBpdCBhIGRhdGUsIHRpbWUgb3IgZHVyYXRpb24/IE9yIGFyYml0cmFyeSB0ZXh0PzwvZGl2PjwvZGl2PjwvZGl2PlwiLGQ9MTAyLGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTItY29sXCI+PC9kaXY+PC9kaXY+JyxkPTEwNCxpKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xMi1jb2wgbWRsLWdyaWRcIj4nLGQ9MTA1LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEtY29sIGZhY2V0SWNvbiBmYWNldEJhc2VWYWx1ZUljb25cIj48L2Rpdj4nLGQ9MTA2LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEtY29sXCI+PC9kaXY+JyxkPTEwNyxpKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS04LWNvbFwiPicsZD0xMDksaSs9JzxkaXYgY2xhc3M9XCJtZGwtZ3JpZCBtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sXCI+JyxkPTExMSxpKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xMi1jb2xcIiBpZD1cImRlZmluZS1taXNzaW5nLWRpdlwiPicsZD0xMTIsaSs9JzxkaXYgY2xhc3M9XCJtZGwtdGV4dGZpZWxkIG1kbC1qcy10ZXh0ZmllbGQgbWRsLXRleHRmaWVsZC0tZmxvYXRpbmctbGFiZWwgZnVsbHdpZHRoXCI+JyxkPTExMyxpKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiBpZD1cImRlZmluZS1taXNzaW5nLWlucHV0XCIgZGF0YS1ob29rPVwiZGVmaW5lLW1pc3NpbmctaW5wdXRcIiB0eXBlPVwidGV4dFwiLz4nLGQ9MTE3LGkrPSc8bGFiZWwgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19sYWJlbFwiIGZvcj1cImRlZmluZS1taXNzaW5nLWlucHV0XCI+JyxkPTExNyxpKz1cIk1pc3NpbmcgZGF0YSBpbmRpY2F0b3I8L2xhYmVsPjwvZGl2PjwvZGl2PlwiLGQ9MTE4LGkrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlIG1kbC10b29sdGlwLS1yaWdodFwiIGZvcj1cImRlZmluZS1taXNzaW5nLWRpdlwiPicsZD0xMTksaSs9XCJJbnZhbGlkLCB1bmRlZmluZWQsIG9yIG1pc3NpbmcgZGF0YSBhcmUgZGVhbHQgd2l0aCBhdXRvbWF0aWNhbGx5LCBidXQgc29tZXRpbWVzIGEgc3BlY2lhbCB2YWx1ZSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBkYXRhIGlzIG1pc3NpbmcuIEVudGVyIHRob3NlIHZhbHVlcyBoZXJlLiBFeGFtcGxlOiA5OTksICd4JywgJ21pc3NpbmcnPC9kaXY+XCIsZD0xMjIsaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sXCIgaWQ9XCJkZWZpbmUtYWNjZXNzb3ItZGl2XCI+JyxkPTEyMyxpKz0nPGRpdiBjbGFzcz1cIm1kbC10ZXh0ZmllbGQgbWRsLWpzLXRleHRmaWVsZCBtZGwtdGV4dGZpZWxkLS1mbG9hdGluZy1sYWJlbCBmdWxsd2lkdGhcIj4nLGQ9MTI0LGkrPSc8aW5wdXQgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19pbnB1dFwiIGlkPVwiZGVmaW5lLWFjY2Vzc29yLWlucHV0XCIgZGF0YS1ob29rPVwiZGVmaW5lLWFjY2Vzc29yLWlucHV0XCIgdHlwZT1cInRleHRcIi8+JyxkPTEyOCxpKz0nPGxhYmVsIGNsYXNzPVwibWRsLXRleHRmaWVsZF9fbGFiZWxcIiBmb3I9XCJkZWZpbmUtYWNjZXNzb3ItaW5wdXRcIj4nLGQ9MTI4LGkrPVwiUHJvcGVydHkgbmFtZSBvciBpbmRleDwvbGFiZWw+PC9kaXY+PC9kaXY+XCIsZD0xMjksaSs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2UgbWRsLXRvb2x0aXAtLXJpZ2h0XCIgZm9yPVwiZGVmaW5lLWFjY2Vzc29yLWRpdlwiPicsZD0xMzAsaSs9XCJIb3cgd2UgZGVyaXZlIHRoZSBmYWNldCB2YWx1ZSBmcm9tIGEgZGF0YSBvYmplY3Q/IEVudGVyIGEgcHJvcGVydHkgbmFtZSAoZm9yIEpTT04gb3IgU1FMIGNvbHVtbnMpLCBvciBpbmRleCAoZm9yIGFycmF5cykuIFVzZSAnLicgbm90YXRpb24gdG8gYWNjZXNzIG5lc3RlZCBwcm9wZXJ0aWVzLjwvZGl2PlwiLGQ9MTMzLGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbCBtZGwtZ3JpZFwiIGlkPVwiZGVmaW5lLXJlc2Nhbi1kaXZcIj4nLGQ9MTM0LGkrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtanMtYnV0dG9uIG1kbC1idXR0b24tLXJhaXNlZCBtZGwtanMtcmlwcGxlLWVmZmVjdCBtZGwtYnV0dG9uLS1hY2NlbnRcIiBkYXRhLWhvb2s9XCJkZWZpbmUtcmVzY2FuLWJ1dHRvblwiPicsZD0xMzQsaSs9XCJTY2FuIGRhdGFzZXQ8L2J1dHRvbj48L2Rpdj5cIixkPTEzNyxpKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xMi1jb2wgbWRsLWdyaWRcIiBpZD1cImRlZmluZS1taW5pbXVtLWRpdlwiIGRhdGEtaG9vaz1cImRlZmluZS1taW5pbXVtLWRpdlwiPicsZD0xMzgsaSs9JzxkaXYgY2xhc3M9XCJtZGwtdGV4dGZpZWxkIG1kbC1qcy10ZXh0ZmllbGQgbWRsLXRleHRmaWVsZC0tZmxvYXRpbmctbGFiZWwgbWRsLWNlbGwgbWRsLWNlbGwtLTEwLWNvbFwiIGlkPVwiZGVmaW5lLW1pbmltdW0tZGl2XCI+JyxkPTEzOSxpKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiBpZD1cImRlZmluZS1taW5pbXVtXCIgZGF0YS1ob29rPVwiZGVmaW5lLW1pbmltdW0taW5wdXRcIiB0eXBlPVwidGV4dFwiLz4nLGQ9MTQzLGkrPSc8bGFiZWwgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19sYWJlbFwiIGZvcj1cInNhbXBsZTRcIj4nLGQ9MTQzLGkrPVwiTWluaW11bSB2YWx1ZTwvbGFiZWw+PC9kaXY+XCIsZD0xNDUsaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2xcIj4nLGQ9MTQ2LGkrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtanMtYnV0dG9uIG1kbC1idXR0b24tLWljb24gbWRsLWJ1dHRvbi0tY29sb3JlZFwiIGRhdGEtaG9vaz1cImJ1dHRvbi1taW52YWwtbWlzc2luZ1wiPicsZD0xNDcsaSs9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj4nLGQ9MTQ3LGkrPVwiY2FuY2VsPC9pPjwvYnV0dG9uPjwvZGl2PlwiLGQ9MTQ5LGkrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlIG1kbC10b29sdGlwLS1yaWdodFwiIGZvcj1cImRlZmluZS1taW5pbXVtLWRpdlwiPicsZD0xNTAsaSs9XCJTZXQgbWluaW11bSB2YWx1ZS48L2Rpdj48L2Rpdj5cIixkPTE1MyxpKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xMi1jb2wgbWRsLWdyaWRcIiBpZD1cImRlZmluZS1tYXhpbXVtLWRpdlwiIGRhdGEtaG9vaz1cImRlZmluZS1tYXhpbXVtLWRpdlwiPicsZD0xNTQsaSs9JzxkaXYgY2xhc3M9XCJtZGwtdGV4dGZpZWxkIG1kbC1qcy10ZXh0ZmllbGQgbWRsLXRleHRmaWVsZC0tZmxvYXRpbmctbGFiZWwgbWRsLWNlbGwgbWRsLWNlbGwtLTEwLWNvbFwiIGlkPVwiZGVmaW5lLW1heGltdW0tZGl2XCI+JyxkPTE1NSxpKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiBpZD1cImRlZmluZS1tYXhpbXVtXCIgZGF0YS1ob29rPVwiZGVmaW5lLW1heGltdW0taW5wdXRcIiB0eXBlPVwidGV4dFwiLz4nLGQ9MTU5LGkrPSc8bGFiZWwgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19sYWJlbFwiIGZvcj1cInNhbXBsZTRcIj4nLGQ9MTU5LGkrPVwiTWF4aW11bSB2YWx1ZTwvbGFiZWw+PC9kaXY+XCIsZD0xNjEsaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2xcIj4nLGQ9MTYyLGkrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtanMtYnV0dG9uIG1kbC1idXR0b24tLWljb24gbWRsLWJ1dHRvbi0tY29sb3JlZFwiIGRhdGEtaG9vaz1cImJ1dHRvbi1tYXh2YWwtbWlzc2luZ1wiPicsZD0xNjMsaSs9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj4nLGQ9MTYzLGkrPVwiY2FuY2VsPC9pPjwvYnV0dG9uPjwvZGl2PlwiLGQ9MTY1LGkrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlIG1kbC10b29sdGlwLS1yaWdodFwiIGZvcj1cImRlZmluZS1tYXhpbXVtLWRpdlwiPicsZD0xNjYsaSs9XCJTZXQgbWF4aW11bSB2YWx1ZS48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj5cIixkPTE2OCxpKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0yLWNvbFwiPjwvZGl2PjwvZGl2PjwvZGl2Pid9Y2F0Y2godCl7cHVnLnJldGhyb3codCxlLGQpfXJldHVybiBpfTtcclxuXHJcbiAgICBwdWdsYXRpemVyW1wiY29uZmlndXJlRmFjZXRcIl1bXCJmYWNldFRyYW5zZm9ybUNhdGVnb3JpYWxcIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZShsKXt2YXIgdCxkLG89XCJcIjt0cnl7ZD0xLG8rPSc8ZGl2IGNsYXNzPVwibWRsLWdyaWRcIiBkYXRhLWhvb2s9XCJ0cmFuc2Zvcm0tY2F0ZWdvcmlhbC1wYW5lbFwiPicsZD0zLG8rPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEtY29sIGZhY2V0SWNvbiBmYWNldENhdGVnb3JpYWxJY29uXCI+PC9kaXY+JyxkPTUsbys9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2xcIj48L2Rpdj4nLGQ9NyxvKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS04LWNvbFwiPicsZD04LG8rPSc8ZGl2IGNsYXNzPVwibWRsLWdyaWRcIiBpZD1cInRyYW5zZm9ybS1jYXRlZ29yaWFsLWRpdlwiPicsZD0xMCxvKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS00LWNvbFwiIGRhdGEtaG9vaz1cImNhdGVnb3JpYWwtYWRkb25lLWJ1dHRvblwiPicsZD0xMSxvKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWpzLWJ1dHRvbiBtZGwtanMtcmlwcGxlLWVmZmVjdFwiPicsZD0xMSxvKz1cIkFkZCBhIHJ1bGU8L2J1dHRvbj48L2Rpdj5cIixkPTEzLG8rPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTQtY29sXCIgZGF0YS1ob29rPVwiY2F0ZWdvcmlhbC1yZW1vdmVhbGwtYnV0dG9uXCI+JyxkPTE0LG8rPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtanMtYnV0dG9uIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCI+JyxkPTE0LG8rPVwiUmVtb3ZlIGFsbCBydWxlczwvYnV0dG9uPjwvZGl2PlwiLGQ9MTYsbys9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sXCI+JyxkPTE3LG8rPVwiPHRhYmxlPlwiLGQ9MTgsbys9XCI8dGhlYWQ+XCIsZD0xOSxvKz1cIjx0cj5cIixkPTIwLG8rPVwiPHRoPlwiLGQ9MjAsbys9XCJUZXh0PC90aD5cIixkPTIxLG8rPVwiPHRoPlwiLGQ9MjEsbys9XCJHcm91cDwvdGg+XCIsZD0yMixvKz1cIjx0aD5cIixkPTIyLG8rPVwiQ291bnQ8L3RoPlwiLGQ9MjMsbys9XCI8dGg+XCIsZD0yMyxvKz1cIlJlbW92ZTwvdGg+PC90cj48L3RoZWFkPlwiLGQ9MjQsbys9Jzx0Ym9keSBkYXRhLWhvb2s9XCJjYXRlZ29yaWFsLXJ1bGVzLXRhYmxlXCI+PC90Ym9keT48L3RhYmxlPjwvZGl2PjwvZGl2PicsZD0yNixvKz0nPGRpdiBjbGFzcz1cIm1kbC10b29sdGlwIG1kbC10b29sdGlwLS1sYXJnZSBtZGwtdG9vbHRpcC0tcmlnaHRcIiBmb3I9XCJ0cmFuc2Zvcm0tY2F0ZWdvcmlhbC1kaXZcIj4nLGQ9MjYsbys9XCIgXCIsZD0yNyxvKz1cIkFzc2lnbiBmYWNldCB2YWx1ZXMgdG8gZ3JvdXMuPC9kaXY+PC9kaXY+XCIsZD0yOSxvKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0yLWNvbFwiPjwvZGl2PjwvZGl2Pid9Y2F0Y2goYSl7cHVnLnJldGhyb3coYSx0LGQpfXJldHVybiBvfTtcclxuXHJcbiAgICBwdWdsYXRpemVyW1wiY29uZmlndXJlRmFjZXRcIl1bXCJmYWNldFRyYW5zZm9ybUNvbnRpbnVvdXNcIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZShsKXt2YXIgZSxkLGE9XCJcIjt0cnl7ZD0xLGErPSc8ZGl2IGNsYXNzPVwibWRsLWdyaWRcIiBkYXRhLWhvb2s9XCJ0cmFuc2Zvcm0tY29udGludW91cy1wYW5lbFwiPicsZD0zLGErPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEtY29sIGZhY2V0SWNvbiBmYWNldENvbnRpbnVvdXNJY29uXCI+PC9kaXY+JyxkPTUsYSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2xcIj48L2Rpdj4nLGQ9NyxhKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS04LWNvbCBtZGwtZ3JpZFwiPicsZD05LGErPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTQtY29sXCI+JyxkPTEwLGErPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiZGVmaW5lLXRyYW5zZm9ybS1ub25lXCI+JyxkPTExLGErPSc8aW5wdXQgY2xhc3M9XCJtZGwtcmFkaW9fX2J1dHRvblwiIGlkPVwiZGVmaW5lLXRyYW5zZm9ybS1ub25lXCIgZGF0YS1ob29rPVwiZGVmaW5lLXRyYW5zZm9ybS1ub25lXCIgdHlwZT1cInJhZGlvXCIgbmFtZT1cInRyYW5zZm9ybXR5cGVcIiB2YWx1ZT1cIm5vbmVcIi8+JyxkPTE3LGErPSc8c3BhbiBjbGFzcz1cIm1kbC1yYWRpb19fbGFiZWxcIj4nLGQ9MTcsYSs9XCJObyB0cmFuc2Zvcm08L3NwYW4+PC9sYWJlbD48L2Rpdj5cIixkPTE5LGErPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTQtY29sXCI+JyxkPTIwLGErPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiZGVmaW5lLXRyYW5zZm9ybS1wZXJjZW50aWxlc1wiPicsZD0yMSxhKz0nPGlucHV0IGNsYXNzPVwibWRsLXJhZGlvX19idXR0b25cIiBpZD1cImRlZmluZS10cmFuc2Zvcm0tcGVyY2VudGlsZXNcIiBkYXRhLWhvb2s9XCJkZWZpbmUtdHJhbnNmb3JtLXBlcmNlbnRpbGVzXCIgdHlwZT1cInJhZGlvXCIgbmFtZT1cInRyYW5zZm9ybXR5cGVcIiB2YWx1ZT1cInBlcmNlbnRpbGVzXCIvPicsZD0yNyxhKz0nPHNwYW4gY2xhc3M9XCJtZGwtcmFkaW9fX2xhYmVsXCI+JyxkPTI3LGErPVwiUGVyY2VudGlsZXM8L3NwYW4+PC9sYWJlbD48L2Rpdj48L2Rpdj5cIixkPTI5LGErPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTItY29sXCI+PC9kaXY+PC9kaXY+J31jYXRjaChzKXtwdWcucmV0aHJvdyhzLGUsZCl9cmV0dXJuIGF9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJjb25maWd1cmVGYWNldFwiXVtcImZhY2V0VHJhbnNmb3JtRGF0ZXRpbWVcIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZShsKXt2YXIgZSxkLHQ9XCJcIjt0cnl7ZD0xLHQrPSc8ZGl2IGNsYXNzPVwibWRsLWdyaWRcIiBkYXRhLWhvb2s9XCJ0cmFuc2Zvcm0tdGltZS1wYW5lbFwiPicsZD0zLHQrPSc8ZGl2IGNsYXNzPVwibWRsLWdyaWQgbWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbFwiPicsZD00LHQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEtY29sIGZhY2V0SWNvbiBmYWNldFRpbWVJY29uXCI+PC9kaXY+JyxkPTUsdCs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2xcIj48L2Rpdj4nLGQ9Nyx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS04LWNvbCBtZGwtZ3JpZFwiPicsZD05LHQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbCBtZGwtZ3JpZFwiIGlkPVwidHJhbnNmb3JtLXRpbWUtZm9ybWF0LWRpdlwiPicsZD0xMCx0Kz0nPGRpdiBjbGFzcz1cIm1kbC10ZXh0ZmllbGQgbWRsLWpzLXRleHRmaWVsZCBtZGwtdGV4dGZpZWxkLS1mbG9hdGluZy1sYWJlbCBtZGwtY2VsbCBtZGwtY2VsbC0tNi1jb2xcIj4nLGQ9MTEsdCs9JzxpbnB1dCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2lucHV0XCIgaWQ9XCJ0cmFuc2Zvcm0tdGltZS1mb3JtYXRcIiBkYXRhLWhvb2s9XCJ0cmFuc2Zvcm0tdGltZS1mb3JtYXQtaW5wdXRcIiB0eXBlPVwidGV4dFwiLz4nLGQ9MTUsdCs9JzxsYWJlbCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2xhYmVsXCIgZm9yPVwidHJhbnNmb3JtLXRpbWUtZm9ybWF0XCI+JyxkPTE1LHQrPVwiSW5wdXQgdGltZSBmb3JtYXQ8L2xhYmVsPjwvZGl2PlwiLGQ9MTcsdCs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tNi1jb2xcIiBkYXRhLWhvb2s9XCJ0aW1lLXpvbmVzXCI+PC9kaXY+PC9kaXY+JyxkPTE5LHQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbCBtZGwtZ3JpZFwiIGlkPVwidHJhbnNmb3JtLXRpbWUtdHJhbnNmb3JtZWRmb3JtYXQtZGl2XCI+JyxkPTIwLHQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTYtY29sXCI+JyxkPTIxLHQrPVwiU2VsZWN0IGRhdGV0aW1lIHBhcnQ8L2Rpdj5cIixkPTIyLHQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTYtY29sXCIgZGF0YS1ob29rPVwidGltZS1wYXJ0c1wiPjwvZGl2PjwvZGl2PicsZD0yNCx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xMi1jb2wgbWRsLWdyaWRcIiBpZD1cInRyYW5zZm9ybS10aW1lLXRyYW5zZm9ybWVkcmVmZXJlbmNlLWRpdlwiPicsZD0yNSx0Kz0nPGRpdiBjbGFzcz1cIm1kbC10ZXh0ZmllbGQgbWRsLWpzLXRleHRmaWVsZCBtZGwtdGV4dGZpZWxkLS1mbG9hdGluZy1sYWJlbCBtZGwtY2VsbCBtZGwtY2VsbC0tNi1jb2xcIj4nLGQ9MjYsdCs9JzxpbnB1dCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2lucHV0XCIgaWQ9XCJ0cmFuc2Zvcm0tdGltZS10cmFuc2Zvcm1lZHJlZmVyZW5jZVwiIGRhdGEtaG9vaz1cInRyYW5zZm9ybS10aW1lLXRyYW5zZm9ybWVkcmVmZXJlbmNlLWlucHV0XCIgdHlwZT1cInRleHRcIi8+JyxkPTMwLHQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19sYWJlbFwiIGZvcj1cInRyYW5zZm9ybS10aW1lLXRyYW5zZm9ybWVkcmVmZXJlbmNlXCI+JyxkPTMwLHQrPVwiQWRkL3N1YnRyYWN0IHJlZmVyZW5jZSB0aW1lPC9sYWJlbD48L2Rpdj5cIixkPTMyLHQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTYtY29sXCIgZGF0YS1ob29rPVwidHJhbnNmb3JtZWQtdGltZS16b25lc1wiPjwvZGl2PjwvZGl2PjwvZGl2PicsZD0zNCx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0yLWNvbFwiPjwvZGl2PjwvZGl2PjwvZGl2Pid9Y2F0Y2gobSl7cHVnLnJldGhyb3cobSxlLGQpfXJldHVybiB0fTtcclxuXHJcbiAgICBwdWdsYXRpemVyW1wiY29uZmlndXJlRmFjZXRcIl1bXCJmYWNldFRyYW5zZm9ybUR1cmF0aW9uXCJdID0gZnVuY3Rpb24gdGVtcGxhdGUobCl7dmFyIGQsZSxjPVwiXCI7dHJ5e2U9MSxjKz0nPGRpdiBjbGFzcz1cIm1kbC1ncmlkXCIgZGF0YS1ob29rPVwidHJhbnNmb3JtLWR1cmF0aW9uLXBhbmVsXCI+JyxlPTMsYys9JzxkaXYgY2xhc3M9XCJtZGwtZ3JpZCBtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sXCI+JyxlPTQsYys9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2wgZmFjZXRJY29uIGZhY2V0VGltZUljb25cIj48L2Rpdj4nLGU9NSxjKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xLWNvbFwiPjwvZGl2PicsZT03LGMrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTgtY29sIG1kbC1ncmlkXCI+JyxlPTksYys9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sIG1kbC1ncmlkXCI+JyxlPTEwLGMrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTYtY29sXCI+JyxlPTExLGMrPVwiSW5wdXQgdW5pdHMgPC9kaXY+XCIsZT0xMixjKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS02LWNvbFwiIGRhdGEtaG9vaz1cImR1cmF0aW9uLXVuaXRzXCI+PC9kaXY+PC9kaXY+JyxlPTE0LGMrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbCBtZGwtZ3JpZFwiPicsZT0xNSxjKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS02LWNvbFwiPicsZT0xNixjKz1cIk91dHB1dCB1bml0czwvZGl2PlwiLGU9MTcsYys9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tNi1jb2xcIiBkYXRhLWhvb2s9XCJ0cmFuc2Zvcm1lZC1kdXJhdGlvbi11bml0c1wiPjwvZGl2PjwvZGl2PicsZT0xOSxjKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xMi1jb2wgbWRsLWdyaWRcIiBpZD1cInRyYW5zZm9ybS1kdXJhdGlvbi10cmFuc2Zvcm1lZHJlZmVyZW5jZS1kaXZcIj4nLGU9MjAsYys9JzxkaXYgY2xhc3M9XCJtZGwtdGV4dGZpZWxkIG1kbC1qcy10ZXh0ZmllbGQgbWRsLXRleHRmaWVsZC0tZmxvYXRpbmctbGFiZWwgbWRsLWNlbGwgbWRsLWNlbGwtLTYtY29sXCI+JyxlPTIxLGMrPSc8aW5wdXQgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19pbnB1dFwiIGlkPVwidHJhbnNmb3JtLWR1cmF0aW9uLXRyYW5zZm9ybWVkcmVmZXJlbmNlXCIgZGF0YS1ob29rPVwidHJhbnNmb3JtLWR1cmF0aW9uLXRyYW5zZm9ybWVkcmVmZXJlbmNlLWlucHV0XCIgdHlwZT1cInRleHRcIi8+JyxlPTI1LGMrPSc8bGFiZWwgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19sYWJlbFwiIGZvcj1cInRyYW5zZm9ybS1kdXJhdGlvbi10cmFuc2Zvcm1lZHJlZmVyZW5jZVwiPicsZT0yNSxjKz1cIkFkZC9zdWJ0cmFjdCByZWZlcmVuY2UgdGltZTwvbGFiZWw+PC9kaXY+XCIsZT0yNyxjKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS02LWNvbFwiIGRhdGEtaG9vaz1cInRyYW5zZm9ybWVkLWR1cmF0aW9uLXpvbmVcIj48L2Rpdj48L2Rpdj48L2Rpdj4nLGU9MjksYys9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMi1jb2xcIj48L2Rpdj48L2Rpdj48L2Rpdj4nfWNhdGNoKGkpe3B1Zy5yZXRocm93KGksZCxlKX1yZXR1cm4gY307XHJcblxyXG4gICAgcHVnbGF0aXplcltcImNvbmZpZ3VyZUZhY2V0XCJdW1wicGFnZVwiXSA9IGZ1bmN0aW9uIHRlbXBsYXRlKGEpe3ZhciBkLHQsbz1cIlwiO3RyeXt0PTEsbys9JzxkaXYgY2xhc3M9XCJtZGwtbGF5b3V0IG1kbC1qcy1sYXlvdXQgbWRsLWxheW91dC0tZml4ZWQtaGVhZGVyXCI+Jyx0PTIsbys9JzxtYWluIGNsYXNzPVwibWRsLWxheW91dF9fY29udGVudFwiIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XCI+Jyx0PTMsbys9JzxkaXYgY2xhc3M9XCJtZGwtbGF5b3V0IG1kbC1qcy1sYXlvdXQgbWRsLWxheW91dC0tZml4ZWQtaGVhZGVyXCI+Jyx0PTQsbys9JzxoZWFkZXIgY2xhc3M9XCJkZW1vLWhlYWRlciBtZGwtbGF5b3V0X19oZWFkZXIgbWRsLWNvbG9yLS1ncmV5LTEwMCBtZGwtY29sb3ItdGV4dC0tZ3JleS02MDBcIj4nLHQ9NSxvKz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXRfX2hlYWRlci1yb3dcIj4nLHQ9NixvKz0nPHNwYW4gY2xhc3M9XCJtZGwtbGF5b3V0LXRpdGxlXCI+Jyx0PTYsbys9XCJDb25maWd1cmUgZmFjZXQ8L3NwYW4+PC9kaXY+PC9oZWFkZXI+XCIsdD04LG8rPVwiPG1haW4+XCIsdD05LG8rPSc8ZGl2IGRhdGEtaG9vaz1cImZhY2V0LWRlZmluZVwiPjwvZGl2PicsdD0xMSxvKz0nPGRpdiBkYXRhLWhvb2s9XCJ0cmFuc2Zvcm0tY2F0ZWdvcmlhbC1wYW5lbFwiPicsdD0xMixvKz0nPGRpdiBkYXRhLWhvb2s9XCJmYWNldC10cmFuc2Zvcm0tY2F0ZWdvcmlhbFwiPjwvZGl2PjwvZGl2PicsdD0xMyxvKz0nPGRpdiBkYXRhLWhvb2s9XCJ0cmFuc2Zvcm0tY29udGludW91cy1wYW5lbFwiPicsdD0xNCxvKz0nPGRpdiBkYXRhLWhvb2s9XCJmYWNldC10cmFuc2Zvcm0tY29udGludW91c1wiPjwvZGl2PjwvZGl2PicsdD0xNSxvKz0nPGRpdiBkYXRhLWhvb2s9XCJ0cmFuc2Zvcm0tZGF0ZXRpbWUtcGFuZWxcIj4nLHQ9MTYsbys9JzxkaXYgZGF0YS1ob29rPVwiZmFjZXQtdHJhbnNmb3JtLWRhdGV0aW1lXCI+PC9kaXY+PC9kaXY+Jyx0PTE3LG8rPSc8ZGl2IGRhdGEtaG9vaz1cInRyYW5zZm9ybS1kdXJhdGlvbi1wYW5lbFwiPicsdD0xOCxvKz0nPGRpdiBkYXRhLWhvb2s9XCJmYWNldC10cmFuc2Zvcm0tZHVyYXRpb25cIj48L2Rpdj48L2Rpdj48L21haW4+PC9kaXY+PC9tYWluPjwvZGl2Pid9Y2F0Y2goZSl7cHVnLnJldGhyb3coZSxkLHQpfXJldHVybiBvfTtcclxuXHJcbiAgICBwdWdsYXRpemVyW1wiY29uZmlndXJlUGFydGl0aW9uXCJdID0ge31cclxuICAgIHB1Z2xhdGl6ZXJbXCJjb25maWd1cmVQYXJ0aXRpb25cIl1bXCJncm91cFwiXSA9IGZ1bmN0aW9uIHRlbXBsYXRlKHQpe3ZhciByLG8sYT1cIlwiO3RyeXtvPTEsYSs9XCI8dHI+XCIsbz0yLGErPSc8dGQgZGF0YS1ob29rPVwiZ3JvdXAtbGFiZWxcIj48L3RkPicsbz0zLGErPSc8dGQgZGF0YS1ob29rPVwiZ3JvdXAtY291bnRcIj48L3RkPjwvdHI+J31jYXRjaChkKXtwdWcucmV0aHJvdyhkLHIsbyl9cmV0dXJuIGF9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJjb25maWd1cmVQYXJ0aXRpb25cIl1bXCJwYWdlXCJdID0gZnVuY3Rpb24gdGVtcGxhdGUobCl7dmFyIGQsdCxpPVwiXCI7dHJ5e3Q9MSxpKz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQgbWRsLWpzLWxheW91dCBtZGwtbGF5b3V0LS1maXhlZC1oZWFkZXJcIj4nLHQ9MixpKz0nPG1haW4gY2xhc3M9XCJtZGwtbGF5b3V0X19jb250ZW50XCIgc3R5bGU9XCJiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTtcIj4nLHQ9NCxpKz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQgbWRsLWpzLWxheW91dCBtZGwtbGF5b3V0LS1maXhlZC1oZWFkZXJcIj4nLHQ9NSxpKz0nPGhlYWRlciBjbGFzcz1cImRlbW8taGVhZGVyIG1kbC1sYXlvdXRfX2hlYWRlciBtZGwtY29sb3ItLWdyZXktMTAwIG1kbC1jb2xvci10ZXh0LS1ncmV5LTYwMFwiPicsdD02LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWxheW91dF9faGVhZGVyLXJvd1wiPicsdD03LGkrPSc8c3BhbiBjbGFzcz1cIm1kbC1sYXlvdXQtdGl0bGVcIj4nLHQ9NyxpKz1cIkNvbmZpZ3VyZSBwYXJ0aXRpb248L3NwYW4+PC9kaXY+PC9oZWFkZXI+XCIsdD05LGkrPVwiPG1haW4+XCIsdD0xMCxpKz0nPGRpdiBjbGFzcz1cIm1kbC1ncmlkXCIgZGF0YS1ob29rPVwicGFydGl0aW9uLWdlbmVyYWxcIj4nLHQ9MTEsaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2wgZmFjZXRJY29uIGZhY2V0SW5mb0ljb25cIj48L2Rpdj4nLHQ9MTIsaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2xcIj48L2Rpdj4nLHQ9MTMsaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tOC1jb2xcIj4nLHQ9MTQsaSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sIG1kbC1ncmlkXCIgaWQ9XCJwYXJ0aXRpb24tbGFiZWwtZGl2XCI+Jyx0PTE1LGkrPSc8ZGl2IGNsYXNzPVwibWRsLXRleHRmaWVsZCBtZGwtanMtdGV4dGZpZWxkIG1kbC10ZXh0ZmllbGQtLWZsb2F0aW5nLWxhYmVsIG1kbC1jZWxsIG1kbC1jZWxsLS0xMi1jb2xcIj4nLHQ9MTYsaSs9JzxpbnB1dCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2lucHV0XCIgaWQ9XCJwYXJ0aXRpb24tdGl0bGVcIiBkYXRhLWhvb2s9XCJwYXJ0aXRpb24tdGl0bGUtaW5wdXRcIiB0eXBlPVwidGV4dFwiLz4nLHQ9MjAsaSs9JzxsYWJlbCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2xhYmVsXCIgZm9yPVwiXCI+Jyx0PTIwLGkrPVwiTGFiZWw8L2xhYmVsPjwvZGl2PjwvZGl2PlwiLHQ9MjIsaSs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2UgbWRsLXRvb2x0aXAtLXJpZ2h0XCIgZm9yPVwicGFydGl0aW9uLWxhYmVsLWRpdlwiPicsdD0yMyxpKz1cIlRoZSBsYWJlbCBhbG9uZyB0aGlzIGF4aXM8L2Rpdj5cIix0PTI1LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbCBtZGwtZ3JpZFwiIGlkPVwicGFydGl0aW9uLW9wdGlvbnMtZGl2XCI+Jyx0PTI2LGkrPSc8ZGl2IGNsYXNzPVwibWRsLXRleHRmaWVsZCBtZGwtanMtdGV4dGZpZWxkIG1kbC10ZXh0ZmllbGQtLWZsb2F0aW5nLWxhYmVsIG1kbC1jZWxsIG1kbC1jZWxsLS0zLWNvbFwiPicsdD0yNyxpKz0nPGxhYmVsIGNsYXNzPVwibWRsLWNoZWNrYm94IG1kbC1qcy1jaGVja2JveCBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGZvcj1cInBhcnRpdGlvbi1jYjFcIj4nLHQ9MjgsaSs9JzxpbnB1dCBjbGFzcz1cIm1kbC1jaGVja2JveF9faW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiBpZD1cInBhcnRpdGlvbi1jYjFcIiBkYXRhLWhvb2s9XCJzaG93LWxhYmVsXCIvPicsdD0yOSxpKz0nPHNwYW4gY2xhc3M9XCJtZGwtY2hlY2tib3hfX2xhYmVsXCI+Jyx0PTI5LGkrPVwiU2hvdyBsYWJlbDwvc3Bhbj48L2xhYmVsPjwvZGl2PlwiLHQ9MzEsaSs9JzxkaXYgY2xhc3M9XCJtZGwtdGV4dGZpZWxkIG1kbC1qcy10ZXh0ZmllbGQgbWRsLXRleHRmaWVsZC0tZmxvYXRpbmctbGFiZWwgbWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCI+Jyx0PTMyLGkrPSc8bGFiZWwgY2xhc3M9XCJtZGwtY2hlY2tib3ggbWRsLWpzLWNoZWNrYm94IG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwicGFydGl0aW9uLWNiMlwiPicsdD0zMyxpKz0nPGlucHV0IGNsYXNzPVwibWRsLWNoZWNrYm94X19pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiIGlkPVwicGFydGl0aW9uLWNiMlwiIGRhdGEtaG9vaz1cInNob3ctbGVnZW5kXCIvPicsdD0zNCxpKz0nPHNwYW4gY2xhc3M9XCJtZGwtY2hlY2tib3hfX2xhYmVsXCI+Jyx0PTM0LGkrPVwiU2hvdyBsZWdlbmQ8L3NwYW4+PC9sYWJlbD48L2Rpdj5cIix0PTM2LGkrPVwiPCEtLSBkaXYubWRsLXRleHRmaWVsZC5tZGwtanMtdGV4dGZpZWxkLm1kbC10ZXh0ZmllbGQtLWZsb2F0aW5nLWxhYmVsLm1kbC1jZWxsLm1kbC1jZWxsLS0zLWNvbC0tPlwiLHQ9MzcsaSs9JzwhLS0gICBsYWJlbChmb3I9XCJwYXJ0aXRpb24tY2IzXCIpLm1kbC1jaGVja2JveC5tZGwtanMtY2hlY2tib3gubWRsLWpzLXJpcHBsZS1lZmZlY3QtLT4nLHQ9MzgsaSs9JzwhLS0gICAgIGlucHV0KHR5cGU9XCJjaGVja2JveFwiIGlkPVwicGFydGl0aW9uLWNiM1wiIGRhdGEtaG9vaz1cImFjY3VtdWxhdGl2ZVwiKS5tZGwtY2hlY2tib3hfX2lucHV0LS0+Jyx0PTM5LGkrPVwiPCEtLSAgICAgc3Bhbi5tZGwtY2hlY2tib3hfX2xhYmVsIEFjY3VtdWxhdGl2ZS0tPlwiLHQ9NDEsaSs9XCI8IS0tIGRpdi5tZGwtdGV4dGZpZWxkLm1kbC1qcy10ZXh0ZmllbGQubWRsLXRleHRmaWVsZC0tZmxvYXRpbmctbGFiZWwubWRsLWNlbGwubWRsLWNlbGwtLTMtY29sLS0+XCIsdD00MixpKz0nPCEtLSAgIGxhYmVsKGZvcj1cInBhcnRpdGlvbi1jYjRcIikubWRsLWNoZWNrYm94Lm1kbC1qcy1jaGVja2JveC5tZGwtanMtcmlwcGxlLWVmZmVjdC0tPicsdD00MyxpKz0nPCEtLSAgICAgaW5wdXQodHlwZT1cImNoZWNrYm94XCIgaWQ9XCJwYXJ0aXRpb24tY2I0XCIgZGF0YS1ob29rPVwicmVsYXRpdmVcIikubWRsLWNoZWNrYm94X19pbnB1dC0tPicsdD00NCxpKz1cIjwhLS0gICAgIHNwYW4ubWRsLWNoZWNrYm94X19sYWJlbCBSZWxhdGl2ZS0tPjwvZGl2PlwiLHQ9NDYsaSs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2UgbWRsLXRvb2x0aXAtLXJpZ2h0XCIgZm9yPVwicGFydGl0aW9uLW9wdGlvbnMtZGl2XCI+Jyx0PTQ3LGkrPVwiU2V0IHZhcmlvdXMgb3B0aW9ucyBmb3IgdGhpcyBwYXJ0aXRpb248L2Rpdj48L2Rpdj5cIix0PTQ5LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTItY29sXCI+PC9kaXY+PC9kaXY+Jyx0PTUxLGkrPSc8ZGl2IGNsYXNzPVwibWRsLWdyaWRcIiBkYXRhLWhvb2s9XCJwYXJ0aXRpb24tY29udGludW91c1wiPjwvZGl2PicsdD01MixpKz0nPGRpdiBjbGFzcz1cIm1kbC1ncmlkXCIgZGF0YS1ob29rPVwicGFydGl0aW9uLWNhdGVnb3JpYWxcIj48L2Rpdj4nLHQ9NTMsaSs9JzxkaXYgY2xhc3M9XCJtZGwtZ3JpZFwiIGRhdGEtaG9vaz1cInBhcnRpdGlvbi1kYXRldGltZVwiPjwvZGl2PicsdD01NCxpKz0nPGRpdiBjbGFzcz1cIm1kbC1ncmlkXCIgZGF0YS1ob29rPVwicGFydGl0aW9uLWR1cmF0aW9uXCI+PC9kaXY+Jyx0PTU1LGkrPSc8ZGl2IGNsYXNzPVwibWRsLWdyaWRcIiBkYXRhLWhvb2s9XCJwYXJ0aXRpb24tdGV4dFwiPjwvZGl2PjwvbWFpbj48L2Rpdj48L21haW4+PC9kaXY+J31jYXRjaChlKXtwdWcucmV0aHJvdyhlLGQsdCl9cmV0dXJuIGl9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJjb25maWd1cmVQYXJ0aXRpb25cIl1bXCJwYXJ0aXRpb25DYXRlZ29yaWFsXCJdID0gZnVuY3Rpb24gdGVtcGxhdGUobCl7dmFyIHQsZCxvPVwiXCI7dHJ5e2Q9MSxvKz0nPGRpdiBjbGFzcz1cIm1kbC1ncmlkXCIgZGF0YS1ob29rPVwiZ3JvdXAtY2F0ZWdvcmlhbC1wYW5lbFwiPicsZD0yLG8rPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEtY29sIGZhY2V0SWNvbiBmYWNldENhdGVnb3JpYWxJY29uXCI+PC9kaXY+JyxkPTMsbys9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2xcIj48L2Rpdj4nLGQ9NCxvKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS04LWNvbFwiPicsZD01LG8rPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbFwiPicsZD02LG8rPSc8dGFibGUgc3R5bGU9XCJ3aWR0aDogMTAwJVwiPicsZD03LG8rPVwiPHRoZWFkPlwiLGQ9OCxvKz1cIjx0cj5cIixkPTksbys9XCI8dGg+XCIsZD0xMCxvKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWpzLWJ1dHRvblwiIGRhdGEtaG9vaz1cImdyb3VwLW9yZGVyLWFiY1wiPicsZD0xMCxvKz1cImxhYmVsPC9idXR0b24+PC90aD5cIixkPTExLG8rPVwiPHRoPlwiLGQ9MTIsbys9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b25cIiBkYXRhLWhvb2s9XCJncm91cC1vcmRlci1jb3VudFwiPicsZD0xMixvKz1cImNvdW50PC9idXR0b24+PC90aD48L3RyPjwvdGhlYWQ+XCIsZD0xMyxvKz0nPHRib2R5IGRhdGEtaG9vaz1cImdyb3Vwcy10YWJsZVwiPjwvdGJvZHk+PC90YWJsZT48L2Rpdj48L2Rpdj4nLGQ9MTQsbys9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMi1jb2xcIj48L2Rpdj48L2Rpdj4nfWNhdGNoKGMpe3B1Zy5yZXRocm93KGMsdCxkKX1yZXR1cm4gb307XHJcblxyXG4gICAgcHVnbGF0aXplcltcImNvbmZpZ3VyZVBhcnRpdGlvblwiXVtcInBhcnRpdGlvbkNvbnRpbnVvdXNcIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZShsKXt2YXIgZCxpLGU9XCJcIjt0cnl7aT0xLGUrPSc8ZGl2IGNsYXNzPVwibWRsLWdyaWRcIiBkYXRhLWhvb2s9XCJncm91cC1jb250aW51b3VzLXBhbmVsXCI+JyxpPTIsZSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2wgZmFjZXRJY29uIGZhY2V0Q29udGludW91c0ljb25cIj48L2Rpdj4nLGk9MyxlKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xLWNvbFwiPjwvZGl2PicsaT00LGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTgtY29sXCI+JyxpPTUsZSs9JzxkaXYgY2xhc3M9XCJtZGwtZ3JpZCBtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sXCI+JyxpPTcsZSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sIG1kbC1ncmlkXCIgaWQ9XCJncm91cC1yYW5nZS1kaXZcIj4nLGk9OCxlKz0nPGRpdiBjbGFzcz1cIm1kbC10ZXh0ZmllbGQgbWRsLWpzLXRleHRmaWVsZCBtZGwtdGV4dGZpZWxkLS1mbG9hdGluZy1sYWJlbCBtZGwtY2VsbCBtZGwtY2VsbC0tNC1jb2xcIj4nLGk9OSxlKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiBpZD1cImdyb3VwLW1pbmltdW1cIiBkYXRhLWhvb2s9XCJncm91cC1taW5pbXVtLWlucHV0XCIgdHlwZT1cInRleHRcIiBwYXR0ZXJuPVwiLT9bMC05XSooLlswLTldKyk/KGVbKy1dWzAtOV0rKT9cIi8+JyxpPTE0LGUrPSc8bGFiZWwgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19sYWJlbFwiIGZvcj1cImdyb3VwLW1pbmltdW1cIj4nLGk9MTQsZSs9XCJNaW5pbXVtIHZhbHVlPC9sYWJlbD5cIixpPTE1LGUrPSc8c3BhbiBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2Vycm9yXCI+JyxpPTE1LGUrPVwiSW5wdXQgaXMgbm90IGEgbnVtYmVyITwvc3Bhbj48L2Rpdj5cIixpPTE3LGUrPSc8ZGl2IGNsYXNzPVwibWRsLXRleHRmaWVsZCBtZGwtanMtdGV4dGZpZWxkIG1kbC10ZXh0ZmllbGQtLWZsb2F0aW5nLWxhYmVsIG1kbC1jZWxsIG1kbC1jZWxsLS00LWNvbFwiPicsaT0xOCxlKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiBpZD1cImdyb3VwLW1heGltdW1cIiBkYXRhLWhvb2s9XCJncm91cC1tYXhpbXVtLWlucHV0XCIgdHlwZT1cInRleHRcIiBwYXR0ZXJuPVwiLT9bMC05XSooLlswLTldKyk/KGVbKy1dWzAtOV0rKT9cIi8+JyxpPTIzLGUrPSc8bGFiZWwgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19sYWJlbFwiIGZvcj1cImdyb3VwLW1heGltdW1cIj4nLGk9MjMsZSs9XCJNYXhpbXVtIHZhbHVlPC9sYWJlbD5cIixpPTI0LGUrPSc8c3BhbiBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2Vycm9yXCI+JyxpPTI0LGUrPVwiSW5wdXQgaXMgbm90IGEgbnVtYmVyITwvc3Bhbj48L2Rpdj5cIixpPTI2LGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTQtY29sXCIgZGF0YS1ob29rPVwiZ3JvdXAtcmFuZ2UtYnV0dG9uXCI+JyxpPTI3LGUrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtanMtYnV0dG9uIG1kbC1idXR0b24tLXJhaXNlZCBtZGwtanMtcmlwcGxlLWVmZmVjdCBtZGwtYnV0dG9uLS1hY2NlbnRcIj4nLGk9MjcsZSs9XCJSZXNldCByYW5nZXM8L2J1dHRvbj48L2Rpdj48L2Rpdj5cIixpPTI5LGUrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlIG1kbC10b29sdGlwLS1yaWdodFwiIGZvcj1cImdyb3VwLXJhbmdlLWRpdlwiPicsaT0zMCxlKz1cIlJlc2V0IG1pbmludW0gYW5kIG1heGltdW0gdmFsdWVzLjwvZGl2PlwiLGk9MzMsZSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sIG1kbC1ncmlkXCIgaWQ9XCJncm91cC1wYXJhbS1kaXZcIj4nLGk9MzQsZSs9JzxkaXYgY2xhc3M9XCJtZGwtdGV4dGZpZWxkIG1kbC1qcy10ZXh0ZmllbGQgbWRsLXRleHRmaWVsZC0tZmxvYXRpbmctbGFiZWwgbWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbFwiPicsaT0zNSxlKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiBpZD1cImdyb3VwLXBhcmFtXCIgZGF0YS1ob29rPVwiZ3JvdXAtcGFyYW0taW5wdXRcIiB0eXBlPVwidGV4dFwiIHBhdHRlcm49XCItP1swLTldKiguWzAtOV0rKT9cIi8+JyxpPTQwLGUrPSc8bGFiZWwgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19sYWJlbFwiIGZvcj1cInNhbXBsZTRcIj4nLGk9NDAsZSs9XCJOdW1iZXIgb2YgYmlucyBvciBiaW5zaXplPC9sYWJlbD5cIixpPTQxLGUrPSc8c3BhbiBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2Vycm9yXCI+JyxpPTQxLGUrPVwiSW5wdXQgaXMgbm90IGEgbnVtYmVyITwvc3Bhbj48L2Rpdj48L2Rpdj5cIixpPTQzLGUrPSc8ZGl2IGNsYXNzPVwibWRsLXRvb2x0aXAgbWRsLXRvb2x0aXAtLWxhcmdlIG1kbC10b29sdGlwLS1yaWdodFwiIGZvcj1cImdyb3VwLXBhcmFtLWRpdlwiPicsaT00NCxlKz1cIlNldCB0aGUgbnVtYmVyIG9mIGJpbnMsIG9yIHRoZSBiaW4gc2l6ZTwvZGl2PlwiLGk9NDcsZSs9JzxkaXYgY2xhc3M9XCJtZGwtZ3JpZCBtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sXCIgaWQ9XCJncm91cC1kaXN0cmlidXRpb24tZGl2XCI+JyxpPTQ5LGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCI+JyxpPTUwLGUrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiZ3JvdXAtZml4ZWRuXCI+JyxpPTUxLGUrPSc8aW5wdXQgY2xhc3M9XCJtZGwtcmFkaW9fX2J1dHRvblwiIGlkPVwiZ3JvdXAtZml4ZWRuXCIgZGF0YS1ob29rPVwiZ3JvdXAtZml4ZWRuLWlucHV0XCIgdHlwZT1cInJhZGlvXCIgbmFtZT1cImdyb3VwLWRpc3RyaWJ1dGlvblwiIHZhbHVlPVwiZml4ZWRuXCIvPicsaT01NyxlKz0nPHNwYW4gY2xhc3M9XCJtZGwtcmFkaW9fX2xhYmVsXCI+JyxpPTU3LGUrPVwiRml4ZWQgbnVtYmVyIG9mIGJpbnM8L3NwYW4+PC9sYWJlbD48L2Rpdj5cIixpPTU5LGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCI+JyxpPTYwLGUrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiZ3JvdXAtZml4ZWRzY1wiPicsaT02MSxlKz0nPGlucHV0IGNsYXNzPVwibWRsLXJhZGlvX19idXR0b25cIiBpZD1cImdyb3VwLWZpeGVkc2NcIiBkYXRhLWhvb2s9XCJncm91cC1maXhlZHNjLWlucHV0XCIgdHlwZT1cInJhZGlvXCIgbmFtZT1cImdyb3VwLWRpc3RyaWJ1dGlvblwiIHZhbHVlPVwiZml4ZWRzY1wiLz4nLGk9NjcsZSs9JzxzcGFuIGNsYXNzPVwibWRsLXJhZGlvX19sYWJlbFwiPicsaT02NyxlKz1cIkZpeGVkIGJpbiBzaXplIChjZW50ZXJlZCk8L3NwYW4+PC9sYWJlbD48L2Rpdj5cIixpPTY5LGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCI+JyxpPTcwLGUrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiZ3JvdXAtZml4ZWRzXCI+JyxpPTcxLGUrPSc8aW5wdXQgY2xhc3M9XCJtZGwtcmFkaW9fX2J1dHRvblwiIGlkPVwiZ3JvdXAtZml4ZWRzXCIgZGF0YS1ob29rPVwiZ3JvdXAtZml4ZWRzLWlucHV0XCIgdHlwZT1cInJhZGlvXCIgbmFtZT1cImdyb3VwLWRpc3RyaWJ1dGlvblwiIHZhbHVlPVwiZml4ZWRzXCIvPicsaT03NyxlKz0nPHNwYW4gY2xhc3M9XCJtZGwtcmFkaW9fX2xhYmVsXCI+JyxpPTc3LGUrPVwiRml4ZWQgYmluIHNpemU8L3NwYW4+PC9sYWJlbD48L2Rpdj5cIixpPTc5LGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCI+JyxpPTgwLGUrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiZ3JvdXAtbG9nXCI+JyxpPTgxLGUrPSc8aW5wdXQgY2xhc3M9XCJtZGwtcmFkaW9fX2J1dHRvblwiIGlkPVwiZ3JvdXAtbG9nXCIgZGF0YS1ob29rPVwiZ3JvdXAtbG9nLWlucHV0XCIgdHlwZT1cInJhZGlvXCIgbmFtZT1cImdyb3VwLWRpc3RyaWJ1dGlvblwiIHZhbHVlPVwibG9nXCIvPicsaT04NyxlKz0nPHNwYW4gY2xhc3M9XCJtZGwtcmFkaW9fX2xhYmVsXCI+JyxpPTg3LGUrPVwiTG9nYXJpdGhtaWM8L3NwYW4+PC9sYWJlbD48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj5cIixpPTg5LGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTItY29sXCI+PC9kaXY+PC9kaXY+J31jYXRjaChhKXtwdWcucmV0aHJvdyhhLGQsaSl9cmV0dXJuIGV9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJjb25maWd1cmVQYXJ0aXRpb25cIl1bXCJwYXJ0aXRpb25EYXRldGltZVwiXSA9IGZ1bmN0aW9uIHRlbXBsYXRlKGwpe3ZhciB0LGUsZD1cIlwiO3RyeXtlPTEsZCs9JzxkaXYgY2xhc3M9XCJtZGwtZ3JpZFwiIGRhdGEtaG9vaz1cImdyb3VwLWRhdGV0aW1lLXBhbmVsXCI+JyxlPTIsZCs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2wgZmFjZXRJY29uIGZhY2V0VGltZUljb25cIj48L2Rpdj4nLGU9MyxkKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xLWNvbFwiPjwvZGl2PicsZT00LGQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTgtY29sIG1kbC1ncmlkXCI+JyxlPTUsZCs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sIG1kbC1ncmlkXCIgaWQ9XCJncm91cC1kYXRldGltZXJhbmdlLWRpdlwiPicsZT02LGQrPSc8ZGl2IGNsYXNzPVwibWRsLXRleHRmaWVsZCBtZGwtanMtdGV4dGZpZWxkIG1kbC10ZXh0ZmllbGQtLWZsb2F0aW5nLWxhYmVsIG1kbC1jZWxsIG1kbC1jZWxsLS0zLWNvbFwiPicsZT03LGQrPSc8aW5wdXQgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19pbnB1dFwiIGlkPVwiZ3JvdXAtc3RhcnRkYXRlXCIgZGF0YS1ob29rPVwiZ3JvdXAtc3RhcnRkYXRlLWlucHV0XCIgdHlwZT1cInRleHRcIi8+JyxlPTExLGQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19sYWJlbFwiIGZvcj1cImdyb3VwLXN0YXJ0ZGF0ZVwiPicsZT0xMSxkKz1cIlN0YXJ0IGRhdGU8L2xhYmVsPjwvZGl2PlwiLGU9MTMsZCs9JzxkaXYgY2xhc3M9XCJtZGwtdGV4dGZpZWxkIG1kbC1qcy10ZXh0ZmllbGQgbWRsLXRleHRmaWVsZC0tZmxvYXRpbmctbGFiZWwgbWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCI+JyxlPTE0LGQrPSc8aW5wdXQgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19pbnB1dFwiIGlkPVwiZ3JvdXAtZW5kZGF0ZVwiIGRhdGEtaG9vaz1cImdyb3VwLWVuZGRhdGUtaW5wdXRcIiB0eXBlPVwidGV4dFwiLz4nLGU9MTgsZCs9JzxsYWJlbCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2xhYmVsXCIgZm9yPVwiZ3JvdXAtZW5kZGF0ZVwiPicsZT0xOCxkKz1cIkVuZCBkYXRlPC9sYWJlbD48L2Rpdj5cIixlPTIwLGQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCI+JyxlPTIxLGQrPSc8ZGl2IGRhdGEtaG9vaz1cInRpbWUtem9uZXNcIj48L2Rpdj48L2Rpdj4nLGU9MjMsZCs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMy1jb2xcIj4nLGU9MjQsZCs9JzxzZWxlY3QgZGF0YS1ob29rPVwidGltZS11bml0c1wiPicsZT0yNSxkKz0nPG9wdGlvbiB2YWx1ZT1cImF1dG9cIj4nLGU9MjUsZCs9XCJhdXRvPC9vcHRpb24+XCIsZT0yNixkKz0nPG9wdGlvbiB2YWx1ZT1cIm1pbGxpc2Vjb25kc1wiPicsZT0yNixkKz1cIm1pbGxpc2Vjb25kczwvb3B0aW9uPlwiLGU9MjcsZCs9JzxvcHRpb24gdmFsdWU9XCJzZWNvbmRzXCI+JyxlPTI3LGQrPVwic2Vjb25kczwvb3B0aW9uPlwiLGU9MjgsZCs9JzxvcHRpb24gdmFsdWU9XCJtaW51dGVzXCI+JyxlPTI4LGQrPVwibWludXRlczwvb3B0aW9uPlwiLGU9MjksZCs9JzxvcHRpb24gdmFsdWU9XCJob3Vyc1wiPicsZT0yOSxkKz1cImhvdXJzPC9vcHRpb24+XCIsZT0zMCxkKz0nPG9wdGlvbiB2YWx1ZT1cImRheXNcIj4nLGU9MzAsZCs9XCJkYXlzPC9vcHRpb24+XCIsZT0zMSxkKz0nPG9wdGlvbiB2YWx1ZT1cIndlZWtzXCI+JyxlPTMxLGQrPVwid2Vla3M8L29wdGlvbj5cIixlPTMyLGQrPSc8b3B0aW9uIHZhbHVlPVwibW9udGhzXCI+JyxlPTMyLGQrPVwibW9udGhzPC9vcHRpb24+XCIsZT0zMyxkKz0nPG9wdGlvbiB2YWx1ZT1cInllYXJzXCI+JyxlPTMzLGQrPVwieWVhcnM8L29wdGlvbj48L3NlbGVjdD48L2Rpdj48L2Rpdj5cIixlPTM1LGQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbFwiIGRhdGEtaG9vaz1cImdyb3VwLWRhdGV0aW1lcmFuZ2UtYnV0dG9uXCI+JyxlPTM2LGQrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtanMtYnV0dG9uIG1kbC1idXR0b24tLXJhaXNlZCBtZGwtanMtcmlwcGxlLWVmZmVjdCBtZGwtYnV0dG9uLS1hY2NlbnRcIj4nLGU9MzYsZCs9XCJSZXNldCByYW5nZXM8L2J1dHRvbj48L2Rpdj48L2Rpdj5cIixlPTM4LGQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTItY29sXCI+PC9kaXY+PC9kaXY+J31jYXRjaChvKXtwdWcucmV0aHJvdyhvLHQsZSl9cmV0dXJuIGR9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJjb25maWd1cmVQYXJ0aXRpb25cIl1bXCJwYXJ0aXRpb25EdXJhdGlvblwiXSA9IGZ1bmN0aW9uIHRlbXBsYXRlKGwpe3ZhciBkLHQsZT1cIlwiO3RyeXt0PTEsZSs9JzxkaXYgY2xhc3M9XCJtZGwtZ3JpZFwiIGRhdGEtaG9vaz1cImdyb3VwLWR1cmF0aW9uLXBhbmVsXCI+Jyx0PTIsZSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2wgZmFjZXRJY29uIGZhY2V0VGltZUljb25cIj48L2Rpdj4nLHQ9MyxlKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS0xLWNvbFwiPjwvZGl2PicsdD00LGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTgtY29sXCI+Jyx0PTUsZSs9JzxkaXYgY2xhc3M9XCJtZGwtZ3JpZCBtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sXCI+Jyx0PTcsZSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMTItY29sIG1kbC1ncmlkXCIgaWQ9XCJncm91cC1kdXJhdGlvbnJhbmdlLWRpdlwiPicsdD04LGUrPSc8ZGl2IGNsYXNzPVwibWRsLXRleHRmaWVsZCBtZGwtanMtdGV4dGZpZWxkIG1kbC10ZXh0ZmllbGQtLWZsb2F0aW5nLWxhYmVsIG1kbC1jZWxsIG1kbC1jZWxsLS00LWNvbFwiPicsdD05LGUrPSc8aW5wdXQgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19pbnB1dFwiIGlkPVwiZ3JvdXAtc3RhcnRkdXJhdGlvblwiIGRhdGEtaG9vaz1cImdyb3VwLXN0YXJ0ZHVyYXRpb24taW5wdXRcIiB0eXBlPVwidGV4dFwiLz4nLHQ9MTMsZSs9JzxsYWJlbCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2xhYmVsXCIgZm9yPVwiZ3JvdXAtc3RhcnRkdXJhdGlvblwiPicsdD0xMyxlKz1cIlN0YXJ0IGludGVydmFsPC9sYWJlbD48L2Rpdj5cIix0PTE1LGUrPSc8ZGl2IGNsYXNzPVwibWRsLXRleHRmaWVsZCBtZGwtanMtdGV4dGZpZWxkIG1kbC10ZXh0ZmllbGQtLWZsb2F0aW5nLWxhYmVsIG1kbC1jZWxsIG1kbC1jZWxsLS00LWNvbFwiPicsdD0xNixlKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiBpZD1cImdyb3VwLWVuZGR1cmF0aW9uXCIgZGF0YS1ob29rPVwiZ3JvdXAtZW5kZHVyYXRpb24taW5wdXRcIiB0eXBlPVwidGV4dFwiLz4nLHQ9MjAsZSs9JzxsYWJlbCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2xhYmVsXCIgZm9yPVwiZ3JvdXAtZW5kZHVyYXRpb25cIj4nLHQ9MjAsZSs9XCJFbmQgaW50ZXJ2YWw8L2xhYmVsPjwvZGl2PlwiLHQ9MjIsZSs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tNC1jb2xcIiBkYXRhLWhvb2s9XCJncm91cC1kdXJhdGlvbnJhbmdlLWJ1dHRvblwiPicsdD0yMyxlKz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWpzLWJ1dHRvbiBtZGwtYnV0dG9uLS1yYWlzZWQgbWRsLWpzLXJpcHBsZS1lZmZlY3QgbWRsLWJ1dHRvbi0tYWNjZW50XCI+Jyx0PTIzLGUrPVwiUmVzZXQgcmFuZ2VzPC9idXR0b24+PC9kaXY+PC9kaXY+XCIsdD0yNSxlKz0nPGRpdiBjbGFzcz1cIm1kbC10b29sdGlwIG1kbC10b29sdGlwLS1sYXJnZSBtZGwtdG9vbHRpcC0tcmlnaHRcIiBmb3I9XCJncm91cC1kdXJhdGlvbnJhbmdlLWRpdlwiPicsdD0yNixlKz1cIlJlc2V0IHN0YXJ0IGFuZCBlbmQgaW50ZXJ2YWw8L2Rpdj48L2Rpdj48L2Rpdj5cIix0PTI4LGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTItY29sXCI+PC9kaXY+PC9kaXY+J31jYXRjaChpKXtwdWcucmV0aHJvdyhpLGQsdCl9cmV0dXJuIGV9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJjb25maWd1cmVQYXJ0aXRpb25cIl1bXCJwYXJ0aXRpb25UZXh0XCJdID0gZnVuY3Rpb24gdGVtcGxhdGUobCl7dmFyIGQsYyx0PVwiXCI7dHJ5e2M9MSx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1ncmlkXCIgZGF0YS1ob29rPVwiZ3JvdXAtdGV4dC1wYW5lbFwiPicsYz0yLHQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEtY29sIGZhY2V0SWNvbiBmYWNldFRleHRJY29uXCI+PC9kaXY+JyxjPTMsdCs9JzxkaXYgY2xhc3M9XCJtZGwtY2VsbCBtZGwtY2VsbC0tMS1jb2xcIj48L2Rpdj4nLGM9NCx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS04LWNvbFwiPicsYz01LHQrPSc8ZGl2IGNsYXNzPVwibWRsLWdyaWQgbWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbFwiPicsYz03LHQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCIgZGF0YS1ob29rPVwiZ3JvdXAtb3JkZXItYWJjXCI+JyxjPTgsdCs9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIj4nLGM9OCx0Kz1cIk9yZGVyIGFsZmFiZXRpY2FsbHk8L2J1dHRvbj48L2Rpdj5cIixjPTEwLHQrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTMtY29sXCIgZGF0YS1ob29rPVwiZ3JvdXAtb3JkZXItY291bnRcIj4nLGM9MTEsdCs9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIj4nLGM9MTEsdCs9XCJPcmRlciBieSBjb3VudDwvYnV0dG9uPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PlwifWNhdGNoKGUpe3B1Zy5yZXRocm93KGUsZCxjKX1yZXR1cm4gdH07XHJcblxyXG4gICAgcHVnbGF0aXplcltcImRhdGFzZXRzXCJdID0ge31cclxuICAgIHB1Z2xhdGl6ZXJbXCJkYXRhc2V0c1wiXVtcImRhdGFzZXRcIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZSh0KXt2YXIgYSxkLGw9XCJcIjt0cnl7ZD0xLGwrPSc8ZGl2IGNsYXNzPVwibWRsLWNhcmQgbWRsLXNoYWRvdy0tMmRwXCIgZGF0YS1ob29rPVwiZGF0YXNldFwiIHN0eWxlPVwibWluLWhlaWdodDogaW5oZXJpdFwiPicsZD0yLGwrPSc8ZGl2IGNsYXNzPVwibWRsLWNhcmRfX3RpdGxlXCI+JyxkPTMsbCs9JzxoMiBjbGFzcz1cIm1kbC1jYXJkX190aXRsZS10ZXh0XCIgZGF0YS1ob29rPVwibmFtZVwiPjwvaDI+PC9kaXY+JyxkPTUsbCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fc3VwcG9ydGluZy10ZXh0XCIgZGF0YS1ob29rPVwiZGVzY3JpcHRpb25cIj48L2Rpdj4nLGQ9NyxsKz0nPGRpdiBjbGFzcz1cIm1kbC1jYXJkX19hY3Rpb25zIG1kbC1jYXJkLS1ib3JkZXJcIj4nLGQ9OCxsKz0nPGEgY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1idXR0b24tLWNvbG9yZWQgbWRsLWpzLWJ1dHRvbiBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGRhdGEtaG9vaz1cImRlbGV0ZVwiPicsZD05LGwrPVwiRGVsZXRlPC9hPlwiLGQ9MTAsbCs9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcyBidXR0b24gbWRsLWJ1dHRvbi0taWNvbiBtZGwtYnV0dG9uLS1jb2xvcmVkXCIgZGF0YS1ob29rPVwic2V0dGluZ3NcIiBzdHlsZT1cImZsb2F0OiByaWdodFwiPicsZD0xMSxsKz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPicsZD0xMSxsKz1cInNldHRpbmdzPC9pPjwvYnV0dG9uPjwvZGl2PlwiLGQ9MTMsbCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fbWVudVwiPicsZD0xNCxsKz0nPHNwYW4gY2xhc3M9XCJtZGwtc3Bpbm5lciBtZGwtanMtc3Bpbm5lciBpcy1hY3RpdmVcIiBkYXRhLWhvb2s9XCJjYnNwaW5uZXJcIj48L3NwYW4+JyxkPTE1LGwrPSc8c3BhbiBkYXRhLWhvb2s9XCJjYnRvZ2dsZVwiPicsZD0xNixsKz0nPGxhYmVsIGNsYXNzPVwibWRsLXN3aXRjaCBtZGwtanMtc3dpdGNoIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZGF0YS1ob29rPVwiY2JsYWJlbFwiIGZvcj1cIlwiPicsZD0xNyxsKz0nPGlucHV0IGNsYXNzPVwibWRsLXN3aXRjaF9faW5wdXRcIiBkYXRhLWhvb2s9XCJjYlwiIHR5cGU9XCJjaGVja2JveFwiIGlkPVwiXCIvPjwvbGFiZWw+JyxkPTE4LGwrPSc8c3BhbiBjbGFzcz1cIm1kbC1zd2l0Y2hfX2xhYmVsXCI+PC9zcGFuPjwvc3Bhbj48L2Rpdj48L2Rpdj4nfWNhdGNoKHMpe3B1Zy5yZXRocm93KHMsYSxkKX1yZXR1cm4gbH07XHJcblxyXG4gICAgcHVnbGF0aXplcltcImRhdGFzZXRzXCJdW1wiZGF0YXNldENvbGxlY3Rpb25cIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZSh0KXt2YXIgYSxlLHI9XCJcIjt0cnl7ZT0xLHIrPSc8ZGl2IGRhdGEtaG9vaz1cIml0ZW1zXCIgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBmbGV4LXdyYXA6IHdyYXA7XCI+PC9kaXY+J31jYXRjaChpKXtwdWcucmV0aHJvdyhpLGEsZSl9cmV0dXJuIHJ9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJkYXRhc2V0c1wiXVtcInBhZ2VcIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZSh0KXt2YXIgYSxsLGQ9XCJcIjt0cnl7bD0xLGQrPSc8ZGl2IGNsYXNzPVwibWRsLWxheW91dCBtZGwtanMtbGF5b3V0IG1kbC1sYXlvdXQtLWZpeGVkLWhlYWRlclwiPicsbD0yLGQrPSc8bWFpbiBjbGFzcz1cIm1kbC1sYXlvdXRfX2NvbnRlbnRcIiBzdHlsZT1cImJhY2tncm91bmQtY29sb3I6IHdoaXRlO1wiPicsbD0zLGQrPVwiPGRpdj5cIixsPTUsZCs9JzxkaXYgY2xhc3M9XCJtZGwtZ3JpZFwiPicsbD02LGQrPSc8ZGlhbG9nIGNsYXNzPVwibWRsLWRpYWxvZ1wiIGRhdGEtaG9vaz1cIkNTVi1zZXR0aW5nc1wiPicsbD03LGQrPSc8ZGl2IGNsYXNzPVwibWRsLWRpYWxvZ19fY29udGVudFwiPicsbD04LGQrPSc8c2VjdGlvbiBjbGFzcz1cIm1kbC1ncmlkXCIgaWQ9XCJjc3Ytc2V0dGluZ3MtdGFibGVcIiBuYW1lPVwiY3N2LXNldHRpbmdzLXRhYmxlXCI+JyxsPTksZCs9XCI8ZGl2PlwiLGw9MTAsZCs9Jzx0YWJsZSBjbGFzcz1cIm1kbC1kYXRhLXRhYmxlIG1kbC1qcy1kYXRhLXRhYmxlXCI+JyxsPTExLGQrPVwiPHRib2R5PlwiLGw9MTIsZCs9XCI8dHI+XCIsbD0xMyxkKz1cIjx0ZD5cIixsPTEzLGQrPVwiSGVhZGVyczwvdGQ+XCIsbD0xNCxkKz1cIjx0ZD5cIixsPTE1LGQrPVwiPHNwYW4+XCIsbD0xNixkKz0nPGxhYmVsIGNsYXNzPVwibWRsLWNoZWNrYm94IG1kbC1qcy1jaGVja2JveCBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGZvcj1cIkNTVi1oZWFkZXItY29sdW1uc1wiPicsbD0xNyxkKz1cIkVuYWJsZVwiLGw9MTgsZCs9JzxpbnB1dCBjbGFzcz1cIm1kbC1jaGVja2JveF9faW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiBpZD1cIkNTVi1oZWFkZXItY29sdW1uc1wiLz48L2xhYmVsPjwvc3Bhbj48L3RkPjwvdHI+JyxsPTE5LGQrPVwiPHRyPlwiLGw9MjAsZCs9XCI8dGQ+XCIsbD0yMCxkKz1cIkRlbGltaXRlcjwvdGQ+XCIsbD0yMSxkKz1cIjx0ZD5cIixsPTIyLGQrPVwiPHNwYW4+XCIsbD0yMyxkKz0nPGxhYmVsIGNsYXNzPVwibWRsLXJhZGlvIG1kbC1qcy1yYWRpbyBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGZvcj1cIkNTVi1zZXBhcmF0b3ItY29tbWFcIj4nLGw9MjQsZCs9JzxpbnB1dCBjbGFzcz1cIm1kbC1yYWRpb19fYnV0dG9uXCIgdHlwZT1cInJhZGlvXCIgaWQ9XCJDU1Ytc2VwYXJhdG9yLWNvbW1hXCIgbmFtZT1cIkNTVi1zZXBhcmF0b3Itb3B0aW9uc1wiIHZhbHVlPVwiY29tbWFcIi8+PC9sYWJlbD48L3NwYW4+JyxsPTI1LGQrPSc8c3BhbiBjbGFzcz1cIm1kbC10eXBvZ3JhcGh5LS10aXRsZS1jb2xvci1jb250cmFzdFwiPicsbD0yNixkKz1cIiw8L3NwYW4+PC90ZD5cIixsPTI3LGQrPVwiPHRkPlwiLGw9MjgsZCs9XCI8c3Bhbj5cIixsPTI5LGQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiQ1NWLXNlcGFyYXRvci1jb2xvblwiPicsbD0zMCxkKz0nPGlucHV0IGNsYXNzPVwibWRsLXJhZGlvX19idXR0b25cIiB0eXBlPVwicmFkaW9cIiBpZD1cIkNTVi1zZXBhcmF0b3ItY29sb25cIiBuYW1lPVwiQ1NWLXNlcGFyYXRvci1vcHRpb25zXCIgdmFsdWU9XCJjb2xvblwiLz48L2xhYmVsPjwvc3Bhbj4nLGw9MzEsZCs9JzxzcGFuIGNsYXNzPVwibWRsLXR5cG9ncmFwaHktLXRpdGxlLWNvbG9yLWNvbnRyYXN0XCI+JyxsPTMyLGQrPVwiOjwvc3Bhbj48L3RkPlwiLGw9MzMsZCs9XCI8dGQ+XCIsbD0zNCxkKz1cIjxzcGFuPlwiLGw9MzUsZCs9JzxsYWJlbCBjbGFzcz1cIm1kbC1yYWRpbyBtZGwtanMtcmFkaW8gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIiBmb3I9XCJDU1Ytc2VwYXJhdG9yLXNlbWljb2xvblwiPicsbD0zNixkKz0nPGlucHV0IGNsYXNzPVwibWRsLXJhZGlvX19idXR0b25cIiB0eXBlPVwicmFkaW9cIiBpZD1cIkNTVi1zZXBhcmF0b3Itc2VtaWNvbG9uXCIgbmFtZT1cIkNTVi1zZXBhcmF0b3Itb3B0aW9uc1wiIHZhbHVlPVwic2VtaWNvbG9uXCIvPjwvbGFiZWw+PC9zcGFuPicsbD0zNyxkKz0nPHNwYW4gY2xhc3M9XCJtZGwtdHlwb2dyYXBoeS0tdGl0bGUtY29sb3ItY29udHJhc3RcIj4nLGw9MzgsZCs9XCI7PC9zcGFuPjwvdGQ+XCIsbD0zOSxkKz1cIjx0ZD5cIixsPTQwLGQrPVwiPHNwYW4+XCIsbD00MSxkKz0nPGxhYmVsIGNsYXNzPVwibWRsLXJhZGlvIG1kbC1qcy1yYWRpbyBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGZvcj1cIkNTVi1zZXBhcmF0b3ItcGlwZVwiPicsbD00MixkKz0nPGlucHV0IGNsYXNzPVwibWRsLXJhZGlvX19idXR0b25cIiB0eXBlPVwicmFkaW9cIiBpZD1cIkNTVi1zZXBhcmF0b3ItcGlwZVwiIG5hbWU9XCJDU1Ytc2VwYXJhdG9yLW9wdGlvbnNcIiB2YWx1ZT1cInBpcGVcIi8+PC9sYWJlbD48L3NwYW4+JyxsPTQzLGQrPSc8c3BhbiBjbGFzcz1cIm1kbC10eXBvZ3JhcGh5LS10aXRsZS1jb2xvci1jb250cmFzdFwiPicsbD00NCxkKz1cInw8L3NwYW4+PC90ZD5cIixsPTQ1LGQrPVwiPHRkPlwiLGw9NDYsZCs9XCI8c3Bhbj5cIixsPTQ3LGQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiQ1NWLXNlcGFyYXRvci10YWJcIj4nLGw9NDgsZCs9JzxpbnB1dCBjbGFzcz1cIm1kbC1yYWRpb19fYnV0dG9uXCIgdHlwZT1cInJhZGlvXCIgaWQ9XCJDU1Ytc2VwYXJhdG9yLXRhYlwiIG5hbWU9XCJDU1Ytc2VwYXJhdG9yLW9wdGlvbnNcIiB2YWx1ZT1cInRhYlwiLz48L2xhYmVsPjwvc3Bhbj4nLGw9NDksZCs9XCI8c3Bhbj5cIixsPTUwLGQrPVwiVGFiPC9zcGFuPjwvdGQ+XCIsbD01MSxkKz1cIjx0ZD5cIixsPTUyLGQrPVwiPHNwYW4+XCIsbD01MyxkKz0nPGxhYmVsIGNsYXNzPVwibWRsLXJhZGlvIG1kbC1qcy1yYWRpbyBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGZvcj1cIkNTVi1zZXBhcmF0b3Itb3RoZXJcIj4nLGw9NTQsZCs9JzxpbnB1dCBjbGFzcz1cIm1kbC1yYWRpb19fYnV0dG9uXCIgdHlwZT1cInJhZGlvXCIgZGF0YS1ob29rPVwiQ1NWLXNlcGFyYXRvci1vdGhlclwiIGlkPVwiQ1NWLXNlcGFyYXRvci1vdGhlclwiIG5hbWU9XCJDU1Ytc2VwYXJhdG9yLW9wdGlvbnNcIiB2YWx1ZT1cIm90aGVyXCIvPjwvbGFiZWw+PC9zcGFuPicsbD01NSxkKz0nPGRpdiBjbGFzcz1cIm1kbC10ZXh0ZmllbGQgbWRsLWpzLXRleHRmaWVsZCBtZGwtdGV4dGZpZWxkLS1mbG9hdGluZy1sYWJlbFwiIHN0eWxlPVwid2lkdGg6IGZpdC1jb250ZW50O1wiPicsbD01NixkKz0nPGlucHV0IGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIiBkYXRhLWhvb2s9XCJDU1Ytc2VwYXJhdG9yLW90aGVyLWlucHV0XCIgdHlwZT1cInRleHRcIiBpZD1cIkNTVi1zZXBhcmF0b3Itb3RoZXItaW5wdXRcIiBuYW1lPVwiQ1NWLXNlcGFyYXRvci1vdGhlci1pbnB1dFwiLz4nLGw9NTcsZCs9JzxsYWJlbCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2xhYmVsXCIgZm9yPVwiQ1NWLXNlcGFyYXRvci1vdGhlci1pbnB1dFwiPicsbD01OCxkKz1cIk90aGVyPC9sYWJlbD48L2Rpdj48L3RkPjwvdHI+XCIsbD01OSxkKz1cIjx0cj5cIixsPTYwLGQrPVwiPHRkPlwiLGw9NjAsZCs9XCJRdW90aW5nPC90ZD5cIixsPTYxLGQrPVwiPHRkPlwiLGw9NjIsZCs9XCI8c3Bhbj5cIixsPTYzLGQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiQ1NWLXF1b3RlLW5vbmVcIj4nLGw9NjQsZCs9JzxpbnB1dCBjbGFzcz1cIm1kbC1yYWRpb19fYnV0dG9uXCIgdHlwZT1cInJhZGlvXCIgaWQ9XCJDU1YtcXVvdGUtbm9uZVwiIG5hbWU9XCJDU1YtcXVvdGVcIiB2YWx1ZT1cIm5vbmVcIi8+PC9sYWJlbD48L3NwYW4+JyxsPTY1LGQrPVwiPHNwYW4+XCIsbD02NixkKz1cIk5vbmU8L3NwYW4+PC90ZD5cIixsPTY3LGQrPVwiPHRkPlwiLGw9NjgsZCs9XCI8c3Bhbj5cIixsPTY5LGQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiQ1NWLXF1b3RlLXNpbmdsZVwiPicsbD03MCxkKz0nPGlucHV0IGNsYXNzPVwibWRsLXJhZGlvX19idXR0b25cIiB0eXBlPVwicmFkaW9cIiBpZD1cIkNTVi1xdW90ZS1zaW5nbGVcIiBuYW1lPVwiQ1NWLXF1b3RlXCIgdmFsdWU9XCJzaW5nbGVcIi8+PC9sYWJlbD48L3NwYW4+JyxsPTcxLGQrPSc8c3BhbiBjbGFzcz1cIm1kbC10eXBvZ3JhcGh5LS10aXRsZS1jb2xvci1jb250cmFzdFwiPicsbD03MixkKz1cIic8L3NwYW4+PC90ZD5cIixsPTczLGQrPVwiPHRkPlwiLGw9NzQsZCs9XCI8c3Bhbj5cIixsPTc1LGQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiQ1NWLXF1b3RlLWRvdWJsZVwiPicsbD03NixkKz0nPGlucHV0IGNsYXNzPVwibWRsLXJhZGlvX19idXR0b25cIiB0eXBlPVwicmFkaW9cIiBpZD1cIkNTVi1xdW90ZS1kb3VibGVcIiBuYW1lPVwiQ1NWLXF1b3RlXCIgdmFsdWU9XCJkb3VibGVcIi8+PC9sYWJlbD48L3NwYW4+JyxsPTc3LGQrPSc8c3BhbiBjbGFzcz1cIm1kbC10eXBvZ3JhcGh5LS10aXRsZS1jb2xvci1jb250cmFzdFwiPicsbD03OCxkKz0nXCI8L3NwYW4+PC90ZD48L3RyPicsbD03OSxkKz1cIjx0cj5cIixsPTgwLGQrPVwiPHRkPlwiLGw9ODAsZCs9XCJDb21tZW50czwvdGQ+XCIsbD04MSxkKz1cIjx0ZD5cIixsPTgyLGQrPVwiPHNwYW4+XCIsbD04MyxkKz0nPGxhYmVsIGNsYXNzPVwibWRsLXJhZGlvIG1kbC1qcy1yYWRpbyBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGZvcj1cIkNTVi1jb21tZW50LXBvdW5kXCI+JyxsPTg0LGQrPSc8aW5wdXQgY2xhc3M9XCJtZGwtcmFkaW9fX2J1dHRvblwiIHR5cGU9XCJyYWRpb1wiIGlkPVwiQ1NWLWNvbW1lbnQtcG91bmRcIiBuYW1lPVwiQ1NWLWNvbW1lbnRcIiB2YWx1ZT1cInBvdW5kXCIvPjwvbGFiZWw+PC9zcGFuPicsbD04NSxkKz0nPHNwYW4gY2xhc3M9XCJtZGwtdHlwb2dyYXBoeS0tdGl0bGUtY29sb3ItY29udHJhc3RcIj4nLGw9ODYsZCs9XCIjPC9zcGFuPjwvdGQ+XCIsbD04NyxkKz1cIjx0ZD5cIixsPTg4LGQrPVwiPHNwYW4+XCIsbD04OSxkKz0nPGxhYmVsIGNsYXNzPVwibWRsLXJhZGlvIG1kbC1qcy1yYWRpbyBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGZvcj1cIkNTVi1jb21tZW50LWV4Y2xhbWF0aW9uXCI+JyxsPTkwLGQrPSc8aW5wdXQgY2xhc3M9XCJtZGwtcmFkaW9fX2J1dHRvblwiIHR5cGU9XCJyYWRpb1wiIGlkPVwiQ1NWLWNvbW1lbnQtZXhjbGFtYXRpb25cIiBuYW1lPVwiQ1NWLWNvbW1lbnRcIiB2YWx1ZT1cImV4Y2xhbWF0aW9uXCIvPjwvbGFiZWw+PC9zcGFuPicsbD05MSxkKz0nPHNwYW4gY2xhc3M9XCJtZGwtdHlwb2dyYXBoeS0tdGl0bGUtY29sb3ItY29udHJhc3RcIj4nLGw9OTIsZCs9XCIhPC9zcGFuPjwvdGQ+XCIsbD05MyxkKz1cIjx0ZD5cIixsPTk0LGQrPVwiPHNwYW4+XCIsbD05NSxkKz0nPGxhYmVsIGNsYXNzPVwibWRsLXJhZGlvIG1kbC1qcy1yYWRpbyBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGZvcj1cIkNTVi1jb21tZW50LXNsYXNoXCI+JyxsPTk2LGQrPSc8aW5wdXQgY2xhc3M9XCJtZGwtcmFkaW9fX2J1dHRvblwiIHR5cGU9XCJyYWRpb1wiIGlkPVwiQ1NWLWNvbW1lbnQtc2xhc2hcIiBuYW1lPVwiQ1NWLWNvbW1lbnRcIiB2YWx1ZT1cInNsYXNoXCIvPjwvbGFiZWw+PC9zcGFuPicsbD05NyxkKz0nPHNwYW4gY2xhc3M9XCJtZGwtdHlwb2dyYXBoeS0tdGl0bGUtY29sb3ItY29udHJhc3RcIj4nLGw9OTgsZCs9XCIvPC9zcGFuPjwvdGQ+XCIsbD05OSxkKz1cIjx0ZD5cIixsPTEwMCxkKz1cIjxzcGFuPlwiLGw9MTAxLGQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiQ1NWLWNvbW1lbnQtZGFzaFwiPicsbD0xMDIsZCs9JzxpbnB1dCBjbGFzcz1cIm1kbC1yYWRpb19fYnV0dG9uXCIgdHlwZT1cInJhZGlvXCIgaWQ9XCJDU1YtY29tbWVudC1kYXNoXCIgbmFtZT1cIkNTVi1jb21tZW50XCIgdmFsdWU9XCJkYXNoXCIvPjwvbGFiZWw+PC9zcGFuPicsbD0xMDMsZCs9JzxzcGFuIGNsYXNzPVwibWRsLXR5cG9ncmFwaHktLXRpdGxlLWNvbG9yLWNvbnRyYXN0XCI+JyxsPTEwNCxkKz1cIi08L3NwYW4+PC90ZD5cIixsPTEwNSxkKz1cIjx0ZD5cIixsPTEwNixkKz1cIjxzcGFuPlwiLGw9MTA3LGQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtcmFkaW8gbWRsLWpzLXJhZGlvIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZm9yPVwiQ1NWLWNvbW1lbnQtcGVyY2VudFwiPicsbD0xMDgsZCs9JzxpbnB1dCBjbGFzcz1cIm1kbC1yYWRpb19fYnV0dG9uXCIgdHlwZT1cInJhZGlvXCIgaWQ9XCJDU1YtY29tbWVudC1wZXJjZW50XCIgbmFtZT1cIkNTVi1jb21tZW50XCIgdmFsdWU9XCJwZXJjZW50XCIvPjwvbGFiZWw+PC9zcGFuPicsbD0xMDksZCs9JzxzcGFuIGNsYXNzPVwibWRsLXR5cG9ncmFwaHktLXRpdGxlLWNvbG9yLWNvbnRyYXN0XCI+JyxsPTExMCxkKz1cIiU8L3NwYW4+PC90ZD48L3RyPjwvdGJvZHk+PC90YWJsZT48L2Rpdj48L3NlY3Rpb24+XCIsbD0xMTIsZCs9JzxkaXYgY2xhc3M9XCJtZGwtZGlhbG9nX19hY3Rpb25zIG1kbC1kaWFsb2dfX2FjdGlvbnNcIj4nLGw9MTE0LGQrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBjbG9zZVwiIGRhdGEtaG9vaz1cIkNTVi1zZXR0aW5ncy1jbG9zZVwiIHR5cGU9XCJidXR0b25cIj4nLGw9MTE0LGQrPVwiQ2xvc2U8L2J1dHRvbj48L2Rpdj48L2Rpdj48L2RpYWxvZz48L2Rpdj5cIixsPTExNixkKz0nPGRpYWxvZyBjbGFzcz1cIm1kbC1kaWFsb2dcIiBkYXRhLWhvb2s9XCJzZXNzaW9uLWRvd25sb2FkLWNsb3VkXCI+JyxsPTExNyxkKz0nPGRpdiBjbGFzcz1cIm1kbC1kaWFsb2dfX2NvbnRlbnRcIj4nLGw9MTE4LGQrPVwiPHA+PC9wPlwiLGw9MTE5LGQrPVwiRW50ZXIgdGhlIHVybCBvZiB0aGUgc2Vzc2lvbi4gPGJyLz5NYWtlIHN1cmUgdGhhdCB5b3Ugc2F2ZWQgeW91ciBjdXJyZW50IHNlc3Npb24hXCIsbD0xMjAsZCs9JzxkaXYgY2xhc3M9XCJtZGwtdGV4dGZpZWxkIG1kbC1qcy10ZXh0ZmllbGQgbWRsLXRleHRmaWVsZC0tZmxvYXRpbmctbGFiZWwgbWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbFwiPicsbD0xMjEsZCs9JzxpbnB1dCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2lucHV0XCIgaWQ9XCJzZXNzaW9uLWltcG9ydC1yZW1vdGUtbGlua1wiIGRhdGEtaG9vaz1cInNlc3Npb24taW1wb3J0LXJlbW90ZS1saW5rXCIgdHlwZT1cInRleHRcIi8+PC9kaXY+PC9kaXY+JyxsPTEyMixkKz0nPGRpdiBjbGFzcz1cIm1kbC1kaWFsb2dfX2FjdGlvbnMgbWRsLWRpYWxvZ19fYWN0aW9uc1wiPicsbD0xMjMsZCs9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uXCIgZGF0YS1ob29rPVwic2Vzc2lvbi1kb3dubG9hZC1jbG91ZC1nZXRcIiB0eXBlPVwiYnV0dG9uXCI+JyxsPTEyMyxkKz1cIkltcG9ydDwvYnV0dG9uPlwiLGw9MTI0LGQrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBjbG9zZVwiIGRhdGEtaG9vaz1cInNlc3Npb24tZG93bmxvYWQtY2xvdWQtY2xvc2UtYnV0dG9uXCIgdHlwZT1cImJ1dHRvblwiPicsbD0xMjQsZCs9XCJDYW5jZWw8L2J1dHRvbj48L2Rpdj48L2RpYWxvZz5cIixsPTEyNyxkKz0nPGhlYWRlciBjbGFzcz1cIm1kbC1sYXlvdXRfX2hlYWRlciBtZGwtY29sb3ItLWdyZXktMTAwIG1kbC1jb2xvci10ZXh0LS1ncmV5LTYwMFwiPicsbD0xMjgsZCs9JzxkaXYgY2xhc3M9XCJtZGwtbGF5b3V0X19oZWFkZXItcm93XCI+JyxsPTEyOSxkKz0nPHNwYW4gY2xhc3M9XCJtZGwtbGF5b3V0LXRpdGxlXCIgc3R5bGU9XCJwYWRkaW5nOiAwOyB0ZXh0LWFsaWduOiBjZW50ZXI7XCI+JyxsPTEyOSxkKz1cIkRhdGFzZXRzPC9zcGFuPlwiLGw9MTMxLGQrPSc8ZGl2IGNsYXNzPVwibWRsLWxheW91dC1zcGFjZXJcIj48L2Rpdj4nLGw9MTMzLGQrPSc8YnV0dG9uIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtanMtYnV0dG9uIG1kbC1idXR0b24tLWljb24gbWRsLWpzLXJpcHBsZS1lZmZlY3RcIiBkYXRhLWhvb2s9XCJzZWFyY2gtYnV0dG9uXCIgaWQ9XCJ0dDNcIiBkYXRhLXBvc2l0aW9uPVwiYm90dG9tXCIgZGF0YS1zdGVwPVwiMVwiIGRhdGEtaW50cm89XCJZb3UgY2FuIHNlYXJjaCBhdmFpbGFibGUgZGF0YXNldHMgaGVyZS5cIj4nLGw9MTM0LGQrPSc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+JyxsPTEzNCxkKz1cInNlYXJjaDwvaT48L2J1dHRvbj5cIixsPTEzNixkKz0nPGRpdiBjbGFzcz1cIm1kbC10b29sdGlwIG1kbC10b29sdGlwLS1sYXJnZVwiIGZvcj1cInR0M1wiPicsbD0xMzcsZCs9XCJTaG93IG9yIGhpZGUgc2VhcmNoIGJhcjwvZGl2PjwvZGl2PlwiLGw9MTM5LGQrPSc8ZGl2IGNsYXNzPVwibWRsLWxheW91dF9faGVhZGVyLXJvd1wiIGRhdGEtaG9vaz1cInNlYXJjaC1iYXJcIj4nLGw9MTQwLGQrPSc8ZGl2IGNsYXNzPVwibWRsLWxheW91dC1zcGFjZXJcIj48L2Rpdj4nLGw9MTQxLGQrPSc8c3BhbiBjbGFzcz1cIm1kbC1jb2xvci0td2hpdGUgbWRsLWNvbG9yLXRleHQtLXByaW1hcnkgc2VhcmNoQmFyXCI+JyxsPTE0MyxkKz0nPHNwYW4gY2xhc3M9XCJtZGwtdGV4dGZpZWxkIHNlYXJjaEJhclwiPicsbD0xNDQsZCs9JzxpbnB1dCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2lucHV0IHNlYXJjaEJhclwiIGRhdGEtaG9vaz1cImRhdGFzZXQtc2VsZWN0b3JcIiB0eXBlPVwidGV4dFwiIGlkPVwidHQ1XCIvPicsbD0xNDUsZCs9JzxkaXYgY2xhc3M9XCJtZGwtdG9vbHRpcCBtZGwtdG9vbHRpcC0tbGFyZ2VcIiBmb3I9XCJ0dDVcIj4nLGw9MTQ2LGQrPVwiU2VhcmNoIGZhY2V0IG5hbWUgYW5kIGRlc2NyaXB0aW9uPC9kaXY+PC9zcGFuPjwvc3Bhbj48L2Rpdj5cIixsPTE0OCxkKz0nPGRpdiBkYXRhLWhvb2s9XCJhZGQtZGF0YXNldHMtZGl2XCIgaWQ9XCJhZGQtZGF0YXNldHMtZGl2XCI+JyxsPTE0OSxkKz0nPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogY2VudGVyO1wiPicsbD0xNTAsZCs9JzxkaXYgY2xhc3M9XCJkYXRhLXBhZ2UtY2FyZC1idXR0b24gbWRsLWNhcmQgbWRsLXNoYWRvdy0tMmRwXCI+JyxsPTE1MSxkKz0nPGRpdiBjbGFzcz1cIm1kbC1jYXJkX190aXRsZVwiPicsbD0xNTIsZCs9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWJ1dHRvbi0tcmFpc2VkIG1kbC1jb2xvci0tYmx1ZS1ncmV5LTkwMCBtZGwtY29sb3ItdGV4dC0td2hpdGUgbWRsLWpzLXJpcHBsZS1lZmZlY3Qgc2VydmVyY29ubmVjdC1idG5cIiBkYXRhLWhvb2s9XCJzZXJ2ZXItY29ubmVjdFwiIGlkPVwic2VydmVyQnV0dG9uXCI+JyxsPTE1MyxkKz1cIkNvbm5lY3Q8L2J1dHRvbj48L2Rpdj5cIixsPTE1NCxkKz0nPGRpdiBjbGFzcz1cIm1kbC1jYXJkX19zdXBwb3J0aW5nLXRleHRcIj4nLGw9MTU1LGQrPVwiQ29ubmVjdCB0byBhIFBvc3RncmVTUUwgc2VydmVyLjwvZGl2PjwvZGl2PlwiLGw9MTU3LGQrPSc8ZGl2IGNsYXNzPVwiZGF0YS1wYWdlLWNhcmQtYnV0dG9uIG1kbC1jYXJkIG1kbC1zaGFkb3ctLTJkcFwiPicsbD0xNTgsZCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fdGl0bGVcIj4nLGw9MTU5LGQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWJ1dHRvbi0tcmFpc2VkIG1kbC1jb2xvci0tYmx1ZS1ncmV5LTkwMCBtZGwtY29sb3ItdGV4dC0td2hpdGUgbWRsLWpzLXJpcHBsZS1lZmZlY3QganNvbnVwbG9hZC1idG5cIiBmb3I9XCJqc29udXBsb2FkQnRuXCIgaWQ9XCJqc29uVXBsb2FkTGFiZWxcIj4nLGw9MTYwLGQrPVwiSW1wb3J0IEpTT048L2xhYmVsPlwiLGw9MTYxLGQrPSc8aW5wdXQgY2xhc3M9XCJmaWxlQnRuXCIgdHlwZT1cImZpbGVcIiBhY2NlcHQ9XCIuanNvblwiIGRhdGEtaG9vaz1cImpzb24tdXBsb2FkLWlucHV0XCIgaWQ9XCJqc29udXBsb2FkQnRuXCIvPjwvZGl2PicsbD0xNjIsZCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fc3VwcG9ydGluZy10ZXh0XCI+JyxsPTE2MyxkKz1cIkltcG9ydCBhIEpTT04gZmlsZSBmcm9tIHlvdXIgY29tcHV0ZXIuPC9kaXY+PC9kaXY+XCIsbD0xNjUsZCs9JzxkaXYgY2xhc3M9XCJkYXRhLXBhZ2UtY2FyZC1idXR0b24gbWRsLWNhcmQgbWRsLXNoYWRvdy0tMmRwXCI+JyxsPTE2NixkKz0nPGRpdiBjbGFzcz1cIm1kbC1jYXJkX190aXRsZVwiPicsbD0xNjcsZCs9JzxsYWJlbCBjbGFzcz1cIm1kbC1idXR0b24gbWRsLWpzLWJ1dHRvbiBtZGwtYnV0dG9uLS1yYWlzZWQgbWRsLWNvbG9yLS1ibHVlLWdyZXktOTAwIG1kbC1jb2xvci10ZXh0LS13aGl0ZSBtZGwtanMtcmlwcGxlLWVmZmVjdCBjc3Z1cGxvYWQtYnRuXCIgZm9yPVwiY3N2dXBsb2FkQnRuXCI+JyxsPTE2OCxkKz1cIkltcG9ydCBDU1Y8L2xhYmVsPlwiLGw9MTY5LGQrPSc8aW5wdXQgY2xhc3M9XCJmaWxlQnRuXCIgdHlwZT1cImZpbGVcIiBhY2NlcHQ9XCIuY3N2LC50eHQsLnRzdlwiIGRhdGEtaG9vaz1cImNzdi11cGxvYWQtaW5wdXRcIiBpZD1cImNzdnVwbG9hZEJ0blwiLz48L2Rpdj4nLGw9MTcwLGQrPSc8ZGl2IGNsYXNzPVwibWRsLWNhcmRfX3N1cHBvcnRpbmctdGV4dFwiPicsbD0xNzEsZCs9XCJJbXBvcnQgYSBDU1YgZmlsZSBmcm9tIHlvdXIgY29tcHV0ZXIuPC9kaXY+XCIsbD0xNzIsZCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fbWVudVwiPicsbD0xNzMsZCs9JzxidXR0b24gY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1idXR0b24tLWljb24gbWRsLWpzLWJ1dHRvbiBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGRhdGEtaG9vaz1cIkNTVi1zZXR0aW5ncy1idXR0b25cIiBpZD1cImNzdi1zZXR0aW5ncy1idXR0b25cIj4nLGw9MTc0LGQrPSc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+JyxsPTE3NCxkKz1cInNldHRpbmdzPC9pPjwvYnV0dG9uPjwvZGl2PjwvZGl2PlwiLGw9MTc2LGQrPSc8ZGl2IGNsYXNzPVwiZGF0YS1wYWdlLWNhcmQtYnV0dG9uIG1kbC1jYXJkIG1kbC1zaGFkb3ctLTJkcFwiPicsbD0xNzcsZCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fdGl0bGVcIj4nLGw9MTc4LGQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWJ1dHRvbi0tcmFpc2VkIG1kbC1jb2xvci0tYmx1ZS1ncmV5LTkwMCBtZGwtY29sb3ItdGV4dC0td2hpdGUgbWRsLWpzLXJpcHBsZS1lZmZlY3QgZGF0YWRvd25sb2FkLWJ0blwiIGZvcj1cImRhdGFEb3dubG9hZEJ0blwiPicsbD0xNzksZCs9XCJEb3dubG9hZCBkYXRhPC9sYWJlbD5cIixsPTE4MCxkKz0nPGEgY2xhc3M9XCJmaWxlQnRuXCIgZGF0YS1ob29rPVwiZGF0YS1kb3dubG9hZFwiIGlkPVwiZGF0YURvd25sb2FkQnRuXCIgZG93bmxvYWQ9XCJkb3dubG9hZFwiPjwvYT48L2Rpdj4nLGw9MTgxLGQrPSc8ZGl2IGNsYXNzPVwibWRsLWNhcmRfX3N1cHBvcnRpbmctdGV4dFwiPicsbD0xODIsZCs9XCJEb3dubG9hZCB0aGUgY3VycmVudCBkYXRhIHRvIHlvdXIgY29tcHV0ZXIuPC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+XCIsbD0xODQsZCs9JzxkaXYgZGF0YS1ob29rPVwiZGF0YXNldC1pdGVtc1wiIHN0eWxlPVwid2lkdGg6IDEwMCVcIj48L2Rpdj48L2hlYWRlcj4nLGw9MTg3LGQrPSc8aGVhZGVyIGNsYXNzPVwibWRsLWxheW91dF9faGVhZGVyIG1kbC1jb2xvci0tZ3JleS0xMDAgbWRsLWNvbG9yLXRleHQtLWdyZXktNjAwXCI+JyxsPTE4OCxkKz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXRfX2hlYWRlci1yb3dcIj4nLGw9MTg5LGQrPSc8c3BhbiBjbGFzcz1cIm1kbC1sYXlvdXQtdGl0bGVcIiBzdHlsZT1cInBhZGRpbmc6IDA7IHRleHQtYWxpZ246IGNlbnRlcjtcIj4nLGw9MTg5LGQrPVwiU2Vzc2lvbnM8L3NwYW4+PC9kaXY+XCIsbD0xOTEsZCs9JzxkaXYgZGF0YS1ob29rPVwiYWRkLXNlc3Npb25zLWRpdlwiIHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XCI+JyxsPTE5MixkKz0nPGRpdiBjbGFzcz1cImRhdGEtcGFnZS1jYXJkLWJ1dHRvbiBtZGwtY2FyZCBtZGwtc2hhZG93LS0yZHBcIj4nLGw9MTkzLGQrPSc8ZGl2IGNsYXNzPVwibWRsLWNhcmRfX3RpdGxlXCI+JyxsPTE5NCxkKz0nPGEgY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWJ1dHRvbi0tcmFpc2VkIG1kbC1jb2xvci0tYmx1ZS1ncmV5LTkwMCBtZGwtY29sb3ItdGV4dC0td2hpdGUgbWRsLWpzLXJpcHBsZS1lZmZlY3Qgc2Vzc2lvbmRvd25sb2FkLWJ0blwiIGRhdGEtaG9vaz1cInNlc3Npb24tZG93bmxvYWRcIiBkb3dubG9hZD1cImRvd25sb2FkXCI+JyxsPTE5NSxkKz1cIkV4cG9ydCBzZXNzaW9uPC9hPjwvZGl2PlwiLGw9MTk2LGQrPSc8ZGl2IGNsYXNzPVwibWRsLWNhcmRfX3N1cHBvcnRpbmctdGV4dFwiPicsbD0xOTcsZCs9XCJTYXZlIHRoZSBjdXJyZW50IGRhc2hib2FyZCB0byB5b3VyIGNvbXB1dGVyLjwvZGl2PjwvZGl2PlwiLGw9MTk5LGQrPSc8ZGl2IGNsYXNzPVwiZGF0YS1wYWdlLWNhcmQtYnV0dG9uIG1kbC1jYXJkIG1kbC1zaGFkb3ctLTJkcFwiPicsbD0yMDAsZCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fdGl0bGVcIj4nLGw9MjAxLGQrPSc8bGFiZWwgY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1qcy1idXR0b24gbWRsLWJ1dHRvbi0tcmFpc2VkIG1kbC1jb2xvci0tYmx1ZS1ncmV5LTkwMCBtZGwtY29sb3ItdGV4dC0td2hpdGUgbWRsLWpzLXJpcHBsZS1lZmZlY3Qgc2Vzc2lvbnVwbG9hZC1idG5cIiBmb3I9XCJzZXNzaW9udXBsb2FkQnRuXCIgZGF0YS1ob29rPVwic2Vzc2lvbi11cGxvYWRcIj4nLGw9MjAyLGQrPVwiSW1wb3J0IHNlc3Npb248L2xhYmVsPlwiLGw9MjAzLGQrPSc8aW5wdXQgY2xhc3M9XCJmaWxlQnRuXCIgdHlwZT1cImZpbGVcIiBhY2NlcHQ9XCIuanNvblwiIGRhdGEtaG9vaz1cInNlc3Npb24tdXBsb2FkLWlucHV0XCIgaWQ9XCJzZXNzaW9udXBsb2FkQnRuXCIvPjwvZGl2PicsbD0yMDQsZCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fc3VwcG9ydGluZy10ZXh0XCI+JyxsPTIwNSxkKz1cIkltcG9ydCBhIHNhdmVkIGRhc2hib2FyZCBmcm9tIHlvdXIgY29tcHV0ZXIuPC9kaXY+PC9kaXY+XCIsbD0yMDcsZCs9JzxkaXYgY2xhc3M9XCJkYXRhLXBhZ2UtY2FyZC1idXR0b24gbWRsLWNhcmQgbWRsLXNoYWRvdy0tMmRwXCI+JyxsPTIwOCxkKz0nPGRpdiBjbGFzcz1cIm1kbC1jYXJkX190aXRsZVwiPicsbD0yMDksZCs9JzxhIGNsYXNzPVwibWRsLWJ1dHRvbiBtZGwtanMtYnV0dG9uIG1kbC1idXR0b24tLXJhaXNlZCBtZGwtY29sb3ItLWJsdWUtZ3JleS05MDAgbWRsLWNvbG9yLXRleHQtLXdoaXRlIG1kbC1qcy1yaXBwbGUtZWZmZWN0IHNlc3Npb25jbG91ZGRvd24tYnRuXCIgZGF0YS1ob29rPVwic2Vzc2lvbi1jbG91ZC1kb3dubG9hZFwiIGNsb3VkLWRvd25sb2FkPVwiY2xvdWQtZG93bmxvYWRcIj4nLGw9MjEwLGQrPVwiU2Vzc2lvbiBieSBVUkw8L2E+PC9kaXY+XCIsbD0yMTEsZCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fc3VwcG9ydGluZy10ZXh0XCI+JyxsPTIxMixkKz1cIkltcG9ydCBhIGRhc2hib2FyZCB1c2luZyBVUkwuPC9kaXY+PC9kaXY+PC9kaXY+XCIsbD0yMTQsZCs9JzxkaXYgZGF0YS1ob29rPVwic2Vzc2lvbi1pdGVtc1wiIHN0eWxlPVwid2lkdGg6IDEwMCVcIj48L2Rpdj48L2hlYWRlcj48L2Rpdj48L21haW4+PC9kaXY+J31jYXRjaChvKXtwdWcucmV0aHJvdyhvLGEsbCl9cmV0dXJuIGR9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJkYXRhc2V0c1wiXVtcInNlc3Npb25cIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZShhKXt2YXIgZCxzLHQ9XCJcIjt0cnl7cz0xLHQrPSc8ZGl2IGNsYXNzPVwibWRsLWNhcmQgbWRsLXNoYWRvdy0tMmRwXCIgZGF0YS1ob29rPVwic2Vzc2lvblwiIHN0eWxlPVwibWluLWhlaWdodDogaW5oZXJpdFwiPicscz0yLHQrPSc8ZGl2IGNsYXNzPVwibWRsLWNhcmRfX3RpdGxlXCI+JyxzPTMsdCs9JzxoMiBjbGFzcz1cIm1kbC1jYXJkX190aXRsZS10ZXh0XCIgZGF0YS1ob29rPVwiZGF0ZVwiPjwvaDI+PC9kaXY+JyxzPTUsdCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fc3VwcG9ydGluZy10ZXh0XCIgZGF0YS1ob29rPVwiZGVzY3JpcHRpb25cIj48L2Rpdj4nLHM9Nyx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1jYXJkX19hY3Rpb25zIG1kbC1jYXJkLS1ib3JkZXJcIj4nLHM9OCx0Kz0nPGEgY2xhc3M9XCJtZGwtYnV0dG9uIG1kbC1idXR0b24tLWNvbG9yZWQgbWRsLWpzLWJ1dHRvbiBtZGwtanMtcmlwcGxlLWVmZmVjdFwiIGRhdGEtaG9vaz1cImRlbGV0ZVwiPicscz05LHQrPVwiRGVsZXRlPC9hPjwvZGl2PlwiLHM9MTEsdCs9JzxkaXYgY2xhc3M9XCJtZGwtY2FyZF9fbWVudVwiPicscz0xMix0Kz0nPHNwYW4gY2xhc3M9XCJtZGwtc3Bpbm5lciBtZGwtanMtc3Bpbm5lciBpcy1hY3RpdmVcIiBkYXRhLWhvb2s9XCJjYnNwaW5uZXJcIj48L3NwYW4+JyxzPTEzLHQrPSc8c3BhbiBkYXRhLWhvb2s9XCJjYnRvZ2dsZVwiPicscz0xNCx0Kz0nPGxhYmVsIGNsYXNzPVwibWRsLXN3aXRjaCBtZGwtanMtc3dpdGNoIG1kbC1qcy1yaXBwbGUtZWZmZWN0XCIgZGF0YS1ob29rPVwiY2JsYWJlbFwiIGZvcj1cIlwiPicscz0xNSx0Kz0nPGlucHV0IGNsYXNzPVwibWRsLXN3aXRjaF9faW5wdXRcIiBkYXRhLWhvb2s9XCJjYlwiIHR5cGU9XCJjaGVja2JveFwiIGlkPVwiXCIvPjwvbGFiZWw+JyxzPTE2LHQrPSc8c3BhbiBjbGFzcz1cIm1kbC1zd2l0Y2hfX2xhYmVsXCI+PC9zcGFuPjwvc3Bhbj48L2Rpdj48L2Rpdj4nfWNhdGNoKGwpe3B1Zy5yZXRocm93KGwsZCxzKX1yZXR1cm4gdH07XHJcblxyXG4gICAgcHVnbGF0aXplcltcImRhdGFzZXRzXCJdW1wic2Vzc2lvbkNvbGxlY3Rpb25cIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZSh0KXt2YXIgZSxhLHI9XCJcIjt0cnl7YT0xLHIrPSc8ZGl2IGRhdGEtaG9vaz1cInNlc3Npb24tY29sbGVjdGlvbi1pdGVtc1wiIHN0eWxlPVwiZGlzcGxheTogZmxleDsgZmxleC13cmFwOiB3cmFwO1wiPjwvZGl2Pid9Y2F0Y2goaSl7cHVnLnJldGhyb3coaSxlLGEpfXJldHVybiByfTtcclxuXHJcbiAgICBwdWdsYXRpemVyW1wiaGVhZFwiXSA9IGZ1bmN0aW9uIHRlbXBsYXRlKGUpe3ZhciB0LGEsbj1cIlwiO3RyeXthPTEsbis9XCI8aGVhZD5cIixhPTIsbis9JzxtZXRhIGNoYXJzZXQ9XCJ1dGYtOFwiLz4nLGE9MyxuKz0nPG1ldGEgaHR0cC1lcXVpdj1cIlgtVUEtQ29tcGF0aWJsZVwiIGNvbnRlbnQ9XCJJRT1lZGdlXCIvPicsYT00LG4rPSc8bWV0YSBuYW1lPVwiZGVzY3JpcHRpb25cIiBjb250ZW50PVwiU3BvdCAtIGV4dGVuc2libGUgZmFjZXQgYnJvd3NlclwiLz4nLGE9NSxuKz0nPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAsIG1pbmltdW0tc2NhbGU9MS4wXCIvPicsYT02LG4rPVwiPHRpdGxlPlwiLGE9NyxuKz1cIlNwb3Q8L3RpdGxlPlwiLGE9OSxuKz1cIjwhLS0gQWRkIHRvIGhvbWVzY3JlZW4gZm9yIENocm9tZSBvbiBBbmRyb2lkIC0tPlwiLGE9MTAsbis9JzxtZXRhIG5hbWU9XCJtb2JpbGUtd2ViLWFwcC1jYXBhYmxlXCIgY29udGVudD1cInllc1wiLz4nLGE9MTMsbis9XCI8IS0tIEFkZCB0byBob21lc2NyZWVuIGZvciBTYWZhcmkgb24gaU9TIC0tPlwiLGE9MTQsbis9JzxtZXRhIG5hbWU9XCJhcHBsZS1tb2JpbGUtd2ViLWFwcC1jYXBhYmxlXCIgY29udGVudD1cInllc1wiLz4nLGE9MTUsbis9JzxtZXRhIG5hbWU9XCJhcHBsZS1tb2JpbGUtd2ViLWFwcC1zdGF0dXMtYmFyLXN0eWxlXCIgY29udGVudD1cImJsYWNrXCIvPicsYT0xNixuKz0nPG1ldGEgbmFtZT1cImFwcGxlLW1vYmlsZS13ZWItYXBwLXRpdGxlXCIgY29udGVudD1cIlNwb3RcIi8+JyxhPTE5LG4rPVwiPCEtLSBUaWxlIGljb24gZm9yIFdpbjggKDE0NHgxNDQgKyB0aWxlIGNvbG9yKSAtLT5cIixhPTIxLG4rPSc8bWV0YSBuYW1lPVwibXNhcHBsaWNhdGlvbi1UaWxlQ29sb3JcIiBjb250ZW50PVwiIzMzNzJERlwiLz48L2hlYWQ+J31jYXRjaChvKXtwdWcucmV0aHJvdyhvLHQsYSl9cmV0dXJuIG59O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJoZWxwXCJdID0ge31cclxuICAgIHB1Z2xhdGl6ZXJbXCJoZWxwXCJdW1wiYW5hbHl6ZVwiXSA9IGZ1bmN0aW9uIHRlbXBsYXRlKGEpe3ZhciBlLHQscD1cIlwiO3RyeXt0PTEscCs9JzxkaXYgZGF0YS1ob29rPVwiYW5hbHl6ZS1oZWxwXCIgaWQ9XCJhbmFseXplLWhlbHBcIiBkYXRhLXBvc2l0aW9uPVwiYm90dG9tXCIgZGF0YS1zdGVwPVwiMVwiPicsdD0yLHArPVwiPGg0PlwiLHQ9MixwKz1cIkFuYWx5emUgcGFnZSBIZWxwPC9oND5cIix0PTMscCs9XCI8cD48L3A+XCIsdD00LHArPVwiVGV4dCBoZXJlPGJyIC8+XCIsdD01LHArPVwiXFxuXCIsdD01LHArPVwiPGJyIC8+PC9kaXY+XCJ9Y2F0Y2gocil7cHVnLnJldGhyb3cocixlLHQpfXJldHVybiBwfTtcclxuXHJcbiAgICBwdWdsYXRpemVyW1wiaGVscFwiXVtcIm1lbnVCdXR0b25zXCJdID0gZnVuY3Rpb24gdGVtcGxhdGUoZSl7dmFyIHQsYSxvPVwiXCI7dHJ5e2E9MSxvKz0nPGRpdiBkYXRhLWhvb2s9XCJ3ZWxjb21lLWluZm9cIiBpZD1cIndlbGNvbWUtaW5mb1wiIGRhdGEtcG9zaXRpb249XCJib3R0b21cIiBkYXRhLXN0ZXA9XCIxXCI+JyxhPTIsbys9XCI8cD48L3A+XCIsYT0zLG8rPVwiPGg2PlwiLGE9MyxvKz1cIllvdSB3aWxsIGZpbmQgdGhlIGZvbGxvd2luZyBidXR0b25zIG9uIHRoZSBsZWZ0IG1lbnU6PC9oNj5cIixhPTQsbys9XCI8bHU+XCIsYT01LG8rPVwiPGxpPlwiLGE9NixvKz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiIHJvbGU9XCJwcmVzZW50YXRpb25cIj4nLGE9NixvKz1cIm1lbnU8L2k+XCIsYT03LG8rPVwiYnV0dG9uIGNvbnRyb2xzIHRoZSBtZW51IGRyYXdlci48L2xpPlwiLGE9OCxvKz1cIjxsaT5cIixhPTksbys9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIiByb2xlPVwicHJlc2VudGF0aW9uXCI+JyxhPTksbys9XCJob21lPC9pPlwiLGE9MTAsbys9XCJidXR0b24gb3BlbnMgdGhlIGhvbWVwYWdlLiBUaGlzIGlzIHdoZXJlIHlvdSBhcmUgYXQgbm93LjwvbGk+XCIsYT0xMSxvKz1cIjxsaT5cIixhPTEyLG8rPSc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCIgcm9sZT1cInByZXNlbnRhdGlvblwiPicsYT0xMixvKz1cInN0b3JhZ2U8L2k+XCIsYT0xMyxvKz1cImJ1dHRvbiB0YWtlcyB5b3UgdG8gRGF0YXNldHMgcGFnZS4gSW4gRGF0YXNldHMgcGFnZSwgeW91IGNhbiB1cGxvYWQgeW91ciBkYXRhc2V0IG9yIHVzZSBleGlzdGluZyBkYXRhc2V0cy4gWW91IGNhbiBhbHNvIGNvbmZpZ3VyZSB5b3VyIGRhdGFzZXRzLjwvbGk+XCIsYT0xNCxvKz1cIjxsaT5cIixhPTE1LG8rPSc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCIgcm9sZT1cInByZXNlbnRhdGlvblwiPicsYT0xNSxvKz1cImluc2VydF9jaGFydDwvaT5cIixhPTE2LG8rPVwiYnV0dG9uIHRha2VzIHlvdSB0byBBbmFseXplIHBhZ2UuIEluIEFuYWx5emUgcGFnZSwgeW91IGNhbiBjcmVhdGUgeW91ciBkYXNoYm9hcmQgaW4gYSBmZXcgY2xpY2tzIGJ5IGNyZWF0aW5nIG5ldyBjaGFydHMuPC9saT5cIixhPTE3LG8rPVwiPGxpPlwiLGE9MTgsbys9JzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIiByb2xlPVwicHJlc2VudGF0aW9uXCI+JyxhPTE4LG8rPVwic2hhcmU8L2k+XCIsYT0xOSxvKz1cImJ1dHRvbiB0YWtlcyB5b3UgdG8gU2hhcmUgcGFnZS4gSW4gc2hhcmUgcGFnZSwgeW91IGNhbiBzaGFyZSB5b3VyIGN1cnJlbnQgc2Vzc2lvbiBvciBsb2FkIHRoZSBzZXNzaW9uIHdoaWNoIGlzIHNoYXJlZCB3aXRoIHlvdS48L2xpPlwiLGE9MjAsbys9XCI8bGk+XCIsYT0yMSxvKz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiIHJvbGU9XCJwcmVzZW50YXRpb25cIj4nLGE9MjEsbys9XCJoZWxwPC9pPlwiLGE9MjIsbys9XCJidXR0b24gZ3VpZGVzIHlvdSBhYm91dCB0aGUgdXNlciBpbnRlcmZhY2UuPC9saT48L2x1PjwvZGl2PlwifWNhdGNoKGkpe3B1Zy5yZXRocm93KGksdCxhKX1yZXR1cm4gb307XHJcblxyXG4gICAgcHVnbGF0aXplcltcImhlbHBcIl1bXCJ3ZWxjb21lXCJdID0gZnVuY3Rpb24gdGVtcGxhdGUoZSl7dmFyIHQsYSxvPVwiXCI7dHJ5e2E9MSxvKz0nPGRpdiBkYXRhLWhvb2s9XCJ3ZWxjb21lLWluZm9cIiBpZD1cIndlbGNvbWUtaW5mb1wiIGRhdGEtcG9zaXRpb249XCJib3R0b21cIiBkYXRhLXN0ZXA9XCIxXCI+JyxhPTIsbys9XCI8aDQ+XCIsYT0yLG8rPVwiV2VsY29tZSB0byBTUE9UITwvaDQ+XCIsYT0zLG8rPVwiPHA+PC9wPlwiLGE9NCxvKz0nVGhpcyBzb2Z0d2FyZSBpcyBiZWluZyBkZXZlbG9wZWQgYnkgdGhlICA8YSBocmVmPVwiaHR0cHM6Ly93d3cuZXNjaWVuY2VjZW50ZXIubmxcIiB0YXJnZXQ9XCJfYmxhbmtcIj5OZXRoZXJsYW5kcyBlU2NpZW5jZSBDZW50ZXI8L2E+LjxiciAvPicsYT01LG8rPVwiXFxuXCIsYT01LG8rPVwiPGJyIC8+XCIsYT02LG8rPVwiXFxuXCIsYT02LG8rPSdTUE9UIGlzIGEgZnJlZSBhbmQgYW4gb3BlbiBzb3VyY2Ugc29mdHdhcmUuIFRoZSBsaWNlbnNlIG9mIHRoZSBTUE9UIGlzICA8YSBocmVmPVwiaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXCIgdGFyZ2V0PVwiX2JsYW5rXCI+QXBhY2hlIDIuMDwvYT4uPGJyIC8+JyxhPTcsbys9XCJcXG5cIixhPTcsbys9XCI8YnIgLz5cIixhPTgsbys9XCJcXG5cIixhPTgsbys9J0ZvciB0aGUgb25saW5lIHR1dG9yaWFsIG9mIFNQT1QsIHBsZWFzZSBjaGVjayA8YSBocmVmPVwiaHR0cHM6Ly9ubGVzYy5naXRodWIuaW8vc3BvdC10dXRvcmlhbC90dXRvcmlhbFwiIHRhcmdldD1cIl9ibGFua1wiPnRoaXMgbGluazwvYT4uPGJyIC8+JyxhPTksbys9XCJcXG5cIixhPTksbys9XCI8YnIgLz5cIixhPTEwLG8rPVwiXFxuXCIsYT0xMCxvKz1cIjxiciAvPlwiLGE9MTEsbys9XCJcXG5cIixhPTExLG8rPSdUaGUgZGVza3RvcCB2ZXJzaW9uIG9mIFNQT1QgY2FuIGJlIGRvd25sb2FkZWQgZnJvbSA8YSBocmVmPVwiaHR0cHM6Ly9naXRodWIuY29tL05MZVNDL3Nwb3QtZGVza3RvcC1hcHAvcmVsZWFzZXNcIiB0YXJnZXQ9XCJfYmxhbmtcIj50aGlzIGxpbms8L2E+LjxiciAvPicsYT0xMixvKz1cIlxcblwiLGE9MTIsbys9XCI8YnI+XCIsYT0xMyxvKz1cIlxcblwiLGE9MTMsbys9XCJZb3UgY2FuIGNsaWNrIHRoZSBidXR0b24gYmVsb3cgdG8gc3RhcnQgYSBkZW1vIHNlc3Npb24uIFRoZSBkZW1vIHNlc3Npb24gaGFzIDxiPkthZ2dsZSBUaXRhbmljIFN1cnZpdmFsPC9iPiBkYXRhc2V0LlwiLGE9MTUsbys9XCJcXG5cIixhPTE1LG8rPVwiPGJyPjxicj4gSGFwcHkgU1BPVFRJTkchPGJyPjwvZGl2PlwifWNhdGNoKG4pe3B1Zy5yZXRocm93KG4sdCxhKX1yZXR1cm4gb307XHJcblxyXG4gICAgcHVnbGF0aXplcltcImhvbWVcIl0gPSBmdW5jdGlvbiB0ZW1wbGF0ZShzKXt2YXIgYSxsLGU9XCJcIjt0cnl7bD0xLGUrPSc8bWFpbiBjbGFzcz1cIm1kbC1sYXlvdXRfX2NvbnRlbnQgaG9tZS1jb250ZW50IGJnc3BvdEltYWdlXCI+JyxsPTIsZSs9JzxkaXYgY2xhc3M9XCJjb250ZW50LWdyaWQgbWRsLWdyaWQgbWRsLWNlbGwtLW1pZGRsZVwiPicsbD00LGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTEyLWNvbCBtZGwtY2VsbC0tMC1vZmZzZXQgbWRsLXNoYWRvdy0tMmRwIHNwb3QtY2VsbCBzcG90LXRyYW5zIHNwb3QtY29sb3I0XCI+JyxsPTYsZSs9JzxzcGFuIGNsYXNzPVwiY2FyZFRpdGxlVGV4dCBtYXRlcmlhbC1pY29ucyBtZW51SWNvblwiPicsbD02LGUrPVwiZXhwbG9yZTwvc3Bhbj5cIixsPTcsZSs9JzxzcGFuIGNsYXNzPVwiY2FyZFRpdGxlVGV4dFwiPicsbD03LGUrPVwiIFNQT1Q6IGludGVyYWN0aXZlLCBmYXN0IGZhY2V0IGJyb3dzZXI8L3NwYW4+XCIsbD04LGUrPVwiPHVsPlwiLGw9OSxlKz1cIjxsaT5cIixsPTEwLGUrPSc8cCBjbGFzcz1cImNhcmRUZXh0XCI+JyxsPTEwLGUrPVwiU1BPVCBpcyBhbiBpbnRlcmFjdGl2ZSwgZmFzdCBkYXRhIHZpc3VhbGl6YXRpb24gdG9vbC4gSXQgd2FzIHByaW1hcmlseSBkZXNpZ25lZCBhcyBkYXRhIGV4cGxvcmF0aW9uIGFuZCBhbmFseXNpcyB0b29sIGZvciBjb21wbGV4IG11bHRpLWRpbWVuc2lvbmFsIGRhdGFzZXRzLiBVc2VycyBjYW4gdmlzdWFsaXplIHRoZSBkYXRhIG9ubHkgd2l0aCBhIGZldyBjbGlja3MuIFNQT1QgY2FuIGJlIHVzZWQgdG8gY29tcGFyZSBkaWZmZXJlbnQgZGF0YXNldHMuIEl0IGlzIGFsc28gcG9zc2libGUgdG8gY29ubmVjdCB0byBhIFBvc3RyZXNxbCBzZXJ2ZXIgdG8gYW5hbHl6ZSBiaWcgZGF0YXNldHMuPC9wPjwvbGk+PC91bD48L2Rpdj5cIixsPTEyLGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTQtY29sIHNwb3QtY2VsbCBzcG90LXRyYW5zIHNwb3QtY29sb3I0XCI+JyxsPTEzLGUrPSc8c3BhbiBjbGFzcz1cImNhcmRUaXRsZVRleHQgbWF0ZXJpYWwtaWNvbnMgbWVudUljb25cIj4nLGw9MTMsZSs9XCJtZXJnZV90eXBlPC9zcGFuPlwiLGw9MTQsZSs9JzxzcGFuIGNsYXNzPVwiY2FyZFRpdGxlVGV4dFwiPicsbD0xNCxlKz1cIkhpZ2hsaWdodHM8L3NwYW4+XCIsbD0xNSxlKz1cIjx1bD5cIixsPTE2LGUrPVwiPGxpPlwiLGw9MTcsZSs9JzxkaXYgY2xhc3M9XCJjYXJkVGV4dFwiPicsbD0xNyxlKz1cIlNwZWNpZmljYWxseSBkZXNpZ25lZCBmb3Igc2NpZW50aWZpYyBkYXRhIHZpc3VhbGl6YXRpb248L2Rpdj48L2xpPlwiLGw9MTgsZSs9XCI8bGk+XCIsbD0xOSxlKz0nPGRpdiBjbGFzcz1cImNhcmRUZXh0XCI+JyxsPTE5LGUrPVwiRnVsbHkgYW5pbWF0ZWQgYW5kIGludGVyYWN0aXZlIGNoYXJ0czwvZGl2PjwvbGk+XCIsbD0yMCxlKz1cIjxsaT5cIixsPTIxLGUrPSc8ZGl2IGNsYXNzPVwiY2FyZFRleHRcIj4nLGw9MjEsZSs9XCJFeHBsb3JhdGlvbiBzZXNzaW9ucyBjYW4gYmUgc2F2ZWQ8L2Rpdj48L2xpPlwiLGw9MjIsZSs9XCI8bGk+XCIsbD0yMyxlKz0nPGRpdiBjbGFzcz1cImNhcmRUZXh0XCI+JyxsPTIzLGUrPVwiRGF0YWJhc2UgY29ubmVjdGlvbiAoUG9zdGdyZXNxbCk8L2Rpdj48L2xpPjwvdWw+PC9kaXY+XCIsbD0yNSxlKz0nPGRpdiBjbGFzcz1cIm1kbC1jZWxsIG1kbC1jZWxsLS00LWNvbCBzcG90LWNlbGwgc3BvdC10cmFucyBzcG90LWNvbG9yNFwiPicsbD0yNixlKz0nPHNwYW4gY2xhc3M9XCJjYXJkVGl0bGVUZXh0IG1hdGVyaWFsLWljb25zIG1lbnVJY29uXCI+JyxsPTI2LGUrPVwiZXh0ZW5zaW9uPC9zcGFuPlwiLGw9MjcsZSs9JzxzcGFuIGNsYXNzPVwiY2FyZFRpdGxlVGV4dFwiPicsbD0yNyxlKz1cIiAgTW9kZXJuIHRvb2xzPC9zcGFuPlwiLGw9MjgsZSs9XCI8dWw+XCIsbD0yOSxlKz1cIjxsaT5cIixsPTMwLGUrPSc8ZGl2IGNsYXNzPVwiY2FyZFRleHRcIj4nLGw9MzAsZSs9XCJWaWV3ZXIgaXMgZnVsbHkgc3RhbmRhbG9uZSAobm8gc2VydmVyIHJlcXVpcmVkKTwvZGl2PjwvbGk+XCIsbD0zMSxlKz1cIjxsaT5cIixsPTMyLGUrPSc8ZGl2IGNsYXNzPVwiY2FyZFRleHRcIj4nLGw9MzIsZSs9XCJSZXNwb25zaXZlIGludGVyZmFjZTogbWF0ZXJpYWwgZGVzaWduIGxpdGU8L2Rpdj48L2xpPlwiLGw9MzMsZSs9XCI8bGk+XCIsbD0zNCxlKz0nPGRpdiBjbGFzcz1cImNhcmRUZXh0XCI+JyxsPTM0LGUrPVwiRmFzdCBmaWx0ZXJpbmcgKH4xTSBkYXRhIHBvaW50cyBpbiB+MzBtcyk8L2Rpdj48L2xpPlwiLGw9MzUsZSs9XCI8bGk+XCIsbD0zNixlKz0nPGRpdiBjbGFzcz1cImNhcmRUZXh0XCI+JyxsPTM2LGUrPVwiQ3Jvc3MgcGxhdGZvcm0gKGRlc2t0b3AsIG1vYmlsZSBhbmQgdGFibGV0KTwvZGl2PjwvbGk+PC91bD48L2Rpdj5cIixsPTM4LGUrPSc8ZGl2IGNsYXNzPVwibWRsLWNlbGwgbWRsLWNlbGwtLTQtY29sIG1kbC1zaGFkb3ctLTJkcCBzcG90LWNlbGwgc3BvdC10cmFucyBzcG90LWNvbG9yNFwiPicsbD0zOSxlKz0nPHNwYW4gY2xhc3M9XCJjYXJkVGl0bGVUZXh0IG1hdGVyaWFsLWljb25zIG1lbnVJY29uXCI+JyxsPTM5LGUrPVwibG9ja19vcGVuPC9zcGFuPlwiLGw9NDAsZSs9JzxzcGFuIGNsYXNzPVwiY2FyZFRpdGxlVGV4dFwiPicsbD00MCxlKz1cIiAgT3BlbiBTb3VyY2U8L3NwYW4+XCIsbD00MSxlKz1cIjx1bD5cIixsPTQyLGUrPVwiPGxpPlwiLGw9NDMsZSs9JzxkaXYgY2xhc3M9XCJjYXJkVGV4dFwiPicsbD00MyxlKz1cIlBlcm1pc3NpdmUgT3BlbiBzb3VyY2UgTGljZW5jZSAoQXBhY2hlIDIuMCk8L2Rpdj48L2xpPlwiLGw9NDQsZSs9XCI8bGk+XCIsbD00NSxlKz0nPGRpdiBjbGFzcz1cImNhcmRUZXh0XCI+JyxsPTQ1LGUrPVwiQ29udGludW91cyBJbnRlZ3JhdGlvbjwvZGl2PjwvbGk+XCIsbD00NixlKz1cIjxsaT5cIixsPTQ3LGUrPSc8ZGl2IGNsYXNzPVwiY2FyZFRleHRcIj4nLGw9NDcsZSs9XCJEb2N1bWVudGVkIChqc2RvYykgYW5kIHRlc3RlZCAoamFzbWluZSk8L2Rpdj48L2xpPlwiLGw9NDgsZSs9XCI8bGk+XCIsbD00OSxlKz0nPGRpdiBjbGFzcz1cImNhcmRUZXh0XCI+JyxsPTQ5LGUrPVwiR2VuZXJpYyB0b29sIHRvIGJlIHVzZWZ1bCBpbiBhbnkgc2NpZW50aWZpYyBwcm9qZWN0PC9kaXY+PC9saT48L3VsPjwvZGl2PjwvZGl2PlwiLGw9NTEsZSs9JzxkaXYgY2xhc3M9XCJtZGwtbGF5b3V0LXNwYWNlclwiPjwvZGl2PicsbD01MyxlKz0nPGZvb3RlciBjbGFzcz1cIm1kbC1tZWdhLWZvb3RlciBzcG90LWNlbGwgc3BvdC10cmFucyBzcG90LWNvbG9yNFwiPicsbD01NCxlKz0nPGRpdiBjbGFzcz1cInNwb3QtZm9vdGVyXCI+JyxsPTU4LGUrPSc8ZGl2IGNsYXNzPVwic3BvdC1mb290ZXItaXRlbVwiPicsbD01OSxlKz0nPGEgY2xhc3M9XCJzcG90bGlua1wiIGRhdGEtaG9vaz1cImRlbW8tc2Vzc2lvblwiIGhyZWY9XCJcIj4nLGw9NjAsZSs9JzxzcGFuIGNsYXNzPVwiZm9vdGVySW1nIG1hdGVyaWFsLWljb25zIG1lbnVJY29uXCI+JyxsPTYwLGUrPVwib25kZW1hbmRfdmlkZW88L3NwYW4+XCIsbD02MSxlKz0nPHNwYW4gY2xhc3M9XCJmb290ZXJJdGVtXCI+JyxsPTYxLGUrPVwiRGVtbzwvc3Bhbj48L2E+PC9kaXY+XCIsbD02MixlKz0nPGRpdiBjbGFzcz1cInNwb3QtZm9vdGVyLWl0ZW1cIj4nLGw9NjMsZSs9JzxhIGNsYXNzPVwic3BvdGxpbmtcIiBkYXRhLWhvb2s9XCJ0dXRvcmlhbHBhZ2VcIiBocmVmPVwiaHR0cHM6Ly9ubGVzYy5naXRodWIuaW8vc3BvdC10dXRvcmlhbC90dXRvcmlhbFwiIHRhcmdldD1cIl9ibGFua1wiPicsbD02NCxlKz0nPHNwYW4gY2xhc3M9XCJmb290ZXJJbWcgbWF0ZXJpYWwtaWNvbnMgbWVudUljb25cIj4nLGw9NjQsZSs9XCJsaW5rPC9zcGFuPlwiLGw9NjUsZSs9JzxzcGFuIGNsYXNzPVwiZm9vdGVySXRlbVwiPicsbD02NSxlKz1cIlR1dG9yaWFsPC9zcGFuPjwvYT48L2Rpdj5cIixsPTY2LGUrPSc8ZGl2IGNsYXNzPVwic3BvdC1mb290ZXItaXRlbVwiPicsbD02NyxlKz0nPGEgY2xhc3M9XCJzcG90bGlua1wiIGRhdGEtaG9vaz1cImdpdGh1YnBhZ2VcIiBocmVmPVwiaHR0cHM6Ly9naXRodWIuY29tL05MZVNDL3Nwb3RcIiB0YXJnZXQ9XCJfYmxhbmtcIj4nLGw9NjgsZSs9JzxzcGFuIGNsYXNzPVwiZm9vdGVySW1nIG1hdGVyaWFsLWljb25zIG1lbnVJY29uXCI+JyxsPTY4LGUrPVwibGluazwvc3Bhbj5cIixsPTY5LGUrPSc8c3BhbiBjbGFzcz1cImZvb3Rlckl0ZW1cIj4nLGw9NjksZSs9XCJQcm9qZWN0PC9zcGFuPjwvYT48L2Rpdj48L2Rpdj5cIixsPTcwLGUrPSc8ZGl2IGNsYXNzPVwic3BvdC1mb290ZXJcIj4nLGw9NzEsZSs9JzxzcGFuIGNsYXNzPVwidmVyc2lvblRleHRcIj4nLGw9NzEsZSs9XCJWZXJzaW9uIDAuMi4wPC9zcGFuPjwvZGl2PjwvZm9vdGVyPjwvbWFpbj5cIn1jYXRjaCh0KXtwdWcucmV0aHJvdyh0LGEsbCl9cmV0dXJuIGV9O1xyXG5cclxuICAgIHB1Z2xhdGl6ZXJbXCJtYWluXCJdID0gZnVuY3Rpb24gdGVtcGxhdGUoYSl7dmFyIGwscyx0PVwiXCI7dHJ5e3M9MSx0Kz1cIjxib2R5PlwiLHM9Mix0Kz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQgbWRsLWpzLWxheW91dFwiIGRhdGEtaG9vaz1cInRlc3RcIj4nLHM9NCx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXRfX2hlYWRlci1yb3cgbWRsLWNvbG9yLS1ibHVlLWdyZXktOTAwXCI+JyxzPTUsdCs9XCI8IS0tIFRpdGxlLS0+XCIscz02LHQrPSc8c3BhbiBjbGFzcz1cIm1kbC1sYXlvdXQtdGl0bGUgbWRsLWxheW91dC0tbGFyZ2Utc2NyZWVuLW9ubHlcIj4nLHM9Nyx0Kz0nPGEgZGF0YS1ob29rPVwibmxlc2NwYWdlXCIgaHJlZj1cImh0dHBzOi8vd3d3LmVzY2llbmNlY2VudGVyLm5sXCIgdGFyZ2V0PVwiX2JsYW5rXCI+JyxzPTgsdCs9JzxkaXYgY2xhc3M9XCJkZW1vLWF2YXRhclwiPjwvZGl2PjwvYT48L3NwYW4+JyxzPTksdCs9XCI8IS0tIEFkZCBzcGFjZXIsIHRvIGFsaWduIG5hdmlnYXRpb24gdG8gdGhlIHJpZ2h0LS0+XCIscz0xMCx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQtc3BhY2VyXCI+PC9kaXY+JyxzPTExLHQrPVwiPCEtLSBOYXZpZ2F0aW9uLiBXZSBoaWRlIGl0IGluIHNtYWxsIHNjcmVlbnMuLS0+XCIscz0xMix0Kz0nPG5hdiBjbGFzcz1cIm1kbC1uYXZpZ2F0aW9uIG1kbC1sYXlvdXQtLWxhcmdlLXNjcmVlbi1vbmx5XCI+JyxzPTEzLHQrPSc8YSBjbGFzcz1cIm1kbC1uYXZpZ2F0aW9uX19saW5rXCIgaHJlZj1cIi9ob21lXCI+JyxzPTEzLHQrPVwiSG9tZTwvYT5cIixzPTE0LHQrPSc8YSBjbGFzcz1cIm1kbC1uYXZpZ2F0aW9uX19saW5rXCIgaHJlZj1cIi9kYXRhc2V0c1wiPicscz0xNCx0Kz1cIkRhdGE8L2E+XCIscz0xNSx0Kz0nPGEgY2xhc3M9XCJtZGwtbmF2aWdhdGlvbl9fbGlua1wiIGhyZWY9XCIvYW5hbHl6ZVwiPicscz0xNSx0Kz1cIkFuYWx5c2lzPC9hPlwiLHM9MTYsdCs9JzxhIGNsYXNzPVwibWRsLW5hdmlnYXRpb25fX2xpbmtcIiBocmVmPVwiI1wiIGRhdGEtaG9vaz1cImhlbHAtYnV0dG9uXCIgaWQ9XCJoZWxwLWJ1dHRvblwiPicscz0xNyx0Kz0nPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPicscz0xNyx0Kz1cImhlbHA8L2k+PC9hPjwvbmF2PjwvZGl2PlwiLHM9MjQsdCs9JzxkaXYgY2xhc3M9XCJtZGwtZHJhd2VyIG1kbC1sYXlvdXRfX2RyYXdlciBtZGwtY29sb3ItLWJsdWUtZ3JleS05MDAgbWRsLWxheW91dC0tc21hbGwtc2NyZWVuLW9ubHlcIj4nLHM9MjUsdCs9JzxzcGFuIGNsYXNzPVwibWRsLWxheW91dC10aXRsZVwiPicscz0yNyx0Kz0nPGEgZGF0YS1ob29rPVwibmxlc2NwYWdlXCIgaHJlZj1cImh0dHBzOi8vd3d3LmVzY2llbmNlY2VudGVyLm5sXCIgdGFyZ2V0PVwiX2JsYW5rXCI+JyxzPTI4LHQrPSc8ZGl2IGNsYXNzPVwiZGVtby1hdmF0YXJcIiBzdHlsZT1cIm1hcmdpbi10b3A6IDIwcHg7IG1hcmdpbi1ib3R0b206IDUwcHg7XCI+PC9kaXY+PC9hPjwvc3Bhbj4nLHM9MjksdCs9JzxuYXYgY2xhc3M9XCJtZGwtbmF2aWdhdGlvblwiPicscz0zMCx0Kz0nPGEgY2xhc3M9XCJtZGwtbmF2aWdhdGlvbl9fbGlua1wiIGhyZWY9XCIvaG9tZVwiPicscz0zMCx0Kz1cIkhvbWU8L2E+XCIscz0zMSx0Kz0nPGEgY2xhc3M9XCJtZGwtbmF2aWdhdGlvbl9fbGlua1wiIGhyZWY9XCIvZGF0YXNldHNcIj4nLHM9MzEsdCs9XCJEYXRhPC9hPlwiLHM9MzIsdCs9JzxhIGNsYXNzPVwibWRsLW5hdmlnYXRpb25fX2xpbmtcIiBocmVmPVwiL2FuYWx5emVcIj4nLHM9MzIsdCs9XCJEYXNoYm9hcmQ8L2E+XCIscz0zMyx0Kz0nPGEgY2xhc3M9XCJtZGwtbmF2aWdhdGlvbl9fbGlua1wiIGhyZWY9XCIjXCIgZGF0YS1ob29rPVwiaGVscC1idXR0b25cIiBpZD1cImhlbHAtYnV0dG9uXCI+JyxzPTM0LHQrPSc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+JyxzPTM0LHQrPVwiaGVscDwvaT5cIixzPTM1LHQrPVwiPHNwYW4+XCIscz0zNSx0Kz1cIkhlbHA8L3NwYW4+PC9hPjwvbmF2PlwiLHM9MzcsdCs9JzxkaXYgY2xhc3M9XCJtZGwtZHJhd2VyLXNlcGFyYXRvclwiPjwvZGl2Picscz0zOCx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQtc3BhY2VyXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAyMHB4O1wiPjwvZGl2Picscz00MCx0Kz0nPG5hdiBjbGFzcz1cIm1kbC1uYXZpZ2F0aW9uXCI+JyxzPTQxLHQrPSc8YSBjbGFzcz1cIm1kbC1uYXZpZ2F0aW9uX19saW5rXCIgaHJlZj1cImh0dHBzOi8vbmxlc2MuZ2l0aHViLmlvL3Nwb3QtdHV0b3JpYWwvdHV0b3JpYWxcIj4nLHM9NDEsdCs9XCJUdXRvcmlhbDwvYT5cIixzPTQyLHQrPSc8YSBjbGFzcz1cIm1kbC1uYXZpZ2F0aW9uX19saW5rXCIgaHJlZj1cImh0dHBzOi8vZ2l0aHViLmNvbS9OTGVTQy9zcG90XCI+JyxzPTQyLHQrPVwiR2l0aHViPC9hPjwvbmF2PlwiLHM9NDQsdCs9JzxkaXYgY2xhc3M9XCJtZGwtZHJhd2VyLXNlcGFyYXRvclwiPjwvZGl2Picscz00NSx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1sYXlvdXQtc3BhY2VyXCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAyMHB4O1wiPjwvZGl2Picscz00Nix0Kz0nPHNwYW4gY2xhc3M9XCJ2ZXJzaW9uVGV4dFwiPicscz00Nix0Kz1cIlZlcnNpb24gMC4yLjA8L3NwYW4+PC9kaXY+XCIscz00OSx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1ncmlkXCI+JyxzPTUwLHQrPSc8ZGlhbG9nIGNsYXNzPVwibWRsLWRpYWxvZ1wiIGRhdGEtaG9vaz1cIm1haW4tZGlhbG9nXCIgaWQ9XCJtYWluLWRpYWxvZ1wiIHN0eWxlPVwiYm9yZGVyOiBub25lOyB3aWR0aDogbWluLWNvbnRlbnQ7IGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1wiPicscz01MSx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1kaWFsb2dfX2NvbnRlbnRcIj4nLHM9NTMsdCs9JzxwMiBjbGFzcz1cIm1kbC1wcm9ncmVzcyBtZGwtanMtcHJvZ3Jlc3MgbWRsLXByb2dyZXNzX19pbmRldGVybWluYXRlXCI+PC9wMj48L2Rpdj48L2RpYWxvZz48L2Rpdj4nLHM9NTgsdCs9JzxtYWluIGNsYXNzPVwibWRsLWxheW91dF9fY29udGVudFwiIGRhdGEtaG9vaz1cInBhZ2UtY29udGFpbmVyXCI+PC9tYWluPicscz02MCx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1wcm9ncmVzcyBtZGwtanMtcHJvZ3Jlc3NcIiBpZD1cInByb2dyZXNzLWJhclwiIHN0eWxlPVwid2lkdGg6IDEwMCU7IGhlaWdodDogNSU7IGRpc3BsYXk6IG5vbmVcIj48L2Rpdj4nLHM9NjIsdCs9JzxkaXYgY2xhc3M9XCJtZGwtanMtc25hY2tiYXIgbWRsLXNuYWNrYmFyXCIgaWQ9XCJzbmFjay1iYXJcIiBhcmlhLWxpdmU9XCJhc3NlcnRpdmVcIiBhcmlhLWF0b21pYz1cInRydWVcIiBhcmlhLXJlbGV2YW50PVwidGV4dFwiPicscz02Myx0Kz0nPGRpdiBjbGFzcz1cIm1kbC1zbmFja2Jhcl9fdGV4dFwiPjwvZGl2Picscz02NCx0Kz0nPGJ1dHRvbiBjbGFzcz1cIm1kbC1zbmFja2Jhcl9fYWN0aW9uXCIgdHlwZT1cImJ1dHRvblwiPjwvYnV0dG9uPjwvZGl2PjwvZGl2PjwvYm9keT4nfWNhdGNoKGkpe3B1Zy5yZXRocm93KGksbCxzKX1yZXR1cm4gdH07XHJcblxyXG5cclxuICAgIHJldHVybiBwdWdsYXRpemVyO1xyXG59KSk7XHJcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBREE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0EsV0FPQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQVBBO0FBVUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBQUE7QUFDQTtBQUVBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4324\n')},48248:function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nmodule.exports = View.extend({\n  template: templates.datasets.session,\n  derived: {// facetsURL: {\n    //   deps: ['model.id'],\n    //   fn: function () {\n    //     return this.model.id;\n    //   }\n    // }\n  },\n  props: {\n    bussy: ['boolean', true, false]\n  },\n  bindings: {\n    'bussy': [{\n      hook: 'cbtoggle',\n      type: 'toggle',\n      invert: true\n    }, {\n      hook: 'cbspinner',\n      type: 'toggle',\n      invert: false\n    }],\n    // 'model.show': {\n    //   hook: 'session',\n    //   type: 'toggle'\n    // },\n    'model.date': {\n      hook: 'date',\n      type: 'text'\n    },\n    'model.name': {\n      hook: 'name',\n      type: 'text'\n    },\n    // material design hooks\n    'model.isActive': [{\n      hook: 'cb',\n      type: 'booleanAttribute',\n      name: 'checked'\n    }, {\n      type: 'toggle',\n      hook: 'settings',\n      invert: true\n    }],\n    'model.id': [{\n      hook: 'cb',\n      type: 'attribute',\n      name: 'id'\n    }, {\n      hook: 'cblabel',\n      type: 'attribute',\n      name: 'for'\n    }]\n  },\n  events: {\n    'change': 'toggleActive',\n    // 'click [data-hook~=settings]': function () { app.navigate('/dataset/' + this.model.id); },\n    'click [data-hook~=delete]': 'deleteSession'\n  },\n  toggleActive: function toggleActive() {\n    var that = this;\n    that.bussy = !that.busy;\n    that.model.isActive = !that.model.isActive; //   // if (that.model.facets.length === 0) {\n    //   //   // Automatically scan the dataset if there are no facets\n    //   //   that.model.scan();\n    //   //   that.model.once('syncFacets', function () {\n    //   //     app.me.toggleDataset(that.model);\n    //   //     that.bussy = !that.bussy;\n    //   //   });\n    //   // } else {\n    //   //   // BUGFIX: we cant show/hide the spinner from within the event loop; so\n    //   //   //  * activate the spinner,\n    //   //   //  * exit the event loop (ie. redraw the page),\n    //   //   //  * and toggle the dataset via the timeout\n    //   //   window.setTimeout(function () {\n    //   //     app.me.toggleDataset(that.model);\n    //   //     that.bussy = !that.bussy;\n    //   //   }, 500);\n    //   // }\n\n    that.bussy = !that.bussy;\n  },\n  deleteSession: function deleteSession() {\n    console.log('Deleting the session'); //   // if (this.model.isActive) {\n    //   //   this.bussy = true;\n    //   //   app.me.toggleDataset(this.model);\n    //   //   this.bussy = false;\n    //   // }\n\n    console.log(this.model);\n    app.removeSessionFromLocalStorage(this.model.id);\n  },\n  render: function render() {\n    this.renderWithTemplate(this);\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDgyNDguanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvcGFnZXMvZGF0YXNldHMvc2Vzc2lvbi12aWV3LmpzPzYzOTMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL3RlbXBsYXRlcycpO1xudmFyIGFwcCA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1hcHAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMuZGF0YXNldHMuc2Vzc2lvbixcbiAgZGVyaXZlZDoge1xuICAgIC8vIGZhY2V0c1VSTDoge1xuICAgIC8vICAgZGVwczogWydtb2RlbC5pZCddLFxuICAgIC8vICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAvLyAgICAgcmV0dXJuIHRoaXMubW9kZWwuaWQ7XG4gICAgLy8gICB9XG4gICAgLy8gfVxuICB9LFxuICBwcm9wczoge1xuICAgIGJ1c3N5OiBbJ2Jvb2xlYW4nLCB0cnVlLCBmYWxzZV1cbiAgfSxcbiAgYmluZGluZ3M6IHtcbiAgICAnYnVzc3knOiBbXG4gICAgICB7XG4gICAgICAgIGhvb2s6ICdjYnRvZ2dsZScsXG4gICAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgICBpbnZlcnQ6IHRydWVcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGhvb2s6ICdjYnNwaW5uZXInLFxuICAgICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgICAgaW52ZXJ0OiBmYWxzZVxuICAgICAgfVxuICAgIF0sXG4gICAgLy8gJ21vZGVsLnNob3cnOiB7XG4gICAgLy8gICBob29rOiAnc2Vzc2lvbicsXG4gICAgLy8gICB0eXBlOiAndG9nZ2xlJ1xuICAgIC8vIH0sXG4gICAgJ21vZGVsLmRhdGUnOiB7XG4gICAgICBob29rOiAnZGF0ZScsXG4gICAgICB0eXBlOiAndGV4dCdcbiAgICB9LCAgICBcbiAgICAnbW9kZWwubmFtZSc6IHtcbiAgICAgIGhvb2s6ICduYW1lJyxcbiAgICAgIHR5cGU6ICd0ZXh0J1xuICAgIH0sXG4gICAgLy8gbWF0ZXJpYWwgZGVzaWduIGhvb2tzXG4gICAgJ21vZGVsLmlzQWN0aXZlJzogW1xuICAgICAge1xuICAgICAgICBob29rOiAnY2InLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbkF0dHJpYnV0ZScsXG4gICAgICAgIG5hbWU6ICdjaGVja2VkJ1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICAgIGhvb2s6ICdzZXR0aW5ncycsXG4gICAgICAgIGludmVydDogdHJ1ZVxuICAgICAgfVxuICAgIF0sXG4gICAgJ21vZGVsLmlkJzogW1xuICAgICAgeyBob29rOiAnY2InLCB0eXBlOiAnYXR0cmlidXRlJywgbmFtZTogJ2lkJyB9LFxuICAgICAgeyBob29rOiAnY2JsYWJlbCcsIHR5cGU6ICdhdHRyaWJ1dGUnLCBuYW1lOiAnZm9yJyB9XG4gICAgXVxuICB9LFxuICBldmVudHM6IHtcbiAgICAnY2hhbmdlJzogJ3RvZ2dsZUFjdGl2ZScsXG4gICAgLy8gJ2NsaWNrIFtkYXRhLWhvb2t+PXNldHRpbmdzXSc6IGZ1bmN0aW9uICgpIHsgYXBwLm5hdmlnYXRlKCcvZGF0YXNldC8nICsgdGhpcy5tb2RlbC5pZCk7IH0sXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWRlbGV0ZV0nOiAnZGVsZXRlU2Vzc2lvbidcbiAgfSxcbiAgdG9nZ2xlQWN0aXZlOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuXG4gICAgdGhhdC5idXNzeSA9ICF0aGF0LmJ1c3k7XG4gICAgdGhhdC5tb2RlbC5pc0FjdGl2ZSA9ICF0aGF0Lm1vZGVsLmlzQWN0aXZlO1xuXG4gIC8vICAgLy8gaWYgKHRoYXQubW9kZWwuZmFjZXRzLmxlbmd0aCA9PT0gMCkge1xuICAvLyAgIC8vICAgLy8gQXV0b21hdGljYWxseSBzY2FuIHRoZSBkYXRhc2V0IGlmIHRoZXJlIGFyZSBubyBmYWNldHNcbiAgLy8gICAvLyAgIHRoYXQubW9kZWwuc2NhbigpO1xuICAvLyAgIC8vICAgdGhhdC5tb2RlbC5vbmNlKCdzeW5jRmFjZXRzJywgZnVuY3Rpb24gKCkge1xuICAvLyAgIC8vICAgICBhcHAubWUudG9nZ2xlRGF0YXNldCh0aGF0Lm1vZGVsKTtcbiAgLy8gICAvLyAgICAgdGhhdC5idXNzeSA9ICF0aGF0LmJ1c3N5O1xuICAvLyAgIC8vICAgfSk7XG4gIC8vICAgLy8gfSBlbHNlIHtcbiAgLy8gICAvLyAgIC8vIEJVR0ZJWDogd2UgY2FudCBzaG93L2hpZGUgdGhlIHNwaW5uZXIgZnJvbSB3aXRoaW4gdGhlIGV2ZW50IGxvb3A7IHNvXG4gIC8vICAgLy8gICAvLyAgKiBhY3RpdmF0ZSB0aGUgc3Bpbm5lcixcbiAgLy8gICAvLyAgIC8vICAqIGV4aXQgdGhlIGV2ZW50IGxvb3AgKGllLiByZWRyYXcgdGhlIHBhZ2UpLFxuICAvLyAgIC8vICAgLy8gICogYW5kIHRvZ2dsZSB0aGUgZGF0YXNldCB2aWEgdGhlIHRpbWVvdXRcbiAgLy8gICAvLyAgIHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgLy8gICAvLyAgICAgYXBwLm1lLnRvZ2dsZURhdGFzZXQodGhhdC5tb2RlbCk7XG4gIC8vICAgLy8gICAgIHRoYXQuYnVzc3kgPSAhdGhhdC5idXNzeTtcbiAgLy8gICAvLyAgIH0sIDUwMCk7XG4gIC8vICAgLy8gfVxuXG4gICAgdGhhdC5idXNzeSA9ICF0aGF0LmJ1c3N5O1xuICB9LFxuICBkZWxldGVTZXNzaW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5sb2coJ0RlbGV0aW5nIHRoZSBzZXNzaW9uJylcbiAgLy8gICAvLyBpZiAodGhpcy5tb2RlbC5pc0FjdGl2ZSkge1xuICAvLyAgIC8vICAgdGhpcy5idXNzeSA9IHRydWU7XG4gIC8vICAgLy8gICBhcHAubWUudG9nZ2xlRGF0YXNldCh0aGlzLm1vZGVsKTtcbiAgLy8gICAvLyAgIHRoaXMuYnVzc3kgPSBmYWxzZTtcbiAgLy8gICAvLyB9XG4gICAgY29uc29sZS5sb2codGhpcy5tb2RlbCk7XG4gICAgYXBwLnJlbW92ZVNlc3Npb25Gcm9tTG9jYWxTdG9yYWdlKHRoaXMubW9kZWwuaWQpO1xuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlbmRlcldpdGhUZW1wbGF0ZSh0aGlzKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFOQTtBQVFBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFIQTtBQU1BO0FBQ0E7QUFDQTtBQUhBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUhBO0FBTUE7QUFDQTtBQUNBO0FBSEE7QUFNQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUF4Q0E7QUEyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFFQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQW5HQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///48248\n")},4916:function(module,exports,__webpack_require__){eval("var Spot = __webpack_require__(/*! spot-framework */ \"3b07\");\n\nvar View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar timeUtil = Spot.util.time; // this.model should be a DurationTransform\n\nvar DurationUnitsView = View.extend({\n  template: '<option data-hook=\"option\"> </option>',\n  render: function render() {\n    this.renderWithTemplate(this);\n  },\n  bindings: {\n    'model.description': [{\n      hook: 'option',\n      type: 'text'\n    }, {\n      hook: 'option',\n      type: 'attribute',\n      name: 'value'\n    }]\n  }\n});\nmodule.exports = View.extend({\n  template: '<select data-hook=\"options\"> </select>',\n  initialize: function initialize(options) {\n    this.field = options.field;\n  },\n  render: function render() {\n    this.renderWithTemplate(this);\n    this.renderCollection(timeUtil.durationUnits, DurationUnitsView, this.queryByHook('options'));\n    var value = this.model[this.field];\n    this.queryByHook('options').value = value;\n  },\n  events: {\n    'change [data-hook=\"options\"]': 'changeDurationUnits'\n  },\n  changeDurationUnits: function changeDurationUnits() {\n    var value = this.queryByHook('options').value;\n    this.model[this.field] = value;\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDkxNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZmFjZXQvZHVyYXRpb24tdW5pdHMtc2VsZWN0LmpzP2JlODEiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFNwb3QgPSByZXF1aXJlKCdzcG90LWZyYW1ld29yaycpO1xudmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRpbWVVdGlsID0gU3BvdC51dGlsLnRpbWU7XG5cbi8vIHRoaXMubW9kZWwgc2hvdWxkIGJlIGEgRHVyYXRpb25UcmFuc2Zvcm1cblxudmFyIER1cmF0aW9uVW5pdHNWaWV3ID0gVmlldy5leHRlbmQoe1xuICB0ZW1wbGF0ZTogJzxvcHRpb24gZGF0YS1ob29rPVwib3B0aW9uXCI+IDwvb3B0aW9uPicsXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVuZGVyV2l0aFRlbXBsYXRlKHRoaXMpO1xuICB9LFxuICBiaW5kaW5nczoge1xuICAgICdtb2RlbC5kZXNjcmlwdGlvbic6IFtcbiAgICAgIHtcbiAgICAgICAgaG9vazogJ29wdGlvbicsXG4gICAgICAgIHR5cGU6ICd0ZXh0J1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaG9vazogJ29wdGlvbicsXG4gICAgICAgIHR5cGU6ICdhdHRyaWJ1dGUnLFxuICAgICAgICBuYW1lOiAndmFsdWUnXG4gICAgICB9XG4gICAgXVxuICB9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiAnPHNlbGVjdCBkYXRhLWhvb2s9XCJvcHRpb25zXCI+IDwvc2VsZWN0PicsXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgdGhpcy5maWVsZCA9IG9wdGlvbnMuZmllbGQ7XG4gIH0sXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVuZGVyV2l0aFRlbXBsYXRlKHRoaXMpO1xuICAgIHRoaXMucmVuZGVyQ29sbGVjdGlvbih0aW1lVXRpbC5kdXJhdGlvblVuaXRzLCBEdXJhdGlvblVuaXRzVmlldywgdGhpcy5xdWVyeUJ5SG9vaygnb3B0aW9ucycpKTtcblxuICAgIHZhciB2YWx1ZSA9IHRoaXMubW9kZWxbdGhpcy5maWVsZF07XG4gICAgdGhpcy5xdWVyeUJ5SG9vaygnb3B0aW9ucycpLnZhbHVlID0gdmFsdWU7XG4gIH0sXG4gIGV2ZW50czoge1xuICAgICdjaGFuZ2UgW2RhdGEtaG9vaz1cIm9wdGlvbnNcIl0nOiAnY2hhbmdlRHVyYXRpb25Vbml0cydcbiAgfSxcbiAgY2hhbmdlRHVyYXRpb25Vbml0czogZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHRoaXMucXVlcnlCeUhvb2soJ29wdGlvbnMnKS52YWx1ZTtcbiAgICB0aGlzLm1vZGVsW3RoaXMuZmllbGRdID0gdmFsdWU7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUhBO0FBTkE7QUFMQTtBQW9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFsQkEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4916\n")},"4b1e":function(module,exports,__webpack_require__){eval("var PageView = __webpack_require__(/*! ./base */ \"b966\");\n\nvar templates = __webpack_require__(/*! ../templates */ \"4324\");\n\nvar FacetCollectionView = __webpack_require__(/*! ./configure-dataset/facet-collection */ \"701f\");\n\nvar app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar $ = __webpack_require__(/*! jquery */ \"802c\"); // Assumption:\n// this.model instanceof Dataset\n// this.collection instanceof facet-collection\n\n\nmodule.exports = PageView.extend({\n  template: templates.configureDataset.page,\n  render: function render() {\n    this.renderWithTemplate();\n\n    if (this.collection) {\n      this.collection.sort();\n      this.renderCollection(this.collection, FacetCollectionView, this.queryByHook('facet-list'));\n    }\n\n    this.query('#description').value = this.model.description; // material design lite does not like this via bindings...\n    // Automatically scan the dataset if necessary\n\n    if (this.model.facets.length === 0) {\n      this.model.scan();\n    }\n  },\n  initialize: function initialize() {\n    this.isLockedDown = app.me.isLockedDown;\n    this.needle = this.collection.needle;\n    this.showSearch = this.collection.showSearch;\n    this.on('remove', function () {\n      this.collection.needle = this.needle;\n      this.collection.showSearch = this.showSearch;\n      this.model.facets.off('add');\n    });\n    this.model.facets.on('add', function () {\n      setTimeout(function () {\n        window.componentHandler.upgradeDom();\n      }, 20);\n    });\n    this.update();\n  },\n  session: {\n    needle: 'string',\n    showSearch: 'boolean',\n    isLockedDown: 'boolean'\n  },\n  bindings: {\n    'isLockedDown': [{\n      type: 'toggle',\n      hook: 'add-button',\n      invert: 'yes'\n    }, {\n      type: 'toggle',\n      hook: 'rescan-button',\n      invert: 'yes'\n    }],\n    'showSearch': {\n      type: 'toggle',\n      hook: 'search-bar'\n    },\n    'needle': {\n      type: 'value',\n      hook: 'facet-selector'\n    },\n    'model.name': {\n      type: 'attribute',\n      selector: '#name',\n      name: 'value'\n    }\n  },\n  events: {\n    'input [data-hook~=facet-selector]': 'input',\n    'input #name': 'setName',\n    'input #description': 'setDescription',\n    'click #eab': 'enableAllFacets',\n    'click #dab': 'disableAllFacets',\n    'click [data-hook~=add-button]': 'add',\n    'click [data-hook~=rescan-button]': 'rescan',\n    'click [data-hook~=search-button]': 'search',\n    'click [data-hook~=clear-button]': 'clear'\n  },\n  enableAllFacets: function enableAllFacets() {\n    var i;\n    var f = $('[data-hook~=cblabel]');\n\n    for (i = 0; i < f.length; i++) {\n      var c = f[i].classList;\n\n      if (!c.contains('is-checked')) {\n        f[i].click();\n      }\n    }\n  },\n  disableAllFacets: function disableAllFacets() {\n    var i;\n    var f = $('[data-hook~=cblabel]');\n\n    for (i = 0; i < f.length; i++) {\n      var c = f[i].classList;\n\n      if (c.contains('is-checked')) {\n        f[i].click();\n      }\n    }\n  },\n  input: function input() {\n    var select = this.el.querySelector('[data-hook~=\"facet-selector\"]');\n    this.needle = select.value;\n    this.update();\n  },\n  setName: function setName() {\n    var field = this.query('#name');\n    this.model.name = field.value;\n  },\n  setDescription: function setDescription() {\n    var field = this.query('#description');\n    this.model.description = field.value;\n  },\n  add: function add() {\n    this.collection.add({\n      name: 'New Facet'\n    });\n  },\n  rescan: function rescan() {\n    this.model.scan();\n  },\n  search: function search() {\n    this.showSearch = !this.showSearch;\n\n    if (this.showSearch) {\n      this.queryByHook('facet-selector').focus();\n    }\n  },\n  clear: function clear() {\n    this.needle = '';\n    this.update();\n  },\n  update: function update() {\n    // build regexp for searching\n    try {\n      var regexp = new RegExp(this.needle, 'i'); // case insensitive search\n      // search through collection, check both name and description\n\n      this.collection.forEach(function (e) {\n        var hay = e.name + e.description;\n        e.show = regexp.test(hay.toLowerCase());\n      });\n    } catch (error) {}\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNGIxZS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZGF0YXNldC5qcz9jMzdiIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBQYWdlVmlldyA9IHJlcXVpcmUoJy4vYmFzZScpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uL3RlbXBsYXRlcycpO1xudmFyIEZhY2V0Q29sbGVjdGlvblZpZXcgPSByZXF1aXJlKCcuL2NvbmZpZ3VyZS1kYXRhc2V0L2ZhY2V0LWNvbGxlY3Rpb24nKTtcbnZhciBhcHAgPSByZXF1aXJlKCdhbXBlcnNhbmQtYXBwJyk7XG52YXIgJCA9IHJlcXVpcmUoJ2pxdWVyeScpO1xuXG4vLyBBc3N1bXB0aW9uOlxuLy8gdGhpcy5tb2RlbCBpbnN0YW5jZW9mIERhdGFzZXRcbi8vIHRoaXMuY29sbGVjdGlvbiBpbnN0YW5jZW9mIGZhY2V0LWNvbGxlY3Rpb25cblxubW9kdWxlLmV4cG9ydHMgPSBQYWdlVmlldy5leHRlbmQoe1xuICB0ZW1wbGF0ZTogdGVtcGxhdGVzLmNvbmZpZ3VyZURhdGFzZXQucGFnZSxcbiAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZW5kZXJXaXRoVGVtcGxhdGUoKTtcblxuICAgIGlmICh0aGlzLmNvbGxlY3Rpb24pIHtcbiAgICAgIHRoaXMuY29sbGVjdGlvbi5zb3J0KCk7XG4gICAgICB0aGlzLnJlbmRlckNvbGxlY3Rpb24odGhpcy5jb2xsZWN0aW9uLCBGYWNldENvbGxlY3Rpb25WaWV3LCB0aGlzLnF1ZXJ5QnlIb29rKCdmYWNldC1saXN0JykpO1xuICAgIH1cbiAgICB0aGlzLnF1ZXJ5KCcjZGVzY3JpcHRpb24nKS52YWx1ZSA9IHRoaXMubW9kZWwuZGVzY3JpcHRpb247IC8vIG1hdGVyaWFsIGRlc2lnbiBsaXRlIGRvZXMgbm90IGxpa2UgdGhpcyB2aWEgYmluZGluZ3MuLi5cblxuICAgIC8vIEF1dG9tYXRpY2FsbHkgc2NhbiB0aGUgZGF0YXNldCBpZiBuZWNlc3NhcnlcbiAgICBpZiAodGhpcy5tb2RlbC5mYWNldHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLm1vZGVsLnNjYW4oKTtcbiAgICB9XG4gIH0sXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmlzTG9ja2VkRG93biA9IGFwcC5tZS5pc0xvY2tlZERvd247XG4gICAgdGhpcy5uZWVkbGUgPSB0aGlzLmNvbGxlY3Rpb24ubmVlZGxlO1xuICAgIHRoaXMuc2hvd1NlYXJjaCA9IHRoaXMuY29sbGVjdGlvbi5zaG93U2VhcmNoO1xuXG4gICAgdGhpcy5vbigncmVtb3ZlJywgZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5jb2xsZWN0aW9uLm5lZWRsZSA9IHRoaXMubmVlZGxlO1xuICAgICAgdGhpcy5jb2xsZWN0aW9uLnNob3dTZWFyY2ggPSB0aGlzLnNob3dTZWFyY2g7XG4gICAgICB0aGlzLm1vZGVsLmZhY2V0cy5vZmYoJ2FkZCcpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5tb2RlbC5mYWNldHMub24oJ2FkZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICB3aW5kb3cuY29tcG9uZW50SGFuZGxlci51cGdyYWRlRG9tKCk7XG4gICAgICB9LCAyMCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnVwZGF0ZSgpO1xuICB9LFxuICBzZXNzaW9uOiB7XG4gICAgbmVlZGxlOiAnc3RyaW5nJyxcbiAgICBzaG93U2VhcmNoOiAnYm9vbGVhbicsXG4gICAgaXNMb2NrZWREb3duOiAnYm9vbGVhbidcbiAgfSxcbiAgYmluZGluZ3M6IHtcbiAgICAnaXNMb2NrZWREb3duJzogW1xuICAgICAgeyB0eXBlOiAndG9nZ2xlJywgaG9vazogJ2FkZC1idXR0b24nLCBpbnZlcnQ6ICd5ZXMnIH0sXG4gICAgICB7IHR5cGU6ICd0b2dnbGUnLCBob29rOiAncmVzY2FuLWJ1dHRvbicsIGludmVydDogJ3llcycgfVxuICAgIF0sXG4gICAgJ3Nob3dTZWFyY2gnOiB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIGhvb2s6ICdzZWFyY2gtYmFyJ1xuICAgIH0sXG4gICAgJ25lZWRsZSc6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAnZmFjZXQtc2VsZWN0b3InXG4gICAgfSxcbiAgICAnbW9kZWwubmFtZSc6IHtcbiAgICAgIHR5cGU6ICdhdHRyaWJ1dGUnLFxuICAgICAgc2VsZWN0b3I6ICcjbmFtZScsXG4gICAgICBuYW1lOiAndmFsdWUnXG4gICAgfVxuICB9LFxuICBldmVudHM6IHtcbiAgICAnaW5wdXQgW2RhdGEtaG9va349ZmFjZXQtc2VsZWN0b3JdJzogJ2lucHV0JyxcbiAgICAnaW5wdXQgI25hbWUnOiAnc2V0TmFtZScsXG4gICAgJ2lucHV0ICNkZXNjcmlwdGlvbic6ICdzZXREZXNjcmlwdGlvbicsXG4gICAgJ2NsaWNrICNlYWInOiAnZW5hYmxlQWxsRmFjZXRzJyxcbiAgICAnY2xpY2sgI2RhYic6ICdkaXNhYmxlQWxsRmFjZXRzJyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349YWRkLWJ1dHRvbl0nOiAnYWRkJyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349cmVzY2FuLWJ1dHRvbl0nOiAncmVzY2FuJyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349c2VhcmNoLWJ1dHRvbl0nOiAnc2VhcmNoJyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349Y2xlYXItYnV0dG9uXSc6ICdjbGVhcidcbiAgfSxcbiAgZW5hYmxlQWxsRmFjZXRzOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGk7XG4gICAgdmFyIGYgPSAkKCdbZGF0YS1ob29rfj1jYmxhYmVsXScpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBmLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgYyA9IGZbaV0uY2xhc3NMaXN0O1xuICAgICAgaWYgKCFjLmNvbnRhaW5zKCdpcy1jaGVja2VkJykpIHtcbiAgICAgICAgZltpXS5jbGljaygpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgZGlzYWJsZUFsbEZhY2V0czogZnVuY3Rpb24gKCkge1xuICAgIHZhciBpO1xuICAgIHZhciBmID0gJCgnW2RhdGEtaG9va349Y2JsYWJlbF0nKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgZi5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGMgPSBmW2ldLmNsYXNzTGlzdDtcbiAgICAgIGlmIChjLmNvbnRhaW5zKCdpcy1jaGVja2VkJykpIHtcbiAgICAgICAgZltpXS5jbGljaygpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgaW5wdXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2VsZWN0ID0gdGhpcy5lbC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1ob29rfj1cImZhY2V0LXNlbGVjdG9yXCJdJyk7XG4gICAgdGhpcy5uZWVkbGUgPSBzZWxlY3QudmFsdWU7XG5cbiAgICB0aGlzLnVwZGF0ZSgpO1xuICB9LFxuICBzZXROYW1lOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGZpZWxkID0gdGhpcy5xdWVyeSgnI25hbWUnKTtcbiAgICB0aGlzLm1vZGVsLm5hbWUgPSBmaWVsZC52YWx1ZTtcbiAgfSxcbiAgc2V0RGVzY3JpcHRpb246IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZmllbGQgPSB0aGlzLnF1ZXJ5KCcjZGVzY3JpcHRpb24nKTtcbiAgICB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uID0gZmllbGQudmFsdWU7XG4gIH0sXG4gIGFkZDogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuY29sbGVjdGlvbi5hZGQoe25hbWU6ICdOZXcgRmFjZXQnfSk7XG4gIH0sXG4gIHJlc2NhbjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMubW9kZWwuc2NhbigpO1xuICB9LFxuICBzZWFyY2g6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNob3dTZWFyY2ggPSAhdGhpcy5zaG93U2VhcmNoO1xuICAgIGlmICh0aGlzLnNob3dTZWFyY2gpIHtcbiAgICAgIHRoaXMucXVlcnlCeUhvb2soJ2ZhY2V0LXNlbGVjdG9yJykuZm9jdXMoKTtcbiAgICB9XG4gIH0sXG4gIGNsZWFyOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5uZWVkbGUgPSAnJztcbiAgICB0aGlzLnVwZGF0ZSgpO1xuICB9LFxuICB1cGRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBidWlsZCByZWdleHAgZm9yIHNlYXJjaGluZ1xuICAgIHRyeSB7XG4gICAgICB2YXIgcmVnZXhwID0gbmV3IFJlZ0V4cCh0aGlzLm5lZWRsZSwgJ2knKTsgLy8gY2FzZSBpbnNlbnNpdGl2ZSBzZWFyY2hcblxuICAgICAgLy8gc2VhcmNoIHRocm91Z2ggY29sbGVjdGlvbiwgY2hlY2sgYm90aCBuYW1lIGFuZCBkZXNjcmlwdGlvblxuICAgICAgdGhpcy5jb2xsZWN0aW9uLmZvckVhY2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIGhheSA9IGUubmFtZSArIGUuZGVzY3JpcHRpb247XG4gICAgICAgIGUuc2hvdyA9IHJlZ2V4cC50ZXN0KGhheS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQWJBO0FBbUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBVEE7QUFXQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBcElBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4b1e\n")},5122:function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar SlotView = __webpack_require__(/*! ./slot */ \"de8e\");\n\nvar $ = __webpack_require__(/*! jquery */ \"802c\");\n\nvar FileSaver = __webpack_require__(/*! file-saver */ \"23bf\"); // NOTE: gridster does not work properly with require()\n// workaround via browserify-shim (configured in package.json)\n\n\n__webpack_require__(/*! gridster */ \"cc37\");\n\nfunction removeWidget(view, filter) {\n  // Remove the filter from the dataset\n  var filters = filter.collection;\n  filters.remove(filter);\n  filter.off('newData'); // Remove gridster stuff\n\n  var gridster = $('[id~=widgets]').gridster().data('gridster');\n  gridster.remove_widget(view.gridsterHook); // Remove ampersand stuff\n\n  var p = view.parent._subviews;\n  p.splice(p.indexOf(view), 1);\n  view.remove();\n}\n\nmodule.exports = View.extend({\n  template: templates.analyze.widgetFrame,\n  initialize: function initialize(opts) {\n    this.editMode = false; // on initialization we have a Filter as model,\n    // but we need to have a (chart specific) model instead\n    // So, create the proper model and swap it for the filter.\n\n    var filter = this.model;\n    this.model = app.widgetFactory.newModel({\n      modelType: filter.chartType,\n      filter: filter\n    });\n    this.widgetHeader = filter.chartType;\n  },\n  props: {\n    editMode: 'boolean',\n    chartType: 'string'\n  },\n  derived: {\n    'showMenu': {\n      deps: ['editMode', 'mouseOver'],\n      fn: function fn() {\n        // never show in edit mode\n        if (this.editMode) return false; // http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript/4819886#4819886\n\n        var touch = 'ontouchstart' in window || navigator.maxTouchPoints;\n        return touch || this.mouseOver;\n      }\n    }\n  },\n  session: {\n    mouseOver: ['boolean', true, false]\n  },\n  bindings: {\n    'editMode': {\n      hook: 'config-view',\n      type: 'toggle',\n      invert: false\n    },\n    'showMenu': {\n      type: 'toggle',\n      hook: 'plot-menu'\n    },\n    'widgetHeader': {\n      hook: 'widgetHeader',\n      type: 'text'\n    }\n  },\n  events: {\n    'click [data-hook~=\"close\"]': 'closeWidget',\n    'click [data-hook~=\"zoom-in\"]': 'zoomIn',\n    'click [data-hook~=\"zoom-out\"]': 'zoomOut',\n    'click [data-hook~=\"save\"]': 'savePlot',\n    'click [data-hook~=\"edit\"]': function clickDataHookEdit() {\n      this.editMode = !this.editMode;\n    },\n    'mouseenter .widgetFrame': 'mouseEnter',\n    'mouseleave .widgetFrame': 'mouseLeave'\n  },\n  zoomIn: function zoomIn(ev) {\n    this.model.filter.zoomIn();\n    app.me.dataview.getData();\n  },\n  zoomOut: function zoomOut() {\n    this.model.filter.zoomOut();\n    app.me.dataview.getData();\n  },\n  savePlot: function savePlot() {\n    // Save the image to disk, but add a white background;\n    // for this we need to make temporary copy\n    // actual onscreen canvas\n    var canvas = this.el.getElementsByTagName('canvas')[0];\n    var ctx = canvas.getContext('2d'); // temporary canvas\n\n    var tempCanvas = document.createElement('canvas');\n    var tempCtx = tempCanvas.getContext('2d');\n    tempCanvas.width = ctx.canvas.width;\n    tempCanvas.height = ctx.canvas.height;\n    tempCtx.fillStyle = 'white';\n    tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height);\n    tempCtx.drawImage(canvas, 0, 0); // use plot type as filename\n\n    var imageName = this.model.modelType;\n    tempCtx.canvas.toBlob(function (blob) {\n      FileSaver.saveAs(blob, imageName);\n    }, 'image/png');\n  },\n  mouseEnter: function mouseEnter() {\n    this.mouseOver = true;\n  },\n  mouseLeave: function mouseLeave() {\n    this.mouseOver = false;\n  },\n  closeWidget: function closeWidget() {\n    removeWidget(this, this.model.filter);\n  },\n  render: function render() {\n    this.renderWithTemplate(this);\n    this.renderCollection(this.model.slots, SlotView, this.queryByHook('slots'));\n    return this;\n  },\n  renderContent: function renderContent() {\n    // Propagate to subview\n    this.widget.renderContent();\n  },\n  subviews: {\n    widget: {\n      hook: 'widget',\n      constructor: function constructor(options) {\n        // NOTE: view type (barchart, bubblechart, ...) is determined from options.model.modelType\n        options.model = options.parent.model;\n        return app.viewFactory.newView(options);\n      }\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTEyMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9hbmFseXplL3dpZGdldC1mcmFtZS5qcz83N2Q5Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBWaWV3ID0gcmVxdWlyZSgnYW1wZXJzYW5kLXZpZXcnKTtcbnZhciB0ZW1wbGF0ZXMgPSByZXF1aXJlKCcuLi8uLi90ZW1wbGF0ZXMnKTtcbnZhciBhcHAgPSByZXF1aXJlKCdhbXBlcnNhbmQtYXBwJyk7XG52YXIgU2xvdFZpZXcgPSByZXF1aXJlKCcuL3Nsb3QnKTtcbnZhciAkID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG52YXIgRmlsZVNhdmVyID0gcmVxdWlyZSgnZmlsZS1zYXZlcicpO1xuXG4vLyBOT1RFOiBncmlkc3RlciBkb2VzIG5vdCB3b3JrIHByb3Blcmx5IHdpdGggcmVxdWlyZSgpXG4vLyB3b3JrYXJvdW5kIHZpYSBicm93c2VyaWZ5LXNoaW0gKGNvbmZpZ3VyZWQgaW4gcGFja2FnZS5qc29uKVxucmVxdWlyZSgnZ3JpZHN0ZXInKTtcblxuZnVuY3Rpb24gcmVtb3ZlV2lkZ2V0ICh2aWV3LCBmaWx0ZXIpIHtcbiAgLy8gUmVtb3ZlIHRoZSBmaWx0ZXIgZnJvbSB0aGUgZGF0YXNldFxuICB2YXIgZmlsdGVycyA9IGZpbHRlci5jb2xsZWN0aW9uO1xuICBmaWx0ZXJzLnJlbW92ZShmaWx0ZXIpO1xuICBmaWx0ZXIub2ZmKCduZXdEYXRhJyk7XG5cbiAgLy8gUmVtb3ZlIGdyaWRzdGVyIHN0dWZmXG4gIHZhciBncmlkc3RlciA9ICQoJ1tpZH49d2lkZ2V0c10nKS5ncmlkc3RlcigpLmRhdGEoJ2dyaWRzdGVyJyk7XG4gIGdyaWRzdGVyLnJlbW92ZV93aWRnZXQodmlldy5ncmlkc3Rlckhvb2spO1xuXG4gIC8vIFJlbW92ZSBhbXBlcnNhbmQgc3R1ZmZcbiAgdmFyIHAgPSB2aWV3LnBhcmVudC5fc3Vidmlld3M7XG4gIHAuc3BsaWNlKHAuaW5kZXhPZih2aWV3KSwgMSk7XG4gIHZpZXcucmVtb3ZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVmlldy5leHRlbmQoe1xuICB0ZW1wbGF0ZTogdGVtcGxhdGVzLmFuYWx5emUud2lkZ2V0RnJhbWUsXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgdGhpcy5lZGl0TW9kZSA9IGZhbHNlO1xuXG4gICAgLy8gb24gaW5pdGlhbGl6YXRpb24gd2UgaGF2ZSBhIEZpbHRlciBhcyBtb2RlbCxcbiAgICAvLyBidXQgd2UgbmVlZCB0byBoYXZlIGEgKGNoYXJ0IHNwZWNpZmljKSBtb2RlbCBpbnN0ZWFkXG4gICAgLy8gU28sIGNyZWF0ZSB0aGUgcHJvcGVyIG1vZGVsIGFuZCBzd2FwIGl0IGZvciB0aGUgZmlsdGVyLlxuICAgIHZhciBmaWx0ZXIgPSB0aGlzLm1vZGVsO1xuXG4gICAgdGhpcy5tb2RlbCA9IGFwcC53aWRnZXRGYWN0b3J5Lm5ld01vZGVsKHtcbiAgICAgIG1vZGVsVHlwZTogZmlsdGVyLmNoYXJ0VHlwZSxcbiAgICAgIGZpbHRlcjogZmlsdGVyXG4gICAgfSk7XG4gICAgdGhpcy53aWRnZXRIZWFkZXIgPSBmaWx0ZXIuY2hhcnRUeXBlO1xuICB9LFxuICBwcm9wczoge1xuICAgIGVkaXRNb2RlOiAnYm9vbGVhbicsXG4gICAgY2hhcnRUeXBlOiAnc3RyaW5nJ1xuICB9LFxuICBkZXJpdmVkOiB7XG4gICAgJ3Nob3dNZW51Jzoge1xuICAgICAgZGVwczogWydlZGl0TW9kZScsICdtb3VzZU92ZXInXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIG5ldmVyIHNob3cgaW4gZWRpdCBtb2RlXG4gICAgICAgIGlmICh0aGlzLmVkaXRNb2RlKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80ODE3MDI5L3doYXRzLXRoZS1iZXN0LXdheS10by1kZXRlY3QtYS10b3VjaC1zY3JlZW4tZGV2aWNlLXVzaW5nLWphdmFzY3JpcHQvNDgxOTg4NiM0ODE5ODg2XG4gICAgICAgIHZhciB0b3VjaCA9ICdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyB8fCBuYXZpZ2F0b3IubWF4VG91Y2hQb2ludHM7XG4gICAgICAgIHJldHVybiB0b3VjaCB8fCB0aGlzLm1vdXNlT3ZlcjtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHNlc3Npb246IHtcbiAgICBtb3VzZU92ZXI6IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXVxuICB9LFxuICBiaW5kaW5nczoge1xuICAgICdlZGl0TW9kZSc6IHtcbiAgICAgIGhvb2s6ICdjb25maWctdmlldycsXG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIGludmVydDogZmFsc2VcbiAgICB9LFxuICAgICdzaG93TWVudSc6IHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgaG9vazogJ3Bsb3QtbWVudSdcbiAgICB9LFxuICAgICd3aWRnZXRIZWFkZXInOiB7XG4gICAgICBob29rOiAnd2lkZ2V0SGVhZGVyJyxcbiAgICAgIHR5cGU6ICd0ZXh0J1xuICAgIH1cbiAgfSxcbiAgZXZlbnRzOiB7XG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PVwiY2xvc2VcIl0nOiAnY2xvc2VXaWRnZXQnLFxuICAgICdjbGljayBbZGF0YS1ob29rfj1cInpvb20taW5cIl0nOiAnem9vbUluJyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349XCJ6b29tLW91dFwiXSc6ICd6b29tT3V0JyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349XCJzYXZlXCJdJzogJ3NhdmVQbG90JyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349XCJlZGl0XCJdJzogZnVuY3Rpb24gKCkgeyB0aGlzLmVkaXRNb2RlID0gIXRoaXMuZWRpdE1vZGU7IH0sXG5cbiAgICAnbW91c2VlbnRlciAud2lkZ2V0RnJhbWUnOiAnbW91c2VFbnRlcicsXG4gICAgJ21vdXNlbGVhdmUgLndpZGdldEZyYW1lJzogJ21vdXNlTGVhdmUnXG4gIH0sXG4gIHpvb21JbjogZnVuY3Rpb24gKGV2KSB7XG4gICAgdGhpcy5tb2RlbC5maWx0ZXIuem9vbUluKCk7XG4gICAgYXBwLm1lLmRhdGF2aWV3LmdldERhdGEoKTtcbiAgfSxcbiAgem9vbU91dDogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMubW9kZWwuZmlsdGVyLnpvb21PdXQoKTtcbiAgICBhcHAubWUuZGF0YXZpZXcuZ2V0RGF0YSgpO1xuICB9LFxuICBzYXZlUGxvdDogZnVuY3Rpb24gKCkge1xuICAgIC8vIFNhdmUgdGhlIGltYWdlIHRvIGRpc2ssIGJ1dCBhZGQgYSB3aGl0ZSBiYWNrZ3JvdW5kO1xuICAgIC8vIGZvciB0aGlzIHdlIG5lZWQgdG8gbWFrZSB0ZW1wb3JhcnkgY29weVxuXG4gICAgLy8gYWN0dWFsIG9uc2NyZWVuIGNhbnZhc1xuICAgIHZhciBjYW52YXMgPSB0aGlzLmVsLmdldEVsZW1lbnRzQnlUYWdOYW1lKCdjYW52YXMnKVswXTtcbiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG5cbiAgICAvLyB0ZW1wb3JhcnkgY2FudmFzXG4gICAgdmFyIHRlbXBDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICB2YXIgdGVtcEN0eCA9IHRlbXBDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcblxuICAgIHRlbXBDYW52YXMud2lkdGggPSBjdHguY2FudmFzLndpZHRoO1xuICAgIHRlbXBDYW52YXMuaGVpZ2h0ID0gY3R4LmNhbnZhcy5oZWlnaHQ7XG4gICAgdGVtcEN0eC5maWxsU3R5bGUgPSAnd2hpdGUnO1xuICAgIHRlbXBDdHguZmlsbFJlY3QoMCwgMCwgdGVtcENhbnZhcy53aWR0aCwgdGVtcENhbnZhcy5oZWlnaHQpO1xuICAgIHRlbXBDdHguZHJhd0ltYWdlKGNhbnZhcywgMCwgMCk7XG5cbiAgICAvLyB1c2UgcGxvdCB0eXBlIGFzIGZpbGVuYW1lXG4gICAgdmFyIGltYWdlTmFtZSA9IHRoaXMubW9kZWwubW9kZWxUeXBlO1xuXG4gICAgdGVtcEN0eC5jYW52YXMudG9CbG9iKGZ1bmN0aW9uIChibG9iKSB7XG4gICAgICBGaWxlU2F2ZXIuc2F2ZUFzKGJsb2IsIGltYWdlTmFtZSk7XG4gICAgfSwgJ2ltYWdlL3BuZycpO1xuICB9LFxuICBtb3VzZUVudGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5tb3VzZU92ZXIgPSB0cnVlO1xuICB9LFxuICBtb3VzZUxlYXZlOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5tb3VzZU92ZXIgPSBmYWxzZTtcbiAgfSxcbiAgY2xvc2VXaWRnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZW1vdmVXaWRnZXQodGhpcywgdGhpcy5tb2RlbC5maWx0ZXIpO1xuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlbmRlcldpdGhUZW1wbGF0ZSh0aGlzKTtcbiAgICB0aGlzLnJlbmRlckNvbGxlY3Rpb24odGhpcy5tb2RlbC5zbG90cywgU2xvdFZpZXcsIHRoaXMucXVlcnlCeUhvb2soJ3Nsb3RzJykpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICByZW5kZXJDb250ZW50OiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gUHJvcGFnYXRlIHRvIHN1YnZpZXdcbiAgICB0aGlzLndpZGdldC5yZW5kZXJDb250ZW50KCk7XG4gIH0sXG4gIHN1YnZpZXdzOiB7XG4gICAgd2lkZ2V0OiB7XG4gICAgICBob29rOiAnd2lkZ2V0JyxcbiAgICAgIGNvbnN0cnVjdG9yOiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICAvLyBOT1RFOiB2aWV3IHR5cGUgKGJhcmNoYXJ0LCBidWJibGVjaGFydCwgLi4uKSBpcyBkZXRlcm1pbmVkIGZyb20gb3B0aW9ucy5tb2RlbC5tb2RlbFR5cGVcbiAgICAgICAgb3B0aW9ucy5tb2RlbCA9IG9wdGlvbnMucGFyZW50Lm1vZGVsO1xuICAgICAgICByZXR1cm4gYXBwLnZpZXdGYWN0b3J5Lm5ld1ZpZXcob3B0aW9ucyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUdBO0FBQ0E7QUFDQTtBQURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFUQTtBQURBO0FBYUE7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFGQTtBQVZBO0FBZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFSQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU5BO0FBREE7QUFoSEEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5122\n")},"56f6":function(module,exports,__webpack_require__){eval('var View = __webpack_require__(/*! ampersand-view */ "2883");\n\nvar templates = __webpack_require__(/*! ../../templates */ "4324");\n\nvar app = __webpack_require__(/*! ampersand-app */ "fcbc");\n\nvar SessionView = __webpack_require__(/*! ./session-view */ "48248");\n\nmodule.exports = View.extend({\n  template: templates.datasets.sessionCollection,\n  initialize: function initialize() {},\n  render: function render() {\n    this.renderWithTemplate(this);\n    this.renderCollection(app.sessions, SessionView, this.queryByHook(\'session-collection-items\'));\n    return this;\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTZmNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9kYXRhc2V0cy9zZXNzaW9uLWNvbGxlY3Rpb24uanM/N2UyZiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgVmlldyA9IHJlcXVpcmUoJ2FtcGVyc2FuZC12aWV3Jyk7XG52YXIgdGVtcGxhdGVzID0gcmVxdWlyZSgnLi4vLi4vdGVtcGxhdGVzJyk7XG52YXIgYXBwID0gcmVxdWlyZSgnYW1wZXJzYW5kLWFwcCcpO1xuXG52YXIgU2Vzc2lvblZpZXcgPSByZXF1aXJlKCcuL3Nlc3Npb24tdmlldycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZXcuZXh0ZW5kKHtcbiAgdGVtcGxhdGU6IHRlbXBsYXRlcy5kYXRhc2V0cy5zZXNzaW9uQ29sbGVjdGlvbixcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlbmRlcldpdGhUZW1wbGF0ZSh0aGlzKTtcbiAgICB0aGlzLnJlbmRlckNvbGxlY3Rpb24oYXBwLnNlc3Npb25zLCBTZXNzaW9uVmlldywgdGhpcy5xdWVyeUJ5SG9vaygnc2Vzc2lvbi1jb2xsZWN0aW9uLWl0ZW1zJykpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFSQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///56f6\n')},"5eb6":function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nmodule.exports = View.extend({\n  template: templates.datasets.dataset,\n  derived: {\n    facetsURL: {\n      deps: ['model.id'],\n      fn: function fn() {\n        return '/dataset/' + this.model.id;\n      }\n    }\n  },\n  props: {\n    bussy: ['boolean', true, false]\n  },\n  bindings: {\n    'bussy': [{\n      hook: 'cbtoggle',\n      type: 'toggle',\n      invert: true\n    }, {\n      hook: 'cbspinner',\n      type: 'toggle',\n      invert: false\n    }],\n    'model.show': {\n      hook: 'dataset',\n      type: 'toggle'\n    },\n    'model.name': {\n      hook: 'name',\n      type: 'text'\n    },\n    'model.description': {\n      hook: 'description',\n      type: 'text'\n    },\n    // material design hooks\n    'model.isActive': [{\n      hook: 'cb',\n      type: 'booleanAttribute',\n      name: 'checked'\n    }, {\n      type: 'toggle',\n      hook: 'settings',\n      invert: true\n    }],\n    'model.id': [{\n      hook: 'cb',\n      type: 'attribute',\n      name: 'id'\n    }, {\n      hook: 'cblabel',\n      type: 'attribute',\n      name: 'for'\n    }]\n  },\n  events: {\n    'change': 'toggleActive',\n    'click [data-hook~=settings]': function clickDataHookSettings() {\n      app.navigate('/dataset/' + this.model.id);\n    },\n    'click [data-hook~=delete]': 'deleteDataset'\n  },\n  toggleActive: function toggleActive() {\n    var that = this;\n    that.bussy = !that.busy;\n\n    if (that.model.facets.length === 0) {\n      // Automatically scan the dataset if there are no facets\n      that.model.scan();\n      that.model.once('syncFacets', function () {\n        app.me.toggleDataset(that.model);\n        that.bussy = !that.bussy;\n      });\n    } else {\n      // BUGFIX: we cant show/hide the spinner from within the event loop; so\n      //  * activate the spinner,\n      //  * exit the event loop (ie. redraw the page),\n      //  * and toggle the dataset via the timeout\n      window.setTimeout(function () {\n        app.me.toggleDataset(that.model);\n        that.bussy = !that.bussy;\n      }, 500);\n    }\n  },\n  deleteDataset: function deleteDataset() {\n    if (this.model.isActive) {\n      this.bussy = true;\n      app.me.toggleDataset(this.model);\n      this.bussy = false;\n    }\n\n    console.log(this.model);\n    app.removeDatasetFromLocalStorage(this.model);\n    app.me.datasets.remove(this.model);\n  },\n  render: function render() {\n    this.renderWithTemplate(this);\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNWViNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9kYXRhc2V0cy9kYXRhc2V0LmpzP2U1M2MiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL3RlbXBsYXRlcycpO1xudmFyIGFwcCA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1hcHAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMuZGF0YXNldHMuZGF0YXNldCxcbiAgZGVyaXZlZDoge1xuICAgIGZhY2V0c1VSTDoge1xuICAgICAgZGVwczogWydtb2RlbC5pZCddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcvZGF0YXNldC8nICsgdGhpcy5tb2RlbC5pZDtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHByb3BzOiB7XG4gICAgYnVzc3k6IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXVxuICB9LFxuICBiaW5kaW5nczoge1xuICAgICdidXNzeSc6IFtcbiAgICAgIHtcbiAgICAgICAgaG9vazogJ2NidG9nZ2xlJyxcbiAgICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICAgIGludmVydDogdHJ1ZVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaG9vazogJ2Nic3Bpbm5lcicsXG4gICAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgICBpbnZlcnQ6IGZhbHNlXG4gICAgICB9XG4gICAgXSxcbiAgICAnbW9kZWwuc2hvdyc6IHtcbiAgICAgIGhvb2s6ICdkYXRhc2V0JyxcbiAgICAgIHR5cGU6ICd0b2dnbGUnXG4gICAgfSxcbiAgICAnbW9kZWwubmFtZSc6IHtcbiAgICAgIGhvb2s6ICduYW1lJyxcbiAgICAgIHR5cGU6ICd0ZXh0J1xuICAgIH0sXG4gICAgJ21vZGVsLmRlc2NyaXB0aW9uJzoge1xuICAgICAgaG9vazogJ2Rlc2NyaXB0aW9uJyxcbiAgICAgIHR5cGU6ICd0ZXh0J1xuICAgIH0sXG5cbiAgICAvLyBtYXRlcmlhbCBkZXNpZ24gaG9va3NcbiAgICAnbW9kZWwuaXNBY3RpdmUnOiBbXG4gICAgICB7XG4gICAgICAgIGhvb2s6ICdjYicsXG4gICAgICAgIHR5cGU6ICdib29sZWFuQXR0cmlidXRlJyxcbiAgICAgICAgbmFtZTogJ2NoZWNrZWQnXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgICAgaG9vazogJ3NldHRpbmdzJyxcbiAgICAgICAgaW52ZXJ0OiB0cnVlXG4gICAgICB9XG4gICAgXSxcbiAgICAnbW9kZWwuaWQnOiBbXG4gICAgICB7IGhvb2s6ICdjYicsIHR5cGU6ICdhdHRyaWJ1dGUnLCBuYW1lOiAnaWQnIH0sXG4gICAgICB7IGhvb2s6ICdjYmxhYmVsJywgdHlwZTogJ2F0dHJpYnV0ZScsIG5hbWU6ICdmb3InIH1cbiAgICBdXG4gIH0sXG4gIGV2ZW50czoge1xuICAgICdjaGFuZ2UnOiAndG9nZ2xlQWN0aXZlJyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349c2V0dGluZ3NdJzogZnVuY3Rpb24gKCkgeyBhcHAubmF2aWdhdGUoJy9kYXRhc2V0LycgKyB0aGlzLm1vZGVsLmlkKTsgfSxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349ZGVsZXRlXSc6ICdkZWxldGVEYXRhc2V0J1xuICB9LFxuICB0b2dnbGVBY3RpdmU6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgICB0aGF0LmJ1c3N5ID0gIXRoYXQuYnVzeTtcbiAgICBpZiAodGhhdC5tb2RlbC5mYWNldHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBBdXRvbWF0aWNhbGx5IHNjYW4gdGhlIGRhdGFzZXQgaWYgdGhlcmUgYXJlIG5vIGZhY2V0c1xuICAgICAgdGhhdC5tb2RlbC5zY2FuKCk7XG4gICAgICB0aGF0Lm1vZGVsLm9uY2UoJ3N5bmNGYWNldHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGFwcC5tZS50b2dnbGVEYXRhc2V0KHRoYXQubW9kZWwpO1xuICAgICAgICB0aGF0LmJ1c3N5ID0gIXRoYXQuYnVzc3k7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQlVHRklYOiB3ZSBjYW50IHNob3cvaGlkZSB0aGUgc3Bpbm5lciBmcm9tIHdpdGhpbiB0aGUgZXZlbnQgbG9vcDsgc29cbiAgICAgIC8vICAqIGFjdGl2YXRlIHRoZSBzcGlubmVyLFxuICAgICAgLy8gICogZXhpdCB0aGUgZXZlbnQgbG9vcCAoaWUuIHJlZHJhdyB0aGUgcGFnZSksXG4gICAgICAvLyAgKiBhbmQgdG9nZ2xlIHRoZSBkYXRhc2V0IHZpYSB0aGUgdGltZW91dFxuICAgICAgd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBhcHAubWUudG9nZ2xlRGF0YXNldCh0aGF0Lm1vZGVsKTtcbiAgICAgICAgdGhhdC5idXNzeSA9ICF0aGF0LmJ1c3N5O1xuICAgICAgfSwgNTAwKTtcbiAgICB9XG4gIH0sXG4gIGRlbGV0ZURhdGFzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5tb2RlbC5pc0FjdGl2ZSkge1xuICAgICAgdGhpcy5idXNzeSA9IHRydWU7XG4gICAgICBhcHAubWUudG9nZ2xlRGF0YXNldCh0aGlzLm1vZGVsKTtcbiAgICAgIHRoaXMuYnVzc3kgPSBmYWxzZTtcbiAgICB9XG4gICAgY29uc29sZS5sb2codGhpcy5tb2RlbCk7XG4gICAgYXBwLnJlbW92ZURhdGFzZXRGcm9tTG9jYWxTdG9yYWdlKHRoaXMubW9kZWwpO1xuICAgIGFwcC5tZS5kYXRhc2V0cy5yZW1vdmUodGhpcy5tb2RlbCk7XG4gIH0sXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVuZGVyV2l0aFRlbXBsYXRlKHRoaXMpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBREE7QUFRQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBSEE7QUFNQTtBQUNBO0FBQ0E7QUFIQTtBQU1BO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFIQTtBQU1BO0FBQ0E7QUFDQTtBQUhBO0FBTUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBekNBO0FBNENBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBaEdBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5eb6\n")},6339:function(module,exports,__webpack_require__){eval("/**\n * @classdesc Base class to hold configuration for charts. Extend and override properties for each chart.\n * @class BaseChart\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\nvar Slots = __webpack_require__(/*! ./slots */ \"e96a\");\n\nfunction titleForChart(chart) {\n  var title = '';\n  var aggregates = chart.filter.aggregates;\n\n  if (aggregates.length === 0) {\n    title = 'count';\n  } else {\n    aggregates.forEach(function (aggregate) {\n      title += aggregate.operation + ' of ' + aggregate.label;\n    });\n  }\n\n  title += ' by';\n  var partitions = chart.filter.partitions;\n  partitions.forEach(function (partition) {\n    title += ' ' + partition.facetName;\n  });\n  return title;\n}\n\nmodule.exports = AmpersandModel.extend({\n  collections: {\n    slots: Slots\n  },\n  session: {\n    /**\n     * Filter instance\n     * @memberof! Chart\n     * @type {Filter}\n     */\n    filter: ['any', true, false],\n\n    /**\n     * True if the charts is properly configured; ie. all required slots are filled.\n     */\n    isConfigured: ['boolean', true, false]\n  },\n  getTitle: function getTitle() {\n    return titleForChart(this);\n  },\n  updateConfiguration: function updateConfiguration() {\n    // without filter instance it cannot be configured\n    if (!this.filter) {\n      this.isConfigured = false;\n    }\n\n    var configured = true; // check if all required slots are filled\n\n    this.slots.forEach(function (slot) {\n      if (slot.required) {\n        if (slot.type === 'partition') {\n          if (!this.filter.partitions.get(slot.rank, 'rank')) {\n            configured = false;\n          }\n        } else if (slot.type === 'aggregate') {\n          if (!this.filter.aggregates.get(slot.rank, 'rank')) {\n            configured = false;\n          }\n        } else {\n          console.error('Illegal slot');\n          configured = false;\n        }\n      }\n    }, this);\n    this.isConfigured = configured;\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjMzOS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL21vZGVscy9iYXNlLWNoYXJ0LmpzPzM5MzIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAY2xhc3NkZXNjIEJhc2UgY2xhc3MgdG8gaG9sZCBjb25maWd1cmF0aW9uIGZvciBjaGFydHMuIEV4dGVuZCBhbmQgb3ZlcnJpZGUgcHJvcGVydGllcyBmb3IgZWFjaCBjaGFydC5cbiAqIEBjbGFzcyBCYXNlQ2hhcnRcbiAqL1xudmFyIEFtcGVyc2FuZE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG52YXIgU2xvdHMgPSByZXF1aXJlKCcuL3Nsb3RzJyk7XG5cbmZ1bmN0aW9uIHRpdGxlRm9yQ2hhcnQgKGNoYXJ0KSB7XG4gIHZhciB0aXRsZSA9ICcnO1xuXG4gIHZhciBhZ2dyZWdhdGVzID0gY2hhcnQuZmlsdGVyLmFnZ3JlZ2F0ZXM7XG4gIGlmIChhZ2dyZWdhdGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHRpdGxlID0gJ2NvdW50JztcbiAgfSBlbHNlIHtcbiAgICBhZ2dyZWdhdGVzLmZvckVhY2goZnVuY3Rpb24gKGFnZ3JlZ2F0ZSkge1xuICAgICAgdGl0bGUgKz0gYWdncmVnYXRlLm9wZXJhdGlvbiArICcgb2YgJyArIGFnZ3JlZ2F0ZS5sYWJlbDtcbiAgICB9KTtcbiAgfVxuXG4gIHRpdGxlICs9ICcgYnknO1xuXG4gIHZhciBwYXJ0aXRpb25zID0gY2hhcnQuZmlsdGVyLnBhcnRpdGlvbnM7XG4gIHBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uKSB7XG4gICAgdGl0bGUgKz0gJyAnICsgcGFydGl0aW9uLmZhY2V0TmFtZTtcbiAgfSk7XG4gIHJldHVybiB0aXRsZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBjb2xsZWN0aW9uczoge1xuICAgIHNsb3RzOiBTbG90c1xuICB9LFxuICBzZXNzaW9uOiB7XG4gICAgLyoqXG4gICAgICogRmlsdGVyIGluc3RhbmNlXG4gICAgICogQG1lbWJlcm9mISBDaGFydFxuICAgICAqIEB0eXBlIHtGaWx0ZXJ9XG4gICAgICovXG4gICAgZmlsdGVyOiBbJ2FueScsIHRydWUsIGZhbHNlXSxcbiAgICAvKipcbiAgICAgKiBUcnVlIGlmIHRoZSBjaGFydHMgaXMgcHJvcGVybHkgY29uZmlndXJlZDsgaWUuIGFsbCByZXF1aXJlZCBzbG90cyBhcmUgZmlsbGVkLlxuICAgICAqL1xuICAgIGlzQ29uZmlndXJlZDogWydib29sZWFuJywgdHJ1ZSwgZmFsc2VdXG4gIH0sXG4gIGdldFRpdGxlOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRpdGxlRm9yQ2hhcnQodGhpcyk7XG4gIH0sXG4gIHVwZGF0ZUNvbmZpZ3VyYXRpb246IGZ1bmN0aW9uICgpIHtcbiAgICAvLyB3aXRob3V0IGZpbHRlciBpbnN0YW5jZSBpdCBjYW5ub3QgYmUgY29uZmlndXJlZFxuICAgIGlmICghdGhpcy5maWx0ZXIpIHtcbiAgICAgIHRoaXMuaXNDb25maWd1cmVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIGNvbmZpZ3VyZWQgPSB0cnVlO1xuXG4gICAgLy8gY2hlY2sgaWYgYWxsIHJlcXVpcmVkIHNsb3RzIGFyZSBmaWxsZWRcbiAgICB0aGlzLnNsb3RzLmZvckVhY2goZnVuY3Rpb24gKHNsb3QpIHtcbiAgICAgIGlmIChzbG90LnJlcXVpcmVkKSB7XG4gICAgICAgIGlmIChzbG90LnR5cGUgPT09ICdwYXJ0aXRpb24nKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLmZpbHRlci5wYXJ0aXRpb25zLmdldChzbG90LnJhbmssICdyYW5rJykpIHtcbiAgICAgICAgICAgIGNvbmZpZ3VyZWQgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoc2xvdC50eXBlID09PSAnYWdncmVnYXRlJykge1xuICAgICAgICAgIGlmICghdGhpcy5maWx0ZXIuYWdncmVnYXRlcy5nZXQoc2xvdC5yYW5rLCAncmFuaycpKSB7XG4gICAgICAgICAgICBjb25maWd1cmVkID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0lsbGVnYWwgc2xvdCcpO1xuICAgICAgICAgIGNvbmZpZ3VyZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sIHRoaXMpO1xuXG4gICAgdGhpcy5pc0NvbmZpZ3VyZWQgPSBjb25maWd1cmVkO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7QUFJQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUFBOzs7QUFHQTtBQVZBO0FBWUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQTlDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6339\n")},6535:function(module,exports,__webpack_require__){eval("/**\n * @classdesc Extends the BaseChart class, and adds configuration.\n * @class BarChart\n * @augments BaseChart\n *\n */\nvar BaseChart = __webpack_require__(/*! ./base-chart */ \"6339\");\n\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nmodule.exports = BaseChart.extend({\n  initialize: function initialize() {\n    this.slots.reset([{\n      description: 'Group by',\n      type: 'partition',\n      rank: 1,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Subdivide by',\n      type: 'partition',\n      rank: 2,\n      required: false,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Bar height',\n      type: 'aggregate',\n      rank: 1,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }, {\n      description: 'Error bar',\n      type: 'aggregate',\n      rank: 2,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }]);\n  },\n  chartjsConfig: function chartjsConfig() {\n    return {\n      type: 'barError',\n      data: {\n        datasets: [],\n        labels: []\n      },\n      options: {\n        title: {\n          display: true,\n          position: 'top'\n        },\n        scales: {\n          xAxes: [{\n            stacked: true,\n            position: 'bottom',\n            scaleLabel: {\n              display: true,\n              labelString: ''\n            },\n            time: {\n              parser: function parser(label) {\n                return moment(label, moment.ISO_8601);\n              }\n            }\n          }],\n          yAxes: [{\n            stacked: true,\n            position: 'left',\n            scaleLabel: {\n              display: true,\n              labelString: ''\n            },\n            time: {\n              parser: function parser(label) {\n                return moment(label, moment.ISO_8601);\n              }\n            }\n          }]\n        },\n        tooltips: {},\n        errorCapWidth: 0.25\n      }\n    };\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjUzNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL21vZGVscy9iYXJjaGFydC5qcz84YmU0Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGNsYXNzZGVzYyBFeHRlbmRzIHRoZSBCYXNlQ2hhcnQgY2xhc3MsIGFuZCBhZGRzIGNvbmZpZ3VyYXRpb24uXG4gKiBAY2xhc3MgQmFyQ2hhcnRcbiAqIEBhdWdtZW50cyBCYXNlQ2hhcnRcbiAqXG4gKi9cbnZhciBCYXNlQ2hhcnQgPSByZXF1aXJlKCcuL2Jhc2UtY2hhcnQnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlQ2hhcnQuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc2xvdHMucmVzZXQoW1xuICAgICAge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ0dyb3VwIGJ5JyxcbiAgICAgICAgdHlwZTogJ3BhcnRpdGlvbicsXG4gICAgICAgIHJhbms6IDEsXG4gICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICBzdXBwb3J0ZWRGYWNldHM6IFsnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICdjb250aW51b3VzJywgJ3RleHQnXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdTdWJkaXZpZGUgYnknLFxuICAgICAgICB0eXBlOiAncGFydGl0aW9uJyxcbiAgICAgICAgcmFuazogMixcbiAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICBzdXBwb3J0ZWRGYWNldHM6IFsnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICdjb250aW51b3VzJywgJ3RleHQnXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdCYXIgaGVpZ2h0JyxcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIHJhbms6IDEsXG4gICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NvbnRpbnVvdXMnLCAnZHVyYXRpb24nXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdFcnJvciBiYXInLFxuICAgICAgICB0eXBlOiAnYWdncmVnYXRlJyxcbiAgICAgICAgcmFuazogMixcbiAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICBzdXBwb3J0ZWRGYWNldHM6IFsnY29udGludW91cycsICdkdXJhdGlvbiddXG4gICAgICB9XG4gICAgXSk7XG4gIH0sXG4gIGNoYXJ0anNDb25maWc6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ2JhckVycm9yJyxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgZGF0YXNldHM6IFtdLFxuICAgICAgICBsYWJlbHM6IFtdXG4gICAgICB9LFxuICAgICAgb3B0aW9uczoge1xuICAgICAgICB0aXRsZToge1xuICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgcG9zaXRpb246ICd0b3AnXG4gICAgICAgIH0sXG4gICAgICAgIHNjYWxlczoge1xuICAgICAgICAgIHhBeGVzOiBbe1xuICAgICAgICAgICAgc3RhY2tlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYm90dG9tJyxcbiAgICAgICAgICAgIHNjYWxlTGFiZWw6IHtcbiAgICAgICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICAgICAgbGFiZWxTdHJpbmc6ICcnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGltZToge1xuICAgICAgICAgICAgICBwYXJzZXI6IGZ1bmN0aW9uIChsYWJlbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtb21lbnQobGFiZWwsIG1vbWVudC5JU09fODYwMSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XSxcbiAgICAgICAgICB5QXhlczogW3tcbiAgICAgICAgICAgIHN0YWNrZWQ6IHRydWUsXG4gICAgICAgICAgICBwb3NpdGlvbjogJ2xlZnQnLFxuICAgICAgICAgICAgc2NhbGVMYWJlbDoge1xuICAgICAgICAgICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgICAgICAgICBsYWJlbFN0cmluZzogJydcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aW1lOiB7XG4gICAgICAgICAgICAgIHBhcnNlcjogZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1vbWVudChsYWJlbCwgbW9tZW50LklTT184NjAxKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1dXG4gICAgICAgIH0sXG4gICAgICAgIHRvb2x0aXBzOiB7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yQ2FwV2lkdGg6IDAuMjVcbiAgICAgIH1cbiAgICB9O1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztBQU1BO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQVBBO0FBYUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBUEE7QUFkQTtBQTRCQTtBQUVBO0FBbkNBO0FBTkE7QUE0Q0E7QUE5RUEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6535\n")},6668:function(module,exports,__webpack_require__){eval("var PageView = __webpack_require__(/*! ./base */ \"b966\");\n\nvar templates = __webpack_require__(/*! ../templates */ \"4324\");\n\nvar FacetDefineView = __webpack_require__(/*! ./configure-facet/facet-define */ \"b24e\");\n\nvar FacetTransformContinuousView = __webpack_require__(/*! ./configure-facet/facet-transform-continuous */ \"f77a\");\n\nvar FacetTransformCategorialView = __webpack_require__(/*! ./configure-facet/facet-transform-categorial */ \"96da\");\n\nvar FacetTransformDatetimeView = __webpack_require__(/*! ./configure-facet/facet-transform-datetime */ \"9ae5\");\n\nvar FacetTransformDurationView = __webpack_require__(/*! ./configure-facet/facet-transform-duration */ \"2960\");\n\nmodule.exports = PageView.extend({\n  initialize: function initialize() {\n    this.pageName = 'configureFacet';\n  },\n  template: templates.configureFacet.page,\n  bindings: {\n    'model.isCategorial': {\n      hook: 'transform-categorial-panel',\n      type: 'toggle'\n    },\n    'model.isContinuous': {\n      hook: 'transform-continuous-panel',\n      type: 'toggle'\n    },\n    'model.isDatetime': {\n      hook: 'transform-datetime-panel',\n      type: 'toggle'\n    },\n    'model.isDuration': {\n      hook: 'transform-duration-panel',\n      type: 'toggle'\n    }\n  },\n  subviews: {\n    facetDefine: {\n      hook: 'facet-define',\n      prepareView: function prepareView(el) {\n        return new FacetDefineView({\n          el: el,\n          model: this.model\n        });\n      }\n    },\n    transformContinuous: {\n      hook: 'facet-transform-continuous',\n      prepareView: function prepareView(el) {\n        return new FacetTransformContinuousView({\n          el: el,\n          model: this.model.continuousTransform\n        });\n      }\n    },\n    transformCategorial: {\n      hook: 'facet-transform-categorial',\n      prepareView: function prepareView(el) {\n        return new FacetTransformCategorialView({\n          el: el,\n          model: this.model.categorialTransform\n        });\n      }\n    },\n    transformDatetime: {\n      hook: 'facet-transform-datetime',\n      prepareView: function prepareView(el) {\n        return new FacetTransformDatetimeView({\n          el: el,\n          model: this.model.datetimeTransform\n        });\n      }\n    },\n    transformDuration: {\n      hook: 'facet-transform-duration',\n      prepareView: function prepareView(el) {\n        return new FacetTransformDurationView({\n          el: el,\n          model: this.model.durationTransform\n        });\n      }\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjY2OC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZmFjZXQuanM/NjA4OCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgUGFnZVZpZXcgPSByZXF1aXJlKCcuL2Jhc2UnKTtcbnZhciB0ZW1wbGF0ZXMgPSByZXF1aXJlKCcuLi90ZW1wbGF0ZXMnKTtcblxudmFyIEZhY2V0RGVmaW5lVmlldyA9IHJlcXVpcmUoJy4vY29uZmlndXJlLWZhY2V0L2ZhY2V0LWRlZmluZScpO1xuXG52YXIgRmFjZXRUcmFuc2Zvcm1Db250aW51b3VzVmlldyA9IHJlcXVpcmUoJy4vY29uZmlndXJlLWZhY2V0L2ZhY2V0LXRyYW5zZm9ybS1jb250aW51b3VzJyk7XG52YXIgRmFjZXRUcmFuc2Zvcm1DYXRlZ29yaWFsVmlldyA9IHJlcXVpcmUoJy4vY29uZmlndXJlLWZhY2V0L2ZhY2V0LXRyYW5zZm9ybS1jYXRlZ29yaWFsJyk7XG52YXIgRmFjZXRUcmFuc2Zvcm1EYXRldGltZVZpZXcgPSByZXF1aXJlKCcuL2NvbmZpZ3VyZS1mYWNldC9mYWNldC10cmFuc2Zvcm0tZGF0ZXRpbWUnKTtcbnZhciBGYWNldFRyYW5zZm9ybUR1cmF0aW9uVmlldyA9IHJlcXVpcmUoJy4vY29uZmlndXJlLWZhY2V0L2ZhY2V0LXRyYW5zZm9ybS1kdXJhdGlvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBhZ2VWaWV3LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnBhZ2VOYW1lID0gJ2NvbmZpZ3VyZUZhY2V0JztcbiAgfSxcbiAgdGVtcGxhdGU6IHRlbXBsYXRlcy5jb25maWd1cmVGYWNldC5wYWdlLFxuICBiaW5kaW5nczoge1xuICAgICdtb2RlbC5pc0NhdGVnb3JpYWwnOiB7XG4gICAgICBob29rOiAndHJhbnNmb3JtLWNhdGVnb3JpYWwtcGFuZWwnLFxuICAgICAgdHlwZTogJ3RvZ2dsZSdcbiAgICB9LFxuICAgICdtb2RlbC5pc0NvbnRpbnVvdXMnOiB7XG4gICAgICBob29rOiAndHJhbnNmb3JtLWNvbnRpbnVvdXMtcGFuZWwnLFxuICAgICAgdHlwZTogJ3RvZ2dsZSdcbiAgICB9LFxuICAgICdtb2RlbC5pc0RhdGV0aW1lJzoge1xuICAgICAgaG9vazogJ3RyYW5zZm9ybS1kYXRldGltZS1wYW5lbCcsXG4gICAgICB0eXBlOiAndG9nZ2xlJ1xuICAgIH0sXG4gICAgJ21vZGVsLmlzRHVyYXRpb24nOiB7XG4gICAgICBob29rOiAndHJhbnNmb3JtLWR1cmF0aW9uLXBhbmVsJyxcbiAgICAgIHR5cGU6ICd0b2dnbGUnXG4gICAgfVxuICB9LFxuICBzdWJ2aWV3czoge1xuICAgIGZhY2V0RGVmaW5lOiB7XG4gICAgICBob29rOiAnZmFjZXQtZGVmaW5lJyxcbiAgICAgIHByZXBhcmVWaWV3OiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGYWNldERlZmluZVZpZXcoe1xuICAgICAgICAgIGVsOiBlbCxcbiAgICAgICAgICBtb2RlbDogdGhpcy5tb2RlbFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9LFxuICAgIHRyYW5zZm9ybUNvbnRpbnVvdXM6IHtcbiAgICAgIGhvb2s6ICdmYWNldC10cmFuc2Zvcm0tY29udGludW91cycsXG4gICAgICBwcmVwYXJlVmlldzogZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgIHJldHVybiBuZXcgRmFjZXRUcmFuc2Zvcm1Db250aW51b3VzVmlldyh7XG4gICAgICAgICAgZWw6IGVsLFxuICAgICAgICAgIG1vZGVsOiB0aGlzLm1vZGVsLmNvbnRpbnVvdXNUcmFuc2Zvcm1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgICB0cmFuc2Zvcm1DYXRlZ29yaWFsOiB7XG4gICAgICBob29rOiAnZmFjZXQtdHJhbnNmb3JtLWNhdGVnb3JpYWwnLFxuICAgICAgcHJlcGFyZVZpZXc6IGZ1bmN0aW9uIChlbCkge1xuICAgICAgICByZXR1cm4gbmV3IEZhY2V0VHJhbnNmb3JtQ2F0ZWdvcmlhbFZpZXcoe1xuICAgICAgICAgIGVsOiBlbCxcbiAgICAgICAgICBtb2RlbDogdGhpcy5tb2RlbC5jYXRlZ29yaWFsVHJhbnNmb3JtXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG4gICAgdHJhbnNmb3JtRGF0ZXRpbWU6IHtcbiAgICAgIGhvb2s6ICdmYWNldC10cmFuc2Zvcm0tZGF0ZXRpbWUnLFxuICAgICAgcHJlcGFyZVZpZXc6IGZ1bmN0aW9uIChlbCkge1xuICAgICAgICByZXR1cm4gbmV3IEZhY2V0VHJhbnNmb3JtRGF0ZXRpbWVWaWV3KHtcbiAgICAgICAgICBlbDogZWwsXG4gICAgICAgICAgbW9kZWw6IHRoaXMubW9kZWwuZGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgICB0cmFuc2Zvcm1EdXJhdGlvbjoge1xuICAgICAgaG9vazogJ2ZhY2V0LXRyYW5zZm9ybS1kdXJhdGlvbicsXG4gICAgICBwcmVwYXJlVmlldzogZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgIHJldHVybiBuZXcgRmFjZXRUcmFuc2Zvcm1EdXJhdGlvblZpZXcoe1xuICAgICAgICAgIGVsOiBlbCxcbiAgICAgICAgICBtb2RlbDogdGhpcy5tb2RlbC5kdXJhdGlvblRyYW5zZm9ybVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRkE7QUFiQTtBQWtCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFQQTtBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFQQTtBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFQQTtBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFQQTtBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFQQTtBQXJDQTtBQXZCQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6668\n")},"6b2d":function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar $ = __webpack_require__(/*! jquery */ \"802c\");\n\nmodule.exports = View.extend({\n  template: templates.analyze.facetbarItem,\n  bindings: {\n    'model.name': '[data-hook~=\"facet-bar-item-button\"]',\n    'model.id': {\n      type: 'attribute',\n      hook: 'facet-bar-item',\n      name: 'data-id'\n    }\n  },\n  events: {\n    'click [data-hook~=facet-bar-item-button]': 'editFacet',\n    'mouseenter': 'enter',\n    'dragstart': 'dragStart',\n    'dragend': 'dragEnd'\n  },\n  editFacet: function editFacet() {\n    if (!app.me.isLockedDown) {\n      app.navigate('facet/' + this.model.id);\n    }\n  },\n  enter: function enter(e) {\n    var tip = document.getElementById('facet-bar-tooltip');\n\n    if (tip) {\n      tip.innerHTML = this.model.description; // Position the tooltip below the mouse pointer\n\n      $('#facet-bar-tooltip').css('left', e.pageX);\n    }\n  },\n  dragStart: function dragStart(e) {\n    var tip = document.getElementById('facet-bar-tooltip');\n    tip.classList.remove('is-active');\n  },\n  dragEnd: function dragEnd(e) {\n    var tip = document.getElementById('facet-bar-tooltip');\n    tip.classList.add('is-active');\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNmIyZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9hbmFseXplL2ZhY2V0YmFyLWl0ZW0uanM/NWMzZiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgVmlldyA9IHJlcXVpcmUoJ2FtcGVyc2FuZC12aWV3Jyk7XG52YXIgdGVtcGxhdGVzID0gcmVxdWlyZSgnLi4vLi4vdGVtcGxhdGVzJyk7XG52YXIgYXBwID0gcmVxdWlyZSgnYW1wZXJzYW5kLWFwcCcpO1xudmFyICQgPSByZXF1aXJlKCdqcXVlcnknKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMuYW5hbHl6ZS5mYWNldGJhckl0ZW0sXG4gIGJpbmRpbmdzOiB7XG4gICAgJ21vZGVsLm5hbWUnOiAnW2RhdGEtaG9va349XCJmYWNldC1iYXItaXRlbS1idXR0b25cIl0nLFxuICAgICdtb2RlbC5pZCc6IHtcbiAgICAgIHR5cGU6ICdhdHRyaWJ1dGUnLFxuICAgICAgaG9vazogJ2ZhY2V0LWJhci1pdGVtJyxcbiAgICAgIG5hbWU6ICdkYXRhLWlkJ1xuICAgIH1cbiAgfSxcbiAgZXZlbnRzOiB7XG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWZhY2V0LWJhci1pdGVtLWJ1dHRvbl0nOiAnZWRpdEZhY2V0JyxcbiAgICAnbW91c2VlbnRlcic6ICdlbnRlcicsXG4gICAgJ2RyYWdzdGFydCc6ICdkcmFnU3RhcnQnLFxuICAgICdkcmFnZW5kJzogJ2RyYWdFbmQnXG4gIH0sXG4gIGVkaXRGYWNldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICghYXBwLm1lLmlzTG9ja2VkRG93bikge1xuICAgICAgYXBwLm5hdmlnYXRlKCdmYWNldC8nICsgdGhpcy5tb2RlbC5pZCk7XG4gICAgfVxuICB9LFxuICBlbnRlcjogZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgdGlwID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZhY2V0LWJhci10b29sdGlwJyk7XG4gICAgaWYgKHRpcCkge1xuICAgICAgdGlwLmlubmVySFRNTCA9IHRoaXMubW9kZWwuZGVzY3JpcHRpb247XG4gICAgICAvLyBQb3NpdGlvbiB0aGUgdG9vbHRpcCBiZWxvdyB0aGUgbW91c2UgcG9pbnRlclxuICAgICAgJCgnI2ZhY2V0LWJhci10b29sdGlwJykuY3NzKCdsZWZ0JywgZS5wYWdlWCk7XG4gICAgfVxuICB9LFxuICBkcmFnU3RhcnQ6IGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIHRpcCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmYWNldC1iYXItdG9vbHRpcCcpO1xuICAgIHRpcC5jbGFzc0xpc3QucmVtb3ZlKCdpcy1hY3RpdmUnKTtcbiAgfSxcbiAgZHJhZ0VuZDogZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgdGlwID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZhY2V0LWJhci10b29sdGlwJyk7XG4gICAgdGlwLmNsYXNzTGlzdC5hZGQoJ2lzLWFjdGl2ZScpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUZBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFwQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6b2d\n")},"6d22":function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nmodule.exports = View.extend({\n  template: templates.configurePartition.partitionContinuous,\n  bindings: {\n    'model.isContinuous': {\n      type: 'toggle',\n      hook: 'group-continuous-panel'\n    },\n    'model.minval': {\n      type: 'value',\n      hook: 'group-minimum-input'\n    },\n    'model.maxval': {\n      type: 'value',\n      hook: 'group-maximum-input'\n    },\n    'model.groupingParam': {\n      type: 'value',\n      hook: 'group-param-input'\n    },\n    'model.groupFixedN': {\n      type: 'booleanAttribute',\n      hook: 'group-fixedn-input',\n      name: 'checked'\n    },\n    'model.groupFixedSC': {\n      type: 'booleanAttribute',\n      hook: 'group-fixedsc-input',\n      name: 'checked'\n    },\n    'model.groupFixedS': {\n      type: 'booleanAttribute',\n      hook: 'group-fixeds-input',\n      name: 'checked'\n    },\n    'model.groupLog': {\n      type: 'booleanAttribute',\n      hook: 'group-log-input',\n      name: 'checked'\n    }\n  },\n  events: {\n    'change [data-hook~=group-minimum-input]': function changeDataHookGroupMinimumInput() {\n      this.model.minval = parseInt(this.queryByHook('group-minimum-input').value);\n      this.parent.resetFilter = true;\n    },\n    'change [data-hook~=group-maximum-input]': function changeDataHookGroupMaximumInput() {\n      this.model.maxval = parseInt(this.queryByHook('group-maximum-input').value);\n      this.parent.resetFilter = true;\n    },\n    'click [data-hook~=group-range-button]': function clickDataHookGroupRangeButton() {\n      var partition = this.model;\n      partition.reset();\n      this.queryByHook('group-minimum-input').dispatchEvent(new window.Event('input'));\n      this.queryByHook('group-maximum-input').dispatchEvent(new window.Event('input'));\n      this.parent.resetFilter = true;\n    },\n    'change [data-hook~=group-param-input]': function changeDataHookGroupParamInput() {\n      this.model.groupingParam = parseInt(this.queryByHook('group-param-input').value);\n      this.parent.resetFilter = true;\n    },\n    'click [data-hook~=group-fixedn-input]': function clickDataHookGroupFixednInput() {\n      this.model.groupingContinuous = 'fixedn';\n      this.parent.resetFilter = true;\n    },\n    'click [data-hook~=group-fixedsc-input]': function clickDataHookGroupFixedscInput() {\n      this.model.groupingContinuous = 'fixedsc';\n      this.parent.resetFilter = true;\n    },\n    'click [data-hook~=group-fixeds-input]': function clickDataHookGroupFixedsInput() {\n      this.model.groupingContinuous = 'fixeds';\n      this.parent.resetFilter = true;\n    },\n    'click [data-hook~=group-log-input]': function clickDataHookGroupLogInput() {\n      this.model.groupingContinuous = 'log';\n      this.parent.resetFilter = true;\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNmQyMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtcGFydGl0aW9uL3BhcnRpdGlvbi1jb250aW51b3VzLmpzPzU4MDIiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL3RlbXBsYXRlcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZXcuZXh0ZW5kKHtcbiAgdGVtcGxhdGU6IHRlbXBsYXRlcy5jb25maWd1cmVQYXJ0aXRpb24ucGFydGl0aW9uQ29udGludW91cyxcbiAgYmluZGluZ3M6IHtcbiAgICAnbW9kZWwuaXNDb250aW51b3VzJzoge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBob29rOiAnZ3JvdXAtY29udGludW91cy1wYW5lbCdcbiAgICB9LFxuXG4gICAgJ21vZGVsLm1pbnZhbCc6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAnZ3JvdXAtbWluaW11bS1pbnB1dCdcbiAgICB9LFxuICAgICdtb2RlbC5tYXh2YWwnOiB7XG4gICAgICB0eXBlOiAndmFsdWUnLFxuICAgICAgaG9vazogJ2dyb3VwLW1heGltdW0taW5wdXQnXG4gICAgfSxcbiAgICAnbW9kZWwuZ3JvdXBpbmdQYXJhbSc6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAnZ3JvdXAtcGFyYW0taW5wdXQnXG4gICAgfSxcbiAgICAnbW9kZWwuZ3JvdXBGaXhlZE4nOiB7XG4gICAgICB0eXBlOiAnYm9vbGVhbkF0dHJpYnV0ZScsXG4gICAgICBob29rOiAnZ3JvdXAtZml4ZWRuLWlucHV0JyxcbiAgICAgIG5hbWU6ICdjaGVja2VkJ1xuICAgIH0sXG4gICAgJ21vZGVsLmdyb3VwRml4ZWRTQyc6IHtcbiAgICAgIHR5cGU6ICdib29sZWFuQXR0cmlidXRlJyxcbiAgICAgIGhvb2s6ICdncm91cC1maXhlZHNjLWlucHV0JyxcbiAgICAgIG5hbWU6ICdjaGVja2VkJ1xuICAgIH0sXG4gICAgJ21vZGVsLmdyb3VwRml4ZWRTJzoge1xuICAgICAgdHlwZTogJ2Jvb2xlYW5BdHRyaWJ1dGUnLFxuICAgICAgaG9vazogJ2dyb3VwLWZpeGVkcy1pbnB1dCcsXG4gICAgICBuYW1lOiAnY2hlY2tlZCdcbiAgICB9LFxuICAgICdtb2RlbC5ncm91cExvZyc6IHtcbiAgICAgIHR5cGU6ICdib29sZWFuQXR0cmlidXRlJyxcbiAgICAgIGhvb2s6ICdncm91cC1sb2ctaW5wdXQnLFxuICAgICAgbmFtZTogJ2NoZWNrZWQnXG4gICAgfVxuICB9LFxuICBldmVudHM6IHtcbiAgICAnY2hhbmdlIFtkYXRhLWhvb2t+PWdyb3VwLW1pbmltdW0taW5wdXRdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC5taW52YWwgPSBwYXJzZUludCh0aGlzLnF1ZXJ5QnlIb29rKCdncm91cC1taW5pbXVtLWlucHV0JykudmFsdWUpO1xuICAgICAgdGhpcy5wYXJlbnQucmVzZXRGaWx0ZXIgPSB0cnVlO1xuICAgIH0sXG4gICAgJ2NoYW5nZSBbZGF0YS1ob29rfj1ncm91cC1tYXhpbXVtLWlucHV0XSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwubWF4dmFsID0gcGFyc2VJbnQodGhpcy5xdWVyeUJ5SG9vaygnZ3JvdXAtbWF4aW11bS1pbnB1dCcpLnZhbHVlKTtcbiAgICAgIHRoaXMucGFyZW50LnJlc2V0RmlsdGVyID0gdHJ1ZTtcbiAgICB9LFxuICAgICdjbGljayBbZGF0YS1ob29rfj1ncm91cC1yYW5nZS1idXR0b25dJzogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHBhcnRpdGlvbiA9IHRoaXMubW9kZWw7XG4gICAgICBwYXJ0aXRpb24ucmVzZXQoKTtcblxuICAgICAgdGhpcy5xdWVyeUJ5SG9vaygnZ3JvdXAtbWluaW11bS1pbnB1dCcpLmRpc3BhdGNoRXZlbnQobmV3IHdpbmRvdy5FdmVudCgnaW5wdXQnKSk7XG4gICAgICB0aGlzLnF1ZXJ5QnlIb29rKCdncm91cC1tYXhpbXVtLWlucHV0JykuZGlzcGF0Y2hFdmVudChuZXcgd2luZG93LkV2ZW50KCdpbnB1dCcpKTtcbiAgICAgIHRoaXMucGFyZW50LnJlc2V0RmlsdGVyID0gdHJ1ZTtcbiAgICB9LFxuXG4gICAgJ2NoYW5nZSBbZGF0YS1ob29rfj1ncm91cC1wYXJhbS1pbnB1dF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLmdyb3VwaW5nUGFyYW0gPSBwYXJzZUludCh0aGlzLnF1ZXJ5QnlIb29rKCdncm91cC1wYXJhbS1pbnB1dCcpLnZhbHVlKTtcbiAgICAgIHRoaXMucGFyZW50LnJlc2V0RmlsdGVyID0gdHJ1ZTtcbiAgICB9LFxuICAgICdjbGljayBbZGF0YS1ob29rfj1ncm91cC1maXhlZG4taW5wdXRdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC5ncm91cGluZ0NvbnRpbnVvdXMgPSAnZml4ZWRuJztcbiAgICAgIHRoaXMucGFyZW50LnJlc2V0RmlsdGVyID0gdHJ1ZTtcbiAgICB9LFxuICAgICdjbGljayBbZGF0YS1ob29rfj1ncm91cC1maXhlZHNjLWlucHV0XSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwuZ3JvdXBpbmdDb250aW51b3VzID0gJ2ZpeGVkc2MnO1xuICAgICAgdGhpcy5wYXJlbnQucmVzZXRGaWx0ZXIgPSB0cnVlO1xuICAgIH0sXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWdyb3VwLWZpeGVkcy1pbnB1dF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLmdyb3VwaW5nQ29udGludW91cyA9ICdmaXhlZHMnO1xuICAgICAgdGhpcy5wYXJlbnQucmVzZXRGaWx0ZXIgPSB0cnVlO1xuICAgIH0sXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWdyb3VwLWxvZy1pbnB1dF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLmdyb3VwaW5nQ29udGludW91cyA9ICdsb2cnO1xuICAgICAgdGhpcy5wYXJlbnQucmVzZXRGaWx0ZXIgPSB0cnVlO1xuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBakNBO0FBdUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQXJDQTtBQXpDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6d22\n")},"701f":function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nmodule.exports = View.extend({\n  template: templates.configureDataset.facet,\n  initialize: function initialize() {\n    this.isLockedDown = app.me.isLockedDown;\n  },\n  render: function render() {\n    this.renderWithTemplate(this);\n    window.componentHandler.upgradeDom(this.el);\n    return this;\n  },\n  session: {\n    'isLockedDown': 'boolean'\n  },\n  bindings: {\n    'isLockedDown': {\n      type: 'toggle',\n      hook: 'actions',\n      invert: 'yes'\n    },\n    'model.name': '[data-hook~=name]',\n    'model.description': '[data-hook~=description]',\n    'model.show': {\n      type: 'toggle',\n      hook: 'fullitem'\n    },\n    //    'model.isCategorial': {\n    //      type: 'booleanClass',\n    //      hook: 'typeIcon',\n    //      name: 'facetCategorialIcon'\n    //    },\n    //    'model.isContinuous': {\n    //      type: 'booleanClass',\n    //      hook: 'typeIcon',\n    //      name: 'facetContinuousIcon'\n    // },\n    //    'model.isDatetime': {\n    //      type: 'booleanClass',\n    //      hook: 'typeIcon',\n    //      name: 'facetDatetimeIcon'\n    //    },\n    //    'model.isDuration': {\n    //      type: 'booleanClass',\n    //      hook: 'typeIcon',\n    //      name: 'facetDurationIcon'\n    //    },\n    //    'model.isText': {\n    //      type: 'booleanClass',\n    //      hook: 'typeIcon',\n    //      name: 'facetTextIcon'\n    //    }\n    // material design hooks\n    'model.id': [{\n      hook: 'cb',\n      type: 'attribute',\n      name: 'id'\n    }, {\n      hook: 'cblabel',\n      type: 'attribute',\n      name: 'for'\n    }],\n    'model.isActive': {\n      hook: 'cb',\n      type: 'booleanAttribute',\n      name: 'checked'\n    }\n  },\n  events: {\n    'change': 'togglePower',\n    'click [data-hook~=configureFacet]': 'configureFacet',\n    'click [data-hook~=removeFacet]': 'removeFacet',\n    'click [data-hook~=duplicateFacet]': 'duplicateFacet'\n  },\n  togglePower: function togglePower(ev) {\n    this.model.isActive = !this.model.isActive;\n\n    if (this.model.isCategorial) {\n      this.model.setCategories();\n    } else if (this.model.isContinuous || this.model.isDatetime || this.model.isDuration) {\n      this.model.setMinMax();\n    }\n  },\n  configureFacet: function configureFacet(ev) {\n    app.navigate('facet/' + this.model.id);\n  },\n  removeFacet: function removeFacet(ev) {\n    this.collection.remove(this.model);\n  },\n  duplicateFacet: function duplicateFacet(ev) {\n    // make a copy with new name and id\n    var duplicateFacet = this.model.toJSON();\n    duplicateFacet.name += ' copy';\n    delete duplicateFacet.id;\n    this.collection.add(duplicateFacet);\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzAxZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZGF0YXNldC9mYWNldC1jb2xsZWN0aW9uLmpzPzBjOTEiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL3RlbXBsYXRlcycpO1xudmFyIGFwcCA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1hcHAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMuY29uZmlndXJlRGF0YXNldC5mYWNldCxcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuaXNMb2NrZWREb3duID0gYXBwLm1lLmlzTG9ja2VkRG93bjtcbiAgfSxcbiAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZW5kZXJXaXRoVGVtcGxhdGUodGhpcyk7XG4gICAgd2luZG93LmNvbXBvbmVudEhhbmRsZXIudXBncmFkZURvbSh0aGlzLmVsKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgc2Vzc2lvbjoge1xuICAgICdpc0xvY2tlZERvd24nOiAnYm9vbGVhbidcbiAgfSxcbiAgYmluZGluZ3M6IHtcbiAgICAnaXNMb2NrZWREb3duJzoge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBob29rOiAnYWN0aW9ucycsXG4gICAgICBpbnZlcnQ6ICd5ZXMnXG4gICAgfSxcbiAgICAnbW9kZWwubmFtZSc6ICdbZGF0YS1ob29rfj1uYW1lXScsXG4gICAgJ21vZGVsLmRlc2NyaXB0aW9uJzogJ1tkYXRhLWhvb2t+PWRlc2NyaXB0aW9uXScsXG4gICAgJ21vZGVsLnNob3cnOiB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIGhvb2s6ICdmdWxsaXRlbSdcbiAgICB9LFxuLy8gICAgJ21vZGVsLmlzQ2F0ZWdvcmlhbCc6IHtcbi8vICAgICAgdHlwZTogJ2Jvb2xlYW5DbGFzcycsXG4vLyAgICAgIGhvb2s6ICd0eXBlSWNvbicsXG4vLyAgICAgIG5hbWU6ICdmYWNldENhdGVnb3JpYWxJY29uJ1xuLy8gICAgfSxcbi8vICAgICdtb2RlbC5pc0NvbnRpbnVvdXMnOiB7XG4vLyAgICAgIHR5cGU6ICdib29sZWFuQ2xhc3MnLFxuLy8gICAgICBob29rOiAndHlwZUljb24nLFxuLy8gICAgICBuYW1lOiAnZmFjZXRDb250aW51b3VzSWNvbidcbi8vIH0sXG4vLyAgICAnbW9kZWwuaXNEYXRldGltZSc6IHtcbi8vICAgICAgdHlwZTogJ2Jvb2xlYW5DbGFzcycsXG4vLyAgICAgIGhvb2s6ICd0eXBlSWNvbicsXG4vLyAgICAgIG5hbWU6ICdmYWNldERhdGV0aW1lSWNvbidcbi8vICAgIH0sXG4vLyAgICAnbW9kZWwuaXNEdXJhdGlvbic6IHtcbi8vICAgICAgdHlwZTogJ2Jvb2xlYW5DbGFzcycsXG4vLyAgICAgIGhvb2s6ICd0eXBlSWNvbicsXG4vLyAgICAgIG5hbWU6ICdmYWNldER1cmF0aW9uSWNvbidcbi8vICAgIH0sXG4vLyAgICAnbW9kZWwuaXNUZXh0Jzoge1xuLy8gICAgICB0eXBlOiAnYm9vbGVhbkNsYXNzJyxcbi8vICAgICAgaG9vazogJ3R5cGVJY29uJyxcbi8vICAgICAgbmFtZTogJ2ZhY2V0VGV4dEljb24nXG4vLyAgICB9XG4gICAgLy8gbWF0ZXJpYWwgZGVzaWduIGhvb2tzXG4gICAgJ21vZGVsLmlkJzogW1xuICAgICAgeyBob29rOiAnY2InLCB0eXBlOiAnYXR0cmlidXRlJywgbmFtZTogJ2lkJyB9LFxuICAgICAgeyBob29rOiAnY2JsYWJlbCcsIHR5cGU6ICdhdHRyaWJ1dGUnLCBuYW1lOiAnZm9yJyB9XG4gICAgXSxcbiAgICAnbW9kZWwuaXNBY3RpdmUnOiB7XG4gICAgICBob29rOiAnY2InLFxuICAgICAgdHlwZTogJ2Jvb2xlYW5BdHRyaWJ1dGUnLFxuICAgICAgbmFtZTogJ2NoZWNrZWQnXG4gICAgfVxuICB9LFxuICBldmVudHM6IHtcbiAgICAnY2hhbmdlJzogJ3RvZ2dsZVBvd2VyJyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349Y29uZmlndXJlRmFjZXRdJzogJ2NvbmZpZ3VyZUZhY2V0JyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349cmVtb3ZlRmFjZXRdJzogJ3JlbW92ZUZhY2V0JyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349ZHVwbGljYXRlRmFjZXRdJzogJ2R1cGxpY2F0ZUZhY2V0J1xuICB9LFxuICB0b2dnbGVQb3dlcjogZnVuY3Rpb24gKGV2KSB7XG4gICAgdGhpcy5tb2RlbC5pc0FjdGl2ZSA9ICF0aGlzLm1vZGVsLmlzQWN0aXZlO1xuXG4gICAgaWYgKHRoaXMubW9kZWwuaXNDYXRlZ29yaWFsKSB7XG4gICAgICB0aGlzLm1vZGVsLnNldENhdGVnb3JpZXMoKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZWwuaXNDb250aW51b3VzIHx8IHRoaXMubW9kZWwuaXNEYXRldGltZSB8fCB0aGlzLm1vZGVsLmlzRHVyYXRpb24pIHtcbiAgICAgIHRoaXMubW9kZWwuc2V0TWluTWF4KCk7XG4gICAgfVxuICB9LFxuICBjb25maWd1cmVGYWNldDogZnVuY3Rpb24gKGV2KSB7XG4gICAgYXBwLm5hdmlnYXRlKCdmYWNldC8nICsgdGhpcy5tb2RlbC5pZCk7XG4gIH0sXG4gIHJlbW92ZUZhY2V0OiBmdW5jdGlvbiAoZXYpIHtcbiAgICB0aGlzLmNvbGxlY3Rpb24ucmVtb3ZlKHRoaXMubW9kZWwpO1xuICB9LFxuICBkdXBsaWNhdGVGYWNldDogZnVuY3Rpb24gKGV2KSB7XG4gICAgLy8gbWFrZSBhIGNvcHkgd2l0aCBuZXcgbmFtZSBhbmQgaWRcbiAgICB2YXIgZHVwbGljYXRlRmFjZXQgPSB0aGlzLm1vZGVsLnRvSlNPTigpO1xuICAgIGR1cGxpY2F0ZUZhY2V0Lm5hbWUgKz0gJyBjb3B5JztcbiAgICBkZWxldGUgZHVwbGljYXRlRmFjZXQuaWQ7XG5cbiAgICB0aGlzLmNvbGxlY3Rpb24uYWRkKGR1cGxpY2F0ZUZhY2V0KTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUExQ0E7QUFnREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUF6RkEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///701f\n")},"71a3":function(module,exports,__webpack_require__){eval("/**\n * @classdesc bubble plot class\n * @class BubblePlot\n * @augments BaseChart\n */\nvar BaseChart = __webpack_require__(/*! ./base-chart */ \"6339\");\n\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nfunction ttLabel(tooltip, data) {\n  var point = data.datasets[tooltip.datasetIndex].data[tooltip.index];\n  var axes = data.datasets[0].spotAxes;\n  var label = [axes.x + ': ' + point.a, axes.y + ': ' + point.b];\n\n  if (axes.r) {\n    label.push('radius (' + axes.r + ') ' + point.bb);\n  }\n\n  if (axes.c) {\n    label.push('color (' + axes.c + ' ) ' + point.aa);\n  }\n\n  label.push('Number of points in bin ' + point.count);\n  return label;\n}\n\nmodule.exports = BaseChart.extend({\n  initialize: function initialize() {\n    this.slots.reset([{\n      description: 'X axis',\n      type: 'partition',\n      rank: 1,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Y axis',\n      type: 'partition',\n      rank: 2,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Point color',\n      type: 'aggregate',\n      rank: 1,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }, {\n      description: 'Point size',\n      type: 'aggregate',\n      rank: 2,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }, {\n      description: 'X error',\n      type: 'aggregate',\n      rank: 3,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }, {\n      description: 'Y error',\n      type: 'aggregate',\n      rank: 4,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }]);\n  },\n  chartjsConfig: function chartjsConfig() {\n    return {\n      type: 'bubbleError',\n      data: {\n        datasets: []\n      },\n      options: {\n        animation: false,\n        title: {\n          display: true,\n          position: 'top'\n        },\n        legend: {\n          display: false\n        },\n        scales: {\n          xAxes: [{\n            type: 'linear',\n            position: 'bottom',\n            gridLines: {\n              zeroLineColor: 'rgba(0,255,0,1)'\n            },\n            scaleLabel: {\n              display: true\n            },\n            time: {\n              parser: function parser(label) {\n                return moment(label, moment.ISO_8601);\n              }\n            }\n          }],\n          yAxes: [{\n            type: 'linear',\n            position: 'left',\n            gridLines: {\n              zeroLineColor: 'rgba(0,255,0,1)'\n            },\n            scaleLabel: {\n              display: true\n            },\n            time: {\n              parser: function parser(label) {\n                return moment(label, moment.ISO_8601);\n              }\n            }\n          }]\n        },\n        tooltips: {\n          enabled: true,\n          mode: 'single',\n          callbacks: {\n            label: ttLabel\n          }\n        }\n      }\n    };\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzFhMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL21vZGVscy9idWJibGVwbG90LmpzPzY4NzIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAY2xhc3NkZXNjIGJ1YmJsZSBwbG90IGNsYXNzXG4gKiBAY2xhc3MgQnViYmxlUGxvdFxuICogQGF1Z21lbnRzIEJhc2VDaGFydFxuICovXG5cbnZhciBCYXNlQ2hhcnQgPSByZXF1aXJlKCcuL2Jhc2UtY2hhcnQnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcblxuZnVuY3Rpb24gdHRMYWJlbCAodG9vbHRpcCwgZGF0YSkge1xuICB2YXIgcG9pbnQgPSBkYXRhLmRhdGFzZXRzW3Rvb2x0aXAuZGF0YXNldEluZGV4XS5kYXRhW3Rvb2x0aXAuaW5kZXhdO1xuICB2YXIgYXhlcyA9IGRhdGEuZGF0YXNldHNbMF0uc3BvdEF4ZXM7XG5cbiAgdmFyIGxhYmVsID0gW1xuICAgIGF4ZXMueCArICc6ICcgKyBwb2ludC5hLFxuICAgIGF4ZXMueSArICc6ICcgKyBwb2ludC5iXG4gIF07XG4gIGlmIChheGVzLnIpIHtcbiAgICBsYWJlbC5wdXNoKCdyYWRpdXMgKCcgKyBheGVzLnIgKyAnKSAnICsgcG9pbnQuYmIpO1xuICB9XG4gIGlmIChheGVzLmMpIHtcbiAgICBsYWJlbC5wdXNoKCdjb2xvciAoJyArIGF4ZXMuYyArICcgKSAnICsgcG9pbnQuYWEpO1xuICB9XG4gIGxhYmVsLnB1c2goJ051bWJlciBvZiBwb2ludHMgaW4gYmluICcgKyBwb2ludC5jb3VudCk7XG4gIHJldHVybiBsYWJlbDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlQ2hhcnQuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc2xvdHMucmVzZXQoW1xuICAgICAge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1ggYXhpcycsXG4gICAgICAgIHR5cGU6ICdwYXJ0aXRpb24nLFxuICAgICAgICByYW5rOiAxLFxuICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NhdGVnb3JpYWwnLCAnZGF0ZXRpbWUnLCAnZHVyYXRpb24nLCAnY29udGludW91cycsICd0ZXh0J11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnWSBheGlzJyxcbiAgICAgICAgdHlwZTogJ3BhcnRpdGlvbicsXG4gICAgICAgIHJhbms6IDIsXG4gICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICBzdXBwb3J0ZWRGYWNldHM6IFsnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICdjb250aW51b3VzJywgJ3RleHQnXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdQb2ludCBjb2xvcicsXG4gICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICByYW5rOiAxLFxuICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIHN1cHBvcnRlZEZhY2V0czogWydjb250aW51b3VzJywgJ2R1cmF0aW9uJ11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnUG9pbnQgc2l6ZScsXG4gICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICByYW5rOiAyLFxuICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIHN1cHBvcnRlZEZhY2V0czogWydjb250aW51b3VzJywgJ2R1cmF0aW9uJ11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnWCBlcnJvcicsXG4gICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICByYW5rOiAzLFxuICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIHN1cHBvcnRlZEZhY2V0czogWydjb250aW51b3VzJywgJ2R1cmF0aW9uJ11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnWSBlcnJvcicsXG4gICAgICAgIHR5cGU6ICdhZ2dyZWdhdGUnLFxuICAgICAgICByYW5rOiA0LFxuICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIHN1cHBvcnRlZEZhY2V0czogWydjb250aW51b3VzJywgJ2R1cmF0aW9uJ11cbiAgICAgIH1cbiAgICBdKTtcbiAgfSxcbiAgY2hhcnRqc0NvbmZpZzogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnYnViYmxlRXJyb3InLFxuICAgICAgZGF0YToge1xuICAgICAgICBkYXRhc2V0czogW11cbiAgICAgIH0sXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIGFuaW1hdGlvbjogZmFsc2UsXG4gICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICBwb3NpdGlvbjogJ3RvcCdcbiAgICAgICAgfSxcbiAgICAgICAgbGVnZW5kOiB7XG4gICAgICAgICAgZGlzcGxheTogZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgc2NhbGVzOiB7XG4gICAgICAgICAgeEF4ZXM6IFt7XG4gICAgICAgICAgICB0eXBlOiAnbGluZWFyJyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYm90dG9tJyxcbiAgICAgICAgICAgIGdyaWRMaW5lczoge1xuICAgICAgICAgICAgICB6ZXJvTGluZUNvbG9yOiAncmdiYSgwLDI1NSwwLDEpJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNjYWxlTGFiZWw6IHtcbiAgICAgICAgICAgICAgZGlzcGxheTogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRpbWU6IHtcbiAgICAgICAgICAgICAgcGFyc2VyOiBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbW9tZW50KGxhYmVsLCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfV0sXG4gICAgICAgICAgeUF4ZXM6IFt7XG4gICAgICAgICAgICB0eXBlOiAnbGluZWFyJyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnbGVmdCcsXG4gICAgICAgICAgICBncmlkTGluZXM6IHtcbiAgICAgICAgICAgICAgemVyb0xpbmVDb2xvcjogJ3JnYmEoMCwyNTUsMCwxKSdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzY2FsZUxhYmVsOiB7XG4gICAgICAgICAgICAgIGRpc3BsYXk6IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aW1lOiB7XG4gICAgICAgICAgICAgIHBhcnNlcjogZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1vbWVudChsYWJlbCwgbW9tZW50LklTT184NjAxKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1dXG4gICAgICAgIH0sXG4gICAgICAgIHRvb2x0aXBzOiB7XG4gICAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICBtb2RlOiAnc2luZ2xlJyxcbiAgICAgICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgICAgIGxhYmVsOiB0dExhYmVsXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBOzs7OztBQU1BO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBVEE7QUFlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBVEE7QUFoQkE7QUFnQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBSEE7QUF6Q0E7QUFMQTtBQXVEQTtBQXZHQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///71a3\n")},"7bdf":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(process) {function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }\n\nfunction _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; }\n\nvar Spot = __webpack_require__(/*! spot-framework */ \"3b07\");\n\nvar PageView = __webpack_require__(/*! ./base */ \"b966\");\n\nvar templates = __webpack_require__(/*! ../templates */ \"4324\");\n\nvar app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar $ = __webpack_require__(/*! jquery */ \"802c\");\n\nvar dialogPolyfill = __webpack_require__(/*! dialog-polyfill */ \"5c00\");\n\nvar SessionModel = __webpack_require__(/*! ./datasets/session-model */ \"bdff\");\n\nvar DatasetCollectionView = __webpack_require__(/*! ./datasets/dataset-collection */ \"1002\");\n\nvar SessionCollectionView = __webpack_require__(/*! ./datasets/session-collection */ \"56f6\");\n\nmodule.exports = PageView.extend({\n  template: templates.datasets.page,\n  initialize: function initialize() {\n    this.pageName = 'datasets';\n    this.helpTemplate = ''; // // display or hide elements\n    // var serverButton = document.getElementById('serverButton-card');\n    // console.log(serverButton);\n    // if ( process.env.MODE !== 'server' ) {\n    //   // serverButton.style.display = 'inherit';\n    //   // serverButton.style.display = 'none';\n    //   // serverButton.style.display = 'inline';\n    // }\n\n    var localStorageDatasets = app.getDatasetsFromLocalStorage();\n    localStorageDatasets.forEach(function (dset, index) {\n      app.me.datasets.add(dset);\n      console.log(\"[\" + index + \"]: \" + dset.id + '  ', dset.name);\n    });\n    var localStorageSessions = app.getSessionsFromLocalStorage();\n    localStorageSessions.forEach(function (sess, index) {\n      var now = new Date();\n      var sessMod = new SessionModel({\n        id: sess.id,\n        name: 'Local session',\n        date: now.toLocaleString()\n      });\n      app.sessions.add(sessMod);\n    });\n  },\n  events: {\n    'change [data-hook~=json-upload-input]': 'importJSON',\n    'change [data-hook~=csv-upload-input]': 'importCSV',\n    'click [data-hook~=server-connect]': 'connectToServer',\n    'input [data-hook~=dataset-selector]': 'input',\n    'input [data-hook~=CSV-separator-other-input]': 'setOtherSeperator',\n    'click [data-hook~=search-button]': 'search',\n    'click [data-hook~=clear-button]': 'clear',\n    'click [data-hook~=CSV-settings-button]': 'showCSVSettings',\n    'click [data-hook~=CSV-settings-close]': 'closeCSVSettings',\n    'click [data-hook~=session-cloud-upload]': 'uploadSessionZenodo',\n    'click [data-hook~=session-cloud-download]': 'showCloudDownloadInfo',\n    'click [data-hook~=session-download]': 'exportSession',\n    'change [data-hook~=session-upload-input]': 'importLocalSession',\n    'click [data-hook~=data-download]': 'exportData',\n    'click [data-hook~=session-download-cloud-close-button]': 'closeCloudDownloadInfo',\n    'click [data-hook~=session-download-cloud-get]': 'getRemoteSession',\n    'click [data-hook~=session-upload-cloud-close-button]': 'closeCloudUploadInfo',\n    'click #CSV-separator-comma': function clickCSVSeparatorComma() {\n      app.CSVSeparator = ',';\n    },\n    'click #CSV-separator-colon': function clickCSVSeparatorColon() {\n      app.CSVSeparator = ':';\n    },\n    'click #CSV-separator-semicolon': function clickCSVSeparatorSemicolon() {\n      app.CSVSeparator = ';';\n    },\n    'click #CSV-separator-pipe': function clickCSVSeparatorPipe() {\n      app.CSVSeparator = '|';\n    },\n    'click #CSV-separator-tab': function clickCSVSeparatorTab() {\n      app.CSVSeparator = '\\t';\n    },\n    'click #CSV-separator-other': function clickCSVSeparatorOther() {\n      this.el.querySelector('[data-hook~=\"CSV-separator-other-input\"]').focus();\n    },\n    'click #CSV-header-columns': function clickCSVHeaderColumns() {\n      app.CSVHeaders = this.query('#CSV-header-columns').checked;\n    },\n    'click #CSV-quote-single': function clickCSVQuoteSingle() {\n      app.CSVQuote = '\\'';\n    },\n    'click #CSV-quote-double': function clickCSVQuoteDouble() {\n      app.CSVQuote = '\"';\n    },\n    'click #CSV-quote-none': function clickCSVQuoteNone() {\n      app.CSVQuote = null;\n    },\n    'click #CSV-comment-pound': function clickCSVCommentPound() {\n      app.CSVComment = '#';\n    },\n    'click #CSV-comment-exclamation': function clickCSVCommentExclamation() {\n      app.CSVComment = '!';\n    },\n    'click #CSV-comment-slash': function clickCSVCommentSlash() {\n      app.CSVComment = '/';\n    },\n    'click #CSV-comment-dash': function clickCSVCommentDash() {\n      app.CSVComment = '-';\n    },\n    'click #CSV-comment-percent': function clickCSVCommentPercent() {\n      app.CSVComment = '%';\n    }\n  },\n  render: function render() {\n    // Reset the CSV parsing dialog.\n    // NOTE: we could do this via bindings, but this is easier (less code)\n    this.renderWithTemplate(this);\n    this.query('#CSV-header-columns').checked = app.CSVHeaders;\n\n    if (app.CSVSeparator === ',') {\n      this.query('#CSV-separator-comma').checked = true;\n    } else if (app.CSVSeparator === ':') {\n      this.query('#CSV-separator-colon').checked = true;\n    } else if (app.CSVSeparator === ';') {\n      this.query('#CSV-separator-semicolon').checked = true;\n    } else if (app.CSVSeparator === '|') {\n      this.query('#CSV-separator-pipe').checked = true;\n    } else if (app.CSVSeparator === '\\t') {\n      this.query('#CSV-separator-tab').checked = true;\n    }\n\n    if (app.CSVQuote === '\"') {\n      this.query('#CSV-quote-double').checked = true;\n    } else if (app.CSVQuote === '\\'') {\n      this.query('#CSV-quote-single').checked = true;\n    } else if (app.CSVQuote === null) {\n      this.query('#CSV-quote-none').checked = true;\n    }\n\n    if (app.CSVComment === '#') {\n      this.query('#CSV-comment-pound').checked = true;\n    } else if (app.CSVComment === '!') {\n      this.query('#CSV-comment-exclamation').checked = true;\n    } else if (app.CSVComment === '/') {\n      this.query('#CSV-comment-slash').checked = true;\n    } else if (app.CSVComment === '-') {\n      this.query('#CSV-comment-dash').checked = true;\n    } else if (app.CSVComment === 'percent') {\n      this.query('#CSV-comment-percent').checked = true;\n    } // mdl hook ups\n\n\n    this.once('remove', function () {\n      app.me.datasets.off('add');\n    });\n    app.me.datasets.on('add', function () {\n      window.componentHandler.upgradeDom();\n    });\n    app.sessions.on('add', function () {\n      window.componentHandler.upgradeDom();\n    });\n  },\n  session: {\n    needle: 'string',\n    showSearch: 'boolean'\n  },\n  subviews: {\n    datasets: {\n      hook: 'dataset-items',\n      constructor: DatasetCollectionView\n    },\n    sessions: {\n      hook: 'session-items',\n      constructor: SessionCollectionView\n    }\n  },\n  bindings: {\n    'model.isLockedDown': {\n      type: 'toggle',\n      hook: 'add-datasets-div',\n      invert: true\n    },\n    'showSearch': {\n      type: 'toggle',\n      hook: 'search-bar'\n    },\n    'needle': {\n      type: 'value',\n      hook: 'dataset-selector'\n    }\n  },\n  input: function input() {\n    var select = this.el.querySelector('[data-hook~=\"dataset-selector\"]');\n    this.needle = select.value;\n    this.update();\n  },\n  setOtherSeperator: function setOtherSeperator() {\n    var select = this.el.querySelector('[data-hook~=\"CSV-separator-other-input\"]');\n    app.CSVSeparator = select.value;\n  },\n  search: function search() {\n    this.showSearch = !this.showSearch;\n\n    if (this.showSearch) {\n      this.queryByHook('dataset-selector').focus();\n    }\n  },\n  clear: function clear() {\n    this.needle = '';\n    this.update();\n  },\n  update: function update() {\n    // build regexp for searching\n    try {\n      var regexp = new RegExp(this.needle, 'i'); // case insensitive search\n      // search through collection, check both name and description\n\n      this.model.datasets.forEach(function (e) {\n        var hay = e.name + e.URL + e.description;\n        e.show = regexp.test(hay.toLowerCase());\n      });\n    } catch (error) {}\n  },\n  connectToServer: function connectToServer() {\n    app.me = new Spot({\n      sessionType: 'server'\n    });\n    app.message({\n      text: 'Connecting to server at ' + process.env.DB_SERVER + \":\" + process.env.DB_SERVER_PORT,\n      type: 'ok'\n    });\n    app.me.connectToServer();\n    app.me.socket.emit('getDatasets');\n    app.navigate('home');\n    setTimeout(function () {\n      app.navigate('datasets');\n    }, 100);\n  },\n  showCSVSettings: function showCSVSettings() {\n    var dialog = this.queryByHook('CSV-settings');\n    dialogPolyfill.registerDialog(dialog);\n    dialog.showModal();\n  },\n  closeCSVSettings: function closeCSVSettings() {\n    var dialog = this.queryByHook('CSV-settings');\n    dialogPolyfill.registerDialog(dialog);\n    dialog.close();\n  },\n  showCloudUploadInfo: function showCloudUploadInfo() {\n    var dialog = this.queryByHook('session-upload-cloud');\n    dialogPolyfill.registerDialog(dialog);\n    dialog.showModal();\n  },\n  closeCloudUploadInfo: function closeCloudUploadInfo() {\n    var dialog = this.queryByHook('session-upload-cloud');\n    dialogPolyfill.registerDialog(dialog);\n    dialog.close();\n  },\n  showCloudDownloadInfo: function showCloudDownloadInfo() {\n    var dialog = this.queryByHook('session-download-cloud');\n    dialogPolyfill.registerDialog(dialog);\n    dialog.showModal();\n  },\n  closeCloudDownloadInfo: function closeCloudDownloadInfo() {\n    var dialog = this.queryByHook('session-download-cloud');\n    dialogPolyfill.registerDialog(dialog);\n    dialog.close();\n  },\n  /////////////////////////////////////////////\n  importJSON: function importJSON() {\n    console.log('called function importJSON');\n    app.importJSON();\n  },\n  importCSV: function importCSV() {\n    console.log('called function importCSV');\n    app.importCSV();\n  },\n  getRemoteSession: function getRemoteSession() {\n    console.log('called function getRemoteSession');\n    var sessionUrl = this.queryByHook('session-import-remote-link').value; // TODO: verify the link\n\n    if (sessionUrl !== '') {\n      console.log('Downloading:', sessionUrl);\n      this.closeCloudDownloadInfo();\n      app.message({\n        text: 'Downloading the session. Please wait.',\n        type: 'ok'\n      });\n      app.importRemoteSession(sessionUrl);\n    }\n  },\n  exportSession: function exportSession() {\n    console.log('called function exportSession');\n    app.exportSession();\n  },\n  exportData: function exportData() {\n    console.log('called function exportData');\n  },\n  importLocalSession: function importLocalSession() {\n    console.log('called function importLocalSession');\n    app.importLocalSession();\n  },\n  uploadSessionZenodo: function uploadSessionZenodo() {\n    var that = this;\n    var json = app.me.toJSON();\n\n    if (app.me.sessionType === 'client') {\n      app.me.datasets.forEach(function (dataset, i) {\n        json.datasets[i].data = dataset.data;\n      });\n    }\n\n    var sessionData = new window.Blob([JSON.stringify(json)], {\n      type: 'application/json'\n    });\n    var shareLink = this.queryByHook('session-upload-cloud-link');\n    var shareDirectLink = this.queryByHook('session-upload-cloud-link-direct');\n    var fileformData = new FormData();\n    var zenodo_id = null;\n    fileformData.append(\"file\", sessionData, \"sessionfile.json\");\n    var metadata = {\n      metadata: {\n        'title': 'SPOT Session',\n        'upload_type': 'dataset',\n        'creators': [{\n          'name': 'Faruk, Diblen',\n          'affiliation': 'NLeSC'\n        }]\n      }\n    }; // console.log(\"Creating a DOI\");\n\n    app.zenodoRequest({\n      url_addition: \"\",\n      requestType: \"doi\",\n      bodyData: {}\n    }).then(function (doi_data) {\n      // console.log(\"doi_data: \", doi_data);\n      zenodo_id = doi_data.id; // console.log(\"Zenodo id:\", zenodo_id);\n      // console.log(\"Uploading file\");\n\n      app.zenodoRequest({\n        url_addition: zenodo_id + \"/files\",\n        requestType: \"upload\",\n        bodyData: fileformData\n      }).then(function (upload_data) {\n        // console.log(\"upload_data: \", upload_data);\n        // console.log(\"direct link: \", upload_data.links.download);\n        metadata.metadata = _objectSpread({}, metadata.metadata, {\n          'description': '<p><a href=\"' + \"http\" + '://' + \"127.0.0.1\" + \":\" + \"9966\" + '/#session=' + 'https://sandbox.zenodo.org/record/' + zenodo_id + '/files/sessionfile.json' + '\">Open with SPOT</a></p>' // console.log('<p><a href=\"' + process.env.PROTOCOL + '://' + process.env.BASE_URL + \":\" + process.env.PORT + '/#session=' + 'https://sandbox.zenodo.org/record/' + zenodo_id + '/files/sessionfile.json' + '\">Open with SPOT</a></p>');\n          // console.log(\"Setting the metadata\");\n\n        });\n        app.zenodoRequest({\n          url_addition: zenodo_id,\n          requestType: \"meta\",\n          bodyData: metadata\n        }).then(function (metadata_data) {\n          // console.log(\"metadata_data: \", metadata_data);\n          // console.log(\"Publishing...\");\n          app.zenodoRequest({\n            url_addition: zenodo_id + \"/actions/publish\",\n            requestType: \"publish\",\n            bodyData: {}\n          }).then(function (publish_data) {\n            // console.log(\"publish_data: \", publish_data);\n            // console.log(\"links: \", publish_data.links.record_html);\n            shareLink.value = publish_data.links.record_html;\n            shareDirectLink.value = \"http\" + '://' + \"127.0.0.1\" + \":\" + \"9966\" + '/#session=' + 'https://sandbox.zenodo.org/record/' + zenodo_id + '/files/sessionfile.json';\n            that.showCloudUploadInfo();\n          }).catch(function (error_publish) {\n            console.error(error_publish);\n          });\n        }).catch(function (error_metadata) {\n          console.error(error_metadata);\n        });\n      }).catch(function (error_upload) {\n        console.error(error_upload);\n      });\n    }).catch(function (error_doi) {\n      console.error(error_doi);\n    });\n  }\n});\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../node_modules/process/browser.js */ \"26d5\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2JkZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9kYXRhc2V0cy5qcz85YzM3Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBTcG90ID0gcmVxdWlyZSgnc3BvdC1mcmFtZXdvcmsnKTtcbnZhciBQYWdlVmlldyA9IHJlcXVpcmUoJy4vYmFzZScpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uL3RlbXBsYXRlcycpO1xudmFyIGFwcCA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1hcHAnKTtcbnZhciAkID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG5cbmNvbnN0IGRpYWxvZ1BvbHlmaWxsID0gcmVxdWlyZSgnZGlhbG9nLXBvbHlmaWxsJyk7XG52YXIgU2Vzc2lvbk1vZGVsID0gcmVxdWlyZSgnLi9kYXRhc2V0cy9zZXNzaW9uLW1vZGVsJyk7XG5cbnZhciBEYXRhc2V0Q29sbGVjdGlvblZpZXcgPSByZXF1aXJlKCcuL2RhdGFzZXRzL2RhdGFzZXQtY29sbGVjdGlvbicpO1xudmFyIFNlc3Npb25Db2xsZWN0aW9uVmlldyA9IHJlcXVpcmUoJy4vZGF0YXNldHMvc2Vzc2lvbi1jb2xsZWN0aW9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gUGFnZVZpZXcuZXh0ZW5kKHtcbiAgdGVtcGxhdGU6IHRlbXBsYXRlcy5kYXRhc2V0cy5wYWdlLFxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5wYWdlTmFtZSA9ICdkYXRhc2V0cyc7XG4gICAgdGhpcy5oZWxwVGVtcGxhdGUgPSAnJztcblxuXG4gICAgLy8gLy8gZGlzcGxheSBvciBoaWRlIGVsZW1lbnRzXG4gICAgLy8gdmFyIHNlcnZlckJ1dHRvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXJ2ZXJCdXR0b24tY2FyZCcpO1xuICAgIC8vIGNvbnNvbGUubG9nKHNlcnZlckJ1dHRvbik7XG4gICAgLy8gaWYgKCBwcm9jZXNzLmVudi5NT0RFICE9PSAnc2VydmVyJyApIHtcbiAgICAvLyAgIC8vIHNlcnZlckJ1dHRvbi5zdHlsZS5kaXNwbGF5ID0gJ2luaGVyaXQnO1xuICAgIC8vICAgLy8gc2VydmVyQnV0dG9uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgLy8gICAvLyBzZXJ2ZXJCdXR0b24uc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUnO1xuICAgIC8vIH1cblxuXG4gICAgdmFyIGxvY2FsU3RvcmFnZURhdGFzZXRzID0gYXBwLmdldERhdGFzZXRzRnJvbUxvY2FsU3RvcmFnZSgpO1xuICAgIGxvY2FsU3RvcmFnZURhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24oZHNldCwgaW5kZXgpIHtcbiAgICAgIGFwcC5tZS5kYXRhc2V0cy5hZGQoZHNldCk7XG4gICAgICBjb25zb2xlLmxvZyhcIltcIiArIGluZGV4ICsgXCJdOiBcIiArIGRzZXQuaWQgKyAnICAnLCBkc2V0Lm5hbWUpO1xuICAgIH0pO1xuXG4gICAgdmFyIGxvY2FsU3RvcmFnZVNlc3Npb25zID0gYXBwLmdldFNlc3Npb25zRnJvbUxvY2FsU3RvcmFnZSgpO1xuICAgIGxvY2FsU3RvcmFnZVNlc3Npb25zLmZvckVhY2goZnVuY3Rpb24oc2VzcywgaW5kZXgpIHtcbiAgICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgICB2YXIgc2Vzc01vZCA9IG5ldyBTZXNzaW9uTW9kZWwoe1xuICAgICAgICBpZDogc2Vzcy5pZCxcbiAgICAgICAgbmFtZTogJ0xvY2FsIHNlc3Npb24nLFxuICAgICAgICBkYXRlOiBub3cudG9Mb2NhbGVTdHJpbmcoKVxuICAgICAgfSk7XG4gICAgICBhcHAuc2Vzc2lvbnMuYWRkKHNlc3NNb2QpO1xuICAgIH0pO1xuXG4gIH0sXG4gIGV2ZW50czoge1xuICAgICdjaGFuZ2UgW2RhdGEtaG9va349anNvbi11cGxvYWQtaW5wdXRdJzogJ2ltcG9ydEpTT04nLFxuICAgICdjaGFuZ2UgW2RhdGEtaG9va349Y3N2LXVwbG9hZC1pbnB1dF0nOiAnaW1wb3J0Q1NWJyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349c2VydmVyLWNvbm5lY3RdJzogJ2Nvbm5lY3RUb1NlcnZlcicsXG5cbiAgICAnaW5wdXQgW2RhdGEtaG9va349ZGF0YXNldC1zZWxlY3Rvcl0nOiAnaW5wdXQnLFxuICAgICdpbnB1dCBbZGF0YS1ob29rfj1DU1Ytc2VwYXJhdG9yLW90aGVyLWlucHV0XSc6ICdzZXRPdGhlclNlcGVyYXRvcicsXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PXNlYXJjaC1idXR0b25dJzogJ3NlYXJjaCcsXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWNsZWFyLWJ1dHRvbl0nOiAnY2xlYXInLFxuXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PUNTVi1zZXR0aW5ncy1idXR0b25dJzogJ3Nob3dDU1ZTZXR0aW5ncycsXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PUNTVi1zZXR0aW5ncy1jbG9zZV0nOiAnY2xvc2VDU1ZTZXR0aW5ncycsXG5cbiAgICAnY2xpY2sgW2RhdGEtaG9va349c2Vzc2lvbi1jbG91ZC11cGxvYWRdJzogJ3VwbG9hZFNlc3Npb25aZW5vZG8nLFxuICAgICdjbGljayBbZGF0YS1ob29rfj1zZXNzaW9uLWNsb3VkLWRvd25sb2FkXSc6ICdzaG93Q2xvdWREb3dubG9hZEluZm8nLFxuICAgICdjbGljayBbZGF0YS1ob29rfj1zZXNzaW9uLWRvd25sb2FkXSc6ICdleHBvcnRTZXNzaW9uJyxcbiAgICAnY2hhbmdlIFtkYXRhLWhvb2t+PXNlc3Npb24tdXBsb2FkLWlucHV0XSc6ICdpbXBvcnRMb2NhbFNlc3Npb24nLFxuICAgICdjbGljayBbZGF0YS1ob29rfj1kYXRhLWRvd25sb2FkXSc6ICdleHBvcnREYXRhJyxcblxuICAgICdjbGljayBbZGF0YS1ob29rfj1zZXNzaW9uLWRvd25sb2FkLWNsb3VkLWNsb3NlLWJ1dHRvbl0nOiAnY2xvc2VDbG91ZERvd25sb2FkSW5mbycsXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PXNlc3Npb24tZG93bmxvYWQtY2xvdWQtZ2V0XSc6ICdnZXRSZW1vdGVTZXNzaW9uJyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349c2Vzc2lvbi11cGxvYWQtY2xvdWQtY2xvc2UtYnV0dG9uXSc6ICdjbG9zZUNsb3VkVXBsb2FkSW5mbycsXG5cbiAgICAnY2xpY2sgI0NTVi1zZXBhcmF0b3ItY29tbWEnOiBmdW5jdGlvbiAoKSB7IGFwcC5DU1ZTZXBhcmF0b3IgPSAnLCc7IH0sXG4gICAgJ2NsaWNrICNDU1Ytc2VwYXJhdG9yLWNvbG9uJzogZnVuY3Rpb24gKCkgeyBhcHAuQ1NWU2VwYXJhdG9yID0gJzonOyB9LFxuICAgICdjbGljayAjQ1NWLXNlcGFyYXRvci1zZW1pY29sb24nOiBmdW5jdGlvbiAoKSB7IGFwcC5DU1ZTZXBhcmF0b3IgPSAnOyc7IH0sXG4gICAgJ2NsaWNrICNDU1Ytc2VwYXJhdG9yLXBpcGUnOiBmdW5jdGlvbiAoKSB7IGFwcC5DU1ZTZXBhcmF0b3IgPSAnfCc7IH0sXG4gICAgJ2NsaWNrICNDU1Ytc2VwYXJhdG9yLXRhYic6IGZ1bmN0aW9uICgpIHsgYXBwLkNTVlNlcGFyYXRvciA9ICdcXHQnOyB9LFxuICAgICdjbGljayAjQ1NWLXNlcGFyYXRvci1vdGhlcic6IGZ1bmN0aW9uICgpIHsgdGhpcy5lbC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1ob29rfj1cIkNTVi1zZXBhcmF0b3Itb3RoZXItaW5wdXRcIl0nKS5mb2N1cygpOyB9LFxuICAgICdjbGljayAjQ1NWLWhlYWRlci1jb2x1bW5zJzogZnVuY3Rpb24gKCkgeyBhcHAuQ1NWSGVhZGVycyA9IHRoaXMucXVlcnkoJyNDU1YtaGVhZGVyLWNvbHVtbnMnKS5jaGVja2VkOyB9LFxuICAgICdjbGljayAjQ1NWLXF1b3RlLXNpbmdsZSc6IGZ1bmN0aW9uICgpIHsgYXBwLkNTVlF1b3RlID0gJ1xcJyc7IH0sXG4gICAgJ2NsaWNrICNDU1YtcXVvdGUtZG91YmxlJzogZnVuY3Rpb24gKCkgeyBhcHAuQ1NWUXVvdGUgPSAnXCInOyB9LFxuICAgICdjbGljayAjQ1NWLXF1b3RlLW5vbmUnOiBmdW5jdGlvbiAoKSB7IGFwcC5DU1ZRdW90ZSA9IG51bGw7IH0sXG4gICAgJ2NsaWNrICNDU1YtY29tbWVudC1wb3VuZCc6IGZ1bmN0aW9uICgpIHsgYXBwLkNTVkNvbW1lbnQgPSAnIyc7IH0sXG4gICAgJ2NsaWNrICNDU1YtY29tbWVudC1leGNsYW1hdGlvbic6IGZ1bmN0aW9uICgpIHsgYXBwLkNTVkNvbW1lbnQgPSAnISc7IH0sXG4gICAgJ2NsaWNrICNDU1YtY29tbWVudC1zbGFzaCc6IGZ1bmN0aW9uICgpIHsgYXBwLkNTVkNvbW1lbnQgPSAnLyc7IH0sXG4gICAgJ2NsaWNrICNDU1YtY29tbWVudC1kYXNoJzogZnVuY3Rpb24gKCkgeyBhcHAuQ1NWQ29tbWVudCA9ICctJzsgfSxcbiAgICAnY2xpY2sgI0NTVi1jb21tZW50LXBlcmNlbnQnOiBmdW5jdGlvbiAoKSB7IGFwcC5DU1ZDb21tZW50ID0gJyUnOyB9XG4gIH0sXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgIC8vIFJlc2V0IHRoZSBDU1YgcGFyc2luZyBkaWFsb2cuXG4gICAgLy8gTk9URTogd2UgY291bGQgZG8gdGhpcyB2aWEgYmluZGluZ3MsIGJ1dCB0aGlzIGlzIGVhc2llciAobGVzcyBjb2RlKVxuICAgIHRoaXMucmVuZGVyV2l0aFRlbXBsYXRlKHRoaXMpO1xuICAgIHRoaXMucXVlcnkoJyNDU1YtaGVhZGVyLWNvbHVtbnMnKS5jaGVja2VkID0gYXBwLkNTVkhlYWRlcnM7XG5cbiAgICBpZiAoYXBwLkNTVlNlcGFyYXRvciA9PT0gJywnKSB7XG4gICAgICB0aGlzLnF1ZXJ5KCcjQ1NWLXNlcGFyYXRvci1jb21tYScpLmNoZWNrZWQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoYXBwLkNTVlNlcGFyYXRvciA9PT0gJzonKSB7XG4gICAgICB0aGlzLnF1ZXJ5KCcjQ1NWLXNlcGFyYXRvci1jb2xvbicpLmNoZWNrZWQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoYXBwLkNTVlNlcGFyYXRvciA9PT0gJzsnKSB7XG4gICAgICB0aGlzLnF1ZXJ5KCcjQ1NWLXNlcGFyYXRvci1zZW1pY29sb24nKS5jaGVja2VkID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKGFwcC5DU1ZTZXBhcmF0b3IgPT09ICd8Jykge1xuICAgICAgdGhpcy5xdWVyeSgnI0NTVi1zZXBhcmF0b3ItcGlwZScpLmNoZWNrZWQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoYXBwLkNTVlNlcGFyYXRvciA9PT0gJ1xcdCcpIHtcbiAgICAgIHRoaXMucXVlcnkoJyNDU1Ytc2VwYXJhdG9yLXRhYicpLmNoZWNrZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChhcHAuQ1NWUXVvdGUgPT09ICdcIicpIHtcbiAgICAgIHRoaXMucXVlcnkoJyNDU1YtcXVvdGUtZG91YmxlJykuY2hlY2tlZCA9IHRydWU7XG4gICAgfSBlbHNlIGlmIChhcHAuQ1NWUXVvdGUgPT09ICdcXCcnKSB7XG4gICAgICB0aGlzLnF1ZXJ5KCcjQ1NWLXF1b3RlLXNpbmdsZScpLmNoZWNrZWQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoYXBwLkNTVlF1b3RlID09PSBudWxsKSB7XG4gICAgICB0aGlzLnF1ZXJ5KCcjQ1NWLXF1b3RlLW5vbmUnKS5jaGVja2VkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoYXBwLkNTVkNvbW1lbnQgPT09ICcjJykge1xuICAgICAgdGhpcy5xdWVyeSgnI0NTVi1jb21tZW50LXBvdW5kJykuY2hlY2tlZCA9IHRydWU7XG4gICAgfSBlbHNlIGlmIChhcHAuQ1NWQ29tbWVudCA9PT0gJyEnKSB7XG4gICAgICB0aGlzLnF1ZXJ5KCcjQ1NWLWNvbW1lbnQtZXhjbGFtYXRpb24nKS5jaGVja2VkID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKGFwcC5DU1ZDb21tZW50ID09PSAnLycpIHtcbiAgICAgIHRoaXMucXVlcnkoJyNDU1YtY29tbWVudC1zbGFzaCcpLmNoZWNrZWQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoYXBwLkNTVkNvbW1lbnQgPT09ICctJykge1xuICAgICAgdGhpcy5xdWVyeSgnI0NTVi1jb21tZW50LWRhc2gnKS5jaGVja2VkID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKGFwcC5DU1ZDb21tZW50ID09PSAncGVyY2VudCcpIHtcbiAgICAgIHRoaXMucXVlcnkoJyNDU1YtY29tbWVudC1wZXJjZW50JykuY2hlY2tlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gbWRsIGhvb2sgdXBzXG4gICAgdGhpcy5vbmNlKCdyZW1vdmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhcHAubWUuZGF0YXNldHMub2ZmKCdhZGQnKTtcbiAgICB9KTtcbiAgICBhcHAubWUuZGF0YXNldHMub24oJ2FkZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHdpbmRvdy5jb21wb25lbnRIYW5kbGVyLnVwZ3JhZGVEb20oKTtcbiAgICB9KTtcbiAgICBhcHAuc2Vzc2lvbnMub24oJ2FkZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHdpbmRvdy5jb21wb25lbnRIYW5kbGVyLnVwZ3JhZGVEb20oKTtcbiAgICB9KTtcbiAgfSxcbiAgc2Vzc2lvbjoge1xuICAgIG5lZWRsZTogJ3N0cmluZycsXG4gICAgc2hvd1NlYXJjaDogJ2Jvb2xlYW4nXG4gIH0sXG4gIHN1YnZpZXdzOiB7XG4gICAgZGF0YXNldHM6IHtcbiAgICAgIGhvb2s6ICdkYXRhc2V0LWl0ZW1zJyxcbiAgICAgIGNvbnN0cnVjdG9yOiBEYXRhc2V0Q29sbGVjdGlvblZpZXdcbiAgICB9LFxuICAgIHNlc3Npb25zOiB7XG4gICAgICBob29rOiAnc2Vzc2lvbi1pdGVtcycsXG4gICAgICBjb25zdHJ1Y3RvcjogU2Vzc2lvbkNvbGxlY3Rpb25WaWV3XG4gICAgfVxuICB9LFxuICBiaW5kaW5nczoge1xuICAgICdtb2RlbC5pc0xvY2tlZERvd24nOiB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIGhvb2s6ICdhZGQtZGF0YXNldHMtZGl2JyxcbiAgICAgIGludmVydDogdHJ1ZVxuICAgIH0sXG4gICAgJ3Nob3dTZWFyY2gnOiB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIGhvb2s6ICdzZWFyY2gtYmFyJ1xuICAgIH0sXG4gICAgJ25lZWRsZSc6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAnZGF0YXNldC1zZWxlY3RvcidcbiAgICB9XG4gIH0sXG4gIGlucHV0OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNlbGVjdCA9IHRoaXMuZWwucXVlcnlTZWxlY3RvcignW2RhdGEtaG9va349XCJkYXRhc2V0LXNlbGVjdG9yXCJdJyk7XG4gICAgdGhpcy5uZWVkbGUgPSBzZWxlY3QudmFsdWU7XG5cbiAgICB0aGlzLnVwZGF0ZSgpO1xuICB9LFxuICBzZXRPdGhlclNlcGVyYXRvcjogZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxlY3QgPSB0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLWhvb2t+PVwiQ1NWLXNlcGFyYXRvci1vdGhlci1pbnB1dFwiXScpO1xuICAgIGFwcC5DU1ZTZXBhcmF0b3IgPSBzZWxlY3QudmFsdWU7XG4gIH0sXG4gIHNlYXJjaDogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc2hvd1NlYXJjaCA9ICF0aGlzLnNob3dTZWFyY2g7XG4gICAgaWYgKHRoaXMuc2hvd1NlYXJjaCkge1xuICAgICAgdGhpcy5xdWVyeUJ5SG9vaygnZGF0YXNldC1zZWxlY3RvcicpLmZvY3VzKCk7XG4gICAgfVxuICB9LFxuICBjbGVhcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMubmVlZGxlID0gJyc7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfSxcbiAgdXBkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gYnVpbGQgcmVnZXhwIGZvciBzZWFyY2hpbmdcbiAgICB0cnkge1xuICAgICAgdmFyIHJlZ2V4cCA9IG5ldyBSZWdFeHAodGhpcy5uZWVkbGUsICdpJyk7IC8vIGNhc2UgaW5zZW5zaXRpdmUgc2VhcmNoXG5cbiAgICAgIC8vIHNlYXJjaCB0aHJvdWdoIGNvbGxlY3Rpb24sIGNoZWNrIGJvdGggbmFtZSBhbmQgZGVzY3JpcHRpb25cbiAgICAgIHRoaXMubW9kZWwuZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgaGF5ID0gZS5uYW1lICsgZS5VUkwgKyBlLmRlc2NyaXB0aW9uO1xuICAgICAgICBlLnNob3cgPSByZWdleHAudGVzdChoYXkudG9Mb3dlckNhc2UoKSk7XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgIH1cbiAgfSxcblxuICBjb25uZWN0VG9TZXJ2ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICBhcHAubWUgPSBuZXcgU3BvdCh7XG4gICAgICBzZXNzaW9uVHlwZTogJ3NlcnZlcidcbiAgICB9KTtcbiAgICBhcHAubWVzc2FnZSh7XG4gICAgICB0ZXh0OiAnQ29ubmVjdGluZyB0byBzZXJ2ZXIgYXQgJyArIHByb2Nlc3MuZW52LkRCX1NFUlZFUiArIFwiOlwiICsgcHJvY2Vzcy5lbnYuREJfU0VSVkVSX1BPUlQsXG4gICAgICB0eXBlOiAnb2snXG4gICAgfSk7XG4gICAgYXBwLm1lLmNvbm5lY3RUb1NlcnZlcigpO1xuICAgIGFwcC5tZS5zb2NrZXQuZW1pdCgnZ2V0RGF0YXNldHMnKTtcblxuICAgIGFwcC5uYXZpZ2F0ZSgnaG9tZScpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgYXBwLm5hdmlnYXRlKCdkYXRhc2V0cycpO1xuICAgIH0sIDEwMCk7XG4gIH0sXG4gIHNob3dDU1ZTZXR0aW5nczogZnVuY3Rpb24gKCkge1xuICAgIHZhciBkaWFsb2cgPSB0aGlzLnF1ZXJ5QnlIb29rKCdDU1Ytc2V0dGluZ3MnKTtcbiAgICBkaWFsb2dQb2x5ZmlsbC5yZWdpc3RlckRpYWxvZyhkaWFsb2cpO1xuICAgIGRpYWxvZy5zaG93TW9kYWwoKTtcbiAgfSxcbiAgY2xvc2VDU1ZTZXR0aW5nczogZnVuY3Rpb24gKCkge1xuICAgIHZhciBkaWFsb2cgPSB0aGlzLnF1ZXJ5QnlIb29rKCdDU1Ytc2V0dGluZ3MnKTtcbiAgICBkaWFsb2dQb2x5ZmlsbC5yZWdpc3RlckRpYWxvZyhkaWFsb2cpO1xuICAgIGRpYWxvZy5jbG9zZSgpO1xuICB9LFxuICBzaG93Q2xvdWRVcGxvYWRJbmZvOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGRpYWxvZyA9IHRoaXMucXVlcnlCeUhvb2soJ3Nlc3Npb24tdXBsb2FkLWNsb3VkJyk7XG4gICAgZGlhbG9nUG9seWZpbGwucmVnaXN0ZXJEaWFsb2coZGlhbG9nKTtcbiAgICBkaWFsb2cuc2hvd01vZGFsKCk7XG4gIH0sXG4gIGNsb3NlQ2xvdWRVcGxvYWRJbmZvOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGRpYWxvZyA9IHRoaXMucXVlcnlCeUhvb2soJ3Nlc3Npb24tdXBsb2FkLWNsb3VkJyk7XG4gICAgZGlhbG9nUG9seWZpbGwucmVnaXN0ZXJEaWFsb2coZGlhbG9nKTtcbiAgICBkaWFsb2cuY2xvc2UoKTtcbiAgfSxcblxuICBzaG93Q2xvdWREb3dubG9hZEluZm86IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGlhbG9nID0gdGhpcy5xdWVyeUJ5SG9vaygnc2Vzc2lvbi1kb3dubG9hZC1jbG91ZCcpO1xuICAgIGRpYWxvZ1BvbHlmaWxsLnJlZ2lzdGVyRGlhbG9nKGRpYWxvZyk7XG4gICAgZGlhbG9nLnNob3dNb2RhbCgpO1xuICB9LFxuICBjbG9zZUNsb3VkRG93bmxvYWRJbmZvOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGRpYWxvZyA9IHRoaXMucXVlcnlCeUhvb2soJ3Nlc3Npb24tZG93bmxvYWQtY2xvdWQnKTtcbiAgICBkaWFsb2dQb2x5ZmlsbC5yZWdpc3RlckRpYWxvZyhkaWFsb2cpO1xuICAgIGRpYWxvZy5jbG9zZSgpO1xuICB9LFxuXG4gIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICBpbXBvcnRKU09OOiBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5sb2coJ2NhbGxlZCBmdW5jdGlvbiBpbXBvcnRKU09OJyk7XG4gICAgYXBwLmltcG9ydEpTT04oKTtcbiAgfSxcblxuICBpbXBvcnRDU1Y6IGZ1bmN0aW9uICgpIHtcbiAgICBjb25zb2xlLmxvZygnY2FsbGVkIGZ1bmN0aW9uIGltcG9ydENTVicpO1xuICAgIGFwcC5pbXBvcnRDU1YoKTtcbiAgfSxcblxuICBnZXRSZW1vdGVTZXNzaW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5sb2coJ2NhbGxlZCBmdW5jdGlvbiBnZXRSZW1vdGVTZXNzaW9uJyk7XG4gICAgdmFyIHNlc3Npb25VcmwgPSB0aGlzLnF1ZXJ5QnlIb29rKCdzZXNzaW9uLWltcG9ydC1yZW1vdGUtbGluaycpLnZhbHVlO1xuXG4gICAgLy8gVE9ETzogdmVyaWZ5IHRoZSBsaW5rXG4gICAgaWYgKHNlc3Npb25VcmwgIT09ICcnKSB7XG4gICAgICBjb25zb2xlLmxvZygnRG93bmxvYWRpbmc6Jywgc2Vzc2lvblVybCk7XG4gICAgICB0aGlzLmNsb3NlQ2xvdWREb3dubG9hZEluZm8oKTtcblxuICAgICAgYXBwLm1lc3NhZ2Uoe1xuICAgICAgICB0ZXh0OiAnRG93bmxvYWRpbmcgdGhlIHNlc3Npb24uIFBsZWFzZSB3YWl0LicsXG4gICAgICAgIHR5cGU6ICdvaydcbiAgICAgIH0pO1xuXG4gICAgICBhcHAuaW1wb3J0UmVtb3RlU2Vzc2lvbihzZXNzaW9uVXJsKTtcbiAgICB9XG4gIH0sXG5cblxuICBleHBvcnRTZXNzaW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5sb2coJ2NhbGxlZCBmdW5jdGlvbiBleHBvcnRTZXNzaW9uJyk7XG4gICAgYXBwLmV4cG9ydFNlc3Npb24oKTtcbiAgfSxcblxuICBleHBvcnREYXRhOiBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5sb2coJ2NhbGxlZCBmdW5jdGlvbiBleHBvcnREYXRhJyk7XG4gIH0sXG5cbiAgaW1wb3J0TG9jYWxTZXNzaW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5sb2coJ2NhbGxlZCBmdW5jdGlvbiBpbXBvcnRMb2NhbFNlc3Npb24nKTtcbiAgICBhcHAuaW1wb3J0TG9jYWxTZXNzaW9uKCk7XG4gIH0sXG4gIHVwbG9hZFNlc3Npb25aZW5vZG86IGZ1bmN0aW9uICgpIHtcblxuICAgIHZhciB0aGF0ID0gdGhpcztcblxuICAgIHZhciBqc29uID0gYXBwLm1lLnRvSlNPTigpO1xuICAgIGlmIChhcHAubWUuc2Vzc2lvblR5cGUgPT09ICdjbGllbnQnKSB7XG4gICAgICBhcHAubWUuZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZGF0YXNldCwgaSkge1xuICAgICAgICBqc29uLmRhdGFzZXRzW2ldLmRhdGEgPSBkYXRhc2V0LmRhdGE7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgc2Vzc2lvbkRhdGEgPSBuZXcgd2luZG93LkJsb2IoW0pTT04uc3RyaW5naWZ5KGpzb24pXSwge3R5cGU6ICdhcHBsaWNhdGlvbi9qc29uJ30pO1xuICAgIHZhciBzaGFyZUxpbmsgPSB0aGlzLnF1ZXJ5QnlIb29rKCdzZXNzaW9uLXVwbG9hZC1jbG91ZC1saW5rJyk7XG4gICAgdmFyIHNoYXJlRGlyZWN0TGluayA9IHRoaXMucXVlcnlCeUhvb2soJ3Nlc3Npb24tdXBsb2FkLWNsb3VkLWxpbmstZGlyZWN0Jyk7XG5cbiAgICB2YXIgZmlsZWZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgdmFyIHplbm9kb19pZCA9IG51bGw7XG5cbiAgICBmaWxlZm9ybURhdGEuYXBwZW5kKFwiZmlsZVwiLCBzZXNzaW9uRGF0YSwgXCJzZXNzaW9uZmlsZS5qc29uXCIpO1xuXG4gICAgdmFyIG1ldGFkYXRhID0gIHtcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICd0aXRsZSc6ICdTUE9UIFNlc3Npb24nLFxuICAgICAgICAndXBsb2FkX3R5cGUnOiAnZGF0YXNldCcsXG4gICAgICAgICdjcmVhdG9ycyc6IFt7J25hbWUnOiAnRmFydWssIERpYmxlbicsXG4gICAgICAgICdhZmZpbGlhdGlvbic6ICdOTGVTQyd9XVxuICAgICAgfVxuICAgIH07XG4gICAgXG4gICAgLy8gY29uc29sZS5sb2coXCJDcmVhdGluZyBhIERPSVwiKTtcbiAgICBhcHAuemVub2RvUmVxdWVzdCh7XG4gICAgICB1cmxfYWRkaXRpb246XCJcIixcbiAgICAgIHJlcXVlc3RUeXBlOlwiZG9pXCIsXG4gICAgICBib2R5RGF0YTp7fVxuICAgIH0pLnRoZW4oZnVuY3Rpb24oZG9pX2RhdGEpIHtcblxuICAgICAgLy8gY29uc29sZS5sb2coXCJkb2lfZGF0YTogXCIsIGRvaV9kYXRhKTtcbiAgICAgIHplbm9kb19pZCA9IGRvaV9kYXRhLmlkO1xuICAgICAgLy8gY29uc29sZS5sb2coXCJaZW5vZG8gaWQ6XCIsIHplbm9kb19pZCk7XG5cbiAgICAgIC8vIGNvbnNvbGUubG9nKFwiVXBsb2FkaW5nIGZpbGVcIik7XG4gICAgICBhcHAuemVub2RvUmVxdWVzdCh7XG4gICAgICAgIHVybF9hZGRpdGlvbjp6ZW5vZG9faWQgKyBcIi9maWxlc1wiLCBcbiAgICAgICAgcmVxdWVzdFR5cGU6XCJ1cGxvYWRcIiwgXG4gICAgICAgIGJvZHlEYXRhOmZpbGVmb3JtRGF0YVxuICAgICAgfSkudGhlbihmdW5jdGlvbih1cGxvYWRfZGF0YSkge1xuICAgICAgXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKFwidXBsb2FkX2RhdGE6IFwiLCB1cGxvYWRfZGF0YSk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKFwiZGlyZWN0IGxpbms6IFwiLCB1cGxvYWRfZGF0YS5saW5rcy5kb3dubG9hZCk7XG5cbiAgICAgICAgbWV0YWRhdGEubWV0YWRhdGEgPSB7XG4gICAgICAgICAgLi4ubWV0YWRhdGEubWV0YWRhdGEsXG4gICAgICAgICAgJ2Rlc2NyaXB0aW9uJzogJzxwPjxhIGhyZWY9XCInICsgcHJvY2Vzcy5lbnYuUFJPVE9DT0wgKyAnOi8vJyArIHByb2Nlc3MuZW52LkJBU0VfVVJMICsgXCI6XCIgKyBwcm9jZXNzLmVudi5QT1JUICsgJy8jc2Vzc2lvbj0nICsgJ2h0dHBzOi8vc2FuZGJveC56ZW5vZG8ub3JnL3JlY29yZC8nICsgemVub2RvX2lkICsgJy9maWxlcy9zZXNzaW9uZmlsZS5qc29uJyArICdcIj5PcGVuIHdpdGggU1BPVDwvYT48L3A+J1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCc8cD48YSBocmVmPVwiJyArIHByb2Nlc3MuZW52LlBST1RPQ09MICsgJzovLycgKyBwcm9jZXNzLmVudi5CQVNFX1VSTCArIFwiOlwiICsgcHJvY2Vzcy5lbnYuUE9SVCArICcvI3Nlc3Npb249JyArICdodHRwczovL3NhbmRib3guemVub2RvLm9yZy9yZWNvcmQvJyArIHplbm9kb19pZCArICcvZmlsZXMvc2Vzc2lvbmZpbGUuanNvbicgKyAnXCI+T3BlbiB3aXRoIFNQT1Q8L2E+PC9wPicpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlNldHRpbmcgdGhlIG1ldGFkYXRhXCIpO1xuICAgICAgICBhcHAuemVub2RvUmVxdWVzdCh7XG4gICAgICAgICAgdXJsX2FkZGl0aW9uOiB6ZW5vZG9faWQsXG4gICAgICAgICAgcmVxdWVzdFR5cGU6IFwibWV0YVwiLFxuICAgICAgICAgIGJvZHlEYXRhOiBtZXRhZGF0YVxuICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKG1ldGFkYXRhX2RhdGEpIHtcblxuICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwibWV0YWRhdGFfZGF0YTogXCIsIG1ldGFkYXRhX2RhdGEpO1xuXG4gICAgICAgICAgLy8gY29uc29sZS5sb2coXCJQdWJsaXNoaW5nLi4uXCIpO1xuICAgICAgICAgIGFwcC56ZW5vZG9SZXF1ZXN0KHtcbiAgICAgICAgICAgIHVybF9hZGRpdGlvbjogemVub2RvX2lkICsgXCIvYWN0aW9ucy9wdWJsaXNoXCIsIFxuICAgICAgICAgICAgcmVxdWVzdFR5cGU6IFwicHVibGlzaFwiLCBcbiAgICAgICAgICAgIGJvZHlEYXRhOiB7fVxuICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24ocHVibGlzaF9kYXRhKSB7XG4gIFxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJwdWJsaXNoX2RhdGE6IFwiLCBwdWJsaXNoX2RhdGEpO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJsaW5rczogXCIsIHB1Ymxpc2hfZGF0YS5saW5rcy5yZWNvcmRfaHRtbCk7XG4gICAgICAgICAgICBzaGFyZUxpbmsudmFsdWUgPSBwdWJsaXNoX2RhdGEubGlua3MucmVjb3JkX2h0bWw7XG4gICAgICAgICAgICBzaGFyZURpcmVjdExpbmsudmFsdWUgPSBwcm9jZXNzLmVudi5QUk9UT0NPTCArICc6Ly8nICsgcHJvY2Vzcy5lbnYuQkFTRV9VUkwgKyBcIjpcIiArIHByb2Nlc3MuZW52LlBPUlQgKyAnLyNzZXNzaW9uPScgKyAnaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvcmVjb3JkLycgKyB6ZW5vZG9faWQgKyAnL2ZpbGVzL3Nlc3Npb25maWxlLmpzb24nO1xuICAgICAgICAgICAgdGhhdC5zaG93Q2xvdWRVcGxvYWRJbmZvKCk7XG4gICAgICAgICAgfSkuY2F0Y2goZnVuY3Rpb24oZXJyb3JfcHVibGlzaCl7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yX3B1Ymxpc2gpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uKGVycm9yX21ldGFkYXRhKXtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yX21ldGFkYXRhKTtcbiAgICAgICAgfSk7XG5cbiAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uKGVycm9yX3VwbG9hZCl7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JfdXBsb2FkKTtcbiAgICAgIH0pO1xuXG4gICAgfSkuY2F0Y2goZnVuY3Rpb24oZXJyb3JfZG9pKXtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JfZG9pKTtcbiAgICB9KTsgXG5cbiAgfSxcblxuXG5cbn0pO1xuXG4iXSwibWFwcGluZ3MiOiI7Ozs7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBckNBO0FBdUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRkE7QUFMQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRkE7QUFWQTtBQWVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBREE7QUFIQTtBQURBO0FBQ0E7QUFTQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBTUE7QUFDQTtBQUdBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBTUE7QUFDQTtBQUVBO0FBRUE7QUFHQTtBQUNBO0FBTkE7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBTUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFqWEE7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7bdf\n")},"8ab4":function(module,exports,__webpack_require__){eval("var PageView = __webpack_require__(/*! ./base */ \"b966\");\n\nvar templates = __webpack_require__(/*! ../templates */ \"4324\");\n\nvar app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nmodule.exports = PageView.extend({\n  initialize: function initialize() {\n    this.pageName = 'home';\n    this.helpTemplate = '';\n    app.detectMobile();\n    app.startWelcome();\n  },\n  pageTitle: 'Home',\n  template: templates.home,\n  events: {\n    'click [data-hook~=demo-session]': 'demoSessionOnline'\n  },\n  bindings: {},\n  renderContent: function renderContent() {},\n  demoSessionOnline: function demoSessionOnline() {\n    app.busy({\n      enable: true\n    });\n    app.importRemoteSession('https://raw.githubusercontent.com/NLeSC/spot/master/dist/demo.json');\n    app.busy({\n      enable: false\n    });\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOGFiNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9ob21lLmpzPzgwNzMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFBhZ2VWaWV3ID0gcmVxdWlyZSgnLi9iYXNlJyk7XG52YXIgdGVtcGxhdGVzID0gcmVxdWlyZSgnLi4vdGVtcGxhdGVzJyk7XG52YXIgYXBwID0gcmVxdWlyZSgnYW1wZXJzYW5kLWFwcCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBhZ2VWaWV3LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnBhZ2VOYW1lID0gJ2hvbWUnO1xuICAgIHRoaXMuaGVscFRlbXBsYXRlID0gJyc7XG4gICAgYXBwLmRldGVjdE1vYmlsZSgpO1xuICAgIGFwcC5zdGFydFdlbGNvbWUoKTtcbiAgfSxcbiAgcGFnZVRpdGxlOiAnSG9tZScsXG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMuaG9tZSxcbiAgZXZlbnRzOiB7XG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWRlbW8tc2Vzc2lvbl0nOiAnZGVtb1Nlc3Npb25PbmxpbmUnXG4gIH0sXG4gIGJpbmRpbmdzOiB7XG5cbiAgfSxcblxuICByZW5kZXJDb250ZW50OiBmdW5jdGlvbiAoKSB7XG5cbiAgfSxcbiAgZGVtb1Nlc3Npb25PbmxpbmU6IGZ1bmN0aW9uICgpIHtcbiAgICBhcHAuYnVzeSh7ZW5hYmxlOiB0cnVlfSk7XG4gICAgYXBwLmltcG9ydFJlbW90ZVNlc3Npb24oJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9OTGVTQy9zcG90L21hc3Rlci9kaXN0L2RlbW8uanNvbicpO1xuICAgIGFwcC5idXN5KHtlbmFibGU6IGZhbHNlfSk7fVxuXG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFJQTtBQUdBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQXRCQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8ab4\n")},"8f0f":function(module,exports,__webpack_require__){eval("/*** IMPORTS FROM imports-loader ***/\n(function() {\n\n/**\n * @classdesc network chart (sigma.js)\n * @class NetworkChart\n * @augments BaseChart\n */\nvar BaseChart = __webpack_require__(/*! ./base-chart */ \"6339\");\n\nmodule.exports = BaseChart.extend({\n  initialize: function initialize() {\n    this.slots.reset([{\n      description: 'From',\n      type: 'partition',\n      rank: 1,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'To',\n      type: 'partition',\n      rank: 2,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Relation',\n      type: 'partition',\n      rank: 3,\n      required: false,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }]);\n  },\n  sigmaConfig: function sigmaConfig() {\n    return {\n      drawEdges: true,\n      labelSize: 'proportional'\n    };\n  }\n});\n}.call(window));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOGYwZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL21vZGVscy9zaWdtYS5qcz9iMDEwIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGNsYXNzZGVzYyBuZXR3b3JrIGNoYXJ0IChzaWdtYS5qcylcbiAqIEBjbGFzcyBOZXR3b3JrQ2hhcnRcbiAqIEBhdWdtZW50cyBCYXNlQ2hhcnRcbiAqL1xuXG52YXIgQmFzZUNoYXJ0ID0gcmVxdWlyZSgnLi9iYXNlLWNoYXJ0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZUNoYXJ0LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNsb3RzLnJlc2V0KFtcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdGcm9tJyxcbiAgICAgICAgdHlwZTogJ3BhcnRpdGlvbicsXG4gICAgICAgIHJhbms6IDEsXG4gICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICBzdXBwb3J0ZWRGYWNldHM6IFsnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICdjb250aW51b3VzJywgJ3RleHQnXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUbycsXG4gICAgICAgIHR5cGU6ICdwYXJ0aXRpb24nLFxuICAgICAgICByYW5rOiAyLFxuICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NhdGVnb3JpYWwnLCAnZGF0ZXRpbWUnLCAnZHVyYXRpb24nLCAnY29udGludW91cycsICd0ZXh0J11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnUmVsYXRpb24nLFxuICAgICAgICB0eXBlOiAncGFydGl0aW9uJyxcbiAgICAgICAgcmFuazogMyxcbiAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICBzdXBwb3J0ZWRGYWNldHM6IFsnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICdjb250aW51b3VzJywgJ3RleHQnXVxuICAgICAgfVxuICAgIF0pO1xuICB9LFxuICBzaWdtYUNvbmZpZzogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB7XG4gICAgICBkcmF3RWRnZXM6IHRydWUsXG4gICAgICBsYWJlbFNpemU6ICdwcm9wb3J0aW9uYWwnXG4gICAgfTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiI7OztBQUFBOzs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQS9CQTtBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8f0f\n")},9218:function(module,exports,__webpack_require__){eval("function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\n\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\n\nvar Spot = __webpack_require__(/*! spot-framework */ \"3b07\");\n\nvar app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar Router = __webpack_require__(/*! ./router */ \"aa00\");\n\nvar MainView = __webpack_require__(/*! ./pages/main */ \"3f86\");\n\nvar DatasetsView = __webpack_require__(/*! ./pages/datasets */ \"7bdf\");\n\nvar domReady = __webpack_require__(/*! domready */ \"3ca4\");\n\nvar widgetFactory = __webpack_require__(/*! ./widgets/widget-factory */ \"f2bc\");\n\nvar viewFactory = __webpack_require__(/*! ./widgets/view-factory */ \"a6e8\");\n\nvar Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\n\nvar SessionModel = __webpack_require__(/*! ./pages/datasets/session-model */ \"bdff\");\n\nvar dialogPolyfill = __webpack_require__(/*! dialog-polyfill */ \"5c00\");\n\nvar Help = __webpack_require__(/*! intro.js */ \"0444\");\n\nvar templates = __webpack_require__(/*! ./templates */ \"4324\");\n\nvar csv = __webpack_require__(/*! csv */ \"00a7\");\n\nvar $ = __webpack_require__(/*! jquery */ \"802c\");\n\n__webpack_require__(/*! babel-polyfill */ \"a26e\");\n\n__webpack_require__(/*! mdl */ \"9d69\");\n\nvar sessionCollection = Collection.extend({\n  mainIndex: 'id',\n  indexes: ['name'],\n  model: SessionModel\n}); // attach our app to `window` so we can\n// easily access it from the console.\n\nwindow.app = app; // Extends our main app singleton\n\napp.extend({\n  /**\n   * [fullscreenMode description]\n   * @type {Boolean}\n   */\n  fullscreenMode: false,\n\n  /**\n   * [demoSession description]\n   * @type {Boolean}\n   */\n  demoSession: false,\n\n  /**\n   * [mobileBrowser description]\n   * @type {Boolean}\n   */\n  mobileBrowser: false,\n\n  /**\n   * [me description]\n   * @type {Spot}\n   */\n  me: new Spot(),\n\n  /**\n   * [widgetFactory description]\n   * @type {any}\n   */\n  widgetFactory: widgetFactory,\n\n  /**\n   * [viewFactory description]\n   * @type {any}\n   */\n  viewFactory: viewFactory,\n\n  /**\n   * [router description]\n   * @type {Router}\n   */\n  router: new Router(),\n\n  /**\n   * [CSVSeparator description]\n   * @type {String}\n   */\n  CSVSeparator: ',',\n\n  /**\n   * [CSVHeaders description]\n   * @type {Boolean}\n   */\n  CSVHeaders: true,\n\n  /**\n   * [CSVQuote description]\n   * @type {String}\n   */\n  CSVQuote: '\"',\n\n  /**\n   * [CSVComment description]\n   * @type {String}\n   */\n  CSVComment: '#',\n  helper: {\n    enabled: false,\n    instance: new Help()\n  },\n\n  /**\n   * [sessions description]\n   * @type {any}\n   */\n  sessions: new sessionCollection(),\n\n  /**\n   * This is where it all starts\n   */\n  init: function init() {\n    // Create and attach our main view\n    this.mainView = new MainView({\n      model: this.me,\n      el: document.body\n    }); // this kicks off our backbutton tracking (browser history)\n    // and will cause the first matching handler in the router\n    // to fire.\n\n    this.router.history.start({\n      root: '/',\n      pushState: true,\n      hashChange: true\n    });\n  },\n\n  /**\n   * This is a helper for navigating around the app.\n     this gets called by a global click handler that handles\n     all the <a> tags in the app.\n     it expects a url pathname for example: \"/costello/settings\"\n   * @param  {any} page [description]\n   */\n  navigate: function navigate(page) {\n    // clean all help items before navigating to new page\n    app.stopHelp();\n    var url = page.charAt(0) === '/' ? page.slice(1) : page;\n    this.router.history.navigate(url, {\n      trigger: true\n    });\n  },\n\n  /**\n   * [description]\n   * @param  {any} percentage [description]\n   */\n  progress: function progress(percentage) {\n    var progressBar = document.getElementById('progress-bar');\n    progressBar.MaterialProgress.setProgress(percentage);\n    progressBar.style.display = 'inherit';\n  },\n\n  /**\n   * [description]\n   * @param  {boolean} status [description]\n   */\n  busy: function busy(callBack) {\n    var that = this;\n    var dialog = document.getElementById('main-dialog');\n    dialogPolyfill.registerDialog(dialog);\n    console.log(dialog);\n    dialog.open = !dialog.open;\n    console.log(dialog);\n  },\n\n  /**\n   * [description]\n   * @param  {any} options [description]\n   */\n  message: function message(options) {\n    var snackbarContainer = document.getElementById('snack-bar');\n    var snackData = {\n      message: options.text\n    }; // BUGFIX: during app initialization, the snackbar is not always ready yet\n\n    if (!snackbarContainer.MaterialSnackbar) {\n      return;\n    }\n\n    var progressBar = document.getElementById('progress-bar');\n    progressBar.style.display = 'none';\n\n    if (options.type === 'error') {\n      console.warn(options.text, options.error);\n      snackData.timeout = 10000; // show error for 10 seconds\n    } else {\n      console.log(options.text);\n      snackData.timeout = 2750;\n    }\n\n    snackbarContainer.MaterialSnackbar.showSnackbar(snackData);\n  },\n\n  /**\n   * [description]\n   */\n  startHelp: function startHelp() {\n    console.log(app.currentPage.helpTemplate);\n    console.log(app.currentPage.helpHints);\n    console.log(app.currentPage.helpSteps);\n\n    if ((!app.currentPage.helpTemplate || app.currentPage.helpTemplate === '') && (!app.currentPage.helpHints || app.currentPage.helpHints() === []) && (!app.currentPage.helpSteps || app.currentPage.helpTemplate === [])) {\n      console.log('No Help item was found for this page! Exiting.');\n      return;\n    }\n\n    console.log(app.helper.enabled);\n\n    if (app.helper.enabled) {\n      console.log('Closing existing help!');\n      app.stopHelp();\n      return;\n    }\n\n    app.helper.enabled = true;\n    console.log(\"app.helper: \", app.helper);\n\n    if (app.currentPage.helpTemplate && app.currentPage.helpTemplate !== '') {\n      console.log(\"Setting intros...\");\n      app.helper.instance.setOptions({\n        steps: [{\n          intro: window[app.currentPage.helpTemplate]()\n        }]\n      });\n    }\n\n    app.helper.instance.setOptions({\n      hints: app.currentPage.helpHints(),\n      steps: app.currentPage.helpSteps()\n    });\n    app.helper.instance.onhintsadded(function () {\n      console.log('all hints added');\n    });\n    app.helper.instance.onhintclick(function (hintElement, item, stepId) {\n      console.log('hint clicked', hintElement, item, stepId);\n    });\n    app.helper.instance.onhintclose(function (stepId) {\n      console.log('hint closed', stepId);\n    });\n    app.helper.instance.addHints();\n    app.helper.instance.showHints(); // app.helper.start();\n  },\n  stopHelp: function stopHelp() {\n    if (app.helper.enabled) {\n      console.log('Closing existing help!'); // app.helper.instance.helper.exit();\n\n      app.helper.instance.hideHints();\n      app.helper.enabled = false;\n      return;\n    }\n  },\n\n  /**\n   * [description]\n   */\n  startWelcome: function startWelcome() {\n    var welcome = Help();\n    welcome.setOption('tooltipClass', 'welcome-dialog');\n    welcome.setOptions({\n      'showStepNumbers': false,\n      'showBullets': false,\n      'showProgress': false,\n      'skipLabel': 'Exit',\n      'doneLabel': 'Start demo',\n      'tooltipPosition': 'auto',\n      steps: [{\n        intro: templates.help.welcome()\n      }]\n    });\n    welcome.onchange(function (targetElement) {\n      if (this._currentStep === this._introItems.length - 1) {\n        $('.introjs-skipbutton').css('color', 'green');\n      }\n    });\n    welcome.oncomplete(function () {\n      window.localStorage.setItem('spotWelcome', 'done');\n      app.message({\n        text: 'Starting the demo session.',\n        type: 'ok'\n      });\n      app.importRemoteSession('https://raw.githubusercontent.com/NLeSC/spot/master/dist/demo.json');\n    }); // add a flag when we exit\n\n    welcome.onexit(function () {\n      window.localStorage.setItem('spotWelcome', 'done');\n    });\n    var spotWelcome = window.localStorage.getItem('spotWelcome') === 'done';\n\n    if (spotWelcome) {// console.log('No need to show welcome dialog again.');\n    } else {\n      console.log('Starting the welcome dialog.');\n      welcome.start();\n    }\n  },\n\n  /**\n   * [description]\n   * @return {boolean} [description]\n   */\n  detectMobile: function detectMobile() {\n    var check = false;\n\n    if (navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/Windows Phone/i)) {\n      check = true;\n    } else {\n      check = false;\n    }\n\n    app.mobileBrowser = check;\n    return check;\n  },\n\n  /**\n   * [description]\n   * @return {} [description]\n   */\n  addDatasetToLocalStorage: function addDatasetToLocalStorage(dataset) {\n    console.log('Adding a dataset to the local storage');\n    console.log(dataset);\n    var allDatasets = this.getDatasetsFromLocalStorage(); // allDatasets.forEach(function(dset, index) {\n    //   console.log(\"[\" + index + \"]: \" + dset.id + '  ', dset.name);\n    // });\n\n    allDatasets.push(dataset);\n    localStorage.setItem('datasets', JSON.stringify(allDatasets));\n  },\n\n  /**\n  * [description]\n  * @return {} [description]\n  */\n  removeDatasetFromLocalStorage: function removeDatasetFromLocalStorage(dataset) {\n    console.log('Removing a dataset from the local storage');\n    console.log(dataset);\n    var allDatasets = this.getDatasetsFromLocalStorage();\n    allDatasets.forEach(function (dset, index) {\n      console.log(\"[\" + index + \"]: \" + dset.id + '  ', dset.name);\n      if (dataset.id === dset.id) allDatasets.splice(index, 1);\n    }); // var index = allDatasets.indexOf(dataset);\n    // if (index > -1) {\n    //   allDatasets.splice(index, 1);\n    // }\n\n    localStorage.setItem('datasets', allDatasets);\n  },\n\n  /**\n  * [description]\n  * @return {} [description]\n  */\n  getDatasetsFromLocalStorage: function getDatasetsFromLocalStorage() {\n    console.log('Getting a list of datasets from the local storage');\n    var allDatasets = JSON.parse(localStorage.getItem('datasets') || \"[]\");\n    return allDatasets;\n  },\n\n  /**\n   * [description]\n   * @return {} [description]\n   */\n  addSessionToLocalStorage: function addSessionToLocalStorage(session) {\n    console.log('Adding a session to the local storage');\n    console.log(session);\n    var allSessions = this.getSessionsFromLocalStorage(); // allDatasets.forEach(function(dset, index) {\n    //   console.log(\"[\" + index + \"]: \" + dset.id + '  ', dset.name);\n    // });\n\n    allSessions.push(session);\n    localStorage.setItem('sessions', JSON.stringify(allSessions));\n  },\n\n  /**\n  * [description]\n  * @return {} [description]\n  */\n  removeSessionFromLocalStorage: function removeSessionFromLocalStorage(input_session) {\n    console.log('Removing a session from the local storage');\n    console.log(input_session);\n    var allSessions = this.getSessionsFromLocalStorage();\n    allSessions.forEach(function (sess, index) {\n      console.log(\"[\" + index + \"]: \" + sess.id + '  ', sess.name);\n      if (input_session.id === sess.id) allSessions.splice(index, 1);\n    });\n    localStorage.setItem('sessions', allSessions);\n  },\n\n  /**\n  * [description]\n  * @return {} [description]\n  */\n  getSessionsFromLocalStorage: function getSessionsFromLocalStorage() {\n    console.log('Getting a list of sessions from the local storage');\n    var allSessions = JSON.parse(localStorage.getItem('sessions') || \"[]\");\n    return allSessions;\n  },\n  getCurrentSession: function getCurrentSession() {\n    var json = app.me.toJSON();\n\n    if (app.me.sessionType === 'client') {\n      // for client datasets, also save the data in the session file\n      app.me.datasets.forEach(function (dataset, i) {\n        json.datasets[i].data = dataset.data;\n      });\n    } // json.saveDate = Date().toLocaleString();\n\n\n    var currentSession = json;\n    return currentSession;\n  },\n  saveCurrentSession: function saveCurrentSession() {\n    var currentSession = this.getCurrentSession();\n    this.addSessionToLocalStorage(currentSession);\n  },\n  importRemoteSession: function importRemoteSession(sessionUrl) {\n    // console.log('app.js: Getting the remote session.');\n    var that = this;\n    app.busy({\n      enable: true\n    });\n    var urlParts = sessionUrl.replace('http://', '').replace('https://', '').split(/[/?#]/);\n    var domain = urlParts[0];\n\n    if (domain === \"sandbox.zenodo.org\" || domain === \"zenodo.org\") {\n      // get files using a proxy to fix CORS issues\n      sessionUrl = 'http://localhost:8000/' + sessionUrl;\n    }\n\n    that.zenodoRequest({\n      base_url: sessionUrl,\n      url_addition: \"\",\n      requestType: \"download\",\n      zenodoId: '',\n      fileHash: ''\n    }).then(function (download_data) {\n      // console.log(download_data);\n      app.busy({\n        enable: false\n      });\n      app.message({\n        text: 'Session was imported succesfully',\n        type: 'ok'\n      });\n      app.loadSessionBlob(download_data);\n    }).catch(function (error_download) {\n      app.busy({\n        enable: false\n      });\n      app.message({\n        text: 'Could not import the session',\n        type: 'error',\n        error: ev\n      });\n      console.error(error_download);\n    });\n  },\n\n  /**\n   * [description]\n   * @param  {any} data [description]\n   */\n  loadSessionBlob: function loadSessionBlob(data) {\n    console.log('Loading the session.');\n    app.me = new Spot(data);\n\n    if (data.sessionType === 'server') {\n      app.me.connectToServer(data.address);\n    } else if (data.sessionType === 'client') {\n      // add data from the session file to the dataset\n      data.datasets.forEach(function (d, i) {\n        app.me.datasets.models[i].crossfilter.add(d.data);\n        app.me.datasets.models[i].isActive = false; // we'll turn it on later\n      }); // merge all the data into the app.me.dataview\n      // by toggling the active datasets back on\n\n      data.datasets.forEach(function (d, i) {\n        if (d.isActive) {\n          app.me.toggleDataset(app.me.datasets.models[i]);\n        }\n      });\n    } // and automatically go to the analyze page\n\n\n    app.navigate('/analyze');\n    app.navigate('/datasets');\n    app.navigate('/analyze');\n  },\n  importJSON: function importJSON() {\n    // var fileLoader = this.queryByHook('json-upload-input');\n    var fileLoader = document.getElementById('jsonuploadBtn');\n    var uploadedFile = fileLoader.files[0];\n    var reader = new window.FileReader();\n    var dataURL = fileLoader.files[0].name; // TODO: enforce spot.driver === 'client'\n\n    var dataset = app.me.datasets.add({\n      name: dataURL,\n      URL: dataURL,\n      description: 'uploaded JSON file'\n    });\n\n    reader.onload = function (ev) {\n      app.message({\n        text: 'Processing',\n        type: 'ok'\n      });\n\n      try {\n        dataset.data = JSON.parse(ev.target.result); // automatically analyze dataset\n\n        dataset.scan();\n        dataset.facets.forEach(function (facet, i) {\n          if (i < 20) {\n            facet.isActive = true;\n\n            if (facet.isCategorial) {\n              facet.setCategories();\n            } else if (facet.isContinuous || facet.isDatetime || facet.isDuration) {\n              facet.setMinMax();\n            }\n          }\n        });\n        app.message({\n          text: dataURL + ' was uploaded succesfully. Configured ' + dataset.facets.length + ' facets',\n          type: 'ok'\n        });\n        window.componentHandler.upgradeDom(); // Automatically activate dataset if it is the only one\n\n        if (app.me.datasets.length === 1) {\n          $('.mdl-switch').click(); // only way to get the switch in the 'on' position\n        }\n      } catch (ev) {\n        app.me.datasets.remove(dataset);\n        app.message({\n          text: 'Error parsing JSON file: ' + ev,\n          type: 'error',\n          error: ev\n        });\n      }\n    };\n\n    reader.onerror = function (ev) {\n      var error = ev.srcElement.error;\n      app.message({\n        text: 'File loading problem: ' + error,\n        type: 'error',\n        error: ev\n      });\n    };\n\n    reader.onprogress = function (ev) {\n      if (ev.lengthComputable) {\n        // ev.loaded and ev.total are ProgressEvent properties\n        app.progress(parseInt(100.0 * ev.loaded / ev.total));\n      }\n    };\n\n    reader.readAsText(uploadedFile);\n  },\n  importCSV: function importCSV() {\n    // var fileLoader = this.queryByHook('csv-upload-input');\n    var fileLoader = document.getElementById('csvuploadBtn');\n    var uploadedFile = fileLoader.files[0];\n    var reader = new window.FileReader();\n    var dataURL = fileLoader.files[0].name; // TODO: enforce spot.driver === 'client'\n\n    var dataset = app.me.datasets.add({\n      name: dataURL,\n      URL: dataURL,\n      description: 'Imported CSV file'\n    });\n\n    reader.onload = function (ev) {\n      app.message({\n        text: 'Processing',\n        type: 'ok'\n      });\n      var options = {\n        columns: app.CSVHeaders,\n        // treat first line as header with column names\n        relax_column_count: false,\n        // accept malformed lines\n        delimiter: app.CSVSeparator,\n        // field delimieter\n        quote: app.CSVQuote,\n        // String quoting character\n        comment: app.CSVComment,\n        // Treat all the characters after this one as a comment.\n        trim: true // ignore white space around delimiter\n\n      };\n      csv.parse(ev.target.result, options, function (err, data) {\n        if (err) {\n          app.me.datasets.remove(dataset);\n          app.message({\n            text: 'Error parsing CSV file: ' + err.message,\n            type: 'error',\n            error: ev\n          });\n        } else {\n          dataset.data = data; // automatically analyze dataset\n\n          dataset.scan();\n          dataset.facets.forEach(function (facet, i) {\n            if (i < 20) {\n              facet.isActive = true;\n\n              if (facet.isCategorial) {\n                facet.setCategories();\n              } else if (facet.isContinuous || facet.isDatetime || facet.isDuration) {\n                facet.setMinMax();\n              }\n            }\n          });\n          app.addDatasetToLocalStorage(dataset);\n          app.message({\n            text: dataURL + ' was uploaded succesfully. Configured ' + dataset.facets.length + ' facets',\n            type: 'ok'\n          });\n          window.componentHandler.upgradeDom(); // Automatically activate dataset if it is the only one\n\n          if (app.me.datasets.length === 1) {\n            $('.mdl-switch').click(); // only way to get the switch in the 'on' position\n          }\n        }\n      });\n    };\n\n    reader.onerror = function (ev) {\n      app.me.datasets.remove(dataset);\n      app.message({\n        text: 'File loading problem: ' + reader.error,\n        type: 'error',\n        error: reader.error\n      });\n    };\n\n    reader.onprogress = function (ev) {\n      if (ev.lengthComputable) {\n        // ev.loaded and ev.total are ProgressEvent properties\n        app.progress(parseInt(100.0 * ev.loaded / ev.total));\n      }\n    };\n\n    reader.readAsText(uploadedFile);\n  },\n  exportSession: function exportSession() {\n    var json = app.me.toJSON();\n\n    if (app.me.sessionType === 'client') {\n      // for client datasets, also save the data in the session file\n      app.me.datasets.forEach(function (dataset, i) {\n        json.datasets[i].data = dataset.data;\n      });\n    }\n\n    var blob = new window.Blob([JSON.stringify(json)], {\n      type: 'application/json'\n    });\n    var url = window.URL.createObjectURL(blob);\n    var element = document.createElement('a');\n    element.download = 'session.json';\n    element.href = url;\n    element.click();\n    window.URL.revokeObjectURL(url);\n  },\n  exportData: function exportData() {\n    var chartsData = [];\n    var partitionRankToName = {\n      1: 'a',\n      2: 'b',\n      3: 'c',\n      4: 'd'\n    };\n    var aggregateRankToName = {\n      1: 'aa',\n      2: 'bb',\n      3: 'cc',\n      4: 'dd',\n      5: 'ee'\n    };\n    app.me.dataview.filters.forEach(function (filter) {\n      var map = {};\n      var axis = [];\n      filter.partitions.forEach(function (partition) {\n        map[partitionRankToName[partition.rank]] = partition.facetName;\n        axis.push(partition.facetName);\n      });\n      filter.aggregates.forEach(function (aggregate) {\n        map[aggregateRankToName[aggregate.rank]] = aggregate.operation + ' ' + aggregate.facetName;\n      });\n      map['count'] = 'count';\n      var data = [];\n      filter.data.forEach(function (d) {\n        var mapped = {};\n        Object.keys(d).forEach(function (k) {\n          if (map[k]) {\n            mapped[map[k]] = d[k];\n          }\n        });\n        data.push(mapped);\n      });\n      chartsData.push({\n        chartType: filter.chartType,\n        axis: axis.join(','),\n        data: data\n      });\n    });\n    var blob = new window.Blob([JSON.stringify(chartsData)], {\n      type: 'application/json'\n    });\n    var url = window.URL.createObjectURL(blob);\n    var element = document.createElement('a');\n    element.download = 'data.json';\n    element.href = url;\n    element.click();\n    window.URL.revokeObjectURL(url);\n  },\n  importLocalSession: function importLocalSession() {\n    // var fileLoader = this.queryByHook('session-upload-input');\n    var fileLoader = document.getElementById('sessionuploadBtn');\n    var uploadedFile = fileLoader.files[0];\n    var reader = new window.FileReader();\n\n    reader.onload = function (ev) {\n      var data = JSON.parse(ev.target.result);\n      app.loadSessionBlob(data);\n      app.message({\n        text: 'Session \"' + uploadedFile.name + '\" was uploaded succesfully',\n        type: 'ok'\n      });\n    };\n\n    reader.onerror = function (ev) {\n      app.message({\n        text: 'Could not load Session \"' + uploadedFile.name + '\"',\n        type: 'error',\n        error: ev\n      });\n    };\n\n    reader.readAsText(uploadedFile);\n  },\n  zenodoRequest: function () {\n    var _zenodoRequest = _asyncToGenerator(\n    /*#__PURE__*/\n    regeneratorRuntime.mark(function _callee(zenodoParams) {\n      var url_addition, requestType, bodyData, base_url, zenodoToken, url, params, request_options, response, data;\n      return regeneratorRuntime.wrap(function _callee$(_context) {\n        while (1) {\n          switch (_context.prev = _context.next) {\n            case 0:\n              url_addition = zenodoParams.url_addition;\n              requestType = zenodoParams.requestType;\n              bodyData = zenodoParams.bodyData; // console.log('requestType:', requestType);\n\n              base_url = new URL(\"https://sandbox.zenodo.org/api/deposit/depositions\");\n\n              if (zenodoParams.base_url) {\n                base_url = zenodoParams.base_url;\n              }\n\n              zenodoToken = \"AddYourTokenHere\";\n\n              if (url_addition) {\n                // console.log(\" Addition is provided: \", url_addition);\n                base_url = base_url + \"/\" + url_addition;\n              }\n\n              url = new URL(base_url), params = {\n                access_token: zenodoToken\n              };\n              Object.keys(params).forEach(function (key) {\n                url.searchParams.append(key, params[key]);\n              }); // console.log('Zenodo base_url:', base_url);\n              // console.log('Zenodo url:', url);\n\n              request_options = {};\n\n              if (requestType === \"doi\") {\n                request_options = {\n                  cache: \"no-cache\",\n                  method: \"POST\",\n                  headers: {\n                    \"Content-Type\": \"application/json\"\n                  },\n                  body: JSON.stringify(bodyData)\n                };\n              } else if (requestType === \"upload\") {\n                request_options = {\n                  cache: \"no-cache\",\n                  method: \"POST\",\n                  body: bodyData\n                };\n              } else if (requestType === \"publish\") {\n                request_options = {\n                  cache: \"no-cache\",\n                  method: \"POST\"\n                };\n              } else if (requestType === \"meta\") {\n                request_options = {\n                  cache: \"no-cache\",\n                  method: \"PUT\",\n                  headers: {\n                    \"Content-Type\": \"application/json\"\n                  },\n                  body: JSON.stringify(bodyData)\n                };\n              } else if (requestType === \"download\") {\n                request_options = {\n                  cache: \"no-cache\",\n                  method: \"GET\",\n                  withCredentials: true\n                };\n              } else {\n                console.error('Unknown method');\n              } // console.log('request_options: ', request_options);\n\n\n              _context.next = 13;\n              return fetch(url, request_options);\n\n            case 13:\n              response = _context.sent;\n              _context.next = 16;\n              return response.json();\n\n            case 16:\n              data = _context.sent;\n              return _context.abrupt(\"return\", data);\n\n            case 18:\n            case \"end\":\n              return _context.stop();\n          }\n        }\n      }, _callee);\n    }));\n\n    function zenodoRequest(_x) {\n      return _zenodoRequest.apply(this, arguments);\n    }\n\n    return zenodoRequest;\n  }()\n});\n/**\n * run it on domReady\n */\n\ndomReady(function () {\n  app.init();\n\n  if (false) {}\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTIxOC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9hcHAuanM/MTExMiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgU3BvdCA9IHJlcXVpcmUoJ3Nwb3QtZnJhbWV3b3JrJyk7XG52YXIgYXBwID0gcmVxdWlyZSgnYW1wZXJzYW5kLWFwcCcpO1xudmFyIFJvdXRlciA9IHJlcXVpcmUoJy4vcm91dGVyJyk7XG52YXIgTWFpblZpZXcgPSByZXF1aXJlKCcuL3BhZ2VzL21haW4nKTtcbnZhciBEYXRhc2V0c1ZpZXcgPSByZXF1aXJlKCcuL3BhZ2VzL2RhdGFzZXRzJyk7XG52YXIgZG9tUmVhZHkgPSByZXF1aXJlKCdkb21yZWFkeScpO1xudmFyIHdpZGdldEZhY3RvcnkgPSByZXF1aXJlKCcuL3dpZGdldHMvd2lkZ2V0LWZhY3RvcnknKTtcbnZhciB2aWV3RmFjdG9yeSA9IHJlcXVpcmUoJy4vd2lkZ2V0cy92aWV3LWZhY3RvcnknKTtcbnZhciBDb2xsZWN0aW9uID0gcmVxdWlyZSgnYW1wZXJzYW5kLWNvbGxlY3Rpb24nKTtcblxudmFyIFNlc3Npb25Nb2RlbCA9IHJlcXVpcmUoJy4vcGFnZXMvZGF0YXNldHMvc2Vzc2lvbi1tb2RlbCcpO1xudmFyIGRpYWxvZ1BvbHlmaWxsID0gcmVxdWlyZSgnZGlhbG9nLXBvbHlmaWxsJyk7XG5cbnZhciBIZWxwID0gcmVxdWlyZSgnaW50cm8uanMnKTtcbnZhciB0ZW1wbGF0ZXMgPSByZXF1aXJlKCcuL3RlbXBsYXRlcycpO1xudmFyIGNzdiA9IHJlcXVpcmUoJ2NzdicpO1xudmFyICQgPSByZXF1aXJlKCdqcXVlcnknKTtcblxucmVxdWlyZSgnYmFiZWwtcG9seWZpbGwnKTtcbnJlcXVpcmUoJ21kbCcpO1xuXG52YXIgc2Vzc2lvbkNvbGxlY3Rpb24gPSBDb2xsZWN0aW9uLmV4dGVuZCh7XG4gIG1haW5JbmRleDogJ2lkJyxcbiAgaW5kZXhlczogWyduYW1lJ10sXG4gIG1vZGVsOiBTZXNzaW9uTW9kZWxcbn0pO1xuXG4vLyBhdHRhY2ggb3VyIGFwcCB0byBgd2luZG93YCBzbyB3ZSBjYW5cbi8vIGVhc2lseSBhY2Nlc3MgaXQgZnJvbSB0aGUgY29uc29sZS5cbndpbmRvdy5hcHAgPSBhcHA7XG5cbi8vIEV4dGVuZHMgb3VyIG1haW4gYXBwIHNpbmdsZXRvblxuYXBwLmV4dGVuZCh7XG4gIC8qKlxuICAgKiBbZnVsbHNjcmVlbk1vZGUgZGVzY3JpcHRpb25dXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKi9cbiAgZnVsbHNjcmVlbk1vZGU6IGZhbHNlLFxuICAvKipcbiAgICogW2RlbW9TZXNzaW9uIGRlc2NyaXB0aW9uXVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICovXG4gIGRlbW9TZXNzaW9uOiBmYWxzZSxcbiAgLyoqXG4gICAqIFttb2JpbGVCcm93c2VyIGRlc2NyaXB0aW9uXVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICovXG4gIG1vYmlsZUJyb3dzZXI6IGZhbHNlLFxuICAvKipcbiAgICogW21lIGRlc2NyaXB0aW9uXVxuICAgKiBAdHlwZSB7U3BvdH1cbiAgICovXG4gIG1lOiBuZXcgU3BvdCgpLFxuICAvKipcbiAgICogW3dpZGdldEZhY3RvcnkgZGVzY3JpcHRpb25dXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICB3aWRnZXRGYWN0b3J5OiB3aWRnZXRGYWN0b3J5LFxuICAvKipcbiAgICogW3ZpZXdGYWN0b3J5IGRlc2NyaXB0aW9uXVxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgdmlld0ZhY3Rvcnk6IHZpZXdGYWN0b3J5LFxuICAvKipcbiAgICogW3JvdXRlciBkZXNjcmlwdGlvbl1cbiAgICogQHR5cGUge1JvdXRlcn1cbiAgICovXG4gIHJvdXRlcjogbmV3IFJvdXRlcigpLFxuICAvKipcbiAgICogW0NTVlNlcGFyYXRvciBkZXNjcmlwdGlvbl1cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICovXG4gIENTVlNlcGFyYXRvcjogJywnLFxuICAvKipcbiAgICogW0NTVkhlYWRlcnMgZGVzY3JpcHRpb25dXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKi9cbiAgQ1NWSGVhZGVyczogdHJ1ZSxcbiAgLyoqXG4gICAqIFtDU1ZRdW90ZSBkZXNjcmlwdGlvbl1cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICovXG4gIENTVlF1b3RlOiAnXCInLFxuICAvKipcbiAgICogW0NTVkNvbW1lbnQgZGVzY3JpcHRpb25dXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqL1xuICBDU1ZDb21tZW50OiAnIycsXG5cbiAgaGVscGVyOiB7ZW5hYmxlZDogZmFsc2UsIGluc3RhbmNlOiBuZXcgSGVscCgpfSxcblxuICAvKipcbiAgICogW3Nlc3Npb25zIGRlc2NyaXB0aW9uXVxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc2Vzc2lvbnM6IG5ldyBzZXNzaW9uQ29sbGVjdGlvbigpLFxuICAvKipcbiAgICogVGhpcyBpcyB3aGVyZSBpdCBhbGwgc3RhcnRzXG4gICAqL1xuICBpbml0OiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gQ3JlYXRlIGFuZCBhdHRhY2ggb3VyIG1haW4gdmlld1xuICAgIHRoaXMubWFpblZpZXcgPSBuZXcgTWFpblZpZXcoe1xuICAgICAgbW9kZWw6IHRoaXMubWUsXG4gICAgICBlbDogZG9jdW1lbnQuYm9keVxuICAgIH0pO1xuXG4gICAgLy8gdGhpcyBraWNrcyBvZmYgb3VyIGJhY2tidXR0b24gdHJhY2tpbmcgKGJyb3dzZXIgaGlzdG9yeSlcbiAgICAvLyBhbmQgd2lsbCBjYXVzZSB0aGUgZmlyc3QgbWF0Y2hpbmcgaGFuZGxlciBpbiB0aGUgcm91dGVyXG4gICAgLy8gdG8gZmlyZS5cbiAgICB0aGlzLnJvdXRlci5oaXN0b3J5LnN0YXJ0KHtcbiAgICAgIHJvb3Q6ICcvJyxcbiAgICAgIHB1c2hTdGF0ZTogdHJ1ZSxcbiAgICAgIGhhc2hDaGFuZ2U6IHRydWVcbiAgICB9KTtcbiAgfSxcbiAgLyoqXG4gICAqIFRoaXMgaXMgYSBoZWxwZXIgZm9yIG5hdmlnYXRpbmcgYXJvdW5kIHRoZSBhcHAuXG4gICAgIHRoaXMgZ2V0cyBjYWxsZWQgYnkgYSBnbG9iYWwgY2xpY2sgaGFuZGxlciB0aGF0IGhhbmRsZXNcbiAgICAgYWxsIHRoZSA8YT4gdGFncyBpbiB0aGUgYXBwLlxuICAgICBpdCBleHBlY3RzIGEgdXJsIHBhdGhuYW1lIGZvciBleGFtcGxlOiBcIi9jb3N0ZWxsby9zZXR0aW5nc1wiXG4gICAqIEBwYXJhbSAge2FueX0gcGFnZSBbZGVzY3JpcHRpb25dXG4gICAqL1xuICBuYXZpZ2F0ZTogZnVuY3Rpb24gKHBhZ2UpIHtcblxuICAgIC8vIGNsZWFuIGFsbCBoZWxwIGl0ZW1zIGJlZm9yZSBuYXZpZ2F0aW5nIHRvIG5ldyBwYWdlXG4gICAgYXBwLnN0b3BIZWxwKCk7XG5cbiAgICB2YXIgdXJsID0gKHBhZ2UuY2hhckF0KDApID09PSAnLycpID8gcGFnZS5zbGljZSgxKSA6IHBhZ2U7XG4gICAgdGhpcy5yb3V0ZXIuaGlzdG9yeS5uYXZpZ2F0ZSh1cmwsIHtcbiAgICAgIHRyaWdnZXI6IHRydWVcbiAgICB9KTtcbiAgfSxcbiAgLyoqXG4gICAqIFtkZXNjcmlwdGlvbl1cbiAgICogQHBhcmFtICB7YW55fSBwZXJjZW50YWdlIFtkZXNjcmlwdGlvbl1cbiAgICovXG4gIHByb2dyZXNzOiBmdW5jdGlvbiAocGVyY2VudGFnZSkge1xuICAgIHZhciBwcm9ncmVzc0JhciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcm9ncmVzcy1iYXInKTtcbiAgICBwcm9ncmVzc0Jhci5NYXRlcmlhbFByb2dyZXNzLnNldFByb2dyZXNzKHBlcmNlbnRhZ2UpO1xuXG4gICAgcHJvZ3Jlc3NCYXIuc3R5bGUuZGlzcGxheSA9ICdpbmhlcml0JztcbiAgfSxcbiAgLyoqXG4gICAqIFtkZXNjcmlwdGlvbl1cbiAgICogQHBhcmFtICB7Ym9vbGVhbn0gc3RhdHVzIFtkZXNjcmlwdGlvbl1cbiAgICovXG4gIGJ1c3k6IGZ1bmN0aW9uIChjYWxsQmFjaykge1xuICAgIHZhciB0aGF0ID0gdGhpcztcblxuICAgIHZhciBkaWFsb2cgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbWFpbi1kaWFsb2cnKTtcbiAgICBkaWFsb2dQb2x5ZmlsbC5yZWdpc3RlckRpYWxvZyhkaWFsb2cpO1xuXG4gICAgY29uc29sZS5sb2coZGlhbG9nKTtcbiAgICBkaWFsb2cub3BlbiA9ICFkaWFsb2cub3BlbjtcbiAgICBjb25zb2xlLmxvZyhkaWFsb2cpO1xuICB9LFxuICAvKipcbiAgICogW2Rlc2NyaXB0aW9uXVxuICAgKiBAcGFyYW0gIHthbnl9IG9wdGlvbnMgW2Rlc2NyaXB0aW9uXVxuICAgKi9cbiAgbWVzc2FnZTogZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICB2YXIgc25hY2tiYXJDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25hY2stYmFyJyk7XG4gICAgdmFyIHNuYWNrRGF0YSA9IHsgbWVzc2FnZTogb3B0aW9ucy50ZXh0IH07XG5cbiAgICAvLyBCVUdGSVg6IGR1cmluZyBhcHAgaW5pdGlhbGl6YXRpb24sIHRoZSBzbmFja2JhciBpcyBub3QgYWx3YXlzIHJlYWR5IHlldFxuICAgIGlmICghc25hY2tiYXJDb250YWluZXIuTWF0ZXJpYWxTbmFja2Jhcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBwcm9ncmVzc0JhciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcm9ncmVzcy1iYXInKTtcbiAgICBwcm9ncmVzc0Jhci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXG4gICAgaWYgKG9wdGlvbnMudHlwZSA9PT0gJ2Vycm9yJykge1xuICAgICAgY29uc29sZS53YXJuKG9wdGlvbnMudGV4dCwgb3B0aW9ucy5lcnJvcik7XG4gICAgICBzbmFja0RhdGEudGltZW91dCA9IDEwMDAwOyAvLyBzaG93IGVycm9yIGZvciAxMCBzZWNvbmRzXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKG9wdGlvbnMudGV4dCk7XG4gICAgICBzbmFja0RhdGEudGltZW91dCA9IDI3NTA7XG4gICAgfVxuICAgIHNuYWNrYmFyQ29udGFpbmVyLk1hdGVyaWFsU25hY2tiYXIuc2hvd1NuYWNrYmFyKHNuYWNrRGF0YSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFtkZXNjcmlwdGlvbl1cbiAgICovXG4gIHN0YXJ0SGVscDogZnVuY3Rpb24gKCkge1xuXG4gICAgY29uc29sZS5sb2coYXBwLmN1cnJlbnRQYWdlLmhlbHBUZW1wbGF0ZSk7XG4gICAgY29uc29sZS5sb2coYXBwLmN1cnJlbnRQYWdlLmhlbHBIaW50cyk7XG4gICAgY29uc29sZS5sb2coYXBwLmN1cnJlbnRQYWdlLmhlbHBTdGVwcyk7XG4gICAgaWYgKFxuICAgICAgKCFhcHAuY3VycmVudFBhZ2UuaGVscFRlbXBsYXRlIHx8IGFwcC5jdXJyZW50UGFnZS5oZWxwVGVtcGxhdGUgPT09ICcnKSAmJlxuICAgICAgKCFhcHAuY3VycmVudFBhZ2UuaGVscEhpbnRzIHx8IGFwcC5jdXJyZW50UGFnZS5oZWxwSGludHMoKSA9PT0gW10pICYmXG4gICAgICAoIWFwcC5jdXJyZW50UGFnZS5oZWxwU3RlcHMgfHwgYXBwLmN1cnJlbnRQYWdlLmhlbHBUZW1wbGF0ZSA9PT0gW10pXG4gICAgKSB7XG4gICAgICBjb25zb2xlLmxvZygnTm8gSGVscCBpdGVtIHdhcyBmb3VuZCBmb3IgdGhpcyBwYWdlISBFeGl0aW5nLicpXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc29sZS5sb2coYXBwLmhlbHBlci5lbmFibGVkKTtcblxuICAgIGlmIChhcHAuaGVscGVyLmVuYWJsZWQpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdDbG9zaW5nIGV4aXN0aW5nIGhlbHAhJyk7XG4gICAgICBhcHAuc3RvcEhlbHAoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhcHAuaGVscGVyLmVuYWJsZWQgPSB0cnVlO1xuXG4gICAgY29uc29sZS5sb2coXCJhcHAuaGVscGVyOiBcIiwgYXBwLmhlbHBlcik7XG5cbiAgICBpZiAoYXBwLmN1cnJlbnRQYWdlLmhlbHBUZW1wbGF0ZSAmJiBhcHAuY3VycmVudFBhZ2UuaGVscFRlbXBsYXRlICE9PSAnJykge1xuICAgICAgY29uc29sZS5sb2coXCJTZXR0aW5nIGludHJvcy4uLlwiKTtcbiAgICAgIGFwcC5oZWxwZXIuaW5zdGFuY2Uuc2V0T3B0aW9ucyh7XG4gICAgICAgIHN0ZXBzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaW50cm86IHdpbmRvd1thcHAuY3VycmVudFBhZ2UuaGVscFRlbXBsYXRlXSgpXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBhcHAuaGVscGVyLmluc3RhbmNlLnNldE9wdGlvbnMoe1xuICAgICAgaGludHM6IGFwcC5jdXJyZW50UGFnZS5oZWxwSGludHMoKSxcbiAgICAgIHN0ZXBzOiBhcHAuY3VycmVudFBhZ2UuaGVscFN0ZXBzKClcbiAgICB9KTtcblxuICAgIGFwcC5oZWxwZXIuaW5zdGFuY2Uub25oaW50c2FkZGVkKGZ1bmN0aW9uKCkge1xuICAgICAgICBjb25zb2xlLmxvZygnYWxsIGhpbnRzIGFkZGVkJyk7XG4gICAgfSk7XG4gICAgYXBwLmhlbHBlci5pbnN0YW5jZS5vbmhpbnRjbGljayhmdW5jdGlvbihoaW50RWxlbWVudCwgaXRlbSwgc3RlcElkKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdoaW50IGNsaWNrZWQnLCBoaW50RWxlbWVudCwgaXRlbSwgc3RlcElkKTtcbiAgICB9KTtcbiAgICBhcHAuaGVscGVyLmluc3RhbmNlLm9uaGludGNsb3NlKGZ1bmN0aW9uIChzdGVwSWQpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ2hpbnQgY2xvc2VkJywgc3RlcElkKTtcbiAgICB9KTtcblxuICAgIGFwcC5oZWxwZXIuaW5zdGFuY2UuYWRkSGludHMoKTtcbiAgICBhcHAuaGVscGVyLmluc3RhbmNlLnNob3dIaW50cygpO1xuICAgIC8vIGFwcC5oZWxwZXIuc3RhcnQoKTtcbiAgfSxcbiAgc3RvcEhlbHA6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoYXBwLmhlbHBlci5lbmFibGVkKSB7XG4gICAgICBjb25zb2xlLmxvZygnQ2xvc2luZyBleGlzdGluZyBoZWxwIScpO1xuICAgICAgLy8gYXBwLmhlbHBlci5pbnN0YW5jZS5oZWxwZXIuZXhpdCgpO1xuICAgICAgYXBwLmhlbHBlci5pbnN0YW5jZS5oaWRlSGludHMoKTtcbiAgICAgIGFwcC5oZWxwZXIuZW5hYmxlZCA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfSxcbiAgLyoqXG4gICAqIFtkZXNjcmlwdGlvbl1cbiAgICovXG4gIHN0YXJ0V2VsY29tZTogZnVuY3Rpb24gKCkge1xuICAgIHZhciB3ZWxjb21lID0gSGVscCgpO1xuICAgIHdlbGNvbWUuc2V0T3B0aW9uKCd0b29sdGlwQ2xhc3MnLCAnd2VsY29tZS1kaWFsb2cnKTtcbiAgICB3ZWxjb21lLnNldE9wdGlvbnMoe1xuICAgICAgJ3Nob3dTdGVwTnVtYmVycyc6IGZhbHNlLFxuICAgICAgJ3Nob3dCdWxsZXRzJzogZmFsc2UsXG4gICAgICAnc2hvd1Byb2dyZXNzJzogZmFsc2UsXG4gICAgICAnc2tpcExhYmVsJzogJ0V4aXQnLFxuICAgICAgJ2RvbmVMYWJlbCc6ICdTdGFydCBkZW1vJyxcbiAgICAgICd0b29sdGlwUG9zaXRpb24nOiAnYXV0bycsXG4gICAgICBzdGVwczogW1xuICAgICAgICB7XG4gICAgICAgICAgaW50cm86IHRlbXBsYXRlcy5oZWxwLndlbGNvbWUoKVxuICAgICAgICB9XG4gICAgICBdXG4gICAgfSk7XG5cbiAgICB3ZWxjb21lLm9uY2hhbmdlKGZ1bmN0aW9uICh0YXJnZXRFbGVtZW50KSB7XG4gICAgICBpZiAodGhpcy5fY3VycmVudFN0ZXAgPT09IHRoaXMuX2ludHJvSXRlbXMubGVuZ3RoIC0gMSkge1xuICAgICAgICAkKCcuaW50cm9qcy1za2lwYnV0dG9uJykuY3NzKCdjb2xvcicsICdncmVlbicpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgd2VsY29tZS5vbmNvbXBsZXRlKGZ1bmN0aW9uICgpIHtcbiAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnc3BvdFdlbGNvbWUnLCAnZG9uZScpO1xuICAgICAgYXBwLm1lc3NhZ2Uoe1xuICAgICAgICB0ZXh0OiAnU3RhcnRpbmcgdGhlIGRlbW8gc2Vzc2lvbi4nLFxuICAgICAgICB0eXBlOiAnb2snXG4gICAgICB9KTtcbiAgICAgIGFwcC5pbXBvcnRSZW1vdGVTZXNzaW9uKCdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vTkxlU0Mvc3BvdC9tYXN0ZXIvZGlzdC9kZW1vLmpzb24nKTtcbiAgICB9KTtcblxuICAgIC8vIGFkZCBhIGZsYWcgd2hlbiB3ZSBleGl0XG4gICAgd2VsY29tZS5vbmV4aXQoZnVuY3Rpb24gKCkge1xuICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKCdzcG90V2VsY29tZScsICdkb25lJyk7XG4gICAgfSk7XG5cbiAgICB2YXIgc3BvdFdlbGNvbWUgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oJ3Nwb3RXZWxjb21lJykgPT09ICdkb25lJztcbiAgICBpZiAoc3BvdFdlbGNvbWUpIHtcbiAgICAgIC8vIGNvbnNvbGUubG9nKCdObyBuZWVkIHRvIHNob3cgd2VsY29tZSBkaWFsb2cgYWdhaW4uJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKCdTdGFydGluZyB0aGUgd2VsY29tZSBkaWFsb2cuJyk7XG4gICAgICB3ZWxjb21lLnN0YXJ0KCk7XG4gICAgfVxuICB9LFxuICAvKipcbiAgICogW2Rlc2NyaXB0aW9uXVxuICAgKiBAcmV0dXJuIHtib29sZWFufSBbZGVzY3JpcHRpb25dXG4gICAqL1xuICBkZXRlY3RNb2JpbGU6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY2hlY2sgPSBmYWxzZTtcbiAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKSB8fFxuICAgIG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL3dlYk9TL2kpIHx8XG4gICAgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lL2kpIHx8XG4gICAgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZC9pKSB8fFxuICAgIG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQb2QvaSkgfHxcbiAgICBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9CbGFja0JlcnJ5L2kpIHx8XG4gICAgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvV2luZG93cyBQaG9uZS9pKVxuICAgKSB7XG4gICAgICBjaGVjayA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNoZWNrID0gZmFsc2U7XG4gICAgfVxuICAgIGFwcC5tb2JpbGVCcm93c2VyID0gY2hlY2s7XG4gICAgcmV0dXJuIGNoZWNrO1xuICB9LFxuXG4gIC8qKlxuICAgKiBbZGVzY3JpcHRpb25dXG4gICAqIEByZXR1cm4ge30gW2Rlc2NyaXB0aW9uXVxuICAgKi9cbiAgYWRkRGF0YXNldFRvTG9jYWxTdG9yYWdlOiBmdW5jdGlvbihkYXRhc2V0KSB7XG4gICAgY29uc29sZS5sb2coJ0FkZGluZyBhIGRhdGFzZXQgdG8gdGhlIGxvY2FsIHN0b3JhZ2UnKTtcbiAgICBjb25zb2xlLmxvZyhkYXRhc2V0KTtcbiAgICB2YXIgYWxsRGF0YXNldHMgPSB0aGlzLmdldERhdGFzZXRzRnJvbUxvY2FsU3RvcmFnZSgpO1xuICAgIC8vIGFsbERhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24oZHNldCwgaW5kZXgpIHtcbiAgICAvLyAgIGNvbnNvbGUubG9nKFwiW1wiICsgaW5kZXggKyBcIl06IFwiICsgZHNldC5pZCArICcgICcsIGRzZXQubmFtZSk7XG4gICAgLy8gfSk7XG4gICAgYWxsRGF0YXNldHMucHVzaChkYXRhc2V0KTtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnZGF0YXNldHMnLCBKU09OLnN0cmluZ2lmeShhbGxEYXRhc2V0cykpO1xuICB9LFxuICAgIC8qKlxuICAgKiBbZGVzY3JpcHRpb25dXG4gICAqIEByZXR1cm4ge30gW2Rlc2NyaXB0aW9uXVxuICAgKi9cbiAgcmVtb3ZlRGF0YXNldEZyb21Mb2NhbFN0b3JhZ2U6IGZ1bmN0aW9uKGRhdGFzZXQpIHtcbiAgICBjb25zb2xlLmxvZygnUmVtb3ZpbmcgYSBkYXRhc2V0IGZyb20gdGhlIGxvY2FsIHN0b3JhZ2UnKTtcbiAgICBjb25zb2xlLmxvZyhkYXRhc2V0KTtcbiAgICB2YXIgYWxsRGF0YXNldHMgPSB0aGlzLmdldERhdGFzZXRzRnJvbUxvY2FsU3RvcmFnZSgpO1xuICAgIGFsbERhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24oZHNldCwgaW5kZXgpIHtcbiAgICAgIGNvbnNvbGUubG9nKFwiW1wiICsgaW5kZXggKyBcIl06IFwiICsgZHNldC5pZCArICcgICcsIGRzZXQubmFtZSk7XG4gICAgICBpZiAoIGRhdGFzZXQuaWQgPT09IGRzZXQuaWQgKVxuICAgICAgICBhbGxEYXRhc2V0cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH0pO1xuICAgIC8vIHZhciBpbmRleCA9IGFsbERhdGFzZXRzLmluZGV4T2YoZGF0YXNldCk7XG4gICAgLy8gaWYgKGluZGV4ID4gLTEpIHtcbiAgICAvLyAgIGFsbERhdGFzZXRzLnNwbGljZShpbmRleCwgMSk7XG4gICAgLy8gfVxuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdkYXRhc2V0cycsIGFsbERhdGFzZXRzKTtcbiAgfSxcbiAgICAvKipcbiAgICogW2Rlc2NyaXB0aW9uXVxuICAgKiBAcmV0dXJuIHt9IFtkZXNjcmlwdGlvbl1cbiAgICovXG4gIGdldERhdGFzZXRzRnJvbUxvY2FsU3RvcmFnZTogZnVuY3Rpb24oKSB7XG4gICAgY29uc29sZS5sb2coJ0dldHRpbmcgYSBsaXN0IG9mIGRhdGFzZXRzIGZyb20gdGhlIGxvY2FsIHN0b3JhZ2UnKTtcbiAgICB2YXIgYWxsRGF0YXNldHMgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdkYXRhc2V0cycpIHx8IFwiW11cIik7XG4gICAgcmV0dXJuIGFsbERhdGFzZXRzO1xuICB9LFxuICAvKipcbiAgICogW2Rlc2NyaXB0aW9uXVxuICAgKiBAcmV0dXJuIHt9IFtkZXNjcmlwdGlvbl1cbiAgICovXG4gIGFkZFNlc3Npb25Ub0xvY2FsU3RvcmFnZTogZnVuY3Rpb24oc2Vzc2lvbikge1xuICAgIGNvbnNvbGUubG9nKCdBZGRpbmcgYSBzZXNzaW9uIHRvIHRoZSBsb2NhbCBzdG9yYWdlJyk7XG4gICAgY29uc29sZS5sb2coc2Vzc2lvbik7XG4gICAgdmFyIGFsbFNlc3Npb25zID0gdGhpcy5nZXRTZXNzaW9uc0Zyb21Mb2NhbFN0b3JhZ2UoKTtcbiAgICAvLyBhbGxEYXRhc2V0cy5mb3JFYWNoKGZ1bmN0aW9uKGRzZXQsIGluZGV4KSB7XG4gICAgLy8gICBjb25zb2xlLmxvZyhcIltcIiArIGluZGV4ICsgXCJdOiBcIiArIGRzZXQuaWQgKyAnICAnLCBkc2V0Lm5hbWUpO1xuICAgIC8vIH0pO1xuICAgIGFsbFNlc3Npb25zLnB1c2goc2Vzc2lvbik7XG4gICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ3Nlc3Npb25zJywgSlNPTi5zdHJpbmdpZnkoYWxsU2Vzc2lvbnMpKTtcbiAgfSxcbiAgICAvKipcbiAgICogW2Rlc2NyaXB0aW9uXVxuICAgKiBAcmV0dXJuIHt9IFtkZXNjcmlwdGlvbl1cbiAgICovXG4gIHJlbW92ZVNlc3Npb25Gcm9tTG9jYWxTdG9yYWdlOiBmdW5jdGlvbihpbnB1dF9zZXNzaW9uKSB7XG4gICAgY29uc29sZS5sb2coJ1JlbW92aW5nIGEgc2Vzc2lvbiBmcm9tIHRoZSBsb2NhbCBzdG9yYWdlJyk7XG4gICAgY29uc29sZS5sb2coaW5wdXRfc2Vzc2lvbik7XG4gICAgdmFyIGFsbFNlc3Npb25zID0gdGhpcy5nZXRTZXNzaW9uc0Zyb21Mb2NhbFN0b3JhZ2UoKTtcbiAgICBhbGxTZXNzaW9ucy5mb3JFYWNoKGZ1bmN0aW9uKHNlc3MsIGluZGV4KSB7XG4gICAgICBjb25zb2xlLmxvZyhcIltcIiArIGluZGV4ICsgXCJdOiBcIiArIHNlc3MuaWQgKyAnICAnLCBzZXNzLm5hbWUpO1xuICAgICAgaWYgKCBpbnB1dF9zZXNzaW9uLmlkID09PSBzZXNzLmlkIClcbiAgICAgICAgYWxsU2Vzc2lvbnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9KTtcblxuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdzZXNzaW9ucycsIGFsbFNlc3Npb25zKTtcbiAgfSxcbiAgICAvKipcbiAgICogW2Rlc2NyaXB0aW9uXVxuICAgKiBAcmV0dXJuIHt9IFtkZXNjcmlwdGlvbl1cbiAgICovXG4gIGdldFNlc3Npb25zRnJvbUxvY2FsU3RvcmFnZTogZnVuY3Rpb24oKSB7XG4gICAgY29uc29sZS5sb2coJ0dldHRpbmcgYSBsaXN0IG9mIHNlc3Npb25zIGZyb20gdGhlIGxvY2FsIHN0b3JhZ2UnKTtcbiAgICB2YXIgYWxsU2Vzc2lvbnMgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdzZXNzaW9ucycpIHx8IFwiW11cIik7XG4gICAgcmV0dXJuIGFsbFNlc3Npb25zO1xuICB9LFxuICBnZXRDdXJyZW50U2Vzc2lvbjogZnVuY3Rpb24gKCkge1xuICAgIHZhciBqc29uID0gYXBwLm1lLnRvSlNPTigpO1xuICAgIGlmIChhcHAubWUuc2Vzc2lvblR5cGUgPT09ICdjbGllbnQnKSB7XG4gICAgICAvLyBmb3IgY2xpZW50IGRhdGFzZXRzLCBhbHNvIHNhdmUgdGhlIGRhdGEgaW4gdGhlIHNlc3Npb24gZmlsZVxuICAgICAgYXBwLm1lLmRhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24gKGRhdGFzZXQsIGkpIHtcbiAgICAgICAganNvbi5kYXRhc2V0c1tpXS5kYXRhID0gZGF0YXNldC5kYXRhO1xuICAgICAgfSk7XG4gICAgfVxuICAgIC8vIGpzb24uc2F2ZURhdGUgPSBEYXRlKCkudG9Mb2NhbGVTdHJpbmcoKTtcbiAgICB2YXIgY3VycmVudFNlc3Npb24gPSBqc29uO1xuICAgIHJldHVybiBjdXJyZW50U2Vzc2lvbjtcbiAgfSxcbiAgc2F2ZUN1cnJlbnRTZXNzaW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGN1cnJlbnRTZXNzaW9uID0gdGhpcy5nZXRDdXJyZW50U2Vzc2lvbigpO1xuICAgIHRoaXMuYWRkU2Vzc2lvblRvTG9jYWxTdG9yYWdlKGN1cnJlbnRTZXNzaW9uKTtcbiAgfSxcbiAgaW1wb3J0UmVtb3RlU2Vzc2lvbjogZnVuY3Rpb24gKHNlc3Npb25VcmwpIHtcbiAgICAvLyBjb25zb2xlLmxvZygnYXBwLmpzOiBHZXR0aW5nIHRoZSByZW1vdGUgc2Vzc2lvbi4nKTtcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgICBhcHAuYnVzeSh7ZW5hYmxlOiB0cnVlfSk7XG5cbiAgICB2YXIgdXJsUGFydHMgPSBzZXNzaW9uVXJsLnJlcGxhY2UoJ2h0dHA6Ly8nLCcnKS5yZXBsYWNlKCdodHRwczovLycsJycpLnNwbGl0KC9bLz8jXS8pO1xuICAgIHZhciBkb21haW4gPSB1cmxQYXJ0c1swXTtcblxuICAgIGlmICggKGRvbWFpbiA9PT0gXCJzYW5kYm94Lnplbm9kby5vcmdcIikgfHwgKGRvbWFpbiA9PT0gXCJ6ZW5vZG8ub3JnXCIpICkge1xuICAgICAgLy8gZ2V0IGZpbGVzIHVzaW5nIGEgcHJveHkgdG8gZml4IENPUlMgaXNzdWVzXG4gICAgICBzZXNzaW9uVXJsID0gJ2h0dHA6Ly9sb2NhbGhvc3Q6ODAwMC8nICsgc2Vzc2lvblVybDtcbiAgICB9XG5cbiAgICB0aGF0Lnplbm9kb1JlcXVlc3Qoe1xuICAgICAgYmFzZV91cmw6IHNlc3Npb25VcmwsXG4gICAgICB1cmxfYWRkaXRpb246XCJcIixcbiAgICAgIHJlcXVlc3RUeXBlOlwiZG93bmxvYWRcIixcbiAgICAgIHplbm9kb0lkOiAnJyxcbiAgICAgIGZpbGVIYXNoOiAnJ1xuICAgIH0pLnRoZW4oZnVuY3Rpb24oZG93bmxvYWRfZGF0YSkge1xuICAgICAgLy8gY29uc29sZS5sb2coZG93bmxvYWRfZGF0YSk7XG4gICAgICBhcHAuYnVzeSh7ZW5hYmxlOiBmYWxzZX0pO1xuICAgICAgYXBwLm1lc3NhZ2Uoe1xuICAgICAgICB0ZXh0OiAnU2Vzc2lvbiB3YXMgaW1wb3J0ZWQgc3VjY2VzZnVsbHknLFxuICAgICAgICB0eXBlOiAnb2snXG4gICAgICB9KTtcbiAgICAgIGFwcC5sb2FkU2Vzc2lvbkJsb2IoZG93bmxvYWRfZGF0YSk7XG4gICAgfSkuY2F0Y2goZnVuY3Rpb24oZXJyb3JfZG93bmxvYWQpe1xuICAgICAgYXBwLmJ1c3koe2VuYWJsZTogZmFsc2V9KTtcbiAgICAgIGFwcC5tZXNzYWdlKHtcbiAgICAgICAgdGV4dDogJ0NvdWxkIG5vdCBpbXBvcnQgdGhlIHNlc3Npb24nLFxuICAgICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgICBlcnJvcjogZXZcbiAgICAgIH0pO1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcl9kb3dubG9hZCk7XG4gICAgfSk7XG5cbiAgfSxcbiAgLyoqXG4gICAqIFtkZXNjcmlwdGlvbl1cbiAgICogQHBhcmFtICB7YW55fSBkYXRhIFtkZXNjcmlwdGlvbl1cbiAgICovXG4gIGxvYWRTZXNzaW9uQmxvYjogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBjb25zb2xlLmxvZygnTG9hZGluZyB0aGUgc2Vzc2lvbi4nKTtcbiAgICBhcHAubWUgPSBuZXcgU3BvdChkYXRhKTtcblxuICAgIGlmIChkYXRhLnNlc3Npb25UeXBlID09PSAnc2VydmVyJykge1xuICAgICAgYXBwLm1lLmNvbm5lY3RUb1NlcnZlcihkYXRhLmFkZHJlc3MpO1xuICAgIH0gZWxzZSBpZiAoZGF0YS5zZXNzaW9uVHlwZSA9PT0gJ2NsaWVudCcpIHtcbiAgICAgIC8vIGFkZCBkYXRhIGZyb20gdGhlIHNlc3Npb24gZmlsZSB0byB0aGUgZGF0YXNldFxuICAgICAgZGF0YS5kYXRhc2V0cy5mb3JFYWNoKGZ1bmN0aW9uIChkLCBpKSB7XG4gICAgICAgIGFwcC5tZS5kYXRhc2V0cy5tb2RlbHNbaV0uY3Jvc3NmaWx0ZXIuYWRkKGQuZGF0YSk7XG4gICAgICAgIGFwcC5tZS5kYXRhc2V0cy5tb2RlbHNbaV0uaXNBY3RpdmUgPSBmYWxzZTsgLy8gd2UnbGwgdHVybiBpdCBvbiBsYXRlclxuICAgICAgfSk7XG4gICAgICAvLyBtZXJnZSBhbGwgdGhlIGRhdGEgaW50byB0aGUgYXBwLm1lLmRhdGF2aWV3XG4gICAgICAvLyBieSB0b2dnbGluZyB0aGUgYWN0aXZlIGRhdGFzZXRzIGJhY2sgb25cbiAgICAgIGRhdGEuZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZCwgaSkge1xuICAgICAgICBpZiAoZC5pc0FjdGl2ZSkge1xuICAgICAgICAgIGFwcC5tZS50b2dnbGVEYXRhc2V0KGFwcC5tZS5kYXRhc2V0cy5tb2RlbHNbaV0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gYW5kIGF1dG9tYXRpY2FsbHkgZ28gdG8gdGhlIGFuYWx5emUgcGFnZVxuICAgIGFwcC5uYXZpZ2F0ZSgnL2FuYWx5emUnKTsgICAgXG4gICAgYXBwLm5hdmlnYXRlKCcvZGF0YXNldHMnKTtcbiAgICBhcHAubmF2aWdhdGUoJy9hbmFseXplJyk7XG4gIH0sXG4gIGltcG9ydEpTT046IGZ1bmN0aW9uICgpIHtcbiAgICAvLyB2YXIgZmlsZUxvYWRlciA9IHRoaXMucXVlcnlCeUhvb2soJ2pzb24tdXBsb2FkLWlucHV0Jyk7XG4gICAgdmFyIGZpbGVMb2FkZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnanNvbnVwbG9hZEJ0bicpO1xuICAgIHZhciB1cGxvYWRlZEZpbGUgPSBmaWxlTG9hZGVyLmZpbGVzWzBdO1xuICAgIHZhciByZWFkZXIgPSBuZXcgd2luZG93LkZpbGVSZWFkZXIoKTtcbiAgICB2YXIgZGF0YVVSTCA9IGZpbGVMb2FkZXIuZmlsZXNbMF0ubmFtZTtcblxuICAgIC8vIFRPRE86IGVuZm9yY2Ugc3BvdC5kcml2ZXIgPT09ICdjbGllbnQnXG5cbiAgICB2YXIgZGF0YXNldCA9IGFwcC5tZS5kYXRhc2V0cy5hZGQoe1xuICAgICAgbmFtZTogZGF0YVVSTCxcbiAgICAgIFVSTDogZGF0YVVSTCxcbiAgICAgIGRlc2NyaXB0aW9uOiAndXBsb2FkZWQgSlNPTiBmaWxlJ1xuICAgIH0pO1xuXG4gICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgYXBwLm1lc3NhZ2Uoe1xuICAgICAgICB0ZXh0OiAnUHJvY2Vzc2luZycsXG4gICAgICAgIHR5cGU6ICdvaydcbiAgICAgIH0pO1xuICAgICAgdHJ5IHtcbiAgICAgICAgZGF0YXNldC5kYXRhID0gSlNPTi5wYXJzZShldi50YXJnZXQucmVzdWx0KTtcblxuICAgICAgICAvLyBhdXRvbWF0aWNhbGx5IGFuYWx5emUgZGF0YXNldFxuICAgICAgICBkYXRhc2V0LnNjYW4oKTtcbiAgICAgICAgZGF0YXNldC5mYWNldHMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQsIGkpIHtcbiAgICAgICAgICBpZiAoaSA8IDIwKSB7XG4gICAgICAgICAgICBmYWNldC5pc0FjdGl2ZSA9IHRydWU7XG5cbiAgICAgICAgICAgIGlmIChmYWNldC5pc0NhdGVnb3JpYWwpIHtcbiAgICAgICAgICAgICAgZmFjZXQuc2V0Q2F0ZWdvcmllcygpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChmYWNldC5pc0NvbnRpbnVvdXMgfHwgZmFjZXQuaXNEYXRldGltZSB8fCBmYWNldC5pc0R1cmF0aW9uKSB7XG4gICAgICAgICAgICAgIGZhY2V0LnNldE1pbk1heCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGFwcC5tZXNzYWdlKHtcbiAgICAgICAgICB0ZXh0OiBkYXRhVVJMICsgJyB3YXMgdXBsb2FkZWQgc3VjY2VzZnVsbHkuIENvbmZpZ3VyZWQgJyArIGRhdGFzZXQuZmFjZXRzLmxlbmd0aCArICcgZmFjZXRzJyxcbiAgICAgICAgICB0eXBlOiAnb2snXG4gICAgICAgIH0pO1xuICAgICAgICB3aW5kb3cuY29tcG9uZW50SGFuZGxlci51cGdyYWRlRG9tKCk7XG5cbiAgICAgICAgLy8gQXV0b21hdGljYWxseSBhY3RpdmF0ZSBkYXRhc2V0IGlmIGl0IGlzIHRoZSBvbmx5IG9uZVxuICAgICAgICBpZiAoYXBwLm1lLmRhdGFzZXRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICQoJy5tZGwtc3dpdGNoJykuY2xpY2soKTsgLy8gb25seSB3YXkgdG8gZ2V0IHRoZSBzd2l0Y2ggaW4gdGhlICdvbicgcG9zaXRpb25cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXYpIHtcbiAgICAgICAgYXBwLm1lLmRhdGFzZXRzLnJlbW92ZShkYXRhc2V0KTtcbiAgICAgICAgYXBwLm1lc3NhZ2Uoe1xuICAgICAgICAgIHRleHQ6ICdFcnJvciBwYXJzaW5nIEpTT04gZmlsZTogJyArIGV2LFxuICAgICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgICAgZXJyb3I6IGV2XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZWFkZXIub25lcnJvciA9IGZ1bmN0aW9uIChldikge1xuICAgICAgdmFyIGVycm9yID0gZXYuc3JjRWxlbWVudC5lcnJvcjtcblxuICAgICAgYXBwLm1lc3NhZ2Uoe1xuICAgICAgICB0ZXh0OiAnRmlsZSBsb2FkaW5nIHByb2JsZW06ICcgKyBlcnJvcixcbiAgICAgICAgdHlwZTogJ2Vycm9yJyxcbiAgICAgICAgZXJyb3I6IGV2XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgcmVhZGVyLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgIGlmIChldi5sZW5ndGhDb21wdXRhYmxlKSB7XG4gICAgICAgIC8vIGV2LmxvYWRlZCBhbmQgZXYudG90YWwgYXJlIFByb2dyZXNzRXZlbnQgcHJvcGVydGllc1xuICAgICAgICBhcHAucHJvZ3Jlc3MocGFyc2VJbnQoMTAwLjAgKiBldi5sb2FkZWQgLyBldi50b3RhbCkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZWFkZXIucmVhZEFzVGV4dCh1cGxvYWRlZEZpbGUpO1xuICB9LFxuICBpbXBvcnRDU1Y6IGZ1bmN0aW9uICgpIHtcbiAgICAvLyB2YXIgZmlsZUxvYWRlciA9IHRoaXMucXVlcnlCeUhvb2soJ2Nzdi11cGxvYWQtaW5wdXQnKTtcbiAgICB2YXIgZmlsZUxvYWRlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjc3Z1cGxvYWRCdG4nKTtcbiAgICB2YXIgdXBsb2FkZWRGaWxlID0gZmlsZUxvYWRlci5maWxlc1swXTtcbiAgICB2YXIgcmVhZGVyID0gbmV3IHdpbmRvdy5GaWxlUmVhZGVyKCk7XG4gICAgdmFyIGRhdGFVUkwgPSBmaWxlTG9hZGVyLmZpbGVzWzBdLm5hbWU7XG5cbiAgICAvLyBUT0RPOiBlbmZvcmNlIHNwb3QuZHJpdmVyID09PSAnY2xpZW50J1xuXG4gICAgdmFyIGRhdGFzZXQgPSBhcHAubWUuZGF0YXNldHMuYWRkKHtcbiAgICAgIG5hbWU6IGRhdGFVUkwsXG4gICAgICBVUkw6IGRhdGFVUkwsXG4gICAgICBkZXNjcmlwdGlvbjogJ0ltcG9ydGVkIENTViBmaWxlJ1xuICAgIH0pO1xuXG4gICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgYXBwLm1lc3NhZ2Uoe1xuICAgICAgICB0ZXh0OiAnUHJvY2Vzc2luZycsXG4gICAgICAgIHR5cGU6ICdvaydcbiAgICAgIH0pO1xuICAgICAgdmFyIG9wdGlvbnMgPSB7XG4gICAgICAgIGNvbHVtbnM6IGFwcC5DU1ZIZWFkZXJzLCAvLyB0cmVhdCBmaXJzdCBsaW5lIGFzIGhlYWRlciB3aXRoIGNvbHVtbiBuYW1lc1xuICAgICAgICByZWxheF9jb2x1bW5fY291bnQ6IGZhbHNlLCAvLyBhY2NlcHQgbWFsZm9ybWVkIGxpbmVzXG4gICAgICAgIGRlbGltaXRlcjogYXBwLkNTVlNlcGFyYXRvciwgLy8gZmllbGQgZGVsaW1pZXRlclxuICAgICAgICBxdW90ZTogYXBwLkNTVlF1b3RlLCAvLyBTdHJpbmcgcXVvdGluZyBjaGFyYWN0ZXJcbiAgICAgICAgY29tbWVudDogYXBwLkNTVkNvbW1lbnQsIC8vIFRyZWF0IGFsbCB0aGUgY2hhcmFjdGVycyBhZnRlciB0aGlzIG9uZSBhcyBhIGNvbW1lbnQuXG4gICAgICAgIHRyaW06IHRydWUgLy8gaWdub3JlIHdoaXRlIHNwYWNlIGFyb3VuZCBkZWxpbWl0ZXJcbiAgICAgIH07XG5cbiAgICAgIGNzdi5wYXJzZShldi50YXJnZXQucmVzdWx0LCBvcHRpb25zLCBmdW5jdGlvbiAoZXJyLCBkYXRhKSB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICBhcHAubWUuZGF0YXNldHMucmVtb3ZlKGRhdGFzZXQpO1xuICAgICAgICAgIGFwcC5tZXNzYWdlKHtcbiAgICAgICAgICAgIHRleHQ6ICdFcnJvciBwYXJzaW5nIENTViBmaWxlOiAnICsgZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgICAgICAgZXJyb3I6IGV2XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGF0YXNldC5kYXRhID0gZGF0YTtcblxuICAgICAgICAgIC8vIGF1dG9tYXRpY2FsbHkgYW5hbHl6ZSBkYXRhc2V0XG4gICAgICAgICAgZGF0YXNldC5zY2FuKCk7XG4gICAgICAgICAgZGF0YXNldC5mYWNldHMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQsIGkpIHtcbiAgICAgICAgICAgIGlmIChpIDwgMjApIHtcbiAgICAgICAgICAgICAgZmFjZXQuaXNBY3RpdmUgPSB0cnVlO1xuXG4gICAgICAgICAgICAgIGlmIChmYWNldC5pc0NhdGVnb3JpYWwpIHtcbiAgICAgICAgICAgICAgICBmYWNldC5zZXRDYXRlZ29yaWVzKCk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoZmFjZXQuaXNDb250aW51b3VzIHx8IGZhY2V0LmlzRGF0ZXRpbWUgfHwgZmFjZXQuaXNEdXJhdGlvbikge1xuICAgICAgICAgICAgICAgIGZhY2V0LnNldE1pbk1heCgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYXBwLmFkZERhdGFzZXRUb0xvY2FsU3RvcmFnZShkYXRhc2V0KTtcbiAgICAgICAgICBhcHAubWVzc2FnZSh7XG4gICAgICAgICAgICB0ZXh0OiBkYXRhVVJMICsgJyB3YXMgdXBsb2FkZWQgc3VjY2VzZnVsbHkuIENvbmZpZ3VyZWQgJyArIGRhdGFzZXQuZmFjZXRzLmxlbmd0aCArICcgZmFjZXRzJyxcbiAgICAgICAgICAgIHR5cGU6ICdvaydcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB3aW5kb3cuY29tcG9uZW50SGFuZGxlci51cGdyYWRlRG9tKCk7XG5cbiAgICAgICAgICAvLyBBdXRvbWF0aWNhbGx5IGFjdGl2YXRlIGRhdGFzZXQgaWYgaXQgaXMgdGhlIG9ubHkgb25lXG4gICAgICAgICAgaWYgKGFwcC5tZS5kYXRhc2V0cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICQoJy5tZGwtc3dpdGNoJykuY2xpY2soKTsgLy8gb25seSB3YXkgdG8gZ2V0IHRoZSBzd2l0Y2ggaW4gdGhlICdvbicgcG9zaXRpb25cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZWFkZXIub25lcnJvciA9IGZ1bmN0aW9uIChldikge1xuICAgICAgYXBwLm1lLmRhdGFzZXRzLnJlbW92ZShkYXRhc2V0KTtcbiAgICAgIGFwcC5tZXNzYWdlKHtcbiAgICAgICAgdGV4dDogJ0ZpbGUgbG9hZGluZyBwcm9ibGVtOiAnICsgcmVhZGVyLmVycm9yLFxuICAgICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgICBlcnJvcjogcmVhZGVyLmVycm9yXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgcmVhZGVyLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgIGlmIChldi5sZW5ndGhDb21wdXRhYmxlKSB7XG4gICAgICAgIC8vIGV2LmxvYWRlZCBhbmQgZXYudG90YWwgYXJlIFByb2dyZXNzRXZlbnQgcHJvcGVydGllc1xuICAgICAgICBhcHAucHJvZ3Jlc3MocGFyc2VJbnQoMTAwLjAgKiBldi5sb2FkZWQgLyBldi50b3RhbCkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZWFkZXIucmVhZEFzVGV4dCh1cGxvYWRlZEZpbGUpO1xuICB9LFxuICBleHBvcnRTZXNzaW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGpzb24gPSBhcHAubWUudG9KU09OKCk7XG5cbiAgICBpZiAoYXBwLm1lLnNlc3Npb25UeXBlID09PSAnY2xpZW50Jykge1xuICAgICAgLy8gZm9yIGNsaWVudCBkYXRhc2V0cywgYWxzbyBzYXZlIHRoZSBkYXRhIGluIHRoZSBzZXNzaW9uIGZpbGVcbiAgICAgIGFwcC5tZS5kYXRhc2V0cy5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhc2V0LCBpKSB7XG4gICAgICAgIGpzb24uZGF0YXNldHNbaV0uZGF0YSA9IGRhdGFzZXQuZGF0YTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB2YXIgYmxvYiA9IG5ldyB3aW5kb3cuQmxvYihbSlNPTi5zdHJpbmdpZnkoanNvbildLCB7dHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nfSk7XG4gICAgdmFyIHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuXG4gICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgZWxlbWVudC5kb3dubG9hZCA9ICdzZXNzaW9uLmpzb24nO1xuICAgIGVsZW1lbnQuaHJlZiA9IHVybDtcbiAgICBlbGVtZW50LmNsaWNrKCk7XG5cbiAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICB9LFxuICBleHBvcnREYXRhOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNoYXJ0c0RhdGEgPSBbXTtcblxuICAgIHZhciBwYXJ0aXRpb25SYW5rVG9OYW1lID0gezE6ICdhJywgMjogJ2InLCAzOiAnYycsIDQ6ICdkJ307XG4gICAgdmFyIGFnZ3JlZ2F0ZVJhbmtUb05hbWUgPSB7MTogJ2FhJywgMjogJ2JiJywgMzogJ2NjJywgNDogJ2RkJywgNTogJ2VlJ307XG5cbiAgICBhcHAubWUuZGF0YXZpZXcuZmlsdGVycy5mb3JFYWNoKGZ1bmN0aW9uIChmaWx0ZXIpIHtcbiAgICAgIHZhciBtYXAgPSB7fTtcbiAgICAgIHZhciBheGlzID0gW107XG4gICAgICBmaWx0ZXIucGFydGl0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgICAgICAgbWFwW3BhcnRpdGlvblJhbmtUb05hbWVbcGFydGl0aW9uLnJhbmtdXSA9IHBhcnRpdGlvbi5mYWNldE5hbWU7XG4gICAgICAgIGF4aXMucHVzaChwYXJ0aXRpb24uZmFjZXROYW1lKTtcbiAgICAgIH0pO1xuICAgICAgZmlsdGVyLmFnZ3JlZ2F0ZXMuZm9yRWFjaChmdW5jdGlvbiAoYWdncmVnYXRlKSB7XG4gICAgICAgIG1hcFthZ2dyZWdhdGVSYW5rVG9OYW1lW2FnZ3JlZ2F0ZS5yYW5rXV0gPSBhZ2dyZWdhdGUub3BlcmF0aW9uICsgJyAnICsgYWdncmVnYXRlLmZhY2V0TmFtZTtcbiAgICAgIH0pO1xuICAgICAgbWFwWydjb3VudCddID0gJ2NvdW50JztcblxuICAgICAgdmFyIGRhdGEgPSBbXTtcbiAgICAgIGZpbHRlci5kYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgdmFyIG1hcHBlZCA9IHt9O1xuICAgICAgICBPYmplY3Qua2V5cyhkKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgaWYgKG1hcFtrXSkge1xuICAgICAgICAgICAgbWFwcGVkW21hcFtrXV0gPSBkW2tdO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGRhdGEucHVzaChtYXBwZWQpO1xuICAgICAgfSk7XG4gICAgICBjaGFydHNEYXRhLnB1c2goe1xuICAgICAgICBjaGFydFR5cGU6IGZpbHRlci5jaGFydFR5cGUsXG4gICAgICAgIGF4aXM6IGF4aXMuam9pbignLCcpLFxuICAgICAgICBkYXRhOiBkYXRhXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHZhciBibG9iID0gbmV3IHdpbmRvdy5CbG9iKFtKU09OLnN0cmluZ2lmeShjaGFydHNEYXRhKV0sIHt0eXBlOiAnYXBwbGljYXRpb24vanNvbid9KTtcbiAgICB2YXIgdXJsID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG5cbiAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBlbGVtZW50LmRvd25sb2FkID0gJ2RhdGEuanNvbic7XG4gICAgZWxlbWVudC5ocmVmID0gdXJsO1xuICAgIGVsZW1lbnQuY2xpY2soKTtcblxuICAgIHdpbmRvdy5VUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gIH0sXG4gIGltcG9ydExvY2FsU2Vzc2lvbjogZnVuY3Rpb24gKCkge1xuICAgIC8vIHZhciBmaWxlTG9hZGVyID0gdGhpcy5xdWVyeUJ5SG9vaygnc2Vzc2lvbi11cGxvYWQtaW5wdXQnKTtcbiAgICB2YXIgZmlsZUxvYWRlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZXNzaW9udXBsb2FkQnRuJyk7XG4gICAgdmFyIHVwbG9hZGVkRmlsZSA9IGZpbGVMb2FkZXIuZmlsZXNbMF07XG4gICAgdmFyIHJlYWRlciA9IG5ldyB3aW5kb3cuRmlsZVJlYWRlcigpO1xuXG4gICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgdmFyIGRhdGEgPSBKU09OLnBhcnNlKGV2LnRhcmdldC5yZXN1bHQpO1xuICAgICAgYXBwLmxvYWRTZXNzaW9uQmxvYihkYXRhKTtcbiAgICAgIGFwcC5tZXNzYWdlKHtcbiAgICAgICAgdGV4dDogJ1Nlc3Npb24gXCInICsgdXBsb2FkZWRGaWxlLm5hbWUgKyAnXCIgd2FzIHVwbG9hZGVkIHN1Y2Nlc2Z1bGx5JyxcbiAgICAgICAgdHlwZTogJ29rJ1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIHJlYWRlci5vbmVycm9yID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICBhcHAubWVzc2FnZSh7XG4gICAgICAgIHRleHQ6ICdDb3VsZCBub3QgbG9hZCBTZXNzaW9uIFwiJyArIHVwbG9hZGVkRmlsZS5uYW1lICsgJ1wiJyxcbiAgICAgICAgdHlwZTogJ2Vycm9yJyxcbiAgICAgICAgZXJyb3I6IGV2XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgcmVhZGVyLnJlYWRBc1RleHQodXBsb2FkZWRGaWxlKTtcbiAgfSxcbiAgemVub2RvUmVxdWVzdDogYXN5bmMgZnVuY3Rpb24oemVub2RvUGFyYW1zKSB7XG5cbiAgICB2YXIgdXJsX2FkZGl0aW9uID0gemVub2RvUGFyYW1zLnVybF9hZGRpdGlvbjtcbiAgICB2YXIgcmVxdWVzdFR5cGUgPSB6ZW5vZG9QYXJhbXMucmVxdWVzdFR5cGU7XG4gICAgdmFyIGJvZHlEYXRhID0gemVub2RvUGFyYW1zLmJvZHlEYXRhO1xuICAgIC8vIGNvbnNvbGUubG9nKCdyZXF1ZXN0VHlwZTonLCByZXF1ZXN0VHlwZSk7XG5cbiAgICB2YXIgYmFzZV91cmwgPSBuZXcgVVJMKFwiaHR0cHM6Ly9zYW5kYm94Lnplbm9kby5vcmcvYXBpL2RlcG9zaXQvZGVwb3NpdGlvbnNcIik7XG5cbiAgICBpZiAoemVub2RvUGFyYW1zLmJhc2VfdXJsKXtcbiAgICAgIGJhc2VfdXJsID0gemVub2RvUGFyYW1zLmJhc2VfdXJsO1xuICAgIH1cblxuICAgIHZhciB6ZW5vZG9Ub2tlbiA9IHByb2Nlc3MuZW52LlpFTk9ET19UT0tFTjtcbiAgICBpZiAodXJsX2FkZGl0aW9uKSB7XG4gICAgICAvLyBjb25zb2xlLmxvZyhcIiBBZGRpdGlvbiBpcyBwcm92aWRlZDogXCIsIHVybF9hZGRpdGlvbik7XG4gICAgICBiYXNlX3VybCA9IGJhc2VfdXJsICsgXCIvXCIgKyB1cmxfYWRkaXRpb247XG4gICAgfVxuICAgIHZhciB1cmwgPSBuZXcgVVJMKGJhc2VfdXJsKSxcbiAgICBwYXJhbXMgPSB7XG4gICAgICBhY2Nlc3NfdG9rZW46IHplbm9kb1Rva2VuXG4gICAgfTtcbiAgICBPYmplY3Qua2V5cyhwYXJhbXMpLmZvckVhY2goZnVuY3Rpb24oa2V5KXtcbiAgICAgIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKGtleSwgcGFyYW1zW2tleV0pO1xuICAgIH0pO1xuXG4gICAgLy8gY29uc29sZS5sb2coJ1plbm9kbyBiYXNlX3VybDonLCBiYXNlX3VybCk7XG4gICAgLy8gY29uc29sZS5sb2coJ1plbm9kbyB1cmw6JywgdXJsKTtcblxuICAgIHZhciByZXF1ZXN0X29wdGlvbnMgPSB7fTtcblxuICAgIGlmIChyZXF1ZXN0VHlwZSA9PT0gXCJkb2lcIikge1xuICAgICAgcmVxdWVzdF9vcHRpb25zID0ge1xuICAgICAgICBjYWNoZTogXCJuby1jYWNoZVwiLFxuICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJvZHlEYXRhKVxuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmIChyZXF1ZXN0VHlwZSA9PT0gXCJ1cGxvYWRcIikge1xuICAgICAgcmVxdWVzdF9vcHRpb25zID0ge1xuICAgICAgICBjYWNoZTogXCJuby1jYWNoZVwiLFxuICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICBib2R5OiBib2R5RGF0YVxuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmIChyZXF1ZXN0VHlwZSA9PT0gXCJwdWJsaXNoXCIpIHtcbiAgICAgIHJlcXVlc3Rfb3B0aW9ucyA9IHtcbiAgICAgICAgY2FjaGU6IFwibm8tY2FjaGVcIixcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAocmVxdWVzdFR5cGUgPT09IFwibWV0YVwiKSB7XG4gICAgICByZXF1ZXN0X29wdGlvbnMgPSB7XG4gICAgICAgIGNhY2hlOiBcIm5vLWNhY2hlXCIsXG4gICAgICAgIG1ldGhvZDogXCJQVVRcIixcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiXG4gICAgICAgIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJvZHlEYXRhKVxuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmIChyZXF1ZXN0VHlwZSA9PT0gXCJkb3dubG9hZFwiKSB7XG4gICAgICByZXF1ZXN0X29wdGlvbnMgPSB7XG4gICAgICAgIGNhY2hlOiBcIm5vLWNhY2hlXCIsXG4gICAgICAgIG1ldGhvZDogXCJHRVRcIixcbiAgICAgICAgd2l0aENyZWRlbnRpYWxzOiB0cnVlLFxuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1Vua25vd24gbWV0aG9kJyk7XG4gICAgfVxuXG4gICAgLy8gY29uc29sZS5sb2coJ3JlcXVlc3Rfb3B0aW9uczogJywgcmVxdWVzdF9vcHRpb25zKTtcblxuICAgIHZhciByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCwgcmVxdWVzdF9vcHRpb25zKTtcbiAgICB2YXIgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxufSk7XG5cbi8qKlxuICogcnVuIGl0IG9uIGRvbVJlYWR5XG4gKi9cbmRvbVJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgYXBwLmluaXQoKTtcblxuICBpZiAoIHByb2Nlc3MuZW52Lk1PREUgPT09ICdzZXJ2ZXInICkge1xuICAgIGNvbnNvbGUubG9nKCdjb25uZWN0aW5nIHRvIGRhdGFiYXNlIGF0JywgcHJvY2Vzcy5lbnYuREJfU0VSVkVSICsgXCI6XCIgKyBwcm9jZXNzLmVudi5EQl9TRVJWRVJfUE9SVCk7XG4gICAgYXBwLm1lLmlzTG9ja2VkRG93biA9IHRydWU7XG4gICAgYXBwLm1lLmNvbm5lY3RUb1NlcnZlcihwcm9jZXNzLmVudi5EQl9TRVJWRVIgKyBcIjpcIiArIHByb2Nlc3MuZW52LkRCX1NFUlZFUl9QT1JUKTtcbiAgICBhcHAubWUuc29ja2V0LmVtaXQoJ2dldERhdGFzZXRzJyk7XG4gIH1cbn0pO1xuXG4iXSwibWFwcGluZ3MiOiI7Ozs7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFPQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFBQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBTUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFBQTs7Ozs7OztBQU9BO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUFBOzs7O0FBSUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBREE7QUFGQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQURBO0FBUkE7QUFjQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFBQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFBQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFPQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBRUE7QUFDQTtBQUFBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQVBBO0FBU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBRUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUVBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFOQTtBQVFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBRUE7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBTkE7QUFRQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBM0VBO0FBQUE7QUFDQTtBQURBO0FBNkVBO0FBN0VBO0FBQUE7QUFDQTtBQURBO0FBOEVBO0FBOUVBO0FBQ0E7QUFEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUFBO0FBL3JCQTtBQWt4QkE7Ozs7QUFHQTtBQUNBO0FBQ0E7QUFDQSxlQUtBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9218\n")},"96da":function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar CategorialRuleView = __webpack_require__(/*! ./categorial-rule */ \"c783\");\n\nmodule.exports = View.extend({\n  template: templates.configureFacet.facetTransformCategorial,\n  render: function render() {\n    this.renderWithTemplate(this);\n    this.renderCollection(this.model.rules, CategorialRuleView, this.queryByHook('categorial-rules-table'));\n    return this;\n  },\n  events: {\n    'click [data-hook~=categorial-addone-button]': function clickDataHookCategorialAddoneButton() {\n      this.model.rules.add({});\n    },\n    'click [data-hook~=categorial-removeall-button]': function clickDataHookCategorialRemoveallButton() {\n      this.model.reset();\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTZkYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZmFjZXQvZmFjZXQtdHJhbnNmb3JtLWNhdGVnb3JpYWwuanM/ZmJlMyJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgVmlldyA9IHJlcXVpcmUoJ2FtcGVyc2FuZC12aWV3Jyk7XG52YXIgdGVtcGxhdGVzID0gcmVxdWlyZSgnLi4vLi4vdGVtcGxhdGVzJyk7XG5cbnZhciBDYXRlZ29yaWFsUnVsZVZpZXcgPSByZXF1aXJlKCcuL2NhdGVnb3JpYWwtcnVsZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZXcuZXh0ZW5kKHtcbiAgdGVtcGxhdGU6IHRlbXBsYXRlcy5jb25maWd1cmVGYWNldC5mYWNldFRyYW5zZm9ybUNhdGVnb3JpYWwsXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVuZGVyV2l0aFRlbXBsYXRlKHRoaXMpO1xuICAgIHRoaXMucmVuZGVyQ29sbGVjdGlvbih0aGlzLm1vZGVsLnJ1bGVzLCBDYXRlZ29yaWFsUnVsZVZpZXcsIHRoaXMucXVlcnlCeUhvb2soJ2NhdGVnb3JpYWwtcnVsZXMtdGFibGUnKSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgZXZlbnRzOiB7XG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWNhdGVnb3JpYWwtYWRkb25lLWJ1dHRvbl0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLnJ1bGVzLmFkZCh7fSk7XG4gICAgfSxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349Y2F0ZWdvcmlhbC1yZW1vdmVhbGwtYnV0dG9uXSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwucmVzZXQoKTtcbiAgICB9XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTkE7QUFSQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///96da\n")},"9ae5":function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar TimePartsSelect = __webpack_require__(/*! ./time-parts-select */ \"c678\");\n\nvar TimeZonesSelect = __webpack_require__(/*! ./time-zones-select */ \"f3d5\");\n\nvar DurationUnitsSelect = __webpack_require__(/*! ./duration-units-select */ \"4916\");\n\nmodule.exports = View.extend({\n  template: templates.configureFacet.facetTransformDatetime,\n  bindings: {\n    'model.transformedZone': {\n      type: 'value',\n      hook: 'transform-time-zone-input'\n    },\n    'model.transformedReference': {\n      type: 'value',\n      hook: 'transform-time-reference-input'\n    }\n  },\n  events: {\n    'change [data-hook~=transform-time-zone-input]': function changeDataHookTransformTimeZoneInput() {\n      this.model.zone = this.queryByHook('transform-time-zone-input').value;\n    },\n    'change [data-hook~=transform-time-format-input]': function changeDataHookTransformTimeFormatInput() {\n      this.model.format = this.queryByHook('transform-time-format-input').value;\n    },\n    'change [data-hook~=transform-time-transformedzone-input]': function changeDataHookTransformTimeTransformedzoneInput() {\n      this.model.transformedZone = this.queryByHook('transform-time-transformedzone-input').value;\n    },\n    'change [data-hook~=transform-time-transformedformat-input]': function changeDataHookTransformTimeTransformedformatInput() {\n      this.model.transformedFormat = this.queryByHook('transform-time-transformedformat-input').value;\n    },\n    'change [data-hook~=transform-time-transformedreference-input]': function changeDataHookTransformTimeTransformedreferenceInput() {\n      this.model.transformedReference = this.queryByHook('transform-time-transformedreference-input').value;\n    },\n    'change [data-hook~=transform-time-transformedunits-input]': function changeDataHookTransformTimeTransformedunitsInput() {\n      this.model.transformedReference = this.queryByHook('transform-time-transformedunits-input').value;\n    }\n  },\n  subviews: {\n    timeParts: {\n      hook: 'time-parts',\n      prepareView: function prepareView(el) {\n        return new TimePartsSelect({\n          el: el,\n          model: this.model\n        });\n      }\n    },\n    timeZones: {\n      hook: 'time-zones',\n      prepareView: function prepareView(el) {\n        return new TimeZonesSelect({\n          el: el,\n          field: 'zone',\n          model: this.model\n        });\n      }\n    },\n    transformedTimeZones: {\n      hook: 'transformed-time-zones',\n      prepareView: function prepareView(el) {\n        return new TimeZonesSelect({\n          el: el,\n          field: 'transformedZone',\n          model: this.model\n        });\n      }\n    },\n    transformedTimeUnits: {\n      hook: 'transformed-time-units',\n      constructor: DurationUnitsSelect\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWFlNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZmFjZXQvZmFjZXQtdHJhbnNmb3JtLWRhdGV0aW1lLmpzPzA4NjAiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL3RlbXBsYXRlcycpO1xudmFyIFRpbWVQYXJ0c1NlbGVjdCA9IHJlcXVpcmUoJy4vdGltZS1wYXJ0cy1zZWxlY3QnKTtcbnZhciBUaW1lWm9uZXNTZWxlY3QgPSByZXF1aXJlKCcuL3RpbWUtem9uZXMtc2VsZWN0Jyk7XG52YXIgRHVyYXRpb25Vbml0c1NlbGVjdCA9IHJlcXVpcmUoJy4vZHVyYXRpb24tdW5pdHMtc2VsZWN0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gVmlldy5leHRlbmQoe1xuICB0ZW1wbGF0ZTogdGVtcGxhdGVzLmNvbmZpZ3VyZUZhY2V0LmZhY2V0VHJhbnNmb3JtRGF0ZXRpbWUsXG4gIGJpbmRpbmdzOiB7XG4gICAgJ21vZGVsLnRyYW5zZm9ybWVkWm9uZSc6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAndHJhbnNmb3JtLXRpbWUtem9uZS1pbnB1dCdcbiAgICB9LFxuICAgICdtb2RlbC50cmFuc2Zvcm1lZFJlZmVyZW5jZSc6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAndHJhbnNmb3JtLXRpbWUtcmVmZXJlbmNlLWlucHV0J1xuICAgIH1cbiAgfSxcbiAgZXZlbnRzOiB7XG4gICAgJ2NoYW5nZSBbZGF0YS1ob29rfj10cmFuc2Zvcm0tdGltZS16b25lLWlucHV0XSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwuem9uZSA9IHRoaXMucXVlcnlCeUhvb2soJ3RyYW5zZm9ybS10aW1lLXpvbmUtaW5wdXQnKS52YWx1ZTtcbiAgICB9LFxuICAgICdjaGFuZ2UgW2RhdGEtaG9va349dHJhbnNmb3JtLXRpbWUtZm9ybWF0LWlucHV0XSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwuZm9ybWF0ID0gdGhpcy5xdWVyeUJ5SG9vaygndHJhbnNmb3JtLXRpbWUtZm9ybWF0LWlucHV0JykudmFsdWU7XG4gICAgfSxcbiAgICAnY2hhbmdlIFtkYXRhLWhvb2t+PXRyYW5zZm9ybS10aW1lLXRyYW5zZm9ybWVkem9uZS1pbnB1dF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLnRyYW5zZm9ybWVkWm9uZSA9IHRoaXMucXVlcnlCeUhvb2soJ3RyYW5zZm9ybS10aW1lLXRyYW5zZm9ybWVkem9uZS1pbnB1dCcpLnZhbHVlO1xuICAgIH0sXG4gICAgJ2NoYW5nZSBbZGF0YS1ob29rfj10cmFuc2Zvcm0tdGltZS10cmFuc2Zvcm1lZGZvcm1hdC1pbnB1dF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLnRyYW5zZm9ybWVkRm9ybWF0ID0gdGhpcy5xdWVyeUJ5SG9vaygndHJhbnNmb3JtLXRpbWUtdHJhbnNmb3JtZWRmb3JtYXQtaW5wdXQnKS52YWx1ZTtcbiAgICB9LFxuICAgICdjaGFuZ2UgW2RhdGEtaG9va349dHJhbnNmb3JtLXRpbWUtdHJhbnNmb3JtZWRyZWZlcmVuY2UtaW5wdXRdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC50cmFuc2Zvcm1lZFJlZmVyZW5jZSA9IHRoaXMucXVlcnlCeUhvb2soJ3RyYW5zZm9ybS10aW1lLXRyYW5zZm9ybWVkcmVmZXJlbmNlLWlucHV0JykudmFsdWU7XG4gICAgfSxcbiAgICAnY2hhbmdlIFtkYXRhLWhvb2t+PXRyYW5zZm9ybS10aW1lLXRyYW5zZm9ybWVkdW5pdHMtaW5wdXRdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC50cmFuc2Zvcm1lZFJlZmVyZW5jZSA9IHRoaXMucXVlcnlCeUhvb2soJ3RyYW5zZm9ybS10aW1lLXRyYW5zZm9ybWVkdW5pdHMtaW5wdXQnKS52YWx1ZTtcbiAgICB9XG4gIH0sXG4gIHN1YnZpZXdzOiB7XG4gICAgdGltZVBhcnRzOiB7XG4gICAgICBob29rOiAndGltZS1wYXJ0cycsXG4gICAgICBwcmVwYXJlVmlldzogZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGltZVBhcnRzU2VsZWN0KHtcbiAgICAgICAgICBlbDogZWwsXG4gICAgICAgICAgbW9kZWw6IHRoaXMubW9kZWxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgICB0aW1lWm9uZXM6IHtcbiAgICAgIGhvb2s6ICd0aW1lLXpvbmVzJyxcbiAgICAgIHByZXBhcmVWaWV3OiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaW1lWm9uZXNTZWxlY3Qoe1xuICAgICAgICAgIGVsOiBlbCxcbiAgICAgICAgICBmaWVsZDogJ3pvbmUnLFxuICAgICAgICAgIG1vZGVsOiB0aGlzLm1vZGVsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRUaW1lWm9uZXM6IHtcbiAgICAgIGhvb2s6ICd0cmFuc2Zvcm1lZC10aW1lLXpvbmVzJyxcbiAgICAgIHByZXBhcmVWaWV3OiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaW1lWm9uZXNTZWxlY3Qoe1xuICAgICAgICAgIGVsOiBlbCxcbiAgICAgICAgICBmaWVsZDogJ3RyYW5zZm9ybWVkWm9uZScsXG4gICAgICAgICAgbW9kZWw6IHRoaXMubW9kZWxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgICB0cmFuc2Zvcm1lZFRpbWVVbml0czoge1xuICAgICAgaG9vazogJ3RyYW5zZm9ybWVkLXRpbWUtdW5pdHMnLFxuICAgICAgY29uc3RydWN0b3I6IER1cmF0aW9uVW5pdHNTZWxlY3RcbiAgICB9XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRkE7QUFMQTtBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBbEJBO0FBb0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQVBBO0FBU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBUkE7QUFVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFSQTtBQVVBO0FBQ0E7QUFDQTtBQUZBO0FBOUJBO0FBaENBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9ae5\n")},"9cb1":function(module,exports,__webpack_require__){eval("/**\n * @classdesc line chart class\n * @class LineChart\n * @augments BaseChart\n */\nvar BaseChart = __webpack_require__(/*! ./base-chart */ \"6339\");\n\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nmodule.exports = BaseChart.extend({\n  initialize: function initialize() {\n    this.slots.reset([{\n      description: 'X axis',\n      type: 'partition',\n      rank: 1,\n      required: true,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Group by',\n      type: 'partition',\n      rank: 2,\n      required: false,\n      supportedFacets: ['categorial', 'datetime', 'duration', 'continuous', 'text']\n    }, {\n      description: 'Y axis',\n      type: 'aggregate',\n      rank: 1,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }, {\n      description: 'X error',\n      type: 'aggregate',\n      rank: 2,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }, {\n      description: 'Y error',\n      type: 'aggregate',\n      rank: 3,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }, {\n      description: 'Second Y axis',\n      type: 'aggregate',\n      rank: 4,\n      required: false,\n      supportedFacets: ['continuous', 'duration']\n    }]);\n  },\n  chartjsConfig: function chartjsConfig() {\n    return {\n      type: 'lineError',\n      data: {\n        datasets: [],\n        labels: []\n      },\n      options: {\n        title: {\n          display: true,\n          position: 'top'\n        },\n        scales: {\n          xAxes: [{\n            type: 'linear',\n            position: 'bottom',\n            scaleLabel: {\n              display: true\n            },\n            time: {\n              parser: function parser(label) {\n                return moment(label, moment.ISO_8601);\n              }\n            }\n          }],\n          yAxes: [{\n            type: 'linear',\n            display: true,\n            position: 'left',\n            id: 'first-scale'\n          }, {\n            type: 'linear',\n            display: false,\n            position: 'right',\n            id: 'second-scale'\n          }, {\n            type: 'linear',\n            display: false,\n            position: 'right',\n            id: 'selection-scale',\n            ticks: {\n              min: 0,\n              max: 1\n            }\n          }]\n        },\n        tooltips: {}\n      }\n    };\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWNiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL21vZGVscy9saW5lY2hhcnQuanM/ZGM2MSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBjbGFzc2Rlc2MgbGluZSBjaGFydCBjbGFzc1xuICogQGNsYXNzIExpbmVDaGFydFxuICogQGF1Z21lbnRzIEJhc2VDaGFydFxuICovXG52YXIgQmFzZUNoYXJ0ID0gcmVxdWlyZSgnLi9iYXNlLWNoYXJ0Jyk7XG52YXIgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50LXRpbWV6b25lJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZUNoYXJ0LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNsb3RzLnJlc2V0KFtcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdYIGF4aXMnLFxuICAgICAgICB0eXBlOiAncGFydGl0aW9uJyxcbiAgICAgICAgcmFuazogMSxcbiAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIHN1cHBvcnRlZEZhY2V0czogWydjYXRlZ29yaWFsJywgJ2RhdGV0aW1lJywgJ2R1cmF0aW9uJywgJ2NvbnRpbnVvdXMnLCAndGV4dCddXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ0dyb3VwIGJ5JyxcbiAgICAgICAgdHlwZTogJ3BhcnRpdGlvbicsXG4gICAgICAgIHJhbms6IDIsXG4gICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NhdGVnb3JpYWwnLCAnZGF0ZXRpbWUnLCAnZHVyYXRpb24nLCAnY29udGludW91cycsICd0ZXh0J11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnWSBheGlzJyxcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIHJhbms6IDEsXG4gICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NvbnRpbnVvdXMnLCAnZHVyYXRpb24nXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdYIGVycm9yJyxcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIHJhbms6IDIsXG4gICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NvbnRpbnVvdXMnLCAnZHVyYXRpb24nXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdZIGVycm9yJyxcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIHJhbms6IDMsXG4gICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NvbnRpbnVvdXMnLCAnZHVyYXRpb24nXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdTZWNvbmQgWSBheGlzJyxcbiAgICAgICAgdHlwZTogJ2FnZ3JlZ2F0ZScsXG4gICAgICAgIHJhbms6IDQsXG4gICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgc3VwcG9ydGVkRmFjZXRzOiBbJ2NvbnRpbnVvdXMnLCAnZHVyYXRpb24nXVxuICAgICAgfVxuICAgIF0pO1xuICB9LFxuICBjaGFydGpzQ29uZmlnOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdsaW5lRXJyb3InLFxuICAgICAgZGF0YToge1xuICAgICAgICBkYXRhc2V0czogW10sXG4gICAgICAgIGxhYmVsczogW11cbiAgICAgIH0sXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgICAgICBwb3NpdGlvbjogJ3RvcCdcbiAgICAgICAgfSxcbiAgICAgICAgc2NhbGVzOiB7XG4gICAgICAgICAgeEF4ZXM6IFt7XG4gICAgICAgICAgICB0eXBlOiAnbGluZWFyJyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYm90dG9tJyxcbiAgICAgICAgICAgIHNjYWxlTGFiZWw6IHtcbiAgICAgICAgICAgICAgZGlzcGxheTogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRpbWU6IHtcbiAgICAgICAgICAgICAgcGFyc2VyOiBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbW9tZW50KGxhYmVsLCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfV0sXG4gICAgICAgICAgeUF4ZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogJ2xpbmVhcicsXG4gICAgICAgICAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICAgICAgICAgIHBvc2l0aW9uOiAnbGVmdCcsXG4gICAgICAgICAgICAgIGlkOiAnZmlyc3Qtc2NhbGUnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiAnbGluZWFyJyxcbiAgICAgICAgICAgICAgZGlzcGxheTogZmFsc2UsXG4gICAgICAgICAgICAgIHBvc2l0aW9uOiAncmlnaHQnLFxuICAgICAgICAgICAgICBpZDogJ3NlY29uZC1zY2FsZSdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6ICdsaW5lYXInLFxuICAgICAgICAgICAgICBkaXNwbGF5OiBmYWxzZSxcbiAgICAgICAgICAgICAgcG9zaXRpb246ICdyaWdodCcsXG4gICAgICAgICAgICAgIGlkOiAnc2VsZWN0aW9uLXNjYWxlJyxcbiAgICAgICAgICAgICAgdGlja3M6IHtcbiAgICAgICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICAgICAgbWF4OiAxXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH0sXG4gICAgICAgIHRvb2x0aXBzOiB7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0FBS0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQU5BO0FBWUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFKQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFMQTtBQTFCQTtBQXNDQTtBQTNDQTtBQU5BO0FBcURBO0FBckdBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9cb1\n")},"9d44":function(module,exports,__webpack_require__){eval("var app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar Spot = __webpack_require__(/*! spot-framework */ \"3b07\");\n\nvar BaseWidget = __webpack_require__(/*! ./base-widget */ \"26ef\");\n\nvar Chart = __webpack_require__(/*! chart.js */ \"70b5\");\n\nvar colors = __webpack_require__(/*! ../../colors */ \"eb63\");\n\nvar misval = Spot.util.misval;\n\nvar util = __webpack_require__(/*! ./util */ \"2b41\"); // used for pie, bar, horizontalbar, and radar charts\n// modify the horizontalbarchart to have the group name printed on the bar\n\n\nChart.pluginService.register({\n  afterDatasetsDraw: function afterDatasetsDraw(chartInstance) {\n    var chartType = chartInstance.config.type;\n\n    if (chartType === 'horizontalBarError') {\n      var scale = chartInstance.scales['y-axis-0'];\n      scale.draw(scale);\n    }\n  }\n});\n\nfunction defaultErrorDir(model) {\n  var t = model.getType();\n\n  if (t === 'barchart') {\n    return 'vertical';\n  } else if (t === 'horizontalbarchart') {\n    return 'horizontal';\n  } else {\n    // pie radar\n    return 'none';\n  }\n}\n\nfunction acceptTimeAxis(model) {\n  var t = model.getType();\n  return t === 'barchart';\n}\n\nfunction hasPerItemColor(model) {\n  // data  Array\n  // color depending on plot type:\n  //           Array<Color>: barchart, piechart\n  //           Color:        radarchart\n  var t = model.getType();\n  return t === 'barchart' || t === 'horizontalbarchart' || t === 'piechart';\n} // true: color items by the index in the data array; for cateogrial facets\n// false:  color items by the index of their subgroup\n\n\nfunction colorByIndex(model) {\n  var t = model.getType();\n  return t === 'piechart';\n} // Called by Chartjs, this -> chart instance\n\n\nfunction onClick(ev, elements) {\n  if (elements.length > 0) {\n    var filter = this._Ampersandview.model.filter;\n    var partition = filter.partitions.get(1, 'rank');\n    partition.updateSelection(partition.groups.models[elements[0]._index]);\n    filter.updateDataFilter();\n    app.me.dataview.getData();\n  }\n}\n\nfunction _deinitChart(view) {\n  if (view._chartjs) {\n    view._chartjs.destroy();\n\n    delete view._chartjs;\n  }\n\n  delete view._config;\n  var canvas = view.queryByHook('canvas');\n\n  if (canvas) {\n    canvas.parentNode.removeChild(canvas);\n  }\n\n  view.isInitialized = false;\n}\n\nfunction _initChart(view) {\n  // Configure plot\n  view._config = view.model.chartjsConfig();\n  var options = view._config.options;\n  var partition = view.model.filter.partitions.get(1, 'rank'); // axis types\n\n  if (acceptTimeAxis(view.model)) {\n    if (partition.isDatetime) {\n      options.scales.xAxes[0].type = 'time';\n    } else if (partition.isDuration) {\n      options.scales.xAxes[0].type = 'spot-duration';\n    } else if (partition.isCategorial) {\n      options.scales.xAxes[0].type = 'category';\n    }\n  } // axis labels and title\n\n\n  if (view.model.getType() === 'barchart' || view.model.getType() === 'horizontalbarchart') {\n    options.scales.xAxes[0].scaleLabel.display = partition.showLabel;\n    options.scales.xAxes[0].scaleLabel.labelString = partition.label;\n  }\n\n  options.title.text = view.model.getTitle(); // mouse selection callbacks\n\n  if (view.model.getType() !== 'radarchart') {\n    options.onClick = onClick;\n  } // force a square full size plot\n\n\n  var width = view.el.offsetWidth;\n  var height = view.el.offsetHeight;\n  var canvas = document.createElement('canvas');\n  canvas.setAttribute('data-hook', 'canvas');\n  view.el.appendChild(canvas);\n  var ctx = canvas.getContext('2d');\n  ctx.canvas.width = width;\n  ctx.canvas.height = height; // Create Chartjs object\n\n  view._chartjs = new Chart(ctx, view._config); // In callbacks on the chart we will need the view, so store a reference\n\n  view._chartjs._Ampersandview = view;\n  view.isInitialized = true;\n}\n\nfunction _update(view) {\n  if (!view.isInitialized) {\n    console.warn('Cannot update chart, not initialized', view);\n    return;\n  }\n\n  var model = view.model;\n  var filter = view.model.filter;\n  var partitionA = filter.partitions.get(1, 'rank');\n  var partitionB = filter.partitions.get(2, 'rank');\n  var chartData = view._config.data;\n  util.resizeChartjsData(chartData, partitionA, partitionB, {\n    perItem: hasPerItemColor(model)\n  }); // update legends and tooltips:\n\n  if (model.getType() === 'piechart') {\n    view._config.options.legend.display = partitionA.showLegend;\n    view._config.options.tooltips.mode = 'single';\n  } else {\n    if (partitionB && partitionB.showLegend) {\n      view._config.options.legend.display = true;\n    } else {\n      view._config.options.legend.display = false;\n    }\n\n    if (partitionB && partitionB.groups && partitionB.groups.length > 1) {\n      view._config.options.tooltips.mode = 'label';\n    } else {\n      view._config.options.tooltips.mode = 'single';\n    }\n  }\n\n  var aggregate;\n  var valueFn;\n  aggregate = filter.aggregates.get(1, 'rank');\n\n  if (aggregate) {\n    valueFn = function valueFn(group) {\n      if (group.aa !== misval) {\n        return parseFloat(group.aa) || 0;\n      }\n\n      return 0;\n    };\n  } else {\n    valueFn = function valueFn(group) {\n      if (group.count !== misval) {\n        return group.count;\n      }\n\n      return 0;\n    };\n  }\n\n  var errorFn;\n  aggregate = filter.aggregates.get(2, 'rank');\n\n  if (aggregate) {\n    errorFn = function errorFn(group) {\n      if (group.bb !== misval) {\n        return parseFloat(group.bb) || 0;\n      }\n\n      return 0;\n    }; // use preset errorDir\n\n\n    view._config.options.errorDir = defaultErrorDir(model);\n  } else {\n    errorFn = function errorFn(group) {\n      return null;\n    };\n\n    view._config.options.errorDir = 'none';\n  }\n\n  var filterFn = partitionA.filterFunction(); // add datapoints\n\n  filter.data.forEach(function (group) {\n    var i = util.partitionValueToIndex(partitionA, group.a);\n    var j = util.partitionValueToIndex(partitionB, group.b); // only plot if both values are well defined\n\n    if (i >= 0 && j >= 0) {\n      // data value\n      chartData.datasets[j].data[i] = valueFn(group);\n      chartData.datasets[j].error[i] = errorFn(group); // data color\n\n      if (hasPerItemColor(model)) {\n        if (filterFn(partitionA.groups.models[i].value)) {\n          if (colorByIndex(model)) {\n            chartData.datasets[j].backgroundColor[i] = colors.getColor(i).css();\n          } else {\n            chartData.datasets[j].backgroundColor[i] = colors.getColor(j).css();\n          }\n        } else {\n          chartData.datasets[j].backgroundColor[i] = colors.unselectedColor.css();\n        }\n      }\n    }\n  }); // Hand-off to ChartJS for plotting\n\n  view._chartjs.update();\n}\n\nmodule.exports = BaseWidget.extend({\n  template: '<div class=\"widgetInner mdl-card__media\"></div>',\n  update: function update() {\n    _update(this);\n  },\n  initChart: function initChart() {\n    _initChart(this);\n  },\n  deinitChart: function deinitChart() {\n    _deinitChart(this);\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWQ0NC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL3ZpZXdzL2NoYXJ0anMuanM/MjFiMSJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYXBwID0gcmVxdWlyZSgnYW1wZXJzYW5kLWFwcCcpO1xudmFyIFNwb3QgPSByZXF1aXJlKCdzcG90LWZyYW1ld29yaycpO1xudmFyIEJhc2VXaWRnZXQgPSByZXF1aXJlKCcuL2Jhc2Utd2lkZ2V0Jyk7XG52YXIgQ2hhcnQgPSByZXF1aXJlKCdjaGFydC5qcycpO1xudmFyIGNvbG9ycyA9IHJlcXVpcmUoJy4uLy4uL2NvbG9ycycpO1xudmFyIG1pc3ZhbCA9IFNwb3QudXRpbC5taXN2YWw7XG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpO1xuXG4vLyB1c2VkIGZvciBwaWUsIGJhciwgaG9yaXpvbnRhbGJhciwgYW5kIHJhZGFyIGNoYXJ0c1xuXG4vLyBtb2RpZnkgdGhlIGhvcml6b250YWxiYXJjaGFydCB0byBoYXZlIHRoZSBncm91cCBuYW1lIHByaW50ZWQgb24gdGhlIGJhclxuQ2hhcnQucGx1Z2luU2VydmljZS5yZWdpc3Rlcih7XG4gIGFmdGVyRGF0YXNldHNEcmF3OiBmdW5jdGlvbiAoY2hhcnRJbnN0YW5jZSkge1xuICAgIHZhciBjaGFydFR5cGUgPSBjaGFydEluc3RhbmNlLmNvbmZpZy50eXBlO1xuXG4gICAgaWYgKGNoYXJ0VHlwZSA9PT0gJ2hvcml6b250YWxCYXJFcnJvcicpIHtcbiAgICAgIHZhciBzY2FsZSA9IGNoYXJ0SW5zdGFuY2Uuc2NhbGVzWyd5LWF4aXMtMCddO1xuICAgICAgc2NhbGUuZHJhdyhzY2FsZSk7XG4gICAgfVxuICB9XG59KTtcblxuZnVuY3Rpb24gZGVmYXVsdEVycm9yRGlyIChtb2RlbCkge1xuICB2YXIgdCA9IG1vZGVsLmdldFR5cGUoKTtcbiAgaWYgKHQgPT09ICdiYXJjaGFydCcpIHtcbiAgICByZXR1cm4gJ3ZlcnRpY2FsJztcbiAgfSBlbHNlIGlmICh0ID09PSAnaG9yaXpvbnRhbGJhcmNoYXJ0Jykge1xuICAgIHJldHVybiAnaG9yaXpvbnRhbCc7XG4gIH0gZWxzZSB7XG4gICAgLy8gcGllIHJhZGFyXG4gICAgcmV0dXJuICdub25lJztcbiAgfVxufVxuXG5mdW5jdGlvbiBhY2NlcHRUaW1lQXhpcyAobW9kZWwpIHtcbiAgdmFyIHQgPSBtb2RlbC5nZXRUeXBlKCk7XG4gIHJldHVybiAodCA9PT0gJ2JhcmNoYXJ0Jyk7XG59XG5cbmZ1bmN0aW9uIGhhc1Blckl0ZW1Db2xvciAobW9kZWwpIHtcbiAgLy8gZGF0YSAgQXJyYXlcbiAgLy8gY29sb3IgZGVwZW5kaW5nIG9uIHBsb3QgdHlwZTpcbiAgLy8gICAgICAgICAgIEFycmF5PENvbG9yPjogYmFyY2hhcnQsIHBpZWNoYXJ0XG4gIC8vICAgICAgICAgICBDb2xvcjogICAgICAgIHJhZGFyY2hhcnRcbiAgdmFyIHQgPSBtb2RlbC5nZXRUeXBlKCk7XG4gIHJldHVybiAodCA9PT0gJ2JhcmNoYXJ0JyB8fCB0ID09PSAnaG9yaXpvbnRhbGJhcmNoYXJ0JyB8fCB0ID09PSAncGllY2hhcnQnKTtcbn1cblxuLy8gdHJ1ZTogY29sb3IgaXRlbXMgYnkgdGhlIGluZGV4IGluIHRoZSBkYXRhIGFycmF5OyBmb3IgY2F0ZW9ncmlhbCBmYWNldHNcbi8vIGZhbHNlOiAgY29sb3IgaXRlbXMgYnkgdGhlIGluZGV4IG9mIHRoZWlyIHN1Ymdyb3VwXG5mdW5jdGlvbiBjb2xvckJ5SW5kZXggKG1vZGVsKSB7XG4gIHZhciB0ID0gbW9kZWwuZ2V0VHlwZSgpO1xuICByZXR1cm4gKHQgPT09ICdwaWVjaGFydCcpO1xufVxuXG4vLyBDYWxsZWQgYnkgQ2hhcnRqcywgdGhpcyAtPiBjaGFydCBpbnN0YW5jZVxuZnVuY3Rpb24gb25DbGljayAoZXYsIGVsZW1lbnRzKSB7XG4gIGlmIChlbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgdmFyIGZpbHRlciA9IHRoaXMuX0FtcGVyc2FuZHZpZXcubW9kZWwuZmlsdGVyO1xuXG4gICAgdmFyIHBhcnRpdGlvbiA9IGZpbHRlci5wYXJ0aXRpb25zLmdldCgxLCAncmFuaycpO1xuICAgIHBhcnRpdGlvbi51cGRhdGVTZWxlY3Rpb24ocGFydGl0aW9uLmdyb3Vwcy5tb2RlbHNbZWxlbWVudHNbMF0uX2luZGV4XSk7XG5cbiAgICBmaWx0ZXIudXBkYXRlRGF0YUZpbHRlcigpO1xuICAgIGFwcC5tZS5kYXRhdmlldy5nZXREYXRhKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVpbml0Q2hhcnQgKHZpZXcpIHtcbiAgaWYgKHZpZXcuX2NoYXJ0anMpIHtcbiAgICB2aWV3Ll9jaGFydGpzLmRlc3Ryb3koKTtcbiAgICBkZWxldGUgdmlldy5fY2hhcnRqcztcbiAgfVxuICBkZWxldGUgdmlldy5fY29uZmlnO1xuXG4gIHZhciBjYW52YXMgPSB2aWV3LnF1ZXJ5QnlIb29rKCdjYW52YXMnKTtcbiAgaWYgKGNhbnZhcykge1xuICAgIGNhbnZhcy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNhbnZhcyk7XG4gIH1cbiAgdmlldy5pc0luaXRpYWxpemVkID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGluaXRDaGFydCAodmlldykge1xuICAvLyBDb25maWd1cmUgcGxvdFxuICB2aWV3Ll9jb25maWcgPSB2aWV3Lm1vZGVsLmNoYXJ0anNDb25maWcoKTtcbiAgdmFyIG9wdGlvbnMgPSB2aWV3Ll9jb25maWcub3B0aW9ucztcblxuICB2YXIgcGFydGl0aW9uID0gdmlldy5tb2RlbC5maWx0ZXIucGFydGl0aW9ucy5nZXQoMSwgJ3JhbmsnKTtcblxuICAvLyBheGlzIHR5cGVzXG4gIGlmIChhY2NlcHRUaW1lQXhpcyh2aWV3Lm1vZGVsKSkge1xuICAgIGlmIChwYXJ0aXRpb24uaXNEYXRldGltZSkge1xuICAgICAgb3B0aW9ucy5zY2FsZXMueEF4ZXNbMF0udHlwZSA9ICd0aW1lJztcbiAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0R1cmF0aW9uKSB7XG4gICAgICBvcHRpb25zLnNjYWxlcy54QXhlc1swXS50eXBlID0gJ3Nwb3QtZHVyYXRpb24nO1xuICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgb3B0aW9ucy5zY2FsZXMueEF4ZXNbMF0udHlwZSA9ICdjYXRlZ29yeSc7XG4gICAgfVxuICB9XG5cbiAgLy8gYXhpcyBsYWJlbHMgYW5kIHRpdGxlXG4gIGlmICh2aWV3Lm1vZGVsLmdldFR5cGUoKSA9PT0gJ2JhcmNoYXJ0JyB8fCB2aWV3Lm1vZGVsLmdldFR5cGUoKSA9PT0gJ2hvcml6b250YWxiYXJjaGFydCcpIHtcbiAgICBvcHRpb25zLnNjYWxlcy54QXhlc1swXS5zY2FsZUxhYmVsLmRpc3BsYXkgPSBwYXJ0aXRpb24uc2hvd0xhYmVsO1xuICAgIG9wdGlvbnMuc2NhbGVzLnhBeGVzWzBdLnNjYWxlTGFiZWwubGFiZWxTdHJpbmcgPSBwYXJ0aXRpb24ubGFiZWw7XG4gIH1cbiAgb3B0aW9ucy50aXRsZS50ZXh0ID0gdmlldy5tb2RlbC5nZXRUaXRsZSgpO1xuXG4gIC8vIG1vdXNlIHNlbGVjdGlvbiBjYWxsYmFja3NcbiAgaWYgKHZpZXcubW9kZWwuZ2V0VHlwZSgpICE9PSAncmFkYXJjaGFydCcpIHtcbiAgICBvcHRpb25zLm9uQ2xpY2sgPSBvbkNsaWNrO1xuICB9XG5cbiAgLy8gZm9yY2UgYSBzcXVhcmUgZnVsbCBzaXplIHBsb3RcbiAgdmFyIHdpZHRoID0gdmlldy5lbC5vZmZzZXRXaWR0aDtcbiAgdmFyIGhlaWdodCA9IHZpZXcuZWwub2Zmc2V0SGVpZ2h0O1xuXG4gIHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgY2FudmFzLnNldEF0dHJpYnV0ZSgnZGF0YS1ob29rJywgJ2NhbnZhcycpO1xuICB2aWV3LmVsLmFwcGVuZENoaWxkKGNhbnZhcyk7XG5cbiAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICBjdHguY2FudmFzLndpZHRoID0gd2lkdGg7XG4gIGN0eC5jYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXG4gIC8vIENyZWF0ZSBDaGFydGpzIG9iamVjdFxuICB2aWV3Ll9jaGFydGpzID0gbmV3IENoYXJ0KGN0eCwgdmlldy5fY29uZmlnKTtcblxuICAvLyBJbiBjYWxsYmFja3Mgb24gdGhlIGNoYXJ0IHdlIHdpbGwgbmVlZCB0aGUgdmlldywgc28gc3RvcmUgYSByZWZlcmVuY2VcbiAgdmlldy5fY2hhcnRqcy5fQW1wZXJzYW5kdmlldyA9IHZpZXc7XG5cbiAgdmlldy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlICh2aWV3KSB7XG4gIGlmICghdmlldy5pc0luaXRpYWxpemVkKSB7XG4gICAgY29uc29sZS53YXJuKCdDYW5ub3QgdXBkYXRlIGNoYXJ0LCBub3QgaW5pdGlhbGl6ZWQnLCB2aWV3KTtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbW9kZWwgPSB2aWV3Lm1vZGVsO1xuICB2YXIgZmlsdGVyID0gdmlldy5tb2RlbC5maWx0ZXI7XG4gIHZhciBwYXJ0aXRpb25BID0gZmlsdGVyLnBhcnRpdGlvbnMuZ2V0KDEsICdyYW5rJyk7XG4gIHZhciBwYXJ0aXRpb25CID0gZmlsdGVyLnBhcnRpdGlvbnMuZ2V0KDIsICdyYW5rJyk7XG5cbiAgdmFyIGNoYXJ0RGF0YSA9IHZpZXcuX2NvbmZpZy5kYXRhO1xuXG4gIHV0aWwucmVzaXplQ2hhcnRqc0RhdGEoY2hhcnREYXRhLCBwYXJ0aXRpb25BLCBwYXJ0aXRpb25CLCB7IHBlckl0ZW06IGhhc1Blckl0ZW1Db2xvcihtb2RlbCkgfSk7XG5cbiAgLy8gdXBkYXRlIGxlZ2VuZHMgYW5kIHRvb2x0aXBzOlxuICBpZiAobW9kZWwuZ2V0VHlwZSgpID09PSAncGllY2hhcnQnKSB7XG4gICAgdmlldy5fY29uZmlnLm9wdGlvbnMubGVnZW5kLmRpc3BsYXkgPSBwYXJ0aXRpb25BLnNob3dMZWdlbmQ7XG4gICAgdmlldy5fY29uZmlnLm9wdGlvbnMudG9vbHRpcHMubW9kZSA9ICdzaW5nbGUnO1xuICB9IGVsc2Uge1xuICAgIGlmIChwYXJ0aXRpb25CICYmIHBhcnRpdGlvbkIuc2hvd0xlZ2VuZCkge1xuICAgICAgdmlldy5fY29uZmlnLm9wdGlvbnMubGVnZW5kLmRpc3BsYXkgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB2aWV3Ll9jb25maWcub3B0aW9ucy5sZWdlbmQuZGlzcGxheSA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAocGFydGl0aW9uQiAmJiBwYXJ0aXRpb25CLmdyb3VwcyAmJiBwYXJ0aXRpb25CLmdyb3Vwcy5sZW5ndGggPiAxKSB7XG4gICAgICB2aWV3Ll9jb25maWcub3B0aW9ucy50b29sdGlwcy5tb2RlID0gJ2xhYmVsJztcbiAgICB9IGVsc2Uge1xuICAgICAgdmlldy5fY29uZmlnLm9wdGlvbnMudG9vbHRpcHMubW9kZSA9ICdzaW5nbGUnO1xuICAgIH1cbiAgfVxuXG4gIHZhciBhZ2dyZWdhdGU7XG5cbiAgdmFyIHZhbHVlRm47XG4gIGFnZ3JlZ2F0ZSA9IGZpbHRlci5hZ2dyZWdhdGVzLmdldCgxLCAncmFuaycpO1xuICBpZiAoYWdncmVnYXRlKSB7XG4gICAgdmFsdWVGbiA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgaWYgKGdyb3VwLmFhICE9PSBtaXN2YWwpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlRmxvYXQoZ3JvdXAuYWEpIHx8IDA7XG4gICAgICB9XG4gICAgICByZXR1cm4gMDtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHZhbHVlRm4gPSBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICAgIGlmIChncm91cC5jb3VudCAhPT0gbWlzdmFsKSB7XG4gICAgICAgIHJldHVybiBncm91cC5jb3VudDtcbiAgICAgIH1cbiAgICAgIHJldHVybiAwO1xuICAgIH07XG4gIH1cblxuICB2YXIgZXJyb3JGbjtcbiAgYWdncmVnYXRlID0gZmlsdGVyLmFnZ3JlZ2F0ZXMuZ2V0KDIsICdyYW5rJyk7XG4gIGlmIChhZ2dyZWdhdGUpIHtcbiAgICBlcnJvckZuID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICBpZiAoZ3JvdXAuYmIgIT09IG1pc3ZhbCkge1xuICAgICAgICByZXR1cm4gcGFyc2VGbG9hdChncm91cC5iYikgfHwgMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiAwO1xuICAgIH07XG4gICAgLy8gdXNlIHByZXNldCBlcnJvckRpclxuICAgIHZpZXcuX2NvbmZpZy5vcHRpb25zLmVycm9yRGlyID0gZGVmYXVsdEVycm9yRGlyKG1vZGVsKTtcbiAgfSBlbHNlIHtcbiAgICBlcnJvckZuID0gZnVuY3Rpb24gKGdyb3VwKSB7IHJldHVybiBudWxsOyB9O1xuICAgIHZpZXcuX2NvbmZpZy5vcHRpb25zLmVycm9yRGlyID0gJ25vbmUnO1xuICB9XG5cbiAgdmFyIGZpbHRlckZuID0gcGFydGl0aW9uQS5maWx0ZXJGdW5jdGlvbigpO1xuXG4gIC8vIGFkZCBkYXRhcG9pbnRzXG4gIGZpbHRlci5kYXRhLmZvckVhY2goZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgdmFyIGkgPSB1dGlsLnBhcnRpdGlvblZhbHVlVG9JbmRleChwYXJ0aXRpb25BLCBncm91cC5hKTtcbiAgICB2YXIgaiA9IHV0aWwucGFydGl0aW9uVmFsdWVUb0luZGV4KHBhcnRpdGlvbkIsIGdyb3VwLmIpO1xuXG4gICAgLy8gb25seSBwbG90IGlmIGJvdGggdmFsdWVzIGFyZSB3ZWxsIGRlZmluZWRcbiAgICBpZiAoaSA+PSAwICYmIGogPj0gMCkge1xuICAgICAgLy8gZGF0YSB2YWx1ZVxuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzW2pdLmRhdGFbaV0gPSB2YWx1ZUZuKGdyb3VwKTtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5lcnJvcltpXSA9IGVycm9yRm4oZ3JvdXApO1xuXG4gICAgICAvLyBkYXRhIGNvbG9yXG4gICAgICBpZiAoaGFzUGVySXRlbUNvbG9yKG1vZGVsKSkge1xuICAgICAgICBpZiAoZmlsdGVyRm4ocGFydGl0aW9uQS5ncm91cHMubW9kZWxzW2ldLnZhbHVlKSkge1xuICAgICAgICAgIGlmIChjb2xvckJ5SW5kZXgobW9kZWwpKSB7XG4gICAgICAgICAgICBjaGFydERhdGEuZGF0YXNldHNbal0uYmFja2dyb3VuZENvbG9yW2ldID0gY29sb3JzLmdldENvbG9yKGkpLmNzcygpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjaGFydERhdGEuZGF0YXNldHNbal0uYmFja2dyb3VuZENvbG9yW2ldID0gY29sb3JzLmdldENvbG9yKGopLmNzcygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjaGFydERhdGEuZGF0YXNldHNbal0uYmFja2dyb3VuZENvbG9yW2ldID0gY29sb3JzLnVuc2VsZWN0ZWRDb2xvci5jc3MoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgLy8gSGFuZC1vZmYgdG8gQ2hhcnRKUyBmb3IgcGxvdHRpbmdcbiAgdmlldy5fY2hhcnRqcy51cGRhdGUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlV2lkZ2V0LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cIndpZGdldElubmVyIG1kbC1jYXJkX19tZWRpYVwiPjwvZGl2PicsXG5cbiAgdXBkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgdXBkYXRlKHRoaXMpO1xuICB9LFxuXG4gIGluaXRDaGFydDogZnVuY3Rpb24gKCkge1xuICAgIGluaXRDaGFydCh0aGlzKTtcbiAgfSxcblxuICBkZWluaXRDaGFydDogZnVuY3Rpb24gKCkge1xuICAgIGRlaW5pdENoYXJ0KHRoaXMpO1xuICB9XG59KTtcblxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUlBO0FBQ0E7QUFDQTtBQURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVJBO0FBQ0E7QUFVQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBYkEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9d44\n")},a6e8:function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\n\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\nvar Chart = __webpack_require__(/*! chart.js */ \"70b5\"); // extend plot with errorbars\n\n\nvar extendWithErrorBar = __webpack_require__(/*! ./chartjs-errorbars */ \"ee83\");\n\nextendWithErrorBar(Chart, 'line', 'lineError');\nextendWithErrorBar(Chart, 'bubble', 'bubbleError');\nextendWithErrorBar(Chart, 'bar', 'barError');\nextendWithErrorBar(Chart, 'horizontalBar', 'horizontalBarError'); // extend plots with a duration scale type\n\nvar extendWithDurationScale = __webpack_require__(/*! ./chartjs-duration-scale */ \"d11f\");\n\nextendWithDurationScale(Chart); // replace the default linear scale with a smarter formatter\n\nvar SciLinearFormatter = __webpack_require__(/*! ./chartjs-scilinear-formatter */ \"de33\");\n\nChart.scaleService.updateScaleDefaults('linear', {\n  ticks: {\n    callback: SciLinearFormatter\n  }\n});\nvar widgetEntry = AmpersandModel.extend({\n  props: {\n    modelType: {\n      type: 'string',\n      required: true\n    },\n    newView: {\n      type: 'any',\n      required: false\n    }\n  }\n});\nvar WidgetCollection = Collection.extend({\n  model: widgetEntry,\n  mainIndex: 'modelType'\n});\n/**\n * A factory producing the Ampersand views corresponding to the different chart types.\n * @module widgets/view-factory\n */\n\nmodule.exports.widgets = new WidgetCollection([{\n  modelType: 'piechart',\n  newView: __webpack_require__(/*! ./views/chartjs */ \"9d44\")\n}, {\n  modelType: 'barchart',\n  newView: __webpack_require__(/*! ./views/chartjs */ \"9d44\")\n}, {\n  modelType: 'horizontalbarchart',\n  newView: __webpack_require__(/*! ./views/chartjs */ \"9d44\")\n}, {\n  modelType: 'linechart',\n  newView: __webpack_require__(/*! ./views/chartjs1d */ \"e9bd\")\n}, {\n  modelType: 'radarchart',\n  newView: __webpack_require__(/*! ./views/chartjs */ \"9d44\")\n}, {\n  modelType: 'bubbleplot',\n  newView: __webpack_require__(/*! ./views/chartjs2d */ \"fdc1\")\n}, {\n  modelType: 'scatterchart',\n  newView: __webpack_require__(/*! ./views/scatter */ \"035a\")\n}, {\n  modelType: 'networkchart',\n  newView: __webpack_require__(/*! ./views/sigma */ \"af18\") // Register new widgets here\n\n}]);\n/**\n * Create a new Ampersand view for a widget\n * @param {Object} options - passed on to the view constructor, see https://github.com/AmpersandJS/ampersand-view#constructor-new-ampersandviewoptions\n * @param {Object} options.model - The widget\n * @returns {View} view - An Ampersand view\n */\n\nmodule.exports.newView = function newView(options) {\n  var entry = module.exports.widgets.get(options.model.modelType);\n  var constructor = entry.newView;\n  return new constructor(options);\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYTZlOC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL3ZpZXctZmFjdG9yeS5qcz8xZTBkIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBDb2xsZWN0aW9uID0gcmVxdWlyZSgnYW1wZXJzYW5kLWNvbGxlY3Rpb24nKTtcbnZhciBBbXBlcnNhbmRNb2RlbCA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1tb2RlbCcpO1xuXG52YXIgQ2hhcnQgPSByZXF1aXJlKCdjaGFydC5qcycpO1xuXG4vLyBleHRlbmQgcGxvdCB3aXRoIGVycm9yYmFyc1xudmFyIGV4dGVuZFdpdGhFcnJvckJhciA9IHJlcXVpcmUoJy4vY2hhcnRqcy1lcnJvcmJhcnMnKTtcbmV4dGVuZFdpdGhFcnJvckJhcihDaGFydCwgJ2xpbmUnLCAnbGluZUVycm9yJyk7XG5leHRlbmRXaXRoRXJyb3JCYXIoQ2hhcnQsICdidWJibGUnLCAnYnViYmxlRXJyb3InKTtcbmV4dGVuZFdpdGhFcnJvckJhcihDaGFydCwgJ2JhcicsICdiYXJFcnJvcicpO1xuZXh0ZW5kV2l0aEVycm9yQmFyKENoYXJ0LCAnaG9yaXpvbnRhbEJhcicsICdob3Jpem9udGFsQmFyRXJyb3InKTtcblxuLy8gZXh0ZW5kIHBsb3RzIHdpdGggYSBkdXJhdGlvbiBzY2FsZSB0eXBlXG52YXIgZXh0ZW5kV2l0aER1cmF0aW9uU2NhbGUgPSByZXF1aXJlKCcuL2NoYXJ0anMtZHVyYXRpb24tc2NhbGUnKTtcbmV4dGVuZFdpdGhEdXJhdGlvblNjYWxlKENoYXJ0KTtcblxuLy8gcmVwbGFjZSB0aGUgZGVmYXVsdCBsaW5lYXIgc2NhbGUgd2l0aCBhIHNtYXJ0ZXIgZm9ybWF0dGVyXG52YXIgU2NpTGluZWFyRm9ybWF0dGVyID0gcmVxdWlyZSgnLi9jaGFydGpzLXNjaWxpbmVhci1mb3JtYXR0ZXInKTtcbkNoYXJ0LnNjYWxlU2VydmljZS51cGRhdGVTY2FsZURlZmF1bHRzKCdsaW5lYXInLCB7IHRpY2tzOiB7IGNhbGxiYWNrOiBTY2lMaW5lYXJGb3JtYXR0ZXIgfSB9KTtcblxudmFyIHdpZGdldEVudHJ5ID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICBtb2RlbFR5cGU6IHt0eXBlOiAnc3RyaW5nJywgcmVxdWlyZWQ6IHRydWV9LFxuICAgIG5ld1ZpZXc6IHt0eXBlOiAnYW55JywgcmVxdWlyZWQ6IGZhbHNlfVxuICB9XG59KTtcblxudmFyIFdpZGdldENvbGxlY3Rpb24gPSBDb2xsZWN0aW9uLmV4dGVuZCh7XG4gIG1vZGVsOiB3aWRnZXRFbnRyeSxcbiAgbWFpbkluZGV4OiAnbW9kZWxUeXBlJ1xufSk7XG5cbi8qKlxuICogQSBmYWN0b3J5IHByb2R1Y2luZyB0aGUgQW1wZXJzYW5kIHZpZXdzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGRpZmZlcmVudCBjaGFydCB0eXBlcy5cbiAqIEBtb2R1bGUgd2lkZ2V0cy92aWV3LWZhY3RvcnlcbiAqL1xubW9kdWxlLmV4cG9ydHMud2lkZ2V0cyA9IG5ldyBXaWRnZXRDb2xsZWN0aW9uKFtcbiAge1xuICAgIG1vZGVsVHlwZTogJ3BpZWNoYXJ0JyxcbiAgICBuZXdWaWV3OiByZXF1aXJlKCcuL3ZpZXdzL2NoYXJ0anMnKVxuICB9LFxuICB7XG4gICAgbW9kZWxUeXBlOiAnYmFyY2hhcnQnLFxuICAgIG5ld1ZpZXc6IHJlcXVpcmUoJy4vdmlld3MvY2hhcnRqcycpXG4gIH0sXG4gIHtcbiAgICBtb2RlbFR5cGU6ICdob3Jpem9udGFsYmFyY2hhcnQnLFxuICAgIG5ld1ZpZXc6IHJlcXVpcmUoJy4vdmlld3MvY2hhcnRqcycpXG4gIH0sXG4gIHtcbiAgICBtb2RlbFR5cGU6ICdsaW5lY2hhcnQnLFxuICAgIG5ld1ZpZXc6IHJlcXVpcmUoJy4vdmlld3MvY2hhcnRqczFkJylcbiAgfSxcbiAge1xuICAgIG1vZGVsVHlwZTogJ3JhZGFyY2hhcnQnLFxuICAgIG5ld1ZpZXc6IHJlcXVpcmUoJy4vdmlld3MvY2hhcnRqcycpXG4gIH0sXG4gIHtcbiAgICBtb2RlbFR5cGU6ICdidWJibGVwbG90JyxcbiAgICBuZXdWaWV3OiByZXF1aXJlKCcuL3ZpZXdzL2NoYXJ0anMyZCcpXG4gIH0sXG4gIHtcbiAgICBtb2RlbFR5cGU6ICdzY2F0dGVyY2hhcnQnLFxuICAgIG5ld1ZpZXc6IHJlcXVpcmUoJy4vdmlld3Mvc2NhdHRlcicpXG4gIH0sXG4gIHtcbiAgICBtb2RlbFR5cGU6ICduZXR3b3JrY2hhcnQnLFxuICAgIG5ld1ZpZXc6IHJlcXVpcmUoJy4vdmlld3Mvc2lnbWEnKVxuICB9XG4gIC8vIFJlZ2lzdGVyIG5ldyB3aWRnZXRzIGhlcmVcbl0pO1xuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBBbXBlcnNhbmQgdmlldyBmb3IgYSB3aWRnZXRcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gcGFzc2VkIG9uIHRvIHRoZSB2aWV3IGNvbnN0cnVjdG9yLCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL0FtcGVyc2FuZEpTL2FtcGVyc2FuZC12aWV3I2NvbnN0cnVjdG9yLW5ldy1hbXBlcnNhbmR2aWV3b3B0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMubW9kZWwgLSBUaGUgd2lkZ2V0XG4gKiBAcmV0dXJucyB7Vmlld30gdmlldyAtIEFuIEFtcGVyc2FuZCB2aWV3XG4gKi9cbm1vZHVsZS5leHBvcnRzLm5ld1ZpZXcgPSBmdW5jdGlvbiBuZXdWaWV3IChvcHRpb25zKSB7XG4gIHZhciBlbnRyeSA9IG1vZHVsZS5leHBvcnRzLndpZGdldHMuZ2V0KG9wdGlvbnMubW9kZWwubW9kZWxUeXBlKTtcbiAgdmFyIGNvbnN0cnVjdG9yID0gZW50cnkubmV3VmlldztcbiAgcmV0dXJuIG5ldyBjb25zdHJ1Y3RvcihvcHRpb25zKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFGQTtBQURBO0FBT0E7QUFDQTtBQUNBO0FBRkE7QUFLQTs7Ozs7QUFJQTtBQUVBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUhBO0FBT0E7Ozs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///a6e8\n")},aa00:function(module,exports,__webpack_require__){eval("var app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar Router = __webpack_require__(/*! ampersand-router */ \"e57e\");\n\nvar HomePage = __webpack_require__(/*! ./pages/home */ \"8ab4\");\n\nvar DatasetsPage = __webpack_require__(/*! ./pages/datasets */ \"7bdf\");\n\nvar ConfigureDatasetPage = __webpack_require__(/*! ./pages/configure-dataset */ \"4b1e\");\n\nvar ConfigureFacetPage = __webpack_require__(/*! ./pages/configure-facet */ \"6668\");\n\nvar ConfigurePartitionPage = __webpack_require__(/*! ./pages/configure-partition */ \"d38c\");\n\nvar AnalyzePage = __webpack_require__(/*! ./pages/analyze */ \"22e9\");\n/**\n * [exports description]\n * @module router\n */\n\n\nmodule.exports = Router.extend({\n  routes: {\n    '': 'home',\n    'home': 'home',\n    'datasets': 'datasets',\n    'analyze': 'analyze',\n    'dataset/:id': 'configureDataset',\n    'facet/:id': 'configureFacet',\n    'partition/:id': 'configurePartition',\n    'session=(*url)': 'getSession',\n    '(*path)': 'catchAll'\n  },\n  // ------- ROUTE HANDLERS ---------\n  home: function home() {\n    app.trigger('page', new HomePage({\n      model: app.me\n    }));\n  },\n  datasets: function datasets() {\n    app.trigger('page', new DatasetsPage({\n      model: app.me\n    }));\n  },\n  analyze: function analyze() {\n    app.trigger('page', new AnalyzePage({\n      model: app.me.dataview,\n      collection: app.me.dataview.filters\n    }));\n  },\n  share: function share() {\n    app.trigger('page', new SharePage({\n      model: app.me\n    }));\n  },\n  configureDataset: function configureDataset(id) {\n    var dataset = app.me.datasets.get(id);\n\n    if (dataset) {\n      app.trigger('page', new ConfigureDatasetPage({\n        model: dataset,\n        collection: dataset.facets\n      }));\n    } else {\n      this.home();\n    }\n  },\n  configureFacet: function configureFacet(id) {\n    var dataset = null;\n    var facet = null; // look for facet in app.me.datasets\n\n    app.me.datasets.forEach(function (d) {\n      facet = d.facets.get(id);\n\n      if (facet) {\n        dataset = d;\n      }\n    }); // look for facet in app.me.dataview\n\n    facet = app.me.dataview.facets.get(id);\n\n    if (facet) {\n      dataset = app.me.dataview;\n    }\n\n    if (dataset) {\n      facet = dataset.facets.get(id);\n      app.trigger('page', new ConfigureFacetPage({\n        dataset: dataset,\n        model: facet\n      }));\n    } else {\n      this.home();\n      console.error('Facet not found');\n    }\n  },\n  configurePartition: function configurePartition(id) {\n    // Search over all filters and partitions in this dataset to find the right partition\n    // Not very pretty, but the number of filters and filters per partition are small\n    var partitionToEdit;\n    var found = false;\n    app.me.dataview.filters.forEach(function (filter) {\n      filter.partitions.forEach(function (partition) {\n        if (partition.getId() === id) {\n          found = true;\n          partitionToEdit = partition;\n        }\n      });\n    });\n\n    if (found) {\n      app.trigger('page', new ConfigurePartitionPage({\n        model: partitionToEdit\n      }));\n    } else {\n      this.home();\n    }\n  },\n  getSession: function getSession(url) {\n    console.log('router.js: Getting a remote session from:', url);\n    app.importRemoteSession(url);\n  },\n  catchAll: function catchAll() {\n    this.redirectTo('');\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWEwMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9yb3V0ZXIuanM/NDFjYiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYXBwID0gcmVxdWlyZSgnYW1wZXJzYW5kLWFwcCcpO1xudmFyIFJvdXRlciA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1yb3V0ZXInKTtcbnZhciBIb21lUGFnZSA9IHJlcXVpcmUoJy4vcGFnZXMvaG9tZScpO1xudmFyIERhdGFzZXRzUGFnZSA9IHJlcXVpcmUoJy4vcGFnZXMvZGF0YXNldHMnKTtcbnZhciBDb25maWd1cmVEYXRhc2V0UGFnZSA9IHJlcXVpcmUoJy4vcGFnZXMvY29uZmlndXJlLWRhdGFzZXQnKTtcbnZhciBDb25maWd1cmVGYWNldFBhZ2UgPSByZXF1aXJlKCcuL3BhZ2VzL2NvbmZpZ3VyZS1mYWNldCcpO1xudmFyIENvbmZpZ3VyZVBhcnRpdGlvblBhZ2UgPSByZXF1aXJlKCcuL3BhZ2VzL2NvbmZpZ3VyZS1wYXJ0aXRpb24nKTtcbnZhciBBbmFseXplUGFnZSA9IHJlcXVpcmUoJy4vcGFnZXMvYW5hbHl6ZScpO1xuXG4vKipcbiAqIFtleHBvcnRzIGRlc2NyaXB0aW9uXVxuICogQG1vZHVsZSByb3V0ZXJcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBSb3V0ZXIuZXh0ZW5kKHtcbiAgcm91dGVzOiB7XG4gICAgJyc6ICdob21lJyxcbiAgICAnaG9tZSc6ICdob21lJyxcbiAgICAnZGF0YXNldHMnOiAnZGF0YXNldHMnLFxuICAgICdhbmFseXplJzogJ2FuYWx5emUnLFxuXG4gICAgJ2RhdGFzZXQvOmlkJzogJ2NvbmZpZ3VyZURhdGFzZXQnLFxuICAgICdmYWNldC86aWQnOiAnY29uZmlndXJlRmFjZXQnLFxuICAgICdwYXJ0aXRpb24vOmlkJzogJ2NvbmZpZ3VyZVBhcnRpdGlvbicsXG4gICAgJ3Nlc3Npb249KCp1cmwpJzogJ2dldFNlc3Npb24nLFxuICAgICcoKnBhdGgpJzogJ2NhdGNoQWxsJ1xuICB9LFxuXG4gIC8vIC0tLS0tLS0gUk9VVEUgSEFORExFUlMgLS0tLS0tLS0tXG4gIGhvbWU6IGZ1bmN0aW9uICgpIHtcbiAgICBhcHAudHJpZ2dlcigncGFnZScsIG5ldyBIb21lUGFnZSh7XG4gICAgICBtb2RlbDogYXBwLm1lXG4gICAgfSkpO1xuICB9LFxuXG4gIGRhdGFzZXRzOiBmdW5jdGlvbiAoKSB7XG4gICAgYXBwLnRyaWdnZXIoJ3BhZ2UnLCBuZXcgRGF0YXNldHNQYWdlKHtcbiAgICAgIG1vZGVsOiBhcHAubWVcbiAgICB9KSk7XG4gIH0sXG5cbiAgYW5hbHl6ZTogZnVuY3Rpb24gKCkge1xuICAgIGFwcC50cmlnZ2VyKCdwYWdlJywgbmV3IEFuYWx5emVQYWdlKHtcbiAgICAgIG1vZGVsOiBhcHAubWUuZGF0YXZpZXcsXG4gICAgICBjb2xsZWN0aW9uOiBhcHAubWUuZGF0YXZpZXcuZmlsdGVyc1xuICAgIH0pKTtcbiAgfSxcblxuICBzaGFyZTogZnVuY3Rpb24gKCkge1xuICAgIGFwcC50cmlnZ2VyKCdwYWdlJywgbmV3IFNoYXJlUGFnZSh7XG4gICAgICBtb2RlbDogYXBwLm1lXG4gICAgfSkpO1xuICB9LFxuXG4gIGNvbmZpZ3VyZURhdGFzZXQ6IGZ1bmN0aW9uIChpZCkge1xuICAgIHZhciBkYXRhc2V0ID0gYXBwLm1lLmRhdGFzZXRzLmdldChpZCk7XG4gICAgaWYgKGRhdGFzZXQpIHtcbiAgICAgIGFwcC50cmlnZ2VyKCdwYWdlJywgbmV3IENvbmZpZ3VyZURhdGFzZXRQYWdlKHtcbiAgICAgICAgbW9kZWw6IGRhdGFzZXQsXG4gICAgICAgIGNvbGxlY3Rpb246IGRhdGFzZXQuZmFjZXRzXG4gICAgICB9KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaG9tZSgpO1xuICAgIH1cbiAgfSxcblxuICBjb25maWd1cmVGYWNldDogZnVuY3Rpb24gKGlkKSB7XG4gICAgdmFyIGRhdGFzZXQgPSBudWxsO1xuICAgIHZhciBmYWNldCA9IG51bGw7XG5cbiAgICAvLyBsb29rIGZvciBmYWNldCBpbiBhcHAubWUuZGF0YXNldHNcbiAgICBhcHAubWUuZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgZmFjZXQgPSBkLmZhY2V0cy5nZXQoaWQpO1xuICAgICAgaWYgKGZhY2V0KSB7XG4gICAgICAgIGRhdGFzZXQgPSBkO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gbG9vayBmb3IgZmFjZXQgaW4gYXBwLm1lLmRhdGF2aWV3XG4gICAgZmFjZXQgPSBhcHAubWUuZGF0YXZpZXcuZmFjZXRzLmdldChpZCk7XG4gICAgaWYgKGZhY2V0KSB7XG4gICAgICBkYXRhc2V0ID0gYXBwLm1lLmRhdGF2aWV3O1xuICAgIH1cblxuICAgIGlmIChkYXRhc2V0KSB7XG4gICAgICBmYWNldCA9IGRhdGFzZXQuZmFjZXRzLmdldChpZCk7XG4gICAgICBhcHAudHJpZ2dlcigncGFnZScsIG5ldyBDb25maWd1cmVGYWNldFBhZ2Uoe1xuICAgICAgICBkYXRhc2V0OiBkYXRhc2V0LFxuICAgICAgICBtb2RlbDogZmFjZXRcbiAgICAgIH0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5ob21lKCk7XG4gICAgICBjb25zb2xlLmVycm9yKCdGYWNldCBub3QgZm91bmQnKTtcbiAgICB9XG4gIH0sXG5cbiAgY29uZmlndXJlUGFydGl0aW9uOiBmdW5jdGlvbiAoaWQpIHtcbiAgICAvLyBTZWFyY2ggb3ZlciBhbGwgZmlsdGVycyBhbmQgcGFydGl0aW9ucyBpbiB0aGlzIGRhdGFzZXQgdG8gZmluZCB0aGUgcmlnaHQgcGFydGl0aW9uXG4gICAgLy8gTm90IHZlcnkgcHJldHR5LCBidXQgdGhlIG51bWJlciBvZiBmaWx0ZXJzIGFuZCBmaWx0ZXJzIHBlciBwYXJ0aXRpb24gYXJlIHNtYWxsXG4gICAgdmFyIHBhcnRpdGlvblRvRWRpdDtcbiAgICB2YXIgZm91bmQgPSBmYWxzZTtcbiAgICBhcHAubWUuZGF0YXZpZXcuZmlsdGVycy5mb3JFYWNoKGZ1bmN0aW9uIChmaWx0ZXIpIHtcbiAgICAgIGZpbHRlci5wYXJ0aXRpb25zLmZvckVhY2goZnVuY3Rpb24gKHBhcnRpdGlvbikge1xuICAgICAgICBpZiAocGFydGl0aW9uLmdldElkKCkgPT09IGlkKSB7XG4gICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgIHBhcnRpdGlvblRvRWRpdCA9IHBhcnRpdGlvbjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpZiAoZm91bmQpIHtcbiAgICAgIGFwcC50cmlnZ2VyKCdwYWdlJywgbmV3IENvbmZpZ3VyZVBhcnRpdGlvblBhZ2UoeyBtb2RlbDogcGFydGl0aW9uVG9FZGl0IH0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5ob21lKCk7XG4gICAgfVxuICB9LFxuICBnZXRTZXNzaW9uOiBmdW5jdGlvbiAodXJsKSB7XG4gICAgY29uc29sZS5sb2coJ3JvdXRlci5qczogR2V0dGluZyBhIHJlbW90ZSBzZXNzaW9uIGZyb206JywgdXJsKTtcbiAgICBhcHAuaW1wb3J0UmVtb3RlU2Vzc2lvbih1cmwpO1xuICB9LFxuICBjYXRjaEFsbDogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVkaXJlY3RUbygnJyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFFQTs7Ozs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVZBO0FBYUE7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBRUE7QUFDQTtBQUNBO0FBREE7QUFHQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUVBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQTVHQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///aa00\n")},aea4:function(module,exports,__webpack_require__){eval("/**\n * A slot defines how a variable can be added to a plot\n *\n * @class Slot\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\nfunction labelForPartition(facet) {\n  // use: \"label [units]\" or \"label\"\n  if (facet.units.length > 0) {\n    return facet.name + ' [' + facet.units + ']';\n  } else {\n    return facet.name;\n  }\n}\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Description of this slot, to be shown in the UI\n     */\n    description: {\n      type: 'string',\n      required: 'true'\n    },\n\n    /**\n     * Type of slot:\n     * 1. partition: partitions the data along this variable\n     * 2. aggregate: this variable is used to style the plot: bar height, color, etc.\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'partition',\n      values: ['partition', 'aggregate']\n    },\n\n    /**\n     * Supported facet types. A subset of: [constant, categorial, datetime, duration, text]\n     */\n    supportedFacets: {\n      type: 'array',\n      required: true,\n      default: function _default() {\n        return [];\n      }\n    },\n    rank: 'number',\n    required: 'boolean',\n    isFilled: 'boolean'\n  },\n\n  /**\n   * Remove facet from the slot\n   * @returns {boolean} succes True if something was removed\n   */\n  emptySlot: function emptySlot() {\n    var filter = this.collection.parent.filter;\n\n    if (!filter || !this.isFilled) {\n      return false;\n    }\n\n    filter.releaseDataFilter();\n\n    if (this.type === 'partition') {\n      var partition = filter.partitions.get(this.rank, 'rank');\n      filter.partitions.remove(partition);\n    } else if (this.type === 'aggregate') {\n      var aggregate = filter.aggregates.get(this.rank, 'rank');\n      filter.aggregates.remove(aggregate);\n    }\n\n    this.isFilled = false;\n    return true;\n  },\n\n  /**\n   * Try to fill the slot with the provided facet\n   * returns true on success, false on failure\n   * The tryFillSlot caller is responsible to do a app.trigger('refresh')\n   *\n   * @param {Facet} facet\n   * @param {string} operation Optional. Requested operation for aggregates\n   * @returns {boolean} success\n   */\n  tryFillSlot: function tryFillSlot(facet, operation) {\n    var filter = this.collection.parent.filter;\n\n    if (!filter || this.isFilled) {\n      return false;\n    } // check if this slot accepts this type of facet\n\n\n    if (this.supportedFacets.indexOf(facet.type) === -1) {\n      return false;\n    } // Release this filter, and add relevant partition or aggregate\n\n\n    filter.releaseDataFilter();\n\n    if (this.type === 'partition') {\n      var partition = filter.partitions.add({\n        facetName: facet.name,\n        label: labelForPartition(facet),\n        showLabel: this.rank !== 1 || !facet.isCategorial,\n        rank: this.rank\n      });\n      partition.reset();\n    } else if (this.type === 'aggregate') {\n      filter.aggregates.add({\n        facetName: facet.name,\n        label: facet.name,\n        rank: this.rank,\n        operation: operation || 'avg'\n      });\n    } else {\n      console.error('Illegal slot');\n      return false;\n    }\n\n    this.isFilled = true;\n    return true;\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWVhNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL21vZGVscy9zbG90LmpzPzdjNmEiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBIHNsb3QgZGVmaW5lcyBob3cgYSB2YXJpYWJsZSBjYW4gYmUgYWRkZWQgdG8gYSBwbG90XG4gKlxuICogQGNsYXNzIFNsb3RcbiAqL1xudmFyIEFtcGVyc2FuZE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG5cbmZ1bmN0aW9uIGxhYmVsRm9yUGFydGl0aW9uIChmYWNldCkge1xuICAvLyB1c2U6IFwibGFiZWwgW3VuaXRzXVwiIG9yIFwibGFiZWxcIlxuICBpZiAoZmFjZXQudW5pdHMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBmYWNldC5uYW1lICsgJyBbJyArIGZhY2V0LnVuaXRzICsgJ10nO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWNldC5uYW1lO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBEZXNjcmlwdGlvbiBvZiB0aGlzIHNsb3QsIHRvIGJlIHNob3duIGluIHRoZSBVSVxuICAgICAqL1xuICAgIGRlc2NyaXB0aW9uOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiAndHJ1ZSdcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFR5cGUgb2Ygc2xvdDpcbiAgICAgKiAxLiBwYXJ0aXRpb246IHBhcnRpdGlvbnMgdGhlIGRhdGEgYWxvbmcgdGhpcyB2YXJpYWJsZVxuICAgICAqIDIuIGFnZ3JlZ2F0ZTogdGhpcyB2YXJpYWJsZSBpcyB1c2VkIHRvIHN0eWxlIHRoZSBwbG90OiBiYXIgaGVpZ2h0LCBjb2xvciwgZXRjLlxuICAgICAqL1xuICAgIHR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAncGFydGl0aW9uJyxcbiAgICAgIHZhbHVlczogWydwYXJ0aXRpb24nLCAnYWdncmVnYXRlJ11cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFN1cHBvcnRlZCBmYWNldCB0eXBlcy4gQSBzdWJzZXQgb2Y6IFtjb25zdGFudCwgY2F0ZWdvcmlhbCwgZGF0ZXRpbWUsIGR1cmF0aW9uLCB0ZXh0XVxuICAgICAqL1xuICAgIHN1cHBvcnRlZEZhY2V0czoge1xuICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgfSxcbiAgICByYW5rOiAnbnVtYmVyJyxcbiAgICByZXF1aXJlZDogJ2Jvb2xlYW4nLFxuICAgIGlzRmlsbGVkOiAnYm9vbGVhbidcbiAgfSxcbiAgLyoqXG4gICAqIFJlbW92ZSBmYWNldCBmcm9tIHRoZSBzbG90XG4gICAqIEByZXR1cm5zIHtib29sZWFufSBzdWNjZXMgVHJ1ZSBpZiBzb21ldGhpbmcgd2FzIHJlbW92ZWRcbiAgICovXG4gIGVtcHR5U2xvdDogZnVuY3Rpb24gKCkge1xuICAgIHZhciBmaWx0ZXIgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50LmZpbHRlcjtcbiAgICBpZiAoIWZpbHRlciB8fCAhdGhpcy5pc0ZpbGxlZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZpbHRlci5yZWxlYXNlRGF0YUZpbHRlcigpO1xuICAgIGlmICh0aGlzLnR5cGUgPT09ICdwYXJ0aXRpb24nKSB7XG4gICAgICB2YXIgcGFydGl0aW9uID0gZmlsdGVyLnBhcnRpdGlvbnMuZ2V0KHRoaXMucmFuaywgJ3JhbmsnKTtcbiAgICAgIGZpbHRlci5wYXJ0aXRpb25zLnJlbW92ZShwYXJ0aXRpb24pO1xuICAgIH0gZWxzZSBpZiAodGhpcy50eXBlID09PSAnYWdncmVnYXRlJykge1xuICAgICAgdmFyIGFnZ3JlZ2F0ZSA9IGZpbHRlci5hZ2dyZWdhdGVzLmdldCh0aGlzLnJhbmssICdyYW5rJyk7XG4gICAgICBmaWx0ZXIuYWdncmVnYXRlcy5yZW1vdmUoYWdncmVnYXRlKTtcbiAgICB9XG4gICAgdGhpcy5pc0ZpbGxlZCA9IGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xuICB9LFxuICAvKipcbiAgICogVHJ5IHRvIGZpbGwgdGhlIHNsb3Qgd2l0aCB0aGUgcHJvdmlkZWQgZmFjZXRcbiAgICogcmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGZhaWx1cmVcbiAgICogVGhlIHRyeUZpbGxTbG90IGNhbGxlciBpcyByZXNwb25zaWJsZSB0byBkbyBhIGFwcC50cmlnZ2VyKCdyZWZyZXNoJylcbiAgICpcbiAgICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9wZXJhdGlvbiBPcHRpb25hbC4gUmVxdWVzdGVkIG9wZXJhdGlvbiBmb3IgYWdncmVnYXRlc1xuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gc3VjY2Vzc1xuICAgKi9cbiAgdHJ5RmlsbFNsb3Q6IGZ1bmN0aW9uIChmYWNldCwgb3BlcmF0aW9uKSB7XG4gICAgdmFyIGZpbHRlciA9IHRoaXMuY29sbGVjdGlvbi5wYXJlbnQuZmlsdGVyO1xuICAgIGlmICghZmlsdGVyIHx8IHRoaXMuaXNGaWxsZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBjaGVjayBpZiB0aGlzIHNsb3QgYWNjZXB0cyB0aGlzIHR5cGUgb2YgZmFjZXRcbiAgICBpZiAodGhpcy5zdXBwb3J0ZWRGYWNldHMuaW5kZXhPZihmYWNldC50eXBlKSA9PT0gLTEpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBSZWxlYXNlIHRoaXMgZmlsdGVyLCBhbmQgYWRkIHJlbGV2YW50IHBhcnRpdGlvbiBvciBhZ2dyZWdhdGVcbiAgICBmaWx0ZXIucmVsZWFzZURhdGFGaWx0ZXIoKTtcblxuICAgIGlmICh0aGlzLnR5cGUgPT09ICdwYXJ0aXRpb24nKSB7XG4gICAgICB2YXIgcGFydGl0aW9uID0gZmlsdGVyLnBhcnRpdGlvbnMuYWRkKHtcbiAgICAgICAgZmFjZXROYW1lOiBmYWNldC5uYW1lLFxuICAgICAgICBsYWJlbDogbGFiZWxGb3JQYXJ0aXRpb24oZmFjZXQpLFxuICAgICAgICBzaG93TGFiZWw6ICh0aGlzLnJhbmsgIT09IDEpIHx8ICFmYWNldC5pc0NhdGVnb3JpYWwsXG4gICAgICAgIHJhbms6IHRoaXMucmFua1xuICAgICAgfSk7XG4gICAgICBwYXJ0aXRpb24ucmVzZXQoKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudHlwZSA9PT0gJ2FnZ3JlZ2F0ZScpIHtcbiAgICAgIGZpbHRlci5hZ2dyZWdhdGVzLmFkZCh7XG4gICAgICAgIGZhY2V0TmFtZTogZmFjZXQubmFtZSxcbiAgICAgICAgbGFiZWw6IGZhY2V0Lm5hbWUsXG4gICAgICAgIHJhbms6IHRoaXMucmFuayxcbiAgICAgICAgb3BlcmF0aW9uOiBvcGVyYXRpb24gfHwgJ2F2ZydcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdJbGxlZ2FsIHNsb3QnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmlzRmlsbGVkID0gdHJ1ZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUZBO0FBQ0E7QUFHQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFDQTtBQUtBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQU9BO0FBQ0E7QUFDQTtBQS9CQTtBQUNBO0FBZ0NBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7Ozs7Ozs7OztBQVNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFKQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFwR0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///aea4\n")},af18:function(module,exports,__webpack_require__){eval("/*** IMPORTS FROM imports-loader ***/\n(function() {\n\nvar Spot = __webpack_require__(/*! spot-framework */ \"3b07\");\n\nvar BaseWidget = __webpack_require__(/*! ./base-widget */ \"26ef\");\n\nvar colors = __webpack_require__(/*! ../../colors */ \"eb63\");\n\nvar misval = Spot.util.misval; // NOTE: sigma and sigma plugins do not work properly with require()\n// workaround via browserify-shim (configured in package.json)\n\nvar Sigma = __webpack_require__(/*! sigmajs */ \"2f77\");\n\n__webpack_require__(/*! sigmajsLayoutForceAtlas2 */ \"48ba\");\n\n__webpack_require__(/*! sigmajsRenderersParallelEdges */ \"f2d8\");\n\nfunction _deinitChart(view) {\n  if (view._sigma) {\n    view._sigma.killForceAtlas2();\n\n    view._sigma.kill();\n\n    delete view._sigma;\n  }\n\n  delete view._config;\n  view.isInitialized = false;\n}\n\nfunction _initChart(view) {\n  // Configure plot\n  view._config = view.model.sigmaConfig(); // Get a new sigma plot\n\n  view._sigma = new Sigma({\n    renderers: [{\n      container: view.el,\n      type: 'canvas'\n    }],\n    settings: view._config\n  }); // In callbacks on the chart we will need the view, so store a reference\n\n  view._sigma._Ampersandview = view; // cache for nodes and their positions\n\n  view._nodes = {}; // number of nodes on screen\n\n  view._nnodes = 0;\n  view.isInitialized = true;\n} // test if node exits, and add it if not\n\n\nfunction testNode(view, label) {\n  var alpha;\n  var x;\n  var y;\n\n  if (!view._sigma.graph.nodes(label)) {\n    // try to get previous postion, or generate new one\n    if (view._nodes.hasOwnProperty(label)) {\n      x = view._nodes[label].x;\n      y = view._nodes[label].y;\n    } else {\n      // place all new nodes on a circle\n      alpha = view._nnodes * 2.0 * 3.1415297 / 5.333333;\n      x = 10.0 * Math.cos(alpha);\n      y = 10.0 * Math.sin(alpha);\n    }\n\n    view._sigma.graph.addNode({\n      id: label,\n      label: label,\n      size: 1,\n      color: '#666',\n      x: x,\n      y: y\n    });\n\n    view._nnodes++;\n  }\n}\n\nfunction drawGraph(view) {\n  var filter = view.model.filter;\n  var edgeToCount = {};\n  var count;\n  var type;\n  var edgePartition = view.model.filter.partitions.get(3, 'rank');\n\n  if (edgePartition) {\n    type = 'curve';\n    edgePartition.groups.forEach(function (group, n) {\n      edgeToCount[group.value] = n;\n    });\n  } else {\n    count = 0;\n    type = 'line';\n  } // draw new ones\n\n\n  filter.data.forEach(function (group, id) {\n    if (group.count !== 0 && group.a !== misval && group.b !== misval) {\n      testNode(view, group.a);\n      testNode(view, group.b);\n\n      if (edgePartition) {\n        if (edgeToCount.hasOwnProperty(group.c)) {\n          count = edgeToCount[group.c];\n        } else {\n          return;\n        }\n      } // add edge\n\n\n      view._sigma.graph.addEdge({\n        color: colors.getColor(count).css(),\n        id: 'e' + id,\n        source: group.a,\n        target: group.b,\n        count: count,\n        type: type\n      });\n    }\n  });\n}\n\nfunction _update(view) {\n  if (!view.isInitialized) {\n    return;\n  } // remove graph, but cache the node positions\n\n\n  view._sigma.killForceAtlas2();\n\n  view._nodes = {};\n  view._nnodes = 0;\n\n  view._sigma.graph.nodes().forEach(function (node) {\n    view._nodes[node.id] = node;\n  });\n\n  view._sigma.graph.clear(); // redraw graph\n\n\n  drawGraph(view);\n\n  view._sigma.refresh();\n\n  view._sigma.startForceAtlas2({\n    worker: true,\n    adjustSizes: true,\n    barnesHutOptimize: true,\n    edgeWeightInfluence: 1,\n    slowDown: 10,\n    gravity: 1\n  });\n}\n\nmodule.exports = BaseWidget.extend({\n  template: '<div class=\"widgetInner sigmajs mdl-card__media\"></div>',\n  update: function update() {\n    _update(this);\n  },\n  initChart: function initChart() {\n    _initChart(this);\n  },\n  deinitChart: function deinitChart() {\n    _deinitChart(this);\n  }\n});\n}.call(window));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWYxOC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL3ZpZXdzL3NpZ21hLmpzPzc1MzgiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFNwb3QgPSByZXF1aXJlKCdzcG90LWZyYW1ld29yaycpO1xudmFyIEJhc2VXaWRnZXQgPSByZXF1aXJlKCcuL2Jhc2Utd2lkZ2V0Jyk7XG52YXIgY29sb3JzID0gcmVxdWlyZSgnLi4vLi4vY29sb3JzJyk7XG52YXIgbWlzdmFsID0gU3BvdC51dGlsLm1pc3ZhbDtcblxuLy8gTk9URTogc2lnbWEgYW5kIHNpZ21hIHBsdWdpbnMgZG8gbm90IHdvcmsgcHJvcGVybHkgd2l0aCByZXF1aXJlKClcbi8vIHdvcmthcm91bmQgdmlhIGJyb3dzZXJpZnktc2hpbSAoY29uZmlndXJlZCBpbiBwYWNrYWdlLmpzb24pXG52YXIgU2lnbWEgPSByZXF1aXJlKCdzaWdtYWpzJyk7XG5yZXF1aXJlKCdzaWdtYWpzTGF5b3V0Rm9yY2VBdGxhczInKTtcbnJlcXVpcmUoJ3NpZ21hanNSZW5kZXJlcnNQYXJhbGxlbEVkZ2VzJyk7XG5cbmZ1bmN0aW9uIGRlaW5pdENoYXJ0ICh2aWV3KSB7XG4gIGlmICh2aWV3Ll9zaWdtYSkge1xuICAgIHZpZXcuX3NpZ21hLmtpbGxGb3JjZUF0bGFzMigpO1xuICAgIHZpZXcuX3NpZ21hLmtpbGwoKTtcbiAgICBkZWxldGUgdmlldy5fc2lnbWE7XG4gIH1cbiAgZGVsZXRlIHZpZXcuX2NvbmZpZztcbiAgdmlldy5pc0luaXRpYWxpemVkID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGluaXRDaGFydCAodmlldykge1xuICAvLyBDb25maWd1cmUgcGxvdFxuICB2aWV3Ll9jb25maWcgPSB2aWV3Lm1vZGVsLnNpZ21hQ29uZmlnKCk7XG5cbiAgLy8gR2V0IGEgbmV3IHNpZ21hIHBsb3RcbiAgdmlldy5fc2lnbWEgPSBuZXcgU2lnbWEoe1xuICAgIHJlbmRlcmVyczogW3tcbiAgICAgIGNvbnRhaW5lcjogdmlldy5lbCxcbiAgICAgIHR5cGU6ICdjYW52YXMnXG4gICAgfV0sXG4gICAgc2V0dGluZ3M6IHZpZXcuX2NvbmZpZ1xuICB9KTtcblxuICAvLyBJbiBjYWxsYmFja3Mgb24gdGhlIGNoYXJ0IHdlIHdpbGwgbmVlZCB0aGUgdmlldywgc28gc3RvcmUgYSByZWZlcmVuY2VcbiAgdmlldy5fc2lnbWEuX0FtcGVyc2FuZHZpZXcgPSB2aWV3O1xuXG4gIC8vIGNhY2hlIGZvciBub2RlcyBhbmQgdGhlaXIgcG9zaXRpb25zXG4gIHZpZXcuX25vZGVzID0ge307XG5cbiAgLy8gbnVtYmVyIG9mIG5vZGVzIG9uIHNjcmVlblxuICB2aWV3Ll9ubm9kZXMgPSAwO1xuXG4gIHZpZXcuaXNJbml0aWFsaXplZCA9IHRydWU7XG59XG5cbi8vIHRlc3QgaWYgbm9kZSBleGl0cywgYW5kIGFkZCBpdCBpZiBub3RcbmZ1bmN0aW9uIHRlc3ROb2RlICh2aWV3LCBsYWJlbCkge1xuICB2YXIgYWxwaGE7XG4gIHZhciB4O1xuICB2YXIgeTtcblxuICBpZiAoIXZpZXcuX3NpZ21hLmdyYXBoLm5vZGVzKGxhYmVsKSkge1xuICAgIC8vIHRyeSB0byBnZXQgcHJldmlvdXMgcG9zdGlvbiwgb3IgZ2VuZXJhdGUgbmV3IG9uZVxuICAgIGlmICh2aWV3Ll9ub2Rlcy5oYXNPd25Qcm9wZXJ0eShsYWJlbCkpIHtcbiAgICAgIHggPSB2aWV3Ll9ub2Rlc1tsYWJlbF0ueDtcbiAgICAgIHkgPSB2aWV3Ll9ub2Rlc1tsYWJlbF0ueTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcGxhY2UgYWxsIG5ldyBub2RlcyBvbiBhIGNpcmNsZVxuICAgICAgYWxwaGEgPSB2aWV3Ll9ubm9kZXMgKiAyLjAgKiAzLjE0MTUyOTcgLyA1LjMzMzMzMztcbiAgICAgIHggPSAxMC4wICogTWF0aC5jb3MoYWxwaGEpO1xuICAgICAgeSA9IDEwLjAgKiBNYXRoLnNpbihhbHBoYSk7XG4gICAgfVxuXG4gICAgdmlldy5fc2lnbWEuZ3JhcGguYWRkTm9kZSh7XG4gICAgICBpZDogbGFiZWwsXG4gICAgICBsYWJlbDogbGFiZWwsXG4gICAgICBzaXplOiAxLFxuICAgICAgY29sb3I6ICcjNjY2JyxcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5XG4gICAgfSk7XG4gICAgdmlldy5fbm5vZGVzKys7XG4gIH1cbn1cblxuZnVuY3Rpb24gZHJhd0dyYXBoICh2aWV3KSB7XG4gIHZhciBmaWx0ZXIgPSB2aWV3Lm1vZGVsLmZpbHRlcjtcbiAgdmFyIGVkZ2VUb0NvdW50ID0ge307XG4gIHZhciBjb3VudDtcbiAgdmFyIHR5cGU7XG5cbiAgdmFyIGVkZ2VQYXJ0aXRpb24gPSB2aWV3Lm1vZGVsLmZpbHRlci5wYXJ0aXRpb25zLmdldCgzLCAncmFuaycpO1xuICBpZiAoZWRnZVBhcnRpdGlvbikge1xuICAgIHR5cGUgPSAnY3VydmUnO1xuICAgIGVkZ2VQYXJ0aXRpb24uZ3JvdXBzLmZvckVhY2goZnVuY3Rpb24gKGdyb3VwLCBuKSB7XG4gICAgICBlZGdlVG9Db3VudFtncm91cC52YWx1ZV0gPSBuO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNvdW50ID0gMDtcbiAgICB0eXBlID0gJ2xpbmUnO1xuICB9XG5cbiAgLy8gZHJhdyBuZXcgb25lc1xuICBmaWx0ZXIuZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCwgaWQpIHtcbiAgICBpZiAoZ3JvdXAuY291bnQgIT09IDAgJiYgZ3JvdXAuYSAhPT0gbWlzdmFsICYmIGdyb3VwLmIgIT09IG1pc3ZhbCkge1xuICAgICAgdGVzdE5vZGUodmlldywgZ3JvdXAuYSk7XG4gICAgICB0ZXN0Tm9kZSh2aWV3LCBncm91cC5iKTtcblxuICAgICAgaWYgKGVkZ2VQYXJ0aXRpb24pIHtcbiAgICAgICAgaWYgKGVkZ2VUb0NvdW50Lmhhc093blByb3BlcnR5KGdyb3VwLmMpKSB7XG4gICAgICAgICAgY291bnQgPSBlZGdlVG9Db3VudFtncm91cC5jXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gYWRkIGVkZ2VcbiAgICAgIHZpZXcuX3NpZ21hLmdyYXBoLmFkZEVkZ2Uoe1xuICAgICAgICBjb2xvcjogY29sb3JzLmdldENvbG9yKGNvdW50KS5jc3MoKSxcbiAgICAgICAgaWQ6ICdlJyArIGlkLFxuICAgICAgICBzb3VyY2U6IGdyb3VwLmEsXG4gICAgICAgIHRhcmdldDogZ3JvdXAuYixcbiAgICAgICAgY291bnQ6IGNvdW50LFxuICAgICAgICB0eXBlOiB0eXBlXG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB1cGRhdGUgKHZpZXcpIHtcbiAgaWYgKCF2aWV3LmlzSW5pdGlhbGl6ZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyByZW1vdmUgZ3JhcGgsIGJ1dCBjYWNoZSB0aGUgbm9kZSBwb3NpdGlvbnNcbiAgdmlldy5fc2lnbWEua2lsbEZvcmNlQXRsYXMyKCk7XG4gIHZpZXcuX25vZGVzID0ge307XG4gIHZpZXcuX25ub2RlcyA9IDA7XG4gIHZpZXcuX3NpZ21hLmdyYXBoLm5vZGVzKCkuZm9yRWFjaChmdW5jdGlvbiAobm9kZSkge1xuICAgIHZpZXcuX25vZGVzW25vZGUuaWRdID0gbm9kZTtcbiAgfSk7XG4gIHZpZXcuX3NpZ21hLmdyYXBoLmNsZWFyKCk7XG5cbiAgLy8gcmVkcmF3IGdyYXBoXG4gIGRyYXdHcmFwaCh2aWV3KTtcbiAgdmlldy5fc2lnbWEucmVmcmVzaCgpO1xuXG4gIHZpZXcuX3NpZ21hLnN0YXJ0Rm9yY2VBdGxhczIoe1xuICAgIHdvcmtlcjogdHJ1ZSxcbiAgICBhZGp1c3RTaXplczogdHJ1ZSxcbiAgICBiYXJuZXNIdXRPcHRpbWl6ZTogdHJ1ZSxcbiAgICBlZGdlV2VpZ2h0SW5mbHVlbmNlOiAxLFxuICAgIHNsb3dEb3duOiAxMCxcbiAgICBncmF2aXR5OiAxXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VXaWRnZXQuZXh0ZW5kKHtcbiAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwid2lkZ2V0SW5uZXIgc2lnbWFqcyBtZGwtY2FyZF9fbWVkaWFcIj48L2Rpdj4nLFxuXG4gIHVwZGF0ZTogZnVuY3Rpb24gKCkge1xuICAgIHVwZGF0ZSh0aGlzKTtcbiAgfSxcblxuICBpbml0Q2hhcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpbml0Q2hhcnQodGhpcyk7XG4gIH0sXG5cbiAgZGVpbml0Q2hhcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICBkZWluaXRDaGFydCh0aGlzKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiI7OztBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBR0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFMQTtBQUNBO0FBUUE7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTkE7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTkE7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFOQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBYkE7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///af18\n")},b24e:function(module,exports,__webpack_require__){eval("function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nvar Spot = __webpack_require__(/*! spot-framework */ \"3b07\");\n\nvar View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar misval = Spot.util.misval;\n\nfunction addRawValue(string, raw) {\n  if (typeof string !== 'string' || string.length === 0) {\n    string = '';\n  } else {\n    string = string + ', ';\n  }\n\n  if (typeof raw === 'string') {\n    string = string + '\"' + raw + '\"';\n  } else if (typeof raw === 'number') {\n    string = string + raw;\n  } else {\n    console.warn('Cannot add raw value', raw, 'of type', _typeof(raw));\n  }\n\n  return string;\n}\n\nmodule.exports = View.extend({\n  template: templates.configureFacet.facetDefine,\n  derived: {\n    showMinMax: {\n      deps: ['model.type'],\n      fn: function fn() {\n        return this.model.type === 'datetime' || this.model.type === 'duration' || this.model.type === 'continuous';\n      }\n    }\n  },\n  bindings: {\n    'showMinMax': [{\n      type: 'toggle',\n      hook: 'define-minimum-div'\n    }, {\n      type: 'toggle',\n      hook: 'define-maximum-div'\n    }],\n    'model.name': {\n      type: 'value',\n      hook: 'define-name-input'\n    },\n    'model.units': {\n      type: 'value',\n      hook: 'define-units-input'\n    },\n    'model.description': {\n      type: 'value',\n      hook: 'define-description-input'\n    },\n    'model.isContinuous': {\n      type: 'booleanAttribute',\n      hook: 'define-type-continuous',\n      name: 'checked'\n    },\n    'model.isCategorial': {\n      type: 'booleanAttribute',\n      hook: 'define-type-categorial',\n      name: 'checked'\n    },\n    'model.isDatetime': {\n      type: 'booleanAttribute',\n      hook: 'define-type-datetime',\n      name: 'checked'\n    },\n    'model.isDuration': {\n      type: 'booleanAttribute',\n      hook: 'define-type-duration',\n      name: 'checked'\n    },\n    'model.isText': {\n      type: 'booleanAttribute',\n      hook: 'define-type-text',\n      name: 'checked'\n    },\n    'model.accessor': {\n      type: 'value',\n      hook: 'define-accessor-input'\n    },\n    'model.misvalAsText': {\n      type: 'value',\n      hook: 'define-missing-input'\n    },\n    'model.minvalAsText': {\n      type: 'value',\n      hook: 'define-minimum-input'\n    },\n    'model.maxvalAsText': {\n      type: 'value',\n      hook: 'define-maximum-input'\n    }\n  },\n  events: {\n    'change [data-hook~=define-name-input]': function changeDataHookDefineNameInput() {\n      this.model.name = this.queryByHook('define-name-input').value;\n    },\n    'change [data-hook~=define-units-input]': function changeDataHookDefineUnitsInput() {\n      this.model.units = this.queryByHook('define-units-input').value;\n    },\n    'change [data-hook~=define-description-input]': function changeDataHookDefineDescriptionInput() {\n      this.model.description = this.queryByHook('define-description-input').value;\n    },\n    'click [data-hook~=define-type-continuous]': function clickDataHookDefineTypeContinuous() {\n      this.model.type = 'continuous';\n    },\n    'click [data-hook~=define-type-categorial]': function clickDataHookDefineTypeCategorial() {\n      this.model.type = 'categorial';\n    },\n    'click [data-hook~=define-type-datetime]': function clickDataHookDefineTypeDatetime() {\n      this.model.type = 'datetime';\n    },\n    'click [data-hook~=define-type-duration]': function clickDataHookDefineTypeDuration() {\n      this.model.type = 'duration';\n    },\n    'click [data-hook~=define-type-text]': function clickDataHookDefineTypeText() {\n      this.model.type = 'text';\n    },\n    'click [data-hook~=button-minval-missing]': function clickDataHookButtonMinvalMissing() {\n      if (this.model.minval === misval) {\n        return;\n      }\n\n      if (this.model.hasOwnProperty('rawMinval')) {\n        this.model.misvalAsText = addRawValue(this.model.misvalAsText, this.model.rawMinval);\n      } else {\n        this.model.misvalAsText += ', ' + this.model.minvalAsText;\n      }\n\n      this.model.minvalAsText = 'scanning';\n      this.model.setMinMax();\n      this.queryByHook('define-maximum-input').dispatchEvent(new window.Event('input'));\n      this.queryByHook('define-minimum-input').dispatchEvent(new window.Event('input'));\n      this.queryByHook('define-missing-input').dispatchEvent(new window.Event('input'));\n    },\n    'click [data-hook~=button-maxval-missing]': function clickDataHookButtonMaxvalMissing() {\n      if (this.model.maxval === misval) {\n        return;\n      }\n\n      if (this.model.hasOwnProperty('rawMaxval')) {\n        this.model.misvalAsText = addRawValue(this.model.misvalAsText, this.model.rawMaxval);\n      } else {\n        this.model.misvalAsText += ', ' + this.model.maxvalAsText;\n      }\n\n      this.model.maxvalAsText = 'scanning';\n      this.model.setMinMax();\n      this.queryByHook('define-maximum-input').dispatchEvent(new window.Event('input'));\n      this.queryByHook('define-minimum-input').dispatchEvent(new window.Event('input'));\n      this.queryByHook('define-missing-input').dispatchEvent(new window.Event('input'));\n    },\n    'click [data-hook~=define-rescan-button]': function clickDataHookDefineRescanButton() {\n      if (this.model.isContinuous || this.model.isDatetime || this.model.isDuration) {\n        this.model.minvalAsText = 'scanning';\n        this.model.maxvalAsText = 'scanning';\n        this.model.setMinMax();\n        this.queryByHook('define-minimum-input').dispatchEvent(new window.Event('input'));\n        this.queryByHook('define-maximum-input').dispatchEvent(new window.Event('input'));\n      } else if (this.model.isCategorial) {\n        this.model.setCategories();\n      }\n    },\n    'change [data-hook~=define-accessor-input]': function changeDataHookDefineAccessorInput() {\n      this.model.accessor = this.queryByHook('define-accessor-input').value;\n    },\n    'change [data-hook~=define-missing-input]': function changeDataHookDefineMissingInput() {\n      this.model.misvalAsText = this.queryByHook('define-missing-input').value;\n    },\n    'change [data-hook~=define-minimum-input]': function changeDataHookDefineMinimumInput() {\n      this.model.minvalAsText = this.queryByHook('define-minimum-input').value;\n    },\n    'change [data-hook~=define-maximum-input]': function changeDataHookDefineMaximumInput() {\n      this.model.maxvalAsText = this.queryByHook('define-maximum-input').value;\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjI0ZS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZmFjZXQvZmFjZXQtZGVmaW5lLmpzP2Q1MWMiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFNwb3QgPSByZXF1aXJlKCdzcG90LWZyYW1ld29yaycpO1xudmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL3RlbXBsYXRlcycpO1xudmFyIG1pc3ZhbCA9IFNwb3QudXRpbC5taXN2YWw7XG5cbmZ1bmN0aW9uIGFkZFJhd1ZhbHVlIChzdHJpbmcsIHJhdykge1xuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycgfHwgc3RyaW5nLmxlbmd0aCA9PT0gMCkge1xuICAgIHN0cmluZyA9ICcnO1xuICB9IGVsc2Uge1xuICAgIHN0cmluZyA9IHN0cmluZyArICcsICc7XG4gIH1cblxuICBpZiAodHlwZW9mIHJhdyA9PT0gJ3N0cmluZycpIHtcbiAgICBzdHJpbmcgPSBzdHJpbmcgKyAnXCInICsgcmF3ICsgJ1wiJztcbiAgfSBlbHNlIGlmICh0eXBlb2YgcmF3ID09PSAnbnVtYmVyJykge1xuICAgIHN0cmluZyA9IHN0cmluZyArIHJhdztcbiAgfSBlbHNlIHtcbiAgICBjb25zb2xlLndhcm4oJ0Nhbm5vdCBhZGQgcmF3IHZhbHVlJywgcmF3LCAnb2YgdHlwZScsIHR5cGVvZiByYXcpO1xuICB9XG4gIHJldHVybiBzdHJpbmc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVmlldy5leHRlbmQoe1xuICB0ZW1wbGF0ZTogdGVtcGxhdGVzLmNvbmZpZ3VyZUZhY2V0LmZhY2V0RGVmaW5lLFxuICBkZXJpdmVkOiB7XG4gICAgc2hvd01pbk1heDoge1xuICAgICAgZGVwczogWydtb2RlbC50eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC50eXBlID09PSAnZGF0ZXRpbWUnIHx8IHRoaXMubW9kZWwudHlwZSA9PT0gJ2R1cmF0aW9uJyB8fCB0aGlzLm1vZGVsLnR5cGUgPT09ICdjb250aW51b3VzJztcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIGJpbmRpbmdzOiB7XG4gICAgJ3Nob3dNaW5NYXgnOiBbXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgICBob29rOiAnZGVmaW5lLW1pbmltdW0tZGl2J1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICAgIGhvb2s6ICdkZWZpbmUtbWF4aW11bS1kaXYnXG4gICAgICB9XG4gICAgXSxcbiAgICAnbW9kZWwubmFtZSc6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAnZGVmaW5lLW5hbWUtaW5wdXQnXG4gICAgfSxcbiAgICAnbW9kZWwudW5pdHMnOiB7XG4gICAgICB0eXBlOiAndmFsdWUnLFxuICAgICAgaG9vazogJ2RlZmluZS11bml0cy1pbnB1dCdcbiAgICB9LFxuICAgICdtb2RlbC5kZXNjcmlwdGlvbic6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAnZGVmaW5lLWRlc2NyaXB0aW9uLWlucHV0J1xuICAgIH0sXG5cbiAgICAnbW9kZWwuaXNDb250aW51b3VzJzoge1xuICAgICAgdHlwZTogJ2Jvb2xlYW5BdHRyaWJ1dGUnLFxuICAgICAgaG9vazogJ2RlZmluZS10eXBlLWNvbnRpbnVvdXMnLFxuICAgICAgbmFtZTogJ2NoZWNrZWQnXG4gICAgfSxcbiAgICAnbW9kZWwuaXNDYXRlZ29yaWFsJzoge1xuICAgICAgdHlwZTogJ2Jvb2xlYW5BdHRyaWJ1dGUnLFxuICAgICAgaG9vazogJ2RlZmluZS10eXBlLWNhdGVnb3JpYWwnLFxuICAgICAgbmFtZTogJ2NoZWNrZWQnXG4gICAgfSxcbiAgICAnbW9kZWwuaXNEYXRldGltZSc6IHtcbiAgICAgIHR5cGU6ICdib29sZWFuQXR0cmlidXRlJyxcbiAgICAgIGhvb2s6ICdkZWZpbmUtdHlwZS1kYXRldGltZScsXG4gICAgICBuYW1lOiAnY2hlY2tlZCdcbiAgICB9LFxuICAgICdtb2RlbC5pc0R1cmF0aW9uJzoge1xuICAgICAgdHlwZTogJ2Jvb2xlYW5BdHRyaWJ1dGUnLFxuICAgICAgaG9vazogJ2RlZmluZS10eXBlLWR1cmF0aW9uJyxcbiAgICAgIG5hbWU6ICdjaGVja2VkJ1xuICAgIH0sXG4gICAgJ21vZGVsLmlzVGV4dCc6IHtcbiAgICAgIHR5cGU6ICdib29sZWFuQXR0cmlidXRlJyxcbiAgICAgIGhvb2s6ICdkZWZpbmUtdHlwZS10ZXh0JyxcbiAgICAgIG5hbWU6ICdjaGVja2VkJ1xuICAgIH0sXG5cbiAgICAnbW9kZWwuYWNjZXNzb3InOiB7XG4gICAgICB0eXBlOiAndmFsdWUnLFxuICAgICAgaG9vazogJ2RlZmluZS1hY2Nlc3Nvci1pbnB1dCdcbiAgICB9LFxuICAgICdtb2RlbC5taXN2YWxBc1RleHQnOiB7XG4gICAgICB0eXBlOiAndmFsdWUnLFxuICAgICAgaG9vazogJ2RlZmluZS1taXNzaW5nLWlucHV0J1xuICAgIH0sXG4gICAgJ21vZGVsLm1pbnZhbEFzVGV4dCc6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAnZGVmaW5lLW1pbmltdW0taW5wdXQnXG4gICAgfSxcbiAgICAnbW9kZWwubWF4dmFsQXNUZXh0Jzoge1xuICAgICAgdHlwZTogJ3ZhbHVlJyxcbiAgICAgIGhvb2s6ICdkZWZpbmUtbWF4aW11bS1pbnB1dCdcbiAgICB9XG4gIH0sXG4gIGV2ZW50czoge1xuICAgICdjaGFuZ2UgW2RhdGEtaG9va349ZGVmaW5lLW5hbWUtaW5wdXRdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC5uYW1lID0gdGhpcy5xdWVyeUJ5SG9vaygnZGVmaW5lLW5hbWUtaW5wdXQnKS52YWx1ZTtcbiAgICB9LFxuICAgICdjaGFuZ2UgW2RhdGEtaG9va349ZGVmaW5lLXVuaXRzLWlucHV0XSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwudW5pdHMgPSB0aGlzLnF1ZXJ5QnlIb29rKCdkZWZpbmUtdW5pdHMtaW5wdXQnKS52YWx1ZTtcbiAgICB9LFxuICAgICdjaGFuZ2UgW2RhdGEtaG9va349ZGVmaW5lLWRlc2NyaXB0aW9uLWlucHV0XSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwuZGVzY3JpcHRpb24gPSB0aGlzLnF1ZXJ5QnlIb29rKCdkZWZpbmUtZGVzY3JpcHRpb24taW5wdXQnKS52YWx1ZTtcbiAgICB9LFxuXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWRlZmluZS10eXBlLWNvbnRpbnVvdXNdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC50eXBlID0gJ2NvbnRpbnVvdXMnO1xuICAgIH0sXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWRlZmluZS10eXBlLWNhdGVnb3JpYWxdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC50eXBlID0gJ2NhdGVnb3JpYWwnO1xuICAgIH0sXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWRlZmluZS10eXBlLWRhdGV0aW1lXSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwudHlwZSA9ICdkYXRldGltZSc7XG4gICAgfSxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349ZGVmaW5lLXR5cGUtZHVyYXRpb25dJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC50eXBlID0gJ2R1cmF0aW9uJztcbiAgICB9LFxuICAgICdjbGljayBbZGF0YS1ob29rfj1kZWZpbmUtdHlwZS10ZXh0XSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwudHlwZSA9ICd0ZXh0JztcbiAgICB9LFxuICAgICdjbGljayBbZGF0YS1ob29rfj1idXR0b24tbWludmFsLW1pc3NpbmddJzogZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHRoaXMubW9kZWwubWludmFsID09PSBtaXN2YWwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMubW9kZWwuaGFzT3duUHJvcGVydHkoJ3Jhd01pbnZhbCcpKSB7XG4gICAgICAgIHRoaXMubW9kZWwubWlzdmFsQXNUZXh0ID0gYWRkUmF3VmFsdWUodGhpcy5tb2RlbC5taXN2YWxBc1RleHQsIHRoaXMubW9kZWwucmF3TWludmFsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubW9kZWwubWlzdmFsQXNUZXh0ICs9ICcsICcgKyB0aGlzLm1vZGVsLm1pbnZhbEFzVGV4dDtcbiAgICAgIH1cbiAgICAgIHRoaXMubW9kZWwubWludmFsQXNUZXh0ID0gJ3NjYW5uaW5nJztcbiAgICAgIHRoaXMubW9kZWwuc2V0TWluTWF4KCk7XG4gICAgICB0aGlzLnF1ZXJ5QnlIb29rKCdkZWZpbmUtbWF4aW11bS1pbnB1dCcpLmRpc3BhdGNoRXZlbnQobmV3IHdpbmRvdy5FdmVudCgnaW5wdXQnKSk7XG4gICAgICB0aGlzLnF1ZXJ5QnlIb29rKCdkZWZpbmUtbWluaW11bS1pbnB1dCcpLmRpc3BhdGNoRXZlbnQobmV3IHdpbmRvdy5FdmVudCgnaW5wdXQnKSk7XG4gICAgICB0aGlzLnF1ZXJ5QnlIb29rKCdkZWZpbmUtbWlzc2luZy1pbnB1dCcpLmRpc3BhdGNoRXZlbnQobmV3IHdpbmRvdy5FdmVudCgnaW5wdXQnKSk7XG4gICAgfSxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349YnV0dG9uLW1heHZhbC1taXNzaW5nXSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICh0aGlzLm1vZGVsLm1heHZhbCA9PT0gbWlzdmFsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm1vZGVsLmhhc093blByb3BlcnR5KCdyYXdNYXh2YWwnKSkge1xuICAgICAgICB0aGlzLm1vZGVsLm1pc3ZhbEFzVGV4dCA9IGFkZFJhd1ZhbHVlKHRoaXMubW9kZWwubWlzdmFsQXNUZXh0LCB0aGlzLm1vZGVsLnJhd01heHZhbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm1vZGVsLm1pc3ZhbEFzVGV4dCArPSAnLCAnICsgdGhpcy5tb2RlbC5tYXh2YWxBc1RleHQ7XG4gICAgICB9XG4gICAgICB0aGlzLm1vZGVsLm1heHZhbEFzVGV4dCA9ICdzY2FubmluZyc7XG4gICAgICB0aGlzLm1vZGVsLnNldE1pbk1heCgpO1xuICAgICAgdGhpcy5xdWVyeUJ5SG9vaygnZGVmaW5lLW1heGltdW0taW5wdXQnKS5kaXNwYXRjaEV2ZW50KG5ldyB3aW5kb3cuRXZlbnQoJ2lucHV0JykpO1xuICAgICAgdGhpcy5xdWVyeUJ5SG9vaygnZGVmaW5lLW1pbmltdW0taW5wdXQnKS5kaXNwYXRjaEV2ZW50KG5ldyB3aW5kb3cuRXZlbnQoJ2lucHV0JykpO1xuICAgICAgdGhpcy5xdWVyeUJ5SG9vaygnZGVmaW5lLW1pc3NpbmctaW5wdXQnKS5kaXNwYXRjaEV2ZW50KG5ldyB3aW5kb3cuRXZlbnQoJ2lucHV0JykpO1xuICAgIH0sXG4gICAgJ2NsaWNrIFtkYXRhLWhvb2t+PWRlZmluZS1yZXNjYW4tYnV0dG9uXSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICh0aGlzLm1vZGVsLmlzQ29udGludW91cyB8fCB0aGlzLm1vZGVsLmlzRGF0ZXRpbWUgfHwgdGhpcy5tb2RlbC5pc0R1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMubW9kZWwubWludmFsQXNUZXh0ID0gJ3NjYW5uaW5nJztcbiAgICAgICAgdGhpcy5tb2RlbC5tYXh2YWxBc1RleHQgPSAnc2Nhbm5pbmcnO1xuICAgICAgICB0aGlzLm1vZGVsLnNldE1pbk1heCgpO1xuICAgICAgICB0aGlzLnF1ZXJ5QnlIb29rKCdkZWZpbmUtbWluaW11bS1pbnB1dCcpLmRpc3BhdGNoRXZlbnQobmV3IHdpbmRvdy5FdmVudCgnaW5wdXQnKSk7XG4gICAgICAgIHRoaXMucXVlcnlCeUhvb2soJ2RlZmluZS1tYXhpbXVtLWlucHV0JykuZGlzcGF0Y2hFdmVudChuZXcgd2luZG93LkV2ZW50KCdpbnB1dCcpKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlbC5pc0NhdGVnb3JpYWwpIHtcbiAgICAgICAgdGhpcy5tb2RlbC5zZXRDYXRlZ29yaWVzKCk7XG4gICAgICB9XG4gICAgfSxcblxuICAgICdjaGFuZ2UgW2RhdGEtaG9va349ZGVmaW5lLWFjY2Vzc29yLWlucHV0XSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwuYWNjZXNzb3IgPSB0aGlzLnF1ZXJ5QnlIb29rKCdkZWZpbmUtYWNjZXNzb3ItaW5wdXQnKS52YWx1ZTtcbiAgICB9LFxuICAgICdjaGFuZ2UgW2RhdGEtaG9va349ZGVmaW5lLW1pc3NpbmctaW5wdXRdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC5taXN2YWxBc1RleHQgPSB0aGlzLnF1ZXJ5QnlIb29rKCdkZWZpbmUtbWlzc2luZy1pbnB1dCcpLnZhbHVlO1xuICAgIH0sXG4gICAgJ2NoYW5nZSBbZGF0YS1ob29rfj1kZWZpbmUtbWluaW11bS1pbnB1dF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLm1pbnZhbEFzVGV4dCA9IHRoaXMucXVlcnlCeUhvb2soJ2RlZmluZS1taW5pbXVtLWlucHV0JykudmFsdWU7XG4gICAgfSxcbiAgICAnY2hhbmdlIFtkYXRhLWhvb2t+PWRlZmluZS1tYXhpbXVtLWlucHV0XSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwubWF4dmFsQXNUZXh0ID0gdGhpcy5xdWVyeUJ5SG9vaygnZGVmaW5lLW1heGltdW0taW5wdXQnKS52YWx1ZTtcbiAgICB9XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFEQTtBQVFBO0FBQ0E7QUFFQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQU1BO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUZBO0FBOURBO0FBbUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBL0VBO0FBN0VBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///b24e\n")},b322:function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nmodule.exports = View.extend({\n  template: templates.configurePartition.partitionDuration,\n  derived: {\n    minvalAsText: {\n      deps: ['model.minval', 'model.isDuration'],\n      fn: function fn() {\n        if (this.model.isDuration) {\n          return this.model.minval.toISOString();\n        } else {\n          return 'not a date';\n        }\n      }\n    },\n    maxvalAsText: {\n      deps: ['model.maxval', 'model.isDuration'],\n      fn: function fn() {\n        if (this.model.isDuration) {\n          return this.model.maxval.toISOString();\n        } else {\n          return 'not a date';\n        }\n      }\n    }\n  },\n  bindings: {\n    'model.isDuration': {\n      type: 'toggle',\n      hook: 'group-duration-panel'\n    },\n    'minvalAsText': {\n      type: 'value',\n      hook: 'group-startduration-input'\n    },\n    'maxvalAsText': {\n      type: 'value',\n      hook: 'group-endduration-input'\n    }\n  },\n  events: {\n    'click [data-hook~=group-durationrange-button]': function clickDataHookGroupDurationrangeButton() {\n      var partition = this.model;\n      partition.reset();\n      this.queryByHook('group-startduration-input').dispatchEvent(new window.Event('input'));\n      this.queryByHook('group-endduration-input').dispatchEvent(new window.Event('input'));\n      this.parent.resetFilter = true;\n    },\n    'change [data-hook~=group-startduration-input]': function changeDataHookGroupStartdurationInput() {\n      var d = moment.duration(this.queryByHook('group-startduration-input').value);\n\n      if (moment.isDuration(d)) {\n        this.model.minval = d;\n      }\n\n      this.parent.resetFilter = true;\n    },\n    'change [data-hook~=group-endduration-input]': function changeDataHookGroupEnddurationInput() {\n      var d = moment.duration(this.queryByHook('group-endduration-input').value);\n\n      if (moment.isDuration(d)) {\n        this.model.maxval = d;\n      }\n\n      this.parent.resetFilter = true;\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjMyMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtcGFydGl0aW9uL3BhcnRpdGlvbi1kdXJhdGlvbi5qcz9jZjk0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBWaWV3ID0gcmVxdWlyZSgnYW1wZXJzYW5kLXZpZXcnKTtcbnZhciB0ZW1wbGF0ZXMgPSByZXF1aXJlKCcuLi8uLi90ZW1wbGF0ZXMnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMuY29uZmlndXJlUGFydGl0aW9uLnBhcnRpdGlvbkR1cmF0aW9uLFxuICBkZXJpdmVkOiB7XG4gICAgbWludmFsQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ21vZGVsLm1pbnZhbCcsICdtb2RlbC5pc0R1cmF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5tb2RlbC5pc0R1cmF0aW9uKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwubWludmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICdub3QgYSBkYXRlJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgbWF4dmFsQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ21vZGVsLm1heHZhbCcsICdtb2RlbC5pc0R1cmF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5tb2RlbC5pc0R1cmF0aW9uKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwubWF4dmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICdub3QgYSBkYXRlJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgYmluZGluZ3M6IHtcbiAgICAnbW9kZWwuaXNEdXJhdGlvbic6IHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgaG9vazogJ2dyb3VwLWR1cmF0aW9uLXBhbmVsJ1xuICAgIH0sXG5cbiAgICAnbWludmFsQXNUZXh0Jzoge1xuICAgICAgdHlwZTogJ3ZhbHVlJyxcbiAgICAgIGhvb2s6ICdncm91cC1zdGFydGR1cmF0aW9uLWlucHV0J1xuICAgIH0sXG4gICAgJ21heHZhbEFzVGV4dCc6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAnZ3JvdXAtZW5kZHVyYXRpb24taW5wdXQnXG4gICAgfVxuXG4gIH0sXG4gIGV2ZW50czoge1xuICAgICdjbGljayBbZGF0YS1ob29rfj1ncm91cC1kdXJhdGlvbnJhbmdlLWJ1dHRvbl0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgcGFydGl0aW9uID0gdGhpcy5tb2RlbDtcbiAgICAgIHBhcnRpdGlvbi5yZXNldCgpO1xuXG4gICAgICB0aGlzLnF1ZXJ5QnlIb29rKCdncm91cC1zdGFydGR1cmF0aW9uLWlucHV0JykuZGlzcGF0Y2hFdmVudChuZXcgd2luZG93LkV2ZW50KCdpbnB1dCcpKTtcbiAgICAgIHRoaXMucXVlcnlCeUhvb2soJ2dyb3VwLWVuZGR1cmF0aW9uLWlucHV0JykuZGlzcGF0Y2hFdmVudChuZXcgd2luZG93LkV2ZW50KCdpbnB1dCcpKTtcbiAgICAgIHRoaXMucGFyZW50LnJlc2V0RmlsdGVyID0gdHJ1ZTtcbiAgICB9LFxuICAgICdjaGFuZ2UgW2RhdGEtaG9va349Z3JvdXAtc3RhcnRkdXJhdGlvbi1pbnB1dF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgZCA9IG1vbWVudC5kdXJhdGlvbih0aGlzLnF1ZXJ5QnlIb29rKCdncm91cC1zdGFydGR1cmF0aW9uLWlucHV0JykudmFsdWUpO1xuICAgICAgaWYgKG1vbWVudC5pc0R1cmF0aW9uKGQpKSB7XG4gICAgICAgIHRoaXMubW9kZWwubWludmFsID0gZDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGFyZW50LnJlc2V0RmlsdGVyID0gdHJ1ZTtcbiAgICB9LFxuICAgICdjaGFuZ2UgW2RhdGEtaG9va349Z3JvdXAtZW5kZHVyYXRpb24taW5wdXRdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGQgPSBtb21lbnQuZHVyYXRpb24odGhpcy5xdWVyeUJ5SG9vaygnZ3JvdXAtZW5kZHVyYXRpb24taW5wdXQnKS52YWx1ZSk7XG4gICAgICBpZiAobW9tZW50LmlzRHVyYXRpb24oZCkpIHtcbiAgICAgICAgdGhpcy5tb2RlbC5tYXh2YWwgPSBkO1xuICAgICAgfVxuICAgICAgdGhpcy5wYXJlbnQucmVzZXRGaWx0ZXIgPSB0cnVlO1xuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVJBO0FBVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUkE7QUFYQTtBQXNCQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFGQTtBQVZBO0FBZ0JBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUF0QkE7QUF4Q0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///b322\n")},b43e:function(module,exports){eval('module.exports = {\n  steps: function steps() {\n    return [// {\n      //     element: document.getElementById(\'saveSessionButton\'),\n      //     position: "bottom",\n      //     intro: "Ok, wasn\'t that fun?",\n      // }\n    ];\n  },\n  hints: function hints() {\n    return [{\n      element: document.getElementById(\'saveSessionButton\'),\n      hintPosition: "bottom",\n      hint: "This buttons saves the current session."\n    }, {\n      element: document.getElementById(\'resetFiltersButton\'),\n      hintPosition: "bottom",\n      hint: "This buttons resets all the filters."\n    }];\n  }\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjQzZS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9oZWxwL2FuYWx5emUuanM/ZDhhMSJdLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBzdGVwczogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAvLyB7XG4gICAgICAgICAgICAvLyAgICAgZWxlbWVudDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NhdmVTZXNzaW9uQnV0dG9uJyksXG4gICAgICAgICAgICAvLyAgICAgcG9zaXRpb246IFwiYm90dG9tXCIsXG4gICAgICAgICAgICAvLyAgICAgaW50cm86IFwiT2ssIHdhc24ndCB0aGF0IGZ1bj9cIixcbiAgICAgICAgICAgIC8vIH1cbiAgICAgICAgXTtcbiAgICB9LFxuICAgIGhpbnRzOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50OiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2F2ZVNlc3Npb25CdXR0b24nKSxcbiAgICAgICAgICAgICAgICBoaW50UG9zaXRpb246IFwiYm90dG9tXCIsXG4gICAgICAgICAgICAgICAgaGludDogXCJUaGlzIGJ1dHRvbnMgc2F2ZXMgdGhlIGN1cnJlbnQgc2Vzc2lvbi5cIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50OiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVzZXRGaWx0ZXJzQnV0dG9uJyksXG4gICAgICAgICAgICAgICAgaGludFBvc2l0aW9uOiBcImJvdHRvbVwiLFxuICAgICAgICAgICAgICAgIGhpbnQ6IFwiVGhpcyBidXR0b25zIHJlc2V0cyBhbGwgdGhlIGZpbHRlcnMuXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgXTtcbiAgICB9ICAgIFxufTsiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFPQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFIQTtBQU1BO0FBQ0E7QUFDQTtBQUhBO0FBTUE7QUF2QkEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///b43e\n')},b966:function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\"); // var key = require('keymaster')\n\n\nmodule.exports = View.extend({\n  // register keyboard handlers\n  registerKeyboardShortcuts: function registerKeyboardShortcuts() {\n    /*\n    var self = this\n    _.each(this.keyboardShortcuts, function (value, k) {\n        // register key handler scoped to this page\n        key(k, self.cid, _.bind(self[value], self))\n    })\n    key.setScope(this.cid)\n    */\n  },\n  unregisterKeyboardShortcuts: function unregisterKeyboardShortcuts() {// key.deleteScope(this.cid)\n  },\n  props: {\n    pageName: 'string'\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjk2Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9iYXNlLmpzP2U0NWUiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xuLy8gdmFyIGtleSA9IHJlcXVpcmUoJ2tleW1hc3RlcicpXG5cbm1vZHVsZS5leHBvcnRzID0gVmlldy5leHRlbmQoe1xuICAvLyByZWdpc3RlciBrZXlib2FyZCBoYW5kbGVyc1xuICByZWdpc3RlcktleWJvYXJkU2hvcnRjdXRzOiBmdW5jdGlvbiAoKSB7XG4gICAgLypcbiAgICB2YXIgc2VsZiA9IHRoaXNcbiAgICBfLmVhY2godGhpcy5rZXlib2FyZFNob3J0Y3V0cywgZnVuY3Rpb24gKHZhbHVlLCBrKSB7XG4gICAgICAgIC8vIHJlZ2lzdGVyIGtleSBoYW5kbGVyIHNjb3BlZCB0byB0aGlzIHBhZ2VcbiAgICAgICAga2V5KGssIHNlbGYuY2lkLCBfLmJpbmQoc2VsZlt2YWx1ZV0sIHNlbGYpKVxuICAgIH0pXG4gICAga2V5LnNldFNjb3BlKHRoaXMuY2lkKVxuICAgICovXG4gIH0sXG4gIHVucmVnaXN0ZXJLZXlib2FyZFNob3J0Y3V0czogZnVuY3Rpb24gKCkge1xuICAgIC8vIGtleS5kZWxldGVTY29wZSh0aGlzLmNpZClcbiAgfSxcbiAgcHJvcHM6IHtcbiAgICBwYWdlTmFtZTogJ3N0cmluZydcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7OztBQVFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFEQTtBQWZBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///b966\n")},bdff:function(module,exports,__webpack_require__){eval("var AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    id: 'string',\n    date: 'string',\n    name: 'string'\n  },\n  session: {\n    isActive: ['boolean', true, false]\n  },\n  derived: {// fullName: {\n    //     deps: ['date', 'name'],\n    //     fn: function () {\n    //         return this.firstName + ' ' + this.lastName;\n    //     }\n    // }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmRmZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9kYXRhc2V0cy9zZXNzaW9uLW1vZGVsLmpzPzcwZWYiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIEFtcGVyc2FuZE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgICBwcm9wczoge1xuICAgICAgICBpZDogJ3N0cmluZycsXG4gICAgICAgIGRhdGU6ICdzdHJpbmcnLFxuICAgICAgICBuYW1lOiAnc3RyaW5nJ1xuICAgIH0sXG4gICAgc2Vzc2lvbjoge1xuICAgICAgICBpc0FjdGl2ZTogWydib29sZWFuJywgdHJ1ZSwgZmFsc2VdLFxuICAgIH0sXG4gICAgZGVyaXZlZDoge1xuICAgICAgICAvLyBmdWxsTmFtZToge1xuICAgICAgICAvLyAgICAgZGVwczogWydkYXRlJywgJ25hbWUnXSxcbiAgICAgICAgLy8gICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vICAgICAgICAgcmV0dXJuIHRoaXMuZmlyc3ROYW1lICsgJyAnICsgdGhpcy5sYXN0TmFtZTtcbiAgICAgICAgLy8gICAgIH1cbiAgICAgICAgLy8gfVxuICAgIH1cbn0pOyJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFEQTtBQUdBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU5BO0FBVEEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///bdff\n")},c678:function(module,exports,__webpack_require__){eval("var Spot = __webpack_require__(/*! spot-framework */ \"3b07\");\n\nvar View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar timeUtil = Spot.util.time; // this.model should be a DatetimeTransform\n\nvar TimePartView = View.extend({\n  template: '<option data-hook=\"option\"> </option>',\n  render: function render() {\n    this.renderWithTemplate(this);\n  },\n  bindings: {\n    'model.description': [{\n      hook: 'option',\n      type: 'text'\n    }, {\n      hook: 'option',\n      type: 'attribute',\n      name: 'value'\n    }]\n  }\n});\nmodule.exports = View.extend({\n  template: '<select data-hook=\"options\"> </select>',\n  render: function render() {\n    this.renderWithTemplate(this);\n    this.renderCollection(timeUtil.timeParts, TimePartView, this.queryByHook('options'));\n    var value = this.model.transformedFormat;\n    this.queryByHook('options').value = value;\n  },\n  events: {\n    'change [data-hook=\"options\"]': 'changeTimePart'\n  },\n  changeTimePart: function changeTimePart() {\n    var value = this.queryByHook('options').value;\n    this.model.transformedFormat = value;\n\n    if (this.parent.parent.resetFilter === false) {\n      this.parent.parent.resetFilter = true;\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYzY3OC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZmFjZXQvdGltZS1wYXJ0cy1zZWxlY3QuanM/ZDlhZCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgU3BvdCA9IHJlcXVpcmUoJ3Nwb3QtZnJhbWV3b3JrJyk7XG52YXIgVmlldyA9IHJlcXVpcmUoJ2FtcGVyc2FuZC12aWV3Jyk7XG52YXIgdGltZVV0aWwgPSBTcG90LnV0aWwudGltZTtcblxuLy8gdGhpcy5tb2RlbCBzaG91bGQgYmUgYSBEYXRldGltZVRyYW5zZm9ybVxuXG52YXIgVGltZVBhcnRWaWV3ID0gVmlldy5leHRlbmQoe1xuICB0ZW1wbGF0ZTogJzxvcHRpb24gZGF0YS1ob29rPVwib3B0aW9uXCI+IDwvb3B0aW9uPicsXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVuZGVyV2l0aFRlbXBsYXRlKHRoaXMpO1xuICB9LFxuICBiaW5kaW5nczoge1xuICAgICdtb2RlbC5kZXNjcmlwdGlvbic6IFtcbiAgICAgIHtcbiAgICAgICAgaG9vazogJ29wdGlvbicsXG4gICAgICAgIHR5cGU6ICd0ZXh0J1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaG9vazogJ29wdGlvbicsXG4gICAgICAgIHR5cGU6ICdhdHRyaWJ1dGUnLFxuICAgICAgICBuYW1lOiAndmFsdWUnXG4gICAgICB9XG4gICAgXVxuICB9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiAnPHNlbGVjdCBkYXRhLWhvb2s9XCJvcHRpb25zXCI+IDwvc2VsZWN0PicsXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVuZGVyV2l0aFRlbXBsYXRlKHRoaXMpO1xuICAgIHRoaXMucmVuZGVyQ29sbGVjdGlvbih0aW1lVXRpbC50aW1lUGFydHMsIFRpbWVQYXJ0VmlldywgdGhpcy5xdWVyeUJ5SG9vaygnb3B0aW9ucycpKTtcblxuICAgIHZhciB2YWx1ZSA9IHRoaXMubW9kZWwudHJhbnNmb3JtZWRGb3JtYXQ7XG4gICAgdGhpcy5xdWVyeUJ5SG9vaygnb3B0aW9ucycpLnZhbHVlID0gdmFsdWU7XG4gIH0sXG4gIGV2ZW50czoge1xuICAgICdjaGFuZ2UgW2RhdGEtaG9vaz1cIm9wdGlvbnNcIl0nOiAnY2hhbmdlVGltZVBhcnQnXG4gIH0sXG4gIGNoYW5nZVRpbWVQYXJ0OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZhbHVlID0gdGhpcy5xdWVyeUJ5SG9vaygnb3B0aW9ucycpLnZhbHVlO1xuICAgIHRoaXMubW9kZWwudHJhbnNmb3JtZWRGb3JtYXQgPSB2YWx1ZTtcbiAgICBpZiAodGhpcy5wYXJlbnQucGFyZW50LnJlc2V0RmlsdGVyID09PSBmYWxzZSkge1xuICAgICAgdGhpcy5wYXJlbnQucGFyZW50LnJlc2V0RmlsdGVyID0gdHJ1ZTtcbiAgICB9XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUhBO0FBTkE7QUFMQTtBQW9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQWxCQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///c678\n")},c783:function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nmodule.exports = View.extend({\n  template: templates.configureFacet.categorialRule,\n  bindings: {\n    'model.expression': {\n      type: 'value',\n      hook: 'category-expression-input'\n    },\n    'model.count': {\n      type: 'text',\n      hook: 'category-value-count'\n    },\n    'model.group': {\n      type: 'value',\n      hook: 'category-group-input'\n    }\n  },\n  events: {\n    'click [data-hook~=category-remove]': function clickDataHookCategoryRemove() {\n      this.collection.remove(this.model);\n    },\n    'change [data-hook~=category-expression-input]': function changeDataHookCategoryExpressionInput() {\n      this.model.expression = this.queryByHook('category-expression-input').value;\n    },\n    'change [data-hook~=category-group-input]': function changeDataHookCategoryGroupInput() {\n      this.model.group = this.queryByHook('category-group-input').value;\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYzc4My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZmFjZXQvY2F0ZWdvcmlhbC1ydWxlLmpzPzdjMWYiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL3RlbXBsYXRlcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZXcuZXh0ZW5kKHtcbiAgdGVtcGxhdGU6IHRlbXBsYXRlcy5jb25maWd1cmVGYWNldC5jYXRlZ29yaWFsUnVsZSxcbiAgYmluZGluZ3M6IHtcbiAgICAnbW9kZWwuZXhwcmVzc2lvbic6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAnY2F0ZWdvcnktZXhwcmVzc2lvbi1pbnB1dCdcbiAgICB9LFxuICAgICdtb2RlbC5jb3VudCc6IHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIGhvb2s6ICdjYXRlZ29yeS12YWx1ZS1jb3VudCdcbiAgICB9LFxuICAgICdtb2RlbC5ncm91cCc6IHtcbiAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICBob29rOiAnY2F0ZWdvcnktZ3JvdXAtaW5wdXQnXG4gICAgfVxuICB9LFxuICBldmVudHM6IHtcbiAgICAnY2xpY2sgW2RhdGEtaG9va349Y2F0ZWdvcnktcmVtb3ZlXSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuY29sbGVjdGlvbi5yZW1vdmUodGhpcy5tb2RlbCk7XG4gICAgfSxcbiAgICAnY2hhbmdlIFtkYXRhLWhvb2t+PWNhdGVnb3J5LWV4cHJlc3Npb24taW5wdXRdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC5leHByZXNzaW9uID0gdGhpcy5xdWVyeUJ5SG9vaygnY2F0ZWdvcnktZXhwcmVzc2lvbi1pbnB1dCcpLnZhbHVlO1xuICAgIH0sXG4gICAgJ2NoYW5nZSBbZGF0YS1ob29rfj1jYXRlZ29yeS1ncm91cC1pbnB1dF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLmdyb3VwID0gdGhpcy5xdWVyeUJ5SG9vaygnY2F0ZWdvcnktZ3JvdXAtaW5wdXQnKS52YWx1ZTtcbiAgICB9XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFGQTtBQVRBO0FBY0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFUQTtBQWhCQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///c783\n")},d11f:function(module,exports,__webpack_require__){"use strict";eval("/* global window: false */\n\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nfunction prettyPrintDuration(tick) {\n  var parts = [];\n  var count;\n  var remainder = moment.duration(tick);\n  count = Math.floor(remainder.asYears());\n\n  if (count) {\n    if (count === 1) {\n      parts.push('1 year');\n    } else {\n      parts.push(count.toString() + ' years');\n    }\n  }\n\n  remainder.subtract(count, 'years');\n  count = Math.floor(remainder.asMonths());\n\n  if (count) {\n    if (count === 1) {\n      parts.push('1 month');\n    } else {\n      parts.push(count.toString() + ' months');\n    }\n  }\n\n  remainder.subtract(count, 'months');\n  count = Math.floor(remainder.asWeeks());\n\n  if (count) {\n    if (count === 1) {\n      parts.push('1 week');\n    } else {\n      parts.push(count.toString() + ' weeks');\n    }\n  }\n\n  remainder.subtract(count, 'weeks');\n  count = Math.floor(remainder.asDays());\n\n  if (count) {\n    if (count === 1) {\n      parts.push('1 day');\n    } else {\n      parts.push(count.toString() + ' days');\n    }\n  }\n\n  remainder.subtract(count, 'days');\n  count = Math.floor(remainder.asHours());\n\n  if (count) {\n    if (count === 1) {\n      parts.push('1 hour');\n    } else {\n      parts.push(count.toString() + ' hours');\n    }\n  }\n\n  remainder.subtract(count, 'hours');\n  count = Math.floor(remainder.asMinutes());\n\n  if (count) {\n    if (count === 1) {\n      parts.push('1 minute');\n    } else {\n      parts.push(count.toString() + ' minutes');\n    }\n  }\n\n  remainder.subtract(count, 'minutes');\n  count = Math.floor(remainder.asSeconds());\n\n  if (count) {\n    if (count === 1) {\n      parts.push('1 second');\n    } else {\n      parts.push(count.toString() + ' seconds');\n    }\n  }\n\n  remainder.subtract(count, 'seconds');\n  count = Math.floor(remainder.asMilliseconds());\n\n  if (count) {\n    if (count === 1) {\n      parts.push('1 millisecond');\n    } else {\n      parts.push(count.toString() + ' milliseconds');\n    }\n  }\n\n  return parts.join(' ');\n}\n\nvar time = {\n  units: [{\n    name: 'millisecond',\n    steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]\n  }, {\n    name: 'second',\n    steps: [1, 2, 5, 10, 30]\n  }, {\n    name: 'minute',\n    steps: [1, 2, 5, 10, 30]\n  }, {\n    name: 'hour',\n    steps: [1, 2, 3, 6, 12]\n  }, {\n    name: 'day',\n    steps: [1, 2, 5]\n  }, {\n    name: 'week',\n    maxStep: 4\n  }, {\n    name: 'month',\n    maxStep: 3 //  }, {\n    //    name: 'quarter',\n    //    maxStep: 4\n\n  }, {\n    name: 'year',\n    maxStep: false\n  }]\n};\nvar defaultConfig = {};\n\nmodule.exports = function (Chart, moment) {\n  var helpers = Chart.helpers;\n  moment = moment || __webpack_require__(/*! moment */ \"da01\");\n  var DurationScale = Chart.Scale.extend({\n    getLabelMoment: function getLabelMoment(datasetIndex, index) {\n      if (datasetIndex === null || index === null) {\n        return null;\n      }\n\n      if (typeof this.labelMoments[datasetIndex] !== 'undefined') {\n        return this.labelMoments[datasetIndex][index];\n      }\n\n      return null;\n    },\n    getLabelDiff: function getLabelDiff(datasetIndex, index) {\n      var me = this;\n\n      if (datasetIndex === null || index === null) {\n        return null;\n      }\n\n      if (me.labelDiffs === undefined) {\n        me.buildLabelDiffs();\n      }\n\n      if (typeof me.labelDiffs[datasetIndex] !== 'undefined') {\n        return me.labelDiffs[datasetIndex][index];\n      }\n\n      return null;\n    },\n    getMomentStartOf: function getMomentStartOf(tick) {\n      var me = this;\n      return moment.duration(Math.floor(tick.as(me.tickUnit)), me.tickUnit);\n    },\n    determineDataLimits: function determineDataLimits() {\n      var me = this;\n      me.labelMoments = []; // Get min max from labels\n\n      var scaleLabelMoments = [];\n\n      if (me.chart.data.labels && me.chart.data.labels.length > 0) {\n        me.firstTick = null;\n        me.lastTick = null;\n        helpers.each(me.chart.data.labels, function (label) {\n          var labelMoment = me.parseDuration(label);\n          scaleLabelMoments.push(labelMoment);\n\n          if (me.firstTick === null || me.firstTick > labelMoment) {\n            me.firstTick = labelMoment;\n          }\n\n          if (me.lastTick === null || me.lastTick < labelMoment) {\n            me.lastTick = labelMoment;\n          }\n        }, me);\n      } else {\n        me.firstTick = moment.duration('PT1S');\n        me.lastTick = moment.duration('PT10S');\n      } // Adjust min max from datasets, and build the labelMoments[dataset][point] array\n\n\n      helpers.each(me.chart.data.datasets, function (dataset, datasetIndex) {\n        var momentsForDataset = [];\n        var datasetVisible = me.chart.isDatasetVisible(datasetIndex);\n\n        if (_typeof(dataset.data[0]) === 'object' && dataset.data[0] !== null) {\n          helpers.each(dataset.data, function (value) {\n            var labelMoment;\n\n            if (me.isHorizontal()) {\n              labelMoment = me.parseDuration(value.x);\n            } else {\n              labelMoment = me.parseDuration(value.y);\n            }\n\n            momentsForDataset.push(labelMoment);\n\n            if (datasetVisible) {\n              // May have gone outside the scale ranges, make sure we keep the first and last ticks updated\n              me.firstTick = me.firstTick > labelMoment ? labelMoment : me.firstTick;\n              me.lastTick = me.lastTick < labelMoment ? labelMoment : me.lastTick;\n            }\n          }, me);\n        } else {\n          // We have no labels. Use the ones from the scale\n          momentsForDataset = scaleLabelMoments;\n        }\n\n        me.labelMoments.push(momentsForDataset);\n      }, me); // We will modify these, so clone for later\n\n      me.firstTick = moment.duration(me.firstTick);\n      me.lastTick = moment.duration(me.lastTick);\n    },\n    buildLabelDiffs: function buildLabelDiffs() {\n      var me = this;\n      me.labelDiffs = [];\n      var scaleLabelDiffs = []; // Parse common labels once\n\n      if (me.chart.data.labels && me.chart.data.labels.length > 0) {\n        helpers.each(me.chart.data.labels, function (label) {\n          var labelMoment = me.parseDuration(label);\n\n          if (moment.isDuration(labelMoment)) {\n            scaleLabelDiffs.push(moment.duration(labelMoment).subtract(me.firstTick).as(me.tickUnit));\n          }\n        }, me);\n      }\n\n      helpers.each(me.chart.data.datasets, function (dataset) {\n        var diffsForDataset = [];\n\n        if (_typeof(dataset.data[0]) === 'object' && dataset.data[0] !== null) {\n          helpers.each(dataset.data, function (value) {\n            var labelMoment;\n\n            if (me.isHorizontal()) {\n              labelMoment = me.parseDuration(value.x);\n            } else {\n              labelMoment = me.parseDuration(value.y);\n            }\n\n            if (moment.isDuration(labelMoment)) {\n              diffsForDataset.push(moment.duration(labelMoment).subtract(me.firstTick).as(me.tickUnit));\n            }\n          }, me);\n        } else {\n          // We have no labels. Use common ones\n          diffsForDataset = scaleLabelDiffs;\n        }\n\n        me.labelDiffs.push(diffsForDataset);\n      }, me);\n    },\n    buildTicks: function buildTicks() {\n      var me = this;\n      me.ctx.save();\n      var tickFontSize = helpers.getValueOrDefault(me.options.ticks.fontSize, Chart.defaults.global.defaultFontSize);\n      var tickFontStyle = helpers.getValueOrDefault(me.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle);\n      var tickFontFamily = helpers.getValueOrDefault(me.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily);\n      var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\n      me.ctx.font = tickLabelFont;\n      me.ticks = [];\n      me.unitScale = 1; // How much we scale the unit by, ie 2 means 2x unit per step\n\n      me.scaleSizeInUnits = 0; // How large the scale is in the base unit (seconds, minutes, etc)\n      // Determine the smallest needed unit of the time\n\n      var innerWidth = me.isHorizontal() ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom); // Crude approximation of what the label length might be\n\n      var tempFirstLabel = me.tickFormatFunction(me.firstTick, 0, []);\n      var tickLabelWidth = me.ctx.measureText(tempFirstLabel).width;\n      var cosRotation = Math.cos(helpers.toRadians(me.options.ticks.maxRotation));\n      var sinRotation = Math.sin(helpers.toRadians(me.options.ticks.maxRotation));\n      tickLabelWidth = tickLabelWidth * cosRotation + tickFontSize * sinRotation;\n      var labelCapacity = innerWidth / tickLabelWidth; // Start as small as possible\n\n      me.tickUnit = 'millisecond';\n      me.scaleSizeInUnits = moment.duration(me.lastTick).subtract(me.firstTick).as(me.tickUnit);\n      var unitDefinitionIndex = 0;\n      var unitDefinition = time.units[unitDefinitionIndex]; // While we aren't ideal and we don't have units left\n\n      while (unitDefinitionIndex < time.units.length) {\n        // Can we scale this unit. If `false` we can scale infinitely\n        me.unitScale = 1;\n\n        if (helpers.isArray(unitDefinition.steps) && Math.ceil(me.scaleSizeInUnits / labelCapacity) < helpers.max(unitDefinition.steps)) {\n          // Use one of the predefined steps\n          for (var idx = 0; idx < unitDefinition.steps.length; ++idx) {\n            if (unitDefinition.steps[idx] >= Math.ceil(me.scaleSizeInUnits / labelCapacity)) {\n              me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, unitDefinition.steps[idx]);\n              break;\n            }\n          }\n\n          break;\n        } else if (unitDefinition.maxStep === false || Math.ceil(me.scaleSizeInUnits / labelCapacity) < unitDefinition.maxStep) {\n          // We have a max step. Scale this unit\n          me.unitScale = helpers.getValueOrDefault(me.options.time.unitStepSize, Math.ceil(me.scaleSizeInUnits / labelCapacity));\n          break;\n        } else {\n          // Move to the next unit up\n          ++unitDefinitionIndex;\n          unitDefinition = time.units[unitDefinitionIndex];\n          me.tickUnit = unitDefinition.name;\n          var leadingUnitBuffer = moment.duration(me.firstTick).subtract(me.getMomentStartOf(me.firstTick)).as(me.tickUnit);\n          var trailingUnitBuffer = me.getMomentStartOf(moment.duration(me.lastTick).add(1, me.tickUnit)).subtract(me.lastTick).as(me.tickUnit);\n          me.scaleSizeInUnits = moment.duration(me.lastTick).subtract(me.firstTick).as(me.tickUnit) + leadingUnitBuffer + trailingUnitBuffer;\n        }\n      } // Round the first tick\n\n\n      var roundedStart = me.getMomentStartOf(me.firstTick); // Round the last tick\n\n      var roundedEnd = me.getMomentStartOf(me.lastTick);\n      var delta = moment.duration(roundedEnd).subtract(me.lastTick).as(me.tickUnit);\n\n      if (delta < 0) {\n        // Do not use end of because we need me to be in the next time unit\n        me.lastTick = roundedEnd.add(1, me.tickUnit);\n      } else if (delta >= 0) {\n        me.lastTick = roundedEnd;\n      }\n\n      me.scaleSizeInUnits = moment.duration(me.lastTick).subtract(me.firstTick).as(me.tickUnit);\n      me.ticks.push(moment.duration(me.firstTick)); // For every unit in between the first and last moment, create a moment and add it to the ticks tick\n\n      for (var i = 1; i <= me.scaleSizeInUnits; ++i) {\n        var newTick = moment.duration(roundedStart).add(i, me.tickUnit);\n\n        if (i % me.unitScale === 0) {\n          me.ticks.push(newTick);\n        }\n      }\n\n      me.ctx.restore(); // Invalidate label diffs cache\n\n      me.labelDiffs = undefined;\n    },\n    // Get tooltip label\n    getLabelForIndex: function getLabelForIndex(index, datasetIndex) {\n      var me = this;\n      var label = me.chart.data.labels && index < me.chart.data.labels.length ? me.chart.data.labels[index] : '';\n\n      if (_typeof(me.chart.data.datasets[datasetIndex].data[0]) === 'object') {\n        if (me.isHorizontal()) {\n          label = me.chart.data.datasets[datasetIndex].data[index].x;\n        } else {\n          label = me.chart.data.datasets[datasetIndex].data[index].y;\n        }\n      }\n\n      return prettyPrintDuration(me.parseDuration(label));\n    },\n    // Function to format an individual tick mark\n    tickFormatFunction: function tickFormatFunction(tick, index, ticks) {\n      return tick.toISOString();\n    },\n    convertTicksToLabels: function convertTicksToLabels() {\n      var me = this;\n      me.tickMoments = me.ticks;\n      me.ticks = me.ticks.map(me.tickFormatFunction, me);\n    },\n    getPixelForValue: function getPixelForValue(value, index, datasetIndex) {\n      var me = this;\n      var offset = null;\n\n      if (index !== undefined && datasetIndex !== undefined) {\n        offset = me.getLabelDiff(datasetIndex, index);\n      }\n\n      if (offset === null) {\n        if (!value || !moment.isDuration(value)) {\n          // not already a moment object\n          value = me.parseDuration(value);\n        }\n\n        if (value && moment.isDuration(value)) {\n          offset = moment.duration(value).subtract(me.firstTick).as(me.tickUnit);\n        }\n      }\n\n      if (offset !== null) {\n        var decimal = offset !== 0 ? offset / me.scaleSizeInUnits : offset;\n\n        if (me.isHorizontal()) {\n          var innerWidth = me.width - (me.paddingLeft + me.paddingRight);\n          var valueOffset = innerWidth * decimal + me.paddingLeft;\n          return me.left + Math.round(valueOffset);\n        }\n\n        var innerHeight = me.height - (me.paddingTop + me.paddingBottom);\n        var heightOffset = innerHeight * decimal + me.paddingTop;\n        return me.top + Math.round(heightOffset);\n      }\n    },\n    getPixelForTick: function getPixelForTick(index) {\n      return this.getPixelForValue(this.tickMoments[index], null, null);\n    },\n    getValueForPixel: function getValueForPixel(pixel) {\n      var me = this;\n      var innerDimension = me.isHorizontal() ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);\n      var offset = (pixel - (me.isHorizontal() ? me.left + me.paddingLeft : me.top + me.paddingTop)) / innerDimension;\n      offset *= me.scaleSizeInUnits;\n      return moment.duration(me.firstTick).add(moment.duration(offset, me.tickUnit).asSeconds(), 'seconds');\n    },\n    parseDuration: function parseDuration(label) {\n      return moment.duration(label);\n    }\n  });\n  Chart.scaleService.registerScaleType('spot-duration', DurationScale, defaultConfig);\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZDExZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL2NoYXJ0anMtZHVyYXRpb24tc2NhbGUuanM/MWY5ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBnbG9iYWwgd2luZG93OiBmYWxzZSAqL1xuJ3VzZSBzdHJpY3QnO1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xuXG5mdW5jdGlvbiBwcmV0dHlQcmludER1cmF0aW9uICh0aWNrKSB7XG4gIHZhciBwYXJ0cyA9IFtdO1xuICB2YXIgY291bnQ7XG4gIHZhciByZW1haW5kZXIgPSBtb21lbnQuZHVyYXRpb24odGljayk7XG5cbiAgY291bnQgPSBNYXRoLmZsb29yKHJlbWFpbmRlci5hc1llYXJzKCkpO1xuICBpZiAoY291bnQpIHsgaWYgKGNvdW50ID09PSAxKSB7IHBhcnRzLnB1c2goJzEgeWVhcicpOyB9IGVsc2UgeyBwYXJ0cy5wdXNoKGNvdW50LnRvU3RyaW5nKCkgKyAnIHllYXJzJyk7IH0gfVxuICByZW1haW5kZXIuc3VidHJhY3QoY291bnQsICd5ZWFycycpO1xuXG4gIGNvdW50ID0gTWF0aC5mbG9vcihyZW1haW5kZXIuYXNNb250aHMoKSk7XG4gIGlmIChjb3VudCkgeyBpZiAoY291bnQgPT09IDEpIHsgcGFydHMucHVzaCgnMSBtb250aCcpOyB9IGVsc2UgeyBwYXJ0cy5wdXNoKGNvdW50LnRvU3RyaW5nKCkgKyAnIG1vbnRocycpOyB9IH1cbiAgcmVtYWluZGVyLnN1YnRyYWN0KGNvdW50LCAnbW9udGhzJyk7XG5cbiAgY291bnQgPSBNYXRoLmZsb29yKHJlbWFpbmRlci5hc1dlZWtzKCkpO1xuICBpZiAoY291bnQpIHsgaWYgKGNvdW50ID09PSAxKSB7IHBhcnRzLnB1c2goJzEgd2VlaycpOyB9IGVsc2UgeyBwYXJ0cy5wdXNoKGNvdW50LnRvU3RyaW5nKCkgKyAnIHdlZWtzJyk7IH0gfVxuICByZW1haW5kZXIuc3VidHJhY3QoY291bnQsICd3ZWVrcycpO1xuXG4gIGNvdW50ID0gTWF0aC5mbG9vcihyZW1haW5kZXIuYXNEYXlzKCkpO1xuICBpZiAoY291bnQpIHsgaWYgKGNvdW50ID09PSAxKSB7IHBhcnRzLnB1c2goJzEgZGF5Jyk7IH0gZWxzZSB7IHBhcnRzLnB1c2goY291bnQudG9TdHJpbmcoKSArICcgZGF5cycpOyB9IH1cbiAgcmVtYWluZGVyLnN1YnRyYWN0KGNvdW50LCAnZGF5cycpO1xuXG4gIGNvdW50ID0gTWF0aC5mbG9vcihyZW1haW5kZXIuYXNIb3VycygpKTtcbiAgaWYgKGNvdW50KSB7IGlmIChjb3VudCA9PT0gMSkgeyBwYXJ0cy5wdXNoKCcxIGhvdXInKTsgfSBlbHNlIHsgcGFydHMucHVzaChjb3VudC50b1N0cmluZygpICsgJyBob3VycycpOyB9IH1cbiAgcmVtYWluZGVyLnN1YnRyYWN0KGNvdW50LCAnaG91cnMnKTtcblxuICBjb3VudCA9IE1hdGguZmxvb3IocmVtYWluZGVyLmFzTWludXRlcygpKTtcbiAgaWYgKGNvdW50KSB7IGlmIChjb3VudCA9PT0gMSkgeyBwYXJ0cy5wdXNoKCcxIG1pbnV0ZScpOyB9IGVsc2UgeyBwYXJ0cy5wdXNoKGNvdW50LnRvU3RyaW5nKCkgKyAnIG1pbnV0ZXMnKTsgfSB9XG4gIHJlbWFpbmRlci5zdWJ0cmFjdChjb3VudCwgJ21pbnV0ZXMnKTtcblxuICBjb3VudCA9IE1hdGguZmxvb3IocmVtYWluZGVyLmFzU2Vjb25kcygpKTtcbiAgaWYgKGNvdW50KSB7IGlmIChjb3VudCA9PT0gMSkgeyBwYXJ0cy5wdXNoKCcxIHNlY29uZCcpOyB9IGVsc2UgeyBwYXJ0cy5wdXNoKGNvdW50LnRvU3RyaW5nKCkgKyAnIHNlY29uZHMnKTsgfSB9XG4gIHJlbWFpbmRlci5zdWJ0cmFjdChjb3VudCwgJ3NlY29uZHMnKTtcblxuICBjb3VudCA9IE1hdGguZmxvb3IocmVtYWluZGVyLmFzTWlsbGlzZWNvbmRzKCkpO1xuICBpZiAoY291bnQpIHsgaWYgKGNvdW50ID09PSAxKSB7IHBhcnRzLnB1c2goJzEgbWlsbGlzZWNvbmQnKTsgfSBlbHNlIHsgcGFydHMucHVzaChjb3VudC50b1N0cmluZygpICsgJyBtaWxsaXNlY29uZHMnKTsgfSB9XG4gIHJldHVybiBwYXJ0cy5qb2luKCcgJyk7XG59XG5cbnZhciB0aW1lID0ge1xuICB1bml0czogW3tcbiAgICBuYW1lOiAnbWlsbGlzZWNvbmQnLFxuICAgIHN0ZXBzOiBbMSwgMiwgNSwgMTAsIDIwLCA1MCwgMTAwLCAyNTAsIDUwMF1cbiAgfSwge1xuICAgIG5hbWU6ICdzZWNvbmQnLFxuICAgIHN0ZXBzOiBbMSwgMiwgNSwgMTAsIDMwXVxuICB9LCB7XG4gICAgbmFtZTogJ21pbnV0ZScsXG4gICAgc3RlcHM6IFsxLCAyLCA1LCAxMCwgMzBdXG4gIH0sIHtcbiAgICBuYW1lOiAnaG91cicsXG4gICAgc3RlcHM6IFsxLCAyLCAzLCA2LCAxMl1cbiAgfSwge1xuICAgIG5hbWU6ICdkYXknLFxuICAgIHN0ZXBzOiBbMSwgMiwgNV1cbiAgfSwge1xuICAgIG5hbWU6ICd3ZWVrJyxcbiAgICBtYXhTdGVwOiA0XG4gIH0sIHtcbiAgICBuYW1lOiAnbW9udGgnLFxuICAgIG1heFN0ZXA6IDNcbi8vICB9LCB7XG4vLyAgICBuYW1lOiAncXVhcnRlcicsXG4vLyAgICBtYXhTdGVwOiA0XG4gIH0sIHtcbiAgICBuYW1lOiAneWVhcicsXG4gICAgbWF4U3RlcDogZmFsc2VcbiAgfV1cbn07XG5cbnZhciBkZWZhdWx0Q29uZmlnID0ge1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQ2hhcnQsIG1vbWVudCkge1xuICB2YXIgaGVscGVycyA9IENoYXJ0LmhlbHBlcnM7XG4gIG1vbWVudCA9IG1vbWVudCB8fCByZXF1aXJlKCdtb21lbnQnKTtcblxuICB2YXIgRHVyYXRpb25TY2FsZSA9IENoYXJ0LlNjYWxlLmV4dGVuZCh7XG4gICAgZ2V0TGFiZWxNb21lbnQ6IGZ1bmN0aW9uIChkYXRhc2V0SW5kZXgsIGluZGV4KSB7XG4gICAgICBpZiAoZGF0YXNldEluZGV4ID09PSBudWxsIHx8IGluZGV4ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHRoaXMubGFiZWxNb21lbnRzW2RhdGFzZXRJbmRleF0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxhYmVsTW9tZW50c1tkYXRhc2V0SW5kZXhdW2luZGV4XTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICBnZXRMYWJlbERpZmY6IGZ1bmN0aW9uIChkYXRhc2V0SW5kZXgsIGluZGV4KSB7XG4gICAgICB2YXIgbWUgPSB0aGlzO1xuICAgICAgaWYgKGRhdGFzZXRJbmRleCA9PT0gbnVsbCB8fCBpbmRleCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lLmxhYmVsRGlmZnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtZS5idWlsZExhYmVsRGlmZnMoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBtZS5sYWJlbERpZmZzW2RhdGFzZXRJbmRleF0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiBtZS5sYWJlbERpZmZzW2RhdGFzZXRJbmRleF1baW5kZXhdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuICAgIGdldE1vbWVudFN0YXJ0T2Y6IGZ1bmN0aW9uICh0aWNrKSB7XG4gICAgICB2YXIgbWUgPSB0aGlzO1xuICAgICAgcmV0dXJuIG1vbWVudC5kdXJhdGlvbihNYXRoLmZsb29yKHRpY2suYXMobWUudGlja1VuaXQpKSwgbWUudGlja1VuaXQpO1xuICAgIH0sXG4gICAgZGV0ZXJtaW5lRGF0YUxpbWl0czogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIG1lID0gdGhpcztcbiAgICAgIG1lLmxhYmVsTW9tZW50cyA9IFtdO1xuXG4gICAgICAvLyBHZXQgbWluIG1heCBmcm9tIGxhYmVsc1xuICAgICAgdmFyIHNjYWxlTGFiZWxNb21lbnRzID0gW107XG4gICAgICBpZiAobWUuY2hhcnQuZGF0YS5sYWJlbHMgJiYgbWUuY2hhcnQuZGF0YS5sYWJlbHMubGVuZ3RoID4gMCkge1xuICAgICAgICBtZS5maXJzdFRpY2sgPSBudWxsO1xuICAgICAgICBtZS5sYXN0VGljayA9IG51bGw7XG5cbiAgICAgICAgaGVscGVycy5lYWNoKG1lLmNoYXJ0LmRhdGEubGFiZWxzLCBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICB2YXIgbGFiZWxNb21lbnQgPSBtZS5wYXJzZUR1cmF0aW9uKGxhYmVsKTtcblxuICAgICAgICAgIHNjYWxlTGFiZWxNb21lbnRzLnB1c2gobGFiZWxNb21lbnQpO1xuXG4gICAgICAgICAgaWYgKG1lLmZpcnN0VGljayA9PT0gbnVsbCB8fCBtZS5maXJzdFRpY2sgPiBsYWJlbE1vbWVudCkge1xuICAgICAgICAgICAgbWUuZmlyc3RUaWNrID0gbGFiZWxNb21lbnQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChtZS5sYXN0VGljayA9PT0gbnVsbCB8fCBtZS5sYXN0VGljayA8IGxhYmVsTW9tZW50KSB7XG4gICAgICAgICAgICBtZS5sYXN0VGljayA9IGxhYmVsTW9tZW50O1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWUuZmlyc3RUaWNrID0gbW9tZW50LmR1cmF0aW9uKCdQVDFTJyk7XG4gICAgICAgIG1lLmxhc3RUaWNrID0gbW9tZW50LmR1cmF0aW9uKCdQVDEwUycpO1xuICAgICAgfVxuXG4gICAgICAvLyBBZGp1c3QgbWluIG1heCBmcm9tIGRhdGFzZXRzLCBhbmQgYnVpbGQgdGhlIGxhYmVsTW9tZW50c1tkYXRhc2V0XVtwb2ludF0gYXJyYXlcbiAgICAgIGhlbHBlcnMuZWFjaChtZS5jaGFydC5kYXRhLmRhdGFzZXRzLCBmdW5jdGlvbiAoZGF0YXNldCwgZGF0YXNldEluZGV4KSB7XG4gICAgICAgIHZhciBtb21lbnRzRm9yRGF0YXNldCA9IFtdO1xuICAgICAgICB2YXIgZGF0YXNldFZpc2libGUgPSBtZS5jaGFydC5pc0RhdGFzZXRWaXNpYmxlKGRhdGFzZXRJbmRleCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhc2V0LmRhdGFbMF0gPT09ICdvYmplY3QnICYmIGRhdGFzZXQuZGF0YVswXSAhPT0gbnVsbCkge1xuICAgICAgICAgIGhlbHBlcnMuZWFjaChkYXRhc2V0LmRhdGEsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgdmFyIGxhYmVsTW9tZW50O1xuICAgICAgICAgICAgaWYgKG1lLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAgICAgICAgIGxhYmVsTW9tZW50ID0gbWUucGFyc2VEdXJhdGlvbih2YWx1ZS54KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGxhYmVsTW9tZW50ID0gbWUucGFyc2VEdXJhdGlvbih2YWx1ZS55KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1vbWVudHNGb3JEYXRhc2V0LnB1c2gobGFiZWxNb21lbnQpO1xuXG4gICAgICAgICAgICBpZiAoZGF0YXNldFZpc2libGUpIHtcbiAgICAgICAgICAgICAgLy8gTWF5IGhhdmUgZ29uZSBvdXRzaWRlIHRoZSBzY2FsZSByYW5nZXMsIG1ha2Ugc3VyZSB3ZSBrZWVwIHRoZSBmaXJzdCBhbmQgbGFzdCB0aWNrcyB1cGRhdGVkXG4gICAgICAgICAgICAgIG1lLmZpcnN0VGljayA9IG1lLmZpcnN0VGljayA+IGxhYmVsTW9tZW50ID8gbGFiZWxNb21lbnQgOiBtZS5maXJzdFRpY2s7XG4gICAgICAgICAgICAgIG1lLmxhc3RUaWNrID0gbWUubGFzdFRpY2sgPCBsYWJlbE1vbWVudCA/IGxhYmVsTW9tZW50IDogbWUubGFzdFRpY2s7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFdlIGhhdmUgbm8gbGFiZWxzLiBVc2UgdGhlIG9uZXMgZnJvbSB0aGUgc2NhbGVcbiAgICAgICAgICBtb21lbnRzRm9yRGF0YXNldCA9IHNjYWxlTGFiZWxNb21lbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgbWUubGFiZWxNb21lbnRzLnB1c2gobW9tZW50c0ZvckRhdGFzZXQpO1xuICAgICAgfSwgbWUpO1xuXG4gICAgICAvLyBXZSB3aWxsIG1vZGlmeSB0aGVzZSwgc28gY2xvbmUgZm9yIGxhdGVyXG4gICAgICBtZS5maXJzdFRpY2sgPSBtb21lbnQuZHVyYXRpb24obWUuZmlyc3RUaWNrKTtcbiAgICAgIG1lLmxhc3RUaWNrID0gbW9tZW50LmR1cmF0aW9uKG1lLmxhc3RUaWNrKTtcbiAgICB9LFxuICAgIGJ1aWxkTGFiZWxEaWZmczogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIG1lID0gdGhpcztcbiAgICAgIG1lLmxhYmVsRGlmZnMgPSBbXTtcbiAgICAgIHZhciBzY2FsZUxhYmVsRGlmZnMgPSBbXTtcbiAgICAgIC8vIFBhcnNlIGNvbW1vbiBsYWJlbHMgb25jZVxuICAgICAgaWYgKG1lLmNoYXJ0LmRhdGEubGFiZWxzICYmIG1lLmNoYXJ0LmRhdGEubGFiZWxzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaGVscGVycy5lYWNoKG1lLmNoYXJ0LmRhdGEubGFiZWxzLCBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgICAgICB2YXIgbGFiZWxNb21lbnQgPSBtZS5wYXJzZUR1cmF0aW9uKGxhYmVsKTtcblxuICAgICAgICAgIGlmIChtb21lbnQuaXNEdXJhdGlvbihsYWJlbE1vbWVudCkpIHtcbiAgICAgICAgICAgIHNjYWxlTGFiZWxEaWZmcy5wdXNoKG1vbWVudC5kdXJhdGlvbihsYWJlbE1vbWVudCkuc3VidHJhY3QobWUuZmlyc3RUaWNrKS5hcyhtZS50aWNrVW5pdCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgbWUpO1xuICAgICAgfVxuXG4gICAgICBoZWxwZXJzLmVhY2gobWUuY2hhcnQuZGF0YS5kYXRhc2V0cywgZnVuY3Rpb24gKGRhdGFzZXQpIHtcbiAgICAgICAgdmFyIGRpZmZzRm9yRGF0YXNldCA9IFtdO1xuXG4gICAgICAgIGlmICh0eXBlb2YgZGF0YXNldC5kYXRhWzBdID09PSAnb2JqZWN0JyAmJiBkYXRhc2V0LmRhdGFbMF0gIT09IG51bGwpIHtcbiAgICAgICAgICBoZWxwZXJzLmVhY2goZGF0YXNldC5kYXRhLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIHZhciBsYWJlbE1vbWVudDtcbiAgICAgICAgICAgIGlmIChtZS5pc0hvcml6b250YWwoKSkge1xuICAgICAgICAgICAgICBsYWJlbE1vbWVudCA9IG1lLnBhcnNlRHVyYXRpb24odmFsdWUueCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBsYWJlbE1vbWVudCA9IG1lLnBhcnNlRHVyYXRpb24odmFsdWUueSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChtb21lbnQuaXNEdXJhdGlvbihsYWJlbE1vbWVudCkpIHtcbiAgICAgICAgICAgICAgZGlmZnNGb3JEYXRhc2V0LnB1c2gobW9tZW50LmR1cmF0aW9uKGxhYmVsTW9tZW50KS5zdWJ0cmFjdChtZS5maXJzdFRpY2spLmFzKG1lLnRpY2tVbml0KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFdlIGhhdmUgbm8gbGFiZWxzLiBVc2UgY29tbW9uIG9uZXNcbiAgICAgICAgICBkaWZmc0ZvckRhdGFzZXQgPSBzY2FsZUxhYmVsRGlmZnM7XG4gICAgICAgIH1cbiAgICAgICAgbWUubGFiZWxEaWZmcy5wdXNoKGRpZmZzRm9yRGF0YXNldCk7XG4gICAgICB9LCBtZSk7XG4gICAgfSxcbiAgICBidWlsZFRpY2tzOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgbWUgPSB0aGlzO1xuXG4gICAgICBtZS5jdHguc2F2ZSgpO1xuICAgICAgdmFyIHRpY2tGb250U2l6ZSA9IGhlbHBlcnMuZ2V0VmFsdWVPckRlZmF1bHQobWUub3B0aW9ucy50aWNrcy5mb250U2l6ZSwgQ2hhcnQuZGVmYXVsdHMuZ2xvYmFsLmRlZmF1bHRGb250U2l6ZSk7XG4gICAgICB2YXIgdGlja0ZvbnRTdHlsZSA9IGhlbHBlcnMuZ2V0VmFsdWVPckRlZmF1bHQobWUub3B0aW9ucy50aWNrcy5mb250U3R5bGUsIENoYXJ0LmRlZmF1bHRzLmdsb2JhbC5kZWZhdWx0Rm9udFN0eWxlKTtcbiAgICAgIHZhciB0aWNrRm9udEZhbWlseSA9IGhlbHBlcnMuZ2V0VmFsdWVPckRlZmF1bHQobWUub3B0aW9ucy50aWNrcy5mb250RmFtaWx5LCBDaGFydC5kZWZhdWx0cy5nbG9iYWwuZGVmYXVsdEZvbnRGYW1pbHkpO1xuICAgICAgdmFyIHRpY2tMYWJlbEZvbnQgPSBoZWxwZXJzLmZvbnRTdHJpbmcodGlja0ZvbnRTaXplLCB0aWNrRm9udFN0eWxlLCB0aWNrRm9udEZhbWlseSk7XG4gICAgICBtZS5jdHguZm9udCA9IHRpY2tMYWJlbEZvbnQ7XG5cbiAgICAgIG1lLnRpY2tzID0gW107XG4gICAgICBtZS51bml0U2NhbGUgPSAxOyAvLyBIb3cgbXVjaCB3ZSBzY2FsZSB0aGUgdW5pdCBieSwgaWUgMiBtZWFucyAyeCB1bml0IHBlciBzdGVwXG4gICAgICBtZS5zY2FsZVNpemVJblVuaXRzID0gMDsgLy8gSG93IGxhcmdlIHRoZSBzY2FsZSBpcyBpbiB0aGUgYmFzZSB1bml0IChzZWNvbmRzLCBtaW51dGVzLCBldGMpXG5cbiAgICAgIC8vIERldGVybWluZSB0aGUgc21hbGxlc3QgbmVlZGVkIHVuaXQgb2YgdGhlIHRpbWVcbiAgICAgIHZhciBpbm5lcldpZHRoID0gbWUuaXNIb3Jpem9udGFsKCkgPyBtZS53aWR0aCAtIChtZS5wYWRkaW5nTGVmdCArIG1lLnBhZGRpbmdSaWdodCkgOiBtZS5oZWlnaHQgLSAobWUucGFkZGluZ1RvcCArIG1lLnBhZGRpbmdCb3R0b20pO1xuXG4gICAgICAvLyBDcnVkZSBhcHByb3hpbWF0aW9uIG9mIHdoYXQgdGhlIGxhYmVsIGxlbmd0aCBtaWdodCBiZVxuICAgICAgdmFyIHRlbXBGaXJzdExhYmVsID0gbWUudGlja0Zvcm1hdEZ1bmN0aW9uKG1lLmZpcnN0VGljaywgMCwgW10pO1xuICAgICAgdmFyIHRpY2tMYWJlbFdpZHRoID0gbWUuY3R4Lm1lYXN1cmVUZXh0KHRlbXBGaXJzdExhYmVsKS53aWR0aDtcbiAgICAgIHZhciBjb3NSb3RhdGlvbiA9IE1hdGguY29zKGhlbHBlcnMudG9SYWRpYW5zKG1lLm9wdGlvbnMudGlja3MubWF4Um90YXRpb24pKTtcbiAgICAgIHZhciBzaW5Sb3RhdGlvbiA9IE1hdGguc2luKGhlbHBlcnMudG9SYWRpYW5zKG1lLm9wdGlvbnMudGlja3MubWF4Um90YXRpb24pKTtcbiAgICAgIHRpY2tMYWJlbFdpZHRoID0gKHRpY2tMYWJlbFdpZHRoICogY29zUm90YXRpb24pICsgKHRpY2tGb250U2l6ZSAqIHNpblJvdGF0aW9uKTtcbiAgICAgIHZhciBsYWJlbENhcGFjaXR5ID0gaW5uZXJXaWR0aCAvICh0aWNrTGFiZWxXaWR0aCk7XG5cbiAgICAgIC8vIFN0YXJ0IGFzIHNtYWxsIGFzIHBvc3NpYmxlXG4gICAgICBtZS50aWNrVW5pdCA9ICdtaWxsaXNlY29uZCc7XG4gICAgICBtZS5zY2FsZVNpemVJblVuaXRzID0gbW9tZW50LmR1cmF0aW9uKG1lLmxhc3RUaWNrKS5zdWJ0cmFjdChtZS5maXJzdFRpY2spLmFzKG1lLnRpY2tVbml0KTtcblxuICAgICAgdmFyIHVuaXREZWZpbml0aW9uSW5kZXggPSAwO1xuICAgICAgdmFyIHVuaXREZWZpbml0aW9uID0gdGltZS51bml0c1t1bml0RGVmaW5pdGlvbkluZGV4XTtcblxuICAgICAgLy8gV2hpbGUgd2UgYXJlbid0IGlkZWFsIGFuZCB3ZSBkb24ndCBoYXZlIHVuaXRzIGxlZnRcbiAgICAgIHdoaWxlICh1bml0RGVmaW5pdGlvbkluZGV4IDwgdGltZS51bml0cy5sZW5ndGgpIHtcbiAgICAgICAgLy8gQ2FuIHdlIHNjYWxlIHRoaXMgdW5pdC4gSWYgYGZhbHNlYCB3ZSBjYW4gc2NhbGUgaW5maW5pdGVseVxuICAgICAgICBtZS51bml0U2NhbGUgPSAxO1xuXG4gICAgICAgIGlmIChoZWxwZXJzLmlzQXJyYXkodW5pdERlZmluaXRpb24uc3RlcHMpICYmIE1hdGguY2VpbChtZS5zY2FsZVNpemVJblVuaXRzIC8gbGFiZWxDYXBhY2l0eSkgPCBoZWxwZXJzLm1heCh1bml0RGVmaW5pdGlvbi5zdGVwcykpIHtcbiAgICAgICAgICAvLyBVc2Ugb25lIG9mIHRoZSBwcmVkZWZpbmVkIHN0ZXBzXG4gICAgICAgICAgZm9yICh2YXIgaWR4ID0gMDsgaWR4IDwgdW5pdERlZmluaXRpb24uc3RlcHMubGVuZ3RoOyArK2lkeCkge1xuICAgICAgICAgICAgaWYgKHVuaXREZWZpbml0aW9uLnN0ZXBzW2lkeF0gPj0gTWF0aC5jZWlsKG1lLnNjYWxlU2l6ZUluVW5pdHMgLyBsYWJlbENhcGFjaXR5KSkge1xuICAgICAgICAgICAgICBtZS51bml0U2NhbGUgPSBoZWxwZXJzLmdldFZhbHVlT3JEZWZhdWx0KG1lLm9wdGlvbnMudGltZS51bml0U3RlcFNpemUsIHVuaXREZWZpbml0aW9uLnN0ZXBzW2lkeF0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIGlmICgodW5pdERlZmluaXRpb24ubWF4U3RlcCA9PT0gZmFsc2UpIHx8IChNYXRoLmNlaWwobWUuc2NhbGVTaXplSW5Vbml0cyAvIGxhYmVsQ2FwYWNpdHkpIDwgdW5pdERlZmluaXRpb24ubWF4U3RlcCkpIHtcbiAgICAgICAgICAvLyBXZSBoYXZlIGEgbWF4IHN0ZXAuIFNjYWxlIHRoaXMgdW5pdFxuICAgICAgICAgIG1lLnVuaXRTY2FsZSA9IGhlbHBlcnMuZ2V0VmFsdWVPckRlZmF1bHQobWUub3B0aW9ucy50aW1lLnVuaXRTdGVwU2l6ZSwgTWF0aC5jZWlsKG1lLnNjYWxlU2l6ZUluVW5pdHMgLyBsYWJlbENhcGFjaXR5KSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gTW92ZSB0byB0aGUgbmV4dCB1bml0IHVwXG4gICAgICAgICAgKyt1bml0RGVmaW5pdGlvbkluZGV4O1xuICAgICAgICAgIHVuaXREZWZpbml0aW9uID0gdGltZS51bml0c1t1bml0RGVmaW5pdGlvbkluZGV4XTtcblxuICAgICAgICAgIG1lLnRpY2tVbml0ID0gdW5pdERlZmluaXRpb24ubmFtZTtcbiAgICAgICAgICB2YXIgbGVhZGluZ1VuaXRCdWZmZXIgPSBtb21lbnQuZHVyYXRpb24obWUuZmlyc3RUaWNrKS5zdWJ0cmFjdChtZS5nZXRNb21lbnRTdGFydE9mKG1lLmZpcnN0VGljaykpLmFzKG1lLnRpY2tVbml0KTtcbiAgICAgICAgICB2YXIgdHJhaWxpbmdVbml0QnVmZmVyID0gbWUuZ2V0TW9tZW50U3RhcnRPZihtb21lbnQuZHVyYXRpb24obWUubGFzdFRpY2spLmFkZCgxLCBtZS50aWNrVW5pdCkpLnN1YnRyYWN0KG1lLmxhc3RUaWNrKS5hcyhtZS50aWNrVW5pdCk7XG4gICAgICAgICAgbWUuc2NhbGVTaXplSW5Vbml0cyA9IG1vbWVudC5kdXJhdGlvbihtZS5sYXN0VGljaykuc3VidHJhY3QobWUuZmlyc3RUaWNrKS5hcyhtZS50aWNrVW5pdCkgKyBsZWFkaW5nVW5pdEJ1ZmZlciArIHRyYWlsaW5nVW5pdEJ1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBSb3VuZCB0aGUgZmlyc3QgdGlja1xuICAgICAgdmFyIHJvdW5kZWRTdGFydCA9IG1lLmdldE1vbWVudFN0YXJ0T2YobWUuZmlyc3RUaWNrKTtcblxuICAgICAgLy8gUm91bmQgdGhlIGxhc3QgdGlja1xuICAgICAgdmFyIHJvdW5kZWRFbmQgPSBtZS5nZXRNb21lbnRTdGFydE9mKG1lLmxhc3RUaWNrKTtcbiAgICAgIHZhciBkZWx0YSA9IG1vbWVudC5kdXJhdGlvbihyb3VuZGVkRW5kKS5zdWJ0cmFjdChtZS5sYXN0VGljaykuYXMobWUudGlja1VuaXQpO1xuICAgICAgaWYgKGRlbHRhIDwgMCkge1xuICAgICAgICAvLyBEbyBub3QgdXNlIGVuZCBvZiBiZWNhdXNlIHdlIG5lZWQgbWUgdG8gYmUgaW4gdGhlIG5leHQgdGltZSB1bml0XG4gICAgICAgIG1lLmxhc3RUaWNrID0gcm91bmRlZEVuZC5hZGQoMSwgbWUudGlja1VuaXQpO1xuICAgICAgfSBlbHNlIGlmIChkZWx0YSA+PSAwKSB7XG4gICAgICAgIG1lLmxhc3RUaWNrID0gcm91bmRlZEVuZDtcbiAgICAgIH1cblxuICAgICAgbWUuc2NhbGVTaXplSW5Vbml0cyA9IG1vbWVudC5kdXJhdGlvbihtZS5sYXN0VGljaykuc3VidHJhY3QobWUuZmlyc3RUaWNrKS5hcyhtZS50aWNrVW5pdCk7XG5cbiAgICAgIG1lLnRpY2tzLnB1c2gobW9tZW50LmR1cmF0aW9uKG1lLmZpcnN0VGljaykpO1xuXG4gICAgICAvLyBGb3IgZXZlcnkgdW5pdCBpbiBiZXR3ZWVuIHRoZSBmaXJzdCBhbmQgbGFzdCBtb21lbnQsIGNyZWF0ZSBhIG1vbWVudCBhbmQgYWRkIGl0IHRvIHRoZSB0aWNrcyB0aWNrXG4gICAgICBmb3IgKHZhciBpID0gMTsgaSA8PSBtZS5zY2FsZVNpemVJblVuaXRzOyArK2kpIHtcbiAgICAgICAgdmFyIG5ld1RpY2sgPSBtb21lbnQuZHVyYXRpb24ocm91bmRlZFN0YXJ0KS5hZGQoaSwgbWUudGlja1VuaXQpO1xuXG4gICAgICAgIGlmIChpICUgbWUudW5pdFNjYWxlID09PSAwKSB7XG4gICAgICAgICAgbWUudGlja3MucHVzaChuZXdUaWNrKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBtZS5jdHgucmVzdG9yZSgpO1xuXG4gICAgICAvLyBJbnZhbGlkYXRlIGxhYmVsIGRpZmZzIGNhY2hlXG4gICAgICBtZS5sYWJlbERpZmZzID0gdW5kZWZpbmVkO1xuICAgIH0sXG4gICAgLy8gR2V0IHRvb2x0aXAgbGFiZWxcbiAgICBnZXRMYWJlbEZvckluZGV4OiBmdW5jdGlvbiAoaW5kZXgsIGRhdGFzZXRJbmRleCkge1xuICAgICAgdmFyIG1lID0gdGhpcztcbiAgICAgIHZhciBsYWJlbCA9IG1lLmNoYXJ0LmRhdGEubGFiZWxzICYmIGluZGV4IDwgbWUuY2hhcnQuZGF0YS5sYWJlbHMubGVuZ3RoID8gbWUuY2hhcnQuZGF0YS5sYWJlbHNbaW5kZXhdIDogJyc7XG5cbiAgICAgIGlmICh0eXBlb2YgbWUuY2hhcnQuZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdLmRhdGFbMF0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChtZS5pc0hvcml6b250YWwoKSkge1xuICAgICAgICAgIGxhYmVsID0gbWUuY2hhcnQuZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdLmRhdGFbaW5kZXhdLng7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGFiZWwgPSBtZS5jaGFydC5kYXRhLmRhdGFzZXRzW2RhdGFzZXRJbmRleF0uZGF0YVtpbmRleF0ueTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHJldHR5UHJpbnREdXJhdGlvbihtZS5wYXJzZUR1cmF0aW9uKGxhYmVsKSk7XG4gICAgfSxcbiAgICAvLyBGdW5jdGlvbiB0byBmb3JtYXQgYW4gaW5kaXZpZHVhbCB0aWNrIG1hcmtcbiAgICB0aWNrRm9ybWF0RnVuY3Rpb246IGZ1bmN0aW9uICh0aWNrLCBpbmRleCwgdGlja3MpIHtcbiAgICAgIHJldHVybiB0aWNrLnRvSVNPU3RyaW5nKCk7XG4gICAgfSxcbiAgICBjb252ZXJ0VGlja3NUb0xhYmVsczogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIG1lID0gdGhpcztcbiAgICAgIG1lLnRpY2tNb21lbnRzID0gbWUudGlja3M7XG4gICAgICBtZS50aWNrcyA9IG1lLnRpY2tzLm1hcChtZS50aWNrRm9ybWF0RnVuY3Rpb24sIG1lKTtcbiAgICB9LFxuICAgIGdldFBpeGVsRm9yVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgsIGRhdGFzZXRJbmRleCkge1xuICAgICAgdmFyIG1lID0gdGhpcztcbiAgICAgIHZhciBvZmZzZXQgPSBudWxsO1xuICAgICAgaWYgKGluZGV4ICE9PSB1bmRlZmluZWQgJiYgZGF0YXNldEluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgb2Zmc2V0ID0gbWUuZ2V0TGFiZWxEaWZmKGRhdGFzZXRJbmRleCwgaW5kZXgpO1xuICAgICAgfVxuXG4gICAgICBpZiAob2Zmc2V0ID09PSBudWxsKSB7XG4gICAgICAgIGlmICghdmFsdWUgfHwgIW1vbWVudC5pc0R1cmF0aW9uKHZhbHVlKSkge1xuICAgICAgICAgIC8vIG5vdCBhbHJlYWR5IGEgbW9tZW50IG9iamVjdFxuICAgICAgICAgIHZhbHVlID0gbWUucGFyc2VEdXJhdGlvbih2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlICYmIG1vbWVudC5pc0R1cmF0aW9uKHZhbHVlKSkge1xuICAgICAgICAgIG9mZnNldCA9IG1vbWVudC5kdXJhdGlvbih2YWx1ZSkuc3VidHJhY3QobWUuZmlyc3RUaWNrKS5hcyhtZS50aWNrVW5pdCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG9mZnNldCAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgZGVjaW1hbCA9IG9mZnNldCAhPT0gMCA/IG9mZnNldCAvIG1lLnNjYWxlU2l6ZUluVW5pdHMgOiBvZmZzZXQ7XG5cbiAgICAgICAgaWYgKG1lLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAgICAgdmFyIGlubmVyV2lkdGggPSBtZS53aWR0aCAtIChtZS5wYWRkaW5nTGVmdCArIG1lLnBhZGRpbmdSaWdodCk7XG4gICAgICAgICAgdmFyIHZhbHVlT2Zmc2V0ID0gKGlubmVyV2lkdGggKiBkZWNpbWFsKSArIG1lLnBhZGRpbmdMZWZ0O1xuXG4gICAgICAgICAgcmV0dXJuIG1lLmxlZnQgKyBNYXRoLnJvdW5kKHZhbHVlT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaW5uZXJIZWlnaHQgPSBtZS5oZWlnaHQgLSAobWUucGFkZGluZ1RvcCArIG1lLnBhZGRpbmdCb3R0b20pO1xuICAgICAgICB2YXIgaGVpZ2h0T2Zmc2V0ID0gKGlubmVySGVpZ2h0ICogZGVjaW1hbCkgKyBtZS5wYWRkaW5nVG9wO1xuXG4gICAgICAgIHJldHVybiBtZS50b3AgKyBNYXRoLnJvdW5kKGhlaWdodE9mZnNldCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBnZXRQaXhlbEZvclRpY2s6IGZ1bmN0aW9uIChpbmRleCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0UGl4ZWxGb3JWYWx1ZSh0aGlzLnRpY2tNb21lbnRzW2luZGV4XSwgbnVsbCwgbnVsbCk7XG4gICAgfSxcbiAgICBnZXRWYWx1ZUZvclBpeGVsOiBmdW5jdGlvbiAocGl4ZWwpIHtcbiAgICAgIHZhciBtZSA9IHRoaXM7XG4gICAgICB2YXIgaW5uZXJEaW1lbnNpb24gPSBtZS5pc0hvcml6b250YWwoKSA/IG1lLndpZHRoIC0gKG1lLnBhZGRpbmdMZWZ0ICsgbWUucGFkZGluZ1JpZ2h0KSA6IG1lLmhlaWdodCAtIChtZS5wYWRkaW5nVG9wICsgbWUucGFkZGluZ0JvdHRvbSk7XG4gICAgICB2YXIgb2Zmc2V0ID0gKHBpeGVsIC0gKG1lLmlzSG9yaXpvbnRhbCgpID8gbWUubGVmdCArIG1lLnBhZGRpbmdMZWZ0IDogbWUudG9wICsgbWUucGFkZGluZ1RvcCkpIC8gaW5uZXJEaW1lbnNpb247XG4gICAgICBvZmZzZXQgKj0gbWUuc2NhbGVTaXplSW5Vbml0cztcbiAgICAgIHJldHVybiBtb21lbnQuZHVyYXRpb24obWUuZmlyc3RUaWNrKS5hZGQobW9tZW50LmR1cmF0aW9uKG9mZnNldCwgbWUudGlja1VuaXQpLmFzU2Vjb25kcygpLCAnc2Vjb25kcycpO1xuICAgIH0sXG4gICAgcGFyc2VEdXJhdGlvbjogZnVuY3Rpb24gKGxhYmVsKSB7XG4gICAgICByZXR1cm4gbW9tZW50LmR1cmF0aW9uKGxhYmVsKTtcbiAgICB9XG4gIH0pO1xuICBDaGFydC5zY2FsZVNlcnZpY2UucmVnaXN0ZXJTY2FsZVR5cGUoJ3Nwb3QtZHVyYXRpb24nLCBEdXJhdGlvblNjYWxlLCBkZWZhdWx0Q29uZmlnKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUVBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFOQTtBQU9BO0FBQ0E7QUFGQTtBQXpCQTtBQStCQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBcFNBO0FBc1NBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///d11f\n")},d38c:function(module,exports,__webpack_require__){eval("var app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar PageView = __webpack_require__(/*! ./base */ \"b966\");\n\nvar templates = __webpack_require__(/*! ../templates */ \"4324\");\n\nvar PartitionContinuousView = __webpack_require__(/*! ./configure-partition/partition-continuous */ \"6d22\");\n\nvar PartitionCategorialView = __webpack_require__(/*! ./configure-partition/partition-categorial */ \"de24\");\n\nvar PartitionDatetimeView = __webpack_require__(/*! ./configure-partition/partition-datetime */ \"0d07\");\n\nvar PartitionDurationView = __webpack_require__(/*! ./configure-partition/partition-duration */ \"b322\");\n\nvar PartitionTextView = __webpack_require__(/*! ./configure-partition/partition-text */ \"faa4\");\n\nmodule.exports = PageView.extend({\n  initialize: function initialize() {\n    this.pageName = 'configurePartition';\n    this.once('remove', function () {\n      if (this.resetFilter) {\n        var filter = this.model.collection.parent;\n        filter.releaseDataFilter();\n        filter.initDataFilter();\n        filter.updateDataFilter(); // this filter needs new data\n\n        app.me.dataview.getData();\n      }\n    }, this);\n  },\n  template: templates.configurePartition.page,\n  bindings: {\n    'model.label': {\n      type: 'value',\n      hook: 'partition-title-input'\n    },\n    'model.showLabel': {\n      type: 'booleanAttribute',\n      hook: 'show-label',\n      name: 'checked'\n    },\n    'model.showLegend': {\n      type: 'booleanAttribute',\n      hook: 'show-legend',\n      name: 'checked'\n    }\n  },\n  session: {\n    resetFilter: ['boolean', true, false]\n  },\n  events: {\n    'change [data-hook~=partition-title-input]': function changeDataHookPartitionTitleInput() {\n      this.model.label = this.queryByHook('partition-title-input').value;\n    },\n    'change [data-hook~=show-label]': function changeDataHookShowLabel() {\n      this.model.showLabel = !this.model.showLabel;\n    },\n    'change [data-hook~=show-legend]': function changeDataHookShowLegend() {\n      this.model.showLegend = !this.model.showLegend;\n    }\n  },\n  subviews: {\n    groupContinuous: {\n      hook: 'partition-continuous',\n      prepareView: function prepareView(el) {\n        return new PartitionContinuousView({\n          el: el,\n          model: this.model\n        });\n      }\n    },\n    groupCategorial: {\n      hook: 'partition-categorial',\n      prepareView: function prepareView(el) {\n        return new PartitionCategorialView({\n          el: el,\n          model: this.model\n        });\n      }\n    },\n    groupDatetime: {\n      hook: 'partition-datetime',\n      prepareView: function prepareView(el) {\n        return new PartitionDatetimeView({\n          el: el,\n          model: this.model\n        });\n      }\n    },\n    groupDuration: {\n      hook: 'partition-duration',\n      prepareView: function prepareView(el) {\n        return new PartitionDurationView({\n          el: el,\n          model: this.model\n        });\n      }\n    },\n    groupText: {\n      hook: 'partition-text',\n      prepareView: function prepareView(el) {\n        return new PartitionTextView({\n          el: el,\n          model: this.model\n        });\n      }\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZDM4Yy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtcGFydGl0aW9uLmpzPzkzOTkiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGFwcCA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1hcHAnKTtcbnZhciBQYWdlVmlldyA9IHJlcXVpcmUoJy4vYmFzZScpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uL3RlbXBsYXRlcycpO1xuXG52YXIgUGFydGl0aW9uQ29udGludW91c1ZpZXcgPSByZXF1aXJlKCcuL2NvbmZpZ3VyZS1wYXJ0aXRpb24vcGFydGl0aW9uLWNvbnRpbnVvdXMnKTtcbnZhciBQYXJ0aXRpb25DYXRlZ29yaWFsVmlldyA9IHJlcXVpcmUoJy4vY29uZmlndXJlLXBhcnRpdGlvbi9wYXJ0aXRpb24tY2F0ZWdvcmlhbCcpO1xudmFyIFBhcnRpdGlvbkRhdGV0aW1lVmlldyA9IHJlcXVpcmUoJy4vY29uZmlndXJlLXBhcnRpdGlvbi9wYXJ0aXRpb24tZGF0ZXRpbWUnKTtcbnZhciBQYXJ0aXRpb25EdXJhdGlvblZpZXcgPSByZXF1aXJlKCcuL2NvbmZpZ3VyZS1wYXJ0aXRpb24vcGFydGl0aW9uLWR1cmF0aW9uJyk7XG52YXIgUGFydGl0aW9uVGV4dFZpZXcgPSByZXF1aXJlKCcuL2NvbmZpZ3VyZS1wYXJ0aXRpb24vcGFydGl0aW9uLXRleHQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBQYWdlVmlldy5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5wYWdlTmFtZSA9ICdjb25maWd1cmVQYXJ0aXRpb24nO1xuXG4gICAgdGhpcy5vbmNlKCdyZW1vdmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAodGhpcy5yZXNldEZpbHRlcikge1xuICAgICAgICB2YXIgZmlsdGVyID0gdGhpcy5tb2RlbC5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICAgICAgZmlsdGVyLnJlbGVhc2VEYXRhRmlsdGVyKCk7XG5cbiAgICAgICAgZmlsdGVyLmluaXREYXRhRmlsdGVyKCk7XG4gICAgICAgIGZpbHRlci51cGRhdGVEYXRhRmlsdGVyKCk7XG5cbiAgICAgICAgLy8gdGhpcyBmaWx0ZXIgbmVlZHMgbmV3IGRhdGFcbiAgICAgICAgYXBwLm1lLmRhdGF2aWV3LmdldERhdGEoKTtcbiAgICAgIH1cbiAgICB9LCB0aGlzKTtcbiAgfSxcbiAgdGVtcGxhdGU6IHRlbXBsYXRlcy5jb25maWd1cmVQYXJ0aXRpb24ucGFnZSxcbiAgYmluZGluZ3M6IHtcbiAgICAnbW9kZWwubGFiZWwnOiB7XG4gICAgICB0eXBlOiAndmFsdWUnLFxuICAgICAgaG9vazogJ3BhcnRpdGlvbi10aXRsZS1pbnB1dCdcbiAgICB9LFxuICAgICdtb2RlbC5zaG93TGFiZWwnOiB7XG4gICAgICB0eXBlOiAnYm9vbGVhbkF0dHJpYnV0ZScsXG4gICAgICBob29rOiAnc2hvdy1sYWJlbCcsXG4gICAgICBuYW1lOiAnY2hlY2tlZCdcbiAgICB9LFxuICAgICdtb2RlbC5zaG93TGVnZW5kJzoge1xuICAgICAgdHlwZTogJ2Jvb2xlYW5BdHRyaWJ1dGUnLFxuICAgICAgaG9vazogJ3Nob3ctbGVnZW5kJyxcbiAgICAgIG5hbWU6ICdjaGVja2VkJ1xuICAgIH1cbiAgfSxcbiAgc2Vzc2lvbjoge1xuICAgIHJlc2V0RmlsdGVyOiBbJ2Jvb2xlYW4nLCB0cnVlLCBmYWxzZV1cbiAgfSxcbiAgZXZlbnRzOiB7XG4gICAgJ2NoYW5nZSBbZGF0YS1ob29rfj1wYXJ0aXRpb24tdGl0bGUtaW5wdXRdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC5sYWJlbCA9IHRoaXMucXVlcnlCeUhvb2soJ3BhcnRpdGlvbi10aXRsZS1pbnB1dCcpLnZhbHVlO1xuICAgIH0sXG4gICAgJ2NoYW5nZSBbZGF0YS1ob29rfj1zaG93LWxhYmVsXSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwuc2hvd0xhYmVsID0gIXRoaXMubW9kZWwuc2hvd0xhYmVsO1xuICAgIH0sXG4gICAgJ2NoYW5nZSBbZGF0YS1ob29rfj1zaG93LWxlZ2VuZF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLnNob3dMZWdlbmQgPSAhdGhpcy5tb2RlbC5zaG93TGVnZW5kO1xuICAgIH1cbiAgfSxcbiAgc3Vidmlld3M6IHtcbiAgICBncm91cENvbnRpbnVvdXM6IHtcbiAgICAgIGhvb2s6ICdwYXJ0aXRpb24tY29udGludW91cycsXG4gICAgICBwcmVwYXJlVmlldzogZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgIHJldHVybiBuZXcgUGFydGl0aW9uQ29udGludW91c1ZpZXcoe1xuICAgICAgICAgIGVsOiBlbCxcbiAgICAgICAgICBtb2RlbDogdGhpcy5tb2RlbFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGdyb3VwQ2F0ZWdvcmlhbDoge1xuICAgICAgaG9vazogJ3BhcnRpdGlvbi1jYXRlZ29yaWFsJyxcbiAgICAgIHByZXBhcmVWaWV3OiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQYXJ0aXRpb25DYXRlZ29yaWFsVmlldyh7XG4gICAgICAgICAgZWw6IGVsLFxuICAgICAgICAgIG1vZGVsOiB0aGlzLm1vZGVsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG4gICAgZ3JvdXBEYXRldGltZToge1xuICAgICAgaG9vazogJ3BhcnRpdGlvbi1kYXRldGltZScsXG4gICAgICBwcmVwYXJlVmlldzogZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgIHJldHVybiBuZXcgUGFydGl0aW9uRGF0ZXRpbWVWaWV3KHtcbiAgICAgICAgICBlbDogZWwsXG4gICAgICAgICAgbW9kZWw6IHRoaXMubW9kZWxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBncm91cER1cmF0aW9uOiB7XG4gICAgICBob29rOiAncGFydGl0aW9uLWR1cmF0aW9uJyxcbiAgICAgIHByZXBhcmVWaWV3OiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQYXJ0aXRpb25EdXJhdGlvblZpZXcoe1xuICAgICAgICAgIGVsOiBlbCxcbiAgICAgICAgICBtb2RlbDogdGhpcy5tb2RlbFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGdyb3VwVGV4dDoge1xuICAgICAgaG9vazogJ3BhcnRpdGlvbi10ZXh0JyxcbiAgICAgIHByZXBhcmVWaWV3OiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQYXJ0aXRpb25UZXh0Vmlldyh7XG4gICAgICAgICAgZWw6IGVsLFxuICAgICAgICAgIG1vZGVsOiB0aGlzLm1vZGVsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBVkE7QUFnQkE7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFUQTtBQVdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQVBBO0FBU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQVBBO0FBU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQVBBO0FBU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQVBBO0FBU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQVBBO0FBckNBO0FBaERBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///d38c\n")},de24:function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar GroupView = __webpack_require__(/*! ./group */ \"0b9a\");\n\nmodule.exports = View.extend({\n  template: templates.configurePartition.partitionCategorial,\n  bindings: {\n    'model.isCategorial': {\n      type: 'toggle',\n      hook: 'group-categorial-panel'\n    }\n  },\n  render: function render() {\n    this.renderWithTemplate(this);\n    this.renderCollection(this.model.groups, GroupView, this.queryByHook('groups-table'));\n    return this;\n  },\n  events: {\n    'click [data-hook~=group-order-count]': function clickDataHookGroupOrderCount() {\n      this.model.ordering = 'count';\n      this.parent.resetFilter = true;\n    },\n    'click [data-hook~=group-order-abc]': function clickDataHookGroupOrderAbc() {\n      this.model.ordering = 'value';\n      this.parent.resetFilter = true;\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGUyNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtcGFydGl0aW9uL3BhcnRpdGlvbi1jYXRlZ29yaWFsLmpzPzJhZTQiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL3RlbXBsYXRlcycpO1xudmFyIEdyb3VwVmlldyA9IHJlcXVpcmUoJy4vZ3JvdXAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMuY29uZmlndXJlUGFydGl0aW9uLnBhcnRpdGlvbkNhdGVnb3JpYWwsXG4gIGJpbmRpbmdzOiB7XG4gICAgJ21vZGVsLmlzQ2F0ZWdvcmlhbCc6IHtcbiAgICAgIHR5cGU6ICd0b2dnbGUnLFxuICAgICAgaG9vazogJ2dyb3VwLWNhdGVnb3JpYWwtcGFuZWwnXG4gICAgfVxuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlbmRlcldpdGhUZW1wbGF0ZSh0aGlzKTtcbiAgICB0aGlzLnJlbmRlckNvbGxlY3Rpb24odGhpcy5tb2RlbC5ncm91cHMsIEdyb3VwVmlldywgdGhpcy5xdWVyeUJ5SG9vaygnZ3JvdXBzLXRhYmxlJykpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG4gIGV2ZW50czoge1xuICAgICdjbGljayBbZGF0YS1ob29rfj1ncm91cC1vcmRlci1jb3VudF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLm9yZGVyaW5nID0gJ2NvdW50JztcbiAgICAgIHRoaXMucGFyZW50LnJlc2V0RmlsdGVyID0gdHJ1ZTtcbiAgICB9LFxuICAgICdjbGljayBbZGF0YS1ob29rfj1ncm91cC1vcmRlci1hYmNdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC5vcmRlcmluZyA9ICd2YWx1ZSc7XG4gICAgICB0aGlzLnBhcmVudC5yZXNldEZpbHRlciA9IHRydWU7XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFEQTtBQU1BO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFSQTtBQWRBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///de24\n")},de33:function(module,exports){eval("/**\n * Formatter for tick labels on a linear axis in chartjs\n *\n * Override the default behavious such that it:\n *  * switches to scientific notation for large numbers with a lot of 'trailing zeros': 1e25\n *  * only prints the trailing (least significant) digits when zoomin in: 100000000000.1 prints as '..000.1'\n *\n * see issue #142\n */\nmodule.exports = function (tickValue, index, ticks) {\n  // Find the proper tick spacing\n  // if we have lots of ticks, don't use the ones\n  var delta = Math.abs(ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0]);\n\n  if (tickValue === 0) {\n    return '0';\n  } // Find the order of magnitude of the least significant digit\n\n\n  var leastSignificantOOM = Math.floor(Math.log10(delta)); // Find the order magnitude of the most significant digit\n\n  var logTicks = [];\n  ticks.forEach(function (value, i) {\n    if (value !== 0) {\n      logTicks.push(Math.log10(Math.abs(value)));\n    }\n  });\n  var mostSignificantOOM = Math.floor(Math.max.apply(Math, logTicks)); // We can chose between 3 different notations for '12.34':\n  //   fixed precision:     12.34\n  //   scientific notation: 1.234e1\n  //   and truncated         ..34\n  // find how long each notation would be, and chose the optimal one\n  // when using scientific notation (1,2303e2), how many digits would it take?\n\n  var totalNumberOfDigits = mostSignificantOOM + 1 - leastSignificantOOM; // when using fixed notation (123.03), how many digits would it take?\n\n  var fixedNotationDitigts = 1 + Math.max(0, mostSignificantOOM) + // digits before '.'\n  Math.max(0, Math.abs(leastSignificantOOM)); // digits after '.'\n  // when truncating the string to the last 5 digits, it is of course 5 digits\n\n  var tickString = '';\n\n  if (fixedNotationDitigts < 9) {\n    var numDecimal = Math.max(Math.min(-1 * leastSignificantOOM, 20), 0); // toFixed has a max of 20 decimal places\n\n    tickString = tickValue.toFixed(numDecimal);\n  } else if (totalNumberOfDigits < 9) {\n    tickString = tickValue.toExponential(totalNumberOfDigits - 1);\n  } else {\n    tickString = tickValue.toFixed(Math.max(0, -1 * leastSignificantOOM));\n    tickString = '..' + tickString.substring(tickString.length - 5, tickString.length);\n  }\n\n  return tickString;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGUzMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL2NoYXJ0anMtc2NpbGluZWFyLWZvcm1hdHRlci5qcz9hZjZhIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRm9ybWF0dGVyIGZvciB0aWNrIGxhYmVscyBvbiBhIGxpbmVhciBheGlzIGluIGNoYXJ0anNcbiAqXG4gKiBPdmVycmlkZSB0aGUgZGVmYXVsdCBiZWhhdmlvdXMgc3VjaCB0aGF0IGl0OlxuICogICogc3dpdGNoZXMgdG8gc2NpZW50aWZpYyBub3RhdGlvbiBmb3IgbGFyZ2UgbnVtYmVycyB3aXRoIGEgbG90IG9mICd0cmFpbGluZyB6ZXJvcyc6IDFlMjVcbiAqICAqIG9ubHkgcHJpbnRzIHRoZSB0cmFpbGluZyAobGVhc3Qgc2lnbmlmaWNhbnQpIGRpZ2l0cyB3aGVuIHpvb21pbiBpbjogMTAwMDAwMDAwMDAwLjEgcHJpbnRzIGFzICcuLjAwMC4xJ1xuICpcbiAqIHNlZSBpc3N1ZSAjMTQyXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRpY2tWYWx1ZSwgaW5kZXgsIHRpY2tzKSB7XG4gIC8vIEZpbmQgdGhlIHByb3BlciB0aWNrIHNwYWNpbmdcbiAgLy8gaWYgd2UgaGF2ZSBsb3RzIG9mIHRpY2tzLCBkb24ndCB1c2UgdGhlIG9uZXNcbiAgdmFyIGRlbHRhID0gTWF0aC5hYnModGlja3MubGVuZ3RoID4gMyA/IHRpY2tzWzJdIC0gdGlja3NbMV0gOiB0aWNrc1sxXSAtIHRpY2tzWzBdKTtcblxuICBpZiAodGlja1ZhbHVlID09PSAwKSB7XG4gICAgcmV0dXJuICcwJztcbiAgfVxuXG4gIC8vIEZpbmQgdGhlIG9yZGVyIG9mIG1hZ25pdHVkZSBvZiB0aGUgbGVhc3Qgc2lnbmlmaWNhbnQgZGlnaXRcbiAgdmFyIGxlYXN0U2lnbmlmaWNhbnRPT00gPSBNYXRoLmZsb29yKE1hdGgubG9nMTAoZGVsdGEpKTtcblxuICAvLyBGaW5kIHRoZSBvcmRlciBtYWduaXR1ZGUgb2YgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgZGlnaXRcbiAgdmFyIGxvZ1RpY2tzID0gW107XG4gIHRpY2tzLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlLCBpKSB7XG4gICAgaWYgKHZhbHVlICE9PSAwKSB7XG4gICAgICBsb2dUaWNrcy5wdXNoKE1hdGgubG9nMTAoTWF0aC5hYnModmFsdWUpKSk7XG4gICAgfVxuICB9KTtcbiAgdmFyIG1vc3RTaWduaWZpY2FudE9PTSA9IE1hdGguZmxvb3IoTWF0aC5tYXguYXBwbHkoTWF0aCwgbG9nVGlja3MpKTtcblxuICAvLyBXZSBjYW4gY2hvc2UgYmV0d2VlbiAzIGRpZmZlcmVudCBub3RhdGlvbnMgZm9yICcxMi4zNCc6XG4gIC8vICAgZml4ZWQgcHJlY2lzaW9uOiAgICAgMTIuMzRcbiAgLy8gICBzY2llbnRpZmljIG5vdGF0aW9uOiAxLjIzNGUxXG4gIC8vICAgYW5kIHRydW5jYXRlZCAgICAgICAgIC4uMzRcbiAgLy8gZmluZCBob3cgbG9uZyBlYWNoIG5vdGF0aW9uIHdvdWxkIGJlLCBhbmQgY2hvc2UgdGhlIG9wdGltYWwgb25lXG5cbiAgLy8gd2hlbiB1c2luZyBzY2llbnRpZmljIG5vdGF0aW9uICgxLDIzMDNlMiksIGhvdyBtYW55IGRpZ2l0cyB3b3VsZCBpdCB0YWtlP1xuICB2YXIgdG90YWxOdW1iZXJPZkRpZ2l0cyA9IG1vc3RTaWduaWZpY2FudE9PTSArIDEgLSBsZWFzdFNpZ25pZmljYW50T09NO1xuXG4gIC8vIHdoZW4gdXNpbmcgZml4ZWQgbm90YXRpb24gKDEyMy4wMyksIGhvdyBtYW55IGRpZ2l0cyB3b3VsZCBpdCB0YWtlP1xuICB2YXIgZml4ZWROb3RhdGlvbkRpdGlndHMgPSAxICtcbiAgICBNYXRoLm1heCgwLCBtb3N0U2lnbmlmaWNhbnRPT00pICsgICAgICAgICAgIC8vIGRpZ2l0cyBiZWZvcmUgJy4nXG4gICAgTWF0aC5tYXgoMCwgTWF0aC5hYnMobGVhc3RTaWduaWZpY2FudE9PTSkpOyAvLyBkaWdpdHMgYWZ0ZXIgJy4nXG5cbiAgLy8gd2hlbiB0cnVuY2F0aW5nIHRoZSBzdHJpbmcgdG8gdGhlIGxhc3QgNSBkaWdpdHMsIGl0IGlzIG9mIGNvdXJzZSA1IGRpZ2l0c1xuXG4gIHZhciB0aWNrU3RyaW5nID0gJyc7XG4gIGlmIChmaXhlZE5vdGF0aW9uRGl0aWd0cyA8IDkpIHtcbiAgICB2YXIgbnVtRGVjaW1hbCA9IE1hdGgubWF4KE1hdGgubWluKC0xICogbGVhc3RTaWduaWZpY2FudE9PTSwgMjApLCAwKTsgLy8gdG9GaXhlZCBoYXMgYSBtYXggb2YgMjAgZGVjaW1hbCBwbGFjZXNcbiAgICB0aWNrU3RyaW5nID0gdGlja1ZhbHVlLnRvRml4ZWQobnVtRGVjaW1hbCk7XG4gIH0gZWxzZSBpZiAodG90YWxOdW1iZXJPZkRpZ2l0cyA8IDkpIHtcbiAgICB0aWNrU3RyaW5nID0gdGlja1ZhbHVlLnRvRXhwb25lbnRpYWwodG90YWxOdW1iZXJPZkRpZ2l0cyAtIDEpO1xuICB9IGVsc2Uge1xuICAgIHRpY2tTdHJpbmcgPSB0aWNrVmFsdWUudG9GaXhlZChNYXRoLm1heCgwLCAtMSAqIGxlYXN0U2lnbmlmaWNhbnRPT00pKTtcbiAgICB0aWNrU3RyaW5nID0gJy4uJyArIHRpY2tTdHJpbmcuc3Vic3RyaW5nKHRpY2tTdHJpbmcubGVuZ3RoIC0gNSwgdGlja1N0cmluZy5sZW5ndGgpO1xuICB9XG5cbiAgcmV0dXJuIHRpY2tTdHJpbmc7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7O0FBU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///de33\n")},de8e:function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nvar sortablejs = __webpack_require__(/*! sortablejs */ \"4776\");\n\nvar app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar startDnd = function startDnd(type) {\n  if (this.model.isFilled) {\n    // do nothing if the slot is already filled\n    this.dndClass = '';\n  } else {\n    if (this.model.supportedFacets.indexOf(type) > -1) {\n      // highlight the drop zone\n      this.dndClass = 'slot-start-dnd-accept';\n    } else {\n      // gray out the drop zone\n      this.dndClass = 'slot-start-dnd-reject';\n    }\n  }\n};\n\nvar stopDnd = function stopDnd() {\n  this.dndClass = '';\n};\n\nmodule.exports = View.extend({\n  template: templates.analyze.slot,\n  props: {\n    dndClass: 'string',\n    // CSS class to add when a facet dnd is in progress\n    updateCounter: {\n      type: 'number',\n      default: 0,\n      required: true\n    }\n  },\n  derived: {\n    requiredText: {\n      deps: ['model.required', 'model.isFilled'],\n      fn: function fn() {\n        if (this.model.isFilled) {\n          return 'click to configure';\n        } else {\n          if (this.model.required) {\n            return 'required';\n          } else {\n            return 'optional';\n          }\n        }\n      }\n    },\n    chipText: {\n      deps: ['model.isFilled', 'updateCounter'],\n      cache: false,\n      fn: function fn() {\n        var filter = this.collection.parent.filter; // stop accepting DND\n\n        if (this._sortable) {\n          this._sortable.option('disabled', true);\n        }\n\n        if (filter) {\n          if (this.model.type === 'partition') {\n            var partition = filter.partitions.get(this.model.rank, 'rank');\n\n            if (partition) {\n              return partition.facetName;\n            }\n          } else if (this.model.type === 'aggregate') {\n            var aggregate = filter.aggregates.get(this.model.rank, 'rank');\n\n            if (aggregate) {\n              return aggregate.operation + ' ' + aggregate.label;\n            }\n          } else {\n            console.error('Illegal slot');\n          }\n        } // this slots should accept DND\n\n\n        if (this._sortable) {\n          this._sortable.option('disabled', false);\n        }\n\n        return '';\n      }\n    }\n  },\n  initialize: function initialize() {\n    var filter = this.collection.parent.filter;\n    this.model.isFilled = false;\n\n    if (filter) {\n      if (this.model.type === 'partition') {\n        var partition = filter.partitions.get(this.model.rank, 'rank');\n\n        if (partition) {\n          this.model.isFilled = true;\n        }\n      } else if (this.model.type === 'aggregate') {\n        var aggregate = filter.aggregates.get(this.model.rank, 'rank');\n\n        if (aggregate) {\n          this.model.isFilled = true;\n        }\n      } else {\n        console.error('Illegal slot');\n      }\n    } // add remove classes 'dndAccept' and 'dndRefuse' on drag-and-drop\n\n\n    app.on('dragStart', startDnd, this);\n    app.on('dragEnd', stopDnd, this);\n    this.on('remove', function () {\n      app.off('dragStart', startDnd);\n      app.off('dragEnd', stopDnd);\n    }, this);\n  },\n  bindings: {\n    'dndClass': {\n      type: 'class',\n      hook: 'drop-zone'\n    },\n    'model.description': {\n      type: 'text',\n      hook: 'description'\n    },\n    'requiredText': {\n      type: 'text',\n      hook: 'required'\n    },\n    'chipText': {\n      type: 'text',\n      hook: 'drop-zone'\n    },\n    'model.isFilled': {\n      type: 'toggle',\n      hook: 'button-div'\n    }\n  },\n  events: {\n    'click .clickTarget': 'rotateSetting',\n    'click [data-hook~=\"delete\"]': 'emptySlot'\n  },\n  rotateSetting: function rotateSetting() {\n    var filter = this.collection.parent.filter;\n    filter.releaseDataFilter();\n\n    if (this.model.type === 'partition') {\n      var partition = filter.partitions.get(this.model.rank, 'rank');\n\n      if (!partition) {\n        return;\n      }\n\n      app.navigate('partition/' + partition.getId());\n    } else if (this.model.type === 'aggregate') {\n      var values = ['count', 'avg', 'sum', 'stddev', 'min', 'max'];\n      var aggregate = filter.aggregates.get(this.model.rank, 'rank');\n\n      if (!aggregate) {\n        return;\n      }\n\n      var i = values.indexOf(aggregate.operation) + 1;\n\n      if (i >= values.length) {\n        i = 0;\n      }\n\n      if (app.me.sessionType === 'client' && values[i] === 'min' | values[i] === 'max') {\n        // crossfilter does not support min/max\n        i = 0;\n      }\n\n      aggregate.operation = values[i];\n      app.trigger('refresh'); // force a redraw of the text\n\n      this.updateCounter += 1;\n    }\n  },\n  emptySlot: function emptySlot() {\n    if (this.model.emptySlot()) {\n      app.trigger('refresh'); // force a redraw of the chipText\n\n      this.updateCounter += 1;\n    }\n  },\n  tryFillSlot: function tryFillSlot(facet) {\n    if (this.model.tryFillSlot(facet)) {\n      // Hack-ish feature:\n      //  * for bubble plots, add a facet dropped as 'X axis' also as 'Point size'\n      //  * for 3d scatter plots, add a facet dropped as 'X axis' also as 'Color by'\n      var chartType = this.model.collection.parent.filter.chartType;\n\n      if (chartType === 'bubbleplot') {\n        if (this.model.description === 'X axis') {\n          this.model.collection.get('Point size', 'description').tryFillSlot(facet, 'count');\n        }\n      } else if (chartType === 'scatterchart') {\n        if (this.model.description === 'X axis') {\n          this.model.collection.get('Color by', 'description').tryFillSlot(facet, 'count');\n        }\n      }\n\n      app.trigger('refresh'); // force a redraw of the chipText\n\n      this.updateCounter += 1;\n    }\n  },\n  render: function render() {\n    this.renderWithTemplate(this);\n    var me = this;\n    this._sortable = sortablejs.create(this.queryByHook('drop-zone'), {\n      draggable: '.mdl-chip',\n      disabled: me.model.isFilled,\n      group: {\n        name: 'facets',\n        pull: false,\n        put: true\n      },\n      onAdd: function onAdd(evt) {\n        // get the dropped facet\n        // because the ampersand view collection takes care of rendering a\n        // prettier one\n        var item = evt.item;\n        var facetId = item.getAttribute('data-id');\n        item.remove();\n        var facet = app.me.dataview.facets.get(facetId);\n\n        if (!facet) {\n          console.error('Cannot find facet');\n          return;\n        }\n\n        me.tryFillSlot(facet);\n      }\n    });\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGU4ZS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9hbmFseXplL3Nsb3QuanM/ZjNmMiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgVmlldyA9IHJlcXVpcmUoJ2FtcGVyc2FuZC12aWV3Jyk7XG52YXIgdGVtcGxhdGVzID0gcmVxdWlyZSgnLi4vLi4vdGVtcGxhdGVzJyk7XG52YXIgc29ydGFibGVqcyA9IHJlcXVpcmUoJ3NvcnRhYmxlanMnKTtcbnZhciBhcHAgPSByZXF1aXJlKCdhbXBlcnNhbmQtYXBwJyk7XG5cbnZhciBzdGFydERuZCA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIGlmICh0aGlzLm1vZGVsLmlzRmlsbGVkKSB7XG4gICAgLy8gZG8gbm90aGluZyBpZiB0aGUgc2xvdCBpcyBhbHJlYWR5IGZpbGxlZFxuICAgIHRoaXMuZG5kQ2xhc3MgPSAnJztcbiAgfSBlbHNlIHtcbiAgICBpZiAodGhpcy5tb2RlbC5zdXBwb3J0ZWRGYWNldHMuaW5kZXhPZih0eXBlKSA+IC0xKSB7XG4gICAgICAvLyBoaWdobGlnaHQgdGhlIGRyb3Agem9uZVxuICAgICAgdGhpcy5kbmRDbGFzcyA9ICdzbG90LXN0YXJ0LWRuZC1hY2NlcHQnO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBncmF5IG91dCB0aGUgZHJvcCB6b25lXG4gICAgICB0aGlzLmRuZENsYXNzID0gJ3Nsb3Qtc3RhcnQtZG5kLXJlamVjdCc7XG4gICAgfVxuICB9XG59O1xuXG52YXIgc3RvcERuZCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5kbmRDbGFzcyA9ICcnO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3LmV4dGVuZCh7XG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZXMuYW5hbHl6ZS5zbG90LFxuICBwcm9wczoge1xuICAgIGRuZENsYXNzOiAnc3RyaW5nJywgLy8gQ1NTIGNsYXNzIHRvIGFkZCB3aGVuIGEgZmFjZXQgZG5kIGlzIGluIHByb2dyZXNzXG4gICAgdXBkYXRlQ291bnRlcjoge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBkZWZhdWx0OiAwLFxuICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICB9XG4gIH0sXG4gIGRlcml2ZWQ6IHtcbiAgICByZXF1aXJlZFRleHQ6IHtcbiAgICAgIGRlcHM6IFsnbW9kZWwucmVxdWlyZWQnLCAnbW9kZWwuaXNGaWxsZWQnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLm1vZGVsLmlzRmlsbGVkKSB7XG4gICAgICAgICAgcmV0dXJuICdjbGljayB0byBjb25maWd1cmUnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLm1vZGVsLnJlcXVpcmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gJ3JlcXVpcmVkJztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuICdvcHRpb25hbCc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBjaGlwVGV4dDoge1xuICAgICAgZGVwczogWydtb2RlbC5pc0ZpbGxlZCcsICd1cGRhdGVDb3VudGVyJ10sXG4gICAgICBjYWNoZTogZmFsc2UsXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZmlsdGVyID0gdGhpcy5jb2xsZWN0aW9uLnBhcmVudC5maWx0ZXI7XG5cbiAgICAgICAgLy8gc3RvcCBhY2NlcHRpbmcgRE5EXG4gICAgICAgIGlmICh0aGlzLl9zb3J0YWJsZSkge1xuICAgICAgICAgIHRoaXMuX3NvcnRhYmxlLm9wdGlvbignZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmaWx0ZXIpIHtcbiAgICAgICAgICBpZiAodGhpcy5tb2RlbC50eXBlID09PSAncGFydGl0aW9uJykge1xuICAgICAgICAgICAgdmFyIHBhcnRpdGlvbiA9IGZpbHRlci5wYXJ0aXRpb25zLmdldCh0aGlzLm1vZGVsLnJhbmssICdyYW5rJyk7XG4gICAgICAgICAgICBpZiAocGFydGl0aW9uKSB7XG4gICAgICAgICAgICAgIHJldHVybiBwYXJ0aXRpb24uZmFjZXROYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlbC50eXBlID09PSAnYWdncmVnYXRlJykge1xuICAgICAgICAgICAgdmFyIGFnZ3JlZ2F0ZSA9IGZpbHRlci5hZ2dyZWdhdGVzLmdldCh0aGlzLm1vZGVsLnJhbmssICdyYW5rJyk7XG4gICAgICAgICAgICBpZiAoYWdncmVnYXRlKSB7XG4gICAgICAgICAgICAgIHJldHVybiBhZ2dyZWdhdGUub3BlcmF0aW9uICsgJyAnICsgYWdncmVnYXRlLmxhYmVsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdJbGxlZ2FsIHNsb3QnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0aGlzIHNsb3RzIHNob3VsZCBhY2NlcHQgRE5EXG4gICAgICAgIGlmICh0aGlzLl9zb3J0YWJsZSkge1xuICAgICAgICAgIHRoaXMuX3NvcnRhYmxlLm9wdGlvbignZGlzYWJsZWQnLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIHZhciBmaWx0ZXIgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50LmZpbHRlcjtcbiAgICB0aGlzLm1vZGVsLmlzRmlsbGVkID0gZmFsc2U7XG5cbiAgICBpZiAoZmlsdGVyKSB7XG4gICAgICBpZiAodGhpcy5tb2RlbC50eXBlID09PSAncGFydGl0aW9uJykge1xuICAgICAgICB2YXIgcGFydGl0aW9uID0gZmlsdGVyLnBhcnRpdGlvbnMuZ2V0KHRoaXMubW9kZWwucmFuaywgJ3JhbmsnKTtcbiAgICAgICAgaWYgKHBhcnRpdGlvbikge1xuICAgICAgICAgIHRoaXMubW9kZWwuaXNGaWxsZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaXMubW9kZWwudHlwZSA9PT0gJ2FnZ3JlZ2F0ZScpIHtcbiAgICAgICAgdmFyIGFnZ3JlZ2F0ZSA9IGZpbHRlci5hZ2dyZWdhdGVzLmdldCh0aGlzLm1vZGVsLnJhbmssICdyYW5rJyk7XG4gICAgICAgIGlmIChhZ2dyZWdhdGUpIHtcbiAgICAgICAgICB0aGlzLm1vZGVsLmlzRmlsbGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignSWxsZWdhbCBzbG90Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRkIHJlbW92ZSBjbGFzc2VzICdkbmRBY2NlcHQnIGFuZCAnZG5kUmVmdXNlJyBvbiBkcmFnLWFuZC1kcm9wXG4gICAgYXBwLm9uKCdkcmFnU3RhcnQnLCBzdGFydERuZCwgdGhpcyk7XG4gICAgYXBwLm9uKCdkcmFnRW5kJywgc3RvcERuZCwgdGhpcyk7XG4gICAgdGhpcy5vbigncmVtb3ZlJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXBwLm9mZignZHJhZ1N0YXJ0Jywgc3RhcnREbmQpO1xuICAgICAgYXBwLm9mZignZHJhZ0VuZCcsIHN0b3BEbmQpO1xuICAgIH0sIHRoaXMpO1xuICB9LFxuICBiaW5kaW5nczoge1xuICAgICdkbmRDbGFzcyc6IHtcbiAgICAgIHR5cGU6ICdjbGFzcycsXG4gICAgICBob29rOiAnZHJvcC16b25lJ1xuICAgIH0sXG4gICAgJ21vZGVsLmRlc2NyaXB0aW9uJzoge1xuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgaG9vazogJ2Rlc2NyaXB0aW9uJ1xuICAgIH0sXG4gICAgJ3JlcXVpcmVkVGV4dCc6IHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIGhvb2s6ICdyZXF1aXJlZCdcbiAgICB9LFxuICAgICdjaGlwVGV4dCc6IHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIGhvb2s6ICdkcm9wLXpvbmUnXG4gICAgfSxcbiAgICAnbW9kZWwuaXNGaWxsZWQnOiB7XG4gICAgICB0eXBlOiAndG9nZ2xlJyxcbiAgICAgIGhvb2s6ICdidXR0b24tZGl2J1xuICAgIH1cbiAgfSxcbiAgZXZlbnRzOiB7XG4gICAgJ2NsaWNrIC5jbGlja1RhcmdldCc6ICdyb3RhdGVTZXR0aW5nJyxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349XCJkZWxldGVcIl0nOiAnZW1wdHlTbG90J1xuICB9LFxuICByb3RhdGVTZXR0aW5nOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGZpbHRlciA9IHRoaXMuY29sbGVjdGlvbi5wYXJlbnQuZmlsdGVyO1xuICAgIGZpbHRlci5yZWxlYXNlRGF0YUZpbHRlcigpO1xuXG4gICAgaWYgKHRoaXMubW9kZWwudHlwZSA9PT0gJ3BhcnRpdGlvbicpIHtcbiAgICAgIHZhciBwYXJ0aXRpb24gPSBmaWx0ZXIucGFydGl0aW9ucy5nZXQodGhpcy5tb2RlbC5yYW5rLCAncmFuaycpO1xuICAgICAgaWYgKCFwYXJ0aXRpb24pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBhcHAubmF2aWdhdGUoJ3BhcnRpdGlvbi8nICsgcGFydGl0aW9uLmdldElkKCkpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlbC50eXBlID09PSAnYWdncmVnYXRlJykge1xuICAgICAgdmFyIHZhbHVlcyA9IFsnY291bnQnLCAnYXZnJywgJ3N1bScsICdzdGRkZXYnLCAnbWluJywgJ21heCddO1xuICAgICAgdmFyIGFnZ3JlZ2F0ZSA9IGZpbHRlci5hZ2dyZWdhdGVzLmdldCh0aGlzLm1vZGVsLnJhbmssICdyYW5rJyk7XG4gICAgICBpZiAoIWFnZ3JlZ2F0ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBpID0gdmFsdWVzLmluZGV4T2YoYWdncmVnYXRlLm9wZXJhdGlvbikgKyAxO1xuICAgICAgaWYgKGkgPj0gdmFsdWVzLmxlbmd0aCkge1xuICAgICAgICBpID0gMDtcbiAgICAgIH1cblxuICAgICAgaWYgKGFwcC5tZS5zZXNzaW9uVHlwZSA9PT0gJ2NsaWVudCcgJiYgdmFsdWVzW2ldID09PSAnbWluJyB8IHZhbHVlc1tpXSA9PT0gJ21heCcpIHtcbiAgICAgICAgLy8gY3Jvc3NmaWx0ZXIgZG9lcyBub3Qgc3VwcG9ydCBtaW4vbWF4XG4gICAgICAgIGkgPSAwO1xuICAgICAgfVxuXG4gICAgICBhZ2dyZWdhdGUub3BlcmF0aW9uID0gdmFsdWVzW2ldO1xuXG4gICAgICBhcHAudHJpZ2dlcigncmVmcmVzaCcpO1xuXG4gICAgICAvLyBmb3JjZSBhIHJlZHJhdyBvZiB0aGUgdGV4dFxuICAgICAgdGhpcy51cGRhdGVDb3VudGVyICs9IDE7XG4gICAgfVxuICB9LFxuICBlbXB0eVNsb3Q6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5tb2RlbC5lbXB0eVNsb3QoKSkge1xuICAgICAgYXBwLnRyaWdnZXIoJ3JlZnJlc2gnKTtcblxuICAgICAgLy8gZm9yY2UgYSByZWRyYXcgb2YgdGhlIGNoaXBUZXh0XG4gICAgICB0aGlzLnVwZGF0ZUNvdW50ZXIgKz0gMTtcbiAgICB9XG4gIH0sXG4gIHRyeUZpbGxTbG90OiBmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICBpZiAodGhpcy5tb2RlbC50cnlGaWxsU2xvdChmYWNldCkpIHtcbiAgICAgIC8vIEhhY2staXNoIGZlYXR1cmU6XG4gICAgICAvLyAgKiBmb3IgYnViYmxlIHBsb3RzLCBhZGQgYSBmYWNldCBkcm9wcGVkIGFzICdYIGF4aXMnIGFsc28gYXMgJ1BvaW50IHNpemUnXG4gICAgICAvLyAgKiBmb3IgM2Qgc2NhdHRlciBwbG90cywgYWRkIGEgZmFjZXQgZHJvcHBlZCBhcyAnWCBheGlzJyBhbHNvIGFzICdDb2xvciBieSdcbiAgICAgIHZhciBjaGFydFR5cGUgPSB0aGlzLm1vZGVsLmNvbGxlY3Rpb24ucGFyZW50LmZpbHRlci5jaGFydFR5cGU7XG4gICAgICBpZiAoY2hhcnRUeXBlID09PSAnYnViYmxlcGxvdCcpIHtcbiAgICAgICAgaWYgKHRoaXMubW9kZWwuZGVzY3JpcHRpb24gPT09ICdYIGF4aXMnKSB7XG4gICAgICAgICAgdGhpcy5tb2RlbC5jb2xsZWN0aW9uLmdldCgnUG9pbnQgc2l6ZScsICdkZXNjcmlwdGlvbicpLnRyeUZpbGxTbG90KGZhY2V0LCAnY291bnQnKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChjaGFydFR5cGUgPT09ICdzY2F0dGVyY2hhcnQnKSB7XG4gICAgICAgIGlmICh0aGlzLm1vZGVsLmRlc2NyaXB0aW9uID09PSAnWCBheGlzJykge1xuICAgICAgICAgIHRoaXMubW9kZWwuY29sbGVjdGlvbi5nZXQoJ0NvbG9yIGJ5JywgJ2Rlc2NyaXB0aW9uJykudHJ5RmlsbFNsb3QoZmFjZXQsICdjb3VudCcpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGFwcC50cmlnZ2VyKCdyZWZyZXNoJyk7XG5cbiAgICAgIC8vIGZvcmNlIGEgcmVkcmF3IG9mIHRoZSBjaGlwVGV4dFxuICAgICAgdGhpcy51cGRhdGVDb3VudGVyICs9IDE7XG4gICAgfVxuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlbmRlcldpdGhUZW1wbGF0ZSh0aGlzKTtcblxuICAgIHZhciBtZSA9IHRoaXM7XG4gICAgdGhpcy5fc29ydGFibGUgPSBzb3J0YWJsZWpzLmNyZWF0ZSh0aGlzLnF1ZXJ5QnlIb29rKCdkcm9wLXpvbmUnKSwge1xuICAgICAgZHJhZ2dhYmxlOiAnLm1kbC1jaGlwJyxcbiAgICAgIGRpc2FibGVkOiBtZS5tb2RlbC5pc0ZpbGxlZCxcbiAgICAgIGdyb3VwOiB7XG4gICAgICAgIG5hbWU6ICdmYWNldHMnLFxuICAgICAgICBwdWxsOiBmYWxzZSxcbiAgICAgICAgcHV0OiB0cnVlXG4gICAgICB9LFxuICAgICAgb25BZGQ6IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgLy8gZ2V0IHRoZSBkcm9wcGVkIGZhY2V0XG4gICAgICAgIC8vIGJlY2F1c2UgdGhlIGFtcGVyc2FuZCB2aWV3IGNvbGxlY3Rpb24gdGFrZXMgY2FyZSBvZiByZW5kZXJpbmcgYVxuICAgICAgICAvLyBwcmV0dGllciBvbmVcbiAgICAgICAgdmFyIGl0ZW0gPSBldnQuaXRlbTtcbiAgICAgICAgdmFyIGZhY2V0SWQgPSBpdGVtLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpO1xuICAgICAgICBpdGVtLnJlbW92ZSgpO1xuXG4gICAgICAgIHZhciBmYWNldCA9IGFwcC5tZS5kYXRhdmlldy5mYWNldHMuZ2V0KGZhY2V0SWQpO1xuICAgICAgICBpZiAoIWZhY2V0KSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignQ2Fubm90IGZpbmQgZmFjZXQnKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbWUudHJ5RmlsbFNsb3QoZmFjZXQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFGQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFaQTtBQWNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFoQ0E7QUFmQTtBQWtEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBRkE7QUFqQkE7QUFzQkE7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUF0QkE7QUF3QkE7QUFoTkEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///de8e\n")},e96a:function(module,exports,__webpack_require__){eval('var Collection = __webpack_require__(/*! ampersand-collection */ "7bd3");\n\nvar Slot = __webpack_require__(/*! ./slot */ "aea4");\n\nmodule.exports = Collection.extend({\n  model: Slot,\n  indexes: [\'description\']\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTk2YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL21vZGVscy9zbG90cy5qcz9jYmU1Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBDb2xsZWN0aW9uID0gcmVxdWlyZSgnYW1wZXJzYW5kLWNvbGxlY3Rpb24nKTtcbnZhciBTbG90ID0gcmVxdWlyZSgnLi9zbG90Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogU2xvdCxcbiAgaW5kZXhlczogWydkZXNjcmlwdGlvbiddXG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///e96a\n')},e9bd:function(module,exports,__webpack_require__){eval("var app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar Spot = __webpack_require__(/*! spot-framework */ \"3b07\");\n\nvar BaseWidget = __webpack_require__(/*! ./base-widget */ \"26ef\");\n\nvar Chart = __webpack_require__(/*! chart.js */ \"70b5\");\n\nvar colors = __webpack_require__(/*! ../../colors */ \"eb63\");\n\nvar misval = Spot.util.misval;\n\nvar util = __webpack_require__(/*! ./util */ \"2b41\"); // Called by Chartjs, this -> chart instance\n\n\nfunction onClick(ev, elements) {\n  var model = this._Ampersandview.model;\n  var partition = model.filter.partitions.get(1, 'rank');\n\n  if (elements.length > 0) {\n    partition.updateSelection(partition.groups.models[elements[0]._index]);\n    model.filter.updateDataFilter();\n    app.me.dataview.getData();\n  }\n}\n\nfunction _deinitChart(view) {\n  if (view._chartjs) {\n    view._chartjs.destroy();\n\n    delete view._chartjs;\n  }\n\n  delete view._config;\n  var canvas = view.queryByHook('canvas');\n\n  if (canvas) {\n    view.el.removeChild(canvas);\n  }\n\n  view.isInitialized = false;\n}\n\nfunction _initChart(view) {\n  // Configure plot\n  view._config = view.model.chartjsConfig();\n  var options = view._config.options; // axis types\n\n  var partitionA = view.model.filter.partitions.get(1, 'rank');\n\n  if (partitionA.isDatetime) {\n    options.scales.xAxes[0].type = 'time';\n  } else if (partitionA.isDuration) {\n    options.scales.xAxes[0].type = 'spot-duration';\n  }\n\n  options.scales.xAxes[0].scaleLabel = {\n    display: partitionA.showLabel,\n    labelString: partitionA.label\n  }; // title\n\n  options.title.text = view.model.getTitle(); // mouse interaction\n\n  options.onClick = onClick; // force a square full size plot\n\n  var width = view.el.offsetWidth;\n  var height = view.el.offsetHeight;\n  var canvas = document.createElement('canvas');\n  canvas.setAttribute('data-hook', 'canvas');\n  view.el.appendChild(canvas);\n  var ctx = canvas.getContext('2d');\n  ctx.canvas.width = width;\n  ctx.canvas.height = height;\n  var aggregateD = view.model.filter.aggregates.get(4, 'rank');\n\n  if (aggregateD) {\n    // show secondary y Axis on the right when we have a second y variable\n    view._config.options.scales.yAxes[1].display = true;\n  } // Create Chartjs object\n\n\n  view._chartjs = new Chart(ctx, view._config); // In callbacks on the chart we will need the view, so store a reference\n\n  view._chartjs._Ampersandview = view;\n  view.isInitialized = true;\n}\n\nfunction _update(view) {\n  if (!view.isInitialized) {\n    return;\n  }\n\n  var filter = view.model.filter;\n  var partitionA = filter.partitions.get(1, 'rank');\n  var partitionB = filter.partitions.get(2, 'rank');\n  var chartData = view._config.data;\n  var datasetCount; // update legends and tooltips\n\n  if (partitionB && partitionB.groups && partitionB.groups.length > 1) {\n    // we have sub-grouping\n    view._config.options.legend.display = partitionB.showLegend;\n    view._config.options.tooltips.mode = 'label';\n    datasetCount = partitionB.groups.length;\n  } else {\n    view._config.options.legend.display = false;\n    view._config.options.tooltips.mode = 'single';\n    datasetCount = 1;\n  }\n\n  var aggregate;\n  aggregate = filter.aggregates.get(1, 'rank');\n  var valueFn;\n\n  if (aggregate) {\n    valueFn = function valueFn(group) {\n      if (group.count !== misval && group.aa !== misval) {\n        return parseFloat(group.aa) || null;\n      }\n\n      return null;\n    };\n  } else {\n    valueFn = function valueFn(group) {\n      if (group.count !== misval && group.count !== 0) {\n        return parseInt(group.count);\n      }\n\n      return null;\n    };\n  }\n\n  view._config.options.errorDir = 'both';\n  aggregate = filter.aggregates.get(2, 'rank');\n  var errorXFn;\n\n  if (aggregate) {\n    errorXFn = function errorXFn(group) {\n      if (group.bb !== misval) {\n        return parseFloat(group.bb) || 0;\n      }\n\n      return 0;\n    };\n  } else {\n    errorXFn = function errorXFn(group) {\n      return null;\n    };\n\n    view._config.options.errorDir = 'vertical';\n  }\n\n  aggregate = filter.aggregates.get(3, 'rank');\n  var errorYFn;\n\n  if (aggregate) {\n    errorYFn = function errorYFn(group) {\n      if (group.cc !== misval) {\n        return parseFloat(group.cc) || 0;\n      }\n\n      return 0;\n    };\n  } else {\n    errorYFn = function errorYFn(group) {\n      return null;\n    };\n\n    if (view._config.options.errorDir === 'vertical') {\n      view._config.options.errorDir === 'none';\n    }\n\n    if (view._config.options.errorDir === 'both') {\n      view._config.options.errorDir === 'horizontal';\n    }\n  }\n\n  aggregate = filter.aggregates.get(4, 'rank');\n  var secondYFn = false;\n  var secondYOffset = datasetCount;\n\n  if (aggregate) {\n    // double the number of datasets for the second y value\n    secondYOffset = datasetCount;\n    datasetCount = 2 * datasetCount;\n\n    secondYFn = function secondYFn(group) {\n      if (group.dd !== misval) {\n        return parseFloat(group.dd) || null;\n      }\n\n      return null;\n    };\n  }\n\n  util.resizeChartjsData(chartData, partitionA, partitionB, {\n    multiDimensional: true,\n    doubleDatasets: secondYFn\n  }); // add datapoints\n\n  filter.data.forEach(function (group) {\n    var i = util.partitionValueToIndex(partitionA, group.a);\n    var j = util.partitionValueToIndex(partitionB, group.b);\n\n    if (i >= 0 && j >= 0) {\n      chartData.datasets[j].data[i].x = group.a;\n      chartData.datasets[j].data[i].y = valueFn(group);\n      chartData.datasets[j].error[i].x = errorXFn(group);\n      chartData.datasets[j].error[i].y = errorYFn(group);\n      chartData.datasets[j].yAxisID = 'first-scale';\n\n      if (secondYFn) {\n        chartData.datasets[secondYOffset + j].data[i].x = group.a;\n        chartData.datasets[secondYOffset + j].data[i].y = secondYFn(group);\n        chartData.datasets[secondYOffset + j].error[i].x = null;\n        chartData.datasets[secondYOffset + j].error[i].y = null;\n        chartData.datasets[secondYOffset + j].yAxisID = 'second-scale';\n      }\n    }\n  }); // Add an extra dataset to highlight selected area\n\n  var selectionId = datasetCount;\n  chartData.datasets[selectionId] = chartData.datasets[selectionId] || {\n    data: [{\n      x: null,\n      y: 1\n    }, {\n      x: null,\n      y: 1\n    }],\n    error: [{\n      x: null,\n      y: null\n    }, {\n      x: null,\n      y: null\n    }],\n    yAxisID: 'selection-scale',\n    label: 'selection',\n    backgroundColor: colors.getColor(1).css(),\n    borderColor: colors.getColor(1).css(),\n    fill: true,\n    lineTension: 0,\n    pointRadius: 0\n  };\n\n  if (partitionA.selected && partitionA.selected.length > 0) {\n    chartData.datasets[selectionId].data[0].x = partitionA.selected[0];\n    chartData.datasets[selectionId].data[1].x = partitionA.selected[1];\n  } else {\n    chartData.datasets[selectionId].data[0].x = null;\n    chartData.datasets[selectionId].data[1].x = null;\n  } // Hand-off to ChartJS for plotting\n\n\n  view._chartjs.update();\n}\n\nmodule.exports = BaseWidget.extend({\n  template: '<div class=\"widgetInner mdl-card__media\"></div>',\n  update: function update() {\n    _update(this);\n  },\n  initChart: function initChart() {\n    _initChart(this);\n  },\n  deinitChart: function deinitChart() {\n    _deinitChart(this);\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTliZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL3ZpZXdzL2NoYXJ0anMxZC5qcz8yN2MxIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBhcHAgPSByZXF1aXJlKCdhbXBlcnNhbmQtYXBwJyk7XG52YXIgU3BvdCA9IHJlcXVpcmUoJ3Nwb3QtZnJhbWV3b3JrJyk7XG52YXIgQmFzZVdpZGdldCA9IHJlcXVpcmUoJy4vYmFzZS13aWRnZXQnKTtcbnZhciBDaGFydCA9IHJlcXVpcmUoJ2NoYXJ0LmpzJyk7XG52YXIgY29sb3JzID0gcmVxdWlyZSgnLi4vLi4vY29sb3JzJyk7XG52YXIgbWlzdmFsID0gU3BvdC51dGlsLm1pc3ZhbDtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi91dGlsJyk7XG5cbi8vIENhbGxlZCBieSBDaGFydGpzLCB0aGlzIC0+IGNoYXJ0IGluc3RhbmNlXG5mdW5jdGlvbiBvbkNsaWNrIChldiwgZWxlbWVudHMpIHtcbiAgdmFyIG1vZGVsID0gdGhpcy5fQW1wZXJzYW5kdmlldy5tb2RlbDtcbiAgdmFyIHBhcnRpdGlvbiA9IG1vZGVsLmZpbHRlci5wYXJ0aXRpb25zLmdldCgxLCAncmFuaycpO1xuXG4gIGlmIChlbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgcGFydGl0aW9uLnVwZGF0ZVNlbGVjdGlvbihwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tlbGVtZW50c1swXS5faW5kZXhdKTtcbiAgICBtb2RlbC5maWx0ZXIudXBkYXRlRGF0YUZpbHRlcigpO1xuICAgIGFwcC5tZS5kYXRhdmlldy5nZXREYXRhKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVpbml0Q2hhcnQgKHZpZXcpIHtcbiAgaWYgKHZpZXcuX2NoYXJ0anMpIHtcbiAgICB2aWV3Ll9jaGFydGpzLmRlc3Ryb3koKTtcbiAgICBkZWxldGUgdmlldy5fY2hhcnRqcztcbiAgfVxuICBkZWxldGUgdmlldy5fY29uZmlnO1xuXG4gIHZhciBjYW52YXMgPSB2aWV3LnF1ZXJ5QnlIb29rKCdjYW52YXMnKTtcbiAgaWYgKGNhbnZhcykge1xuICAgIHZpZXcuZWwucmVtb3ZlQ2hpbGQoY2FudmFzKTtcbiAgfVxuICB2aWV3LmlzSW5pdGlhbGl6ZWQgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaW5pdENoYXJ0ICh2aWV3KSB7XG4gIC8vIENvbmZpZ3VyZSBwbG90XG4gIHZpZXcuX2NvbmZpZyA9IHZpZXcubW9kZWwuY2hhcnRqc0NvbmZpZygpO1xuICB2YXIgb3B0aW9ucyA9IHZpZXcuX2NvbmZpZy5vcHRpb25zO1xuXG4gIC8vIGF4aXMgdHlwZXNcbiAgdmFyIHBhcnRpdGlvbkEgPSB2aWV3Lm1vZGVsLmZpbHRlci5wYXJ0aXRpb25zLmdldCgxLCAncmFuaycpO1xuICBpZiAocGFydGl0aW9uQS5pc0RhdGV0aW1lKSB7XG4gICAgb3B0aW9ucy5zY2FsZXMueEF4ZXNbMF0udHlwZSA9ICd0aW1lJztcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb25BLmlzRHVyYXRpb24pIHtcbiAgICBvcHRpb25zLnNjYWxlcy54QXhlc1swXS50eXBlID0gJ3Nwb3QtZHVyYXRpb24nO1xuICB9XG4gIG9wdGlvbnMuc2NhbGVzLnhBeGVzWzBdLnNjYWxlTGFiZWwgPSB7XG4gICAgZGlzcGxheTogcGFydGl0aW9uQS5zaG93TGFiZWwsXG4gICAgbGFiZWxTdHJpbmc6IHBhcnRpdGlvbkEubGFiZWxcbiAgfTtcblxuICAvLyB0aXRsZVxuICBvcHRpb25zLnRpdGxlLnRleHQgPSB2aWV3Lm1vZGVsLmdldFRpdGxlKCk7XG5cbiAgLy8gbW91c2UgaW50ZXJhY3Rpb25cbiAgb3B0aW9ucy5vbkNsaWNrID0gb25DbGljaztcblxuICAvLyBmb3JjZSBhIHNxdWFyZSBmdWxsIHNpemUgcGxvdFxuICB2YXIgd2lkdGggPSB2aWV3LmVsLm9mZnNldFdpZHRoO1xuICB2YXIgaGVpZ2h0ID0gdmlldy5lbC5vZmZzZXRIZWlnaHQ7XG5cbiAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICBjYW52YXMuc2V0QXR0cmlidXRlKCdkYXRhLWhvb2snLCAnY2FudmFzJyk7XG4gIHZpZXcuZWwuYXBwZW5kQ2hpbGQoY2FudmFzKTtcblxuICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gIGN0eC5jYW52YXMud2lkdGggPSB3aWR0aDtcbiAgY3R4LmNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG5cbiAgdmFyIGFnZ3JlZ2F0ZUQgPSB2aWV3Lm1vZGVsLmZpbHRlci5hZ2dyZWdhdGVzLmdldCg0LCAncmFuaycpO1xuICBpZiAoYWdncmVnYXRlRCkge1xuICAgIC8vIHNob3cgc2Vjb25kYXJ5IHkgQXhpcyBvbiB0aGUgcmlnaHQgd2hlbiB3ZSBoYXZlIGEgc2Vjb25kIHkgdmFyaWFibGVcbiAgICB2aWV3Ll9jb25maWcub3B0aW9ucy5zY2FsZXMueUF4ZXNbMV0uZGlzcGxheSA9IHRydWU7XG4gIH1cblxuICAvLyBDcmVhdGUgQ2hhcnRqcyBvYmplY3RcbiAgdmlldy5fY2hhcnRqcyA9IG5ldyBDaGFydChjdHgsIHZpZXcuX2NvbmZpZyk7XG5cbiAgLy8gSW4gY2FsbGJhY2tzIG9uIHRoZSBjaGFydCB3ZSB3aWxsIG5lZWQgdGhlIHZpZXcsIHNvIHN0b3JlIGEgcmVmZXJlbmNlXG4gIHZpZXcuX2NoYXJ0anMuX0FtcGVyc2FuZHZpZXcgPSB2aWV3O1xuICB2aWV3LmlzSW5pdGlhbGl6ZWQgPSB0cnVlO1xufVxuXG5mdW5jdGlvbiB1cGRhdGUgKHZpZXcpIHtcbiAgaWYgKCF2aWV3LmlzSW5pdGlhbGl6ZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZmlsdGVyID0gdmlldy5tb2RlbC5maWx0ZXI7XG4gIHZhciBwYXJ0aXRpb25BID0gZmlsdGVyLnBhcnRpdGlvbnMuZ2V0KDEsICdyYW5rJyk7XG4gIHZhciBwYXJ0aXRpb25CID0gZmlsdGVyLnBhcnRpdGlvbnMuZ2V0KDIsICdyYW5rJyk7XG5cbiAgdmFyIGNoYXJ0RGF0YSA9IHZpZXcuX2NvbmZpZy5kYXRhO1xuICB2YXIgZGF0YXNldENvdW50O1xuXG4gIC8vIHVwZGF0ZSBsZWdlbmRzIGFuZCB0b29sdGlwc1xuICBpZiAocGFydGl0aW9uQiAmJiBwYXJ0aXRpb25CLmdyb3VwcyAmJiBwYXJ0aXRpb25CLmdyb3Vwcy5sZW5ndGggPiAxKSB7XG4gICAgLy8gd2UgaGF2ZSBzdWItZ3JvdXBpbmdcbiAgICB2aWV3Ll9jb25maWcub3B0aW9ucy5sZWdlbmQuZGlzcGxheSA9IHBhcnRpdGlvbkIuc2hvd0xlZ2VuZDtcbiAgICB2aWV3Ll9jb25maWcub3B0aW9ucy50b29sdGlwcy5tb2RlID0gJ2xhYmVsJztcbiAgICBkYXRhc2V0Q291bnQgPSBwYXJ0aXRpb25CLmdyb3Vwcy5sZW5ndGg7XG4gIH0gZWxzZSB7XG4gICAgdmlldy5fY29uZmlnLm9wdGlvbnMubGVnZW5kLmRpc3BsYXkgPSBmYWxzZTtcbiAgICB2aWV3Ll9jb25maWcub3B0aW9ucy50b29sdGlwcy5tb2RlID0gJ3NpbmdsZSc7XG4gICAgZGF0YXNldENvdW50ID0gMTtcbiAgfVxuXG4gIHZhciBhZ2dyZWdhdGU7XG5cbiAgYWdncmVnYXRlID0gZmlsdGVyLmFnZ3JlZ2F0ZXMuZ2V0KDEsICdyYW5rJyk7XG4gIHZhciB2YWx1ZUZuO1xuICBpZiAoYWdncmVnYXRlKSB7XG4gICAgdmFsdWVGbiA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgaWYgKGdyb3VwLmNvdW50ICE9PSBtaXN2YWwgJiYgZ3JvdXAuYWEgIT09IG1pc3ZhbCkge1xuICAgICAgICByZXR1cm4gcGFyc2VGbG9hdChncm91cC5hYSkgfHwgbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgdmFsdWVGbiA9IGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgaWYgKGdyb3VwLmNvdW50ICE9PSBtaXN2YWwgJiYgZ3JvdXAuY291bnQgIT09IDApIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KGdyb3VwLmNvdW50KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICB2aWV3Ll9jb25maWcub3B0aW9ucy5lcnJvckRpciA9ICdib3RoJztcbiAgYWdncmVnYXRlID0gZmlsdGVyLmFnZ3JlZ2F0ZXMuZ2V0KDIsICdyYW5rJyk7XG4gIHZhciBlcnJvclhGbjtcbiAgaWYgKGFnZ3JlZ2F0ZSkge1xuICAgIGVycm9yWEZuID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICBpZiAoZ3JvdXAuYmIgIT09IG1pc3ZhbCkge1xuICAgICAgICByZXR1cm4gcGFyc2VGbG9hdChncm91cC5iYikgfHwgMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiAwO1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgZXJyb3JYRm4gPSBmdW5jdGlvbiAoZ3JvdXApIHsgcmV0dXJuIG51bGw7IH07XG4gICAgdmlldy5fY29uZmlnLm9wdGlvbnMuZXJyb3JEaXIgPSAndmVydGljYWwnO1xuICB9XG5cbiAgYWdncmVnYXRlID0gZmlsdGVyLmFnZ3JlZ2F0ZXMuZ2V0KDMsICdyYW5rJyk7XG4gIHZhciBlcnJvcllGbjtcbiAgaWYgKGFnZ3JlZ2F0ZSkge1xuICAgIGVycm9yWUZuID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICBpZiAoZ3JvdXAuY2MgIT09IG1pc3ZhbCkge1xuICAgICAgICByZXR1cm4gcGFyc2VGbG9hdChncm91cC5jYykgfHwgMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiAwO1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgZXJyb3JZRm4gPSBmdW5jdGlvbiAoZ3JvdXApIHsgcmV0dXJuIG51bGw7IH07XG4gICAgaWYgKHZpZXcuX2NvbmZpZy5vcHRpb25zLmVycm9yRGlyID09PSAndmVydGljYWwnKSB7XG4gICAgICB2aWV3Ll9jb25maWcub3B0aW9ucy5lcnJvckRpciA9PT0gJ25vbmUnO1xuICAgIH1cbiAgICBpZiAodmlldy5fY29uZmlnLm9wdGlvbnMuZXJyb3JEaXIgPT09ICdib3RoJykge1xuICAgICAgdmlldy5fY29uZmlnLm9wdGlvbnMuZXJyb3JEaXIgPT09ICdob3Jpem9udGFsJztcbiAgICB9XG4gIH1cblxuICBhZ2dyZWdhdGUgPSBmaWx0ZXIuYWdncmVnYXRlcy5nZXQoNCwgJ3JhbmsnKTtcbiAgdmFyIHNlY29uZFlGbiA9IGZhbHNlO1xuICB2YXIgc2Vjb25kWU9mZnNldCA9IGRhdGFzZXRDb3VudDtcbiAgaWYgKGFnZ3JlZ2F0ZSkge1xuICAgIC8vIGRvdWJsZSB0aGUgbnVtYmVyIG9mIGRhdGFzZXRzIGZvciB0aGUgc2Vjb25kIHkgdmFsdWVcbiAgICBzZWNvbmRZT2Zmc2V0ID0gZGF0YXNldENvdW50O1xuICAgIGRhdGFzZXRDb3VudCA9IDIgKiBkYXRhc2V0Q291bnQ7XG4gICAgc2Vjb25kWUZuID0gZnVuY3Rpb24gKGdyb3VwKSB7XG4gICAgICBpZiAoZ3JvdXAuZGQgIT09IG1pc3ZhbCkge1xuICAgICAgICByZXR1cm4gcGFyc2VGbG9hdChncm91cC5kZCkgfHwgbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICB1dGlsLnJlc2l6ZUNoYXJ0anNEYXRhKGNoYXJ0RGF0YSwgcGFydGl0aW9uQSwgcGFydGl0aW9uQiwge1xuICAgIG11bHRpRGltZW5zaW9uYWw6IHRydWUsXG4gICAgZG91YmxlRGF0YXNldHM6IHNlY29uZFlGblxuICB9KTtcblxuICAvLyBhZGQgZGF0YXBvaW50c1xuICBmaWx0ZXIuZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgIHZhciBpID0gdXRpbC5wYXJ0aXRpb25WYWx1ZVRvSW5kZXgocGFydGl0aW9uQSwgZ3JvdXAuYSk7XG4gICAgdmFyIGogPSB1dGlsLnBhcnRpdGlvblZhbHVlVG9JbmRleChwYXJ0aXRpb25CLCBncm91cC5iKTtcblxuICAgIGlmIChpID49IDAgJiYgaiA+PSAwKSB7XG4gICAgICBjaGFydERhdGEuZGF0YXNldHNbal0uZGF0YVtpXS54ID0gZ3JvdXAuYTtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5kYXRhW2ldLnkgPSB2YWx1ZUZuKGdyb3VwKTtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tqXS5lcnJvcltpXS54ID0gZXJyb3JYRm4oZ3JvdXApO1xuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzW2pdLmVycm9yW2ldLnkgPSBlcnJvcllGbihncm91cCk7XG4gICAgICBjaGFydERhdGEuZGF0YXNldHNbal0ueUF4aXNJRCA9ICdmaXJzdC1zY2FsZSc7XG5cbiAgICAgIGlmIChzZWNvbmRZRm4pIHtcbiAgICAgICAgY2hhcnREYXRhLmRhdGFzZXRzW3NlY29uZFlPZmZzZXQgKyBqXS5kYXRhW2ldLnggPSBncm91cC5hO1xuICAgICAgICBjaGFydERhdGEuZGF0YXNldHNbc2Vjb25kWU9mZnNldCArIGpdLmRhdGFbaV0ueSA9IHNlY29uZFlGbihncm91cCk7XG4gICAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tzZWNvbmRZT2Zmc2V0ICsgal0uZXJyb3JbaV0ueCA9IG51bGw7XG4gICAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tzZWNvbmRZT2Zmc2V0ICsgal0uZXJyb3JbaV0ueSA9IG51bGw7XG4gICAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tzZWNvbmRZT2Zmc2V0ICsgal0ueUF4aXNJRCA9ICdzZWNvbmQtc2NhbGUnO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgLy8gQWRkIGFuIGV4dHJhIGRhdGFzZXQgdG8gaGlnaGxpZ2h0IHNlbGVjdGVkIGFyZWFcbiAgdmFyIHNlbGVjdGlvbklkID0gZGF0YXNldENvdW50O1xuICBjaGFydERhdGEuZGF0YXNldHNbc2VsZWN0aW9uSWRdID0gY2hhcnREYXRhLmRhdGFzZXRzW3NlbGVjdGlvbklkXSB8fCB7XG4gICAgZGF0YTogWyB7eDogbnVsbCwgeTogMX0sIHt4OiBudWxsLCB5OiAxfSBdLFxuICAgIGVycm9yOiBbIHt4OiBudWxsLCB5OiBudWxsfSwge3g6IG51bGwsIHk6IG51bGx9IF0sXG4gICAgeUF4aXNJRDogJ3NlbGVjdGlvbi1zY2FsZScsXG4gICAgbGFiZWw6ICdzZWxlY3Rpb24nLFxuICAgIGJhY2tncm91bmRDb2xvcjogY29sb3JzLmdldENvbG9yKDEpLmNzcygpLFxuICAgIGJvcmRlckNvbG9yOiBjb2xvcnMuZ2V0Q29sb3IoMSkuY3NzKCksXG4gICAgZmlsbDogdHJ1ZSxcbiAgICBsaW5lVGVuc2lvbjogMCxcbiAgICBwb2ludFJhZGl1czogMFxuICB9O1xuXG4gIGlmIChwYXJ0aXRpb25BLnNlbGVjdGVkICYmIHBhcnRpdGlvbkEuc2VsZWN0ZWQubGVuZ3RoID4gMCkge1xuICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tzZWxlY3Rpb25JZF0uZGF0YVswXS54ID0gcGFydGl0aW9uQS5zZWxlY3RlZFswXTtcbiAgICBjaGFydERhdGEuZGF0YXNldHNbc2VsZWN0aW9uSWRdLmRhdGFbMV0ueCA9IHBhcnRpdGlvbkEuc2VsZWN0ZWRbMV07XG4gIH0gZWxzZSB7XG4gICAgY2hhcnREYXRhLmRhdGFzZXRzW3NlbGVjdGlvbklkXS5kYXRhWzBdLnggPSBudWxsO1xuICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1tzZWxlY3Rpb25JZF0uZGF0YVsxXS54ID0gbnVsbDtcbiAgfVxuXG4gIC8vIEhhbmQtb2ZmIHRvIENoYXJ0SlMgZm9yIHBsb3R0aW5nXG4gIHZpZXcuX2NoYXJ0anMudXBkYXRlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZVdpZGdldC5leHRlbmQoe1xuICB0ZW1wbGF0ZTogJzxkaXYgY2xhc3M9XCJ3aWRnZXRJbm5lciBtZGwtY2FyZF9fbWVkaWFcIj48L2Rpdj4nLFxuXG4gIHVwZGF0ZTogZnVuY3Rpb24gKCkge1xuICAgIHVwZGF0ZSh0aGlzKTtcbiAgfSxcblxuICBpbml0Q2hhcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpbml0Q2hhcnQodGhpcyk7XG4gIH0sXG5cbiAgZGVpbml0Q2hhcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICBkZWluaXRDaGFydCh0aGlzKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFGQTtBQUNBO0FBS0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVRBO0FBQ0E7QUFXQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBYkEiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///e9bd\n")},eb63:function(module,exports,__webpack_require__){eval("/**\n *\n * Color handling\n *\n * All colors are a chroma.js color. See http://gka.github.io/chroma.js/\n * @module colors\n */\nvar chroma = __webpack_require__(/*! chroma-js */ \"9b81\");\n\nvar colors = ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f']; // alternative color scheme, needs some tuning:\n// var colors = ['#cccccc', '#c2e06c', '#00168c', '#997100', '#eabd00', '#ff4889', '#f497ff', '#0db700', '#d26bb8', '#a8e74b', '#a83375', '#ff6a2b', '#8690ff', '#ff4b50', '#fb78ff', '#00a349', '#c6008f', '#4ef168', '#ff25a2', '#be6300', '#b667ff', '#ff9451', '#e113d2', '#cc0013', '#ff66e0'];\n\nvar scale = chroma.scale('Spectral');\nmodule.exports = {\n  /**\n   * Get i-th color\n   * @param {number} color number\n   * @returns {Object} color\n   */\n  getColor: function getColor(i) {\n    i = parseInt(i);\n\n    if (i < 0 || i >= colors.length) {\n      // pick a color from the scale defined above\n      return scale((i - colors.length) * (211 / 971) % 1);\n    } else {\n      return chroma(colors[i]);\n    }\n  },\n\n  /**\n   * Colorscale from 0 to 1\n   * @param  {number} f [description]\n   * @return {number}   [description]\n   */\n  getColorFloat: function getColorFloat(f) {\n    return scale(f);\n  },\n\n  /**\n   * Color for unselected groups\n   * @type {any}\n   */\n  unselectedColor: chroma('#aaaaaa')\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWI2My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9jb2xvcnMuanM/MWI5MiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqXG4gKiBDb2xvciBoYW5kbGluZ1xuICpcbiAqIEFsbCBjb2xvcnMgYXJlIGEgY2hyb21hLmpzIGNvbG9yLiBTZWUgaHR0cDovL2drYS5naXRodWIuaW8vY2hyb21hLmpzL1xuICogQG1vZHVsZSBjb2xvcnNcbiAqL1xudmFyIGNocm9tYSA9IHJlcXVpcmUoJ2Nocm9tYS1qcycpO1xuXG52YXIgY29sb3JzID0gWycjOGRkM2M3JywgJyNmZmZmYjMnLCAnI2JlYmFkYScsICcjZmI4MDcyJywgJyM4MGIxZDMnLCAnI2ZkYjQ2MicsICcjYjNkZTY5JywgJyNmY2NkZTUnLCAnI2Q5ZDlkOScsICcjYmM4MGJkJywgJyNjY2ViYzUnLCAnI2ZmZWQ2ZiddO1xuLy8gYWx0ZXJuYXRpdmUgY29sb3Igc2NoZW1lLCBuZWVkcyBzb21lIHR1bmluZzpcbi8vIHZhciBjb2xvcnMgPSBbJyNjY2NjY2MnLCAnI2MyZTA2YycsICcjMDAxNjhjJywgJyM5OTcxMDAnLCAnI2VhYmQwMCcsICcjZmY0ODg5JywgJyNmNDk3ZmYnLCAnIzBkYjcwMCcsICcjZDI2YmI4JywgJyNhOGU3NGInLCAnI2E4MzM3NScsICcjZmY2YTJiJywgJyM4NjkwZmYnLCAnI2ZmNGI1MCcsICcjZmI3OGZmJywgJyMwMGEzNDknLCAnI2M2MDA4ZicsICcjNGVmMTY4JywgJyNmZjI1YTInLCAnI2JlNjMwMCcsICcjYjY2N2ZmJywgJyNmZjk0NTEnLCAnI2UxMTNkMicsICcjY2MwMDEzJywgJyNmZjY2ZTAnXTtcbnZhciBzY2FsZSA9IGNocm9tYS5zY2FsZSgnU3BlY3RyYWwnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIC8qKlxuICAgKiBHZXQgaS10aCBjb2xvclxuICAgKiBAcGFyYW0ge251bWJlcn0gY29sb3IgbnVtYmVyXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IGNvbG9yXG4gICAqL1xuICBnZXRDb2xvcjogZnVuY3Rpb24gZ2V0Q29sb3IgKGkpIHtcbiAgICBpID0gcGFyc2VJbnQoaSk7XG4gICAgaWYgKGkgPCAwIHx8IGkgPj0gY29sb3JzLmxlbmd0aCkge1xuICAgICAgLy8gcGljayBhIGNvbG9yIGZyb20gdGhlIHNjYWxlIGRlZmluZWQgYWJvdmVcbiAgICAgIHJldHVybiBzY2FsZSgoKGkgLSBjb2xvcnMubGVuZ3RoKSAqICgyMTEgLyA5NzEpKSAlIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY2hyb21hKGNvbG9yc1tpXSk7XG4gICAgfVxuICB9LFxuICAvKipcbiAgICogQ29sb3JzY2FsZSBmcm9tIDAgdG8gMVxuICAgKiBAcGFyYW0gIHtudW1iZXJ9IGYgW2Rlc2NyaXB0aW9uXVxuICAgKiBAcmV0dXJuIHtudW1iZXJ9ICAgW2Rlc2NyaXB0aW9uXVxuICAgKi9cbiAgZ2V0Q29sb3JGbG9hdDogZnVuY3Rpb24gKGYpIHtcbiAgICByZXR1cm4gc2NhbGUoZik7XG4gIH0sXG4gIC8qKlxuICAgKiBDb2xvciBmb3IgdW5zZWxlY3RlZCBncm91cHNcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHVuc2VsZWN0ZWRDb2xvcjogY2hyb21hKCcjYWFhYWFhJylcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7O0FBT0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBRUE7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTs7OztBQUlBO0FBM0JBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///eb63\n")},ee83:function(module,exports,__webpack_require__){"use strict";eval("// Code adapted from: https://github.com/CAYdenberg/Chart.js-ErrorBars.git\n// Original license: MIT\n// Original copyright: Copyright (c) 2013-2016 Nick Downie\n\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nmodule.exports = function (Chart, chartType, newType) {\n  var helpers = Chart.helpers; // ErrorBar element\n\n  Chart.elements.ErrorBar = Chart.elements.ErrorBar || Chart.Element.extend({\n    draw: function draw() {\n      var ctx = this._chart.ctx;\n      var vm = this._view;\n\n      if (vm.direction === 'none') {\n        return;\n      }\n\n      var halfWidth = vm.capWidth / 2;\n      var halfHeight = vm.capHeight / 2;\n      var top = vm.yTop;\n      var bottom = vm.yBottom;\n      var left = vm.xLeft;\n      var right = vm.xRight;\n      ctx.strokeStyle = vm.strokeColor;\n      ctx.lineWidth = vm.strokeWidth; // draw vertical error bar\n\n      if (vm.direction === 'vertical' || vm.direction === 'both') {\n        ctx.beginPath();\n        ctx.moveTo(vm.x, top);\n        ctx.lineTo(vm.x, bottom);\n        ctx.stroke();\n        ctx.beginPath();\n        ctx.moveTo(vm.x - halfWidth, top);\n        ctx.lineTo(vm.x + halfWidth, top);\n        ctx.stroke();\n        ctx.beginPath();\n        ctx.moveTo(vm.x - halfWidth, bottom);\n        ctx.lineTo(vm.x + halfWidth, bottom);\n        ctx.stroke();\n      } // draw horizontal error bar\n\n\n      if (vm.direction === 'horizontal' || vm.direction === 'both') {\n        ctx.beginPath();\n        ctx.moveTo(left, vm.y);\n        ctx.lineTo(right, vm.y);\n        ctx.stroke();\n        ctx.beginPath();\n        ctx.moveTo(left, vm.y - halfHeight);\n        ctx.lineTo(left, vm.y + halfHeight);\n        ctx.stroke();\n        ctx.beginPath();\n        ctx.moveTo(right, vm.y - halfHeight);\n        ctx.lineTo(right, vm.y + halfHeight);\n        ctx.stroke();\n      }\n    }\n  });\n  /**\n   * Default config for errorbars:\n   * errorDir: none, horizontal, vertical, both\n   * errorStrokeWidth\n   * errorCapWidth\n   * errorCapHeight\n   * errorColor\n   */\n\n  Chart.defaults[newType] = helpers.extend(Chart.defaults[chartType], {\n    errorDir: 'vertical',\n    errorStrokeWidth: 1,\n    errorCapWidth: 2.5,\n    errorCapHeight: 0.25,\n    errorColor: 'rgba(0,0,0,1)'\n  }); // Extend chart type with error bar\n\n  Chart.controllers[newType] = Chart.controllers[chartType].extend({\n    initialize: function initialize(chart, datasetIndex) {\n      // call Super\n      Chart.controllers[chartType].prototype.initialize.call(this, chart, datasetIndex);\n      var options = chart.chart.config.options;\n      options.errorDir = options.errorDir || Chart.defaults[newType].errorDir;\n      options.errorCapWidth = options.errorCapWidth || Chart.defaults[newType].errorCapWidth;\n      options.errorCapHeight = options.errorCapHeight || Chart.defaults[newType].errorCapHeight;\n      options.errorStrokeColor = options.errorColor || Chart.defaults[newType].errorColor;\n      options.errorStrokeWidth = options.errorStrokeWidth || Chart.defaults[newType].errorStrokeWidth;\n    },\n    addElements: function addElements() {\n      // call Super\n      Chart.controllers[chartType].prototype.addElements.call(this);\n      var meta = this.getMeta();\n      var error = this.getDataset().error || [];\n      var metaError = meta.error || [];\n      var i, ilen;\n\n      for (i = 0, ilen = error.length; i < ilen; i++) {\n        metaError[i] = metaError[i] || new Chart.elements.ErrorBar({\n          _chart: this.chart.chart,\n          _datasetIndex: this.index,\n          _index: i\n        });\n      }\n\n      meta.error = metaError;\n    },\n    addElementAndReset: function addElementAndReset(index) {\n      // call Super\n      Chart.controllers[chartType].prototype.addElementAndReset.call(this, index);\n      var meta = this.getMeta();\n      var metaError = meta.error;\n      var metaData = meta.data;\n      metaError[index] = metaError[index] || new Chart.elements.ErrorBar({\n        _chart: this.chart.chart,\n        _datasetIndex: this.index,\n        _index: index,\n        x: 0,\n        y: 0\n      });\n      this.updateErrorBar(metaError[index], metaData[index], index, true);\n    },\n    update: function update(reset) {\n      // call Super\n      Chart.controllers[chartType].prototype.update.call(this, reset);\n      var meta = this.getMeta();\n      var metaData = meta.data;\n      var metaError = meta.error; // make sure we don't have more error bars than points\n\n      var cut = metaError.length - metaData.length;\n\n      if (cut > 0) {\n        metaError.splice(metaData.length, cut);\n      }\n\n      metaError.forEach(function (errorBar, index) {\n        this.updateErrorBar(errorBar, metaData[index], index, reset);\n      }, this);\n    },\n    updateErrorBar: function updateErrorBar(errorBar, element, index, reset) {\n      var dataset = this.getDataset();\n      var meta = this.getMeta();\n      var xScale = this.getScaleForId(meta.xAxisID);\n      var yScale = this.getScaleForId(meta.yAxisID);\n      var options = this.chart.chart.config.options;\n      var px = element._model.x;\n      var py = element._model.y;\n      var x = xScale.getValueForPixel(px);\n      var y = yScale.getValueForPixel(py);\n      var errorX;\n      var errorY;\n\n      if (_typeof(dataset.error[index]) === 'object' && dataset.error[index] != null) {\n        errorX = dataset.error[index].x;\n        errorY = dataset.error[index].y;\n      } else {\n        errorX = dataset.error[index];\n        errorY = dataset.error[index];\n      } // Utility\n\n\n      errorBar._chart = this.chart.chart;\n      errorBar._xScale = xScale;\n      errorBar._yScale = yScale;\n      errorBar._datasetIndex = this.index;\n      errorBar._index = index;\n      errorBar._model = {\n        // Position\n        x: px,\n        y: py,\n        yTop: yScale.getPixelForValue(y + errorY, index, this.index, this.chart.isCombo),\n        yBottom: yScale.getPixelForValue(y - errorY, index, this.index, this.chart.isCombo),\n        xLeft: xScale.getPixelForValue(x - errorX, index, this.index, this.chart.isCombo),\n        xRight: xScale.getPixelForValue(x + errorX, index, this.index, this.chart.isCombo),\n        // Appearance\n        capWidth: element._model.width * options.errorCapWidth || options.errorCapWidth,\n        capHeight: element._model.height * options.errorCapHeight || options.errorCapHeight,\n        direction: options.errorDir,\n        strokeColor: options.errorStrokeColor,\n        strokeWidth: options.errorStrokeWidth\n      };\n      errorBar.pivot();\n    },\n    draw: function draw(ease) {\n      var easingDecimal = ease || 1; // call Super\n\n      Chart.controllers[chartType].prototype.draw.call(this, ease);\n      this.getMeta().error.forEach(function (errorBar, index) {\n        // Chech for valid errror bar sizes:\n        // 2-d datastructure: check error.x and error.y\n        // 1-d datastructure: check error\n        var e = this.getDataset().error[index];\n\n        if (e !== null && _typeof(e) === 'object') {\n          if (e.x !== null && e.x !== undefined && !isNaN(e.x) || e.y !== null && e.y !== undefined && !isNaN(e.y)) {\n            errorBar.transition(easingDecimal).draw();\n          }\n        } else if (e !== null && e !== undefined && !isNaN(e) && e !== 0) {\n          errorBar.transition(easingDecimal).draw();\n        }\n      }, this);\n    }\n  });\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWU4My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL2NoYXJ0anMtZXJyb3JiYXJzLmpzPzZmOWMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29kZSBhZGFwdGVkIGZyb206IGh0dHBzOi8vZ2l0aHViLmNvbS9DQVlkZW5iZXJnL0NoYXJ0LmpzLUVycm9yQmFycy5naXRcbi8vIE9yaWdpbmFsIGxpY2Vuc2U6IE1JVFxuLy8gT3JpZ2luYWwgY29weXJpZ2h0OiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAxNiBOaWNrIERvd25pZVxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDaGFydCwgY2hhcnRUeXBlLCBuZXdUeXBlKSB7XG4gIHZhciBoZWxwZXJzID0gQ2hhcnQuaGVscGVycztcblxuICAvLyBFcnJvckJhciBlbGVtZW50XG4gIENoYXJ0LmVsZW1lbnRzLkVycm9yQmFyID0gQ2hhcnQuZWxlbWVudHMuRXJyb3JCYXIgfHwgQ2hhcnQuRWxlbWVudC5leHRlbmQoe1xuICAgIGRyYXc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBjdHggPSB0aGlzLl9jaGFydC5jdHg7XG4gICAgICB2YXIgdm0gPSB0aGlzLl92aWV3O1xuXG4gICAgICBpZiAodm0uZGlyZWN0aW9uID09PSAnbm9uZScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgaGFsZldpZHRoID0gdm0uY2FwV2lkdGggLyAyO1xuICAgICAgdmFyIGhhbGZIZWlnaHQgPSB2bS5jYXBIZWlnaHQgLyAyO1xuXG4gICAgICB2YXIgdG9wID0gdm0ueVRvcDtcbiAgICAgIHZhciBib3R0b20gPSB2bS55Qm90dG9tO1xuICAgICAgdmFyIGxlZnQgPSB2bS54TGVmdDtcbiAgICAgIHZhciByaWdodCA9IHZtLnhSaWdodDtcblxuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gdm0uc3Ryb2tlQ29sb3I7XG4gICAgICBjdHgubGluZVdpZHRoID0gdm0uc3Ryb2tlV2lkdGg7XG5cbiAgICAgIC8vIGRyYXcgdmVydGljYWwgZXJyb3IgYmFyXG4gICAgICBpZiAodm0uZGlyZWN0aW9uID09PSAndmVydGljYWwnIHx8IHZtLmRpcmVjdGlvbiA9PT0gJ2JvdGgnKSB7XG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgY3R4Lm1vdmVUbyh2bS54LCB0b3ApO1xuICAgICAgICBjdHgubGluZVRvKHZtLngsIGJvdHRvbSk7XG4gICAgICAgIGN0eC5zdHJva2UoKTtcblxuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIGN0eC5tb3ZlVG8odm0ueCAtIGhhbGZXaWR0aCwgdG9wKTtcbiAgICAgICAgY3R4LmxpbmVUbyh2bS54ICsgaGFsZldpZHRoLCB0b3ApO1xuICAgICAgICBjdHguc3Ryb2tlKCk7XG5cbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBjdHgubW92ZVRvKHZtLnggLSBoYWxmV2lkdGgsIGJvdHRvbSk7XG4gICAgICAgIGN0eC5saW5lVG8odm0ueCArIGhhbGZXaWR0aCwgYm90dG9tKTtcbiAgICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgfVxuXG4gICAgICAvLyBkcmF3IGhvcml6b250YWwgZXJyb3IgYmFyXG4gICAgICBpZiAodm0uZGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcgfHwgdm0uZGlyZWN0aW9uID09PSAnYm90aCcpIHtcbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBjdHgubW92ZVRvKGxlZnQsIHZtLnkpO1xuICAgICAgICBjdHgubGluZVRvKHJpZ2h0LCB2bS55KTtcbiAgICAgICAgY3R4LnN0cm9rZSgpO1xuXG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgY3R4Lm1vdmVUbyhsZWZ0LCB2bS55IC0gaGFsZkhlaWdodCk7XG4gICAgICAgIGN0eC5saW5lVG8obGVmdCwgdm0ueSArIGhhbGZIZWlnaHQpO1xuICAgICAgICBjdHguc3Ryb2tlKCk7XG5cbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBjdHgubW92ZVRvKHJpZ2h0LCB2bS55IC0gaGFsZkhlaWdodCk7XG4gICAgICAgIGN0eC5saW5lVG8ocmlnaHQsIHZtLnkgKyBoYWxmSGVpZ2h0KTtcbiAgICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgY29uZmlnIGZvciBlcnJvcmJhcnM6XG4gICAqIGVycm9yRGlyOiBub25lLCBob3Jpem9udGFsLCB2ZXJ0aWNhbCwgYm90aFxuICAgKiBlcnJvclN0cm9rZVdpZHRoXG4gICAqIGVycm9yQ2FwV2lkdGhcbiAgICogZXJyb3JDYXBIZWlnaHRcbiAgICogZXJyb3JDb2xvclxuICAgKi9cbiAgQ2hhcnQuZGVmYXVsdHNbbmV3VHlwZV0gPSBoZWxwZXJzLmV4dGVuZChDaGFydC5kZWZhdWx0c1tjaGFydFR5cGVdLCB7XG4gICAgZXJyb3JEaXI6ICd2ZXJ0aWNhbCcsXG4gICAgZXJyb3JTdHJva2VXaWR0aDogMSxcbiAgICBlcnJvckNhcFdpZHRoOiAyLjUsXG4gICAgZXJyb3JDYXBIZWlnaHQ6IDAuMjUsXG4gICAgZXJyb3JDb2xvcjogJ3JnYmEoMCwwLDAsMSknXG4gIH0pO1xuXG4gIC8vIEV4dGVuZCBjaGFydCB0eXBlIHdpdGggZXJyb3IgYmFyXG4gIENoYXJ0LmNvbnRyb2xsZXJzW25ld1R5cGVdID0gQ2hhcnQuY29udHJvbGxlcnNbY2hhcnRUeXBlXS5leHRlbmQoe1xuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uIChjaGFydCwgZGF0YXNldEluZGV4KSB7XG4gICAgICAvLyBjYWxsIFN1cGVyXG4gICAgICBDaGFydC5jb250cm9sbGVyc1tjaGFydFR5cGVdLnByb3RvdHlwZS5pbml0aWFsaXplLmNhbGwodGhpcywgY2hhcnQsIGRhdGFzZXRJbmRleCk7XG5cbiAgICAgIHZhciBvcHRpb25zID0gY2hhcnQuY2hhcnQuY29uZmlnLm9wdGlvbnM7XG4gICAgICBvcHRpb25zLmVycm9yRGlyID0gb3B0aW9ucy5lcnJvckRpciB8fCBDaGFydC5kZWZhdWx0c1tuZXdUeXBlXS5lcnJvckRpcjtcbiAgICAgIG9wdGlvbnMuZXJyb3JDYXBXaWR0aCA9IG9wdGlvbnMuZXJyb3JDYXBXaWR0aCB8fCBDaGFydC5kZWZhdWx0c1tuZXdUeXBlXS5lcnJvckNhcFdpZHRoO1xuICAgICAgb3B0aW9ucy5lcnJvckNhcEhlaWdodCA9IG9wdGlvbnMuZXJyb3JDYXBIZWlnaHQgfHwgQ2hhcnQuZGVmYXVsdHNbbmV3VHlwZV0uZXJyb3JDYXBIZWlnaHQ7XG4gICAgICBvcHRpb25zLmVycm9yU3Ryb2tlQ29sb3IgPSBvcHRpb25zLmVycm9yQ29sb3IgfHwgQ2hhcnQuZGVmYXVsdHNbbmV3VHlwZV0uZXJyb3JDb2xvcjtcbiAgICAgIG9wdGlvbnMuZXJyb3JTdHJva2VXaWR0aCA9IG9wdGlvbnMuZXJyb3JTdHJva2VXaWR0aCB8fCBDaGFydC5kZWZhdWx0c1tuZXdUeXBlXS5lcnJvclN0cm9rZVdpZHRoO1xuICAgIH0sXG5cbiAgICBhZGRFbGVtZW50czogZnVuY3Rpb24gKCkge1xuICAgICAgLy8gY2FsbCBTdXBlclxuICAgICAgQ2hhcnQuY29udHJvbGxlcnNbY2hhcnRUeXBlXS5wcm90b3R5cGUuYWRkRWxlbWVudHMuY2FsbCh0aGlzKTtcblxuICAgICAgdmFyIG1ldGEgPSB0aGlzLmdldE1ldGEoKTtcbiAgICAgIHZhciBlcnJvciA9IHRoaXMuZ2V0RGF0YXNldCgpLmVycm9yIHx8IFtdO1xuICAgICAgdmFyIG1ldGFFcnJvciA9IG1ldGEuZXJyb3IgfHwgW107XG4gICAgICB2YXIgaSwgaWxlbjtcblxuICAgICAgZm9yIChpID0gMCwgaWxlbiA9IGVycm9yLmxlbmd0aDsgaSA8IGlsZW47IGkrKykge1xuICAgICAgICBtZXRhRXJyb3JbaV0gPSBtZXRhRXJyb3JbaV0gfHwgbmV3IENoYXJ0LmVsZW1lbnRzLkVycm9yQmFyKHtcbiAgICAgICAgICBfY2hhcnQ6IHRoaXMuY2hhcnQuY2hhcnQsXG4gICAgICAgICAgX2RhdGFzZXRJbmRleDogdGhpcy5pbmRleCxcbiAgICAgICAgICBfaW5kZXg6IGlcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBtZXRhLmVycm9yID0gbWV0YUVycm9yO1xuICAgIH0sXG5cbiAgICBhZGRFbGVtZW50QW5kUmVzZXQ6IGZ1bmN0aW9uIChpbmRleCkge1xuICAgICAgLy8gY2FsbCBTdXBlclxuICAgICAgQ2hhcnQuY29udHJvbGxlcnNbY2hhcnRUeXBlXS5wcm90b3R5cGUuYWRkRWxlbWVudEFuZFJlc2V0LmNhbGwodGhpcywgaW5kZXgpO1xuXG4gICAgICB2YXIgbWV0YSA9IHRoaXMuZ2V0TWV0YSgpO1xuICAgICAgdmFyIG1ldGFFcnJvciA9IG1ldGEuZXJyb3I7XG4gICAgICB2YXIgbWV0YURhdGEgPSBtZXRhLmRhdGE7XG5cbiAgICAgIG1ldGFFcnJvcltpbmRleF0gPSBtZXRhRXJyb3JbaW5kZXhdIHx8IG5ldyBDaGFydC5lbGVtZW50cy5FcnJvckJhcih7XG4gICAgICAgIF9jaGFydDogdGhpcy5jaGFydC5jaGFydCxcbiAgICAgICAgX2RhdGFzZXRJbmRleDogdGhpcy5pbmRleCxcbiAgICAgICAgX2luZGV4OiBpbmRleCxcbiAgICAgICAgeDogMCxcbiAgICAgICAgeTogMFxuICAgICAgfSk7XG4gICAgICB0aGlzLnVwZGF0ZUVycm9yQmFyKG1ldGFFcnJvcltpbmRleF0sIG1ldGFEYXRhW2luZGV4XSwgaW5kZXgsIHRydWUpO1xuICAgIH0sXG5cbiAgICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSAocmVzZXQpIHtcbiAgICAgIC8vIGNhbGwgU3VwZXJcbiAgICAgIENoYXJ0LmNvbnRyb2xsZXJzW2NoYXJ0VHlwZV0ucHJvdG90eXBlLnVwZGF0ZS5jYWxsKHRoaXMsIHJlc2V0KTtcblxuICAgICAgdmFyIG1ldGEgPSB0aGlzLmdldE1ldGEoKTtcbiAgICAgIHZhciBtZXRhRGF0YSA9IG1ldGEuZGF0YTtcbiAgICAgIHZhciBtZXRhRXJyb3IgPSBtZXRhLmVycm9yO1xuXG4gICAgICAvLyBtYWtlIHN1cmUgd2UgZG9uJ3QgaGF2ZSBtb3JlIGVycm9yIGJhcnMgdGhhbiBwb2ludHNcbiAgICAgIHZhciBjdXQgPSBtZXRhRXJyb3IubGVuZ3RoIC0gbWV0YURhdGEubGVuZ3RoO1xuICAgICAgaWYgKGN1dCA+IDApIHtcbiAgICAgICAgbWV0YUVycm9yLnNwbGljZShtZXRhRGF0YS5sZW5ndGgsIGN1dCk7XG4gICAgICB9XG5cbiAgICAgIG1ldGFFcnJvci5mb3JFYWNoKGZ1bmN0aW9uIChlcnJvckJhciwgaW5kZXgpIHtcbiAgICAgICAgdGhpcy51cGRhdGVFcnJvckJhcihlcnJvckJhciwgbWV0YURhdGFbaW5kZXhdLCBpbmRleCwgcmVzZXQpO1xuICAgICAgfSwgdGhpcyk7XG4gICAgfSxcblxuICAgIHVwZGF0ZUVycm9yQmFyOiBmdW5jdGlvbiB1cGRhdGVFcnJvckJhciAoZXJyb3JCYXIsIGVsZW1lbnQsIGluZGV4LCByZXNldCkge1xuICAgICAgdmFyIGRhdGFzZXQgPSB0aGlzLmdldERhdGFzZXQoKTtcbiAgICAgIHZhciBtZXRhID0gdGhpcy5nZXRNZXRhKCk7XG4gICAgICB2YXIgeFNjYWxlID0gdGhpcy5nZXRTY2FsZUZvcklkKG1ldGEueEF4aXNJRCk7XG4gICAgICB2YXIgeVNjYWxlID0gdGhpcy5nZXRTY2FsZUZvcklkKG1ldGEueUF4aXNJRCk7XG5cbiAgICAgIHZhciBvcHRpb25zID0gdGhpcy5jaGFydC5jaGFydC5jb25maWcub3B0aW9ucztcblxuICAgICAgdmFyIHB4ID0gZWxlbWVudC5fbW9kZWwueDtcbiAgICAgIHZhciBweSA9IGVsZW1lbnQuX21vZGVsLnk7XG5cbiAgICAgIHZhciB4ID0geFNjYWxlLmdldFZhbHVlRm9yUGl4ZWwocHgpO1xuICAgICAgdmFyIHkgPSB5U2NhbGUuZ2V0VmFsdWVGb3JQaXhlbChweSk7XG5cbiAgICAgIHZhciBlcnJvclg7XG4gICAgICB2YXIgZXJyb3JZO1xuICAgICAgaWYgKHR5cGVvZiBkYXRhc2V0LmVycm9yW2luZGV4XSA9PT0gJ29iamVjdCcgJiYgZGF0YXNldC5lcnJvcltpbmRleF0gIT0gbnVsbCkge1xuICAgICAgICBlcnJvclggPSBkYXRhc2V0LmVycm9yW2luZGV4XS54O1xuICAgICAgICBlcnJvclkgPSBkYXRhc2V0LmVycm9yW2luZGV4XS55O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3JYID0gZGF0YXNldC5lcnJvcltpbmRleF07XG4gICAgICAgIGVycm9yWSA9IGRhdGFzZXQuZXJyb3JbaW5kZXhdO1xuICAgICAgfVxuXG4gICAgICAvLyBVdGlsaXR5XG4gICAgICBlcnJvckJhci5fY2hhcnQgPSB0aGlzLmNoYXJ0LmNoYXJ0O1xuICAgICAgZXJyb3JCYXIuX3hTY2FsZSA9IHhTY2FsZTtcbiAgICAgIGVycm9yQmFyLl95U2NhbGUgPSB5U2NhbGU7XG4gICAgICBlcnJvckJhci5fZGF0YXNldEluZGV4ID0gdGhpcy5pbmRleDtcbiAgICAgIGVycm9yQmFyLl9pbmRleCA9IGluZGV4O1xuXG4gICAgICBlcnJvckJhci5fbW9kZWwgPSB7XG4gICAgICAgIC8vIFBvc2l0aW9uXG4gICAgICAgIHg6IHB4LFxuICAgICAgICB5OiBweSxcbiAgICAgICAgeVRvcDogeVNjYWxlLmdldFBpeGVsRm9yVmFsdWUoeSArIGVycm9yWSwgaW5kZXgsIHRoaXMuaW5kZXgsIHRoaXMuY2hhcnQuaXNDb21ibyksXG4gICAgICAgIHlCb3R0b206IHlTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHkgLSBlcnJvclksIGluZGV4LCB0aGlzLmluZGV4LCB0aGlzLmNoYXJ0LmlzQ29tYm8pLFxuICAgICAgICB4TGVmdDogeFNjYWxlLmdldFBpeGVsRm9yVmFsdWUoeCAtIGVycm9yWCwgaW5kZXgsIHRoaXMuaW5kZXgsIHRoaXMuY2hhcnQuaXNDb21ibyksXG4gICAgICAgIHhSaWdodDogeFNjYWxlLmdldFBpeGVsRm9yVmFsdWUoeCArIGVycm9yWCwgaW5kZXgsIHRoaXMuaW5kZXgsIHRoaXMuY2hhcnQuaXNDb21ibyksXG5cbiAgICAgICAgLy8gQXBwZWFyYW5jZVxuICAgICAgICBjYXBXaWR0aDogZWxlbWVudC5fbW9kZWwud2lkdGggKiBvcHRpb25zLmVycm9yQ2FwV2lkdGggfHwgb3B0aW9ucy5lcnJvckNhcFdpZHRoLFxuICAgICAgICBjYXBIZWlnaHQ6IGVsZW1lbnQuX21vZGVsLmhlaWdodCAqIG9wdGlvbnMuZXJyb3JDYXBIZWlnaHQgfHwgb3B0aW9ucy5lcnJvckNhcEhlaWdodCxcbiAgICAgICAgZGlyZWN0aW9uOiBvcHRpb25zLmVycm9yRGlyLFxuICAgICAgICBzdHJva2VDb2xvcjogb3B0aW9ucy5lcnJvclN0cm9rZUNvbG9yLFxuICAgICAgICBzdHJva2VXaWR0aDogb3B0aW9ucy5lcnJvclN0cm9rZVdpZHRoXG4gICAgICB9O1xuXG4gICAgICBlcnJvckJhci5waXZvdCgpO1xuICAgIH0sXG5cbiAgICBkcmF3OiBmdW5jdGlvbiAoZWFzZSkge1xuICAgICAgdmFyIGVhc2luZ0RlY2ltYWwgPSBlYXNlIHx8IDE7XG5cbiAgICAgIC8vIGNhbGwgU3VwZXJcbiAgICAgIENoYXJ0LmNvbnRyb2xsZXJzW2NoYXJ0VHlwZV0ucHJvdG90eXBlLmRyYXcuY2FsbCh0aGlzLCBlYXNlKTtcblxuICAgICAgdGhpcy5nZXRNZXRhKCkuZXJyb3IuZm9yRWFjaChmdW5jdGlvbiAoZXJyb3JCYXIsIGluZGV4KSB7XG4gICAgICAgIC8vIENoZWNoIGZvciB2YWxpZCBlcnJyb3IgYmFyIHNpemVzOlxuICAgICAgICAvLyAyLWQgZGF0YXN0cnVjdHVyZTogY2hlY2sgZXJyb3IueCBhbmQgZXJyb3IueVxuICAgICAgICAvLyAxLWQgZGF0YXN0cnVjdHVyZTogY2hlY2sgZXJyb3JcbiAgICAgICAgdmFyIGUgPSB0aGlzLmdldERhdGFzZXQoKS5lcnJvcltpbmRleF07XG5cbiAgICAgICAgaWYgKGUgIT09IG51bGwgJiYgdHlwZW9mIGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgaWYgKChlLnggIT09IG51bGwgJiYgZS54ICE9PSB1bmRlZmluZWQgJiYgIWlzTmFOKGUueCkpIHx8IChlLnkgIT09IG51bGwgJiYgZS55ICE9PSB1bmRlZmluZWQgJiYgIWlzTmFOKGUueSkpKSB7XG4gICAgICAgICAgICBlcnJvckJhci50cmFuc2l0aW9uKGVhc2luZ0RlY2ltYWwpLmRyYXcoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZSAhPT0gbnVsbCAmJiBlICE9PSB1bmRlZmluZWQgJiYgIWlzTmFOKGUpICYmIGUgIT09IDApIHtcbiAgICAgICAgICBlcnJvckJhci50cmFuc2l0aW9uKGVhc2luZ0RlY2ltYWwpLmRyYXcoKTtcbiAgICAgICAgfVxuICAgICAgfSwgdGhpcyk7XG4gICAgfVxuICB9KTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBdkRBO0FBMERBOzs7Ozs7Ozs7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQTtBQUNBO0FBUUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBT0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBZEE7QUFpQkE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBNUlBO0FBOElBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///ee83\n")},f2bc:function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\n\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\nvar widgetEntry = AmpersandModel.extend({\n  props: {\n    modelType: {\n      type: 'string',\n      required: true\n    },\n    newModel: {\n      type: 'any',\n      required: true\n    }\n  }\n});\nvar WidgetCollection = Collection.extend({\n  model: widgetEntry,\n  mainIndex: 'modelType'\n});\n/**\n * A collection of Ampersand widget containing all available chart types\n * @module widgets/widget-factory\n */\n\nmodule.exports.widgets = new WidgetCollection([{\n  modelType: 'piechart',\n  newModel: __webpack_require__(/*! ./models/piechart */ \"2413\")\n}, {\n  modelType: 'horizontalbarchart',\n  newModel: __webpack_require__(/*! ./models/horizontalbarchart */ \"1c81\")\n}, {\n  modelType: 'barchart',\n  newModel: __webpack_require__(/*! ./models/barchart */ \"6535\")\n}, {\n  modelType: 'linechart',\n  newModel: __webpack_require__(/*! ./models/linechart */ \"9cb1\")\n}, {\n  modelType: 'radarchart',\n  newModel: __webpack_require__(/*! ./models/radarchart */ \"0b9d\")\n}, {\n  modelType: 'bubbleplot',\n  newModel: __webpack_require__(/*! ./models/bubbleplot */ \"71a3\")\n}, {\n  modelType: 'scatterchart',\n  newModel: __webpack_require__(/*! ./models/scatter */ \"37f6\")\n}, {\n  modelType: 'networkchart',\n  newModel: __webpack_require__(/*! ./models/sigma */ \"8f0f\") // Register new widgets here\n\n}]);\n/**\n * Create a new Ampersand model for a widget\n * @param {Object} attrs - Used for initialization of model properties, passed on to the model constructor.\n * @param {Object} options - passed on to the model constructor, see https://github.com/AmpersandJS/ampersand-model#constructorinitialize-new-extendedampersandmodelattrs-options\n * @returns {Model} widget - An Ampersand model representing the widget\n */\n\nmodule.exports.newModel = function newModel(attrs, options) {\n  var model;\n  var entry = module.exports.widgets.get(attrs.modelType);\n  var constructor = entry.newModel;\n  model = new constructor(attrs, options);\n  model.modelType = attrs.modelType;\n  return model;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZjJiYy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL3dpZGdldC1mYWN0b3J5LmpzP2Y0M2EiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIENvbGxlY3Rpb24gPSByZXF1aXJlKCdhbXBlcnNhbmQtY29sbGVjdGlvbicpO1xudmFyIEFtcGVyc2FuZE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG5cbnZhciB3aWRnZXRFbnRyeSA9IEFtcGVyc2FuZE1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgbW9kZWxUeXBlOiB7dHlwZTogJ3N0cmluZycsIHJlcXVpcmVkOiB0cnVlfSxcbiAgICBuZXdNb2RlbDoge3R5cGU6ICdhbnknLCByZXF1aXJlZDogdHJ1ZX1cbiAgfVxufSk7XG5cbnZhciBXaWRnZXRDb2xsZWN0aW9uID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogd2lkZ2V0RW50cnksXG4gIG1haW5JbmRleDogJ21vZGVsVHlwZSdcbn0pO1xuXG4vKipcbiAqIEEgY29sbGVjdGlvbiBvZiBBbXBlcnNhbmQgd2lkZ2V0IGNvbnRhaW5pbmcgYWxsIGF2YWlsYWJsZSBjaGFydCB0eXBlc1xuICogQG1vZHVsZSB3aWRnZXRzL3dpZGdldC1mYWN0b3J5XG4gKi9cbm1vZHVsZS5leHBvcnRzLndpZGdldHMgPSBuZXcgV2lkZ2V0Q29sbGVjdGlvbihbXG4gIHtcbiAgICBtb2RlbFR5cGU6ICdwaWVjaGFydCcsXG4gICAgbmV3TW9kZWw6IHJlcXVpcmUoJy4vbW9kZWxzL3BpZWNoYXJ0JylcbiAgfSxcbiAge1xuICAgIG1vZGVsVHlwZTogJ2hvcml6b250YWxiYXJjaGFydCcsXG4gICAgbmV3TW9kZWw6IHJlcXVpcmUoJy4vbW9kZWxzL2hvcml6b250YWxiYXJjaGFydCcpXG4gIH0sXG4gIHtcbiAgICBtb2RlbFR5cGU6ICdiYXJjaGFydCcsXG4gICAgbmV3TW9kZWw6IHJlcXVpcmUoJy4vbW9kZWxzL2JhcmNoYXJ0JylcbiAgfSxcbiAge1xuICAgIG1vZGVsVHlwZTogJ2xpbmVjaGFydCcsXG4gICAgbmV3TW9kZWw6IHJlcXVpcmUoJy4vbW9kZWxzL2xpbmVjaGFydCcpXG4gIH0sXG4gIHtcbiAgICBtb2RlbFR5cGU6ICdyYWRhcmNoYXJ0JyxcbiAgICBuZXdNb2RlbDogcmVxdWlyZSgnLi9tb2RlbHMvcmFkYXJjaGFydCcpXG4gIH0sXG4gIHtcbiAgICBtb2RlbFR5cGU6ICdidWJibGVwbG90JyxcbiAgICBuZXdNb2RlbDogcmVxdWlyZSgnLi9tb2RlbHMvYnViYmxlcGxvdCcpXG4gIH0sXG4gIHtcbiAgICBtb2RlbFR5cGU6ICdzY2F0dGVyY2hhcnQnLFxuICAgIG5ld01vZGVsOiByZXF1aXJlKCcuL21vZGVscy9zY2F0dGVyJylcbiAgfSxcbiAge1xuICAgIG1vZGVsVHlwZTogJ25ldHdvcmtjaGFydCcsXG4gICAgbmV3TW9kZWw6IHJlcXVpcmUoJy4vbW9kZWxzL3NpZ21hJylcbiAgfVxuICAvLyBSZWdpc3RlciBuZXcgd2lkZ2V0cyBoZXJlXG5dKTtcblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgQW1wZXJzYW5kIG1vZGVsIGZvciBhIHdpZGdldFxuICogQHBhcmFtIHtPYmplY3R9IGF0dHJzIC0gVXNlZCBmb3IgaW5pdGlhbGl6YXRpb24gb2YgbW9kZWwgcHJvcGVydGllcywgcGFzc2VkIG9uIHRvIHRoZSBtb2RlbCBjb25zdHJ1Y3Rvci5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gcGFzc2VkIG9uIHRvIHRoZSBtb2RlbCBjb25zdHJ1Y3Rvciwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9BbXBlcnNhbmRKUy9hbXBlcnNhbmQtbW9kZWwjY29uc3RydWN0b3Jpbml0aWFsaXplLW5ldy1leHRlbmRlZGFtcGVyc2FuZG1vZGVsYXR0cnMtb3B0aW9uc1xuICogQHJldHVybnMge01vZGVsfSB3aWRnZXQgLSBBbiBBbXBlcnNhbmQgbW9kZWwgcmVwcmVzZW50aW5nIHRoZSB3aWRnZXRcbiAqL1xubW9kdWxlLmV4cG9ydHMubmV3TW9kZWwgPSBmdW5jdGlvbiBuZXdNb2RlbCAoYXR0cnMsIG9wdGlvbnMpIHtcbiAgdmFyIG1vZGVsO1xuICB2YXIgZW50cnkgPSBtb2R1bGUuZXhwb3J0cy53aWRnZXRzLmdldChhdHRycy5tb2RlbFR5cGUpO1xuICB2YXIgY29uc3RydWN0b3IgPSBlbnRyeS5uZXdNb2RlbDtcbiAgbW9kZWwgPSBuZXcgY29uc3RydWN0b3IoYXR0cnMsIG9wdGlvbnMpO1xuICBtb2RlbC5tb2RlbFR5cGUgPSBhdHRycy5tb2RlbFR5cGU7XG5cbiAgcmV0dXJuIG1vZGVsO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUZBO0FBREE7QUFPQTtBQUNBO0FBQ0E7QUFGQTtBQUtBOzs7OztBQUlBO0FBRUE7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUNBO0FBSEE7QUFPQTs7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///f2bc\n")},f3d5:function(module,exports,__webpack_require__){eval("var Spot = __webpack_require__(/*! spot-framework */ \"3b07\");\n\nvar timeUtil = Spot.util.time;\n\nvar View = __webpack_require__(/*! ampersand-view */ \"2883\"); // this.model should be a DatetimeTransform or DurationTransform\n\n\nvar TimeZoneView = View.extend({\n  template: '<option data-hook=\"option\"> </option>',\n  render: function render() {\n    this.renderWithTemplate(this);\n  },\n  bindings: {\n    'model.description': {\n      hook: 'option',\n      type: 'text'\n    },\n    'model.format': {\n      hook: 'option',\n      type: 'attribute',\n      name: 'value'\n    }\n  }\n});\nmodule.exports = View.extend({\n  template: '<select data-hook=\"options\"> </select>',\n  initialize: function initialize(options) {\n    this.field = options.field;\n  },\n  render: function render() {\n    this.renderWithTemplate(this);\n    this.renderCollection(timeUtil.timeZones, TimeZoneView, this.queryByHook('options'));\n    var value = this.model[this.field];\n    this.queryByHook('options').value = value;\n  },\n  events: {\n    'change [data-hook=\"options\"]': 'changeTimeZone'\n  },\n  changeTimeZone: function changeTimeZone() {\n    var value = this.queryByHook('options').value;\n    this.model[this.field] = value;\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZjNkNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZmFjZXQvdGltZS16b25lcy1zZWxlY3QuanM/ZDY4YiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgU3BvdCA9IHJlcXVpcmUoJ3Nwb3QtZnJhbWV3b3JrJyk7XG52YXIgdGltZVV0aWwgPSBTcG90LnV0aWwudGltZTtcbnZhciBWaWV3ID0gcmVxdWlyZSgnYW1wZXJzYW5kLXZpZXcnKTtcblxuLy8gdGhpcy5tb2RlbCBzaG91bGQgYmUgYSBEYXRldGltZVRyYW5zZm9ybSBvciBEdXJhdGlvblRyYW5zZm9ybVxuXG52YXIgVGltZVpvbmVWaWV3ID0gVmlldy5leHRlbmQoe1xuICB0ZW1wbGF0ZTogJzxvcHRpb24gZGF0YS1ob29rPVwib3B0aW9uXCI+IDwvb3B0aW9uPicsXG4gIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVuZGVyV2l0aFRlbXBsYXRlKHRoaXMpO1xuICB9LFxuICBiaW5kaW5nczoge1xuICAgICdtb2RlbC5kZXNjcmlwdGlvbic6IHtcbiAgICAgIGhvb2s6ICdvcHRpb24nLFxuICAgICAgdHlwZTogJ3RleHQnXG4gICAgfSxcbiAgICAnbW9kZWwuZm9ybWF0Jzoge1xuICAgICAgaG9vazogJ29wdGlvbicsXG4gICAgICB0eXBlOiAnYXR0cmlidXRlJyxcbiAgICAgIG5hbWU6ICd2YWx1ZSdcbiAgICB9XG4gIH1cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZXcuZXh0ZW5kKHtcbiAgdGVtcGxhdGU6ICc8c2VsZWN0IGRhdGEtaG9vaz1cIm9wdGlvbnNcIj4gPC9zZWxlY3Q+JyxcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICB0aGlzLmZpZWxkID0gb3B0aW9ucy5maWVsZDtcbiAgfSxcbiAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZW5kZXJXaXRoVGVtcGxhdGUodGhpcyk7XG4gICAgdGhpcy5yZW5kZXJDb2xsZWN0aW9uKHRpbWVVdGlsLnRpbWVab25lcywgVGltZVpvbmVWaWV3LCB0aGlzLnF1ZXJ5QnlIb29rKCdvcHRpb25zJykpO1xuXG4gICAgdmFyIHZhbHVlID0gdGhpcy5tb2RlbFt0aGlzLmZpZWxkXTtcbiAgICB0aGlzLnF1ZXJ5QnlIb29rKCdvcHRpb25zJykudmFsdWUgPSB2YWx1ZTtcbiAgfSxcbiAgZXZlbnRzOiB7XG4gICAgJ2NoYW5nZSBbZGF0YS1ob29rPVwib3B0aW9uc1wiXSc6ICdjaGFuZ2VUaW1lWm9uZSdcbiAgfSxcbiAgY2hhbmdlVGltZVpvbmU6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLnF1ZXJ5QnlIb29rKCdvcHRpb25zJykudmFsdWU7XG4gICAgdGhpcy5tb2RlbFt0aGlzLmZpZWxkXSA9IHZhbHVlO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFMQTtBQUxBO0FBa0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQWxCQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///f3d5\n")},f77a:function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nmodule.exports = View.extend({\n  template: templates.configureFacet.facetTransformContinuous,\n  bindings: {\n    'model.isNone': {\n      type: 'booleanAttribute',\n      hook: 'define-transform-none',\n      name: 'checked'\n    },\n    'model.isPercentiles': {\n      type: 'booleanAttribute',\n      hook: 'define-transform-percentiles',\n      name: 'checked'\n    }\n  },\n  events: {\n    'click [data-hook~=define-transform-percentiles]': function clickDataHookDefineTransformPercentiles() {\n      this.model.clear();\n      this.model.setPercentiles();\n    },\n    'click [data-hook~=define-transform-none]': function clickDataHookDefineTransformNone() {\n      this.model.clear();\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZjc3YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtZmFjZXQvZmFjZXQtdHJhbnNmb3JtLWNvbnRpbnVvdXMuanM/NDgyNCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgVmlldyA9IHJlcXVpcmUoJ2FtcGVyc2FuZC12aWV3Jyk7XG52YXIgdGVtcGxhdGVzID0gcmVxdWlyZSgnLi4vLi4vdGVtcGxhdGVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gVmlldy5leHRlbmQoe1xuICB0ZW1wbGF0ZTogdGVtcGxhdGVzLmNvbmZpZ3VyZUZhY2V0LmZhY2V0VHJhbnNmb3JtQ29udGludW91cyxcbiAgYmluZGluZ3M6IHtcbiAgICAnbW9kZWwuaXNOb25lJzoge1xuICAgICAgdHlwZTogJ2Jvb2xlYW5BdHRyaWJ1dGUnLFxuICAgICAgaG9vazogJ2RlZmluZS10cmFuc2Zvcm0tbm9uZScsXG4gICAgICBuYW1lOiAnY2hlY2tlZCdcbiAgICB9LFxuICAgICdtb2RlbC5pc1BlcmNlbnRpbGVzJzoge1xuICAgICAgdHlwZTogJ2Jvb2xlYW5BdHRyaWJ1dGUnLFxuICAgICAgaG9vazogJ2RlZmluZS10cmFuc2Zvcm0tcGVyY2VudGlsZXMnLFxuICAgICAgbmFtZTogJ2NoZWNrZWQnXG4gICAgfVxuICB9LFxuICBldmVudHM6IHtcbiAgICAnY2xpY2sgW2RhdGEtaG9va349ZGVmaW5lLXRyYW5zZm9ybS1wZXJjZW50aWxlc10nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLmNsZWFyKCk7XG4gICAgICB0aGlzLm1vZGVsLnNldFBlcmNlbnRpbGVzKCk7XG4gICAgfSxcbiAgICAnY2xpY2sgW2RhdGEtaG9va349ZGVmaW5lLXRyYW5zZm9ybS1ub25lXSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMubW9kZWwuY2xlYXIoKTtcbiAgICB9XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBTkE7QUFZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUEE7QUFkQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///f77a\n")},faa4:function(module,exports,__webpack_require__){eval("var View = __webpack_require__(/*! ampersand-view */ \"2883\");\n\nvar templates = __webpack_require__(/*! ../../templates */ \"4324\");\n\nmodule.exports = View.extend({\n  template: templates.configurePartition.partitionText,\n  bindings: {\n    'model.isText': {\n      type: 'toggle',\n      hook: 'group-text-panel'\n    }\n  },\n  events: {\n    'click [data-hook~=group-order-count]': function clickDataHookGroupOrderCount() {\n      this.model.ordering = 'count';\n      this.parent.resetFilter = true;\n    },\n    'click [data-hook~=group-order-abc]': function clickDataHookGroupOrderAbc() {\n      this.model.ordering = 'value';\n      this.parent.resetFilter = true;\n    }\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFhNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9wYWdlcy9jb25maWd1cmUtcGFydGl0aW9uL3BhcnRpdGlvbi10ZXh0LmpzPzdhOGYiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFZpZXcgPSByZXF1aXJlKCdhbXBlcnNhbmQtdmlldycpO1xudmFyIHRlbXBsYXRlcyA9IHJlcXVpcmUoJy4uLy4uL3RlbXBsYXRlcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZXcuZXh0ZW5kKHtcbiAgdGVtcGxhdGU6IHRlbXBsYXRlcy5jb25maWd1cmVQYXJ0aXRpb24ucGFydGl0aW9uVGV4dCxcbiAgYmluZGluZ3M6IHtcbiAgICAnbW9kZWwuaXNUZXh0Jzoge1xuICAgICAgdHlwZTogJ3RvZ2dsZScsXG4gICAgICBob29rOiAnZ3JvdXAtdGV4dC1wYW5lbCdcbiAgICB9XG4gIH0sXG4gIGV2ZW50czoge1xuICAgICdjbGljayBbZGF0YS1ob29rfj1ncm91cC1vcmRlci1jb3VudF0nOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLm1vZGVsLm9yZGVyaW5nID0gJ2NvdW50JztcbiAgICAgIHRoaXMucGFyZW50LnJlc2V0RmlsdGVyID0gdHJ1ZTtcbiAgICB9LFxuICAgICdjbGljayBbZGF0YS1ob29rfj1ncm91cC1vcmRlci1hYmNdJzogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5tb2RlbC5vcmRlcmluZyA9ICd2YWx1ZSc7XG4gICAgICB0aGlzLnBhcmVudC5yZXNldEZpbHRlciA9IHRydWU7XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQURBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUkE7QUFSQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///faa4\n")},fdc1:function(module,exports,__webpack_require__){eval("var app = __webpack_require__(/*! ampersand-app */ \"fcbc\");\n\nvar Spot = __webpack_require__(/*! spot-framework */ \"3b07\");\n\nvar BaseWidget = __webpack_require__(/*! ./base-widget */ \"26ef\");\n\nvar Chart = __webpack_require__(/*! chart.js */ \"70b5\");\n\nvar colors = __webpack_require__(/*! ../../colors */ \"eb63\");\n\nvar misval = Spot.util.misval;\n\nvar util = __webpack_require__(/*! ./util */ \"2b41\");\n\nvar BUBBLE_ALPHA = 0.5;\nvar MAX_BUBBLE_SIZE = 50; // in pixels\n\nvar MIN_BUBBLE_SIZE = 5; // in pixels\n\nfunction normalizeGroup(data, key) {\n  var norm;\n  var min = Number.MAX_VALUE;\n  var max = -min;\n  data.forEach(function (group) {\n    if (group.count !== 0) {\n      var val = parseFloat(group[key]) || 0;\n\n      if (val !== misval) {\n        min = min <= val ? min : val;\n        max = max >= val ? max : val;\n      }\n    }\n  });\n\n  if (min === Number.MAX_VALUE) {\n    // no data, no normalization\n    norm = function norm(v) {\n      return 1;\n    };\n  } else if (min < 0 && max > 0) {\n    // bubble radius should always be positive,\n    // so take abs, and normalize by largest of |min| and max\n    min = Math.abs(min);\n    max = max < min ? min : max;\n\n    norm = function norm(v) {\n      return Math.abs(v) / max;\n    };\n  } else if (max > 0 && min >= 0 || max <= 0 && min < 0) {\n    // linear map v from [min, max] to [0,1]\n    norm = function norm(v) {\n      return (v - min) / (max - min);\n    };\n  } else {\n    // not sure if ever reached\n    norm = function norm(v) {\n      return 1;\n    };\n  }\n\n  return norm;\n}\n\nfunction _deinitChart(view) {\n  if (view._chartjs) {\n    view._chartjs.destroy();\n\n    delete view._chartjs;\n  }\n\n  delete view._config;\n  var canvas = view.queryByHook('canvas');\n\n  if (canvas) {\n    view.el.removeChild(canvas);\n  }\n\n  view.isInitialized = false;\n}\n\nfunction _initChart(view) {\n  // Configure plot\n  view._config = view.model.chartjsConfig();\n  var options = view._config.options;\n  var filter = view.model.filter;\n  var partition;\n  var canSelect = true; // configure x-axis\n\n  partition = filter.partitions.get(1, 'rank');\n\n  if (partition.isDatetime) {\n    options.scales.xAxes[0].type = 'time';\n  } else if (partition.isDuration) {\n    options.scales.xAxes[0].type = 'spot-duration';\n  } else if (partition.isContinuous) {\n    if (partition.groupLog) {\n      options.scales.xAxes[0].type = 'logarithmic';\n    } else {\n      options.scales.xAxes[0].type = 'linear';\n    }\n  } else {\n    canSelect = false;\n  }\n\n  options.scales.xAxes[0].scaleLabel = {\n    display: partition.showLabel,\n    labelString: partition.label\n  }; // configure y-axis\n\n  partition = filter.partitions.get(2, 'rank');\n\n  if (partition.isDatetime) {\n    options.scales.yAxes[0].type = 'time';\n  } else if (partition.isDuration) {\n    options.scales.yAxes[0].type = 'spot-duration';\n  } else if (partition.isContinuous) {\n    if (partition.groupLog) {\n      options.scales.yAxes[0].type = 'logarithmic';\n    } else {\n      options.scales.yAxes[0].type = 'linear';\n    }\n  } else {\n    canSelect = false;\n  }\n\n  options.scales.yAxes[0].scaleLabel = {\n    display: partition.showLabel,\n    labelString: partition.label\n  }; // title\n\n  options.title.text = view.model.getTitle(); // user interaction\n\n  if (canSelect) {\n    options.onClick = function (ev, elements) {\n      var partitionA = filter.partitions.get(1, 'rank');\n      var partitionB = filter.partitions.get(2, 'rank');\n\n      if (elements && elements[0]) {\n        // get the clicked-on bubble\n        var index = elements[0]._index;\n        var point = view._config.data.datasets[0].data[index]; // update selection on x-axis\n\n        var groupx = partitionA.groups.models[point.i];\n        partitionA.updateSelection(groupx); // update selection on y-axis\n\n        var groupy = partitionB.groups.models[point.j];\n        partitionB.updateSelection(groupy);\n        view.model.filter.updateDataFilter();\n        app.me.dataview.getData();\n      }\n    };\n  } // force a square full size plot\n\n\n  var width = view.el.offsetWidth;\n  var height = view.el.offsetHeight;\n  var canvas = document.createElement('canvas');\n  canvas.setAttribute('data-hook', 'canvas');\n  view.el.appendChild(canvas);\n  var ctx = canvas.getContext('2d');\n  ctx.canvas.width = width;\n  ctx.canvas.height = height; // Create Chartjs object\n\n  view._chartjs = new Chart(ctx, view._config); // In callbacks on the chart we will need the view, so store a reference\n\n  view._chartjs._Ampersandview = view;\n  view.isInitialized = true;\n}\n\nfunction _update(view) {\n  if (!view.isInitialized) {\n    return;\n  } // Add our data to the plot\n\n\n  updateBubbles(view); // Hand over to Chartjs for actual plotting\n\n  view._chartjs.update();\n}\n\nfunction updateBubbles(view) {\n  var filter = view.model.filter;\n  var chartData = view._config.data;\n  var partitionA = filter.partitions.get(1, 'rank');\n  var partitionB = filter.partitions.get(2, 'rank');\n  chartData.datasets = chartData.datasets || [];\n  chartData.datasets[0] = chartData.datasets[0] || {\n    data: [],\n    error: [],\n    backgroundColor: []\n  }; // find facet names for tooltips\n\n  chartData.datasets[0].spotAxes = {\n    x: partitionA.label,\n    y: partitionB.label\n  };\n  var aggregate;\n  var bubbleColorFn; // normalization function for bubble color\n\n  var bubbleRadiusFn; // normalization function for bubble radius\n\n  var errorXFn;\n  var errorYFn;\n  aggregate = filter.aggregates.get(1, 'rank');\n\n  if (aggregate) {\n    bubbleColorFn = normalizeGroup(filter.data, 'aa');\n    chartData.datasets[0].spotAxes.c = aggregate.operation + ' ' + aggregate.label;\n  }\n\n  aggregate = filter.aggregates.get(2, 'rank');\n\n  if (aggregate) {\n    bubbleRadiusFn = normalizeGroup(filter.data, 'bb');\n    chartData.datasets[0].spotAxes.r = aggregate.operation + ' ' + aggregate.label;\n  }\n\n  view._config.options.errorDir = 'both';\n  aggregate = filter.aggregates.get(3, 'rank');\n\n  if (aggregate) {\n    errorXFn = function errorXFn(group) {\n      return group['cc'];\n    };\n  } else {\n    errorXFn = function errorXFn(group) {\n      return null;\n    };\n\n    view._config.options.errorDir = 'vertical';\n  }\n\n  aggregate = filter.aggregates.get(4, 'rank');\n\n  if (aggregate) {\n    errorYFn = function errorYFn(group) {\n      return group['dd'];\n    };\n  } else {\n    errorYFn = function errorYFn(group) {\n      return null;\n    };\n\n    if (view._config.options.errorDir === 'vertical') {\n      view._config.options.errorDir === 'none';\n    }\n\n    if (view._config.options.errorDir === 'both') {\n      view._config.options.errorDir === 'horizontal';\n    }\n  } // add data\n\n\n  var val;\n  var d = 0;\n  filter.data.forEach(function (group) {\n    var i = util.partitionValueToIndex(partitionA, group.a);\n    var j = util.partitionValueToIndex(partitionB, group.b);\n\n    if (i >= 0 && j >= 0 && group.aa !== misval && group.bb !== misval && group.count !== 0) {\n      // initialize if necessary\n      chartData.datasets[0].data[d] = chartData.datasets[0].data[d] || {};\n      chartData.datasets[0].error[d] = chartData.datasets[0].error[d] || {}; // update position\n\n      if (partitionA.isDatetime || partitionA.isDuration || partitionA.isContinuous) {\n        chartData.datasets[0].data[d].x = partitionA.groups.models[i].value;\n      } else {\n        chartData.datasets[0].data[d].x = i;\n      }\n\n      if (partitionB.isDatetime || partitionB.isDuration || partitionB.isContinuous) {\n        chartData.datasets[0].data[d].y = partitionB.groups.models[j].value;\n      } else {\n        chartData.datasets[0].data[d].y = j;\n      } // update error\n\n\n      chartData.datasets[0].error[d].x = errorXFn(group);\n      chartData.datasets[0].error[d].y = errorYFn(group); // update color\n\n      val = parseFloat(group.aa) || 0;\n\n      if (bubbleColorFn) {\n        chartData.datasets[0].backgroundColor[d] = colors.getColorFloat(bubbleColorFn(val)).alpha(BUBBLE_ALPHA).css();\n      } else {\n        chartData.datasets[0].backgroundColor[d] = colors.getColor(0).alpha(BUBBLE_ALPHA).css();\n      } // update radius\n\n\n      val = parseFloat(group.bb) || 0;\n\n      if (bubbleRadiusFn) {\n        chartData.datasets[0].data[d].r = Math.round(MIN_BUBBLE_SIZE + Math.sqrt(bubbleRadiusFn(val)) * (MAX_BUBBLE_SIZE - MIN_BUBBLE_SIZE));\n      } else {\n        chartData.datasets[0].data[d].r = MIN_BUBBLE_SIZE; // NOTE: in pixels\n      } // store group indexes for onClick callback\n\n\n      chartData.datasets[0].data[d].i = i;\n      chartData.datasets[0].data[d].j = j;\n      chartData.datasets[0].data[d].a = group.a;\n      chartData.datasets[0].data[d].b = group.b;\n      chartData.datasets[0].data[d].aa = group.aa;\n      chartData.datasets[0].data[d].bb = group.bb;\n      chartData.datasets[0].data[d].count = group.count;\n      d++;\n    }\n  }); // remove remaining (unused) points\n\n  var cut = chartData.datasets[0].data.length - d;\n\n  if (cut > 0) {\n    chartData.datasets[0].data.splice(d, cut);\n    chartData.datasets[0].error.splice(d, cut);\n    chartData.datasets[0].backgroundColor.splice(d, cut);\n  } // highlight selected area\n\n\n  if ((partitionA.isDatetime || partitionA.isDuration || partitionA.isContinuous) && (partitionB.isDatetime || partitionB.isDuration || partitionB.isContinuous)) {\n    if (partitionA.selected && partitionA.selected.length > 0) {\n      chartData.datasets[1] = chartData.datasets[1] || {\n        type: 'line',\n        lineTension: 0\n      };\n      chartData.datasets[1].data = [{\n        x: partitionA.selected[0],\n        y: partitionB.selected[0],\n        r: 1\n      }, {\n        x: partitionA.selected[0],\n        y: partitionB.selected[1],\n        r: 1\n      }, {\n        x: partitionA.selected[1],\n        y: partitionB.selected[1],\n        r: 1\n      }, {\n        x: partitionA.selected[1],\n        y: partitionB.selected[0],\n        r: 1\n      }, {\n        x: partitionA.selected[0],\n        y: partitionB.selected[0],\n        r: 1\n      }];\n      chartData.datasets[1].error = [null, null, null, null];\n      chartData.datasets[1].backgroundColor = colors.getColor(1).alpha(BUBBLE_ALPHA).css();\n    } else {\n      chartData.datasets.splice(1, 1);\n    }\n  }\n}\n\nmodule.exports = BaseWidget.extend({\n  template: '<div class=\"widgetInner mdl-card__media\"></div>',\n  update: function update() {\n    _update(this);\n  },\n  initChart: function initChart() {\n    _initChart(this);\n  },\n  deinitChart: function deinitChart() {\n    _deinitChart(this);\n  }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmRjMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy93aWRnZXRzL3ZpZXdzL2NoYXJ0anMyZC5qcz85MDhlIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBhcHAgPSByZXF1aXJlKCdhbXBlcnNhbmQtYXBwJyk7XG52YXIgU3BvdCA9IHJlcXVpcmUoJ3Nwb3QtZnJhbWV3b3JrJyk7XG52YXIgQmFzZVdpZGdldCA9IHJlcXVpcmUoJy4vYmFzZS13aWRnZXQnKTtcbnZhciBDaGFydCA9IHJlcXVpcmUoJ2NoYXJ0LmpzJyk7XG52YXIgY29sb3JzID0gcmVxdWlyZSgnLi4vLi4vY29sb3JzJyk7XG52YXIgbWlzdmFsID0gU3BvdC51dGlsLm1pc3ZhbDtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi91dGlsJyk7XG5cbnZhciBCVUJCTEVfQUxQSEEgPSAwLjU7XG52YXIgTUFYX0JVQkJMRV9TSVpFID0gNTA7IC8vIGluIHBpeGVsc1xudmFyIE1JTl9CVUJCTEVfU0laRSA9IDU7IC8vIGluIHBpeGVsc1xuXG5mdW5jdGlvbiBub3JtYWxpemVHcm91cCAoZGF0YSwga2V5KSB7XG4gIHZhciBub3JtO1xuICB2YXIgbWluID0gTnVtYmVyLk1BWF9WQUxVRTtcbiAgdmFyIG1heCA9IC1taW47XG4gIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICBpZiAoZ3JvdXAuY291bnQgIT09IDApIHtcbiAgICAgIHZhciB2YWwgPSBwYXJzZUZsb2F0KGdyb3VwW2tleV0pIHx8IDA7XG4gICAgICBpZiAodmFsICE9PSBtaXN2YWwpIHtcbiAgICAgICAgbWluID0gbWluIDw9IHZhbCA/IG1pbiA6IHZhbDtcbiAgICAgICAgbWF4ID0gbWF4ID49IHZhbCA/IG1heCA6IHZhbDtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGlmIChtaW4gPT09IE51bWJlci5NQVhfVkFMVUUpIHtcbiAgICAvLyBubyBkYXRhLCBubyBub3JtYWxpemF0aW9uXG4gICAgbm9ybSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiAxOyB9O1xuICB9IGVsc2UgaWYgKG1pbiA8IDAgJiYgbWF4ID4gMCkge1xuICAgIC8vIGJ1YmJsZSByYWRpdXMgc2hvdWxkIGFsd2F5cyBiZSBwb3NpdGl2ZSxcbiAgICAvLyBzbyB0YWtlIGFicywgYW5kIG5vcm1hbGl6ZSBieSBsYXJnZXN0IG9mIHxtaW58IGFuZCBtYXhcbiAgICBtaW4gPSBNYXRoLmFicyhtaW4pO1xuICAgIG1heCA9IG1heCA8IG1pbiA/IG1pbiA6IG1heDtcbiAgICBub3JtID0gZnVuY3Rpb24gKHYpIHtcbiAgICAgIHJldHVybiBNYXRoLmFicyh2KSAvIG1heDtcbiAgICB9O1xuICB9IGVsc2UgaWYgKChtYXggPiAwICYmIG1pbiA+PSAwKSB8fCAobWF4IDw9IDAgJiYgbWluIDwgMCkpIHtcbiAgICAvLyBsaW5lYXIgbWFwIHYgZnJvbSBbbWluLCBtYXhdIHRvIFswLDFdXG4gICAgbm9ybSA9IGZ1bmN0aW9uICh2KSB7XG4gICAgICByZXR1cm4gKHYgLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICAvLyBub3Qgc3VyZSBpZiBldmVyIHJlYWNoZWRcbiAgICBub3JtID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIDE7IH07XG4gIH1cbiAgcmV0dXJuIG5vcm07XG59XG5cbmZ1bmN0aW9uIGRlaW5pdENoYXJ0ICh2aWV3KSB7XG4gIGlmICh2aWV3Ll9jaGFydGpzKSB7XG4gICAgdmlldy5fY2hhcnRqcy5kZXN0cm95KCk7XG4gICAgZGVsZXRlIHZpZXcuX2NoYXJ0anM7XG4gIH1cbiAgZGVsZXRlIHZpZXcuX2NvbmZpZztcblxuICB2YXIgY2FudmFzID0gdmlldy5xdWVyeUJ5SG9vaygnY2FudmFzJyk7XG4gIGlmIChjYW52YXMpIHtcbiAgICB2aWV3LmVsLnJlbW92ZUNoaWxkKGNhbnZhcyk7XG4gIH1cbiAgdmlldy5pc0luaXRpYWxpemVkID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGluaXRDaGFydCAodmlldykge1xuICAvLyBDb25maWd1cmUgcGxvdFxuICB2aWV3Ll9jb25maWcgPSB2aWV3Lm1vZGVsLmNoYXJ0anNDb25maWcoKTtcbiAgdmFyIG9wdGlvbnMgPSB2aWV3Ll9jb25maWcub3B0aW9ucztcblxuICB2YXIgZmlsdGVyID0gdmlldy5tb2RlbC5maWx0ZXI7XG4gIHZhciBwYXJ0aXRpb247XG5cbiAgdmFyIGNhblNlbGVjdCA9IHRydWU7XG5cbiAgLy8gY29uZmlndXJlIHgtYXhpc1xuICBwYXJ0aXRpb24gPSBmaWx0ZXIucGFydGl0aW9ucy5nZXQoMSwgJ3JhbmsnKTtcblxuICBpZiAocGFydGl0aW9uLmlzRGF0ZXRpbWUpIHtcbiAgICBvcHRpb25zLnNjYWxlcy54QXhlc1swXS50eXBlID0gJ3RpbWUnO1xuICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0R1cmF0aW9uKSB7XG4gICAgb3B0aW9ucy5zY2FsZXMueEF4ZXNbMF0udHlwZSA9ICdzcG90LWR1cmF0aW9uJztcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNDb250aW51b3VzKSB7XG4gICAgaWYgKHBhcnRpdGlvbi5ncm91cExvZykge1xuICAgICAgb3B0aW9ucy5zY2FsZXMueEF4ZXNbMF0udHlwZSA9ICdsb2dhcml0aG1pYyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMuc2NhbGVzLnhBeGVzWzBdLnR5cGUgPSAnbGluZWFyJztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY2FuU2VsZWN0ID0gZmFsc2U7XG4gIH1cbiAgb3B0aW9ucy5zY2FsZXMueEF4ZXNbMF0uc2NhbGVMYWJlbCA9IHtcbiAgICBkaXNwbGF5OiBwYXJ0aXRpb24uc2hvd0xhYmVsLFxuICAgIGxhYmVsU3RyaW5nOiBwYXJ0aXRpb24ubGFiZWxcbiAgfTtcblxuICAvLyBjb25maWd1cmUgeS1heGlzXG4gIHBhcnRpdGlvbiA9IGZpbHRlci5wYXJ0aXRpb25zLmdldCgyLCAncmFuaycpO1xuXG4gIGlmIChwYXJ0aXRpb24uaXNEYXRldGltZSkge1xuICAgIG9wdGlvbnMuc2NhbGVzLnlBeGVzWzBdLnR5cGUgPSAndGltZSc7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzRHVyYXRpb24pIHtcbiAgICBvcHRpb25zLnNjYWxlcy55QXhlc1swXS50eXBlID0gJ3Nwb3QtZHVyYXRpb24nO1xuICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0NvbnRpbnVvdXMpIHtcbiAgICBpZiAocGFydGl0aW9uLmdyb3VwTG9nKSB7XG4gICAgICBvcHRpb25zLnNjYWxlcy55QXhlc1swXS50eXBlID0gJ2xvZ2FyaXRobWljJztcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucy5zY2FsZXMueUF4ZXNbMF0udHlwZSA9ICdsaW5lYXInO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBjYW5TZWxlY3QgPSBmYWxzZTtcbiAgfVxuICBvcHRpb25zLnNjYWxlcy55QXhlc1swXS5zY2FsZUxhYmVsID0ge1xuICAgIGRpc3BsYXk6IHBhcnRpdGlvbi5zaG93TGFiZWwsXG4gICAgbGFiZWxTdHJpbmc6IHBhcnRpdGlvbi5sYWJlbFxuICB9O1xuXG4gIC8vIHRpdGxlXG4gIG9wdGlvbnMudGl0bGUudGV4dCA9IHZpZXcubW9kZWwuZ2V0VGl0bGUoKTtcblxuICAvLyB1c2VyIGludGVyYWN0aW9uXG4gIGlmIChjYW5TZWxlY3QpIHtcbiAgICBvcHRpb25zLm9uQ2xpY2sgPSBmdW5jdGlvbiAoZXYsIGVsZW1lbnRzKSB7XG4gICAgICB2YXIgcGFydGl0aW9uQSA9IGZpbHRlci5wYXJ0aXRpb25zLmdldCgxLCAncmFuaycpO1xuICAgICAgdmFyIHBhcnRpdGlvbkIgPSBmaWx0ZXIucGFydGl0aW9ucy5nZXQoMiwgJ3JhbmsnKTtcblxuICAgICAgaWYgKGVsZW1lbnRzICYmIGVsZW1lbnRzWzBdKSB7XG4gICAgICAgIC8vIGdldCB0aGUgY2xpY2tlZC1vbiBidWJibGVcbiAgICAgICAgdmFyIGluZGV4ID0gZWxlbWVudHNbMF0uX2luZGV4O1xuICAgICAgICB2YXIgcG9pbnQgPSB2aWV3Ll9jb25maWcuZGF0YS5kYXRhc2V0c1swXS5kYXRhW2luZGV4XTtcblxuICAgICAgICAvLyB1cGRhdGUgc2VsZWN0aW9uIG9uIHgtYXhpc1xuICAgICAgICB2YXIgZ3JvdXB4ID0gcGFydGl0aW9uQS5ncm91cHMubW9kZWxzW3BvaW50LmldO1xuICAgICAgICBwYXJ0aXRpb25BLnVwZGF0ZVNlbGVjdGlvbihncm91cHgpO1xuXG4gICAgICAgIC8vIHVwZGF0ZSBzZWxlY3Rpb24gb24geS1heGlzXG4gICAgICAgIHZhciBncm91cHkgPSBwYXJ0aXRpb25CLmdyb3Vwcy5tb2RlbHNbcG9pbnQual07XG4gICAgICAgIHBhcnRpdGlvbkIudXBkYXRlU2VsZWN0aW9uKGdyb3VweSk7XG5cbiAgICAgICAgdmlldy5tb2RlbC5maWx0ZXIudXBkYXRlRGF0YUZpbHRlcigpO1xuICAgICAgICBhcHAubWUuZGF0YXZpZXcuZ2V0RGF0YSgpO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvLyBmb3JjZSBhIHNxdWFyZSBmdWxsIHNpemUgcGxvdFxuICB2YXIgd2lkdGggPSB2aWV3LmVsLm9mZnNldFdpZHRoO1xuICB2YXIgaGVpZ2h0ID0gdmlldy5lbC5vZmZzZXRIZWlnaHQ7XG5cbiAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICBjYW52YXMuc2V0QXR0cmlidXRlKCdkYXRhLWhvb2snLCAnY2FudmFzJyk7XG4gIHZpZXcuZWwuYXBwZW5kQ2hpbGQoY2FudmFzKTtcblxuICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gIGN0eC5jYW52YXMud2lkdGggPSB3aWR0aDtcbiAgY3R4LmNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG5cbiAgLy8gQ3JlYXRlIENoYXJ0anMgb2JqZWN0XG4gIHZpZXcuX2NoYXJ0anMgPSBuZXcgQ2hhcnQoY3R4LCB2aWV3Ll9jb25maWcpO1xuXG4gIC8vIEluIGNhbGxiYWNrcyBvbiB0aGUgY2hhcnQgd2Ugd2lsbCBuZWVkIHRoZSB2aWV3LCBzbyBzdG9yZSBhIHJlZmVyZW5jZVxuICB2aWV3Ll9jaGFydGpzLl9BbXBlcnNhbmR2aWV3ID0gdmlldztcblxuICB2aWV3LmlzSW5pdGlhbGl6ZWQgPSB0cnVlO1xufVxuXG5mdW5jdGlvbiB1cGRhdGUgKHZpZXcpIHtcbiAgaWYgKCF2aWV3LmlzSW5pdGlhbGl6ZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBBZGQgb3VyIGRhdGEgdG8gdGhlIHBsb3RcbiAgdXBkYXRlQnViYmxlcyh2aWV3KTtcblxuICAvLyBIYW5kIG92ZXIgdG8gQ2hhcnRqcyBmb3IgYWN0dWFsIHBsb3R0aW5nXG4gIHZpZXcuX2NoYXJ0anMudXBkYXRlKCk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUJ1YmJsZXMgKHZpZXcpIHtcbiAgdmFyIGZpbHRlciA9IHZpZXcubW9kZWwuZmlsdGVyO1xuICB2YXIgY2hhcnREYXRhID0gdmlldy5fY29uZmlnLmRhdGE7XG5cbiAgdmFyIHBhcnRpdGlvbkEgPSBmaWx0ZXIucGFydGl0aW9ucy5nZXQoMSwgJ3JhbmsnKTtcbiAgdmFyIHBhcnRpdGlvbkIgPSBmaWx0ZXIucGFydGl0aW9ucy5nZXQoMiwgJ3JhbmsnKTtcblxuICBjaGFydERhdGEuZGF0YXNldHMgPSBjaGFydERhdGEuZGF0YXNldHMgfHwgW107XG4gIGNoYXJ0RGF0YS5kYXRhc2V0c1swXSA9IGNoYXJ0RGF0YS5kYXRhc2V0c1swXSB8fCB7IGRhdGE6IFtdLCBlcnJvcjogW10sIGJhY2tncm91bmRDb2xvcjogW10gfTtcblxuICAvLyBmaW5kIGZhY2V0IG5hbWVzIGZvciB0b29sdGlwc1xuICBjaGFydERhdGEuZGF0YXNldHNbMF0uc3BvdEF4ZXMgPSB7XG4gICAgeDogcGFydGl0aW9uQS5sYWJlbCxcbiAgICB5OiBwYXJ0aXRpb25CLmxhYmVsXG4gIH07XG5cbiAgdmFyIGFnZ3JlZ2F0ZTtcbiAgdmFyIGJ1YmJsZUNvbG9yRm47IC8vIG5vcm1hbGl6YXRpb24gZnVuY3Rpb24gZm9yIGJ1YmJsZSBjb2xvclxuICB2YXIgYnViYmxlUmFkaXVzRm47IC8vIG5vcm1hbGl6YXRpb24gZnVuY3Rpb24gZm9yIGJ1YmJsZSByYWRpdXNcbiAgdmFyIGVycm9yWEZuO1xuICB2YXIgZXJyb3JZRm47XG5cbiAgYWdncmVnYXRlID0gZmlsdGVyLmFnZ3JlZ2F0ZXMuZ2V0KDEsICdyYW5rJyk7XG4gIGlmIChhZ2dyZWdhdGUpIHtcbiAgICBidWJibGVDb2xvckZuID0gbm9ybWFsaXplR3JvdXAoZmlsdGVyLmRhdGEsICdhYScpO1xuICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1swXS5zcG90QXhlcy5jID0gYWdncmVnYXRlLm9wZXJhdGlvbiArICcgJyArIGFnZ3JlZ2F0ZS5sYWJlbDtcbiAgfVxuXG4gIGFnZ3JlZ2F0ZSA9IGZpbHRlci5hZ2dyZWdhdGVzLmdldCgyLCAncmFuaycpO1xuICBpZiAoYWdncmVnYXRlKSB7XG4gICAgYnViYmxlUmFkaXVzRm4gPSBub3JtYWxpemVHcm91cChmaWx0ZXIuZGF0YSwgJ2JiJyk7XG4gICAgY2hhcnREYXRhLmRhdGFzZXRzWzBdLnNwb3RBeGVzLnIgPSBhZ2dyZWdhdGUub3BlcmF0aW9uICsgJyAnICsgYWdncmVnYXRlLmxhYmVsO1xuICB9XG5cbiAgdmlldy5fY29uZmlnLm9wdGlvbnMuZXJyb3JEaXIgPSAnYm90aCc7XG4gIGFnZ3JlZ2F0ZSA9IGZpbHRlci5hZ2dyZWdhdGVzLmdldCgzLCAncmFuaycpO1xuICBpZiAoYWdncmVnYXRlKSB7XG4gICAgZXJyb3JYRm4gPSBmdW5jdGlvbiAoZ3JvdXApIHsgcmV0dXJuIGdyb3VwWydjYyddOyB9O1xuICB9IGVsc2Uge1xuICAgIGVycm9yWEZuID0gZnVuY3Rpb24gKGdyb3VwKSB7IHJldHVybiBudWxsOyB9O1xuICAgIHZpZXcuX2NvbmZpZy5vcHRpb25zLmVycm9yRGlyID0gJ3ZlcnRpY2FsJztcbiAgfVxuXG4gIGFnZ3JlZ2F0ZSA9IGZpbHRlci5hZ2dyZWdhdGVzLmdldCg0LCAncmFuaycpO1xuICBpZiAoYWdncmVnYXRlKSB7XG4gICAgZXJyb3JZRm4gPSBmdW5jdGlvbiAoZ3JvdXApIHsgcmV0dXJuIGdyb3VwWydkZCddOyB9O1xuICB9IGVsc2Uge1xuICAgIGVycm9yWUZuID0gZnVuY3Rpb24gKGdyb3VwKSB7IHJldHVybiBudWxsOyB9O1xuICAgIGlmICh2aWV3Ll9jb25maWcub3B0aW9ucy5lcnJvckRpciA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgdmlldy5fY29uZmlnLm9wdGlvbnMuZXJyb3JEaXIgPT09ICdub25lJztcbiAgICB9XG4gICAgaWYgKHZpZXcuX2NvbmZpZy5vcHRpb25zLmVycm9yRGlyID09PSAnYm90aCcpIHtcbiAgICAgIHZpZXcuX2NvbmZpZy5vcHRpb25zLmVycm9yRGlyID09PSAnaG9yaXpvbnRhbCc7XG4gICAgfVxuICB9XG5cbiAgLy8gYWRkIGRhdGFcbiAgdmFyIHZhbDtcbiAgdmFyIGQgPSAwO1xuICBmaWx0ZXIuZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgIHZhciBpID0gdXRpbC5wYXJ0aXRpb25WYWx1ZVRvSW5kZXgocGFydGl0aW9uQSwgZ3JvdXAuYSk7XG4gICAgdmFyIGogPSB1dGlsLnBhcnRpdGlvblZhbHVlVG9JbmRleChwYXJ0aXRpb25CLCBncm91cC5iKTtcblxuICAgIGlmIChpID49IDAgJiYgaiA+PSAwICYmIGdyb3VwLmFhICE9PSBtaXN2YWwgJiYgZ3JvdXAuYmIgIT09IG1pc3ZhbCAmJiBncm91cC5jb3VudCAhPT0gMCkge1xuICAgICAgLy8gaW5pdGlhbGl6ZSBpZiBuZWNlc3NhcnlcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1swXS5kYXRhW2RdID0gY2hhcnREYXRhLmRhdGFzZXRzWzBdLmRhdGFbZF0gfHwge307XG4gICAgICBjaGFydERhdGEuZGF0YXNldHNbMF0uZXJyb3JbZF0gPSBjaGFydERhdGEuZGF0YXNldHNbMF0uZXJyb3JbZF0gfHwge307XG5cbiAgICAgIC8vIHVwZGF0ZSBwb3NpdGlvblxuICAgICAgaWYgKHBhcnRpdGlvbkEuaXNEYXRldGltZSB8fCBwYXJ0aXRpb25BLmlzRHVyYXRpb24gfHwgcGFydGl0aW9uQS5pc0NvbnRpbnVvdXMpIHtcbiAgICAgICAgY2hhcnREYXRhLmRhdGFzZXRzWzBdLmRhdGFbZF0ueCA9IHBhcnRpdGlvbkEuZ3JvdXBzLm1vZGVsc1tpXS52YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1swXS5kYXRhW2RdLnggPSBpO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFydGl0aW9uQi5pc0RhdGV0aW1lIHx8IHBhcnRpdGlvbkIuaXNEdXJhdGlvbiB8fCBwYXJ0aXRpb25CLmlzQ29udGludW91cykge1xuICAgICAgICBjaGFydERhdGEuZGF0YXNldHNbMF0uZGF0YVtkXS55ID0gcGFydGl0aW9uQi5ncm91cHMubW9kZWxzW2pdLnZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2hhcnREYXRhLmRhdGFzZXRzWzBdLmRhdGFbZF0ueSA9IGo7XG4gICAgICB9XG5cbiAgICAgIC8vIHVwZGF0ZSBlcnJvclxuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzWzBdLmVycm9yW2RdLnggPSBlcnJvclhGbihncm91cCk7XG4gICAgICBjaGFydERhdGEuZGF0YXNldHNbMF0uZXJyb3JbZF0ueSA9IGVycm9yWUZuKGdyb3VwKTtcblxuICAgICAgLy8gdXBkYXRlIGNvbG9yXG4gICAgICB2YWwgPSBwYXJzZUZsb2F0KGdyb3VwLmFhKSB8fCAwO1xuICAgICAgaWYgKGJ1YmJsZUNvbG9yRm4pIHtcbiAgICAgICAgY2hhcnREYXRhLmRhdGFzZXRzWzBdLmJhY2tncm91bmRDb2xvcltkXSA9IGNvbG9ycy5nZXRDb2xvckZsb2F0KGJ1YmJsZUNvbG9yRm4odmFsKSkuYWxwaGEoQlVCQkxFX0FMUEhBKS5jc3MoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1swXS5iYWNrZ3JvdW5kQ29sb3JbZF0gPSBjb2xvcnMuZ2V0Q29sb3IoMCkuYWxwaGEoQlVCQkxFX0FMUEhBKS5jc3MoKTtcbiAgICAgIH1cblxuICAgICAgLy8gdXBkYXRlIHJhZGl1c1xuICAgICAgdmFsID0gcGFyc2VGbG9hdChncm91cC5iYikgfHwgMDtcbiAgICAgIGlmIChidWJibGVSYWRpdXNGbikge1xuICAgICAgICBjaGFydERhdGEuZGF0YXNldHNbMF0uZGF0YVtkXS5yID0gTWF0aC5yb3VuZChNSU5fQlVCQkxFX1NJWkUgKyBNYXRoLnNxcnQoYnViYmxlUmFkaXVzRm4odmFsKSkgKiAoTUFYX0JVQkJMRV9TSVpFIC0gTUlOX0JVQkJMRV9TSVpFKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGFydERhdGEuZGF0YXNldHNbMF0uZGF0YVtkXS5yID0gTUlOX0JVQkJMRV9TSVpFOyAvLyBOT1RFOiBpbiBwaXhlbHNcbiAgICAgIH1cblxuICAgICAgLy8gc3RvcmUgZ3JvdXAgaW5kZXhlcyBmb3Igb25DbGljayBjYWxsYmFja1xuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzWzBdLmRhdGFbZF0uaSA9IGk7XG4gICAgICBjaGFydERhdGEuZGF0YXNldHNbMF0uZGF0YVtkXS5qID0gajtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1swXS5kYXRhW2RdLmEgPSBncm91cC5hO1xuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzWzBdLmRhdGFbZF0uYiA9IGdyb3VwLmI7XG4gICAgICBjaGFydERhdGEuZGF0YXNldHNbMF0uZGF0YVtkXS5hYSA9IGdyb3VwLmFhO1xuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzWzBdLmRhdGFbZF0uYmIgPSBncm91cC5iYjtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1swXS5kYXRhW2RdLmNvdW50ID0gZ3JvdXAuY291bnQ7XG4gICAgICBkKys7XG4gICAgfVxuICB9KTtcblxuICAvLyByZW1vdmUgcmVtYWluaW5nICh1bnVzZWQpIHBvaW50c1xuICB2YXIgY3V0ID0gY2hhcnREYXRhLmRhdGFzZXRzWzBdLmRhdGEubGVuZ3RoIC0gZDtcbiAgaWYgKGN1dCA+IDApIHtcbiAgICBjaGFydERhdGEuZGF0YXNldHNbMF0uZGF0YS5zcGxpY2UoZCwgY3V0KTtcbiAgICBjaGFydERhdGEuZGF0YXNldHNbMF0uZXJyb3Iuc3BsaWNlKGQsIGN1dCk7XG4gICAgY2hhcnREYXRhLmRhdGFzZXRzWzBdLmJhY2tncm91bmRDb2xvci5zcGxpY2UoZCwgY3V0KTtcbiAgfVxuXG4gIC8vIGhpZ2hsaWdodCBzZWxlY3RlZCBhcmVhXG4gIGlmIChcbiAgICAocGFydGl0aW9uQS5pc0RhdGV0aW1lIHx8IHBhcnRpdGlvbkEuaXNEdXJhdGlvbiB8fCBwYXJ0aXRpb25BLmlzQ29udGludW91cykgJiZcbiAgICAocGFydGl0aW9uQi5pc0RhdGV0aW1lIHx8IHBhcnRpdGlvbkIuaXNEdXJhdGlvbiB8fCBwYXJ0aXRpb25CLmlzQ29udGludW91cykpIHtcbiAgICBpZiAocGFydGl0aW9uQS5zZWxlY3RlZCAmJiBwYXJ0aXRpb25BLnNlbGVjdGVkLmxlbmd0aCA+IDApIHtcbiAgICAgIGNoYXJ0RGF0YS5kYXRhc2V0c1sxXSA9IGNoYXJ0RGF0YS5kYXRhc2V0c1sxXSB8fCB7XG4gICAgICAgIHR5cGU6ICdsaW5lJyxcbiAgICAgICAgbGluZVRlbnNpb246IDBcbiAgICAgIH07XG4gICAgICBjaGFydERhdGEuZGF0YXNldHNbMV0uZGF0YSA9IFtcbiAgICAgICAgeyB4OiBwYXJ0aXRpb25BLnNlbGVjdGVkWzBdLCB5OiBwYXJ0aXRpb25CLnNlbGVjdGVkWzBdLCByOiAxIH0sXG4gICAgICAgIHsgeDogcGFydGl0aW9uQS5zZWxlY3RlZFswXSwgeTogcGFydGl0aW9uQi5zZWxlY3RlZFsxXSwgcjogMSB9LFxuICAgICAgICB7IHg6IHBhcnRpdGlvbkEuc2VsZWN0ZWRbMV0sIHk6IHBhcnRpdGlvbkIuc2VsZWN0ZWRbMV0sIHI6IDEgfSxcbiAgICAgICAgeyB4OiBwYXJ0aXRpb25BLnNlbGVjdGVkWzFdLCB5OiBwYXJ0aXRpb25CLnNlbGVjdGVkWzBdLCByOiAxIH0sXG4gICAgICAgIHsgeDogcGFydGl0aW9uQS5zZWxlY3RlZFswXSwgeTogcGFydGl0aW9uQi5zZWxlY3RlZFswXSwgcjogMSB9XG4gICAgICBdO1xuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzWzFdLmVycm9yID0gW251bGwsIG51bGwsIG51bGwsIG51bGxdO1xuICAgICAgY2hhcnREYXRhLmRhdGFzZXRzWzFdLmJhY2tncm91bmRDb2xvciA9IGNvbG9ycy5nZXRDb2xvcigxKS5hbHBoYShCVUJCTEVfQUxQSEEpLmNzcygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjaGFydERhdGEuZGF0YXNldHMuc3BsaWNlKDEsIDEpO1xuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VXaWRnZXQuZXh0ZW5kKHtcbiAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwid2lkZ2V0SW5uZXIgbWRsLWNhcmRfX21lZGlhXCI+PC9kaXY+JyxcblxuICB1cGRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICB1cGRhdGUodGhpcyk7XG4gIH0sXG5cbiAgaW5pdENoYXJ0OiBmdW5jdGlvbiAoKSB7XG4gICAgaW5pdENoYXJ0KHRoaXMpO1xuICB9LFxuXG4gIGRlaW5pdENoYXJ0OiBmdW5jdGlvbiAoKSB7XG4gICAgZGVpbml0Q2hhcnQodGhpcyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRkE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBRkE7QUFDQTtBQUtBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFGQTtBQUtBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBRUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQWJBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///fdc1\n")}},[[0,"runtime","npm.core-js","npm.lodash","npm.spot-framework","npm.chart.js","npm.readable-stream","npm.es-abstract","npm.qs","npm.string.prototype.trim","npm.webpack","npm.sigma","npm.moment-timezone","npm.object-keys","npm.ampersand-events","npm.ampersand-router","npm.ampersand-sync","npm.babel-polyfill","npm.closest","npm.color-convert","npm.es-to-primitive","npm.function-bind","npm.has-binary","npm.node-libs-browser","npm.util","npm.after","npm.ampersand-app","npm.ampersand-class-extend","npm.ampersand-collection-view","npm.ampersand-collection","npm.ampersand-dom-bindings","npm.ampersand-dom","npm.ampersand-model","npm.ampersand-state","npm.ampersand-view-switcher","npm.ampersand-view","npm.array-next","npm.backo2","npm.base64-arraybuffer","npm.base64-js","npm.buffer","npm.chartjs-color-string","npm.chartjs-color","npm.chroma-js","npm.color-name","npm.component-bind","npm.component-emitter","npm.component-event","npm.component-inherit","npm.core-util-is","npm.csv-generate","npm.csv-parse","npm.csv-stringify","npm.csv","npm.define-properties","npm.delegate-events","npm.dialog-polyfill","npm.domify","npm.domready","npm.events-mixin","npm.events","npm.file-saver","npm.for-each","npm.global","npm.gridster","npm.has-cors","npm.has","npm.ieee754","npm.indexof","npm.inherits","npm.intro.js","npm.is-callable","npm.is-function","npm.isarray","npm.jquery","npm.json3","npm.key-tree-store","npm.local-links","npm.lodash.get","npm.matches-selector","npm.material-design-lite","npm.media-type","npm.moment","npm.parse-headers","npm.parsejson","npm.parseqs","npm.parseuri","npm.process-nextick-args","npm.process","npm.safe-buffer","npm.setimmediate","npm.sortablejs","npm.stream-browserify","npm.stream-transform","npm.timers-browserify","npm.to-array","npm.util-deprecate","npm.vis","npm.wtf-8","npm.xhr","npm.xtend","npm.yeast"]]]);

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.dialog-polyfill"],{"5c00":function(module,exports,__webpack_require__){eval("var __WEBPACK_AMD_DEFINE_RESULT__;(function() {\n\n  // nb. This is for IE10 and lower _only_.\n  var supportCustomEvent = window.CustomEvent;\n  if (!supportCustomEvent || typeof supportCustomEvent === 'object') {\n    supportCustomEvent = function CustomEvent(event, x) {\n      x = x || {};\n      var ev = document.createEvent('CustomEvent');\n      ev.initCustomEvent(event, !!x.bubbles, !!x.cancelable, x.detail || null);\n      return ev;\n    };\n    supportCustomEvent.prototype = window.Event.prototype;\n  }\n\n  /**\n   * @param {Element} el to check for stacking context\n   * @return {boolean} whether this el or its parents creates a stacking context\n   */\n  function createsStackingContext(el) {\n    while (el && el !== document.body) {\n      var s = window.getComputedStyle(el);\n      var invalid = function(k, ok) {\n        return !(s[k] === undefined || s[k] === ok);\n      }\n      if (s.opacity < 1 ||\n          invalid('zIndex', 'auto') ||\n          invalid('transform', 'none') ||\n          invalid('mixBlendMode', 'normal') ||\n          invalid('filter', 'none') ||\n          invalid('perspective', 'none') ||\n          s['isolation'] === 'isolate' ||\n          s.position === 'fixed' ||\n          s.webkitOverflowScrolling === 'touch') {\n        return true;\n      }\n      el = el.parentElement;\n    }\n    return false;\n  }\n\n  /**\n   * Finds the nearest <dialog> from the passed element.\n   *\n   * @param {Element} el to search from\n   * @return {HTMLDialogElement} dialog found\n   */\n  function findNearestDialog(el) {\n    while (el) {\n      if (el.localName === 'dialog') {\n        return /** @type {HTMLDialogElement} */ (el);\n      }\n      el = el.parentElement;\n    }\n    return null;\n  }\n\n  /**\n   * Blur the specified element, as long as it's not the HTML body element.\n   * This works around an IE9/10 bug - blurring the body causes Windows to\n   * blur the whole application.\n   *\n   * @param {Element} el to blur\n   */\n  function safeBlur(el) {\n    if (el && el.blur && el !== document.body) {\n      el.blur();\n    }\n  }\n\n  /**\n   * @param {!NodeList} nodeList to search\n   * @param {Node} node to find\n   * @return {boolean} whether node is inside nodeList\n   */\n  function inNodeList(nodeList, node) {\n    for (var i = 0; i < nodeList.length; ++i) {\n      if (nodeList[i] === node) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * @param {HTMLFormElement} el to check\n   * @return {boolean} whether this form has method=\"dialog\"\n   */\n  function isFormMethodDialog(el) {\n    if (!el || !el.hasAttribute('method')) {\n      return false;\n    }\n    return el.getAttribute('method').toLowerCase() === 'dialog';\n  }\n\n  /**\n   * @param {!HTMLDialogElement} dialog to upgrade\n   * @constructor\n   */\n  function dialogPolyfillInfo(dialog) {\n    this.dialog_ = dialog;\n    this.replacedStyleTop_ = false;\n    this.openAsModal_ = false;\n\n    // Set a11y role. Browsers that support dialog implicitly know this already.\n    if (!dialog.hasAttribute('role')) {\n      dialog.setAttribute('role', 'dialog');\n    }\n\n    dialog.show = this.show.bind(this);\n    dialog.showModal = this.showModal.bind(this);\n    dialog.close = this.close.bind(this);\n\n    if (!('returnValue' in dialog)) {\n      dialog.returnValue = '';\n    }\n\n    if ('MutationObserver' in window) {\n      var mo = new MutationObserver(this.maybeHideModal.bind(this));\n      mo.observe(dialog, {attributes: true, attributeFilter: ['open']});\n    } else {\n      // IE10 and below support. Note that DOMNodeRemoved etc fire _before_ removal. They also\n      // seem to fire even if the element was removed as part of a parent removal. Use the removed\n      // events to force downgrade (useful if removed/immediately added).\n      var removed = false;\n      var cb = function() {\n        removed ? this.downgradeModal() : this.maybeHideModal();\n        removed = false;\n      }.bind(this);\n      var timeout;\n      var delayModel = function(ev) {\n        if (ev.target !== dialog) { return; }  // not for a child element\n        var cand = 'DOMNodeRemoved';\n        removed |= (ev.type.substr(0, cand.length) === cand);\n        window.clearTimeout(timeout);\n        timeout = window.setTimeout(cb, 0);\n      };\n      ['DOMAttrModified', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument'].forEach(function(name) {\n        dialog.addEventListener(name, delayModel);\n      });\n    }\n    // Note that the DOM is observed inside DialogManager while any dialog\n    // is being displayed as a modal, to catch modal removal from the DOM.\n\n    Object.defineProperty(dialog, 'open', {\n      set: this.setOpen.bind(this),\n      get: dialog.hasAttribute.bind(dialog, 'open')\n    });\n\n    this.backdrop_ = document.createElement('div');\n    this.backdrop_.className = 'backdrop';\n    this.backdrop_.addEventListener('click', this.backdropClick_.bind(this));\n  }\n\n  dialogPolyfillInfo.prototype = {\n\n    get dialog() {\n      return this.dialog_;\n    },\n\n    /**\n     * Maybe remove this dialog from the modal top layer. This is called when\n     * a modal dialog may no longer be tenable, e.g., when the dialog is no\n     * longer open or is no longer part of the DOM.\n     */\n    maybeHideModal: function() {\n      if (this.dialog_.hasAttribute('open') && document.body.contains(this.dialog_)) { return; }\n      this.downgradeModal();\n    },\n\n    /**\n     * Remove this dialog from the modal top layer, leaving it as a non-modal.\n     */\n    downgradeModal: function() {\n      if (!this.openAsModal_) { return; }\n      this.openAsModal_ = false;\n      this.dialog_.style.zIndex = '';\n\n      // This won't match the native <dialog> exactly because if the user set top on a centered\n      // polyfill dialog, that top gets thrown away when the dialog is closed. Not sure it's\n      // possible to polyfill this perfectly.\n      if (this.replacedStyleTop_) {\n        this.dialog_.style.top = '';\n        this.replacedStyleTop_ = false;\n      }\n\n      // Clear the backdrop and remove from the manager.\n      this.backdrop_.parentNode && this.backdrop_.parentNode.removeChild(this.backdrop_);\n      dialogPolyfill.dm.removeDialog(this);\n    },\n\n    /**\n     * @param {boolean} value whether to open or close this dialog\n     */\n    setOpen: function(value) {\n      if (value) {\n        this.dialog_.hasAttribute('open') || this.dialog_.setAttribute('open', '');\n      } else {\n        this.dialog_.removeAttribute('open');\n        this.maybeHideModal();  // nb. redundant with MutationObserver\n      }\n    },\n\n    /**\n     * Handles clicks on the fake .backdrop element, redirecting them as if\n     * they were on the dialog itself.\n     *\n     * @param {!Event} e to redirect\n     */\n    backdropClick_: function(e) {\n      if (!this.dialog_.hasAttribute('tabindex')) {\n        // Clicking on the backdrop should move the implicit cursor, even if dialog cannot be\n        // focused. Create a fake thing to focus on. If the backdrop was _before_ the dialog, this\n        // would not be needed - clicks would move the implicit cursor there.\n        var fake = document.createElement('div');\n        this.dialog_.insertBefore(fake, this.dialog_.firstChild);\n        fake.tabIndex = -1;\n        fake.focus();\n        this.dialog_.removeChild(fake);\n      } else {\n        this.dialog_.focus();\n      }\n\n      var redirectedEvent = document.createEvent('MouseEvents');\n      redirectedEvent.initMouseEvent(e.type, e.bubbles, e.cancelable, window,\n          e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey,\n          e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);\n      this.dialog_.dispatchEvent(redirectedEvent);\n      e.stopPropagation();\n    },\n\n    /**\n     * Focuses on the first focusable element within the dialog. This will always blur the current\n     * focus, even if nothing within the dialog is found.\n     */\n    focus_: function() {\n      // Find element with `autofocus` attribute, or fall back to the first form/tabindex control.\n      var target = this.dialog_.querySelector('[autofocus]:not([disabled])');\n      if (!target && this.dialog_.tabIndex >= 0) {\n        target = this.dialog_;\n      }\n      if (!target) {\n        // Note that this is 'any focusable area'. This list is probably not exhaustive, but the\n        // alternative involves stepping through and trying to focus everything.\n        var opts = ['button', 'input', 'keygen', 'select', 'textarea'];\n        var query = opts.map(function(el) {\n          return el + ':not([disabled])';\n        });\n        // TODO(samthor): tabindex values that are not numeric are not focusable.\n        query.push('[tabindex]:not([disabled]):not([tabindex=\"\"])');  // tabindex != \"\", not disabled\n        target = this.dialog_.querySelector(query.join(', '));\n      }\n      safeBlur(document.activeElement);\n      target && target.focus();\n    },\n\n    /**\n     * Sets the zIndex for the backdrop and dialog.\n     *\n     * @param {number} dialogZ\n     * @param {number} backdropZ\n     */\n    updateZIndex: function(dialogZ, backdropZ) {\n      if (dialogZ < backdropZ) {\n        throw new Error('dialogZ should never be < backdropZ');\n      }\n      this.dialog_.style.zIndex = dialogZ;\n      this.backdrop_.style.zIndex = backdropZ;\n    },\n\n    /**\n     * Shows the dialog. If the dialog is already open, this does nothing.\n     */\n    show: function() {\n      if (!this.dialog_.open) {\n        this.setOpen(true);\n        this.focus_();\n      }\n    },\n\n    /**\n     * Show this dialog modally.\n     */\n    showModal: function() {\n      if (this.dialog_.hasAttribute('open')) {\n        throw new Error('Failed to execute \\'showModal\\' on dialog: The element is already open, and therefore cannot be opened modally.');\n      }\n      if (!document.body.contains(this.dialog_)) {\n        throw new Error('Failed to execute \\'showModal\\' on dialog: The element is not in a Document.');\n      }\n      if (!dialogPolyfill.dm.pushDialog(this)) {\n        throw new Error('Failed to execute \\'showModal\\' on dialog: There are too many open modal dialogs.');\n      }\n\n      if (createsStackingContext(this.dialog_.parentElement)) {\n        console.warn('A dialog is being shown inside a stacking context. ' +\n            'This may cause it to be unusable. For more information, see this link: ' +\n            'https://github.com/GoogleChrome/dialog-polyfill/#stacking-context');\n      }\n\n      this.setOpen(true);\n      this.openAsModal_ = true;\n\n      // Optionally center vertically, relative to the current viewport.\n      if (dialogPolyfill.needsCentering(this.dialog_)) {\n        dialogPolyfill.reposition(this.dialog_);\n        this.replacedStyleTop_ = true;\n      } else {\n        this.replacedStyleTop_ = false;\n      }\n\n      // Insert backdrop.\n      this.dialog_.parentNode.insertBefore(this.backdrop_, this.dialog_.nextSibling);\n\n      // Focus on whatever inside the dialog.\n      this.focus_();\n    },\n\n    /**\n     * Closes this HTMLDialogElement. This is optional vs clearing the open\n     * attribute, however this fires a 'close' event.\n     *\n     * @param {string=} opt_returnValue to use as the returnValue\n     */\n    close: function(opt_returnValue) {\n      if (!this.dialog_.hasAttribute('open')) {\n        throw new Error('Failed to execute \\'close\\' on dialog: The element does not have an \\'open\\' attribute, and therefore cannot be closed.');\n      }\n      this.setOpen(false);\n\n      // Leave returnValue untouched in case it was set directly on the element\n      if (opt_returnValue !== undefined) {\n        this.dialog_.returnValue = opt_returnValue;\n      }\n\n      // Triggering \"close\" event for any attached listeners on the <dialog>.\n      var closeEvent = new supportCustomEvent('close', {\n        bubbles: false,\n        cancelable: false\n      });\n      this.dialog_.dispatchEvent(closeEvent);\n    }\n\n  };\n\n  var dialogPolyfill = {};\n\n  dialogPolyfill.reposition = function(element) {\n    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;\n    var topValue = scrollTop + (window.innerHeight - element.offsetHeight) / 2;\n    element.style.top = Math.max(scrollTop, topValue) + 'px';\n  };\n\n  dialogPolyfill.isInlinePositionSetByStylesheet = function(element) {\n    for (var i = 0; i < document.styleSheets.length; ++i) {\n      var styleSheet = document.styleSheets[i];\n      var cssRules = null;\n      // Some browsers throw on cssRules.\n      try {\n        cssRules = styleSheet.cssRules;\n      } catch (e) {}\n      if (!cssRules) { continue; }\n      for (var j = 0; j < cssRules.length; ++j) {\n        var rule = cssRules[j];\n        var selectedNodes = null;\n        // Ignore errors on invalid selector texts.\n        try {\n          selectedNodes = document.querySelectorAll(rule.selectorText);\n        } catch(e) {}\n        if (!selectedNodes || !inNodeList(selectedNodes, element)) {\n          continue;\n        }\n        var cssTop = rule.style.getPropertyValue('top');\n        var cssBottom = rule.style.getPropertyValue('bottom');\n        if ((cssTop && cssTop !== 'auto') || (cssBottom && cssBottom !== 'auto')) {\n          return true;\n        }\n      }\n    }\n    return false;\n  };\n\n  dialogPolyfill.needsCentering = function(dialog) {\n    var computedStyle = window.getComputedStyle(dialog);\n    if (computedStyle.position !== 'absolute') {\n      return false;\n    }\n\n    // We must determine whether the top/bottom specified value is non-auto.  In\n    // WebKit/Blink, checking computedStyle.top == 'auto' is sufficient, but\n    // Firefox returns the used value. So we do this crazy thing instead: check\n    // the inline style and then go through CSS rules.\n    if ((dialog.style.top !== 'auto' && dialog.style.top !== '') ||\n        (dialog.style.bottom !== 'auto' && dialog.style.bottom !== '')) {\n      return false;\n    }\n    return !dialogPolyfill.isInlinePositionSetByStylesheet(dialog);\n  };\n\n  /**\n   * @param {!Element} element to force upgrade\n   */\n  dialogPolyfill.forceRegisterDialog = function(element) {\n    if (window.HTMLDialogElement || element.showModal) {\n      console.warn('This browser already supports <dialog>, the polyfill ' +\n          'may not work correctly', element);\n    }\n    if (element.localName !== 'dialog') {\n      throw new Error('Failed to register dialog: The element is not a dialog.');\n    }\n    new dialogPolyfillInfo(/** @type {!HTMLDialogElement} */ (element));\n  };\n\n  /**\n   * @param {!Element} element to upgrade, if necessary\n   */\n  dialogPolyfill.registerDialog = function(element) {\n    if (!element.showModal) {\n      dialogPolyfill.forceRegisterDialog(element);\n    }\n  };\n\n  /**\n   * @constructor\n   */\n  dialogPolyfill.DialogManager = function() {\n    /** @type {!Array<!dialogPolyfillInfo>} */\n    this.pendingDialogStack = [];\n\n    var checkDOM = this.checkDOM_.bind(this);\n\n    // The overlay is used to simulate how a modal dialog blocks the document.\n    // The blocking dialog is positioned on top of the overlay, and the rest of\n    // the dialogs on the pending dialog stack are positioned below it. In the\n    // actual implementation, the modal dialog stacking is controlled by the\n    // top layer, where z-index has no effect.\n    this.overlay = document.createElement('div');\n    this.overlay.className = '_dialog_overlay';\n    this.overlay.addEventListener('click', function(e) {\n      this.forwardTab_ = undefined;\n      e.stopPropagation();\n      checkDOM([]);  // sanity-check DOM\n    }.bind(this));\n\n    this.handleKey_ = this.handleKey_.bind(this);\n    this.handleFocus_ = this.handleFocus_.bind(this);\n\n    this.zIndexLow_ = 100000;\n    this.zIndexHigh_ = 100000 + 150;\n\n    this.forwardTab_ = undefined;\n\n    if ('MutationObserver' in window) {\n      this.mo_ = new MutationObserver(function(records) {\n        var removed = [];\n        records.forEach(function(rec) {\n          for (var i = 0, c; c = rec.removedNodes[i]; ++i) {\n            if (!(c instanceof Element)) {\n              continue;\n            } else if (c.localName === 'dialog') {\n              removed.push(c);\n            }\n            removed = removed.concat(c.querySelectorAll('dialog'));\n          }\n        });\n        removed.length && checkDOM(removed);\n      });\n    }\n  };\n\n  /**\n   * Called on the first modal dialog being shown. Adds the overlay and related\n   * handlers.\n   */\n  dialogPolyfill.DialogManager.prototype.blockDocument = function() {\n    document.documentElement.addEventListener('focus', this.handleFocus_, true);\n    document.addEventListener('keydown', this.handleKey_);\n    this.mo_ && this.mo_.observe(document, {childList: true, subtree: true});\n  };\n\n  /**\n   * Called on the first modal dialog being removed, i.e., when no more modal\n   * dialogs are visible.\n   */\n  dialogPolyfill.DialogManager.prototype.unblockDocument = function() {\n    document.documentElement.removeEventListener('focus', this.handleFocus_, true);\n    document.removeEventListener('keydown', this.handleKey_);\n    this.mo_ && this.mo_.disconnect();\n  };\n\n  /**\n   * Updates the stacking of all known dialogs.\n   */\n  dialogPolyfill.DialogManager.prototype.updateStacking = function() {\n    var zIndex = this.zIndexHigh_;\n\n    for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {\n      dpi.updateZIndex(--zIndex, --zIndex);\n      if (i === 0) {\n        this.overlay.style.zIndex = --zIndex;\n      }\n    }\n\n    // Make the overlay a sibling of the dialog itself.\n    var last = this.pendingDialogStack[0];\n    if (last) {\n      var p = last.dialog.parentNode || document.body;\n      p.appendChild(this.overlay);\n    } else if (this.overlay.parentNode) {\n      this.overlay.parentNode.removeChild(this.overlay);\n    }\n  };\n\n  /**\n   * @param {Element} candidate to check if contained or is the top-most modal dialog\n   * @return {boolean} whether candidate is contained in top dialog\n   */\n  dialogPolyfill.DialogManager.prototype.containedByTopDialog_ = function(candidate) {\n    while (candidate = findNearestDialog(candidate)) {\n      for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {\n        if (dpi.dialog === candidate) {\n          return i === 0;  // only valid if top-most\n        }\n      }\n      candidate = candidate.parentElement;\n    }\n    return false;\n  };\n\n  dialogPolyfill.DialogManager.prototype.handleFocus_ = function(event) {\n    if (this.containedByTopDialog_(event.target)) { return; }\n\n    event.preventDefault();\n    event.stopPropagation();\n    safeBlur(/** @type {Element} */ (event.target));\n\n    if (this.forwardTab_ === undefined) { return; }  // move focus only from a tab key\n\n    var dpi = this.pendingDialogStack[0];\n    var dialog = dpi.dialog;\n    var position = dialog.compareDocumentPosition(event.target);\n    if (position & Node.DOCUMENT_POSITION_PRECEDING) {\n      if (this.forwardTab_) {  // forward\n        dpi.focus_();\n      } else {  // backwards\n        document.documentElement.focus();\n      }\n    } else {\n      // TODO: Focus after the dialog, is ignored.\n    }\n\n    return false;\n  };\n\n  dialogPolyfill.DialogManager.prototype.handleKey_ = function(event) {\n    this.forwardTab_ = undefined;\n    if (event.keyCode === 27) {\n      event.preventDefault();\n      event.stopPropagation();\n      var cancelEvent = new supportCustomEvent('cancel', {\n        bubbles: false,\n        cancelable: true\n      });\n      var dpi = this.pendingDialogStack[0];\n      if (dpi && dpi.dialog.dispatchEvent(cancelEvent)) {\n        dpi.dialog.close();\n      }\n    } else if (event.keyCode === 9) {\n      this.forwardTab_ = !event.shiftKey;\n    }\n  };\n\n  /**\n   * Finds and downgrades any known modal dialogs that are no longer displayed. Dialogs that are\n   * removed and immediately readded don't stay modal, they become normal.\n   *\n   * @param {!Array<!HTMLDialogElement>} removed that have definitely been removed\n   */\n  dialogPolyfill.DialogManager.prototype.checkDOM_ = function(removed) {\n    // This operates on a clone because it may cause it to change. Each change also calls\n    // updateStacking, which only actually needs to happen once. But who removes many modal dialogs\n    // at a time?!\n    var clone = this.pendingDialogStack.slice();\n    clone.forEach(function(dpi) {\n      if (removed.indexOf(dpi.dialog) !== -1) {\n        dpi.downgradeModal();\n      } else {\n        dpi.maybeHideModal();\n      }\n    });\n  };\n\n  /**\n   * @param {!dialogPolyfillInfo} dpi\n   * @return {boolean} whether the dialog was allowed\n   */\n  dialogPolyfill.DialogManager.prototype.pushDialog = function(dpi) {\n    var allowed = (this.zIndexHigh_ - this.zIndexLow_) / 2 - 1;\n    if (this.pendingDialogStack.length >= allowed) {\n      return false;\n    }\n    if (this.pendingDialogStack.unshift(dpi) === 1) {\n      this.blockDocument();\n    }\n    this.updateStacking();\n    return true;\n  };\n\n  /**\n   * @param {!dialogPolyfillInfo} dpi\n   */\n  dialogPolyfill.DialogManager.prototype.removeDialog = function(dpi) {\n    var index = this.pendingDialogStack.indexOf(dpi);\n    if (index === -1) { return; }\n\n    this.pendingDialogStack.splice(index, 1);\n    if (this.pendingDialogStack.length === 0) {\n      this.unblockDocument();\n    }\n    this.updateStacking();\n  };\n\n  dialogPolyfill.dm = new dialogPolyfill.DialogManager();\n  dialogPolyfill.formSubmitter = null;\n  dialogPolyfill.useValue = null;\n\n  /**\n   * Installs global handlers, such as click listers and native method overrides. These are needed\n   * even if a no dialog is registered, as they deal with <form method=\"dialog\">.\n   */\n  if (window.HTMLDialogElement === undefined) {\n\n    /**\n     * If HTMLFormElement translates method=\"DIALOG\" into 'get', then replace the descriptor with\n     * one that returns the correct value.\n     */\n    var testForm = document.createElement('form');\n    testForm.setAttribute('method', 'dialog');\n    if (testForm.method !== 'dialog') {\n      var methodDescriptor = Object.getOwnPropertyDescriptor(HTMLFormElement.prototype, 'method');\n      if (methodDescriptor) {\n        // nb. Some older iOS and older PhantomJS fail to return the descriptor. Don't do anything\n        // and don't bother to update the element.\n        var realGet = methodDescriptor.get;\n        methodDescriptor.get = function() {\n          if (isFormMethodDialog(this)) {\n            return 'dialog';\n          }\n          return realGet.call(this);\n        };\n        var realSet = methodDescriptor.set;\n        methodDescriptor.set = function(v) {\n          if (typeof v === 'string' && v.toLowerCase() === 'dialog') {\n            return this.setAttribute('method', v);\n          }\n          return realSet.call(this, v);\n        };\n        Object.defineProperty(HTMLFormElement.prototype, 'method', methodDescriptor);\n      }\n    }\n\n    /**\n     * Global 'click' handler, to capture the <input type=\"submit\"> or <button> element which has\n     * submitted a <form method=\"dialog\">. Needed as Safari and others don't report this inside\n     * document.activeElement.\n     */\n    document.addEventListener('click', function(ev) {\n      dialogPolyfill.formSubmitter = null;\n      dialogPolyfill.useValue = null;\n      if (ev.defaultPrevented) { return; }  // e.g. a submit which prevents default submission\n\n      var target = /** @type {Element} */ (ev.target);\n      if (!target || !isFormMethodDialog(target.form)) { return; }\n\n      var valid = (target.type === 'submit' && ['button', 'input'].indexOf(target.localName) > -1);\n      if (!valid) {\n        if (!(target.localName === 'input' && target.type === 'image')) { return; }\n        // this is a <input type=\"image\">, which can submit forms\n        dialogPolyfill.useValue = ev.offsetX + ',' + ev.offsetY;\n      }\n\n      var dialog = findNearestDialog(target);\n      if (!dialog) { return; }\n\n      dialogPolyfill.formSubmitter = target;\n    }, false);\n\n    /**\n     * Replace the native HTMLFormElement.submit() method, as it won't fire the\n     * submit event and give us a chance to respond.\n     */\n    var nativeFormSubmit = HTMLFormElement.prototype.submit;\n    var replacementFormSubmit = function () {\n      if (!isFormMethodDialog(this)) {\n        return nativeFormSubmit.call(this);\n      }\n      var dialog = findNearestDialog(this);\n      dialog && dialog.close();\n    };\n    HTMLFormElement.prototype.submit = replacementFormSubmit;\n\n    /**\n     * Global form 'dialog' method handler. Closes a dialog correctly on submit\n     * and possibly sets its return value.\n     */\n    document.addEventListener('submit', function(ev) {\n      var form = /** @type {HTMLFormElement} */ (ev.target);\n      if (!isFormMethodDialog(form)) { return; }\n      ev.preventDefault();\n\n      var dialog = findNearestDialog(form);\n      if (!dialog) { return; }\n\n      // Forms can only be submitted via .submit() or a click (?), but anyway: sanity-check that\n      // the submitter is correct before using its value as .returnValue.\n      var s = dialogPolyfill.formSubmitter;\n      if (s && s.form === form) {\n        dialog.close(dialogPolyfill.useValue || s.value);\n      } else {\n        dialog.close();\n      }\n      dialogPolyfill.formSubmitter = null;\n    }, true);\n  }\n\n  dialogPolyfill['forceRegisterDialog'] = dialogPolyfill.forceRegisterDialog;\n  dialogPolyfill['registerDialog'] = dialogPolyfill.registerDialog;\n\n  if ( true && 'amd' in __webpack_require__(/*! !webpack amd define */ \"30d1\")) {\n    // AMD support\n    !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() { return dialogPolyfill; }).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n  } else if ( true && typeof module['exports'] === 'object') {\n    // CommonJS support\n    module['exports'] = dialogPolyfill;\n  } else {\n    // all others\n    window['dialogPolyfill'] = dialogPolyfill;\n  }\n})();\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNWMwMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9kaWFsb2ctcG9seWZpbGwvZGlhbG9nLXBvbHlmaWxsLmpzP2M5NzAiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCkge1xuXG4gIC8vIG5iLiBUaGlzIGlzIGZvciBJRTEwIGFuZCBsb3dlciBfb25seV8uXG4gIHZhciBzdXBwb3J0Q3VzdG9tRXZlbnQgPSB3aW5kb3cuQ3VzdG9tRXZlbnQ7XG4gIGlmICghc3VwcG9ydEN1c3RvbUV2ZW50IHx8IHR5cGVvZiBzdXBwb3J0Q3VzdG9tRXZlbnQgPT09ICdvYmplY3QnKSB7XG4gICAgc3VwcG9ydEN1c3RvbUV2ZW50ID0gZnVuY3Rpb24gQ3VzdG9tRXZlbnQoZXZlbnQsIHgpIHtcbiAgICAgIHggPSB4IHx8IHt9O1xuICAgICAgdmFyIGV2ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0N1c3RvbUV2ZW50Jyk7XG4gICAgICBldi5pbml0Q3VzdG9tRXZlbnQoZXZlbnQsICEheC5idWJibGVzLCAhIXguY2FuY2VsYWJsZSwgeC5kZXRhaWwgfHwgbnVsbCk7XG4gICAgICByZXR1cm4gZXY7XG4gICAgfTtcbiAgICBzdXBwb3J0Q3VzdG9tRXZlbnQucHJvdG90eXBlID0gd2luZG93LkV2ZW50LnByb3RvdHlwZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsIHRvIGNoZWNrIGZvciBzdGFja2luZyBjb250ZXh0XG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IHdoZXRoZXIgdGhpcyBlbCBvciBpdHMgcGFyZW50cyBjcmVhdGVzIGEgc3RhY2tpbmcgY29udGV4dFxuICAgKi9cbiAgZnVuY3Rpb24gY3JlYXRlc1N0YWNraW5nQ29udGV4dChlbCkge1xuICAgIHdoaWxlIChlbCAmJiBlbCAhPT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgdmFyIHMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCk7XG4gICAgICB2YXIgaW52YWxpZCA9IGZ1bmN0aW9uKGssIG9rKSB7XG4gICAgICAgIHJldHVybiAhKHNba10gPT09IHVuZGVmaW5lZCB8fCBzW2tdID09PSBvayk7XG4gICAgICB9XG4gICAgICBpZiAocy5vcGFjaXR5IDwgMSB8fFxuICAgICAgICAgIGludmFsaWQoJ3pJbmRleCcsICdhdXRvJykgfHxcbiAgICAgICAgICBpbnZhbGlkKCd0cmFuc2Zvcm0nLCAnbm9uZScpIHx8XG4gICAgICAgICAgaW52YWxpZCgnbWl4QmxlbmRNb2RlJywgJ25vcm1hbCcpIHx8XG4gICAgICAgICAgaW52YWxpZCgnZmlsdGVyJywgJ25vbmUnKSB8fFxuICAgICAgICAgIGludmFsaWQoJ3BlcnNwZWN0aXZlJywgJ25vbmUnKSB8fFxuICAgICAgICAgIHNbJ2lzb2xhdGlvbiddID09PSAnaXNvbGF0ZScgfHxcbiAgICAgICAgICBzLnBvc2l0aW9uID09PSAnZml4ZWQnIHx8XG4gICAgICAgICAgcy53ZWJraXRPdmVyZmxvd1Njcm9sbGluZyA9PT0gJ3RvdWNoJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGVsID0gZWwucGFyZW50RWxlbWVudDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIHRoZSBuZWFyZXN0IDxkaWFsb2c+IGZyb20gdGhlIHBhc3NlZCBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsIHRvIHNlYXJjaCBmcm9tXG4gICAqIEByZXR1cm4ge0hUTUxEaWFsb2dFbGVtZW50fSBkaWFsb2cgZm91bmRcbiAgICovXG4gIGZ1bmN0aW9uIGZpbmROZWFyZXN0RGlhbG9nKGVsKSB7XG4gICAgd2hpbGUgKGVsKSB7XG4gICAgICBpZiAoZWwubG9jYWxOYW1lID09PSAnZGlhbG9nJykge1xuICAgICAgICByZXR1cm4gLyoqIEB0eXBlIHtIVE1MRGlhbG9nRWxlbWVudH0gKi8gKGVsKTtcbiAgICAgIH1cbiAgICAgIGVsID0gZWwucGFyZW50RWxlbWVudDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQmx1ciB0aGUgc3BlY2lmaWVkIGVsZW1lbnQsIGFzIGxvbmcgYXMgaXQncyBub3QgdGhlIEhUTUwgYm9keSBlbGVtZW50LlxuICAgKiBUaGlzIHdvcmtzIGFyb3VuZCBhbiBJRTkvMTAgYnVnIC0gYmx1cnJpbmcgdGhlIGJvZHkgY2F1c2VzIFdpbmRvd3MgdG9cbiAgICogYmx1ciB0aGUgd2hvbGUgYXBwbGljYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWwgdG8gYmx1clxuICAgKi9cbiAgZnVuY3Rpb24gc2FmZUJsdXIoZWwpIHtcbiAgICBpZiAoZWwgJiYgZWwuYmx1ciAmJiBlbCAhPT0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgZWwuYmx1cigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0geyFOb2RlTGlzdH0gbm9kZUxpc3QgdG8gc2VhcmNoXG4gICAqIEBwYXJhbSB7Tm9kZX0gbm9kZSB0byBmaW5kXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IHdoZXRoZXIgbm9kZSBpcyBpbnNpZGUgbm9kZUxpc3RcbiAgICovXG4gIGZ1bmN0aW9uIGluTm9kZUxpc3Qobm9kZUxpc3QsIG5vZGUpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGVMaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAobm9kZUxpc3RbaV0gPT09IG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxGb3JtRWxlbWVudH0gZWwgdG8gY2hlY2tcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gd2hldGhlciB0aGlzIGZvcm0gaGFzIG1ldGhvZD1cImRpYWxvZ1wiXG4gICAqL1xuICBmdW5jdGlvbiBpc0Zvcm1NZXRob2REaWFsb2coZWwpIHtcbiAgICBpZiAoIWVsIHx8ICFlbC5oYXNBdHRyaWJ1dGUoJ21ldGhvZCcpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBlbC5nZXRBdHRyaWJ1dGUoJ21ldGhvZCcpLnRvTG93ZXJDYXNlKCkgPT09ICdkaWFsb2cnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IUhUTUxEaWFsb2dFbGVtZW50fSBkaWFsb2cgdG8gdXBncmFkZVxuICAgKiBAY29uc3RydWN0b3JcbiAgICovXG4gIGZ1bmN0aW9uIGRpYWxvZ1BvbHlmaWxsSW5mbyhkaWFsb2cpIHtcbiAgICB0aGlzLmRpYWxvZ18gPSBkaWFsb2c7XG4gICAgdGhpcy5yZXBsYWNlZFN0eWxlVG9wXyA9IGZhbHNlO1xuICAgIHRoaXMub3BlbkFzTW9kYWxfID0gZmFsc2U7XG5cbiAgICAvLyBTZXQgYTExeSByb2xlLiBCcm93c2VycyB0aGF0IHN1cHBvcnQgZGlhbG9nIGltcGxpY2l0bHkga25vdyB0aGlzIGFscmVhZHkuXG4gICAgaWYgKCFkaWFsb2cuaGFzQXR0cmlidXRlKCdyb2xlJykpIHtcbiAgICAgIGRpYWxvZy5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAnZGlhbG9nJyk7XG4gICAgfVxuXG4gICAgZGlhbG9nLnNob3cgPSB0aGlzLnNob3cuYmluZCh0aGlzKTtcbiAgICBkaWFsb2cuc2hvd01vZGFsID0gdGhpcy5zaG93TW9kYWwuYmluZCh0aGlzKTtcbiAgICBkaWFsb2cuY2xvc2UgPSB0aGlzLmNsb3NlLmJpbmQodGhpcyk7XG5cbiAgICBpZiAoISgncmV0dXJuVmFsdWUnIGluIGRpYWxvZykpIHtcbiAgICAgIGRpYWxvZy5yZXR1cm5WYWx1ZSA9ICcnO1xuICAgIH1cblxuICAgIGlmICgnTXV0YXRpb25PYnNlcnZlcicgaW4gd2luZG93KSB7XG4gICAgICB2YXIgbW8gPSBuZXcgTXV0YXRpb25PYnNlcnZlcih0aGlzLm1heWJlSGlkZU1vZGFsLmJpbmQodGhpcykpO1xuICAgICAgbW8ub2JzZXJ2ZShkaWFsb2csIHthdHRyaWJ1dGVzOiB0cnVlLCBhdHRyaWJ1dGVGaWx0ZXI6IFsnb3BlbiddfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElFMTAgYW5kIGJlbG93IHN1cHBvcnQuIE5vdGUgdGhhdCBET01Ob2RlUmVtb3ZlZCBldGMgZmlyZSBfYmVmb3JlXyByZW1vdmFsLiBUaGV5IGFsc29cbiAgICAgIC8vIHNlZW0gdG8gZmlyZSBldmVuIGlmIHRoZSBlbGVtZW50IHdhcyByZW1vdmVkIGFzIHBhcnQgb2YgYSBwYXJlbnQgcmVtb3ZhbC4gVXNlIHRoZSByZW1vdmVkXG4gICAgICAvLyBldmVudHMgdG8gZm9yY2UgZG93bmdyYWRlICh1c2VmdWwgaWYgcmVtb3ZlZC9pbW1lZGlhdGVseSBhZGRlZCkuXG4gICAgICB2YXIgcmVtb3ZlZCA9IGZhbHNlO1xuICAgICAgdmFyIGNiID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJlbW92ZWQgPyB0aGlzLmRvd25ncmFkZU1vZGFsKCkgOiB0aGlzLm1heWJlSGlkZU1vZGFsKCk7XG4gICAgICAgIHJlbW92ZWQgPSBmYWxzZTtcbiAgICAgIH0uYmluZCh0aGlzKTtcbiAgICAgIHZhciB0aW1lb3V0O1xuICAgICAgdmFyIGRlbGF5TW9kZWwgPSBmdW5jdGlvbihldikge1xuICAgICAgICBpZiAoZXYudGFyZ2V0ICE9PSBkaWFsb2cpIHsgcmV0dXJuOyB9ICAvLyBub3QgZm9yIGEgY2hpbGQgZWxlbWVudFxuICAgICAgICB2YXIgY2FuZCA9ICdET01Ob2RlUmVtb3ZlZCc7XG4gICAgICAgIHJlbW92ZWQgfD0gKGV2LnR5cGUuc3Vic3RyKDAsIGNhbmQubGVuZ3RoKSA9PT0gY2FuZCk7XG4gICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIHRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dChjYiwgMCk7XG4gICAgICB9O1xuICAgICAgWydET01BdHRyTW9kaWZpZWQnLCAnRE9NTm9kZVJlbW92ZWQnLCAnRE9NTm9kZVJlbW92ZWRGcm9tRG9jdW1lbnQnXS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgZGlhbG9nLmFkZEV2ZW50TGlzdGVuZXIobmFtZSwgZGVsYXlNb2RlbCk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gTm90ZSB0aGF0IHRoZSBET00gaXMgb2JzZXJ2ZWQgaW5zaWRlIERpYWxvZ01hbmFnZXIgd2hpbGUgYW55IGRpYWxvZ1xuICAgIC8vIGlzIGJlaW5nIGRpc3BsYXllZCBhcyBhIG1vZGFsLCB0byBjYXRjaCBtb2RhbCByZW1vdmFsIGZyb20gdGhlIERPTS5cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkaWFsb2csICdvcGVuJywge1xuICAgICAgc2V0OiB0aGlzLnNldE9wZW4uYmluZCh0aGlzKSxcbiAgICAgIGdldDogZGlhbG9nLmhhc0F0dHJpYnV0ZS5iaW5kKGRpYWxvZywgJ29wZW4nKVxuICAgIH0pO1xuXG4gICAgdGhpcy5iYWNrZHJvcF8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmJhY2tkcm9wXy5jbGFzc05hbWUgPSAnYmFja2Ryb3AnO1xuICAgIHRoaXMuYmFja2Ryb3BfLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5iYWNrZHJvcENsaWNrXy5iaW5kKHRoaXMpKTtcbiAgfVxuXG4gIGRpYWxvZ1BvbHlmaWxsSW5mby5wcm90b3R5cGUgPSB7XG5cbiAgICBnZXQgZGlhbG9nKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGlhbG9nXztcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogTWF5YmUgcmVtb3ZlIHRoaXMgZGlhbG9nIGZyb20gdGhlIG1vZGFsIHRvcCBsYXllci4gVGhpcyBpcyBjYWxsZWQgd2hlblxuICAgICAqIGEgbW9kYWwgZGlhbG9nIG1heSBubyBsb25nZXIgYmUgdGVuYWJsZSwgZS5nLiwgd2hlbiB0aGUgZGlhbG9nIGlzIG5vXG4gICAgICogbG9uZ2VyIG9wZW4gb3IgaXMgbm8gbG9uZ2VyIHBhcnQgb2YgdGhlIERPTS5cbiAgICAgKi9cbiAgICBtYXliZUhpZGVNb2RhbDogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5kaWFsb2dfLmhhc0F0dHJpYnV0ZSgnb3BlbicpICYmIGRvY3VtZW50LmJvZHkuY29udGFpbnModGhpcy5kaWFsb2dfKSkgeyByZXR1cm47IH1cbiAgICAgIHRoaXMuZG93bmdyYWRlTW9kYWwoKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHRoaXMgZGlhbG9nIGZyb20gdGhlIG1vZGFsIHRvcCBsYXllciwgbGVhdmluZyBpdCBhcyBhIG5vbi1tb2RhbC5cbiAgICAgKi9cbiAgICBkb3duZ3JhZGVNb2RhbDogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIXRoaXMub3BlbkFzTW9kYWxfKSB7IHJldHVybjsgfVxuICAgICAgdGhpcy5vcGVuQXNNb2RhbF8gPSBmYWxzZTtcbiAgICAgIHRoaXMuZGlhbG9nXy5zdHlsZS56SW5kZXggPSAnJztcblxuICAgICAgLy8gVGhpcyB3b24ndCBtYXRjaCB0aGUgbmF0aXZlIDxkaWFsb2c+IGV4YWN0bHkgYmVjYXVzZSBpZiB0aGUgdXNlciBzZXQgdG9wIG9uIGEgY2VudGVyZWRcbiAgICAgIC8vIHBvbHlmaWxsIGRpYWxvZywgdGhhdCB0b3AgZ2V0cyB0aHJvd24gYXdheSB3aGVuIHRoZSBkaWFsb2cgaXMgY2xvc2VkLiBOb3Qgc3VyZSBpdCdzXG4gICAgICAvLyBwb3NzaWJsZSB0byBwb2x5ZmlsbCB0aGlzIHBlcmZlY3RseS5cbiAgICAgIGlmICh0aGlzLnJlcGxhY2VkU3R5bGVUb3BfKSB7XG4gICAgICAgIHRoaXMuZGlhbG9nXy5zdHlsZS50b3AgPSAnJztcbiAgICAgICAgdGhpcy5yZXBsYWNlZFN0eWxlVG9wXyA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyBDbGVhciB0aGUgYmFja2Ryb3AgYW5kIHJlbW92ZSBmcm9tIHRoZSBtYW5hZ2VyLlxuICAgICAgdGhpcy5iYWNrZHJvcF8ucGFyZW50Tm9kZSAmJiB0aGlzLmJhY2tkcm9wXy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuYmFja2Ryb3BfKTtcbiAgICAgIGRpYWxvZ1BvbHlmaWxsLmRtLnJlbW92ZURpYWxvZyh0aGlzKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtib29sZWFufSB2YWx1ZSB3aGV0aGVyIHRvIG9wZW4gb3IgY2xvc2UgdGhpcyBkaWFsb2dcbiAgICAgKi9cbiAgICBzZXRPcGVuOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuZGlhbG9nXy5oYXNBdHRyaWJ1dGUoJ29wZW4nKSB8fCB0aGlzLmRpYWxvZ18uc2V0QXR0cmlidXRlKCdvcGVuJywgJycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5kaWFsb2dfLnJlbW92ZUF0dHJpYnV0ZSgnb3BlbicpO1xuICAgICAgICB0aGlzLm1heWJlSGlkZU1vZGFsKCk7ICAvLyBuYi4gcmVkdW5kYW50IHdpdGggTXV0YXRpb25PYnNlcnZlclxuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIGNsaWNrcyBvbiB0aGUgZmFrZSAuYmFja2Ryb3AgZWxlbWVudCwgcmVkaXJlY3RpbmcgdGhlbSBhcyBpZlxuICAgICAqIHRoZXkgd2VyZSBvbiB0aGUgZGlhbG9nIGl0c2VsZi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7IUV2ZW50fSBlIHRvIHJlZGlyZWN0XG4gICAgICovXG4gICAgYmFja2Ryb3BDbGlja186IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGlmICghdGhpcy5kaWFsb2dfLmhhc0F0dHJpYnV0ZSgndGFiaW5kZXgnKSkge1xuICAgICAgICAvLyBDbGlja2luZyBvbiB0aGUgYmFja2Ryb3Agc2hvdWxkIG1vdmUgdGhlIGltcGxpY2l0IGN1cnNvciwgZXZlbiBpZiBkaWFsb2cgY2Fubm90IGJlXG4gICAgICAgIC8vIGZvY3VzZWQuIENyZWF0ZSBhIGZha2UgdGhpbmcgdG8gZm9jdXMgb24uIElmIHRoZSBiYWNrZHJvcCB3YXMgX2JlZm9yZV8gdGhlIGRpYWxvZywgdGhpc1xuICAgICAgICAvLyB3b3VsZCBub3QgYmUgbmVlZGVkIC0gY2xpY2tzIHdvdWxkIG1vdmUgdGhlIGltcGxpY2l0IGN1cnNvciB0aGVyZS5cbiAgICAgICAgdmFyIGZha2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgdGhpcy5kaWFsb2dfLmluc2VydEJlZm9yZShmYWtlLCB0aGlzLmRpYWxvZ18uZmlyc3RDaGlsZCk7XG4gICAgICAgIGZha2UudGFiSW5kZXggPSAtMTtcbiAgICAgICAgZmFrZS5mb2N1cygpO1xuICAgICAgICB0aGlzLmRpYWxvZ18ucmVtb3ZlQ2hpbGQoZmFrZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRpYWxvZ18uZm9jdXMoKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHJlZGlyZWN0ZWRFdmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50cycpO1xuICAgICAgcmVkaXJlY3RlZEV2ZW50LmluaXRNb3VzZUV2ZW50KGUudHlwZSwgZS5idWJibGVzLCBlLmNhbmNlbGFibGUsIHdpbmRvdyxcbiAgICAgICAgICBlLmRldGFpbCwgZS5zY3JlZW5YLCBlLnNjcmVlblksIGUuY2xpZW50WCwgZS5jbGllbnRZLCBlLmN0cmxLZXksXG4gICAgICAgICAgZS5hbHRLZXksIGUuc2hpZnRLZXksIGUubWV0YUtleSwgZS5idXR0b24sIGUucmVsYXRlZFRhcmdldCk7XG4gICAgICB0aGlzLmRpYWxvZ18uZGlzcGF0Y2hFdmVudChyZWRpcmVjdGVkRXZlbnQpO1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRm9jdXNlcyBvbiB0aGUgZmlyc3QgZm9jdXNhYmxlIGVsZW1lbnQgd2l0aGluIHRoZSBkaWFsb2cuIFRoaXMgd2lsbCBhbHdheXMgYmx1ciB0aGUgY3VycmVudFxuICAgICAqIGZvY3VzLCBldmVuIGlmIG5vdGhpbmcgd2l0aGluIHRoZSBkaWFsb2cgaXMgZm91bmQuXG4gICAgICovXG4gICAgZm9jdXNfOiBmdW5jdGlvbigpIHtcbiAgICAgIC8vIEZpbmQgZWxlbWVudCB3aXRoIGBhdXRvZm9jdXNgIGF0dHJpYnV0ZSwgb3IgZmFsbCBiYWNrIHRvIHRoZSBmaXJzdCBmb3JtL3RhYmluZGV4IGNvbnRyb2wuXG4gICAgICB2YXIgdGFyZ2V0ID0gdGhpcy5kaWFsb2dfLnF1ZXJ5U2VsZWN0b3IoJ1thdXRvZm9jdXNdOm5vdChbZGlzYWJsZWRdKScpO1xuICAgICAgaWYgKCF0YXJnZXQgJiYgdGhpcy5kaWFsb2dfLnRhYkluZGV4ID49IDApIHtcbiAgICAgICAgdGFyZ2V0ID0gdGhpcy5kaWFsb2dfO1xuICAgICAgfVxuICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgJ2FueSBmb2N1c2FibGUgYXJlYScuIFRoaXMgbGlzdCBpcyBwcm9iYWJseSBub3QgZXhoYXVzdGl2ZSwgYnV0IHRoZVxuICAgICAgICAvLyBhbHRlcm5hdGl2ZSBpbnZvbHZlcyBzdGVwcGluZyB0aHJvdWdoIGFuZCB0cnlpbmcgdG8gZm9jdXMgZXZlcnl0aGluZy5cbiAgICAgICAgdmFyIG9wdHMgPSBbJ2J1dHRvbicsICdpbnB1dCcsICdrZXlnZW4nLCAnc2VsZWN0JywgJ3RleHRhcmVhJ107XG4gICAgICAgIHZhciBxdWVyeSA9IG9wdHMubWFwKGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgICAgcmV0dXJuIGVsICsgJzpub3QoW2Rpc2FibGVkXSknO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gVE9ETyhzYW10aG9yKTogdGFiaW5kZXggdmFsdWVzIHRoYXQgYXJlIG5vdCBudW1lcmljIGFyZSBub3QgZm9jdXNhYmxlLlxuICAgICAgICBxdWVyeS5wdXNoKCdbdGFiaW5kZXhdOm5vdChbZGlzYWJsZWRdKTpub3QoW3RhYmluZGV4PVwiXCJdKScpOyAgLy8gdGFiaW5kZXggIT0gXCJcIiwgbm90IGRpc2FibGVkXG4gICAgICAgIHRhcmdldCA9IHRoaXMuZGlhbG9nXy5xdWVyeVNlbGVjdG9yKHF1ZXJ5LmpvaW4oJywgJykpO1xuICAgICAgfVxuICAgICAgc2FmZUJsdXIoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCk7XG4gICAgICB0YXJnZXQgJiYgdGFyZ2V0LmZvY3VzKCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHpJbmRleCBmb3IgdGhlIGJhY2tkcm9wIGFuZCBkaWFsb2cuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGlhbG9nWlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiYWNrZHJvcFpcbiAgICAgKi9cbiAgICB1cGRhdGVaSW5kZXg6IGZ1bmN0aW9uKGRpYWxvZ1osIGJhY2tkcm9wWikge1xuICAgICAgaWYgKGRpYWxvZ1ogPCBiYWNrZHJvcFopIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkaWFsb2daIHNob3VsZCBuZXZlciBiZSA8IGJhY2tkcm9wWicpO1xuICAgICAgfVxuICAgICAgdGhpcy5kaWFsb2dfLnN0eWxlLnpJbmRleCA9IGRpYWxvZ1o7XG4gICAgICB0aGlzLmJhY2tkcm9wXy5zdHlsZS56SW5kZXggPSBiYWNrZHJvcFo7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNob3dzIHRoZSBkaWFsb2cuIElmIHRoZSBkaWFsb2cgaXMgYWxyZWFkeSBvcGVuLCB0aGlzIGRvZXMgbm90aGluZy5cbiAgICAgKi9cbiAgICBzaG93OiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghdGhpcy5kaWFsb2dfLm9wZW4pIHtcbiAgICAgICAgdGhpcy5zZXRPcGVuKHRydWUpO1xuICAgICAgICB0aGlzLmZvY3VzXygpO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTaG93IHRoaXMgZGlhbG9nIG1vZGFsbHkuXG4gICAgICovXG4gICAgc2hvd01vZGFsOiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmRpYWxvZ18uaGFzQXR0cmlidXRlKCdvcGVuJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gZXhlY3V0ZSBcXCdzaG93TW9kYWxcXCcgb24gZGlhbG9nOiBUaGUgZWxlbWVudCBpcyBhbHJlYWR5IG9wZW4sIGFuZCB0aGVyZWZvcmUgY2Fubm90IGJlIG9wZW5lZCBtb2RhbGx5LicpO1xuICAgICAgfVxuICAgICAgaWYgKCFkb2N1bWVudC5ib2R5LmNvbnRhaW5zKHRoaXMuZGlhbG9nXykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gZXhlY3V0ZSBcXCdzaG93TW9kYWxcXCcgb24gZGlhbG9nOiBUaGUgZWxlbWVudCBpcyBub3QgaW4gYSBEb2N1bWVudC4nKTtcbiAgICAgIH1cbiAgICAgIGlmICghZGlhbG9nUG9seWZpbGwuZG0ucHVzaERpYWxvZyh0aGlzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBleGVjdXRlIFxcJ3Nob3dNb2RhbFxcJyBvbiBkaWFsb2c6IFRoZXJlIGFyZSB0b28gbWFueSBvcGVuIG1vZGFsIGRpYWxvZ3MuJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjcmVhdGVzU3RhY2tpbmdDb250ZXh0KHRoaXMuZGlhbG9nXy5wYXJlbnRFbGVtZW50KSkge1xuICAgICAgICBjb25zb2xlLndhcm4oJ0EgZGlhbG9nIGlzIGJlaW5nIHNob3duIGluc2lkZSBhIHN0YWNraW5nIGNvbnRleHQuICcgK1xuICAgICAgICAgICAgJ1RoaXMgbWF5IGNhdXNlIGl0IHRvIGJlIHVudXNhYmxlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoaXMgbGluazogJyArXG4gICAgICAgICAgICAnaHR0cHM6Ly9naXRodWIuY29tL0dvb2dsZUNocm9tZS9kaWFsb2ctcG9seWZpbGwvI3N0YWNraW5nLWNvbnRleHQnKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXRPcGVuKHRydWUpO1xuICAgICAgdGhpcy5vcGVuQXNNb2RhbF8gPSB0cnVlO1xuXG4gICAgICAvLyBPcHRpb25hbGx5IGNlbnRlciB2ZXJ0aWNhbGx5LCByZWxhdGl2ZSB0byB0aGUgY3VycmVudCB2aWV3cG9ydC5cbiAgICAgIGlmIChkaWFsb2dQb2x5ZmlsbC5uZWVkc0NlbnRlcmluZyh0aGlzLmRpYWxvZ18pKSB7XG4gICAgICAgIGRpYWxvZ1BvbHlmaWxsLnJlcG9zaXRpb24odGhpcy5kaWFsb2dfKTtcbiAgICAgICAgdGhpcy5yZXBsYWNlZFN0eWxlVG9wXyA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlcGxhY2VkU3R5bGVUb3BfID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIC8vIEluc2VydCBiYWNrZHJvcC5cbiAgICAgIHRoaXMuZGlhbG9nXy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmJhY2tkcm9wXywgdGhpcy5kaWFsb2dfLm5leHRTaWJsaW5nKTtcblxuICAgICAgLy8gRm9jdXMgb24gd2hhdGV2ZXIgaW5zaWRlIHRoZSBkaWFsb2cuXG4gICAgICB0aGlzLmZvY3VzXygpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDbG9zZXMgdGhpcyBIVE1MRGlhbG9nRWxlbWVudC4gVGhpcyBpcyBvcHRpb25hbCB2cyBjbGVhcmluZyB0aGUgb3BlblxuICAgICAqIGF0dHJpYnV0ZSwgaG93ZXZlciB0aGlzIGZpcmVzIGEgJ2Nsb3NlJyBldmVudC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nPX0gb3B0X3JldHVyblZhbHVlIHRvIHVzZSBhcyB0aGUgcmV0dXJuVmFsdWVcbiAgICAgKi9cbiAgICBjbG9zZTogZnVuY3Rpb24ob3B0X3JldHVyblZhbHVlKSB7XG4gICAgICBpZiAoIXRoaXMuZGlhbG9nXy5oYXNBdHRyaWJ1dGUoJ29wZW4nKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBleGVjdXRlIFxcJ2Nsb3NlXFwnIG9uIGRpYWxvZzogVGhlIGVsZW1lbnQgZG9lcyBub3QgaGF2ZSBhbiBcXCdvcGVuXFwnIGF0dHJpYnV0ZSwgYW5kIHRoZXJlZm9yZSBjYW5ub3QgYmUgY2xvc2VkLicpO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRPcGVuKGZhbHNlKTtcblxuICAgICAgLy8gTGVhdmUgcmV0dXJuVmFsdWUgdW50b3VjaGVkIGluIGNhc2UgaXQgd2FzIHNldCBkaXJlY3RseSBvbiB0aGUgZWxlbWVudFxuICAgICAgaWYgKG9wdF9yZXR1cm5WYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuZGlhbG9nXy5yZXR1cm5WYWx1ZSA9IG9wdF9yZXR1cm5WYWx1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gVHJpZ2dlcmluZyBcImNsb3NlXCIgZXZlbnQgZm9yIGFueSBhdHRhY2hlZCBsaXN0ZW5lcnMgb24gdGhlIDxkaWFsb2c+LlxuICAgICAgdmFyIGNsb3NlRXZlbnQgPSBuZXcgc3VwcG9ydEN1c3RvbUV2ZW50KCdjbG9zZScsIHtcbiAgICAgICAgYnViYmxlczogZmFsc2UsXG4gICAgICAgIGNhbmNlbGFibGU6IGZhbHNlXG4gICAgICB9KTtcbiAgICAgIHRoaXMuZGlhbG9nXy5kaXNwYXRjaEV2ZW50KGNsb3NlRXZlbnQpO1xuICAgIH1cblxuICB9O1xuXG4gIHZhciBkaWFsb2dQb2x5ZmlsbCA9IHt9O1xuXG4gIGRpYWxvZ1BvbHlmaWxsLnJlcG9zaXRpb24gPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgdmFyIHNjcm9sbFRvcCA9IGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3A7XG4gICAgdmFyIHRvcFZhbHVlID0gc2Nyb2xsVG9wICsgKHdpbmRvdy5pbm5lckhlaWdodCAtIGVsZW1lbnQub2Zmc2V0SGVpZ2h0KSAvIDI7XG4gICAgZWxlbWVudC5zdHlsZS50b3AgPSBNYXRoLm1heChzY3JvbGxUb3AsIHRvcFZhbHVlKSArICdweCc7XG4gIH07XG5cbiAgZGlhbG9nUG9seWZpbGwuaXNJbmxpbmVQb3NpdGlvblNldEJ5U3R5bGVzaGVldCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRvY3VtZW50LnN0eWxlU2hlZXRzLmxlbmd0aDsgKytpKSB7XG4gICAgICB2YXIgc3R5bGVTaGVldCA9IGRvY3VtZW50LnN0eWxlU2hlZXRzW2ldO1xuICAgICAgdmFyIGNzc1J1bGVzID0gbnVsbDtcbiAgICAgIC8vIFNvbWUgYnJvd3NlcnMgdGhyb3cgb24gY3NzUnVsZXMuXG4gICAgICB0cnkge1xuICAgICAgICBjc3NSdWxlcyA9IHN0eWxlU2hlZXQuY3NzUnVsZXM7XG4gICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgaWYgKCFjc3NSdWxlcykgeyBjb250aW51ZTsgfVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBjc3NSdWxlcy5sZW5ndGg7ICsraikge1xuICAgICAgICB2YXIgcnVsZSA9IGNzc1J1bGVzW2pdO1xuICAgICAgICB2YXIgc2VsZWN0ZWROb2RlcyA9IG51bGw7XG4gICAgICAgIC8vIElnbm9yZSBlcnJvcnMgb24gaW52YWxpZCBzZWxlY3RvciB0ZXh0cy5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBzZWxlY3RlZE5vZGVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChydWxlLnNlbGVjdG9yVGV4dCk7XG4gICAgICAgIH0gY2F0Y2goZSkge31cbiAgICAgICAgaWYgKCFzZWxlY3RlZE5vZGVzIHx8ICFpbk5vZGVMaXN0KHNlbGVjdGVkTm9kZXMsIGVsZW1lbnQpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNzc1RvcCA9IHJ1bGUuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgndG9wJyk7XG4gICAgICAgIHZhciBjc3NCb3R0b20gPSBydWxlLnN0eWxlLmdldFByb3BlcnR5VmFsdWUoJ2JvdHRvbScpO1xuICAgICAgICBpZiAoKGNzc1RvcCAmJiBjc3NUb3AgIT09ICdhdXRvJykgfHwgKGNzc0JvdHRvbSAmJiBjc3NCb3R0b20gIT09ICdhdXRvJykpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG5cbiAgZGlhbG9nUG9seWZpbGwubmVlZHNDZW50ZXJpbmcgPSBmdW5jdGlvbihkaWFsb2cpIHtcbiAgICB2YXIgY29tcHV0ZWRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGRpYWxvZyk7XG4gICAgaWYgKGNvbXB1dGVkU3R5bGUucG9zaXRpb24gIT09ICdhYnNvbHV0ZScpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBXZSBtdXN0IGRldGVybWluZSB3aGV0aGVyIHRoZSB0b3AvYm90dG9tIHNwZWNpZmllZCB2YWx1ZSBpcyBub24tYXV0by4gIEluXG4gICAgLy8gV2ViS2l0L0JsaW5rLCBjaGVja2luZyBjb21wdXRlZFN0eWxlLnRvcCA9PSAnYXV0bycgaXMgc3VmZmljaWVudCwgYnV0XG4gICAgLy8gRmlyZWZveCByZXR1cm5zIHRoZSB1c2VkIHZhbHVlLiBTbyB3ZSBkbyB0aGlzIGNyYXp5IHRoaW5nIGluc3RlYWQ6IGNoZWNrXG4gICAgLy8gdGhlIGlubGluZSBzdHlsZSBhbmQgdGhlbiBnbyB0aHJvdWdoIENTUyBydWxlcy5cbiAgICBpZiAoKGRpYWxvZy5zdHlsZS50b3AgIT09ICdhdXRvJyAmJiBkaWFsb2cuc3R5bGUudG9wICE9PSAnJykgfHxcbiAgICAgICAgKGRpYWxvZy5zdHlsZS5ib3R0b20gIT09ICdhdXRvJyAmJiBkaWFsb2cuc3R5bGUuYm90dG9tICE9PSAnJykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuICFkaWFsb2dQb2x5ZmlsbC5pc0lubGluZVBvc2l0aW9uU2V0QnlTdHlsZXNoZWV0KGRpYWxvZyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgdG8gZm9yY2UgdXBncmFkZVxuICAgKi9cbiAgZGlhbG9nUG9seWZpbGwuZm9yY2VSZWdpc3RlckRpYWxvZyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBpZiAod2luZG93LkhUTUxEaWFsb2dFbGVtZW50IHx8IGVsZW1lbnQuc2hvd01vZGFsKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1RoaXMgYnJvd3NlciBhbHJlYWR5IHN1cHBvcnRzIDxkaWFsb2c+LCB0aGUgcG9seWZpbGwgJyArXG4gICAgICAgICAgJ21heSBub3Qgd29yayBjb3JyZWN0bHknLCBlbGVtZW50KTtcbiAgICB9XG4gICAgaWYgKGVsZW1lbnQubG9jYWxOYW1lICE9PSAnZGlhbG9nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcmVnaXN0ZXIgZGlhbG9nOiBUaGUgZWxlbWVudCBpcyBub3QgYSBkaWFsb2cuJyk7XG4gICAgfVxuICAgIG5ldyBkaWFsb2dQb2x5ZmlsbEluZm8oLyoqIEB0eXBlIHshSFRNTERpYWxvZ0VsZW1lbnR9ICovIChlbGVtZW50KSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgdG8gdXBncmFkZSwgaWYgbmVjZXNzYXJ5XG4gICAqL1xuICBkaWFsb2dQb2x5ZmlsbC5yZWdpc3RlckRpYWxvZyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBpZiAoIWVsZW1lbnQuc2hvd01vZGFsKSB7XG4gICAgICBkaWFsb2dQb2x5ZmlsbC5mb3JjZVJlZ2lzdGVyRGlhbG9nKGVsZW1lbnQpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqL1xuICBkaWFsb2dQb2x5ZmlsbC5EaWFsb2dNYW5hZ2VyID0gZnVuY3Rpb24oKSB7XG4gICAgLyoqIEB0eXBlIHshQXJyYXk8IWRpYWxvZ1BvbHlmaWxsSW5mbz59ICovXG4gICAgdGhpcy5wZW5kaW5nRGlhbG9nU3RhY2sgPSBbXTtcblxuICAgIHZhciBjaGVja0RPTSA9IHRoaXMuY2hlY2tET01fLmJpbmQodGhpcyk7XG5cbiAgICAvLyBUaGUgb3ZlcmxheSBpcyB1c2VkIHRvIHNpbXVsYXRlIGhvdyBhIG1vZGFsIGRpYWxvZyBibG9ja3MgdGhlIGRvY3VtZW50LlxuICAgIC8vIFRoZSBibG9ja2luZyBkaWFsb2cgaXMgcG9zaXRpb25lZCBvbiB0b3Agb2YgdGhlIG92ZXJsYXksIGFuZCB0aGUgcmVzdCBvZlxuICAgIC8vIHRoZSBkaWFsb2dzIG9uIHRoZSBwZW5kaW5nIGRpYWxvZyBzdGFjayBhcmUgcG9zaXRpb25lZCBiZWxvdyBpdC4gSW4gdGhlXG4gICAgLy8gYWN0dWFsIGltcGxlbWVudGF0aW9uLCB0aGUgbW9kYWwgZGlhbG9nIHN0YWNraW5nIGlzIGNvbnRyb2xsZWQgYnkgdGhlXG4gICAgLy8gdG9wIGxheWVyLCB3aGVyZSB6LWluZGV4IGhhcyBubyBlZmZlY3QuXG4gICAgdGhpcy5vdmVybGF5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5vdmVybGF5LmNsYXNzTmFtZSA9ICdfZGlhbG9nX292ZXJsYXknO1xuICAgIHRoaXMub3ZlcmxheS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIHRoaXMuZm9yd2FyZFRhYl8gPSB1bmRlZmluZWQ7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgY2hlY2tET00oW10pOyAgLy8gc2FuaXR5LWNoZWNrIERPTVxuICAgIH0uYmluZCh0aGlzKSk7XG5cbiAgICB0aGlzLmhhbmRsZUtleV8gPSB0aGlzLmhhbmRsZUtleV8uYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZUZvY3VzXyA9IHRoaXMuaGFuZGxlRm9jdXNfLmJpbmQodGhpcyk7XG5cbiAgICB0aGlzLnpJbmRleExvd18gPSAxMDAwMDA7XG4gICAgdGhpcy56SW5kZXhIaWdoXyA9IDEwMDAwMCArIDE1MDtcblxuICAgIHRoaXMuZm9yd2FyZFRhYl8gPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAoJ011dGF0aW9uT2JzZXJ2ZXInIGluIHdpbmRvdykge1xuICAgICAgdGhpcy5tb18gPSBuZXcgTXV0YXRpb25PYnNlcnZlcihmdW5jdGlvbihyZWNvcmRzKSB7XG4gICAgICAgIHZhciByZW1vdmVkID0gW107XG4gICAgICAgIHJlY29yZHMuZm9yRWFjaChmdW5jdGlvbihyZWMpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMCwgYzsgYyA9IHJlYy5yZW1vdmVkTm9kZXNbaV07ICsraSkge1xuICAgICAgICAgICAgaWYgKCEoYyBpbnN0YW5jZW9mIEVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjLmxvY2FsTmFtZSA9PT0gJ2RpYWxvZycpIHtcbiAgICAgICAgICAgICAgcmVtb3ZlZC5wdXNoKGMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVtb3ZlZCA9IHJlbW92ZWQuY29uY2F0KGMucXVlcnlTZWxlY3RvckFsbCgnZGlhbG9nJykpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJlbW92ZWQubGVuZ3RoICYmIGNoZWNrRE9NKHJlbW92ZWQpO1xuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBDYWxsZWQgb24gdGhlIGZpcnN0IG1vZGFsIGRpYWxvZyBiZWluZyBzaG93bi4gQWRkcyB0aGUgb3ZlcmxheSBhbmQgcmVsYXRlZFxuICAgKiBoYW5kbGVycy5cbiAgICovXG4gIGRpYWxvZ1BvbHlmaWxsLkRpYWxvZ01hbmFnZXIucHJvdG90eXBlLmJsb2NrRG9jdW1lbnQgPSBmdW5jdGlvbigpIHtcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCB0aGlzLmhhbmRsZUZvY3VzXywgdHJ1ZSk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMuaGFuZGxlS2V5Xyk7XG4gICAgdGhpcy5tb18gJiYgdGhpcy5tb18ub2JzZXJ2ZShkb2N1bWVudCwge2NoaWxkTGlzdDogdHJ1ZSwgc3VidHJlZTogdHJ1ZX0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDYWxsZWQgb24gdGhlIGZpcnN0IG1vZGFsIGRpYWxvZyBiZWluZyByZW1vdmVkLCBpLmUuLCB3aGVuIG5vIG1vcmUgbW9kYWxcbiAgICogZGlhbG9ncyBhcmUgdmlzaWJsZS5cbiAgICovXG4gIGRpYWxvZ1BvbHlmaWxsLkRpYWxvZ01hbmFnZXIucHJvdG90eXBlLnVuYmxvY2tEb2N1bWVudCA9IGZ1bmN0aW9uKCkge1xuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1cycsIHRoaXMuaGFuZGxlRm9jdXNfLCB0cnVlKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5oYW5kbGVLZXlfKTtcbiAgICB0aGlzLm1vXyAmJiB0aGlzLm1vXy5kaXNjb25uZWN0KCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIHN0YWNraW5nIG9mIGFsbCBrbm93biBkaWFsb2dzLlxuICAgKi9cbiAgZGlhbG9nUG9seWZpbGwuRGlhbG9nTWFuYWdlci5wcm90b3R5cGUudXBkYXRlU3RhY2tpbmcgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgekluZGV4ID0gdGhpcy56SW5kZXhIaWdoXztcblxuICAgIGZvciAodmFyIGkgPSAwLCBkcGk7IGRwaSA9IHRoaXMucGVuZGluZ0RpYWxvZ1N0YWNrW2ldOyArK2kpIHtcbiAgICAgIGRwaS51cGRhdGVaSW5kZXgoLS16SW5kZXgsIC0tekluZGV4KTtcbiAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgIHRoaXMub3ZlcmxheS5zdHlsZS56SW5kZXggPSAtLXpJbmRleDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNYWtlIHRoZSBvdmVybGF5IGEgc2libGluZyBvZiB0aGUgZGlhbG9nIGl0c2VsZi5cbiAgICB2YXIgbGFzdCA9IHRoaXMucGVuZGluZ0RpYWxvZ1N0YWNrWzBdO1xuICAgIGlmIChsYXN0KSB7XG4gICAgICB2YXIgcCA9IGxhc3QuZGlhbG9nLnBhcmVudE5vZGUgfHwgZG9jdW1lbnQuYm9keTtcbiAgICAgIHAuYXBwZW5kQ2hpbGQodGhpcy5vdmVybGF5KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMub3ZlcmxheS5wYXJlbnROb2RlKSB7XG4gICAgICB0aGlzLm92ZXJsYXkucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLm92ZXJsYXkpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSBjYW5kaWRhdGUgdG8gY2hlY2sgaWYgY29udGFpbmVkIG9yIGlzIHRoZSB0b3AtbW9zdCBtb2RhbCBkaWFsb2dcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gd2hldGhlciBjYW5kaWRhdGUgaXMgY29udGFpbmVkIGluIHRvcCBkaWFsb2dcbiAgICovXG4gIGRpYWxvZ1BvbHlmaWxsLkRpYWxvZ01hbmFnZXIucHJvdG90eXBlLmNvbnRhaW5lZEJ5VG9wRGlhbG9nXyA9IGZ1bmN0aW9uKGNhbmRpZGF0ZSkge1xuICAgIHdoaWxlIChjYW5kaWRhdGUgPSBmaW5kTmVhcmVzdERpYWxvZyhjYW5kaWRhdGUpKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgZHBpOyBkcGkgPSB0aGlzLnBlbmRpbmdEaWFsb2dTdGFja1tpXTsgKytpKSB7XG4gICAgICAgIGlmIChkcGkuZGlhbG9nID09PSBjYW5kaWRhdGUpIHtcbiAgICAgICAgICByZXR1cm4gaSA9PT0gMDsgIC8vIG9ubHkgdmFsaWQgaWYgdG9wLW1vc3RcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2FuZGlkYXRlID0gY2FuZGlkYXRlLnBhcmVudEVsZW1lbnQ7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICBkaWFsb2dQb2x5ZmlsbC5EaWFsb2dNYW5hZ2VyLnByb3RvdHlwZS5oYW5kbGVGb2N1c18gPSBmdW5jdGlvbihldmVudCkge1xuICAgIGlmICh0aGlzLmNvbnRhaW5lZEJ5VG9wRGlhbG9nXyhldmVudC50YXJnZXQpKSB7IHJldHVybjsgfVxuXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBzYWZlQmx1cigvKiogQHR5cGUge0VsZW1lbnR9ICovIChldmVudC50YXJnZXQpKTtcblxuICAgIGlmICh0aGlzLmZvcndhcmRUYWJfID09PSB1bmRlZmluZWQpIHsgcmV0dXJuOyB9ICAvLyBtb3ZlIGZvY3VzIG9ubHkgZnJvbSBhIHRhYiBrZXlcblxuICAgIHZhciBkcGkgPSB0aGlzLnBlbmRpbmdEaWFsb2dTdGFja1swXTtcbiAgICB2YXIgZGlhbG9nID0gZHBpLmRpYWxvZztcbiAgICB2YXIgcG9zaXRpb24gPSBkaWFsb2cuY29tcGFyZURvY3VtZW50UG9zaXRpb24oZXZlbnQudGFyZ2V0KTtcbiAgICBpZiAocG9zaXRpb24gJiBOb2RlLkRPQ1VNRU5UX1BPU0lUSU9OX1BSRUNFRElORykge1xuICAgICAgaWYgKHRoaXMuZm9yd2FyZFRhYl8pIHsgIC8vIGZvcndhcmRcbiAgICAgICAgZHBpLmZvY3VzXygpO1xuICAgICAgfSBlbHNlIHsgIC8vIGJhY2t3YXJkc1xuICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogRm9jdXMgYWZ0ZXIgdGhlIGRpYWxvZywgaXMgaWdub3JlZC5cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG5cbiAgZGlhbG9nUG9seWZpbGwuRGlhbG9nTWFuYWdlci5wcm90b3R5cGUuaGFuZGxlS2V5XyA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdGhpcy5mb3J3YXJkVGFiXyA9IHVuZGVmaW5lZDtcbiAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gMjcpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIHZhciBjYW5jZWxFdmVudCA9IG5ldyBzdXBwb3J0Q3VzdG9tRXZlbnQoJ2NhbmNlbCcsIHtcbiAgICAgICAgYnViYmxlczogZmFsc2UsXG4gICAgICAgIGNhbmNlbGFibGU6IHRydWVcbiAgICAgIH0pO1xuICAgICAgdmFyIGRwaSA9IHRoaXMucGVuZGluZ0RpYWxvZ1N0YWNrWzBdO1xuICAgICAgaWYgKGRwaSAmJiBkcGkuZGlhbG9nLmRpc3BhdGNoRXZlbnQoY2FuY2VsRXZlbnQpKSB7XG4gICAgICAgIGRwaS5kaWFsb2cuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV2ZW50LmtleUNvZGUgPT09IDkpIHtcbiAgICAgIHRoaXMuZm9yd2FyZFRhYl8gPSAhZXZlbnQuc2hpZnRLZXk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBGaW5kcyBhbmQgZG93bmdyYWRlcyBhbnkga25vd24gbW9kYWwgZGlhbG9ncyB0aGF0IGFyZSBubyBsb25nZXIgZGlzcGxheWVkLiBEaWFsb2dzIHRoYXQgYXJlXG4gICAqIHJlbW92ZWQgYW5kIGltbWVkaWF0ZWx5IHJlYWRkZWQgZG9uJ3Qgc3RheSBtb2RhbCwgdGhleSBiZWNvbWUgbm9ybWFsLlxuICAgKlxuICAgKiBAcGFyYW0geyFBcnJheTwhSFRNTERpYWxvZ0VsZW1lbnQ+fSByZW1vdmVkIHRoYXQgaGF2ZSBkZWZpbml0ZWx5IGJlZW4gcmVtb3ZlZFxuICAgKi9cbiAgZGlhbG9nUG9seWZpbGwuRGlhbG9nTWFuYWdlci5wcm90b3R5cGUuY2hlY2tET01fID0gZnVuY3Rpb24ocmVtb3ZlZCkge1xuICAgIC8vIFRoaXMgb3BlcmF0ZXMgb24gYSBjbG9uZSBiZWNhdXNlIGl0IG1heSBjYXVzZSBpdCB0byBjaGFuZ2UuIEVhY2ggY2hhbmdlIGFsc28gY2FsbHNcbiAgICAvLyB1cGRhdGVTdGFja2luZywgd2hpY2ggb25seSBhY3R1YWxseSBuZWVkcyB0byBoYXBwZW4gb25jZS4gQnV0IHdobyByZW1vdmVzIG1hbnkgbW9kYWwgZGlhbG9nc1xuICAgIC8vIGF0IGEgdGltZT8hXG4gICAgdmFyIGNsb25lID0gdGhpcy5wZW5kaW5nRGlhbG9nU3RhY2suc2xpY2UoKTtcbiAgICBjbG9uZS5mb3JFYWNoKGZ1bmN0aW9uKGRwaSkge1xuICAgICAgaWYgKHJlbW92ZWQuaW5kZXhPZihkcGkuZGlhbG9nKSAhPT0gLTEpIHtcbiAgICAgICAgZHBpLmRvd25ncmFkZU1vZGFsKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkcGkubWF5YmVIaWRlTW9kYWwoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvKipcbiAgICogQHBhcmFtIHshZGlhbG9nUG9seWZpbGxJbmZvfSBkcGlcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gd2hldGhlciB0aGUgZGlhbG9nIHdhcyBhbGxvd2VkXG4gICAqL1xuICBkaWFsb2dQb2x5ZmlsbC5EaWFsb2dNYW5hZ2VyLnByb3RvdHlwZS5wdXNoRGlhbG9nID0gZnVuY3Rpb24oZHBpKSB7XG4gICAgdmFyIGFsbG93ZWQgPSAodGhpcy56SW5kZXhIaWdoXyAtIHRoaXMuekluZGV4TG93XykgLyAyIC0gMTtcbiAgICBpZiAodGhpcy5wZW5kaW5nRGlhbG9nU3RhY2subGVuZ3RoID49IGFsbG93ZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHRoaXMucGVuZGluZ0RpYWxvZ1N0YWNrLnVuc2hpZnQoZHBpKSA9PT0gMSkge1xuICAgICAgdGhpcy5ibG9ja0RvY3VtZW50KCk7XG4gICAgfVxuICAgIHRoaXMudXBkYXRlU3RhY2tpbmcoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICAvKipcbiAgICogQHBhcmFtIHshZGlhbG9nUG9seWZpbGxJbmZvfSBkcGlcbiAgICovXG4gIGRpYWxvZ1BvbHlmaWxsLkRpYWxvZ01hbmFnZXIucHJvdG90eXBlLnJlbW92ZURpYWxvZyA9IGZ1bmN0aW9uKGRwaSkge1xuICAgIHZhciBpbmRleCA9IHRoaXMucGVuZGluZ0RpYWxvZ1N0YWNrLmluZGV4T2YoZHBpKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7IHJldHVybjsgfVxuXG4gICAgdGhpcy5wZW5kaW5nRGlhbG9nU3RhY2suc3BsaWNlKGluZGV4LCAxKTtcbiAgICBpZiAodGhpcy5wZW5kaW5nRGlhbG9nU3RhY2subGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLnVuYmxvY2tEb2N1bWVudCgpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZVN0YWNraW5nKCk7XG4gIH07XG5cbiAgZGlhbG9nUG9seWZpbGwuZG0gPSBuZXcgZGlhbG9nUG9seWZpbGwuRGlhbG9nTWFuYWdlcigpO1xuICBkaWFsb2dQb2x5ZmlsbC5mb3JtU3VibWl0dGVyID0gbnVsbDtcbiAgZGlhbG9nUG9seWZpbGwudXNlVmFsdWUgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBJbnN0YWxscyBnbG9iYWwgaGFuZGxlcnMsIHN1Y2ggYXMgY2xpY2sgbGlzdGVycyBhbmQgbmF0aXZlIG1ldGhvZCBvdmVycmlkZXMuIFRoZXNlIGFyZSBuZWVkZWRcbiAgICogZXZlbiBpZiBhIG5vIGRpYWxvZyBpcyByZWdpc3RlcmVkLCBhcyB0aGV5IGRlYWwgd2l0aCA8Zm9ybSBtZXRob2Q9XCJkaWFsb2dcIj4uXG4gICAqL1xuICBpZiAod2luZG93LkhUTUxEaWFsb2dFbGVtZW50ID09PSB1bmRlZmluZWQpIHtcblxuICAgIC8qKlxuICAgICAqIElmIEhUTUxGb3JtRWxlbWVudCB0cmFuc2xhdGVzIG1ldGhvZD1cIkRJQUxPR1wiIGludG8gJ2dldCcsIHRoZW4gcmVwbGFjZSB0aGUgZGVzY3JpcHRvciB3aXRoXG4gICAgICogb25lIHRoYXQgcmV0dXJucyB0aGUgY29ycmVjdCB2YWx1ZS5cbiAgICAgKi9cbiAgICB2YXIgdGVzdEZvcm0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdmb3JtJyk7XG4gICAgdGVzdEZvcm0uc2V0QXR0cmlidXRlKCdtZXRob2QnLCAnZGlhbG9nJyk7XG4gICAgaWYgKHRlc3RGb3JtLm1ldGhvZCAhPT0gJ2RpYWxvZycpIHtcbiAgICAgIHZhciBtZXRob2REZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihIVE1MRm9ybUVsZW1lbnQucHJvdG90eXBlLCAnbWV0aG9kJyk7XG4gICAgICBpZiAobWV0aG9kRGVzY3JpcHRvcikge1xuICAgICAgICAvLyBuYi4gU29tZSBvbGRlciBpT1MgYW5kIG9sZGVyIFBoYW50b21KUyBmYWlsIHRvIHJldHVybiB0aGUgZGVzY3JpcHRvci4gRG9uJ3QgZG8gYW55dGhpbmdcbiAgICAgICAgLy8gYW5kIGRvbid0IGJvdGhlciB0byB1cGRhdGUgdGhlIGVsZW1lbnQuXG4gICAgICAgIHZhciByZWFsR2V0ID0gbWV0aG9kRGVzY3JpcHRvci5nZXQ7XG4gICAgICAgIG1ldGhvZERlc2NyaXB0b3IuZ2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKGlzRm9ybU1ldGhvZERpYWxvZyh0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuICdkaWFsb2cnO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmVhbEdldC5jYWxsKHRoaXMpO1xuICAgICAgICB9O1xuICAgICAgICB2YXIgcmVhbFNldCA9IG1ldGhvZERlc2NyaXB0b3Iuc2V0O1xuICAgICAgICBtZXRob2REZXNjcmlwdG9yLnNldCA9IGZ1bmN0aW9uKHYpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHYgPT09ICdzdHJpbmcnICYmIHYudG9Mb3dlckNhc2UoKSA9PT0gJ2RpYWxvZycpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNldEF0dHJpYnV0ZSgnbWV0aG9kJywgdik7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByZWFsU2V0LmNhbGwodGhpcywgdik7XG4gICAgICAgIH07XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShIVE1MRm9ybUVsZW1lbnQucHJvdG90eXBlLCAnbWV0aG9kJywgbWV0aG9kRGVzY3JpcHRvcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2xvYmFsICdjbGljaycgaGFuZGxlciwgdG8gY2FwdHVyZSB0aGUgPGlucHV0IHR5cGU9XCJzdWJtaXRcIj4gb3IgPGJ1dHRvbj4gZWxlbWVudCB3aGljaCBoYXNcbiAgICAgKiBzdWJtaXR0ZWQgYSA8Zm9ybSBtZXRob2Q9XCJkaWFsb2dcIj4uIE5lZWRlZCBhcyBTYWZhcmkgYW5kIG90aGVycyBkb24ndCByZXBvcnQgdGhpcyBpbnNpZGVcbiAgICAgKiBkb2N1bWVudC5hY3RpdmVFbGVtZW50LlxuICAgICAqL1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZXYpIHtcbiAgICAgIGRpYWxvZ1BvbHlmaWxsLmZvcm1TdWJtaXR0ZXIgPSBudWxsO1xuICAgICAgZGlhbG9nUG9seWZpbGwudXNlVmFsdWUgPSBudWxsO1xuICAgICAgaWYgKGV2LmRlZmF1bHRQcmV2ZW50ZWQpIHsgcmV0dXJuOyB9ICAvLyBlLmcuIGEgc3VibWl0IHdoaWNoIHByZXZlbnRzIGRlZmF1bHQgc3VibWlzc2lvblxuXG4gICAgICB2YXIgdGFyZ2V0ID0gLyoqIEB0eXBlIHtFbGVtZW50fSAqLyAoZXYudGFyZ2V0KTtcbiAgICAgIGlmICghdGFyZ2V0IHx8ICFpc0Zvcm1NZXRob2REaWFsb2codGFyZ2V0LmZvcm0pKSB7IHJldHVybjsgfVxuXG4gICAgICB2YXIgdmFsaWQgPSAodGFyZ2V0LnR5cGUgPT09ICdzdWJtaXQnICYmIFsnYnV0dG9uJywgJ2lucHV0J10uaW5kZXhPZih0YXJnZXQubG9jYWxOYW1lKSA+IC0xKTtcbiAgICAgIGlmICghdmFsaWQpIHtcbiAgICAgICAgaWYgKCEodGFyZ2V0LmxvY2FsTmFtZSA9PT0gJ2lucHV0JyAmJiB0YXJnZXQudHlwZSA9PT0gJ2ltYWdlJykpIHsgcmV0dXJuOyB9XG4gICAgICAgIC8vIHRoaXMgaXMgYSA8aW5wdXQgdHlwZT1cImltYWdlXCI+LCB3aGljaCBjYW4gc3VibWl0IGZvcm1zXG4gICAgICAgIGRpYWxvZ1BvbHlmaWxsLnVzZVZhbHVlID0gZXYub2Zmc2V0WCArICcsJyArIGV2Lm9mZnNldFk7XG4gICAgICB9XG5cbiAgICAgIHZhciBkaWFsb2cgPSBmaW5kTmVhcmVzdERpYWxvZyh0YXJnZXQpO1xuICAgICAgaWYgKCFkaWFsb2cpIHsgcmV0dXJuOyB9XG5cbiAgICAgIGRpYWxvZ1BvbHlmaWxsLmZvcm1TdWJtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgfSwgZmFsc2UpO1xuXG4gICAgLyoqXG4gICAgICogUmVwbGFjZSB0aGUgbmF0aXZlIEhUTUxGb3JtRWxlbWVudC5zdWJtaXQoKSBtZXRob2QsIGFzIGl0IHdvbid0IGZpcmUgdGhlXG4gICAgICogc3VibWl0IGV2ZW50IGFuZCBnaXZlIHVzIGEgY2hhbmNlIHRvIHJlc3BvbmQuXG4gICAgICovXG4gICAgdmFyIG5hdGl2ZUZvcm1TdWJtaXQgPSBIVE1MRm9ybUVsZW1lbnQucHJvdG90eXBlLnN1Ym1pdDtcbiAgICB2YXIgcmVwbGFjZW1lbnRGb3JtU3VibWl0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKCFpc0Zvcm1NZXRob2REaWFsb2codGhpcykpIHtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUZvcm1TdWJtaXQuY2FsbCh0aGlzKTtcbiAgICAgIH1cbiAgICAgIHZhciBkaWFsb2cgPSBmaW5kTmVhcmVzdERpYWxvZyh0aGlzKTtcbiAgICAgIGRpYWxvZyAmJiBkaWFsb2cuY2xvc2UoKTtcbiAgICB9O1xuICAgIEhUTUxGb3JtRWxlbWVudC5wcm90b3R5cGUuc3VibWl0ID0gcmVwbGFjZW1lbnRGb3JtU3VibWl0O1xuXG4gICAgLyoqXG4gICAgICogR2xvYmFsIGZvcm0gJ2RpYWxvZycgbWV0aG9kIGhhbmRsZXIuIENsb3NlcyBhIGRpYWxvZyBjb3JyZWN0bHkgb24gc3VibWl0XG4gICAgICogYW5kIHBvc3NpYmx5IHNldHMgaXRzIHJldHVybiB2YWx1ZS5cbiAgICAgKi9cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdzdWJtaXQnLCBmdW5jdGlvbihldikge1xuICAgICAgdmFyIGZvcm0gPSAvKiogQHR5cGUge0hUTUxGb3JtRWxlbWVudH0gKi8gKGV2LnRhcmdldCk7XG4gICAgICBpZiAoIWlzRm9ybU1ldGhvZERpYWxvZyhmb3JtKSkgeyByZXR1cm47IH1cbiAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgIHZhciBkaWFsb2cgPSBmaW5kTmVhcmVzdERpYWxvZyhmb3JtKTtcbiAgICAgIGlmICghZGlhbG9nKSB7IHJldHVybjsgfVxuXG4gICAgICAvLyBGb3JtcyBjYW4gb25seSBiZSBzdWJtaXR0ZWQgdmlhIC5zdWJtaXQoKSBvciBhIGNsaWNrICg/KSwgYnV0IGFueXdheTogc2FuaXR5LWNoZWNrIHRoYXRcbiAgICAgIC8vIHRoZSBzdWJtaXR0ZXIgaXMgY29ycmVjdCBiZWZvcmUgdXNpbmcgaXRzIHZhbHVlIGFzIC5yZXR1cm5WYWx1ZS5cbiAgICAgIHZhciBzID0gZGlhbG9nUG9seWZpbGwuZm9ybVN1Ym1pdHRlcjtcbiAgICAgIGlmIChzICYmIHMuZm9ybSA9PT0gZm9ybSkge1xuICAgICAgICBkaWFsb2cuY2xvc2UoZGlhbG9nUG9seWZpbGwudXNlVmFsdWUgfHwgcy52YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaWFsb2cuY2xvc2UoKTtcbiAgICAgIH1cbiAgICAgIGRpYWxvZ1BvbHlmaWxsLmZvcm1TdWJtaXR0ZXIgPSBudWxsO1xuICAgIH0sIHRydWUpO1xuICB9XG5cbiAgZGlhbG9nUG9seWZpbGxbJ2ZvcmNlUmVnaXN0ZXJEaWFsb2cnXSA9IGRpYWxvZ1BvbHlmaWxsLmZvcmNlUmVnaXN0ZXJEaWFsb2c7XG4gIGRpYWxvZ1BvbHlmaWxsWydyZWdpc3RlckRpYWxvZyddID0gZGlhbG9nUG9seWZpbGwucmVnaXN0ZXJEaWFsb2c7XG5cbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgJ2FtZCcgaW4gZGVmaW5lKSB7XG4gICAgLy8gQU1EIHN1cHBvcnRcbiAgICBkZWZpbmUoZnVuY3Rpb24oKSB7IHJldHVybiBkaWFsb2dQb2x5ZmlsbDsgfSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZVsnZXhwb3J0cyddID09PSAnb2JqZWN0Jykge1xuICAgIC8vIENvbW1vbkpTIHN1cHBvcnRcbiAgICBtb2R1bGVbJ2V4cG9ydHMnXSA9IGRpYWxvZ1BvbHlmaWxsO1xuICB9IGVsc2Uge1xuICAgIC8vIGFsbCBvdGhlcnNcbiAgICB3aW5kb3dbJ2RpYWxvZ1BvbHlmaWxsJ10gPSBkaWFsb2dQb2x5ZmlsbDtcbiAgfVxufSkoKTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5c00\n")}}]);

TODO found
Open

    // TODO: enforce spot.driver === 'client'
Severity: Minor
Found in docs/api/app.js.html by fixme

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.moment"],{da01:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js\n\n;(function (global, factory) {\n     true ? module.exports = factory() :\n    undefined\n}(this, (function () { 'use strict';\n\n    var hookCallback;\n\n    function hooks () {\n        return hookCallback.apply(null, arguments);\n    }\n\n    // This is done to register the method called with moment()\n    // without creating circular dependencies.\n    function setHookCallback (callback) {\n        hookCallback = callback;\n    }\n\n    function isArray(input) {\n        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n    }\n\n    function isObject(input) {\n        // IE8 will treat undefined and null as object if it wasn't for\n        // input != null\n        return input != null && Object.prototype.toString.call(input) === '[object Object]';\n    }\n\n    function isObjectEmpty(obj) {\n        if (Object.getOwnPropertyNames) {\n            return (Object.getOwnPropertyNames(obj).length === 0);\n        } else {\n            var k;\n            for (k in obj) {\n                if (obj.hasOwnProperty(k)) {\n                    return false;\n                }\n            }\n            return true;\n        }\n    }\n\n    function isUndefined(input) {\n        return input === void 0;\n    }\n\n    function isNumber(input) {\n        return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n    }\n\n    function isDate(input) {\n        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n    }\n\n    function map(arr, fn) {\n        var res = [], i;\n        for (i = 0; i < arr.length; ++i) {\n            res.push(fn(arr[i], i));\n        }\n        return res;\n    }\n\n    function hasOwnProp(a, b) {\n        return Object.prototype.hasOwnProperty.call(a, b);\n    }\n\n    function extend(a, b) {\n        for (var i in b) {\n            if (hasOwnProp(b, i)) {\n                a[i] = b[i];\n            }\n        }\n\n        if (hasOwnProp(b, 'toString')) {\n            a.toString = b.toString;\n        }\n\n        if (hasOwnProp(b, 'valueOf')) {\n            a.valueOf = b.valueOf;\n        }\n\n        return a;\n    }\n\n    function createUTC (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, true).utc();\n    }\n\n    function defaultParsingFlags() {\n        // We need to deep clone this object.\n        return {\n            empty           : false,\n            unusedTokens    : [],\n            unusedInput     : [],\n            overflow        : -2,\n            charsLeftOver   : 0,\n            nullInput       : false,\n            invalidMonth    : null,\n            invalidFormat   : false,\n            userInvalidated : false,\n            iso             : false,\n            parsedDateParts : [],\n            meridiem        : null,\n            rfc2822         : false,\n            weekdayMismatch : false\n        };\n    }\n\n    function getParsingFlags(m) {\n        if (m._pf == null) {\n            m._pf = defaultParsingFlags();\n        }\n        return m._pf;\n    }\n\n    var some;\n    if (Array.prototype.some) {\n        some = Array.prototype.some;\n    } else {\n        some = function (fun) {\n            var t = Object(this);\n            var len = t.length >>> 0;\n\n            for (var i = 0; i < len; i++) {\n                if (i in t && fun.call(this, t[i], i, t)) {\n                    return true;\n                }\n            }\n\n            return false;\n        };\n    }\n\n    function isValid(m) {\n        if (m._isValid == null) {\n            var flags = getParsingFlags(m);\n            var parsedParts = some.call(flags.parsedDateParts, function (i) {\n                return i != null;\n            });\n            var isNowValid = !isNaN(m._d.getTime()) &&\n                flags.overflow < 0 &&\n                !flags.empty &&\n                !flags.invalidMonth &&\n                !flags.invalidWeekday &&\n                !flags.weekdayMismatch &&\n                !flags.nullInput &&\n                !flags.invalidFormat &&\n                !flags.userInvalidated &&\n                (!flags.meridiem || (flags.meridiem && parsedParts));\n\n            if (m._strict) {\n                isNowValid = isNowValid &&\n                    flags.charsLeftOver === 0 &&\n                    flags.unusedTokens.length === 0 &&\n                    flags.bigHour === undefined;\n            }\n\n            if (Object.isFrozen == null || !Object.isFrozen(m)) {\n                m._isValid = isNowValid;\n            }\n            else {\n                return isNowValid;\n            }\n        }\n        return m._isValid;\n    }\n\n    function createInvalid (flags) {\n        var m = createUTC(NaN);\n        if (flags != null) {\n            extend(getParsingFlags(m), flags);\n        }\n        else {\n            getParsingFlags(m).userInvalidated = true;\n        }\n\n        return m;\n    }\n\n    // Plugins that add properties should also add the key here (null value),\n    // so we can properly clone ourselves.\n    var momentProperties = hooks.momentProperties = [];\n\n    function copyConfig(to, from) {\n        var i, prop, val;\n\n        if (!isUndefined(from._isAMomentObject)) {\n            to._isAMomentObject = from._isAMomentObject;\n        }\n        if (!isUndefined(from._i)) {\n            to._i = from._i;\n        }\n        if (!isUndefined(from._f)) {\n            to._f = from._f;\n        }\n        if (!isUndefined(from._l)) {\n            to._l = from._l;\n        }\n        if (!isUndefined(from._strict)) {\n            to._strict = from._strict;\n        }\n        if (!isUndefined(from._tzm)) {\n            to._tzm = from._tzm;\n        }\n        if (!isUndefined(from._isUTC)) {\n            to._isUTC = from._isUTC;\n        }\n        if (!isUndefined(from._offset)) {\n            to._offset = from._offset;\n        }\n        if (!isUndefined(from._pf)) {\n            to._pf = getParsingFlags(from);\n        }\n        if (!isUndefined(from._locale)) {\n            to._locale = from._locale;\n        }\n\n        if (momentProperties.length > 0) {\n            for (i = 0; i < momentProperties.length; i++) {\n                prop = momentProperties[i];\n                val = from[prop];\n                if (!isUndefined(val)) {\n                    to[prop] = val;\n                }\n            }\n        }\n\n        return to;\n    }\n\n    var updateInProgress = false;\n\n    // Moment prototype object\n    function Moment(config) {\n        copyConfig(this, config);\n        this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n        if (!this.isValid()) {\n            this._d = new Date(NaN);\n        }\n        // Prevent infinite loop in case updateOffset creates new moment\n        // objects.\n        if (updateInProgress === false) {\n            updateInProgress = true;\n            hooks.updateOffset(this);\n            updateInProgress = false;\n        }\n    }\n\n    function isMoment (obj) {\n        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n    }\n\n    function absFloor (number) {\n        if (number < 0) {\n            // -0 -> 0\n            return Math.ceil(number) || 0;\n        } else {\n            return Math.floor(number);\n        }\n    }\n\n    function toInt(argumentForCoercion) {\n        var coercedNumber = +argumentForCoercion,\n            value = 0;\n\n        if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n            value = absFloor(coercedNumber);\n        }\n\n        return value;\n    }\n\n    // compare two arrays, return the number of differences\n    function compareArrays(array1, array2, dontConvert) {\n        var len = Math.min(array1.length, array2.length),\n            lengthDiff = Math.abs(array1.length - array2.length),\n            diffs = 0,\n            i;\n        for (i = 0; i < len; i++) {\n            if ((dontConvert && array1[i] !== array2[i]) ||\n                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n                diffs++;\n            }\n        }\n        return diffs + lengthDiff;\n    }\n\n    function warn(msg) {\n        if (hooks.suppressDeprecationWarnings === false &&\n                (typeof console !==  'undefined') && console.warn) {\n            console.warn('Deprecation warning: ' + msg);\n        }\n    }\n\n    function deprecate(msg, fn) {\n        var firstTime = true;\n\n        return extend(function () {\n            if (hooks.deprecationHandler != null) {\n                hooks.deprecationHandler(null, msg);\n            }\n            if (firstTime) {\n                var args = [];\n                var arg;\n                for (var i = 0; i < arguments.length; i++) {\n                    arg = '';\n                    if (typeof arguments[i] === 'object') {\n                        arg += '\\n[' + i + '] ';\n                        for (var key in arguments[0]) {\n                            arg += key + ': ' + arguments[0][key] + ', ';\n                        }\n                        arg = arg.slice(0, -2); // Remove trailing comma and space\n                    } else {\n                        arg = arguments[i];\n                    }\n                    args.push(arg);\n                }\n                warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n                firstTime = false;\n            }\n            return fn.apply(this, arguments);\n        }, fn);\n    }\n\n    var deprecations = {};\n\n    function deprecateSimple(name, msg) {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(name, msg);\n        }\n        if (!deprecations[name]) {\n            warn(msg);\n            deprecations[name] = true;\n        }\n    }\n\n    hooks.suppressDeprecationWarnings = false;\n    hooks.deprecationHandler = null;\n\n    function isFunction(input) {\n        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n    }\n\n    function set (config) {\n        var prop, i;\n        for (i in config) {\n            prop = config[i];\n            if (isFunction(prop)) {\n                this[i] = prop;\n            } else {\n                this['_' + i] = prop;\n            }\n        }\n        this._config = config;\n        // Lenient ordinal parsing accepts just a number in addition to\n        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n        // TODO: Remove \"ordinalParse\" fallback in next major release.\n        this._dayOfMonthOrdinalParseLenient = new RegExp(\n            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n                '|' + (/\\d{1,2}/).source);\n    }\n\n    function mergeConfigs(parentConfig, childConfig) {\n        var res = extend({}, parentConfig), prop;\n        for (prop in childConfig) {\n            if (hasOwnProp(childConfig, prop)) {\n                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                    res[prop] = {};\n                    extend(res[prop], parentConfig[prop]);\n                    extend(res[prop], childConfig[prop]);\n                } else if (childConfig[prop] != null) {\n                    res[prop] = childConfig[prop];\n                } else {\n                    delete res[prop];\n                }\n            }\n        }\n        for (prop in parentConfig) {\n            if (hasOwnProp(parentConfig, prop) &&\n                    !hasOwnProp(childConfig, prop) &&\n                    isObject(parentConfig[prop])) {\n                // make sure changes to properties don't modify parent config\n                res[prop] = extend({}, res[prop]);\n            }\n        }\n        return res;\n    }\n\n    function Locale(config) {\n        if (config != null) {\n            this.set(config);\n        }\n    }\n\n    var keys;\n\n    if (Object.keys) {\n        keys = Object.keys;\n    } else {\n        keys = function (obj) {\n            var i, res = [];\n            for (i in obj) {\n                if (hasOwnProp(obj, i)) {\n                    res.push(i);\n                }\n            }\n            return res;\n        };\n    }\n\n    var defaultCalendar = {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    };\n\n    function calendar (key, mom, now) {\n        var output = this._calendar[key] || this._calendar['sameElse'];\n        return isFunction(output) ? output.call(mom, now) : output;\n    }\n\n    var defaultLongDateFormat = {\n        LTS  : 'h:mm:ss A',\n        LT   : 'h:mm A',\n        L    : 'MM/DD/YYYY',\n        LL   : 'MMMM D, YYYY',\n        LLL  : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    };\n\n    function longDateFormat (key) {\n        var format = this._longDateFormat[key],\n            formatUpper = this._longDateFormat[key.toUpperCase()];\n\n        if (format || !formatUpper) {\n            return format;\n        }\n\n        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n            return val.slice(1);\n        });\n\n        return this._longDateFormat[key];\n    }\n\n    var defaultInvalidDate = 'Invalid date';\n\n    function invalidDate () {\n        return this._invalidDate;\n    }\n\n    var defaultOrdinal = '%d';\n    var defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\n    function ordinal (number) {\n        return this._ordinal.replace('%d', number);\n    }\n\n    var defaultRelativeTime = {\n        future : 'in %s',\n        past   : '%s ago',\n        s  : 'a few seconds',\n        ss : '%d seconds',\n        m  : 'a minute',\n        mm : '%d minutes',\n        h  : 'an hour',\n        hh : '%d hours',\n        d  : 'a day',\n        dd : '%d days',\n        M  : 'a month',\n        MM : '%d months',\n        y  : 'a year',\n        yy : '%d years'\n    };\n\n    function relativeTime (number, withoutSuffix, string, isFuture) {\n        var output = this._relativeTime[string];\n        return (isFunction(output)) ?\n            output(number, withoutSuffix, string, isFuture) :\n            output.replace(/%d/i, number);\n    }\n\n    function pastFuture (diff, output) {\n        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n        return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n    }\n\n    var aliases = {};\n\n    function addUnitAlias (unit, shorthand) {\n        var lowerCase = unit.toLowerCase();\n        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n    }\n\n    function normalizeUnits(units) {\n        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n    }\n\n    function normalizeObjectUnits(inputObject) {\n        var normalizedInput = {},\n            normalizedProp,\n            prop;\n\n        for (prop in inputObject) {\n            if (hasOwnProp(inputObject, prop)) {\n                normalizedProp = normalizeUnits(prop);\n                if (normalizedProp) {\n                    normalizedInput[normalizedProp] = inputObject[prop];\n                }\n            }\n        }\n\n        return normalizedInput;\n    }\n\n    var priorities = {};\n\n    function addUnitPriority(unit, priority) {\n        priorities[unit] = priority;\n    }\n\n    function getPrioritizedUnits(unitsObj) {\n        var units = [];\n        for (var u in unitsObj) {\n            units.push({unit: u, priority: priorities[u]});\n        }\n        units.sort(function (a, b) {\n            return a.priority - b.priority;\n        });\n        return units;\n    }\n\n    function zeroFill(number, targetLength, forceSign) {\n        var absNumber = '' + Math.abs(number),\n            zerosToFill = targetLength - absNumber.length,\n            sign = number >= 0;\n        return (sign ? (forceSign ? '+' : '') : '-') +\n            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n    }\n\n    var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\n    var localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\n    var formatFunctions = {};\n\n    var formatTokenFunctions = {};\n\n    // token:    'M'\n    // padded:   ['MM', 2]\n    // ordinal:  'Mo'\n    // callback: function () { this.month() + 1 }\n    function addFormatToken (token, padded, ordinal, callback) {\n        var func = callback;\n        if (typeof callback === 'string') {\n            func = function () {\n                return this[callback]();\n            };\n        }\n        if (token) {\n            formatTokenFunctions[token] = func;\n        }\n        if (padded) {\n            formatTokenFunctions[padded[0]] = function () {\n                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n            };\n        }\n        if (ordinal) {\n            formatTokenFunctions[ordinal] = function () {\n                return this.localeData().ordinal(func.apply(this, arguments), token);\n            };\n        }\n    }\n\n    function removeFormattingTokens(input) {\n        if (input.match(/\\[[\\s\\S]/)) {\n            return input.replace(/^\\[|\\]$/g, '');\n        }\n        return input.replace(/\\\\/g, '');\n    }\n\n    function makeFormatFunction(format) {\n        var array = format.match(formattingTokens), i, length;\n\n        for (i = 0, length = array.length; i < length; i++) {\n            if (formatTokenFunctions[array[i]]) {\n                array[i] = formatTokenFunctions[array[i]];\n            } else {\n                array[i] = removeFormattingTokens(array[i]);\n            }\n        }\n\n        return function (mom) {\n            var output = '', i;\n            for (i = 0; i < length; i++) {\n                output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n            }\n            return output;\n        };\n    }\n\n    // format date using native date object\n    function formatMoment(m, format) {\n        if (!m.isValid()) {\n            return m.localeData().invalidDate();\n        }\n\n        format = expandFormat(format, m.localeData());\n        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n        return formatFunctions[format](m);\n    }\n\n    function expandFormat(format, locale) {\n        var i = 5;\n\n        function replaceLongDateFormatTokens(input) {\n            return locale.longDateFormat(input) || input;\n        }\n\n        localFormattingTokens.lastIndex = 0;\n        while (i >= 0 && localFormattingTokens.test(format)) {\n            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n            localFormattingTokens.lastIndex = 0;\n            i -= 1;\n        }\n\n        return format;\n    }\n\n    var match1         = /\\d/;            //       0 - 9\n    var match2         = /\\d\\d/;          //      00 - 99\n    var match3         = /\\d{3}/;         //     000 - 999\n    var match4         = /\\d{4}/;         //    0000 - 9999\n    var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\n    var match1to2      = /\\d\\d?/;         //       0 - 99\n    var match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\n    var match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\n    var match1to3      = /\\d{1,3}/;       //       0 - 999\n    var match1to4      = /\\d{1,4}/;       //       0 - 9999\n    var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\n    var matchUnsigned  = /\\d+/;           //       0 - inf\n    var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\n    var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n    var matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\n    var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n    // any word (or two) characters or numbers including two/three word month in arabic.\n    // includes scottish gaelic two word and hyphenated months\n    var matchWord = /[0-9]{0,256}['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFF07\\uFF10-\\uFFEF]{1,256}|[\\u0600-\\u06FF\\/]{1,256}(\\s*?[\\u0600-\\u06FF]{1,256}){1,2}/i;\n\n    var regexes = {};\n\n    function addRegexToken (token, regex, strictRegex) {\n        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n            return (isStrict && strictRegex) ? strictRegex : regex;\n        };\n    }\n\n    function getParseRegexForToken (token, config) {\n        if (!hasOwnProp(regexes, token)) {\n            return new RegExp(unescapeFormat(token));\n        }\n\n        return regexes[token](config._strict, config._locale);\n    }\n\n    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\n    function unescapeFormat(s) {\n        return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n            return p1 || p2 || p3 || p4;\n        }));\n    }\n\n    function regexEscape(s) {\n        return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n    }\n\n    var tokens = {};\n\n    function addParseToken (token, callback) {\n        var i, func = callback;\n        if (typeof token === 'string') {\n            token = [token];\n        }\n        if (isNumber(callback)) {\n            func = function (input, array) {\n                array[callback] = toInt(input);\n            };\n        }\n        for (i = 0; i < token.length; i++) {\n            tokens[token[i]] = func;\n        }\n    }\n\n    function addWeekParseToken (token, callback) {\n        addParseToken(token, function (input, array, config, token) {\n            config._w = config._w || {};\n            callback(input, config._w, config, token);\n        });\n    }\n\n    function addTimeToArrayFromToken(token, input, config) {\n        if (input != null && hasOwnProp(tokens, token)) {\n            tokens[token](input, config._a, config, token);\n        }\n    }\n\n    var YEAR = 0;\n    var MONTH = 1;\n    var DATE = 2;\n    var HOUR = 3;\n    var MINUTE = 4;\n    var SECOND = 5;\n    var MILLISECOND = 6;\n    var WEEK = 7;\n    var WEEKDAY = 8;\n\n    // FORMATTING\n\n    addFormatToken('Y', 0, 0, function () {\n        var y = this.year();\n        return y <= 9999 ? '' + y : '+' + y;\n    });\n\n    addFormatToken(0, ['YY', 2], 0, function () {\n        return this.year() % 100;\n    });\n\n    addFormatToken(0, ['YYYY',   4],       0, 'year');\n    addFormatToken(0, ['YYYYY',  5],       0, 'year');\n    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n    // ALIASES\n\n    addUnitAlias('year', 'y');\n\n    // PRIORITIES\n\n    addUnitPriority('year', 1);\n\n    // PARSING\n\n    addRegexToken('Y',      matchSigned);\n    addRegexToken('YY',     match1to2, match2);\n    addRegexToken('YYYY',   match1to4, match4);\n    addRegexToken('YYYYY',  match1to6, match6);\n    addRegexToken('YYYYYY', match1to6, match6);\n\n    addParseToken(['YYYYY', 'YYYYYY'], YEAR);\n    addParseToken('YYYY', function (input, array) {\n        array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n    });\n    addParseToken('YY', function (input, array) {\n        array[YEAR] = hooks.parseTwoDigitYear(input);\n    });\n    addParseToken('Y', function (input, array) {\n        array[YEAR] = parseInt(input, 10);\n    });\n\n    // HELPERS\n\n    function daysInYear(year) {\n        return isLeapYear(year) ? 366 : 365;\n    }\n\n    function isLeapYear(year) {\n        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n    }\n\n    // HOOKS\n\n    hooks.parseTwoDigitYear = function (input) {\n        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n    };\n\n    // MOMENTS\n\n    var getSetYear = makeGetSet('FullYear', true);\n\n    function getIsLeapYear () {\n        return isLeapYear(this.year());\n    }\n\n    function makeGetSet (unit, keepTime) {\n        return function (value) {\n            if (value != null) {\n                set$1(this, unit, value);\n                hooks.updateOffset(this, keepTime);\n                return this;\n            } else {\n                return get(this, unit);\n            }\n        };\n    }\n\n    function get (mom, unit) {\n        return mom.isValid() ?\n            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n    }\n\n    function set$1 (mom, unit, value) {\n        if (mom.isValid() && !isNaN(value)) {\n            if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {\n                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));\n            }\n            else {\n                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function stringGet (units) {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units]();\n        }\n        return this;\n    }\n\n\n    function stringSet (units, value) {\n        if (typeof units === 'object') {\n            units = normalizeObjectUnits(units);\n            var prioritized = getPrioritizedUnits(units);\n            for (var i = 0; i < prioritized.length; i++) {\n                this[prioritized[i].unit](units[prioritized[i].unit]);\n            }\n        } else {\n            units = normalizeUnits(units);\n            if (isFunction(this[units])) {\n                return this[units](value);\n            }\n        }\n        return this;\n    }\n\n    function mod(n, x) {\n        return ((n % x) + x) % x;\n    }\n\n    var indexOf;\n\n    if (Array.prototype.indexOf) {\n        indexOf = Array.prototype.indexOf;\n    } else {\n        indexOf = function (o) {\n            // I know\n            var i;\n            for (i = 0; i < this.length; ++i) {\n                if (this[i] === o) {\n                    return i;\n                }\n            }\n            return -1;\n        };\n    }\n\n    function daysInMonth(year, month) {\n        if (isNaN(year) || isNaN(month)) {\n            return NaN;\n        }\n        var modMonth = mod(month, 12);\n        year += (month - modMonth) / 12;\n        return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);\n    }\n\n    // FORMATTING\n\n    addFormatToken('M', ['MM', 2], 'Mo', function () {\n        return this.month() + 1;\n    });\n\n    addFormatToken('MMM', 0, 0, function (format) {\n        return this.localeData().monthsShort(this, format);\n    });\n\n    addFormatToken('MMMM', 0, 0, function (format) {\n        return this.localeData().months(this, format);\n    });\n\n    // ALIASES\n\n    addUnitAlias('month', 'M');\n\n    // PRIORITY\n\n    addUnitPriority('month', 8);\n\n    // PARSING\n\n    addRegexToken('M',    match1to2);\n    addRegexToken('MM',   match1to2, match2);\n    addRegexToken('MMM',  function (isStrict, locale) {\n        return locale.monthsShortRegex(isStrict);\n    });\n    addRegexToken('MMMM', function (isStrict, locale) {\n        return locale.monthsRegex(isStrict);\n    });\n\n    addParseToken(['M', 'MM'], function (input, array) {\n        array[MONTH] = toInt(input) - 1;\n    });\n\n    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n        var month = config._locale.monthsParse(input, token, config._strict);\n        // if we didn't find a month name, mark the date as invalid.\n        if (month != null) {\n            array[MONTH] = month;\n        } else {\n            getParsingFlags(config).invalidMonth = input;\n        }\n    });\n\n    // LOCALES\n\n    var MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\n    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\n    function localeMonths (m, format) {\n        if (!m) {\n            return isArray(this._months) ? this._months :\n                this._months['standalone'];\n        }\n        return isArray(this._months) ? this._months[m.month()] :\n            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n    }\n\n    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\n    function localeMonthsShort (m, format) {\n        if (!m) {\n            return isArray(this._monthsShort) ? this._monthsShort :\n                this._monthsShort['standalone'];\n        }\n        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n    }\n\n    function handleStrictParse(monthName, format, strict) {\n        var i, ii, mom, llc = monthName.toLocaleLowerCase();\n        if (!this._monthsParse) {\n            // this is not used\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n            for (i = 0; i < 12; ++i) {\n                mom = createUTC([2000, i]);\n                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n            }\n        }\n\n        if (strict) {\n            if (format === 'MMM') {\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._longMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        } else {\n            if (format === 'MMM') {\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._longMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._longMonthsParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        }\n    }\n\n    function localeMonthsParse (monthName, format, strict) {\n        var i, mom, regex;\n\n        if (this._monthsParseExact) {\n            return handleStrictParse.call(this, monthName, format, strict);\n        }\n\n        if (!this._monthsParse) {\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n        }\n\n        // TODO: add sorting\n        // Sorting makes sure if one month (or abbr) is a prefix of another\n        // see sorting in computeMonthsParse\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, i]);\n            if (strict && !this._longMonthsParse[i]) {\n                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n            }\n            if (!strict && !this._monthsParse[i]) {\n                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (!strict && this._monthsParse[i].test(monthName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function setMonth (mom, value) {\n        var dayOfMonth;\n\n        if (!mom.isValid()) {\n            // No op\n            return mom;\n        }\n\n        if (typeof value === 'string') {\n            if (/^\\d+$/.test(value)) {\n                value = toInt(value);\n            } else {\n                value = mom.localeData().monthsParse(value);\n                // TODO: Another silent failure?\n                if (!isNumber(value)) {\n                    return mom;\n                }\n            }\n        }\n\n        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n        return mom;\n    }\n\n    function getSetMonth (value) {\n        if (value != null) {\n            setMonth(this, value);\n            hooks.updateOffset(this, true);\n            return this;\n        } else {\n            return get(this, 'Month');\n        }\n    }\n\n    function getDaysInMonth () {\n        return daysInMonth(this.year(), this.month());\n    }\n\n    var defaultMonthsShortRegex = matchWord;\n    function monthsShortRegex (isStrict) {\n        if (this._monthsParseExact) {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                computeMonthsParse.call(this);\n            }\n            if (isStrict) {\n                return this._monthsShortStrictRegex;\n            } else {\n                return this._monthsShortRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_monthsShortRegex')) {\n                this._monthsShortRegex = defaultMonthsShortRegex;\n            }\n            return this._monthsShortStrictRegex && isStrict ?\n                this._monthsShortStrictRegex : this._monthsShortRegex;\n        }\n    }\n\n    var defaultMonthsRegex = matchWord;\n    function monthsRegex (isStrict) {\n        if (this._monthsParseExact) {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                computeMonthsParse.call(this);\n            }\n            if (isStrict) {\n                return this._monthsStrictRegex;\n            } else {\n                return this._monthsRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                this._monthsRegex = defaultMonthsRegex;\n            }\n            return this._monthsStrictRegex && isStrict ?\n                this._monthsStrictRegex : this._monthsRegex;\n        }\n    }\n\n    function computeMonthsParse () {\n        function cmpLenRev(a, b) {\n            return b.length - a.length;\n        }\n\n        var shortPieces = [], longPieces = [], mixedPieces = [],\n            i, mom;\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, i]);\n            shortPieces.push(this.monthsShort(mom, ''));\n            longPieces.push(this.months(mom, ''));\n            mixedPieces.push(this.months(mom, ''));\n            mixedPieces.push(this.monthsShort(mom, ''));\n        }\n        // Sorting makes sure if one month (or abbr) is a prefix of another it\n        // will match the longer piece.\n        shortPieces.sort(cmpLenRev);\n        longPieces.sort(cmpLenRev);\n        mixedPieces.sort(cmpLenRev);\n        for (i = 0; i < 12; i++) {\n            shortPieces[i] = regexEscape(shortPieces[i]);\n            longPieces[i] = regexEscape(longPieces[i]);\n        }\n        for (i = 0; i < 24; i++) {\n            mixedPieces[i] = regexEscape(mixedPieces[i]);\n        }\n\n        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n        this._monthsShortRegex = this._monthsRegex;\n        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    }\n\n    function createDate (y, m, d, h, M, s, ms) {\n        // can't just apply() to create a date:\n        // https://stackoverflow.com/q/181348\n        var date;\n        // the date constructor remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            date = new Date(y + 400, m, d, h, M, s, ms);\n            if (isFinite(date.getFullYear())) {\n                date.setFullYear(y);\n            }\n        } else {\n            date = new Date(y, m, d, h, M, s, ms);\n        }\n\n        return date;\n    }\n\n    function createUTCDate (y) {\n        var date;\n        // the Date.UTC function remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            var args = Array.prototype.slice.call(arguments);\n            // preserve leap years using a full 400 year cycle, then reset\n            args[0] = y + 400;\n            date = new Date(Date.UTC.apply(null, args));\n            if (isFinite(date.getUTCFullYear())) {\n                date.setUTCFullYear(y);\n            }\n        } else {\n            date = new Date(Date.UTC.apply(null, arguments));\n        }\n\n        return date;\n    }\n\n    // start-of-first-week - start-of-year\n    function firstWeekOffset(year, dow, doy) {\n        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n            fwd = 7 + dow - doy,\n            // first-week day local weekday -- which local weekday is fwd\n            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n        return -fwdlw + fwd - 1;\n    }\n\n    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\n    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n        var localWeekday = (7 + weekday - dow) % 7,\n            weekOffset = firstWeekOffset(year, dow, doy),\n            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n            resYear, resDayOfYear;\n\n        if (dayOfYear <= 0) {\n            resYear = year - 1;\n            resDayOfYear = daysInYear(resYear) + dayOfYear;\n        } else if (dayOfYear > daysInYear(year)) {\n            resYear = year + 1;\n            resDayOfYear = dayOfYear - daysInYear(year);\n        } else {\n            resYear = year;\n            resDayOfYear = dayOfYear;\n        }\n\n        return {\n            year: resYear,\n            dayOfYear: resDayOfYear\n        };\n    }\n\n    function weekOfYear(mom, dow, doy) {\n        var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n            resWeek, resYear;\n\n        if (week < 1) {\n            resYear = mom.year() - 1;\n            resWeek = week + weeksInYear(resYear, dow, doy);\n        } else if (week > weeksInYear(mom.year(), dow, doy)) {\n            resWeek = week - weeksInYear(mom.year(), dow, doy);\n            resYear = mom.year() + 1;\n        } else {\n            resYear = mom.year();\n            resWeek = week;\n        }\n\n        return {\n            week: resWeek,\n            year: resYear\n        };\n    }\n\n    function weeksInYear(year, dow, doy) {\n        var weekOffset = firstWeekOffset(year, dow, doy),\n            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n    }\n\n    // FORMATTING\n\n    addFormatToken('w', ['ww', 2], 'wo', 'week');\n    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n    // ALIASES\n\n    addUnitAlias('week', 'w');\n    addUnitAlias('isoWeek', 'W');\n\n    // PRIORITIES\n\n    addUnitPriority('week', 5);\n    addUnitPriority('isoWeek', 5);\n\n    // PARSING\n\n    addRegexToken('w',  match1to2);\n    addRegexToken('ww', match1to2, match2);\n    addRegexToken('W',  match1to2);\n    addRegexToken('WW', match1to2, match2);\n\n    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n        week[token.substr(0, 1)] = toInt(input);\n    });\n\n    // HELPERS\n\n    // LOCALES\n\n    function localeWeek (mom) {\n        return weekOfYear(mom, this._week.dow, this._week.doy).week;\n    }\n\n    var defaultLocaleWeek = {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 6th is the first week of the year.\n    };\n\n    function localeFirstDayOfWeek () {\n        return this._week.dow;\n    }\n\n    function localeFirstDayOfYear () {\n        return this._week.doy;\n    }\n\n    // MOMENTS\n\n    function getSetWeek (input) {\n        var week = this.localeData().week(this);\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    function getSetISOWeek (input) {\n        var week = weekOfYear(this, 1, 4).week;\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    // FORMATTING\n\n    addFormatToken('d', 0, 'do', 'day');\n\n    addFormatToken('dd', 0, 0, function (format) {\n        return this.localeData().weekdaysMin(this, format);\n    });\n\n    addFormatToken('ddd', 0, 0, function (format) {\n        return this.localeData().weekdaysShort(this, format);\n    });\n\n    addFormatToken('dddd', 0, 0, function (format) {\n        return this.localeData().weekdays(this, format);\n    });\n\n    addFormatToken('e', 0, 0, 'weekday');\n    addFormatToken('E', 0, 0, 'isoWeekday');\n\n    // ALIASES\n\n    addUnitAlias('day', 'd');\n    addUnitAlias('weekday', 'e');\n    addUnitAlias('isoWeekday', 'E');\n\n    // PRIORITY\n    addUnitPriority('day', 11);\n    addUnitPriority('weekday', 11);\n    addUnitPriority('isoWeekday', 11);\n\n    // PARSING\n\n    addRegexToken('d',    match1to2);\n    addRegexToken('e',    match1to2);\n    addRegexToken('E',    match1to2);\n    addRegexToken('dd',   function (isStrict, locale) {\n        return locale.weekdaysMinRegex(isStrict);\n    });\n    addRegexToken('ddd',   function (isStrict, locale) {\n        return locale.weekdaysShortRegex(isStrict);\n    });\n    addRegexToken('dddd',   function (isStrict, locale) {\n        return locale.weekdaysRegex(isStrict);\n    });\n\n    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n        var weekday = config._locale.weekdaysParse(input, token, config._strict);\n        // if we didn't get a weekday name, mark the date as invalid\n        if (weekday != null) {\n            week.d = weekday;\n        } else {\n            getParsingFlags(config).invalidWeekday = input;\n        }\n    });\n\n    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n        week[token] = toInt(input);\n    });\n\n    // HELPERS\n\n    function parseWeekday(input, locale) {\n        if (typeof input !== 'string') {\n            return input;\n        }\n\n        if (!isNaN(input)) {\n            return parseInt(input, 10);\n        }\n\n        input = locale.weekdaysParse(input);\n        if (typeof input === 'number') {\n            return input;\n        }\n\n        return null;\n    }\n\n    function parseIsoWeekday(input, locale) {\n        if (typeof input === 'string') {\n            return locale.weekdaysParse(input) % 7 || 7;\n        }\n        return isNaN(input) ? null : input;\n    }\n\n    // LOCALES\n    function shiftWeekdays (ws, n) {\n        return ws.slice(n, 7).concat(ws.slice(0, n));\n    }\n\n    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\n    function localeWeekdays (m, format) {\n        var weekdays = isArray(this._weekdays) ? this._weekdays :\n            this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone'];\n        return (m === true) ? shiftWeekdays(weekdays, this._week.dow)\n            : (m) ? weekdays[m.day()] : weekdays;\n    }\n\n    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\n    function localeWeekdaysShort (m) {\n        return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow)\n            : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n    }\n\n    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\n    function localeWeekdaysMin (m) {\n        return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow)\n            : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n    }\n\n    function handleStrictParse$1(weekdayName, format, strict) {\n        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n            this._shortWeekdaysParse = [];\n            this._minWeekdaysParse = [];\n\n            for (i = 0; i < 7; ++i) {\n                mom = createUTC([2000, 1]).day(i);\n                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n            }\n        }\n\n        if (strict) {\n            if (format === 'dddd') {\n                ii = indexOf.call(this._weekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else if (format === 'ddd') {\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        } else {\n            if (format === 'dddd') {\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else if (format === 'ddd') {\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        }\n    }\n\n    function localeWeekdaysParse (weekdayName, format, strict) {\n        var i, mom, regex;\n\n        if (this._weekdaysParseExact) {\n            return handleStrictParse$1.call(this, weekdayName, format, strict);\n        }\n\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n            this._minWeekdaysParse = [];\n            this._shortWeekdaysParse = [];\n            this._fullWeekdaysParse = [];\n        }\n\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n\n            mom = createUTC([2000, 1]).day(i);\n            if (strict && !this._fullWeekdaysParse[i]) {\n                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\\\.?') + '$', 'i');\n                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\\\.?') + '$', 'i');\n                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\\\.?') + '$', 'i');\n            }\n            if (!this._weekdaysParse[i]) {\n                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function getSetDayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n        if (input != null) {\n            input = parseWeekday(input, this.localeData());\n            return this.add(input - day, 'd');\n        } else {\n            return day;\n        }\n    }\n\n    function getSetLocaleDayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n        return input == null ? weekday : this.add(input - weekday, 'd');\n    }\n\n    function getSetISODayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n\n        // behaves the same as moment#day except\n        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n        // as a setter, sunday should belong to the previous week.\n\n        if (input != null) {\n            var weekday = parseIsoWeekday(input, this.localeData());\n            return this.day(this.day() % 7 ? weekday : weekday - 7);\n        } else {\n            return this.day() || 7;\n        }\n    }\n\n    var defaultWeekdaysRegex = matchWord;\n    function weekdaysRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysStrictRegex;\n            } else {\n                return this._weekdaysRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                this._weekdaysRegex = defaultWeekdaysRegex;\n            }\n            return this._weekdaysStrictRegex && isStrict ?\n                this._weekdaysStrictRegex : this._weekdaysRegex;\n        }\n    }\n\n    var defaultWeekdaysShortRegex = matchWord;\n    function weekdaysShortRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysShortStrictRegex;\n            } else {\n                return this._weekdaysShortRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n                this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n            }\n            return this._weekdaysShortStrictRegex && isStrict ?\n                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n        }\n    }\n\n    var defaultWeekdaysMinRegex = matchWord;\n    function weekdaysMinRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysMinStrictRegex;\n            } else {\n                return this._weekdaysMinRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n                this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n            }\n            return this._weekdaysMinStrictRegex && isStrict ?\n                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n        }\n    }\n\n\n    function computeWeekdaysParse () {\n        function cmpLenRev(a, b) {\n            return b.length - a.length;\n        }\n\n        var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n            i, mom, minp, shortp, longp;\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, 1]).day(i);\n            minp = this.weekdaysMin(mom, '');\n            shortp = this.weekdaysShort(mom, '');\n            longp = this.weekdays(mom, '');\n            minPieces.push(minp);\n            shortPieces.push(shortp);\n            longPieces.push(longp);\n            mixedPieces.push(minp);\n            mixedPieces.push(shortp);\n            mixedPieces.push(longp);\n        }\n        // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n        // will match the longer piece.\n        minPieces.sort(cmpLenRev);\n        shortPieces.sort(cmpLenRev);\n        longPieces.sort(cmpLenRev);\n        mixedPieces.sort(cmpLenRev);\n        for (i = 0; i < 7; i++) {\n            shortPieces[i] = regexEscape(shortPieces[i]);\n            longPieces[i] = regexEscape(longPieces[i]);\n            mixedPieces[i] = regexEscape(mixedPieces[i]);\n        }\n\n        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n        this._weekdaysShortRegex = this._weekdaysRegex;\n        this._weekdaysMinRegex = this._weekdaysRegex;\n\n        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n    }\n\n    // FORMATTING\n\n    function hFormat() {\n        return this.hours() % 12 || 12;\n    }\n\n    function kFormat() {\n        return this.hours() || 24;\n    }\n\n    addFormatToken('H', ['HH', 2], 0, 'hour');\n    addFormatToken('h', ['hh', 2], 0, hFormat);\n    addFormatToken('k', ['kk', 2], 0, kFormat);\n\n    addFormatToken('hmm', 0, 0, function () {\n        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n    });\n\n    addFormatToken('hmmss', 0, 0, function () {\n        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n            zeroFill(this.seconds(), 2);\n    });\n\n    addFormatToken('Hmm', 0, 0, function () {\n        return '' + this.hours() + zeroFill(this.minutes(), 2);\n    });\n\n    addFormatToken('Hmmss', 0, 0, function () {\n        return '' + this.hours() + zeroFill(this.minutes(), 2) +\n            zeroFill(this.seconds(), 2);\n    });\n\n    function meridiem (token, lowercase) {\n        addFormatToken(token, 0, 0, function () {\n            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n        });\n    }\n\n    meridiem('a', true);\n    meridiem('A', false);\n\n    // ALIASES\n\n    addUnitAlias('hour', 'h');\n\n    // PRIORITY\n    addUnitPriority('hour', 13);\n\n    // PARSING\n\n    function matchMeridiem (isStrict, locale) {\n        return locale._meridiemParse;\n    }\n\n    addRegexToken('a',  matchMeridiem);\n    addRegexToken('A',  matchMeridiem);\n    addRegexToken('H',  match1to2);\n    addRegexToken('h',  match1to2);\n    addRegexToken('k',  match1to2);\n    addRegexToken('HH', match1to2, match2);\n    addRegexToken('hh', match1to2, match2);\n    addRegexToken('kk', match1to2, match2);\n\n    addRegexToken('hmm', match3to4);\n    addRegexToken('hmmss', match5to6);\n    addRegexToken('Hmm', match3to4);\n    addRegexToken('Hmmss', match5to6);\n\n    addParseToken(['H', 'HH'], HOUR);\n    addParseToken(['k', 'kk'], function (input, array, config) {\n        var kInput = toInt(input);\n        array[HOUR] = kInput === 24 ? 0 : kInput;\n    });\n    addParseToken(['a', 'A'], function (input, array, config) {\n        config._isPm = config._locale.isPM(input);\n        config._meridiem = input;\n    });\n    addParseToken(['h', 'hh'], function (input, array, config) {\n        array[HOUR] = toInt(input);\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('hmm', function (input, array, config) {\n        var pos = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos));\n        array[MINUTE] = toInt(input.substr(pos));\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('hmmss', function (input, array, config) {\n        var pos1 = input.length - 4;\n        var pos2 = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos1));\n        array[MINUTE] = toInt(input.substr(pos1, 2));\n        array[SECOND] = toInt(input.substr(pos2));\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('Hmm', function (input, array, config) {\n        var pos = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos));\n        array[MINUTE] = toInt(input.substr(pos));\n    });\n    addParseToken('Hmmss', function (input, array, config) {\n        var pos1 = input.length - 4;\n        var pos2 = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos1));\n        array[MINUTE] = toInt(input.substr(pos1, 2));\n        array[SECOND] = toInt(input.substr(pos2));\n    });\n\n    // LOCALES\n\n    function localeIsPM (input) {\n        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n        // Using charAt should be more compatible.\n        return ((input + '').toLowerCase().charAt(0) === 'p');\n    }\n\n    var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\n    function localeMeridiem (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'pm' : 'PM';\n        } else {\n            return isLower ? 'am' : 'AM';\n        }\n    }\n\n\n    // MOMENTS\n\n    // Setting the hour should keep the time, because the user explicitly\n    // specified which hour they want. So trying to maintain the same hour (in\n    // a new timezone) makes sense. Adding/subtracting hours does not follow\n    // this rule.\n    var getSetHour = makeGetSet('Hours', true);\n\n    var baseConfig = {\n        calendar: defaultCalendar,\n        longDateFormat: defaultLongDateFormat,\n        invalidDate: defaultInvalidDate,\n        ordinal: defaultOrdinal,\n        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n        relativeTime: defaultRelativeTime,\n\n        months: defaultLocaleMonths,\n        monthsShort: defaultLocaleMonthsShort,\n\n        week: defaultLocaleWeek,\n\n        weekdays: defaultLocaleWeekdays,\n        weekdaysMin: defaultLocaleWeekdaysMin,\n        weekdaysShort: defaultLocaleWeekdaysShort,\n\n        meridiemParse: defaultLocaleMeridiemParse\n    };\n\n    // internal storage for locale config files\n    var locales = {};\n    var localeFamilies = {};\n    var globalLocale;\n\n    function normalizeLocale(key) {\n        return key ? key.toLowerCase().replace('_', '-') : key;\n    }\n\n    // pick the locale from the array\n    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\n    function chooseLocale(names) {\n        var i = 0, j, next, locale, split;\n\n        while (i < names.length) {\n            split = normalizeLocale(names[i]).split('-');\n            j = split.length;\n            next = normalizeLocale(names[i + 1]);\n            next = next ? next.split('-') : null;\n            while (j > 0) {\n                locale = loadLocale(split.slice(0, j).join('-'));\n                if (locale) {\n                    return locale;\n                }\n                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                    //the next array item is better than a shallower substring of this one\n                    break;\n                }\n                j--;\n            }\n            i++;\n        }\n        return globalLocale;\n    }\n\n    function loadLocale(name) {\n        var oldLocale = null;\n        // TODO: Find a better way to register and load all the locales in Node\n        if (!locales[name] && (typeof module !== 'undefined') &&\n                module && module.exports) {\n            try {\n                oldLocale = globalLocale._abbr;\n                var aliasedRequire = require;\n                !(function webpackMissingModule() { var e = new Error(\"Cannot find module 'undefined'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }());\n                getSetGlobalLocale(oldLocale);\n            } catch (e) {}\n        }\n        return locales[name];\n    }\n\n    // This function will load locale and then set the global locale.  If\n    // no arguments are passed in, it will simply return the current global\n    // locale key.\n    function getSetGlobalLocale (key, values) {\n        var data;\n        if (key) {\n            if (isUndefined(values)) {\n                data = getLocale(key);\n            }\n            else {\n                data = defineLocale(key, values);\n            }\n\n            if (data) {\n                // moment.duration._locale = moment._locale = data;\n                globalLocale = data;\n            }\n            else {\n                if ((typeof console !==  'undefined') && console.warn) {\n                    //warn user if arguments are passed but the locale could not be set\n                    console.warn('Locale ' + key +  ' not found. Did you forget to load it?');\n                }\n            }\n        }\n\n        return globalLocale._abbr;\n    }\n\n    function defineLocale (name, config) {\n        if (config !== null) {\n            var locale, parentConfig = baseConfig;\n            config.abbr = name;\n            if (locales[name] != null) {\n                deprecateSimple('defineLocaleOverride',\n                        'use moment.updateLocale(localeName, config) to change ' +\n                        'an existing locale. moment.defineLocale(localeName, ' +\n                        'config) should only be used for creating a new locale ' +\n                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n                parentConfig = locales[name]._config;\n            } else if (config.parentLocale != null) {\n                if (locales[config.parentLocale] != null) {\n                    parentConfig = locales[config.parentLocale]._config;\n                } else {\n                    locale = loadLocale(config.parentLocale);\n                    if (locale != null) {\n                        parentConfig = locale._config;\n                    } else {\n                        if (!localeFamilies[config.parentLocale]) {\n                            localeFamilies[config.parentLocale] = [];\n                        }\n                        localeFamilies[config.parentLocale].push({\n                            name: name,\n                            config: config\n                        });\n                        return null;\n                    }\n                }\n            }\n            locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n            if (localeFamilies[name]) {\n                localeFamilies[name].forEach(function (x) {\n                    defineLocale(x.name, x.config);\n                });\n            }\n\n            // backwards compat for now: also set the locale\n            // make sure we set the locale AFTER all child locales have been\n            // created, so we won't end up with the child locale set.\n            getSetGlobalLocale(name);\n\n\n            return locales[name];\n        } else {\n            // useful for testing\n            delete locales[name];\n            return null;\n        }\n    }\n\n    function updateLocale(name, config) {\n        if (config != null) {\n            var locale, tmpLocale, parentConfig = baseConfig;\n            // MERGE\n            tmpLocale = loadLocale(name);\n            if (tmpLocale != null) {\n                parentConfig = tmpLocale._config;\n            }\n            config = mergeConfigs(parentConfig, config);\n            locale = new Locale(config);\n            locale.parentLocale = locales[name];\n            locales[name] = locale;\n\n            // backwards compat for now: also set the locale\n            getSetGlobalLocale(name);\n        } else {\n            // pass null for config to unupdate, useful for tests\n            if (locales[name] != null) {\n                if (locales[name].parentLocale != null) {\n                    locales[name] = locales[name].parentLocale;\n                } else if (locales[name] != null) {\n                    delete locales[name];\n                }\n            }\n        }\n        return locales[name];\n    }\n\n    // returns locale data\n    function getLocale (key) {\n        var locale;\n\n        if (key && key._locale && key._locale._abbr) {\n            key = key._locale._abbr;\n        }\n\n        if (!key) {\n            return globalLocale;\n        }\n\n        if (!isArray(key)) {\n            //short-circuit everything else\n            locale = loadLocale(key);\n            if (locale) {\n                return locale;\n            }\n            key = [key];\n        }\n\n        return chooseLocale(key);\n    }\n\n    function listLocales() {\n        return keys(locales);\n    }\n\n    function checkOverflow (m) {\n        var overflow;\n        var a = m._a;\n\n        if (a && getParsingFlags(m).overflow === -2) {\n            overflow =\n                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n                -1;\n\n            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n                overflow = DATE;\n            }\n            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n                overflow = WEEK;\n            }\n            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n                overflow = WEEKDAY;\n            }\n\n            getParsingFlags(m).overflow = overflow;\n        }\n\n        return m;\n    }\n\n    // Pick the first defined of two or three arguments.\n    function defaults(a, b, c) {\n        if (a != null) {\n            return a;\n        }\n        if (b != null) {\n            return b;\n        }\n        return c;\n    }\n\n    function currentDateArray(config) {\n        // hooks is actually the exported moment object\n        var nowValue = new Date(hooks.now());\n        if (config._useUTC) {\n            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n        }\n        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n    }\n\n    // convert an array to a date.\n    // the array should mirror the parameters below\n    // note: all values past the year are optional and will default to the lowest possible value.\n    // [year, month, day , hour, minute, second, millisecond]\n    function configFromArray (config) {\n        var i, date, input = [], currentDate, expectedWeekday, yearToUse;\n\n        if (config._d) {\n            return;\n        }\n\n        currentDate = currentDateArray(config);\n\n        //compute day of the year from weeks and weekdays\n        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n            dayOfYearFromWeekInfo(config);\n        }\n\n        //if the day of the year is set, figure out what it is\n        if (config._dayOfYear != null) {\n            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n            if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n                getParsingFlags(config)._overflowDayOfYear = true;\n            }\n\n            date = createUTCDate(yearToUse, 0, config._dayOfYear);\n            config._a[MONTH] = date.getUTCMonth();\n            config._a[DATE] = date.getUTCDate();\n        }\n\n        // Default to current date.\n        // * if no year, month, day of month are given, default to today\n        // * if day of month is given, default month and year\n        // * if month is given, default only year\n        // * if year is given, don't default anything\n        for (i = 0; i < 3 && config._a[i] == null; ++i) {\n            config._a[i] = input[i] = currentDate[i];\n        }\n\n        // Zero out whatever was not defaulted, including time\n        for (; i < 7; i++) {\n            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n        }\n\n        // Check for 24:00:00.000\n        if (config._a[HOUR] === 24 &&\n                config._a[MINUTE] === 0 &&\n                config._a[SECOND] === 0 &&\n                config._a[MILLISECOND] === 0) {\n            config._nextDay = true;\n            config._a[HOUR] = 0;\n        }\n\n        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n        expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();\n\n        // Apply timezone offset from input. The actual utcOffset can be changed\n        // with parseZone.\n        if (config._tzm != null) {\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n        }\n\n        if (config._nextDay) {\n            config._a[HOUR] = 24;\n        }\n\n        // check for mismatching day of week\n        if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {\n            getParsingFlags(config).weekdayMismatch = true;\n        }\n    }\n\n    function dayOfYearFromWeekInfo(config) {\n        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n        w = config._w;\n        if (w.GG != null || w.W != null || w.E != null) {\n            dow = 1;\n            doy = 4;\n\n            // TODO: We need to take the current isoWeekYear, but that depends on\n            // how we interpret now (local, utc, fixed offset). So create\n            // a now version of current config (take local/utc/offset flags, and\n            // create now).\n            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n            week = defaults(w.W, 1);\n            weekday = defaults(w.E, 1);\n            if (weekday < 1 || weekday > 7) {\n                weekdayOverflow = true;\n            }\n        } else {\n            dow = config._locale._week.dow;\n            doy = config._locale._week.doy;\n\n            var curWeek = weekOfYear(createLocal(), dow, doy);\n\n            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n            // Default to current week.\n            week = defaults(w.w, curWeek.week);\n\n            if (w.d != null) {\n                // weekday -- low day numbers are considered next week\n                weekday = w.d;\n                if (weekday < 0 || weekday > 6) {\n                    weekdayOverflow = true;\n                }\n            } else if (w.e != null) {\n                // local weekday -- counting starts from beginning of week\n                weekday = w.e + dow;\n                if (w.e < 0 || w.e > 6) {\n                    weekdayOverflow = true;\n                }\n            } else {\n                // default to beginning of week\n                weekday = dow;\n            }\n        }\n        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n            getParsingFlags(config)._overflowWeeks = true;\n        } else if (weekdayOverflow != null) {\n            getParsingFlags(config)._overflowWeekday = true;\n        } else {\n            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n            config._a[YEAR] = temp.year;\n            config._dayOfYear = temp.dayOfYear;\n        }\n    }\n\n    // iso 8601 regex\n    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\n    var extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n    var basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\n    var tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\n    var isoDates = [\n        ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n        ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n        ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n        ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n        ['YYYY-DDD', /\\d{4}-\\d{3}/],\n        ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n        ['YYYYYYMMDD', /[+-]\\d{10}/],\n        ['YYYYMMDD', /\\d{8}/],\n        // YYYYMM is NOT allowed by the standard\n        ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n        ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n        ['YYYYDDD', /\\d{7}/]\n    ];\n\n    // iso time formats and regexes\n    var isoTimes = [\n        ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n        ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n        ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n        ['HH:mm', /\\d\\d:\\d\\d/],\n        ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n        ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n        ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n        ['HHmm', /\\d\\d\\d\\d/],\n        ['HH', /\\d\\d/]\n    ];\n\n    var aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n    // date from iso format\n    function configFromISO(config) {\n        var i, l,\n            string = config._i,\n            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n            allowTime, dateFormat, timeFormat, tzFormat;\n\n        if (match) {\n            getParsingFlags(config).iso = true;\n\n            for (i = 0, l = isoDates.length; i < l; i++) {\n                if (isoDates[i][1].exec(match[1])) {\n                    dateFormat = isoDates[i][0];\n                    allowTime = isoDates[i][2] !== false;\n                    break;\n                }\n            }\n            if (dateFormat == null) {\n                config._isValid = false;\n                return;\n            }\n            if (match[3]) {\n                for (i = 0, l = isoTimes.length; i < l; i++) {\n                    if (isoTimes[i][1].exec(match[3])) {\n                        // match[2] should be 'T' or space\n                        timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                        break;\n                    }\n                }\n                if (timeFormat == null) {\n                    config._isValid = false;\n                    return;\n                }\n            }\n            if (!allowTime && timeFormat != null) {\n                config._isValid = false;\n                return;\n            }\n            if (match[4]) {\n                if (tzRegex.exec(match[4])) {\n                    tzFormat = 'Z';\n                } else {\n                    config._isValid = false;\n                    return;\n                }\n            }\n            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n            configFromStringAndFormat(config);\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\n    var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d{1,2})\\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(\\d{2,4})\\s(\\d\\d):(\\d\\d)(?::(\\d\\d))?\\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\\d{4}))$/;\n\n    function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {\n        var result = [\n            untruncateYear(yearStr),\n            defaultLocaleMonthsShort.indexOf(monthStr),\n            parseInt(dayStr, 10),\n            parseInt(hourStr, 10),\n            parseInt(minuteStr, 10)\n        ];\n\n        if (secondStr) {\n            result.push(parseInt(secondStr, 10));\n        }\n\n        return result;\n    }\n\n    function untruncateYear(yearStr) {\n        var year = parseInt(yearStr, 10);\n        if (year <= 49) {\n            return 2000 + year;\n        } else if (year <= 999) {\n            return 1900 + year;\n        }\n        return year;\n    }\n\n    function preprocessRFC2822(s) {\n        // Remove comments and folding whitespace and replace multiple-spaces with a single space\n        return s.replace(/\\([^)]*\\)|[\\n\\t]/g, ' ').replace(/(\\s\\s+)/g, ' ').replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n    }\n\n    function checkWeekday(weekdayStr, parsedInput, config) {\n        if (weekdayStr) {\n            // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),\n                weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();\n            if (weekdayProvided !== weekdayActual) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return false;\n            }\n        }\n        return true;\n    }\n\n    var obsOffsets = {\n        UT: 0,\n        GMT: 0,\n        EDT: -4 * 60,\n        EST: -5 * 60,\n        CDT: -5 * 60,\n        CST: -6 * 60,\n        MDT: -6 * 60,\n        MST: -7 * 60,\n        PDT: -7 * 60,\n        PST: -8 * 60\n    };\n\n    function calculateOffset(obsOffset, militaryOffset, numOffset) {\n        if (obsOffset) {\n            return obsOffsets[obsOffset];\n        } else if (militaryOffset) {\n            // the only allowed military tz is Z\n            return 0;\n        } else {\n            var hm = parseInt(numOffset, 10);\n            var m = hm % 100, h = (hm - m) / 100;\n            return h * 60 + m;\n        }\n    }\n\n    // date and time from ref 2822 format\n    function configFromRFC2822(config) {\n        var match = rfc2822.exec(preprocessRFC2822(config._i));\n        if (match) {\n            var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);\n            if (!checkWeekday(match[1], parsedArray, config)) {\n                return;\n            }\n\n            config._a = parsedArray;\n            config._tzm = calculateOffset(match[8], match[9], match[10]);\n\n            config._d = createUTCDate.apply(null, config._a);\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n\n            getParsingFlags(config).rfc2822 = true;\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // date from iso format or fallback\n    function configFromString(config) {\n        var matched = aspNetJsonRegex.exec(config._i);\n\n        if (matched !== null) {\n            config._d = new Date(+matched[1]);\n            return;\n        }\n\n        configFromISO(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n        } else {\n            return;\n        }\n\n        configFromRFC2822(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n        } else {\n            return;\n        }\n\n        // Final attempt, use Input Fallback\n        hooks.createFromInputFallback(config);\n    }\n\n    hooks.createFromInputFallback = deprecate(\n        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n        'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n        'discouraged and will be removed in an upcoming major release. Please refer to ' +\n        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n        function (config) {\n            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n        }\n    );\n\n    // constant that refers to the ISO standard\n    hooks.ISO_8601 = function () {};\n\n    // constant that refers to the RFC 2822 form\n    hooks.RFC_2822 = function () {};\n\n    // date from string and format string\n    function configFromStringAndFormat(config) {\n        // TODO: Move this to another part of the creation flow to prevent circular deps\n        if (config._f === hooks.ISO_8601) {\n            configFromISO(config);\n            return;\n        }\n        if (config._f === hooks.RFC_2822) {\n            configFromRFC2822(config);\n            return;\n        }\n        config._a = [];\n        getParsingFlags(config).empty = true;\n\n        // This array is used to make a Date, either with `new Date` or `Date.UTC`\n        var string = '' + config._i,\n            i, parsedInput, tokens, token, skipped,\n            stringLength = string.length,\n            totalParsedInputLength = 0;\n\n        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n        for (i = 0; i < tokens.length; i++) {\n            token = tokens[i];\n            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n            // console.log('token', token, 'parsedInput', parsedInput,\n            //         'regex', getParseRegexForToken(token, config));\n            if (parsedInput) {\n                skipped = string.substr(0, string.indexOf(parsedInput));\n                if (skipped.length > 0) {\n                    getParsingFlags(config).unusedInput.push(skipped);\n                }\n                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n                totalParsedInputLength += parsedInput.length;\n            }\n            // don't parse if it's not a known token\n            if (formatTokenFunctions[token]) {\n                if (parsedInput) {\n                    getParsingFlags(config).empty = false;\n                }\n                else {\n                    getParsingFlags(config).unusedTokens.push(token);\n                }\n                addTimeToArrayFromToken(token, parsedInput, config);\n            }\n            else if (config._strict && !parsedInput) {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n        }\n\n        // add remaining unparsed input length to the string\n        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n        if (string.length > 0) {\n            getParsingFlags(config).unusedInput.push(string);\n        }\n\n        // clear _12h flag if hour is <= 12\n        if (config._a[HOUR] <= 12 &&\n            getParsingFlags(config).bigHour === true &&\n            config._a[HOUR] > 0) {\n            getParsingFlags(config).bigHour = undefined;\n        }\n\n        getParsingFlags(config).parsedDateParts = config._a.slice(0);\n        getParsingFlags(config).meridiem = config._meridiem;\n        // handle meridiem\n        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n        configFromArray(config);\n        checkOverflow(config);\n    }\n\n\n    function meridiemFixWrap (locale, hour, meridiem) {\n        var isPm;\n\n        if (meridiem == null) {\n            // nothing to do\n            return hour;\n        }\n        if (locale.meridiemHour != null) {\n            return locale.meridiemHour(hour, meridiem);\n        } else if (locale.isPM != null) {\n            // Fallback\n            isPm = locale.isPM(meridiem);\n            if (isPm && hour < 12) {\n                hour += 12;\n            }\n            if (!isPm && hour === 12) {\n                hour = 0;\n            }\n            return hour;\n        } else {\n            // this is not supposed to happen\n            return hour;\n        }\n    }\n\n    // date from string and array of format strings\n    function configFromStringAndArray(config) {\n        var tempConfig,\n            bestMoment,\n\n            scoreToBeat,\n            i,\n            currentScore;\n\n        if (config._f.length === 0) {\n            getParsingFlags(config).invalidFormat = true;\n            config._d = new Date(NaN);\n            return;\n        }\n\n        for (i = 0; i < config._f.length; i++) {\n            currentScore = 0;\n            tempConfig = copyConfig({}, config);\n            if (config._useUTC != null) {\n                tempConfig._useUTC = config._useUTC;\n            }\n            tempConfig._f = config._f[i];\n            configFromStringAndFormat(tempConfig);\n\n            if (!isValid(tempConfig)) {\n                continue;\n            }\n\n            // if there is any input that was not parsed add a penalty for that format\n            currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n            //or tokens\n            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n            getParsingFlags(tempConfig).score = currentScore;\n\n            if (scoreToBeat == null || currentScore < scoreToBeat) {\n                scoreToBeat = currentScore;\n                bestMoment = tempConfig;\n            }\n        }\n\n        extend(config, bestMoment || tempConfig);\n    }\n\n    function configFromObject(config) {\n        if (config._d) {\n            return;\n        }\n\n        var i = normalizeObjectUnits(config._i);\n        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n            return obj && parseInt(obj, 10);\n        });\n\n        configFromArray(config);\n    }\n\n    function createFromConfig (config) {\n        var res = new Moment(checkOverflow(prepareConfig(config)));\n        if (res._nextDay) {\n            // Adding is smart enough around DST\n            res.add(1, 'd');\n            res._nextDay = undefined;\n        }\n\n        return res;\n    }\n\n    function prepareConfig (config) {\n        var input = config._i,\n            format = config._f;\n\n        config._locale = config._locale || getLocale(config._l);\n\n        if (input === null || (format === undefined && input === '')) {\n            return createInvalid({nullInput: true});\n        }\n\n        if (typeof input === 'string') {\n            config._i = input = config._locale.preparse(input);\n        }\n\n        if (isMoment(input)) {\n            return new Moment(checkOverflow(input));\n        } else if (isDate(input)) {\n            config._d = input;\n        } else if (isArray(format)) {\n            configFromStringAndArray(config);\n        } else if (format) {\n            configFromStringAndFormat(config);\n        }  else {\n            configFromInput(config);\n        }\n\n        if (!isValid(config)) {\n            config._d = null;\n        }\n\n        return config;\n    }\n\n    function configFromInput(config) {\n        var input = config._i;\n        if (isUndefined(input)) {\n            config._d = new Date(hooks.now());\n        } else if (isDate(input)) {\n            config._d = new Date(input.valueOf());\n        } else if (typeof input === 'string') {\n            configFromString(config);\n        } else if (isArray(input)) {\n            config._a = map(input.slice(0), function (obj) {\n                return parseInt(obj, 10);\n            });\n            configFromArray(config);\n        } else if (isObject(input)) {\n            configFromObject(config);\n        } else if (isNumber(input)) {\n            // from milliseconds\n            config._d = new Date(input);\n        } else {\n            hooks.createFromInputFallback(config);\n        }\n    }\n\n    function createLocalOrUTC (input, format, locale, strict, isUTC) {\n        var c = {};\n\n        if (locale === true || locale === false) {\n            strict = locale;\n            locale = undefined;\n        }\n\n        if ((isObject(input) && isObjectEmpty(input)) ||\n                (isArray(input) && input.length === 0)) {\n            input = undefined;\n        }\n        // object construction must be done this way.\n        // https://github.com/moment/moment/issues/1423\n        c._isAMomentObject = true;\n        c._useUTC = c._isUTC = isUTC;\n        c._l = locale;\n        c._i = input;\n        c._f = format;\n        c._strict = strict;\n\n        return createFromConfig(c);\n    }\n\n    function createLocal (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, false);\n    }\n\n    var prototypeMin = deprecate(\n        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n        function () {\n            var other = createLocal.apply(null, arguments);\n            if (this.isValid() && other.isValid()) {\n                return other < this ? this : other;\n            } else {\n                return createInvalid();\n            }\n        }\n    );\n\n    var prototypeMax = deprecate(\n        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n        function () {\n            var other = createLocal.apply(null, arguments);\n            if (this.isValid() && other.isValid()) {\n                return other > this ? this : other;\n            } else {\n                return createInvalid();\n            }\n        }\n    );\n\n    // Pick a moment m from moments so that m[fn](other) is true for all\n    // other. This relies on the function fn to be transitive.\n    //\n    // moments should either be an array of moment objects or an array, whose\n    // first element is an array of moment objects.\n    function pickBy(fn, moments) {\n        var res, i;\n        if (moments.length === 1 && isArray(moments[0])) {\n            moments = moments[0];\n        }\n        if (!moments.length) {\n            return createLocal();\n        }\n        res = moments[0];\n        for (i = 1; i < moments.length; ++i) {\n            if (!moments[i].isValid() || moments[i][fn](res)) {\n                res = moments[i];\n            }\n        }\n        return res;\n    }\n\n    // TODO: Use [].sort instead?\n    function min () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isBefore', args);\n    }\n\n    function max () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isAfter', args);\n    }\n\n    var now = function () {\n        return Date.now ? Date.now() : +(new Date());\n    };\n\n    var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\n    function isDurationValid(m) {\n        for (var key in m) {\n            if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n                return false;\n            }\n        }\n\n        var unitHasDecimal = false;\n        for (var i = 0; i < ordering.length; ++i) {\n            if (m[ordering[i]]) {\n                if (unitHasDecimal) {\n                    return false; // only allow non-integers for smallest unit\n                }\n                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                    unitHasDecimal = true;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    function isValid$1() {\n        return this._isValid;\n    }\n\n    function createInvalid$1() {\n        return createDuration(NaN);\n    }\n\n    function Duration (duration) {\n        var normalizedInput = normalizeObjectUnits(duration),\n            years = normalizedInput.year || 0,\n            quarters = normalizedInput.quarter || 0,\n            months = normalizedInput.month || 0,\n            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,\n            days = normalizedInput.day || 0,\n            hours = normalizedInput.hour || 0,\n            minutes = normalizedInput.minute || 0,\n            seconds = normalizedInput.second || 0,\n            milliseconds = normalizedInput.millisecond || 0;\n\n        this._isValid = isDurationValid(normalizedInput);\n\n        // representation for dateAddRemove\n        this._milliseconds = +milliseconds +\n            seconds * 1e3 + // 1000\n            minutes * 6e4 + // 1000 * 60\n            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n        // Because of dateAddRemove treats 24 hours as different from a\n        // day when working around DST, we need to store them separately\n        this._days = +days +\n            weeks * 7;\n        // It is impossible to translate months into days without knowing\n        // which months you are are talking about, so we have to store\n        // it separately.\n        this._months = +months +\n            quarters * 3 +\n            years * 12;\n\n        this._data = {};\n\n        this._locale = getLocale();\n\n        this._bubble();\n    }\n\n    function isDuration (obj) {\n        return obj instanceof Duration;\n    }\n\n    function absRound (number) {\n        if (number < 0) {\n            return Math.round(-1 * number) * -1;\n        } else {\n            return Math.round(number);\n        }\n    }\n\n    // FORMATTING\n\n    function offset (token, separator) {\n        addFormatToken(token, 0, 0, function () {\n            var offset = this.utcOffset();\n            var sign = '+';\n            if (offset < 0) {\n                offset = -offset;\n                sign = '-';\n            }\n            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n        });\n    }\n\n    offset('Z', ':');\n    offset('ZZ', '');\n\n    // PARSING\n\n    addRegexToken('Z',  matchShortOffset);\n    addRegexToken('ZZ', matchShortOffset);\n    addParseToken(['Z', 'ZZ'], function (input, array, config) {\n        config._useUTC = true;\n        config._tzm = offsetFromString(matchShortOffset, input);\n    });\n\n    // HELPERS\n\n    // timezone chunker\n    // '+10:00' > ['10',  '00']\n    // '-1530'  > ['-15', '30']\n    var chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\n    function offsetFromString(matcher, string) {\n        var matches = (string || '').match(matcher);\n\n        if (matches === null) {\n            return null;\n        }\n\n        var chunk   = matches[matches.length - 1] || [];\n        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n        var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n        return minutes === 0 ?\n          0 :\n          parts[0] === '+' ? minutes : -minutes;\n    }\n\n    // Return a moment from input, that is local/utc/zone equivalent to model.\n    function cloneWithOffset(input, model) {\n        var res, diff;\n        if (model._isUTC) {\n            res = model.clone();\n            diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n            // Use low-level api, because this fn is low-level api.\n            res._d.setTime(res._d.valueOf() + diff);\n            hooks.updateOffset(res, false);\n            return res;\n        } else {\n            return createLocal(input).local();\n        }\n    }\n\n    function getDateOffset (m) {\n        // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n        // https://github.com/moment/moment/pull/1871\n        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n    }\n\n    // HOOKS\n\n    // This function will be called whenever a moment is mutated.\n    // It is intended to keep the offset in sync with the timezone.\n    hooks.updateOffset = function () {};\n\n    // MOMENTS\n\n    // keepLocalTime = true means only change the timezone, without\n    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--\x3e\n    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n    // +0200, so we adjust the time as needed, to be valid.\n    //\n    // Keeping the time actually adds/subtracts (one hour)\n    // from the actual represented time. That is why we call updateOffset\n    // a second time. In case it wants us to change the offset again\n    // _changeInProgress == true case, then we have to adjust, because\n    // there is no such time in the given timezone.\n    function getSetOffset (input, keepLocalTime, keepMinutes) {\n        var offset = this._offset || 0,\n            localAdjust;\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        if (input != null) {\n            if (typeof input === 'string') {\n                input = offsetFromString(matchShortOffset, input);\n                if (input === null) {\n                    return this;\n                }\n            } else if (Math.abs(input) < 16 && !keepMinutes) {\n                input = input * 60;\n            }\n            if (!this._isUTC && keepLocalTime) {\n                localAdjust = getDateOffset(this);\n            }\n            this._offset = input;\n            this._isUTC = true;\n            if (localAdjust != null) {\n                this.add(localAdjust, 'm');\n            }\n            if (offset !== input) {\n                if (!keepLocalTime || this._changeInProgress) {\n                    addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n                } else if (!this._changeInProgress) {\n                    this._changeInProgress = true;\n                    hooks.updateOffset(this, true);\n                    this._changeInProgress = null;\n                }\n            }\n            return this;\n        } else {\n            return this._isUTC ? offset : getDateOffset(this);\n        }\n    }\n\n    function getSetZone (input, keepLocalTime) {\n        if (input != null) {\n            if (typeof input !== 'string') {\n                input = -input;\n            }\n\n            this.utcOffset(input, keepLocalTime);\n\n            return this;\n        } else {\n            return -this.utcOffset();\n        }\n    }\n\n    function setOffsetToUTC (keepLocalTime) {\n        return this.utcOffset(0, keepLocalTime);\n    }\n\n    function setOffsetToLocal (keepLocalTime) {\n        if (this._isUTC) {\n            this.utcOffset(0, keepLocalTime);\n            this._isUTC = false;\n\n            if (keepLocalTime) {\n                this.subtract(getDateOffset(this), 'm');\n            }\n        }\n        return this;\n    }\n\n    function setOffsetToParsedOffset () {\n        if (this._tzm != null) {\n            this.utcOffset(this._tzm, false, true);\n        } else if (typeof this._i === 'string') {\n            var tZone = offsetFromString(matchOffset, this._i);\n            if (tZone != null) {\n                this.utcOffset(tZone);\n            }\n            else {\n                this.utcOffset(0, true);\n            }\n        }\n        return this;\n    }\n\n    function hasAlignedHourOffset (input) {\n        if (!this.isValid()) {\n            return false;\n        }\n        input = input ? createLocal(input).utcOffset() : 0;\n\n        return (this.utcOffset() - input) % 60 === 0;\n    }\n\n    function isDaylightSavingTime () {\n        return (\n            this.utcOffset() > this.clone().month(0).utcOffset() ||\n            this.utcOffset() > this.clone().month(5).utcOffset()\n        );\n    }\n\n    function isDaylightSavingTimeShifted () {\n        if (!isUndefined(this._isDSTShifted)) {\n            return this._isDSTShifted;\n        }\n\n        var c = {};\n\n        copyConfig(c, this);\n        c = prepareConfig(c);\n\n        if (c._a) {\n            var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n            this._isDSTShifted = this.isValid() &&\n                compareArrays(c._a, other.toArray()) > 0;\n        } else {\n            this._isDSTShifted = false;\n        }\n\n        return this._isDSTShifted;\n    }\n\n    function isLocal () {\n        return this.isValid() ? !this._isUTC : false;\n    }\n\n    function isUtcOffset () {\n        return this.isValid() ? this._isUTC : false;\n    }\n\n    function isUtc () {\n        return this.isValid() ? this._isUTC && this._offset === 0 : false;\n    }\n\n    // ASP.NET json date format regex\n    var aspNetRegex = /^(\\-|\\+)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n    // and further modified to allow for strings containing both week and day\n    var isoRegex = /^(-|\\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;\n\n    function createDuration (input, key) {\n        var duration = input,\n            // matching against regexp is expensive, do it on demand\n            match = null,\n            sign,\n            ret,\n            diffRes;\n\n        if (isDuration(input)) {\n            duration = {\n                ms : input._milliseconds,\n                d  : input._days,\n                M  : input._months\n            };\n        } else if (isNumber(input)) {\n            duration = {};\n            if (key) {\n                duration[key] = input;\n            } else {\n                duration.milliseconds = input;\n            }\n        } else if (!!(match = aspNetRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y  : 0,\n                d  : toInt(match[DATE])                         * sign,\n                h  : toInt(match[HOUR])                         * sign,\n                m  : toInt(match[MINUTE])                       * sign,\n                s  : toInt(match[SECOND])                       * sign,\n                ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n            };\n        } else if (!!(match = isoRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y : parseIso(match[2], sign),\n                M : parseIso(match[3], sign),\n                w : parseIso(match[4], sign),\n                d : parseIso(match[5], sign),\n                h : parseIso(match[6], sign),\n                m : parseIso(match[7], sign),\n                s : parseIso(match[8], sign)\n            };\n        } else if (duration == null) {// checks for null or undefined\n            duration = {};\n        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n            diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n            duration = {};\n            duration.ms = diffRes.milliseconds;\n            duration.M = diffRes.months;\n        }\n\n        ret = new Duration(duration);\n\n        if (isDuration(input) && hasOwnProp(input, '_locale')) {\n            ret._locale = input._locale;\n        }\n\n        return ret;\n    }\n\n    createDuration.fn = Duration.prototype;\n    createDuration.invalid = createInvalid$1;\n\n    function parseIso (inp, sign) {\n        // We'd normally use ~~inp for this, but unfortunately it also\n        // converts floats to ints.\n        // inp may be undefined, so careful calling replace on it.\n        var res = inp && parseFloat(inp.replace(',', '.'));\n        // apply sign while we're at it\n        return (isNaN(res) ? 0 : res) * sign;\n    }\n\n    function positiveMomentsDifference(base, other) {\n        var res = {};\n\n        res.months = other.month() - base.month() +\n            (other.year() - base.year()) * 12;\n        if (base.clone().add(res.months, 'M').isAfter(other)) {\n            --res.months;\n        }\n\n        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n        return res;\n    }\n\n    function momentsDifference(base, other) {\n        var res;\n        if (!(base.isValid() && other.isValid())) {\n            return {milliseconds: 0, months: 0};\n        }\n\n        other = cloneWithOffset(other, base);\n        if (base.isBefore(other)) {\n            res = positiveMomentsDifference(base, other);\n        } else {\n            res = positiveMomentsDifference(other, base);\n            res.milliseconds = -res.milliseconds;\n            res.months = -res.months;\n        }\n\n        return res;\n    }\n\n    // TODO: remove 'name' arg after deprecation is removed\n    function createAdder(direction, name) {\n        return function (val, period) {\n            var dur, tmp;\n            //invert the arguments, but complain about it\n            if (period !== null && !isNaN(+period)) {\n                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n                'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n                tmp = val; val = period; period = tmp;\n            }\n\n            val = typeof val === 'string' ? +val : val;\n            dur = createDuration(val, period);\n            addSubtract(this, dur, direction);\n            return this;\n        };\n    }\n\n    function addSubtract (mom, duration, isAdding, updateOffset) {\n        var milliseconds = duration._milliseconds,\n            days = absRound(duration._days),\n            months = absRound(duration._months);\n\n        if (!mom.isValid()) {\n            // No op\n            return;\n        }\n\n        updateOffset = updateOffset == null ? true : updateOffset;\n\n        if (months) {\n            setMonth(mom, get(mom, 'Month') + months * isAdding);\n        }\n        if (days) {\n            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n        }\n        if (milliseconds) {\n            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n        }\n        if (updateOffset) {\n            hooks.updateOffset(mom, days || months);\n        }\n    }\n\n    var add      = createAdder(1, 'add');\n    var subtract = createAdder(-1, 'subtract');\n\n    function getCalendarFormat(myMoment, now) {\n        var diff = myMoment.diff(now, 'days', true);\n        return diff < -6 ? 'sameElse' :\n                diff < -1 ? 'lastWeek' :\n                diff < 0 ? 'lastDay' :\n                diff < 1 ? 'sameDay' :\n                diff < 2 ? 'nextDay' :\n                diff < 7 ? 'nextWeek' : 'sameElse';\n    }\n\n    function calendar$1 (time, formats) {\n        // We want to compare the start of today, vs this.\n        // Getting start-of-today depends on whether we're local/utc/offset or not.\n        var now = time || createLocal(),\n            sod = cloneWithOffset(now, this).startOf('day'),\n            format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n        return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n    }\n\n    function clone () {\n        return new Moment(this);\n    }\n\n    function isAfter (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input);\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() > localInput.valueOf();\n        } else {\n            return localInput.valueOf() < this.clone().startOf(units).valueOf();\n        }\n    }\n\n    function isBefore (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input);\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() < localInput.valueOf();\n        } else {\n            return this.clone().endOf(units).valueOf() < localInput.valueOf();\n        }\n    }\n\n    function isBetween (from, to, units, inclusivity) {\n        var localFrom = isMoment(from) ? from : createLocal(from),\n            localTo = isMoment(to) ? to : createLocal(to);\n        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {\n            return false;\n        }\n        inclusivity = inclusivity || '()';\n        return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) &&\n            (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));\n    }\n\n    function isSame (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input),\n            inputMs;\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() === localInput.valueOf();\n        } else {\n            inputMs = localInput.valueOf();\n            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n        }\n    }\n\n    function isSameOrAfter (input, units) {\n        return this.isSame(input, units) || this.isAfter(input, units);\n    }\n\n    function isSameOrBefore (input, units) {\n        return this.isSame(input, units) || this.isBefore(input, units);\n    }\n\n    function diff (input, units, asFloat) {\n        var that,\n            zoneDelta,\n            output;\n\n        if (!this.isValid()) {\n            return NaN;\n        }\n\n        that = cloneWithOffset(input, this);\n\n        if (!that.isValid()) {\n            return NaN;\n        }\n\n        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n        units = normalizeUnits(units);\n\n        switch (units) {\n            case 'year': output = monthDiff(this, that) / 12; break;\n            case 'month': output = monthDiff(this, that); break;\n            case 'quarter': output = monthDiff(this, that) / 3; break;\n            case 'second': output = (this - that) / 1e3; break; // 1000\n            case 'minute': output = (this - that) / 6e4; break; // 1000 * 60\n            case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60\n            case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst\n            case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst\n            default: output = this - that;\n        }\n\n        return asFloat ? output : absFloor(output);\n    }\n\n    function monthDiff (a, b) {\n        // difference in months\n        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n            // b is in (anchor - 1 month, anchor + 1 month)\n            anchor = a.clone().add(wholeMonthDiff, 'months'),\n            anchor2, adjust;\n\n        if (b - anchor < 0) {\n            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor - anchor2);\n        } else {\n            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor2 - anchor);\n        }\n\n        //check for negative zero, return zero if negative zero\n        return -(wholeMonthDiff + adjust) || 0;\n    }\n\n    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\n    function toString () {\n        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n    }\n\n    function toISOString(keepOffset) {\n        if (!this.isValid()) {\n            return null;\n        }\n        var utc = keepOffset !== true;\n        var m = utc ? this.clone().utc() : this;\n        if (m.year() < 0 || m.year() > 9999) {\n            return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');\n        }\n        if (isFunction(Date.prototype.toISOString)) {\n            // native implementation is ~50x faster, use it when we can\n            if (utc) {\n                return this.toDate().toISOString();\n            } else {\n                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));\n            }\n        }\n        return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');\n    }\n\n    /**\n     * Return a human readable representation of a moment that can\n     * also be evaluated to get a new moment which is the same\n     *\n     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n     */\n    function inspect () {\n        if (!this.isValid()) {\n            return 'moment.invalid(/* ' + this._i + ' */)';\n        }\n        var func = 'moment';\n        var zone = '';\n        if (!this.isLocal()) {\n            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n            zone = 'Z';\n        }\n        var prefix = '[' + func + '(\"]';\n        var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n        var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n        var suffix = zone + '[\")]';\n\n        return this.format(prefix + year + datetime + suffix);\n    }\n\n    function format (inputString) {\n        if (!inputString) {\n            inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n        }\n        var output = formatMoment(this, inputString);\n        return this.localeData().postformat(output);\n    }\n\n    function from (time, withoutSuffix) {\n        if (this.isValid() &&\n                ((isMoment(time) && time.isValid()) ||\n                 createLocal(time).isValid())) {\n            return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n        } else {\n            return this.localeData().invalidDate();\n        }\n    }\n\n    function fromNow (withoutSuffix) {\n        return this.from(createLocal(), withoutSuffix);\n    }\n\n    function to (time, withoutSuffix) {\n        if (this.isValid() &&\n                ((isMoment(time) && time.isValid()) ||\n                 createLocal(time).isValid())) {\n            return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n        } else {\n            return this.localeData().invalidDate();\n        }\n    }\n\n    function toNow (withoutSuffix) {\n        return this.to(createLocal(), withoutSuffix);\n    }\n\n    // If passed a locale key, it will set the locale for this\n    // instance.  Otherwise, it will return the locale configuration\n    // variables for this instance.\n    function locale (key) {\n        var newLocaleData;\n\n        if (key === undefined) {\n            return this._locale._abbr;\n        } else {\n            newLocaleData = getLocale(key);\n            if (newLocaleData != null) {\n                this._locale = newLocaleData;\n            }\n            return this;\n        }\n    }\n\n    var lang = deprecate(\n        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n        function (key) {\n            if (key === undefined) {\n                return this.localeData();\n            } else {\n                return this.locale(key);\n            }\n        }\n    );\n\n    function localeData () {\n        return this._locale;\n    }\n\n    var MS_PER_SECOND = 1000;\n    var MS_PER_MINUTE = 60 * MS_PER_SECOND;\n    var MS_PER_HOUR = 60 * MS_PER_MINUTE;\n    var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;\n\n    // actual modulo - handles negative numbers (for dates before 1970):\n    function mod$1(dividend, divisor) {\n        return (dividend % divisor + divisor) % divisor;\n    }\n\n    function localStartOfDate(y, m, d) {\n        // the date constructor remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            return new Date(y + 400, m, d) - MS_PER_400_YEARS;\n        } else {\n            return new Date(y, m, d).valueOf();\n        }\n    }\n\n    function utcStartOfDate(y, m, d) {\n        // Date.UTC remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;\n        } else {\n            return Date.UTC(y, m, d);\n        }\n    }\n\n    function startOf (units) {\n        var time;\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond' || !this.isValid()) {\n            return this;\n        }\n\n        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;\n\n        switch (units) {\n            case 'year':\n                time = startOfDate(this.year(), 0, 1);\n                break;\n            case 'quarter':\n                time = startOfDate(this.year(), this.month() - this.month() % 3, 1);\n                break;\n            case 'month':\n                time = startOfDate(this.year(), this.month(), 1);\n                break;\n            case 'week':\n                time = startOfDate(this.year(), this.month(), this.date() - this.weekday());\n                break;\n            case 'isoWeek':\n                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));\n                break;\n            case 'day':\n            case 'date':\n                time = startOfDate(this.year(), this.month(), this.date());\n                break;\n            case 'hour':\n                time = this._d.valueOf();\n                time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);\n                break;\n            case 'minute':\n                time = this._d.valueOf();\n                time -= mod$1(time, MS_PER_MINUTE);\n                break;\n            case 'second':\n                time = this._d.valueOf();\n                time -= mod$1(time, MS_PER_SECOND);\n                break;\n        }\n\n        this._d.setTime(time);\n        hooks.updateOffset(this, true);\n        return this;\n    }\n\n    function endOf (units) {\n        var time;\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond' || !this.isValid()) {\n            return this;\n        }\n\n        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;\n\n        switch (units) {\n            case 'year':\n                time = startOfDate(this.year() + 1, 0, 1) - 1;\n                break;\n            case 'quarter':\n                time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;\n                break;\n            case 'month':\n                time = startOfDate(this.year(), this.month() + 1, 1) - 1;\n                break;\n            case 'week':\n                time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;\n                break;\n            case 'isoWeek':\n                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;\n                break;\n            case 'day':\n            case 'date':\n                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;\n                break;\n            case 'hour':\n                time = this._d.valueOf();\n                time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;\n                break;\n            case 'minute':\n                time = this._d.valueOf();\n                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;\n                break;\n            case 'second':\n                time = this._d.valueOf();\n                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;\n                break;\n        }\n\n        this._d.setTime(time);\n        hooks.updateOffset(this, true);\n        return this;\n    }\n\n    function valueOf () {\n        return this._d.valueOf() - ((this._offset || 0) * 60000);\n    }\n\n    function unix () {\n        return Math.floor(this.valueOf() / 1000);\n    }\n\n    function toDate () {\n        return new Date(this.valueOf());\n    }\n\n    function toArray () {\n        var m = this;\n        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n    }\n\n    function toObject () {\n        var m = this;\n        return {\n            years: m.year(),\n            months: m.month(),\n            date: m.date(),\n            hours: m.hours(),\n            minutes: m.minutes(),\n            seconds: m.seconds(),\n            milliseconds: m.milliseconds()\n        };\n    }\n\n    function toJSON () {\n        // new Date(NaN).toJSON() === null\n        return this.isValid() ? this.toISOString() : null;\n    }\n\n    function isValid$2 () {\n        return isValid(this);\n    }\n\n    function parsingFlags () {\n        return extend({}, getParsingFlags(this));\n    }\n\n    function invalidAt () {\n        return getParsingFlags(this).overflow;\n    }\n\n    function creationData() {\n        return {\n            input: this._i,\n            format: this._f,\n            locale: this._locale,\n            isUTC: this._isUTC,\n            strict: this._strict\n        };\n    }\n\n    // FORMATTING\n\n    addFormatToken(0, ['gg', 2], 0, function () {\n        return this.weekYear() % 100;\n    });\n\n    addFormatToken(0, ['GG', 2], 0, function () {\n        return this.isoWeekYear() % 100;\n    });\n\n    function addWeekYearFormatToken (token, getter) {\n        addFormatToken(0, [token, token.length], 0, getter);\n    }\n\n    addWeekYearFormatToken('gggg',     'weekYear');\n    addWeekYearFormatToken('ggggg',    'weekYear');\n    addWeekYearFormatToken('GGGG',  'isoWeekYear');\n    addWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n    // ALIASES\n\n    addUnitAlias('weekYear', 'gg');\n    addUnitAlias('isoWeekYear', 'GG');\n\n    // PRIORITY\n\n    addUnitPriority('weekYear', 1);\n    addUnitPriority('isoWeekYear', 1);\n\n\n    // PARSING\n\n    addRegexToken('G',      matchSigned);\n    addRegexToken('g',      matchSigned);\n    addRegexToken('GG',     match1to2, match2);\n    addRegexToken('gg',     match1to2, match2);\n    addRegexToken('GGGG',   match1to4, match4);\n    addRegexToken('gggg',   match1to4, match4);\n    addRegexToken('GGGGG',  match1to6, match6);\n    addRegexToken('ggggg',  match1to6, match6);\n\n    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n        week[token.substr(0, 2)] = toInt(input);\n    });\n\n    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n        week[token] = hooks.parseTwoDigitYear(input);\n    });\n\n    // MOMENTS\n\n    function getSetWeekYear (input) {\n        return getSetWeekYearHelper.call(this,\n                input,\n                this.week(),\n                this.weekday(),\n                this.localeData()._week.dow,\n                this.localeData()._week.doy);\n    }\n\n    function getSetISOWeekYear (input) {\n        return getSetWeekYearHelper.call(this,\n                input, this.isoWeek(), this.isoWeekday(), 1, 4);\n    }\n\n    function getISOWeeksInYear () {\n        return weeksInYear(this.year(), 1, 4);\n    }\n\n    function getWeeksInYear () {\n        var weekInfo = this.localeData()._week;\n        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n    }\n\n    function getSetWeekYearHelper(input, week, weekday, dow, doy) {\n        var weeksTarget;\n        if (input == null) {\n            return weekOfYear(this, dow, doy).year;\n        } else {\n            weeksTarget = weeksInYear(input, dow, doy);\n            if (week > weeksTarget) {\n                week = weeksTarget;\n            }\n            return setWeekAll.call(this, input, week, weekday, dow, doy);\n        }\n    }\n\n    function setWeekAll(weekYear, week, weekday, dow, doy) {\n        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n        this.year(date.getUTCFullYear());\n        this.month(date.getUTCMonth());\n        this.date(date.getUTCDate());\n        return this;\n    }\n\n    // FORMATTING\n\n    addFormatToken('Q', 0, 'Qo', 'quarter');\n\n    // ALIASES\n\n    addUnitAlias('quarter', 'Q');\n\n    // PRIORITY\n\n    addUnitPriority('quarter', 7);\n\n    // PARSING\n\n    addRegexToken('Q', match1);\n    addParseToken('Q', function (input, array) {\n        array[MONTH] = (toInt(input) - 1) * 3;\n    });\n\n    // MOMENTS\n\n    function getSetQuarter (input) {\n        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n    }\n\n    // FORMATTING\n\n    addFormatToken('D', ['DD', 2], 'Do', 'date');\n\n    // ALIASES\n\n    addUnitAlias('date', 'D');\n\n    // PRIORITY\n    addUnitPriority('date', 9);\n\n    // PARSING\n\n    addRegexToken('D',  match1to2);\n    addRegexToken('DD', match1to2, match2);\n    addRegexToken('Do', function (isStrict, locale) {\n        // TODO: Remove \"ordinalParse\" fallback in next major release.\n        return isStrict ?\n          (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n          locale._dayOfMonthOrdinalParseLenient;\n    });\n\n    addParseToken(['D', 'DD'], DATE);\n    addParseToken('Do', function (input, array) {\n        array[DATE] = toInt(input.match(match1to2)[0]);\n    });\n\n    // MOMENTS\n\n    var getSetDayOfMonth = makeGetSet('Date', true);\n\n    // FORMATTING\n\n    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n    // ALIASES\n\n    addUnitAlias('dayOfYear', 'DDD');\n\n    // PRIORITY\n    addUnitPriority('dayOfYear', 4);\n\n    // PARSING\n\n    addRegexToken('DDD',  match1to3);\n    addRegexToken('DDDD', match3);\n    addParseToken(['DDD', 'DDDD'], function (input, array, config) {\n        config._dayOfYear = toInt(input);\n    });\n\n    // HELPERS\n\n    // MOMENTS\n\n    function getSetDayOfYear (input) {\n        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n    }\n\n    // FORMATTING\n\n    addFormatToken('m', ['mm', 2], 0, 'minute');\n\n    // ALIASES\n\n    addUnitAlias('minute', 'm');\n\n    // PRIORITY\n\n    addUnitPriority('minute', 14);\n\n    // PARSING\n\n    addRegexToken('m',  match1to2);\n    addRegexToken('mm', match1to2, match2);\n    addParseToken(['m', 'mm'], MINUTE);\n\n    // MOMENTS\n\n    var getSetMinute = makeGetSet('Minutes', false);\n\n    // FORMATTING\n\n    addFormatToken('s', ['ss', 2], 0, 'second');\n\n    // ALIASES\n\n    addUnitAlias('second', 's');\n\n    // PRIORITY\n\n    addUnitPriority('second', 15);\n\n    // PARSING\n\n    addRegexToken('s',  match1to2);\n    addRegexToken('ss', match1to2, match2);\n    addParseToken(['s', 'ss'], SECOND);\n\n    // MOMENTS\n\n    var getSetSecond = makeGetSet('Seconds', false);\n\n    // FORMATTING\n\n    addFormatToken('S', 0, 0, function () {\n        return ~~(this.millisecond() / 100);\n    });\n\n    addFormatToken(0, ['SS', 2], 0, function () {\n        return ~~(this.millisecond() / 10);\n    });\n\n    addFormatToken(0, ['SSS', 3], 0, 'millisecond');\n    addFormatToken(0, ['SSSS', 4], 0, function () {\n        return this.millisecond() * 10;\n    });\n    addFormatToken(0, ['SSSSS', 5], 0, function () {\n        return this.millisecond() * 100;\n    });\n    addFormatToken(0, ['SSSSSS', 6], 0, function () {\n        return this.millisecond() * 1000;\n    });\n    addFormatToken(0, ['SSSSSSS', 7], 0, function () {\n        return this.millisecond() * 10000;\n    });\n    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n        return this.millisecond() * 100000;\n    });\n    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n        return this.millisecond() * 1000000;\n    });\n\n\n    // ALIASES\n\n    addUnitAlias('millisecond', 'ms');\n\n    // PRIORITY\n\n    addUnitPriority('millisecond', 16);\n\n    // PARSING\n\n    addRegexToken('S',    match1to3, match1);\n    addRegexToken('SS',   match1to3, match2);\n    addRegexToken('SSS',  match1to3, match3);\n\n    var token;\n    for (token = 'SSSS'; token.length <= 9; token += 'S') {\n        addRegexToken(token, matchUnsigned);\n    }\n\n    function parseMs(input, array) {\n        array[MILLISECOND] = toInt(('0.' + input) * 1000);\n    }\n\n    for (token = 'S'; token.length <= 9; token += 'S') {\n        addParseToken(token, parseMs);\n    }\n    // MOMENTS\n\n    var getSetMillisecond = makeGetSet('Milliseconds', false);\n\n    // FORMATTING\n\n    addFormatToken('z',  0, 0, 'zoneAbbr');\n    addFormatToken('zz', 0, 0, 'zoneName');\n\n    // MOMENTS\n\n    function getZoneAbbr () {\n        return this._isUTC ? 'UTC' : '';\n    }\n\n    function getZoneName () {\n        return this._isUTC ? 'Coordinated Universal Time' : '';\n    }\n\n    var proto = Moment.prototype;\n\n    proto.add               = add;\n    proto.calendar          = calendar$1;\n    proto.clone             = clone;\n    proto.diff              = diff;\n    proto.endOf             = endOf;\n    proto.format            = format;\n    proto.from              = from;\n    proto.fromNow           = fromNow;\n    proto.to                = to;\n    proto.toNow             = toNow;\n    proto.get               = stringGet;\n    proto.invalidAt         = invalidAt;\n    proto.isAfter           = isAfter;\n    proto.isBefore          = isBefore;\n    proto.isBetween         = isBetween;\n    proto.isSame            = isSame;\n    proto.isSameOrAfter     = isSameOrAfter;\n    proto.isSameOrBefore    = isSameOrBefore;\n    proto.isValid           = isValid$2;\n    proto.lang              = lang;\n    proto.locale            = locale;\n    proto.localeData        = localeData;\n    proto.max               = prototypeMax;\n    proto.min               = prototypeMin;\n    proto.parsingFlags      = parsingFlags;\n    proto.set               = stringSet;\n    proto.startOf           = startOf;\n    proto.subtract          = subtract;\n    proto.toArray           = toArray;\n    proto.toObject          = toObject;\n    proto.toDate            = toDate;\n    proto.toISOString       = toISOString;\n    proto.inspect           = inspect;\n    proto.toJSON            = toJSON;\n    proto.toString          = toString;\n    proto.unix              = unix;\n    proto.valueOf           = valueOf;\n    proto.creationData      = creationData;\n    proto.year       = getSetYear;\n    proto.isLeapYear = getIsLeapYear;\n    proto.weekYear    = getSetWeekYear;\n    proto.isoWeekYear = getSetISOWeekYear;\n    proto.quarter = proto.quarters = getSetQuarter;\n    proto.month       = getSetMonth;\n    proto.daysInMonth = getDaysInMonth;\n    proto.week           = proto.weeks        = getSetWeek;\n    proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\n    proto.weeksInYear    = getWeeksInYear;\n    proto.isoWeeksInYear = getISOWeeksInYear;\n    proto.date       = getSetDayOfMonth;\n    proto.day        = proto.days             = getSetDayOfWeek;\n    proto.weekday    = getSetLocaleDayOfWeek;\n    proto.isoWeekday = getSetISODayOfWeek;\n    proto.dayOfYear  = getSetDayOfYear;\n    proto.hour = proto.hours = getSetHour;\n    proto.minute = proto.minutes = getSetMinute;\n    proto.second = proto.seconds = getSetSecond;\n    proto.millisecond = proto.milliseconds = getSetMillisecond;\n    proto.utcOffset            = getSetOffset;\n    proto.utc                  = setOffsetToUTC;\n    proto.local                = setOffsetToLocal;\n    proto.parseZone            = setOffsetToParsedOffset;\n    proto.hasAlignedHourOffset = hasAlignedHourOffset;\n    proto.isDST                = isDaylightSavingTime;\n    proto.isLocal              = isLocal;\n    proto.isUtcOffset          = isUtcOffset;\n    proto.isUtc                = isUtc;\n    proto.isUTC                = isUtc;\n    proto.zoneAbbr = getZoneAbbr;\n    proto.zoneName = getZoneName;\n    proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\n    proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\n    proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\n    proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\n    proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\n    function createUnix (input) {\n        return createLocal(input * 1000);\n    }\n\n    function createInZone () {\n        return createLocal.apply(null, arguments).parseZone();\n    }\n\n    function preParsePostFormat (string) {\n        return string;\n    }\n\n    var proto$1 = Locale.prototype;\n\n    proto$1.calendar        = calendar;\n    proto$1.longDateFormat  = longDateFormat;\n    proto$1.invalidDate     = invalidDate;\n    proto$1.ordinal         = ordinal;\n    proto$1.preparse        = preParsePostFormat;\n    proto$1.postformat      = preParsePostFormat;\n    proto$1.relativeTime    = relativeTime;\n    proto$1.pastFuture      = pastFuture;\n    proto$1.set             = set;\n\n    proto$1.months            =        localeMonths;\n    proto$1.monthsShort       =        localeMonthsShort;\n    proto$1.monthsParse       =        localeMonthsParse;\n    proto$1.monthsRegex       = monthsRegex;\n    proto$1.monthsShortRegex  = monthsShortRegex;\n    proto$1.week = localeWeek;\n    proto$1.firstDayOfYear = localeFirstDayOfYear;\n    proto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n    proto$1.weekdays       =        localeWeekdays;\n    proto$1.weekdaysMin    =        localeWeekdaysMin;\n    proto$1.weekdaysShort  =        localeWeekdaysShort;\n    proto$1.weekdaysParse  =        localeWeekdaysParse;\n\n    proto$1.weekdaysRegex       =        weekdaysRegex;\n    proto$1.weekdaysShortRegex  =        weekdaysShortRegex;\n    proto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n    proto$1.isPM = localeIsPM;\n    proto$1.meridiem = localeMeridiem;\n\n    function get$1 (format, index, field, setter) {\n        var locale = getLocale();\n        var utc = createUTC().set(setter, index);\n        return locale[field](utc, format);\n    }\n\n    function listMonthsImpl (format, index, field) {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n\n        if (index != null) {\n            return get$1(format, index, field, 'month');\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < 12; i++) {\n            out[i] = get$1(format, i, field, 'month');\n        }\n        return out;\n    }\n\n    // ()\n    // (5)\n    // (fmt, 5)\n    // (fmt)\n    // (true)\n    // (true, 5)\n    // (true, fmt, 5)\n    // (true, fmt)\n    function listWeekdaysImpl (localeSorted, format, index, field) {\n        if (typeof localeSorted === 'boolean') {\n            if (isNumber(format)) {\n                index = format;\n                format = undefined;\n            }\n\n            format = format || '';\n        } else {\n            format = localeSorted;\n            index = format;\n            localeSorted = false;\n\n            if (isNumber(format)) {\n                index = format;\n                format = undefined;\n            }\n\n            format = format || '';\n        }\n\n        var locale = getLocale(),\n            shift = localeSorted ? locale._week.dow : 0;\n\n        if (index != null) {\n            return get$1(format, (index + shift) % 7, field, 'day');\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < 7; i++) {\n            out[i] = get$1(format, (i + shift) % 7, field, 'day');\n        }\n        return out;\n    }\n\n    function listMonths (format, index) {\n        return listMonthsImpl(format, index, 'months');\n    }\n\n    function listMonthsShort (format, index) {\n        return listMonthsImpl(format, index, 'monthsShort');\n    }\n\n    function listWeekdays (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n    }\n\n    function listWeekdaysShort (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n    }\n\n    function listWeekdaysMin (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n    }\n\n    getSetGlobalLocale('en', {\n        dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (toInt(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    // Side effect imports\n\n    hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\n    hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\n    var mathAbs = Math.abs;\n\n    function abs () {\n        var data           = this._data;\n\n        this._milliseconds = mathAbs(this._milliseconds);\n        this._days         = mathAbs(this._days);\n        this._months       = mathAbs(this._months);\n\n        data.milliseconds  = mathAbs(data.milliseconds);\n        data.seconds       = mathAbs(data.seconds);\n        data.minutes       = mathAbs(data.minutes);\n        data.hours         = mathAbs(data.hours);\n        data.months        = mathAbs(data.months);\n        data.years         = mathAbs(data.years);\n\n        return this;\n    }\n\n    function addSubtract$1 (duration, input, value, direction) {\n        var other = createDuration(input, value);\n\n        duration._milliseconds += direction * other._milliseconds;\n        duration._days         += direction * other._days;\n        duration._months       += direction * other._months;\n\n        return duration._bubble();\n    }\n\n    // supports only 2.0-style add(1, 's') or add(duration)\n    function add$1 (input, value) {\n        return addSubtract$1(this, input, value, 1);\n    }\n\n    // supports only 2.0-style subtract(1, 's') or subtract(duration)\n    function subtract$1 (input, value) {\n        return addSubtract$1(this, input, value, -1);\n    }\n\n    function absCeil (number) {\n        if (number < 0) {\n            return Math.floor(number);\n        } else {\n            return Math.ceil(number);\n        }\n    }\n\n    function bubble () {\n        var milliseconds = this._milliseconds;\n        var days         = this._days;\n        var months       = this._months;\n        var data         = this._data;\n        var seconds, minutes, hours, years, monthsFromDays;\n\n        // if we have a mix of positive and negative values, bubble down first\n        // check: https://github.com/moment/moment/issues/2166\n        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n                (milliseconds <= 0 && days <= 0 && months <= 0))) {\n            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n            days = 0;\n            months = 0;\n        }\n\n        // The following code bubbles up values, see the tests for\n        // examples of what that means.\n        data.milliseconds = milliseconds % 1000;\n\n        seconds           = absFloor(milliseconds / 1000);\n        data.seconds      = seconds % 60;\n\n        minutes           = absFloor(seconds / 60);\n        data.minutes      = minutes % 60;\n\n        hours             = absFloor(minutes / 60);\n        data.hours        = hours % 24;\n\n        days += absFloor(hours / 24);\n\n        // convert days to months\n        monthsFromDays = absFloor(daysToMonths(days));\n        months += monthsFromDays;\n        days -= absCeil(monthsToDays(monthsFromDays));\n\n        // 12 months -> 1 year\n        years = absFloor(months / 12);\n        months %= 12;\n\n        data.days   = days;\n        data.months = months;\n        data.years  = years;\n\n        return this;\n    }\n\n    function daysToMonths (days) {\n        // 400 years have 146097 days (taking into account leap year rules)\n        // 400 years have 12 months === 4800\n        return days * 4800 / 146097;\n    }\n\n    function monthsToDays (months) {\n        // the reverse of daysToMonths\n        return months * 146097 / 4800;\n    }\n\n    function as (units) {\n        if (!this.isValid()) {\n            return NaN;\n        }\n        var days;\n        var months;\n        var milliseconds = this._milliseconds;\n\n        units = normalizeUnits(units);\n\n        if (units === 'month' || units === 'quarter' || units === 'year') {\n            days = this._days + milliseconds / 864e5;\n            months = this._months + daysToMonths(days);\n            switch (units) {\n                case 'month':   return months;\n                case 'quarter': return months / 3;\n                case 'year':    return months / 12;\n            }\n        } else {\n            // handle milliseconds separately because of floating point math errors (issue #1867)\n            days = this._days + Math.round(monthsToDays(this._months));\n            switch (units) {\n                case 'week'   : return days / 7     + milliseconds / 6048e5;\n                case 'day'    : return days         + milliseconds / 864e5;\n                case 'hour'   : return days * 24    + milliseconds / 36e5;\n                case 'minute' : return days * 1440  + milliseconds / 6e4;\n                case 'second' : return days * 86400 + milliseconds / 1000;\n                // Math.floor prevents floating point math errors here\n                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n                default: throw new Error('Unknown unit ' + units);\n            }\n        }\n    }\n\n    // TODO: Use this.as('ms')?\n    function valueOf$1 () {\n        if (!this.isValid()) {\n            return NaN;\n        }\n        return (\n            this._milliseconds +\n            this._days * 864e5 +\n            (this._months % 12) * 2592e6 +\n            toInt(this._months / 12) * 31536e6\n        );\n    }\n\n    function makeAs (alias) {\n        return function () {\n            return this.as(alias);\n        };\n    }\n\n    var asMilliseconds = makeAs('ms');\n    var asSeconds      = makeAs('s');\n    var asMinutes      = makeAs('m');\n    var asHours        = makeAs('h');\n    var asDays         = makeAs('d');\n    var asWeeks        = makeAs('w');\n    var asMonths       = makeAs('M');\n    var asQuarters     = makeAs('Q');\n    var asYears        = makeAs('y');\n\n    function clone$1 () {\n        return createDuration(this);\n    }\n\n    function get$2 (units) {\n        units = normalizeUnits(units);\n        return this.isValid() ? this[units + 's']() : NaN;\n    }\n\n    function makeGetter(name) {\n        return function () {\n            return this.isValid() ? this._data[name] : NaN;\n        };\n    }\n\n    var milliseconds = makeGetter('milliseconds');\n    var seconds      = makeGetter('seconds');\n    var minutes      = makeGetter('minutes');\n    var hours        = makeGetter('hours');\n    var days         = makeGetter('days');\n    var months       = makeGetter('months');\n    var years        = makeGetter('years');\n\n    function weeks () {\n        return absFloor(this.days() / 7);\n    }\n\n    var round = Math.round;\n    var thresholds = {\n        ss: 44,         // a few seconds to seconds\n        s : 45,         // seconds to minute\n        m : 45,         // minutes to hour\n        h : 22,         // hours to day\n        d : 26,         // days to month\n        M : 11          // months to year\n    };\n\n    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\n    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n    }\n\n    function relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n        var duration = createDuration(posNegDuration).abs();\n        var seconds  = round(duration.as('s'));\n        var minutes  = round(duration.as('m'));\n        var hours    = round(duration.as('h'));\n        var days     = round(duration.as('d'));\n        var months   = round(duration.as('M'));\n        var years    = round(duration.as('y'));\n\n        var a = seconds <= thresholds.ss && ['s', seconds]  ||\n                seconds < thresholds.s   && ['ss', seconds] ||\n                minutes <= 1             && ['m']           ||\n                minutes < thresholds.m   && ['mm', minutes] ||\n                hours   <= 1             && ['h']           ||\n                hours   < thresholds.h   && ['hh', hours]   ||\n                days    <= 1             && ['d']           ||\n                days    < thresholds.d   && ['dd', days]    ||\n                months  <= 1             && ['M']           ||\n                months  < thresholds.M   && ['MM', months]  ||\n                years   <= 1             && ['y']           || ['yy', years];\n\n        a[2] = withoutSuffix;\n        a[3] = +posNegDuration > 0;\n        a[4] = locale;\n        return substituteTimeAgo.apply(null, a);\n    }\n\n    // This function allows you to set the rounding function for relative time strings\n    function getSetRelativeTimeRounding (roundingFunction) {\n        if (roundingFunction === undefined) {\n            return round;\n        }\n        if (typeof(roundingFunction) === 'function') {\n            round = roundingFunction;\n            return true;\n        }\n        return false;\n    }\n\n    // This function allows you to set a threshold for relative time strings\n    function getSetRelativeTimeThreshold (threshold, limit) {\n        if (thresholds[threshold] === undefined) {\n            return false;\n        }\n        if (limit === undefined) {\n            return thresholds[threshold];\n        }\n        thresholds[threshold] = limit;\n        if (threshold === 's') {\n            thresholds.ss = limit - 1;\n        }\n        return true;\n    }\n\n    function humanize (withSuffix) {\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n\n        var locale = this.localeData();\n        var output = relativeTime$1(this, !withSuffix, locale);\n\n        if (withSuffix) {\n            output = locale.pastFuture(+this, output);\n        }\n\n        return locale.postformat(output);\n    }\n\n    var abs$1 = Math.abs;\n\n    function sign(x) {\n        return ((x > 0) - (x < 0)) || +x;\n    }\n\n    function toISOString$1() {\n        // for ISO strings we do not use the normal bubbling rules:\n        //  * milliseconds bubble up until they become hours\n        //  * days do not bubble at all\n        //  * months bubble up until they become years\n        // This is because there is no context-free conversion between hours and days\n        // (think of clock changes)\n        // and also not between days and months (28-31 days per month)\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n\n        var seconds = abs$1(this._milliseconds) / 1000;\n        var days         = abs$1(this._days);\n        var months       = abs$1(this._months);\n        var minutes, hours, years;\n\n        // 3600 seconds -> 60 minutes -> 1 hour\n        minutes           = absFloor(seconds / 60);\n        hours             = absFloor(minutes / 60);\n        seconds %= 60;\n        minutes %= 60;\n\n        // 12 months -> 1 year\n        years  = absFloor(months / 12);\n        months %= 12;\n\n\n        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n        var Y = years;\n        var M = months;\n        var D = days;\n        var h = hours;\n        var m = minutes;\n        var s = seconds ? seconds.toFixed(3).replace(/\\.?0+$/, '') : '';\n        var total = this.asSeconds();\n\n        if (!total) {\n            // this is the same as C#'s (Noda) and python (isodate)...\n            // but not other JS (goog.date)\n            return 'P0D';\n        }\n\n        var totalSign = total < 0 ? '-' : '';\n        var ymSign = sign(this._months) !== sign(total) ? '-' : '';\n        var daysSign = sign(this._days) !== sign(total) ? '-' : '';\n        var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';\n\n        return totalSign + 'P' +\n            (Y ? ymSign + Y + 'Y' : '') +\n            (M ? ymSign + M + 'M' : '') +\n            (D ? daysSign + D + 'D' : '') +\n            ((h || m || s) ? 'T' : '') +\n            (h ? hmsSign + h + 'H' : '') +\n            (m ? hmsSign + m + 'M' : '') +\n            (s ? hmsSign + s + 'S' : '');\n    }\n\n    var proto$2 = Duration.prototype;\n\n    proto$2.isValid        = isValid$1;\n    proto$2.abs            = abs;\n    proto$2.add            = add$1;\n    proto$2.subtract       = subtract$1;\n    proto$2.as             = as;\n    proto$2.asMilliseconds = asMilliseconds;\n    proto$2.asSeconds      = asSeconds;\n    proto$2.asMinutes      = asMinutes;\n    proto$2.asHours        = asHours;\n    proto$2.asDays         = asDays;\n    proto$2.asWeeks        = asWeeks;\n    proto$2.asMonths       = asMonths;\n    proto$2.asQuarters     = asQuarters;\n    proto$2.asYears        = asYears;\n    proto$2.valueOf        = valueOf$1;\n    proto$2._bubble        = bubble;\n    proto$2.clone          = clone$1;\n    proto$2.get            = get$2;\n    proto$2.milliseconds   = milliseconds;\n    proto$2.seconds        = seconds;\n    proto$2.minutes        = minutes;\n    proto$2.hours          = hours;\n    proto$2.days           = days;\n    proto$2.weeks          = weeks;\n    proto$2.months         = months;\n    proto$2.years          = years;\n    proto$2.humanize       = humanize;\n    proto$2.toISOString    = toISOString$1;\n    proto$2.toString       = toISOString$1;\n    proto$2.toJSON         = toISOString$1;\n    proto$2.locale         = locale;\n    proto$2.localeData     = localeData;\n\n    proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\n    proto$2.lang = lang;\n\n    // Side effect imports\n\n    // FORMATTING\n\n    addFormatToken('X', 0, 0, 'unix');\n    addFormatToken('x', 0, 0, 'valueOf');\n\n    // PARSING\n\n    addRegexToken('x', matchSigned);\n    addRegexToken('X', matchTimestamp);\n    addParseToken('X', function (input, array, config) {\n        config._d = new Date(parseFloat(input, 10) * 1000);\n    });\n    addParseToken('x', function (input, array, config) {\n        config._d = new Date(toInt(input));\n    });\n\n    // Side effect imports\n\n\n    hooks.version = '2.24.0';\n\n    setHookCallback(createLocal);\n\n    hooks.fn                    = proto;\n    hooks.min                   = min;\n    hooks.max                   = max;\n    hooks.now                   = now;\n    hooks.utc                   = createUTC;\n    hooks.unix                  = createUnix;\n    hooks.months                = listMonths;\n    hooks.isDate                = isDate;\n    hooks.locale                = getSetGlobalLocale;\n    hooks.invalid               = createInvalid;\n    hooks.duration              = createDuration;\n    hooks.isMoment              = isMoment;\n    hooks.weekdays              = listWeekdays;\n    hooks.parseZone             = createInZone;\n    hooks.localeData            = getLocale;\n    hooks.isDuration            = isDuration;\n    hooks.monthsShort           = listMonthsShort;\n    hooks.weekdaysMin           = listWeekdaysMin;\n    hooks.defineLocale          = defineLocale;\n    hooks.updateLocale          = updateLocale;\n    hooks.locales               = listLocales;\n    hooks.weekdaysShort         = listWeekdaysShort;\n    hooks.normalizeUnits        = normalizeUnits;\n    hooks.relativeTimeRounding  = getSetRelativeTimeRounding;\n    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\n    hooks.calendarFormat        = getCalendarFormat;\n    hooks.prototype             = proto;\n\n    // currently HTML5 input type only supports 24-hour formats\n    hooks.HTML5_FMT = {\n        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type=\"datetime-local\" />\n        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type=\"datetime-local\" step=\"1\" />\n        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type=\"datetime-local\" step=\"0.001\" />\n        DATE: 'YYYY-MM-DD',                             // <input type=\"date\" />\n        TIME: 'HH:mm',                                  // <input type=\"time\" />\n        TIME_SECONDS: 'HH:mm:ss',                       // <input type=\"time\" step=\"1\" />\n        TIME_MS: 'HH:mm:ss.SSS',                        // <input type=\"time\" step=\"0.001\" />\n        WEEK: 'GGGG-[W]WW',                             // <input type=\"week\" />\n        MONTH: 'YYYY-MM'                                // <input type=\"month\" />\n    };\n\n    return hooks;\n\n})));\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/module.js */ \"f586\")(module)))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGEwMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9tb21lbnQvbW9tZW50LmpzP2MxZGYiXSwic291cmNlc0NvbnRlbnQiOlsiLy8hIG1vbWVudC5qc1xuXG47KGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG4gICAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgICBnbG9iYWwubW9tZW50ID0gZmFjdG9yeSgpXG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuICAgIHZhciBob29rQ2FsbGJhY2s7XG5cbiAgICBmdW5jdGlvbiBob29rcyAoKSB7XG4gICAgICAgIHJldHVybiBob29rQ2FsbGJhY2suYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGlzIGRvbmUgdG8gcmVnaXN0ZXIgdGhlIG1ldGhvZCBjYWxsZWQgd2l0aCBtb21lbnQoKVxuICAgIC8vIHdpdGhvdXQgY3JlYXRpbmcgY2lyY3VsYXIgZGVwZW5kZW5jaWVzLlxuICAgIGZ1bmN0aW9uIHNldEhvb2tDYWxsYmFjayAoY2FsbGJhY2spIHtcbiAgICAgICAgaG9va0NhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBcnJheShpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXQgaW5zdGFuY2VvZiBBcnJheSB8fCBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaW5wdXQpID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzT2JqZWN0KGlucHV0KSB7XG4gICAgICAgIC8vIElFOCB3aWxsIHRyZWF0IHVuZGVmaW5lZCBhbmQgbnVsbCBhcyBvYmplY3QgaWYgaXQgd2Fzbid0IGZvclxuICAgICAgICAvLyBpbnB1dCAhPSBudWxsXG4gICAgICAgIHJldHVybiBpbnB1dCAhPSBudWxsICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IE9iamVjdF0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzT2JqZWN0RW1wdHkob2JqKSB7XG4gICAgICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcykge1xuICAgICAgICAgICAgcmV0dXJuIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCA9PT0gMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaztcbiAgICAgICAgICAgIGZvciAoayBpbiBvYmopIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVW5kZWZpbmVkKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBpbnB1dCA9PT0gdm9pZCAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzTnVtYmVyKGlucHV0KSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IE51bWJlcl0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzRGF0ZShpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXQgaW5zdGFuY2VvZiBEYXRlIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IERhdGVdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXAoYXJyLCBmbikge1xuICAgICAgICB2YXIgcmVzID0gW10sIGk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHJlcy5wdXNoKGZuKGFycltpXSwgaSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzT3duUHJvcChhLCBiKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSwgYik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXh0ZW5kKGEsIGIpIHtcbiAgICAgICAgZm9yICh2YXIgaSBpbiBiKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChiLCBpKSkge1xuICAgICAgICAgICAgICAgIGFbaV0gPSBiW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc093blByb3AoYiwgJ3RvU3RyaW5nJykpIHtcbiAgICAgICAgICAgIGEudG9TdHJpbmcgPSBiLnRvU3RyaW5nO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc093blByb3AoYiwgJ3ZhbHVlT2YnKSkge1xuICAgICAgICAgICAgYS52YWx1ZU9mID0gYi52YWx1ZU9mO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlVVRDIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWxPclVUQyhpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCwgdHJ1ZSkudXRjKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmYXVsdFBhcnNpbmdGbGFncygpIHtcbiAgICAgICAgLy8gV2UgbmVlZCB0byBkZWVwIGNsb25lIHRoaXMgb2JqZWN0LlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZW1wdHkgICAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICB1bnVzZWRUb2tlbnMgICAgOiBbXSxcbiAgICAgICAgICAgIHVudXNlZElucHV0ICAgICA6IFtdLFxuICAgICAgICAgICAgb3ZlcmZsb3cgICAgICAgIDogLTIsXG4gICAgICAgICAgICBjaGFyc0xlZnRPdmVyICAgOiAwLFxuICAgICAgICAgICAgbnVsbElucHV0ICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICBpbnZhbGlkTW9udGggICAgOiBudWxsLFxuICAgICAgICAgICAgaW52YWxpZEZvcm1hdCAgIDogZmFsc2UsXG4gICAgICAgICAgICB1c2VySW52YWxpZGF0ZWQgOiBmYWxzZSxcbiAgICAgICAgICAgIGlzbyAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICAgICAgcGFyc2VkRGF0ZVBhcnRzIDogW10sXG4gICAgICAgICAgICBtZXJpZGllbSAgICAgICAgOiBudWxsLFxuICAgICAgICAgICAgcmZjMjgyMiAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICB3ZWVrZGF5TWlzbWF0Y2ggOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFBhcnNpbmdGbGFncyhtKSB7XG4gICAgICAgIGlmIChtLl9wZiA9PSBudWxsKSB7XG4gICAgICAgICAgICBtLl9wZiA9IGRlZmF1bHRQYXJzaW5nRmxhZ3MoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbS5fcGY7XG4gICAgfVxuXG4gICAgdmFyIHNvbWU7XG4gICAgaWYgKEFycmF5LnByb3RvdHlwZS5zb21lKSB7XG4gICAgICAgIHNvbWUgPSBBcnJheS5wcm90b3R5cGUuc29tZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBzb21lID0gZnVuY3Rpb24gKGZ1bikge1xuICAgICAgICAgICAgdmFyIHQgPSBPYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgbGVuID0gdC5sZW5ndGggPj4+IDA7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiB0ICYmIGZ1bi5jYWxsKHRoaXMsIHRbaV0sIGksIHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVmFsaWQobSkge1xuICAgICAgICBpZiAobS5faXNWYWxpZCA9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgZmxhZ3MgPSBnZXRQYXJzaW5nRmxhZ3MobSk7XG4gICAgICAgICAgICB2YXIgcGFyc2VkUGFydHMgPSBzb21lLmNhbGwoZmxhZ3MucGFyc2VkRGF0ZVBhcnRzLCBmdW5jdGlvbiAoaSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpICE9IG51bGw7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhciBpc05vd1ZhbGlkID0gIWlzTmFOKG0uX2QuZ2V0VGltZSgpKSAmJlxuICAgICAgICAgICAgICAgIGZsYWdzLm92ZXJmbG93IDwgMCAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5lbXB0eSAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5pbnZhbGlkTW9udGggJiZcbiAgICAgICAgICAgICAgICAhZmxhZ3MuaW52YWxpZFdlZWtkYXkgJiZcbiAgICAgICAgICAgICAgICAhZmxhZ3Mud2Vla2RheU1pc21hdGNoICYmXG4gICAgICAgICAgICAgICAgIWZsYWdzLm51bGxJbnB1dCAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5pbnZhbGlkRm9ybWF0ICYmXG4gICAgICAgICAgICAgICAgIWZsYWdzLnVzZXJJbnZhbGlkYXRlZCAmJlxuICAgICAgICAgICAgICAgICghZmxhZ3MubWVyaWRpZW0gfHwgKGZsYWdzLm1lcmlkaWVtICYmIHBhcnNlZFBhcnRzKSk7XG5cbiAgICAgICAgICAgIGlmIChtLl9zdHJpY3QpIHtcbiAgICAgICAgICAgICAgICBpc05vd1ZhbGlkID0gaXNOb3dWYWxpZCAmJlxuICAgICAgICAgICAgICAgICAgICBmbGFncy5jaGFyc0xlZnRPdmVyID09PSAwICYmXG4gICAgICAgICAgICAgICAgICAgIGZsYWdzLnVudXNlZFRva2Vucy5sZW5ndGggPT09IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgZmxhZ3MuYmlnSG91ciA9PT0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoT2JqZWN0LmlzRnJvemVuID09IG51bGwgfHwgIU9iamVjdC5pc0Zyb3plbihtKSkge1xuICAgICAgICAgICAgICAgIG0uX2lzVmFsaWQgPSBpc05vd1ZhbGlkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzTm93VmFsaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG0uX2lzVmFsaWQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlSW52YWxpZCAoZmxhZ3MpIHtcbiAgICAgICAgdmFyIG0gPSBjcmVhdGVVVEMoTmFOKTtcbiAgICAgICAgaWYgKGZsYWdzICE9IG51bGwpIHtcbiAgICAgICAgICAgIGV4dGVuZChnZXRQYXJzaW5nRmxhZ3MobSksIGZsYWdzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhtKS51c2VySW52YWxpZGF0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG07XG4gICAgfVxuXG4gICAgLy8gUGx1Z2lucyB0aGF0IGFkZCBwcm9wZXJ0aWVzIHNob3VsZCBhbHNvIGFkZCB0aGUga2V5IGhlcmUgKG51bGwgdmFsdWUpLFxuICAgIC8vIHNvIHdlIGNhbiBwcm9wZXJseSBjbG9uZSBvdXJzZWx2ZXMuXG4gICAgdmFyIG1vbWVudFByb3BlcnRpZXMgPSBob29rcy5tb21lbnRQcm9wZXJ0aWVzID0gW107XG5cbiAgICBmdW5jdGlvbiBjb3B5Q29uZmlnKHRvLCBmcm9tKSB7XG4gICAgICAgIHZhciBpLCBwcm9wLCB2YWw7XG5cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9pc0FNb21lbnRPYmplY3QpKSB7XG4gICAgICAgICAgICB0by5faXNBTW9tZW50T2JqZWN0ID0gZnJvbS5faXNBTW9tZW50T2JqZWN0O1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5faSkpIHtcbiAgICAgICAgICAgIHRvLl9pID0gZnJvbS5faTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX2YpKSB7XG4gICAgICAgICAgICB0by5fZiA9IGZyb20uX2Y7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9sKSkge1xuICAgICAgICAgICAgdG8uX2wgPSBmcm9tLl9sO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fc3RyaWN0KSkge1xuICAgICAgICAgICAgdG8uX3N0cmljdCA9IGZyb20uX3N0cmljdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX3R6bSkpIHtcbiAgICAgICAgICAgIHRvLl90em0gPSBmcm9tLl90em07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9pc1VUQykpIHtcbiAgICAgICAgICAgIHRvLl9pc1VUQyA9IGZyb20uX2lzVVRDO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fb2Zmc2V0KSkge1xuICAgICAgICAgICAgdG8uX29mZnNldCA9IGZyb20uX29mZnNldDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX3BmKSkge1xuICAgICAgICAgICAgdG8uX3BmID0gZ2V0UGFyc2luZ0ZsYWdzKGZyb20pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fbG9jYWxlKSkge1xuICAgICAgICAgICAgdG8uX2xvY2FsZSA9IGZyb20uX2xvY2FsZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtb21lbnRQcm9wZXJ0aWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBtb21lbnRQcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcHJvcCA9IG1vbWVudFByb3BlcnRpZXNbaV07XG4gICAgICAgICAgICAgICAgdmFsID0gZnJvbVtwcm9wXTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKHZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9bcHJvcF0gPSB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRvO1xuICAgIH1cblxuICAgIHZhciB1cGRhdGVJblByb2dyZXNzID0gZmFsc2U7XG5cbiAgICAvLyBNb21lbnQgcHJvdG90eXBlIG9iamVjdFxuICAgIGZ1bmN0aW9uIE1vbWVudChjb25maWcpIHtcbiAgICAgICAgY29weUNvbmZpZyh0aGlzLCBjb25maWcpO1xuICAgICAgICB0aGlzLl9kID0gbmV3IERhdGUoY29uZmlnLl9kICE9IG51bGwgPyBjb25maWcuX2QuZ2V0VGltZSgpIDogTmFOKTtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgdGhpcy5fZCA9IG5ldyBEYXRlKE5hTik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUHJldmVudCBpbmZpbml0ZSBsb29wIGluIGNhc2UgdXBkYXRlT2Zmc2V0IGNyZWF0ZXMgbmV3IG1vbWVudFxuICAgICAgICAvLyBvYmplY3RzLlxuICAgICAgICBpZiAodXBkYXRlSW5Qcm9ncmVzcyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHVwZGF0ZUluUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMpO1xuICAgICAgICAgICAgdXBkYXRlSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNNb21lbnQgKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgTW9tZW50IHx8IChvYmogIT0gbnVsbCAmJiBvYmouX2lzQU1vbWVudE9iamVjdCAhPSBudWxsKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhYnNGbG9vciAobnVtYmVyKSB7XG4gICAgICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICAgICAgICAvLyAtMCAtPiAwXG4gICAgICAgICAgICByZXR1cm4gTWF0aC5jZWlsKG51bWJlcikgfHwgMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKG51bWJlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0ludChhcmd1bWVudEZvckNvZXJjaW9uKSB7XG4gICAgICAgIHZhciBjb2VyY2VkTnVtYmVyID0gK2FyZ3VtZW50Rm9yQ29lcmNpb24sXG4gICAgICAgICAgICB2YWx1ZSA9IDA7XG5cbiAgICAgICAgaWYgKGNvZXJjZWROdW1iZXIgIT09IDAgJiYgaXNGaW5pdGUoY29lcmNlZE51bWJlcikpIHtcbiAgICAgICAgICAgIHZhbHVlID0gYWJzRmxvb3IoY29lcmNlZE51bWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gY29tcGFyZSB0d28gYXJyYXlzLCByZXR1cm4gdGhlIG51bWJlciBvZiBkaWZmZXJlbmNlc1xuICAgIGZ1bmN0aW9uIGNvbXBhcmVBcnJheXMoYXJyYXkxLCBhcnJheTIsIGRvbnRDb252ZXJ0KSB7XG4gICAgICAgIHZhciBsZW4gPSBNYXRoLm1pbihhcnJheTEubGVuZ3RoLCBhcnJheTIubGVuZ3RoKSxcbiAgICAgICAgICAgIGxlbmd0aERpZmYgPSBNYXRoLmFicyhhcnJheTEubGVuZ3RoIC0gYXJyYXkyLmxlbmd0aCksXG4gICAgICAgICAgICBkaWZmcyA9IDAsXG4gICAgICAgICAgICBpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmICgoZG9udENvbnZlcnQgJiYgYXJyYXkxW2ldICE9PSBhcnJheTJbaV0pIHx8XG4gICAgICAgICAgICAgICAgKCFkb250Q29udmVydCAmJiB0b0ludChhcnJheTFbaV0pICE9PSB0b0ludChhcnJheTJbaV0pKSkge1xuICAgICAgICAgICAgICAgIGRpZmZzKys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRpZmZzICsgbGVuZ3RoRGlmZjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3YXJuKG1zZykge1xuICAgICAgICBpZiAoaG9va3Muc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmdzID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICh0eXBlb2YgY29uc29sZSAhPT0gICd1bmRlZmluZWQnKSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRGVwcmVjYXRpb24gd2FybmluZzogJyArIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkZXByZWNhdGUobXNnLCBmbikge1xuICAgICAgICB2YXIgZmlyc3RUaW1lID0gdHJ1ZTtcblxuICAgICAgICByZXR1cm4gZXh0ZW5kKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChob29rcy5kZXByZWNhdGlvbkhhbmRsZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGhvb2tzLmRlcHJlY2F0aW9uSGFuZGxlcihudWxsLCBtc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZpcnN0VGltZSkge1xuICAgICAgICAgICAgICAgIHZhciBhcmdzID0gW107XG4gICAgICAgICAgICAgICAgdmFyIGFyZztcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBhcmcgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbaV0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgKz0gJ1xcblsnICsgaSArICddICc7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gYXJndW1lbnRzWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnICs9IGtleSArICc6ICcgKyBhcmd1bWVudHNbMF1ba2V5XSArICcsICc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBhcmcuc2xpY2UoMCwgLTIpOyAvLyBSZW1vdmUgdHJhaWxpbmcgY29tbWEgYW5kIHNwYWNlXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKGFyZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdhcm4obXNnICsgJ1xcbkFyZ3VtZW50czogJyArIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MpLmpvaW4oJycpICsgJ1xcbicgKyAobmV3IEVycm9yKCkpLnN0YWNrKTtcbiAgICAgICAgICAgICAgICBmaXJzdFRpbWUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9LCBmbik7XG4gICAgfVxuXG4gICAgdmFyIGRlcHJlY2F0aW9ucyA9IHt9O1xuXG4gICAgZnVuY3Rpb24gZGVwcmVjYXRlU2ltcGxlKG5hbWUsIG1zZykge1xuICAgICAgICBpZiAoaG9va3MuZGVwcmVjYXRpb25IYW5kbGVyICE9IG51bGwpIHtcbiAgICAgICAgICAgIGhvb2tzLmRlcHJlY2F0aW9uSGFuZGxlcihuYW1lLCBtc2cpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZGVwcmVjYXRpb25zW25hbWVdKSB7XG4gICAgICAgICAgICB3YXJuKG1zZyk7XG4gICAgICAgICAgICBkZXByZWNhdGlvbnNbbmFtZV0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaG9va3Muc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmdzID0gZmFsc2U7XG4gICAgaG9va3MuZGVwcmVjYXRpb25IYW5kbGVyID0gbnVsbDtcblxuICAgIGZ1bmN0aW9uIGlzRnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0IGluc3RhbmNlb2YgRnVuY3Rpb24gfHwgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGlucHV0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXQgKGNvbmZpZykge1xuICAgICAgICB2YXIgcHJvcCwgaTtcbiAgICAgICAgZm9yIChpIGluIGNvbmZpZykge1xuICAgICAgICAgICAgcHJvcCA9IGNvbmZpZ1tpXTtcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHByb3ApKSB7XG4gICAgICAgICAgICAgICAgdGhpc1tpXSA9IHByb3A7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXNbJ18nICsgaV0gPSBwcm9wO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgLy8gTGVuaWVudCBvcmRpbmFsIHBhcnNpbmcgYWNjZXB0cyBqdXN0IGEgbnVtYmVyIGluIGFkZGl0aW9uIHRvXG4gICAgICAgIC8vIG51bWJlciArIChwb3NzaWJseSkgc3R1ZmYgY29taW5nIGZyb20gX2RheU9mTW9udGhPcmRpbmFsUGFyc2UuXG4gICAgICAgIC8vIFRPRE86IFJlbW92ZSBcIm9yZGluYWxQYXJzZVwiIGZhbGxiYWNrIGluIG5leHQgbWFqb3IgcmVsZWFzZS5cbiAgICAgICAgdGhpcy5fZGF5T2ZNb250aE9yZGluYWxQYXJzZUxlbmllbnQgPSBuZXcgUmVnRXhwKFxuICAgICAgICAgICAgKHRoaXMuX2RheU9mTW9udGhPcmRpbmFsUGFyc2Uuc291cmNlIHx8IHRoaXMuX29yZGluYWxQYXJzZS5zb3VyY2UpICtcbiAgICAgICAgICAgICAgICAnfCcgKyAoL1xcZHsxLDJ9Lykuc291cmNlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtZXJnZUNvbmZpZ3MocGFyZW50Q29uZmlnLCBjaGlsZENvbmZpZykge1xuICAgICAgICB2YXIgcmVzID0gZXh0ZW5kKHt9LCBwYXJlbnRDb25maWcpLCBwcm9wO1xuICAgICAgICBmb3IgKHByb3AgaW4gY2hpbGRDb25maWcpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd25Qcm9wKGNoaWxkQ29uZmlnLCBwcm9wKSkge1xuICAgICAgICAgICAgICAgIGlmIChpc09iamVjdChwYXJlbnRDb25maWdbcHJvcF0pICYmIGlzT2JqZWN0KGNoaWxkQ29uZmlnW3Byb3BdKSkge1xuICAgICAgICAgICAgICAgICAgICByZXNbcHJvcF0gPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kKHJlc1twcm9wXSwgcGFyZW50Q29uZmlnW3Byb3BdKTtcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kKHJlc1twcm9wXSwgY2hpbGRDb25maWdbcHJvcF0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hpbGRDb25maWdbcHJvcF0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXNbcHJvcF0gPSBjaGlsZENvbmZpZ1twcm9wXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcmVzW3Byb3BdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKHByb3AgaW4gcGFyZW50Q29uZmlnKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChwYXJlbnRDb25maWcsIHByb3ApICYmXG4gICAgICAgICAgICAgICAgICAgICFoYXNPd25Qcm9wKGNoaWxkQ29uZmlnLCBwcm9wKSAmJlxuICAgICAgICAgICAgICAgICAgICBpc09iamVjdChwYXJlbnRDb25maWdbcHJvcF0pKSB7XG4gICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGNoYW5nZXMgdG8gcHJvcGVydGllcyBkb24ndCBtb2RpZnkgcGFyZW50IGNvbmZpZ1xuICAgICAgICAgICAgICAgIHJlc1twcm9wXSA9IGV4dGVuZCh7fSwgcmVzW3Byb3BdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIExvY2FsZShjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZyAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnNldChjb25maWcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGtleXM7XG5cbiAgICBpZiAoT2JqZWN0LmtleXMpIHtcbiAgICAgICAga2V5cyA9IE9iamVjdC5rZXlzO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGtleXMgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICB2YXIgaSwgcmVzID0gW107XG4gICAgICAgICAgICBmb3IgKGkgaW4gb2JqKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhc093blByb3Aob2JqLCBpKSkge1xuICAgICAgICAgICAgICAgICAgICByZXMucHVzaChpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0Q2FsZW5kYXIgPSB7XG4gICAgICAgIHNhbWVEYXkgOiAnW1RvZGF5IGF0XSBMVCcsXG4gICAgICAgIG5leHREYXkgOiAnW1RvbW9ycm93IGF0XSBMVCcsXG4gICAgICAgIG5leHRXZWVrIDogJ2RkZGQgW2F0XSBMVCcsXG4gICAgICAgIGxhc3REYXkgOiAnW1llc3RlcmRheSBhdF0gTFQnLFxuICAgICAgICBsYXN0V2VlayA6ICdbTGFzdF0gZGRkZCBbYXRdIExUJyxcbiAgICAgICAgc2FtZUVsc2UgOiAnTCdcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gY2FsZW5kYXIgKGtleSwgbW9tLCBub3cpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX2NhbGVuZGFyW2tleV0gfHwgdGhpcy5fY2FsZW5kYXJbJ3NhbWVFbHNlJ107XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKG91dHB1dCkgPyBvdXRwdXQuY2FsbChtb20sIG5vdykgOiBvdXRwdXQ7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb25nRGF0ZUZvcm1hdCA9IHtcbiAgICAgICAgTFRTICA6ICdoOm1tOnNzIEEnLFxuICAgICAgICBMVCAgIDogJ2g6bW0gQScsXG4gICAgICAgIEwgICAgOiAnTU0vREQvWVlZWScsXG4gICAgICAgIExMICAgOiAnTU1NTSBELCBZWVlZJyxcbiAgICAgICAgTExMICA6ICdNTU1NIEQsIFlZWVkgaDptbSBBJyxcbiAgICAgICAgTExMTCA6ICdkZGRkLCBNTU1NIEQsIFlZWVkgaDptbSBBJ1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb25nRGF0ZUZvcm1hdCAoa2V5KSB7XG4gICAgICAgIHZhciBmb3JtYXQgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldLFxuICAgICAgICAgICAgZm9ybWF0VXBwZXIgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXkudG9VcHBlckNhc2UoKV07XG5cbiAgICAgICAgaWYgKGZvcm1hdCB8fCAhZm9ybWF0VXBwZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldID0gZm9ybWF0VXBwZXIucmVwbGFjZSgvTU1NTXxNTXxERHxkZGRkL2csIGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWwuc2xpY2UoMSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0SW52YWxpZERhdGUgPSAnSW52YWxpZCBkYXRlJztcblxuICAgIGZ1bmN0aW9uIGludmFsaWREYXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ludmFsaWREYXRlO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0T3JkaW5hbCA9ICclZCc7XG4gICAgdmFyIGRlZmF1bHREYXlPZk1vbnRoT3JkaW5hbFBhcnNlID0gL1xcZHsxLDJ9LztcblxuICAgIGZ1bmN0aW9uIG9yZGluYWwgKG51bWJlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3JkaW5hbC5yZXBsYWNlKCclZCcsIG51bWJlcik7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRSZWxhdGl2ZVRpbWUgPSB7XG4gICAgICAgIGZ1dHVyZSA6ICdpbiAlcycsXG4gICAgICAgIHBhc3QgICA6ICclcyBhZ28nLFxuICAgICAgICBzICA6ICdhIGZldyBzZWNvbmRzJyxcbiAgICAgICAgc3MgOiAnJWQgc2Vjb25kcycsXG4gICAgICAgIG0gIDogJ2EgbWludXRlJyxcbiAgICAgICAgbW0gOiAnJWQgbWludXRlcycsXG4gICAgICAgIGggIDogJ2FuIGhvdXInLFxuICAgICAgICBoaCA6ICclZCBob3VycycsXG4gICAgICAgIGQgIDogJ2EgZGF5JyxcbiAgICAgICAgZGQgOiAnJWQgZGF5cycsXG4gICAgICAgIE0gIDogJ2EgbW9udGgnLFxuICAgICAgICBNTSA6ICclZCBtb250aHMnLFxuICAgICAgICB5ICA6ICdhIHllYXInLFxuICAgICAgICB5eSA6ICclZCB5ZWFycydcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcmVsYXRpdmVUaW1lIChudW1iZXIsIHdpdGhvdXRTdWZmaXgsIHN0cmluZywgaXNGdXR1cmUpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX3JlbGF0aXZlVGltZVtzdHJpbmddO1xuICAgICAgICByZXR1cm4gKGlzRnVuY3Rpb24ob3V0cHV0KSkgP1xuICAgICAgICAgICAgb3V0cHV0KG51bWJlciwgd2l0aG91dFN1ZmZpeCwgc3RyaW5nLCBpc0Z1dHVyZSkgOlxuICAgICAgICAgICAgb3V0cHV0LnJlcGxhY2UoLyVkL2ksIG51bWJlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFzdEZ1dHVyZSAoZGlmZiwgb3V0cHV0KSB7XG4gICAgICAgIHZhciBmb3JtYXQgPSB0aGlzLl9yZWxhdGl2ZVRpbWVbZGlmZiA+IDAgPyAnZnV0dXJlJyA6ICdwYXN0J107XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKGZvcm1hdCkgPyBmb3JtYXQob3V0cHV0KSA6IGZvcm1hdC5yZXBsYWNlKC8lcy9pLCBvdXRwdXQpO1xuICAgIH1cblxuICAgIHZhciBhbGlhc2VzID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRVbml0QWxpYXMgKHVuaXQsIHNob3J0aGFuZCkge1xuICAgICAgICB2YXIgbG93ZXJDYXNlID0gdW5pdC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBhbGlhc2VzW2xvd2VyQ2FzZV0gPSBhbGlhc2VzW2xvd2VyQ2FzZSArICdzJ10gPSBhbGlhc2VzW3Nob3J0aGFuZF0gPSB1bml0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdW5pdHMgPT09ICdzdHJpbmcnID8gYWxpYXNlc1t1bml0c10gfHwgYWxpYXNlc1t1bml0cy50b0xvd2VyQ2FzZSgpXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBub3JtYWxpemVPYmplY3RVbml0cyhpbnB1dE9iamVjdCkge1xuICAgICAgICB2YXIgbm9ybWFsaXplZElucHV0ID0ge30sXG4gICAgICAgICAgICBub3JtYWxpemVkUHJvcCxcbiAgICAgICAgICAgIHByb3A7XG5cbiAgICAgICAgZm9yIChwcm9wIGluIGlucHV0T2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChpbnB1dE9iamVjdCwgcHJvcCkpIHtcbiAgICAgICAgICAgICAgICBub3JtYWxpemVkUHJvcCA9IG5vcm1hbGl6ZVVuaXRzKHByb3ApO1xuICAgICAgICAgICAgICAgIGlmIChub3JtYWxpemVkUHJvcCkge1xuICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkSW5wdXRbbm9ybWFsaXplZFByb3BdID0gaW5wdXRPYmplY3RbcHJvcF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRJbnB1dDtcbiAgICB9XG5cbiAgICB2YXIgcHJpb3JpdGllcyA9IHt9O1xuXG4gICAgZnVuY3Rpb24gYWRkVW5pdFByaW9yaXR5KHVuaXQsIHByaW9yaXR5KSB7XG4gICAgICAgIHByaW9yaXRpZXNbdW5pdF0gPSBwcmlvcml0eTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRQcmlvcml0aXplZFVuaXRzKHVuaXRzT2JqKSB7XG4gICAgICAgIHZhciB1bml0cyA9IFtdO1xuICAgICAgICBmb3IgKHZhciB1IGluIHVuaXRzT2JqKSB7XG4gICAgICAgICAgICB1bml0cy5wdXNoKHt1bml0OiB1LCBwcmlvcml0eTogcHJpb3JpdGllc1t1XX0pO1xuICAgICAgICB9XG4gICAgICAgIHVuaXRzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgIHJldHVybiBhLnByaW9yaXR5IC0gYi5wcmlvcml0eTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB1bml0cztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB6ZXJvRmlsbChudW1iZXIsIHRhcmdldExlbmd0aCwgZm9yY2VTaWduKSB7XG4gICAgICAgIHZhciBhYnNOdW1iZXIgPSAnJyArIE1hdGguYWJzKG51bWJlciksXG4gICAgICAgICAgICB6ZXJvc1RvRmlsbCA9IHRhcmdldExlbmd0aCAtIGFic051bWJlci5sZW5ndGgsXG4gICAgICAgICAgICBzaWduID0gbnVtYmVyID49IDA7XG4gICAgICAgIHJldHVybiAoc2lnbiA/IChmb3JjZVNpZ24gPyAnKycgOiAnJykgOiAnLScpICtcbiAgICAgICAgICAgIE1hdGgucG93KDEwLCBNYXRoLm1heCgwLCB6ZXJvc1RvRmlsbCkpLnRvU3RyaW5nKCkuc3Vic3RyKDEpICsgYWJzTnVtYmVyO1xuICAgIH1cblxuICAgIHZhciBmb3JtYXR0aW5nVG9rZW5zID0gLyhcXFtbXlxcW10qXFxdKXwoXFxcXCk/KFtIaF1tbShzcyk/fE1vfE1NP00/TT98RG98REREb3xERD9EP0Q/fGRkZD9kP3xkbz98d1tvfHddP3xXW298V10/fFFvP3xZWVlZWVl8WVlZWVl8WVlZWXxZWXxnZyhnZ2c/KT98R0coR0dHPyk/fGV8RXxhfEF8aGg/fEhIP3xraz98bW0/fHNzP3xTezEsOX18eHxYfHp6P3xaWj98LikvZztcblxuICAgIHZhciBsb2NhbEZvcm1hdHRpbmdUb2tlbnMgPSAvKFxcW1teXFxbXSpcXF0pfChcXFxcKT8oTFRTfExUfExMP0w/TD98bHsxLDR9KS9nO1xuXG4gICAgdmFyIGZvcm1hdEZ1bmN0aW9ucyA9IHt9O1xuXG4gICAgdmFyIGZvcm1hdFRva2VuRnVuY3Rpb25zID0ge307XG5cbiAgICAvLyB0b2tlbjogICAgJ00nXG4gICAgLy8gcGFkZGVkOiAgIFsnTU0nLCAyXVxuICAgIC8vIG9yZGluYWw6ICAnTW8nXG4gICAgLy8gY2FsbGJhY2s6IGZ1bmN0aW9uICgpIHsgdGhpcy5tb250aCgpICsgMSB9XG4gICAgZnVuY3Rpb24gYWRkRm9ybWF0VG9rZW4gKHRva2VuLCBwYWRkZWQsIG9yZGluYWwsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBmdW5jID0gY2FsbGJhY2s7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBmdW5jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW2NhbGxiYWNrXSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9rZW4pIHtcbiAgICAgICAgICAgIGZvcm1hdFRva2VuRnVuY3Rpb25zW3Rva2VuXSA9IGZ1bmM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhZGRlZCkge1xuICAgICAgICAgICAgZm9ybWF0VG9rZW5GdW5jdGlvbnNbcGFkZGVkWzBdXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gemVyb0ZpbGwoZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpLCBwYWRkZWRbMV0sIHBhZGRlZFsyXSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcmRpbmFsKSB7XG4gICAgICAgICAgICBmb3JtYXRUb2tlbkZ1bmN0aW9uc1tvcmRpbmFsXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkub3JkaW5hbChmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIHRva2VuKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGlucHV0KSB7XG4gICAgICAgIGlmIChpbnB1dC5tYXRjaCgvXFxbW1xcc1xcU10vKSkge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL15cXFt8XFxdJC9nLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL1xcXFwvZywgJycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VGb3JtYXRGdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgICAgdmFyIGFycmF5ID0gZm9ybWF0Lm1hdGNoKGZvcm1hdHRpbmdUb2tlbnMpLCBpLCBsZW5ndGg7XG5cbiAgICAgICAgZm9yIChpID0gMCwgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXRUb2tlbkZ1bmN0aW9uc1thcnJheVtpXV0pIHtcbiAgICAgICAgICAgICAgICBhcnJheVtpXSA9IGZvcm1hdFRva2VuRnVuY3Rpb25zW2FycmF5W2ldXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXJyYXlbaV0gPSByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGFycmF5W2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAobW9tKSB7XG4gICAgICAgICAgICB2YXIgb3V0cHV0ID0gJycsIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gaXNGdW5jdGlvbihhcnJheVtpXSkgPyBhcnJheVtpXS5jYWxsKG1vbSwgZm9ybWF0KSA6IGFycmF5W2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBmb3JtYXQgZGF0ZSB1c2luZyBuYXRpdmUgZGF0ZSBvYmplY3RcbiAgICBmdW5jdGlvbiBmb3JtYXRNb21lbnQobSwgZm9ybWF0KSB7XG4gICAgICAgIGlmICghbS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBtLmxvY2FsZURhdGEoKS5pbnZhbGlkRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9ybWF0ID0gZXhwYW5kRm9ybWF0KGZvcm1hdCwgbS5sb2NhbGVEYXRhKCkpO1xuICAgICAgICBmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XSA9IGZvcm1hdEZ1bmN0aW9uc1tmb3JtYXRdIHx8IG1ha2VGb3JtYXRGdW5jdGlvbihmb3JtYXQpO1xuXG4gICAgICAgIHJldHVybiBmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XShtKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBleHBhbmRGb3JtYXQoZm9ybWF0LCBsb2NhbGUpIHtcbiAgICAgICAgdmFyIGkgPSA1O1xuXG4gICAgICAgIGZ1bmN0aW9uIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2VucyhpbnB1dCkge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS5sb25nRGF0ZUZvcm1hdChpbnB1dCkgfHwgaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPj0gMCAmJiBsb2NhbEZvcm1hdHRpbmdUb2tlbnMudGVzdChmb3JtYXQpKSB7XG4gICAgICAgICAgICBmb3JtYXQgPSBmb3JtYXQucmVwbGFjZShsb2NhbEZvcm1hdHRpbmdUb2tlbnMsIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2Vucyk7XG4gICAgICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgfVxuXG4gICAgdmFyIG1hdGNoMSAgICAgICAgID0gL1xcZC87ICAgICAgICAgICAgLy8gICAgICAgMCAtIDlcbiAgICB2YXIgbWF0Y2gyICAgICAgICAgPSAvXFxkXFxkLzsgICAgICAgICAgLy8gICAgICAwMCAtIDk5XG4gICAgdmFyIG1hdGNoMyAgICAgICAgID0gL1xcZHszfS87ICAgICAgICAgLy8gICAgIDAwMCAtIDk5OVxuICAgIHZhciBtYXRjaDQgICAgICAgICA9IC9cXGR7NH0vOyAgICAgICAgIC8vICAgIDAwMDAgLSA5OTk5XG4gICAgdmFyIG1hdGNoNiAgICAgICAgID0gL1srLV0/XFxkezZ9LzsgICAgLy8gLTk5OTk5OSAtIDk5OTk5OVxuICAgIHZhciBtYXRjaDF0bzIgICAgICA9IC9cXGRcXGQ/LzsgICAgICAgICAvLyAgICAgICAwIC0gOTlcbiAgICB2YXIgbWF0Y2gzdG80ICAgICAgPSAvXFxkXFxkXFxkXFxkPy87ICAgICAvLyAgICAgOTk5IC0gOTk5OVxuICAgIHZhciBtYXRjaDV0bzYgICAgICA9IC9cXGRcXGRcXGRcXGRcXGRcXGQ/LzsgLy8gICA5OTk5OSAtIDk5OTk5OVxuICAgIHZhciBtYXRjaDF0bzMgICAgICA9IC9cXGR7MSwzfS87ICAgICAgIC8vICAgICAgIDAgLSA5OTlcbiAgICB2YXIgbWF0Y2gxdG80ICAgICAgPSAvXFxkezEsNH0vOyAgICAgICAvLyAgICAgICAwIC0gOTk5OVxuICAgIHZhciBtYXRjaDF0bzYgICAgICA9IC9bKy1dP1xcZHsxLDZ9LzsgIC8vIC05OTk5OTkgLSA5OTk5OTlcblxuICAgIHZhciBtYXRjaFVuc2lnbmVkICA9IC9cXGQrLzsgICAgICAgICAgIC8vICAgICAgIDAgLSBpbmZcbiAgICB2YXIgbWF0Y2hTaWduZWQgICAgPSAvWystXT9cXGQrLzsgICAgICAvLyAgICAtaW5mIC0gaW5mXG5cbiAgICB2YXIgbWF0Y2hPZmZzZXQgICAgPSAvWnxbKy1dXFxkXFxkOj9cXGRcXGQvZ2k7IC8vICswMDowMCAtMDA6MDAgKzAwMDAgLTAwMDAgb3IgWlxuICAgIHZhciBtYXRjaFNob3J0T2Zmc2V0ID0gL1p8WystXVxcZFxcZCg/Ojo/XFxkXFxkKT8vZ2k7IC8vICswMCAtMDAgKzAwOjAwIC0wMDowMCArMDAwMCAtMDAwMCBvciBaXG5cbiAgICB2YXIgbWF0Y2hUaW1lc3RhbXAgPSAvWystXT9cXGQrKFxcLlxcZHsxLDN9KT8vOyAvLyAxMjM0NTY3ODkgMTIzNDU2Nzg5LjEyM1xuXG4gICAgLy8gYW55IHdvcmQgKG9yIHR3bykgY2hhcmFjdGVycyBvciBudW1iZXJzIGluY2x1ZGluZyB0d28vdGhyZWUgd29yZCBtb250aCBpbiBhcmFiaWMuXG4gICAgLy8gaW5jbHVkZXMgc2NvdHRpc2ggZ2FlbGljIHR3byB3b3JkIGFuZCBoeXBoZW5hdGVkIG1vbnRoc1xuICAgIHZhciBtYXRjaFdvcmQgPSAvWzAtOV17MCwyNTZ9WydhLXpcXHUwMEEwLVxcdTA1RkZcXHUwNzAwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGMDdcXHVGRjEwLVxcdUZGRUZdezEsMjU2fXxbXFx1MDYwMC1cXHUwNkZGXFwvXXsxLDI1Nn0oXFxzKj9bXFx1MDYwMC1cXHUwNkZGXXsxLDI1Nn0pezEsMn0vaTtcblxuICAgIHZhciByZWdleGVzID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRSZWdleFRva2VuICh0b2tlbiwgcmVnZXgsIHN0cmljdFJlZ2V4KSB7XG4gICAgICAgIHJlZ2V4ZXNbdG9rZW5dID0gaXNGdW5jdGlvbihyZWdleCkgPyByZWdleCA6IGZ1bmN0aW9uIChpc1N0cmljdCwgbG9jYWxlRGF0YSkge1xuICAgICAgICAgICAgcmV0dXJuIChpc1N0cmljdCAmJiBzdHJpY3RSZWdleCkgPyBzdHJpY3RSZWdleCA6IHJlZ2V4O1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFBhcnNlUmVnZXhGb3JUb2tlbiAodG9rZW4sIGNvbmZpZykge1xuICAgICAgICBpZiAoIWhhc093blByb3AocmVnZXhlcywgdG9rZW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cCh1bmVzY2FwZUZvcm1hdCh0b2tlbikpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlZ2V4ZXNbdG9rZW5dKGNvbmZpZy5fc3RyaWN0LCBjb25maWcuX2xvY2FsZSk7XG4gICAgfVxuXG4gICAgLy8gQ29kZSBmcm9tIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzU2MTQ5My9pcy10aGVyZS1hLXJlZ2V4cC1lc2NhcGUtZnVuY3Rpb24taW4tamF2YXNjcmlwdFxuICAgIGZ1bmN0aW9uIHVuZXNjYXBlRm9ybWF0KHMpIHtcbiAgICAgICAgcmV0dXJuIHJlZ2V4RXNjYXBlKHMucmVwbGFjZSgnXFxcXCcsICcnKS5yZXBsYWNlKC9cXFxcKFxcWyl8XFxcXChcXF0pfFxcWyhbXlxcXVxcW10qKVxcXXxcXFxcKC4pL2csIGZ1bmN0aW9uIChtYXRjaGVkLCBwMSwgcDIsIHAzLCBwNCkge1xuICAgICAgICAgICAgcmV0dXJuIHAxIHx8IHAyIHx8IHAzIHx8IHA0O1xuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVnZXhFc2NhcGUocykge1xuICAgICAgICByZXR1cm4gcy5yZXBsYWNlKC9bLVxcL1xcXFxeJCorPy4oKXxbXFxde31dL2csICdcXFxcJCYnKTtcbiAgICB9XG5cbiAgICB2YXIgdG9rZW5zID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRQYXJzZVRva2VuICh0b2tlbiwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGksIGZ1bmMgPSBjYWxsYmFjaztcbiAgICAgICAgaWYgKHR5cGVvZiB0b2tlbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRva2VuID0gW3Rva2VuXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNOdW1iZXIoY2FsbGJhY2spKSB7XG4gICAgICAgICAgICBmdW5jID0gZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICAgICAgICAgIGFycmF5W2NhbGxiYWNrXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRva2VuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0b2tlbnNbdG9rZW5baV1dID0gZnVuYztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFdlZWtQYXJzZVRva2VuICh0b2tlbiwgY2FsbGJhY2spIHtcbiAgICAgICAgYWRkUGFyc2VUb2tlbih0b2tlbiwgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnLCB0b2tlbikge1xuICAgICAgICAgICAgY29uZmlnLl93ID0gY29uZmlnLl93IHx8IHt9O1xuICAgICAgICAgICAgY2FsbGJhY2soaW5wdXQsIGNvbmZpZy5fdywgY29uZmlnLCB0b2tlbik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFRpbWVUb0FycmF5RnJvbVRva2VuKHRva2VuLCBpbnB1dCwgY29uZmlnKSB7XG4gICAgICAgIGlmIChpbnB1dCAhPSBudWxsICYmIGhhc093blByb3AodG9rZW5zLCB0b2tlbikpIHtcbiAgICAgICAgICAgIHRva2Vuc1t0b2tlbl0oaW5wdXQsIGNvbmZpZy5fYSwgY29uZmlnLCB0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgWUVBUiA9IDA7XG4gICAgdmFyIE1PTlRIID0gMTtcbiAgICB2YXIgREFURSA9IDI7XG4gICAgdmFyIEhPVVIgPSAzO1xuICAgIHZhciBNSU5VVEUgPSA0O1xuICAgIHZhciBTRUNPTkQgPSA1O1xuICAgIHZhciBNSUxMSVNFQ09ORCA9IDY7XG4gICAgdmFyIFdFRUsgPSA3O1xuICAgIHZhciBXRUVLREFZID0gODtcblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdZJywgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgeSA9IHRoaXMueWVhcigpO1xuICAgICAgICByZXR1cm4geSA8PSA5OTk5ID8gJycgKyB5IDogJysnICsgeTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnWVknLCAyXSwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy55ZWFyKCkgJSAxMDA7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1lZWVknLCAgIDRdLCAgICAgICAwLCAneWVhcicpO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnWVlZWVknLCAgNV0sICAgICAgIDAsICd5ZWFyJyk7XG4gICAgYWRkRm9ybWF0VG9rZW4oMCwgWydZWVlZWVknLCA2LCB0cnVlXSwgMCwgJ3llYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygneWVhcicsICd5Jyk7XG5cbiAgICAvLyBQUklPUklUSUVTXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ3llYXInLCAxKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1knLCAgICAgIG1hdGNoU2lnbmVkKTtcbiAgICBhZGRSZWdleFRva2VuKCdZWScsICAgICBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignWVlZWScsICAgbWF0Y2gxdG80LCBtYXRjaDQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1lZWVlZJywgIG1hdGNoMXRvNiwgbWF0Y2g2KTtcbiAgICBhZGRSZWdleFRva2VuKCdZWVlZWVknLCBtYXRjaDF0bzYsIG1hdGNoNik7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnWVlZWVknLCAnWVlZWVlZJ10sIFlFQVIpO1xuICAgIGFkZFBhcnNlVG9rZW4oJ1lZWVknLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5KSB7XG4gICAgICAgIGFycmF5W1lFQVJdID0gaW5wdXQubGVuZ3RoID09PSAyID8gaG9va3MucGFyc2VUd29EaWdpdFllYXIoaW5wdXQpIDogdG9JbnQoaW5wdXQpO1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oJ1lZJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtZRUFSXSA9IGhvb2tzLnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCdZJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtZRUFSXSA9IHBhcnNlSW50KGlucHV0LCAxMCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICBmdW5jdGlvbiBkYXlzSW5ZZWFyKHllYXIpIHtcbiAgICAgICAgcmV0dXJuIGlzTGVhcFllYXIoeWVhcikgPyAzNjYgOiAzNjU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNMZWFwWWVhcih5ZWFyKSB7XG4gICAgICAgIHJldHVybiAoeWVhciAlIDQgPT09IDAgJiYgeWVhciAlIDEwMCAhPT0gMCkgfHwgeWVhciAlIDQwMCA9PT0gMDtcbiAgICB9XG5cbiAgICAvLyBIT09LU1xuXG4gICAgaG9va3MucGFyc2VUd29EaWdpdFllYXIgPSBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHRvSW50KGlucHV0KSArICh0b0ludChpbnB1dCkgPiA2OCA/IDE5MDAgOiAyMDAwKTtcbiAgICB9O1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgdmFyIGdldFNldFllYXIgPSBtYWtlR2V0U2V0KCdGdWxsWWVhcicsIHRydWUpO1xuXG4gICAgZnVuY3Rpb24gZ2V0SXNMZWFwWWVhciAoKSB7XG4gICAgICAgIHJldHVybiBpc0xlYXBZZWFyKHRoaXMueWVhcigpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlR2V0U2V0ICh1bml0LCBrZWVwVGltZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHNldCQxKHRoaXMsIHVuaXQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywga2VlcFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0KHRoaXMsIHVuaXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldCAobW9tLCB1bml0KSB7XG4gICAgICAgIHJldHVybiBtb20uaXNWYWxpZCgpID9cbiAgICAgICAgICAgIG1vbS5fZFsnZ2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyB1bml0XSgpIDogTmFOO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldCQxIChtb20sIHVuaXQsIHZhbHVlKSB7XG4gICAgICAgIGlmIChtb20uaXNWYWxpZCgpICYmICFpc05hTih2YWx1ZSkpIHtcbiAgICAgICAgICAgIGlmICh1bml0ID09PSAnRnVsbFllYXInICYmIGlzTGVhcFllYXIobW9tLnllYXIoKSkgJiYgbW9tLm1vbnRoKCkgPT09IDEgJiYgbW9tLmRhdGUoKSA9PT0gMjkpIHtcbiAgICAgICAgICAgICAgICBtb20uX2RbJ3NldCcgKyAobW9tLl9pc1VUQyA/ICdVVEMnIDogJycpICsgdW5pdF0odmFsdWUsIG1vbS5tb250aCgpLCBkYXlzSW5Nb250aCh2YWx1ZSwgbW9tLm1vbnRoKCkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyB1bml0XSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBzdHJpbmdHZXQgKHVuaXRzKSB7XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICBpZiAoaXNGdW5jdGlvbih0aGlzW3VuaXRzXSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzXSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gc3RyaW5nU2V0ICh1bml0cywgdmFsdWUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB1bml0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHVuaXRzID0gbm9ybWFsaXplT2JqZWN0VW5pdHModW5pdHMpO1xuICAgICAgICAgICAgdmFyIHByaW9yaXRpemVkID0gZ2V0UHJpb3JpdGl6ZWRVbml0cyh1bml0cyk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByaW9yaXRpemVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpc1twcmlvcml0aXplZFtpXS51bml0XSh1bml0c1twcmlvcml0aXplZFtpXS51bml0XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHRoaXNbdW5pdHNdKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzXSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbW9kKG4sIHgpIHtcbiAgICAgICAgcmV0dXJuICgobiAlIHgpICsgeCkgJSB4O1xuICAgIH1cblxuICAgIHZhciBpbmRleE9mO1xuXG4gICAgaWYgKEFycmF5LnByb3RvdHlwZS5pbmRleE9mKSB7XG4gICAgICAgIGluZGV4T2YgPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZjtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpbmRleE9mID0gZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgICAgIC8vIEkga25vd1xuICAgICAgICAgICAgdmFyIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSBvKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlzSW5Nb250aCh5ZWFyLCBtb250aCkge1xuICAgICAgICBpZiAoaXNOYU4oeWVhcikgfHwgaXNOYU4obW9udGgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtb2RNb250aCA9IG1vZChtb250aCwgMTIpO1xuICAgICAgICB5ZWFyICs9IChtb250aCAtIG1vZE1vbnRoKSAvIDEyO1xuICAgICAgICByZXR1cm4gbW9kTW9udGggPT09IDEgPyAoaXNMZWFwWWVhcih5ZWFyKSA/IDI5IDogMjgpIDogKDMxIC0gbW9kTW9udGggJSA3ICUgMik7XG4gICAgfVxuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ00nLCBbJ01NJywgMl0sICdNbycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9udGgoKSArIDE7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignTU1NJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzU2hvcnQodGhpcywgZm9ybWF0KTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdNTU1NJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzKHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21vbnRoJywgJ00nKTtcblxuICAgIC8vIFBSSU9SSVRZXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ21vbnRoJywgOCk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdNJywgICAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdNTScsICAgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ01NTScsICBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLm1vbnRoc1Nob3J0UmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ01NTU0nLCBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLm1vbnRoc1JlZ2V4KGlzU3RyaWN0KTtcbiAgICB9KTtcblxuICAgIGFkZFBhcnNlVG9rZW4oWydNJywgJ01NJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbTU9OVEhdID0gdG9JbnQoaW5wdXQpIC0gMTtcbiAgICB9KTtcblxuICAgIGFkZFBhcnNlVG9rZW4oWydNTU0nLCAnTU1NTSddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcsIHRva2VuKSB7XG4gICAgICAgIHZhciBtb250aCA9IGNvbmZpZy5fbG9jYWxlLm1vbnRoc1BhcnNlKGlucHV0LCB0b2tlbiwgY29uZmlnLl9zdHJpY3QpO1xuICAgICAgICAvLyBpZiB3ZSBkaWRuJ3QgZmluZCBhIG1vbnRoIG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZC5cbiAgICAgICAgaWYgKG1vbnRoICE9IG51bGwpIHtcbiAgICAgICAgICAgIGFycmF5W01PTlRIXSA9IG1vbnRoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuaW52YWxpZE1vbnRoID0gaW5wdXQ7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIExPQ0FMRVNcblxuICAgIHZhciBNT05USFNfSU5fRk9STUFUID0gL0Rbb0RdPyhcXFtbXlxcW1xcXV0qXFxdfFxccykrTU1NTT8vO1xuICAgIHZhciBkZWZhdWx0TG9jYWxlTW9udGhzID0gJ0phbnVhcnlfRmVicnVhcnlfTWFyY2hfQXByaWxfTWF5X0p1bmVfSnVseV9BdWd1c3RfU2VwdGVtYmVyX09jdG9iZXJfTm92ZW1iZXJfRGVjZW1iZXInLnNwbGl0KCdfJyk7XG4gICAgZnVuY3Rpb24gbG9jYWxlTW9udGhzIChtLCBmb3JtYXQpIHtcbiAgICAgICAgaWYgKCFtKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNBcnJheSh0aGlzLl9tb250aHMpID8gdGhpcy5fbW9udGhzIDpcbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNbJ3N0YW5kYWxvbmUnXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNBcnJheSh0aGlzLl9tb250aHMpID8gdGhpcy5fbW9udGhzW20ubW9udGgoKV0gOlxuICAgICAgICAgICAgdGhpcy5fbW9udGhzWyh0aGlzLl9tb250aHMuaXNGb3JtYXQgfHwgTU9OVEhTX0lOX0ZPUk1BVCkudGVzdChmb3JtYXQpID8gJ2Zvcm1hdCcgOiAnc3RhbmRhbG9uZSddW20ubW9udGgoKV07XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb2NhbGVNb250aHNTaG9ydCA9ICdKYW5fRmViX01hcl9BcHJfTWF5X0p1bl9KdWxfQXVnX1NlcF9PY3RfTm92X0RlYycuc3BsaXQoJ18nKTtcbiAgICBmdW5jdGlvbiBsb2NhbGVNb250aHNTaG9ydCAobSwgZm9ybWF0KSB7XG4gICAgICAgIGlmICghbSkge1xuICAgICAgICAgICAgcmV0dXJuIGlzQXJyYXkodGhpcy5fbW9udGhzU2hvcnQpID8gdGhpcy5fbW9udGhzU2hvcnQgOlxuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1Nob3J0WydzdGFuZGFsb25lJ107XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlzQXJyYXkodGhpcy5fbW9udGhzU2hvcnQpID8gdGhpcy5fbW9udGhzU2hvcnRbbS5tb250aCgpXSA6XG4gICAgICAgICAgICB0aGlzLl9tb250aHNTaG9ydFtNT05USFNfSU5fRk9STUFULnRlc3QoZm9ybWF0KSA/ICdmb3JtYXQnIDogJ3N0YW5kYWxvbmUnXVttLm1vbnRoKCldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZVN0cmljdFBhcnNlKG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGksIGlpLCBtb20sIGxsYyA9IG1vbnRoTmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoIXRoaXMuX21vbnRoc1BhcnNlKSB7XG4gICAgICAgICAgICAvLyB0aGlzIGlzIG5vdCB1c2VkXG4gICAgICAgICAgICB0aGlzLl9tb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTI7ICsraSkge1xuICAgICAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgaV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Nob3J0TW9udGhzUGFyc2VbaV0gPSB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldID0gdGhpcy5tb250aHMobW9tLCAnJykudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdNTU0nKSB7XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9sb25nTW9udGhzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdNTU0nKSB7XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fbG9uZ01vbnRoc1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpaSAhPT0gLTEgPyBpaSA6IG51bGw7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX2xvbmdNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9jYWxlTW9udGhzUGFyc2UgKG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGksIG1vbSwgcmVnZXg7XG5cbiAgICAgICAgaWYgKHRoaXMuX21vbnRoc1BhcnNlRXhhY3QpIHtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVTdHJpY3RQYXJzZS5jYWxsKHRoaXMsIG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLl9tb250aHNQYXJzZSkge1xuICAgICAgICAgICAgdGhpcy5fbW9udGhzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX2xvbmdNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVE9ETzogYWRkIHNvcnRpbmdcbiAgICAgICAgLy8gU29ydGluZyBtYWtlcyBzdXJlIGlmIG9uZSBtb250aCAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlclxuICAgICAgICAvLyBzZWUgc29ydGluZyBpbiBjb21wdXRlTW9udGhzUGFyc2VcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuICAgICAgICAgICAgbW9tID0gY3JlYXRlVVRDKFsyMDAwLCBpXSk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmICF0aGlzLl9sb25nTW9udGhzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb25nTW9udGhzUGFyc2VbaV0gPSBuZXcgUmVnRXhwKCdeJyArIHRoaXMubW9udGhzKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnJykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZVtpXSA9IG5ldyBSZWdFeHAoJ14nICsgdGhpcy5tb250aHNTaG9ydChtb20sICcnKS5yZXBsYWNlKCcuJywgJycpICsgJyQnLCAnaScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFzdHJpY3QgJiYgIXRoaXMuX21vbnRoc1BhcnNlW2ldKSB7XG4gICAgICAgICAgICAgICAgcmVnZXggPSAnXicgKyB0aGlzLm1vbnRocyhtb20sICcnKSArICd8XicgKyB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1BhcnNlW2ldID0gbmV3IFJlZ0V4cChyZWdleC5yZXBsYWNlKCcuJywgJycpLCAnaScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdGVzdCB0aGUgcmVnZXhcbiAgICAgICAgICAgIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NTScgJiYgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NJyAmJiB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghc3RyaWN0ICYmIHRoaXMuX21vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgZnVuY3Rpb24gc2V0TW9udGggKG1vbSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIGRheU9mTW9udGg7XG5cbiAgICAgICAgaWYgKCFtb20uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICAvLyBObyBvcFxuICAgICAgICAgICAgcmV0dXJuIG1vbTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAoL15cXGQrJC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRvSW50KHZhbHVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBtb20ubG9jYWxlRGF0YSgpLm1vbnRoc1BhcnNlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBBbm90aGVyIHNpbGVudCBmYWlsdXJlP1xuICAgICAgICAgICAgICAgIGlmICghaXNOdW1iZXIodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtb207XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZGF5T2ZNb250aCA9IE1hdGgubWluKG1vbS5kYXRlKCksIGRheXNJbk1vbnRoKG1vbS55ZWFyKCksIHZhbHVlKSk7XG4gICAgICAgIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyAnTW9udGgnXSh2YWx1ZSwgZGF5T2ZNb250aCk7XG4gICAgICAgIHJldHVybiBtb207XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2V0TW9udGggKHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBzZXRNb250aCh0aGlzLCB2YWx1ZSk7XG4gICAgICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBnZXQodGhpcywgJ01vbnRoJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXREYXlzSW5Nb250aCAoKSB7XG4gICAgICAgIHJldHVybiBkYXlzSW5Nb250aCh0aGlzLnllYXIoKSwgdGhpcy5tb250aCgpKTtcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdE1vbnRoc1Nob3J0UmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gbW9udGhzU2hvcnRSZWdleCAoaXNTdHJpY3QpIHtcbiAgICAgICAgaWYgKHRoaXMuX21vbnRoc1BhcnNlRXhhY3QpIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlTW9udGhzUGFyc2UuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1N0cmljdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1Nob3J0UmVnZXgnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1Nob3J0UmVnZXggPSBkZWZhdWx0TW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4ICYmIGlzU3RyaWN0ID9cbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4IDogdGhpcy5fbW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TW9udGhzUmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gbW9udGhzUmVnZXggKGlzU3RyaWN0KSB7XG4gICAgICAgIGlmICh0aGlzLl9tb250aHNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ19tb250aHNSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgY29tcHV0ZU1vbnRoc1BhcnNlLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNTdHJpY3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNSZWdleCA9IGRlZmF1bHRNb250aHNSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTdHJpY3RSZWdleCAmJiBpc1N0cmljdCA/XG4gICAgICAgICAgICAgICAgdGhpcy5fbW9udGhzU3RyaWN0UmVnZXggOiB0aGlzLl9tb250aHNSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbXB1dGVNb250aHNQYXJzZSAoKSB7XG4gICAgICAgIGZ1bmN0aW9uIGNtcExlblJldihhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi5sZW5ndGggLSBhLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzaG9ydFBpZWNlcyA9IFtdLCBsb25nUGllY2VzID0gW10sIG1peGVkUGllY2VzID0gW10sXG4gICAgICAgICAgICBpLCBtb207XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG4gICAgICAgICAgICAvLyBtYWtlIHRoZSByZWdleCBpZiB3ZSBkb24ndCBoYXZlIGl0IGFscmVhZHlcbiAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgaV0pO1xuICAgICAgICAgICAgc2hvcnRQaWVjZXMucHVzaCh0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpKTtcbiAgICAgICAgICAgIGxvbmdQaWVjZXMucHVzaCh0aGlzLm1vbnRocyhtb20sICcnKSk7XG4gICAgICAgICAgICBtaXhlZFBpZWNlcy5wdXNoKHRoaXMubW9udGhzKG1vbSwgJycpKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2godGhpcy5tb250aHNTaG9ydChtb20sICcnKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU29ydGluZyBtYWtlcyBzdXJlIGlmIG9uZSBtb250aCAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlciBpdFxuICAgICAgICAvLyB3aWxsIG1hdGNoIHRoZSBsb25nZXIgcGllY2UuXG4gICAgICAgIHNob3J0UGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgbG9uZ1BpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIG1peGVkUGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgIHNob3J0UGllY2VzW2ldID0gcmVnZXhFc2NhcGUoc2hvcnRQaWVjZXNbaV0pO1xuICAgICAgICAgICAgbG9uZ1BpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKGxvbmdQaWVjZXNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNDsgaSsrKSB7XG4gICAgICAgICAgICBtaXhlZFBpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKG1peGVkUGllY2VzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX21vbnRoc1JlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbWl4ZWRQaWVjZXMuam9pbignfCcpICsgJyknLCAnaScpO1xuICAgICAgICB0aGlzLl9tb250aHNTaG9ydFJlZ2V4ID0gdGhpcy5fbW9udGhzUmVnZXg7XG4gICAgICAgIHRoaXMuX21vbnRoc1N0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbG9uZ1BpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgICAgIHRoaXMuX21vbnRoc1Nob3J0U3RyaWN0UmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBzaG9ydFBpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlRGF0ZSAoeSwgbSwgZCwgaCwgTSwgcywgbXMpIHtcbiAgICAgICAgLy8gY2FuJ3QganVzdCBhcHBseSgpIHRvIGNyZWF0ZSBhIGRhdGU6XG4gICAgICAgIC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcS8xODEzNDhcbiAgICAgICAgdmFyIGRhdGU7XG4gICAgICAgIC8vIHRoZSBkYXRlIGNvbnN0cnVjdG9yIHJlbWFwcyB5ZWFycyAwLTk5IHRvIDE5MDAtMTk5OVxuICAgICAgICBpZiAoeSA8IDEwMCAmJiB5ID49IDApIHtcbiAgICAgICAgICAgIC8vIHByZXNlcnZlIGxlYXAgeWVhcnMgdXNpbmcgYSBmdWxsIDQwMCB5ZWFyIGN5Y2xlLCB0aGVuIHJlc2V0XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoeSArIDQwMCwgbSwgZCwgaCwgTSwgcywgbXMpO1xuICAgICAgICAgICAgaWYgKGlzRmluaXRlKGRhdGUuZ2V0RnVsbFllYXIoKSkpIHtcbiAgICAgICAgICAgICAgICBkYXRlLnNldEZ1bGxZZWFyKHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKHksIG0sIGQsIGgsIE0sIHMsIG1zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkYXRlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZVVUQ0RhdGUgKHkpIHtcbiAgICAgICAgdmFyIGRhdGU7XG4gICAgICAgIC8vIHRoZSBEYXRlLlVUQyBmdW5jdGlvbiByZW1hcHMgeWVhcnMgMC05OSB0byAxOTAwLTE5OTlcbiAgICAgICAgaWYgKHkgPCAxMDAgJiYgeSA+PSAwKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAvLyBwcmVzZXJ2ZSBsZWFwIHllYXJzIHVzaW5nIGEgZnVsbCA0MDAgeWVhciBjeWNsZSwgdGhlbiByZXNldFxuICAgICAgICAgICAgYXJnc1swXSA9IHkgKyA0MDA7XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoRGF0ZS5VVEMuYXBwbHkobnVsbCwgYXJncykpO1xuICAgICAgICAgICAgaWYgKGlzRmluaXRlKGRhdGUuZ2V0VVRDRnVsbFllYXIoKSkpIHtcbiAgICAgICAgICAgICAgICBkYXRlLnNldFVUQ0Z1bGxZZWFyKHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDLmFwcGx5KG51bGwsIGFyZ3VtZW50cykpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgLy8gc3RhcnQtb2YtZmlyc3Qtd2VlayAtIHN0YXJ0LW9mLXllYXJcbiAgICBmdW5jdGlvbiBmaXJzdFdlZWtPZmZzZXQoeWVhciwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIC8vIGZpcnN0LXdlZWsgZGF5IC0tIHdoaWNoIGphbnVhcnkgaXMgYWx3YXlzIGluIHRoZSBmaXJzdCB3ZWVrICg0IGZvciBpc28sIDEgZm9yIG90aGVyKVxuICAgICAgICAgICAgZndkID0gNyArIGRvdyAtIGRveSxcbiAgICAgICAgICAgIC8vIGZpcnN0LXdlZWsgZGF5IGxvY2FsIHdlZWtkYXkgLS0gd2hpY2ggbG9jYWwgd2Vla2RheSBpcyBmd2RcbiAgICAgICAgICAgIGZ3ZGx3ID0gKDcgKyBjcmVhdGVVVENEYXRlKHllYXIsIDAsIGZ3ZCkuZ2V0VVRDRGF5KCkgLSBkb3cpICUgNztcblxuICAgICAgICByZXR1cm4gLWZ3ZGx3ICsgZndkIC0gMTtcbiAgICB9XG5cbiAgICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlI0NhbGN1bGF0aW5nX2FfZGF0ZV9naXZlbl90aGVfeWVhci4yQ193ZWVrX251bWJlcl9hbmRfd2Vla2RheVxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrcyh5ZWFyLCB3ZWVrLCB3ZWVrZGF5LCBkb3csIGRveSkge1xuICAgICAgICB2YXIgbG9jYWxXZWVrZGF5ID0gKDcgKyB3ZWVrZGF5IC0gZG93KSAlIDcsXG4gICAgICAgICAgICB3ZWVrT2Zmc2V0ID0gZmlyc3RXZWVrT2Zmc2V0KHllYXIsIGRvdywgZG95KSxcbiAgICAgICAgICAgIGRheU9mWWVhciA9IDEgKyA3ICogKHdlZWsgLSAxKSArIGxvY2FsV2Vla2RheSArIHdlZWtPZmZzZXQsXG4gICAgICAgICAgICByZXNZZWFyLCByZXNEYXlPZlllYXI7XG5cbiAgICAgICAgaWYgKGRheU9mWWVhciA8PSAwKSB7XG4gICAgICAgICAgICByZXNZZWFyID0geWVhciAtIDE7XG4gICAgICAgICAgICByZXNEYXlPZlllYXIgPSBkYXlzSW5ZZWFyKHJlc1llYXIpICsgZGF5T2ZZZWFyO1xuICAgICAgICB9IGVsc2UgaWYgKGRheU9mWWVhciA+IGRheXNJblllYXIoeWVhcikpIHtcbiAgICAgICAgICAgIHJlc1llYXIgPSB5ZWFyICsgMTtcbiAgICAgICAgICAgIHJlc0RheU9mWWVhciA9IGRheU9mWWVhciAtIGRheXNJblllYXIoeWVhcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNZZWFyID0geWVhcjtcbiAgICAgICAgICAgIHJlc0RheU9mWWVhciA9IGRheU9mWWVhcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB5ZWFyOiByZXNZZWFyLFxuICAgICAgICAgICAgZGF5T2ZZZWFyOiByZXNEYXlPZlllYXJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3ZWVrT2ZZZWFyKG1vbSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIHdlZWtPZmZzZXQgPSBmaXJzdFdlZWtPZmZzZXQobW9tLnllYXIoKSwgZG93LCBkb3kpLFxuICAgICAgICAgICAgd2VlayA9IE1hdGguZmxvb3IoKG1vbS5kYXlPZlllYXIoKSAtIHdlZWtPZmZzZXQgLSAxKSAvIDcpICsgMSxcbiAgICAgICAgICAgIHJlc1dlZWssIHJlc1llYXI7XG5cbiAgICAgICAgaWYgKHdlZWsgPCAxKSB7XG4gICAgICAgICAgICByZXNZZWFyID0gbW9tLnllYXIoKSAtIDE7XG4gICAgICAgICAgICByZXNXZWVrID0gd2VlayArIHdlZWtzSW5ZZWFyKHJlc1llYXIsIGRvdywgZG95KTtcbiAgICAgICAgfSBlbHNlIGlmICh3ZWVrID4gd2Vla3NJblllYXIobW9tLnllYXIoKSwgZG93LCBkb3kpKSB7XG4gICAgICAgICAgICByZXNXZWVrID0gd2VlayAtIHdlZWtzSW5ZZWFyKG1vbS55ZWFyKCksIGRvdywgZG95KTtcbiAgICAgICAgICAgIHJlc1llYXIgPSBtb20ueWVhcigpICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc1llYXIgPSBtb20ueWVhcigpO1xuICAgICAgICAgICAgcmVzV2VlayA9IHdlZWs7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgd2VlazogcmVzV2VlayxcbiAgICAgICAgICAgIHllYXI6IHJlc1llYXJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3ZWVrc0luWWVhcih5ZWFyLCBkb3csIGRveSkge1xuICAgICAgICB2YXIgd2Vla09mZnNldCA9IGZpcnN0V2Vla09mZnNldCh5ZWFyLCBkb3csIGRveSksXG4gICAgICAgICAgICB3ZWVrT2Zmc2V0TmV4dCA9IGZpcnN0V2Vla09mZnNldCh5ZWFyICsgMSwgZG93LCBkb3kpO1xuICAgICAgICByZXR1cm4gKGRheXNJblllYXIoeWVhcikgLSB3ZWVrT2Zmc2V0ICsgd2Vla09mZnNldE5leHQpIC8gNztcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigndycsIFsnd3cnLCAyXSwgJ3dvJywgJ3dlZWsnKTtcbiAgICBhZGRGb3JtYXRUb2tlbignVycsIFsnV1cnLCAyXSwgJ1dvJywgJ2lzb1dlZWsnKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnd2VlaycsICd3Jyk7XG4gICAgYWRkVW5pdEFsaWFzKCdpc29XZWVrJywgJ1cnKTtcblxuICAgIC8vIFBSSU9SSVRJRVNcblxuICAgIGFkZFVuaXRQcmlvcml0eSgnd2VlaycsIDUpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2VlaycsIDUpO1xuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbigndycsICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ3d3JywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1cnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdXVycsIG1hdGNoMXRvMiwgbWF0Y2gyKTtcblxuICAgIGFkZFdlZWtQYXJzZVRva2VuKFsndycsICd3dycsICdXJywgJ1dXJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuLnN1YnN0cigwLCAxKV0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICAvLyBMT0NBTEVTXG5cbiAgICBmdW5jdGlvbiBsb2NhbGVXZWVrIChtb20pIHtcbiAgICAgICAgcmV0dXJuIHdlZWtPZlllYXIobW9tLCB0aGlzLl93ZWVrLmRvdywgdGhpcy5fd2Vlay5kb3kpLndlZWs7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb2NhbGVXZWVrID0ge1xuICAgICAgICBkb3cgOiAwLCAvLyBTdW5kYXkgaXMgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2Vlay5cbiAgICAgICAgZG95IDogNiAgLy8gVGhlIHdlZWsgdGhhdCBjb250YWlucyBKYW4gNnRoIGlzIHRoZSBmaXJzdCB3ZWVrIG9mIHRoZSB5ZWFyLlxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2NhbGVGaXJzdERheU9mV2VlayAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93ZWVrLmRvdztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsb2NhbGVGaXJzdERheU9mWWVhciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93ZWVrLmRveTtcbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBnZXRTZXRXZWVrIChpbnB1dCkge1xuICAgICAgICB2YXIgd2VlayA9IHRoaXMubG9jYWxlRGF0YSgpLndlZWsodGhpcyk7XG4gICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8gd2VlayA6IHRoaXMuYWRkKChpbnB1dCAtIHdlZWspICogNywgJ2QnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRJU09XZWVrIChpbnB1dCkge1xuICAgICAgICB2YXIgd2VlayA9IHdlZWtPZlllYXIodGhpcywgMSwgNCkud2VlaztcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrIDogdGhpcy5hZGQoKGlucHV0IC0gd2VlaykgKiA3LCAnZCcpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdkJywgMCwgJ2RvJywgJ2RheScpO1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ2RkJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkud2Vla2RheXNNaW4odGhpcywgZm9ybWF0KTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdkZGQnLCAwLCAwLCBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS53ZWVrZGF5c1Nob3J0KHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignZGRkZCcsIDAsIDAsIGZ1bmN0aW9uIChmb3JtYXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLndlZWtkYXlzKHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignZScsIDAsIDAsICd3ZWVrZGF5Jyk7XG4gICAgYWRkRm9ybWF0VG9rZW4oJ0UnLCAwLCAwLCAnaXNvV2Vla2RheScpO1xuXG4gICAgLy8gQUxJQVNFU1xuXG4gICAgYWRkVW5pdEFsaWFzKCdkYXknLCAnZCcpO1xuICAgIGFkZFVuaXRBbGlhcygnd2Vla2RheScsICdlJyk7XG4gICAgYWRkVW5pdEFsaWFzKCdpc29XZWVrZGF5JywgJ0UnKTtcblxuICAgIC8vIFBSSU9SSVRZXG4gICAgYWRkVW5pdFByaW9yaXR5KCdkYXknLCAxMSk7XG4gICAgYWRkVW5pdFByaW9yaXR5KCd3ZWVrZGF5JywgMTEpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2Vla2RheScsIDExKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ2QnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2UnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0UnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkJywgICBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLndlZWtkYXlzTWluUmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkZCcsICAgZnVuY3Rpb24gKGlzU3RyaWN0LCBsb2NhbGUpIHtcbiAgICAgICAgcmV0dXJuIGxvY2FsZS53ZWVrZGF5c1Nob3J0UmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkZGQnLCAgIGZ1bmN0aW9uIChpc1N0cmljdCwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUud2Vla2RheXNSZWdleChpc1N0cmljdCk7XG4gICAgfSk7XG5cbiAgICBhZGRXZWVrUGFyc2VUb2tlbihbJ2RkJywgJ2RkZCcsICdkZGRkJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB2YXIgd2Vla2RheSA9IGNvbmZpZy5fbG9jYWxlLndlZWtkYXlzUGFyc2UoaW5wdXQsIHRva2VuLCBjb25maWcuX3N0cmljdCk7XG4gICAgICAgIC8vIGlmIHdlIGRpZG4ndCBnZXQgYSB3ZWVrZGF5IG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZFxuICAgICAgICBpZiAod2Vla2RheSAhPSBudWxsKSB7XG4gICAgICAgICAgICB3ZWVrLmQgPSB3ZWVrZGF5O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuaW52YWxpZFdlZWtkYXkgPSBpbnB1dDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgYWRkV2Vla1BhcnNlVG9rZW4oWydkJywgJ2UnLCAnRSddLCBmdW5jdGlvbiAoaW5wdXQsIHdlZWssIGNvbmZpZywgdG9rZW4pIHtcbiAgICAgICAgd2Vla1t0b2tlbl0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICBmdW5jdGlvbiBwYXJzZVdlZWtkYXkoaW5wdXQsIGxvY2FsZSkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc05hTihpbnB1dCkpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUludChpbnB1dCwgMTApO1xuICAgICAgICB9XG5cbiAgICAgICAgaW5wdXQgPSBsb2NhbGUud2Vla2RheXNQYXJzZShpbnB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZUlzb1dlZWtkYXkoaW5wdXQsIGxvY2FsZSkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS53ZWVrZGF5c1BhcnNlKGlucHV0KSAlIDcgfHwgNztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNOYU4oaW5wdXQpID8gbnVsbCA6IGlucHV0O1xuICAgIH1cblxuICAgIC8vIExPQ0FMRVNcbiAgICBmdW5jdGlvbiBzaGlmdFdlZWtkYXlzICh3cywgbikge1xuICAgICAgICByZXR1cm4gd3Muc2xpY2UobiwgNykuY29uY2F0KHdzLnNsaWNlKDAsIG4pKTtcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdExvY2FsZVdlZWtkYXlzID0gJ1N1bmRheV9Nb25kYXlfVHVlc2RheV9XZWRuZXNkYXlfVGh1cnNkYXlfRnJpZGF5X1NhdHVyZGF5Jy5zcGxpdCgnXycpO1xuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzIChtLCBmb3JtYXQpIHtcbiAgICAgICAgdmFyIHdlZWtkYXlzID0gaXNBcnJheSh0aGlzLl93ZWVrZGF5cykgPyB0aGlzLl93ZWVrZGF5cyA6XG4gICAgICAgICAgICB0aGlzLl93ZWVrZGF5c1sobSAmJiBtICE9PSB0cnVlICYmIHRoaXMuX3dlZWtkYXlzLmlzRm9ybWF0LnRlc3QoZm9ybWF0KSkgPyAnZm9ybWF0JyA6ICdzdGFuZGFsb25lJ107XG4gICAgICAgIHJldHVybiAobSA9PT0gdHJ1ZSkgPyBzaGlmdFdlZWtkYXlzKHdlZWtkYXlzLCB0aGlzLl93ZWVrLmRvdylcbiAgICAgICAgICAgIDogKG0pID8gd2Vla2RheXNbbS5kYXkoKV0gOiB3ZWVrZGF5cztcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdExvY2FsZVdlZWtkYXlzU2hvcnQgPSAnU3VuX01vbl9UdWVfV2VkX1RodV9GcmlfU2F0Jy5zcGxpdCgnXycpO1xuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzU2hvcnQgKG0pIHtcbiAgICAgICAgcmV0dXJuIChtID09PSB0cnVlKSA/IHNoaWZ0V2Vla2RheXModGhpcy5fd2Vla2RheXNTaG9ydCwgdGhpcy5fd2Vlay5kb3cpXG4gICAgICAgICAgICA6IChtKSA/IHRoaXMuX3dlZWtkYXlzU2hvcnRbbS5kYXkoKV0gOiB0aGlzLl93ZWVrZGF5c1Nob3J0O1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TG9jYWxlV2Vla2RheXNNaW4gPSAnU3VfTW9fVHVfV2VfVGhfRnJfU2EnLnNwbGl0KCdfJyk7XG4gICAgZnVuY3Rpb24gbG9jYWxlV2Vla2RheXNNaW4gKG0pIHtcbiAgICAgICAgcmV0dXJuIChtID09PSB0cnVlKSA/IHNoaWZ0V2Vla2RheXModGhpcy5fd2Vla2RheXNNaW4sIHRoaXMuX3dlZWsuZG93KVxuICAgICAgICAgICAgOiAobSkgPyB0aGlzLl93ZWVrZGF5c01pblttLmRheSgpXSA6IHRoaXMuX3dlZWtkYXlzTWluO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZVN0cmljdFBhcnNlJDEod2Vla2RheU5hbWUsIGZvcm1hdCwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBpLCBpaSwgbW9tLCBsbGMgPSB3ZWVrZGF5TmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fbWluV2Vla2RheXNQYXJzZSA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNzsgKytpKSB7XG4gICAgICAgICAgICAgICAgbW9tID0gY3JlYXRlVVRDKFsyMDAwLCAxXSkuZGF5KGkpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21pbldlZWtkYXlzUGFyc2VbaV0gPSB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRXZWVrZGF5c1BhcnNlW2ldID0gdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZVtpXSA9IHRoaXMud2Vla2RheXMobW9tLCAnJykudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdkZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3dlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9taW5XZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpaSAhPT0gLTEgPyBpaSA6IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoZm9ybWF0ID09PSAnZGRkZCcpIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl93ZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9zaG9ydFdlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgaWYgKGlpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX21pbldlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fd2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fbWluV2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9taW5XZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl93ZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9zaG9ydFdlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzUGFyc2UgKHdlZWtkYXlOYW1lLCBmb3JtYXQsIHN0cmljdCkge1xuICAgICAgICB2YXIgaSwgbW9tLCByZWdleDtcblxuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlU3RyaWN0UGFyc2UkMS5jYWxsKHRoaXMsIHdlZWtkYXlOYW1lLCBmb3JtYXQsIHN0cmljdCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX21pbldlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fZnVsbFdlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuXG4gICAgICAgICAgICBtb20gPSBjcmVhdGVVVEMoWzIwMDAsIDFdKS5kYXkoaSk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmICF0aGlzLl9mdWxsV2Vla2RheXNQYXJzZVtpXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2Z1bGxXZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnXFxcXC4/JykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRXZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzU2hvcnQobW9tLCAnJykucmVwbGFjZSgnLicsICdcXFxcLj8nKSArICckJywgJ2knKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9taW5XZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnXFxcXC4/JykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICByZWdleCA9ICdeJyArIHRoaXMud2Vla2RheXMobW9tLCAnJykgKyAnfF4nICsgdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpICsgJ3xeJyArIHRoaXMud2Vla2RheXNNaW4obW9tLCAnJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZVtpXSA9IG5ldyBSZWdFeHAocmVnZXgucmVwbGFjZSgnLicsICcnKSwgJ2knKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHRlc3QgdGhlIHJlZ2V4XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmIGZvcm1hdCA9PT0gJ2RkZGQnICYmIHRoaXMuX2Z1bGxXZWVrZGF5c1BhcnNlW2ldLnRlc3Qod2Vla2RheU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmljdCAmJiBmb3JtYXQgPT09ICdkZGQnICYmIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZVtpXS50ZXN0KHdlZWtkYXlOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnZGQnICYmIHRoaXMuX21pbldlZWtkYXlzUGFyc2VbaV0udGVzdCh3ZWVrZGF5TmFtZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXN0cmljdCAmJiB0aGlzLl93ZWVrZGF5c1BhcnNlW2ldLnRlc3Qod2Vla2RheU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBnZXRTZXREYXlPZldlZWsgKGlucHV0KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnB1dCAhPSBudWxsID8gdGhpcyA6IE5hTjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF5ID0gdGhpcy5faXNVVEMgPyB0aGlzLl9kLmdldFVUQ0RheSgpIDogdGhpcy5fZC5nZXREYXkoKTtcbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlucHV0ID0gcGFyc2VXZWVrZGF5KGlucHV0LCB0aGlzLmxvY2FsZURhdGEoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGQoaW5wdXQgLSBkYXksICdkJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZGF5O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2V0TG9jYWxlRGF5T2ZXZWVrIChpbnB1dCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgIT0gbnVsbCA/IHRoaXMgOiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHdlZWtkYXkgPSAodGhpcy5kYXkoKSArIDcgLSB0aGlzLmxvY2FsZURhdGEoKS5fd2Vlay5kb3cpICUgNztcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrZGF5IDogdGhpcy5hZGQoaW5wdXQgLSB3ZWVrZGF5LCAnZCcpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNldElTT0RheU9mV2VlayAoaW5wdXQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0ICE9IG51bGwgPyB0aGlzIDogTmFOO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYmVoYXZlcyB0aGUgc2FtZSBhcyBtb21lbnQjZGF5IGV4Y2VwdFxuICAgICAgICAvLyBhcyBhIGdldHRlciwgcmV0dXJucyA3IGluc3RlYWQgb2YgMCAoMS03IHJhbmdlIGluc3RlYWQgb2YgMC02KVxuICAgICAgICAvLyBhcyBhIHNldHRlciwgc3VuZGF5IHNob3VsZCBiZWxvbmcgdG8gdGhlIHByZXZpb3VzIHdlZWsuXG5cbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhciB3ZWVrZGF5ID0gcGFyc2VJc29XZWVrZGF5KGlucHV0LCB0aGlzLmxvY2FsZURhdGEoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kYXkodGhpcy5kYXkoKSAlIDcgPyB3ZWVrZGF5IDogd2Vla2RheSAtIDcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF5KCkgfHwgNztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0V2Vla2RheXNSZWdleCA9IG1hdGNoV29yZDtcbiAgICBmdW5jdGlvbiB3ZWVrZGF5c1JlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wKHRoaXMsICdfd2Vla2RheXNSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNSZWdleCA9IGRlZmF1bHRXZWVrZGF5c1JlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggOiB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRXZWVrZGF5c1Nob3J0UmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gd2Vla2RheXNTaG9ydFJlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU2hvcnRTdHJpY3RSZWdleDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX3dlZWtkYXlzU2hvcnRSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNTaG9ydFJlZ2V4ID0gZGVmYXVsdFdlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c1Nob3J0U3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzU2hvcnRTdHJpY3RSZWdleCA6IHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0V2Vla2RheXNNaW5SZWdleCA9IG1hdGNoV29yZDtcbiAgICBmdW5jdGlvbiB3ZWVrZGF5c01pblJlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wKHRoaXMsICdfd2Vla2RheXNNaW5SZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNNaW5SZWdleCA9IGRlZmF1bHRXZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXggOiB0aGlzLl93ZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjb21wdXRlV2Vla2RheXNQYXJzZSAoKSB7XG4gICAgICAgIGZ1bmN0aW9uIGNtcExlblJldihhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi5sZW5ndGggLSBhLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtaW5QaWVjZXMgPSBbXSwgc2hvcnRQaWVjZXMgPSBbXSwgbG9uZ1BpZWNlcyA9IFtdLCBtaXhlZFBpZWNlcyA9IFtdLFxuICAgICAgICAgICAgaSwgbW9tLCBtaW5wLCBzaG9ydHAsIGxvbmdwO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNzsgaSsrKSB7XG4gICAgICAgICAgICAvLyBtYWtlIHRoZSByZWdleCBpZiB3ZSBkb24ndCBoYXZlIGl0IGFscmVhZHlcbiAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgMV0pLmRheShpKTtcbiAgICAgICAgICAgIG1pbnAgPSB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpO1xuICAgICAgICAgICAgc2hvcnRwID0gdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpO1xuICAgICAgICAgICAgbG9uZ3AgPSB0aGlzLndlZWtkYXlzKG1vbSwgJycpO1xuICAgICAgICAgICAgbWluUGllY2VzLnB1c2gobWlucCk7XG4gICAgICAgICAgICBzaG9ydFBpZWNlcy5wdXNoKHNob3J0cCk7XG4gICAgICAgICAgICBsb25nUGllY2VzLnB1c2gobG9uZ3ApO1xuICAgICAgICAgICAgbWl4ZWRQaWVjZXMucHVzaChtaW5wKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2goc2hvcnRwKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2gobG9uZ3ApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNvcnRpbmcgbWFrZXMgc3VyZSBpZiBvbmUgd2Vla2RheSAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlciBpdFxuICAgICAgICAvLyB3aWxsIG1hdGNoIHRoZSBsb25nZXIgcGllY2UuXG4gICAgICAgIG1pblBpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIHNob3J0UGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgbG9uZ1BpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIG1peGVkUGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDc7IGkrKykge1xuICAgICAgICAgICAgc2hvcnRQaWVjZXNbaV0gPSByZWdleEVzY2FwZShzaG9ydFBpZWNlc1tpXSk7XG4gICAgICAgICAgICBsb25nUGllY2VzW2ldID0gcmVnZXhFc2NhcGUobG9uZ1BpZWNlc1tpXSk7XG4gICAgICAgICAgICBtaXhlZFBpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKG1peGVkUGllY2VzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3dlZWtkYXlzUmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBtaXhlZFBpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgICAgIHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleCA9IHRoaXMuX3dlZWtkYXlzUmVnZXg7XG4gICAgICAgIHRoaXMuX3dlZWtkYXlzTWluUmVnZXggPSB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuXG4gICAgICAgIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBsb25nUGllY2VzLmpvaW4oJ3wnKSArICcpJywgJ2knKTtcbiAgICAgICAgdGhpcy5fd2Vla2RheXNTaG9ydFN0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgc2hvcnRQaWVjZXMuam9pbignfCcpICsgJyknLCAnaScpO1xuICAgICAgICB0aGlzLl93ZWVrZGF5c01pblN0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbWluUGllY2VzLmpvaW4oJ3wnKSArICcpJywgJ2knKTtcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBmdW5jdGlvbiBoRm9ybWF0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ob3VycygpICUgMTIgfHwgMTI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24ga0Zvcm1hdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaG91cnMoKSB8fCAyNDtcbiAgICB9XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSCcsIFsnSEgnLCAyXSwgMCwgJ2hvdXInKTtcbiAgICBhZGRGb3JtYXRUb2tlbignaCcsIFsnaGgnLCAyXSwgMCwgaEZvcm1hdCk7XG4gICAgYWRkRm9ybWF0VG9rZW4oJ2snLCBbJ2trJywgMl0sIDAsIGtGb3JtYXQpO1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ2htbScsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnICsgaEZvcm1hdC5hcHBseSh0aGlzKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdobW1zcycsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnICsgaEZvcm1hdC5hcHBseSh0aGlzKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKSArXG4gICAgICAgICAgICB6ZXJvRmlsbCh0aGlzLnNlY29uZHMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSG1tJywgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gJycgKyB0aGlzLmhvdXJzKCkgKyB6ZXJvRmlsbCh0aGlzLm1pbnV0ZXMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSG1tc3MnLCAwLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAnJyArIHRoaXMuaG91cnMoKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKSArXG4gICAgICAgICAgICB6ZXJvRmlsbCh0aGlzLnNlY29uZHMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBtZXJpZGllbSAodG9rZW4sIGxvd2VyY2FzZSkge1xuICAgICAgICBhZGRGb3JtYXRUb2tlbih0b2tlbiwgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLm1lcmlkaWVtKHRoaXMuaG91cnMoKSwgdGhpcy5taW51dGVzKCksIGxvd2VyY2FzZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG1lcmlkaWVtKCdhJywgdHJ1ZSk7XG4gICAgbWVyaWRpZW0oJ0EnLCBmYWxzZSk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ2hvdXInLCAnaCcpO1xuXG4gICAgLy8gUFJJT1JJVFlcbiAgICBhZGRVbml0UHJpb3JpdHkoJ2hvdXInLCAxMyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBmdW5jdGlvbiBtYXRjaE1lcmlkaWVtIChpc1N0cmljdCwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUuX21lcmlkaWVtUGFyc2U7XG4gICAgfVxuXG4gICAgYWRkUmVnZXhUb2tlbignYScsICBtYXRjaE1lcmlkaWVtKTtcbiAgICBhZGRSZWdleFRva2VuKCdBJywgIG1hdGNoTWVyaWRpZW0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0gnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdoJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignaycsICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0hIJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2hoJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2trJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuXG4gICAgYWRkUmVnZXhUb2tlbignaG1tJywgbWF0Y2gzdG80KTtcbiAgICBhZGRSZWdleFRva2VuKCdobW1zcycsIG1hdGNoNXRvNik7XG4gICAgYWRkUmVnZXhUb2tlbignSG1tJywgbWF0Y2gzdG80KTtcbiAgICBhZGRSZWdleFRva2VuKCdIbW1zcycsIG1hdGNoNXRvNik7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnSCcsICdISCddLCBIT1VSKTtcbiAgICBhZGRQYXJzZVRva2VuKFsnaycsICdrayddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIGtJbnB1dCA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgYXJyYXlbSE9VUl0gPSBrSW5wdXQgPT09IDI0ID8gMCA6IGtJbnB1dDtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKFsnYScsICdBJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2lzUG0gPSBjb25maWcuX2xvY2FsZS5pc1BNKGlucHV0KTtcbiAgICAgICAgY29uZmlnLl9tZXJpZGllbSA9IGlucHV0O1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oWydoJywgJ2hoJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuYmlnSG91ciA9IHRydWU7XG4gICAgfSk7XG4gICAgYWRkUGFyc2VUb2tlbignaG1tJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIHZhciBwb3MgPSBpbnB1dC5sZW5ndGggLSAyO1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0LnN1YnN0cigwLCBwb3MpKTtcbiAgICAgICAgYXJyYXlbTUlOVVRFXSA9IHRvSW50KGlucHV0LnN1YnN0cihwb3MpKTtcbiAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuYmlnSG91ciA9IHRydWU7XG4gICAgfSk7XG4gICAgYWRkUGFyc2VUb2tlbignaG1tc3MnLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIHBvczEgPSBpbnB1dC5sZW5ndGggLSA0O1xuICAgICAgICB2YXIgcG9zMiA9IGlucHV0Lmxlbmd0aCAtIDI7XG4gICAgICAgIGFycmF5W0hPVVJdID0gdG9JbnQoaW5wdXQuc3Vic3RyKDAsIHBvczEpKTtcbiAgICAgICAgYXJyYXlbTUlOVVRFXSA9IHRvSW50KGlucHV0LnN1YnN0cihwb3MxLCAyKSk7XG4gICAgICAgIGFycmF5W1NFQ09ORF0gPSB0b0ludChpbnB1dC5zdWJzdHIocG9zMikpO1xuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5iaWdIb3VyID0gdHJ1ZTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCdIbW0nLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIHBvcyA9IGlucHV0Lmxlbmd0aCAtIDI7XG4gICAgICAgIGFycmF5W0hPVVJdID0gdG9JbnQoaW5wdXQuc3Vic3RyKDAsIHBvcykpO1xuICAgICAgICBhcnJheVtNSU5VVEVdID0gdG9JbnQoaW5wdXQuc3Vic3RyKHBvcykpO1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oJ0htbXNzJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIHZhciBwb3MxID0gaW5wdXQubGVuZ3RoIC0gNDtcbiAgICAgICAgdmFyIHBvczIgPSBpbnB1dC5sZW5ndGggLSAyO1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0LnN1YnN0cigwLCBwb3MxKSk7XG4gICAgICAgIGFycmF5W01JTlVURV0gPSB0b0ludChpbnB1dC5zdWJzdHIocG9zMSwgMikpO1xuICAgICAgICBhcnJheVtTRUNPTkRdID0gdG9JbnQoaW5wdXQuc3Vic3RyKHBvczIpKTtcbiAgICB9KTtcblxuICAgIC8vIExPQ0FMRVNcblxuICAgIGZ1bmN0aW9uIGxvY2FsZUlzUE0gKGlucHV0KSB7XG4gICAgICAgIC8vIElFOCBRdWlya3MgTW9kZSAmIElFNyBTdGFuZGFyZHMgTW9kZSBkbyBub3QgYWxsb3cgYWNjZXNzaW5nIHN0cmluZ3MgbGlrZSBhcnJheXNcbiAgICAgICAgLy8gVXNpbmcgY2hhckF0IHNob3VsZCBiZSBtb3JlIGNvbXBhdGlibGUuXG4gICAgICAgIHJldHVybiAoKGlucHV0ICsgJycpLnRvTG93ZXJDYXNlKCkuY2hhckF0KDApID09PSAncCcpO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TG9jYWxlTWVyaWRpZW1QYXJzZSA9IC9bYXBdXFwuP20/XFwuPy9pO1xuICAgIGZ1bmN0aW9uIGxvY2FsZU1lcmlkaWVtIChob3VycywgbWludXRlcywgaXNMb3dlcikge1xuICAgICAgICBpZiAoaG91cnMgPiAxMSkge1xuICAgICAgICAgICAgcmV0dXJuIGlzTG93ZXIgPyAncG0nIDogJ1BNJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBpc0xvd2VyID8gJ2FtJyA6ICdBTSc7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8vIE1PTUVOVFNcblxuICAgIC8vIFNldHRpbmcgdGhlIGhvdXIgc2hvdWxkIGtlZXAgdGhlIHRpbWUsIGJlY2F1c2UgdGhlIHVzZXIgZXhwbGljaXRseVxuICAgIC8vIHNwZWNpZmllZCB3aGljaCBob3VyIHRoZXkgd2FudC4gU28gdHJ5aW5nIHRvIG1haW50YWluIHRoZSBzYW1lIGhvdXIgKGluXG4gICAgLy8gYSBuZXcgdGltZXpvbmUpIG1ha2VzIHNlbnNlLiBBZGRpbmcvc3VidHJhY3RpbmcgaG91cnMgZG9lcyBub3QgZm9sbG93XG4gICAgLy8gdGhpcyBydWxlLlxuICAgIHZhciBnZXRTZXRIb3VyID0gbWFrZUdldFNldCgnSG91cnMnLCB0cnVlKTtcblxuICAgIHZhciBiYXNlQ29uZmlnID0ge1xuICAgICAgICBjYWxlbmRhcjogZGVmYXVsdENhbGVuZGFyLFxuICAgICAgICBsb25nRGF0ZUZvcm1hdDogZGVmYXVsdExvbmdEYXRlRm9ybWF0LFxuICAgICAgICBpbnZhbGlkRGF0ZTogZGVmYXVsdEludmFsaWREYXRlLFxuICAgICAgICBvcmRpbmFsOiBkZWZhdWx0T3JkaW5hbCxcbiAgICAgICAgZGF5T2ZNb250aE9yZGluYWxQYXJzZTogZGVmYXVsdERheU9mTW9udGhPcmRpbmFsUGFyc2UsXG4gICAgICAgIHJlbGF0aXZlVGltZTogZGVmYXVsdFJlbGF0aXZlVGltZSxcblxuICAgICAgICBtb250aHM6IGRlZmF1bHRMb2NhbGVNb250aHMsXG4gICAgICAgIG1vbnRoc1Nob3J0OiBkZWZhdWx0TG9jYWxlTW9udGhzU2hvcnQsXG5cbiAgICAgICAgd2VlazogZGVmYXVsdExvY2FsZVdlZWssXG5cbiAgICAgICAgd2Vla2RheXM6IGRlZmF1bHRMb2NhbGVXZWVrZGF5cyxcbiAgICAgICAgd2Vla2RheXNNaW46IGRlZmF1bHRMb2NhbGVXZWVrZGF5c01pbixcbiAgICAgICAgd2Vla2RheXNTaG9ydDogZGVmYXVsdExvY2FsZVdlZWtkYXlzU2hvcnQsXG5cbiAgICAgICAgbWVyaWRpZW1QYXJzZTogZGVmYXVsdExvY2FsZU1lcmlkaWVtUGFyc2VcbiAgICB9O1xuXG4gICAgLy8gaW50ZXJuYWwgc3RvcmFnZSBmb3IgbG9jYWxlIGNvbmZpZyBmaWxlc1xuICAgIHZhciBsb2NhbGVzID0ge307XG4gICAgdmFyIGxvY2FsZUZhbWlsaWVzID0ge307XG4gICAgdmFyIGdsb2JhbExvY2FsZTtcblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZUxvY2FsZShrZXkpIHtcbiAgICAgICAgcmV0dXJuIGtleSA/IGtleS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoJ18nLCAnLScpIDoga2V5O1xuICAgIH1cblxuICAgIC8vIHBpY2sgdGhlIGxvY2FsZSBmcm9tIHRoZSBhcnJheVxuICAgIC8vIHRyeSBbJ2VuLWF1JywgJ2VuLWdiJ10gYXMgJ2VuLWF1JywgJ2VuLWdiJywgJ2VuJywgYXMgaW4gbW92ZSB0aHJvdWdoIHRoZSBsaXN0IHRyeWluZyBlYWNoXG4gICAgLy8gc3Vic3RyaW5nIGZyb20gbW9zdCBzcGVjaWZpYyB0byBsZWFzdCwgYnV0IG1vdmUgdG8gdGhlIG5leHQgYXJyYXkgaXRlbSBpZiBpdCdzIGEgbW9yZSBzcGVjaWZpYyB2YXJpYW50IHRoYW4gdGhlIGN1cnJlbnQgcm9vdFxuICAgIGZ1bmN0aW9uIGNob29zZUxvY2FsZShuYW1lcykge1xuICAgICAgICB2YXIgaSA9IDAsIGosIG5leHQsIGxvY2FsZSwgc3BsaXQ7XG5cbiAgICAgICAgd2hpbGUgKGkgPCBuYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHNwbGl0ID0gbm9ybWFsaXplTG9jYWxlKG5hbWVzW2ldKS5zcGxpdCgnLScpO1xuICAgICAgICAgICAgaiA9IHNwbGl0Lmxlbmd0aDtcbiAgICAgICAgICAgIG5leHQgPSBub3JtYWxpemVMb2NhbGUobmFtZXNbaSArIDFdKTtcbiAgICAgICAgICAgIG5leHQgPSBuZXh0ID8gbmV4dC5zcGxpdCgnLScpIDogbnVsbDtcbiAgICAgICAgICAgIHdoaWxlIChqID4gMCkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGxvYWRMb2NhbGUoc3BsaXQuc2xpY2UoMCwgaikuam9pbignLScpKTtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChuZXh0ICYmIG5leHQubGVuZ3RoID49IGogJiYgY29tcGFyZUFycmF5cyhzcGxpdCwgbmV4dCwgdHJ1ZSkgPj0gaiAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgLy90aGUgbmV4dCBhcnJheSBpdGVtIGlzIGJldHRlciB0aGFuIGEgc2hhbGxvd2VyIHN1YnN0cmluZyBvZiB0aGlzIG9uZVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgai0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9hZExvY2FsZShuYW1lKSB7XG4gICAgICAgIHZhciBvbGRMb2NhbGUgPSBudWxsO1xuICAgICAgICAvLyBUT0RPOiBGaW5kIGEgYmV0dGVyIHdheSB0byByZWdpc3RlciBhbmQgbG9hZCBhbGwgdGhlIGxvY2FsZXMgaW4gTm9kZVxuICAgICAgICBpZiAoIWxvY2FsZXNbbmFtZV0gJiYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgICAgICAgICAgIG1vZHVsZSAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBvbGRMb2NhbGUgPSBnbG9iYWxMb2NhbGUuX2FiYnI7XG4gICAgICAgICAgICAgICAgdmFyIGFsaWFzZWRSZXF1aXJlID0gcmVxdWlyZTtcbiAgICAgICAgICAgICAgICBhbGlhc2VkUmVxdWlyZSgnLi9sb2NhbGUvJyArIG5hbWUpO1xuICAgICAgICAgICAgICAgIGdldFNldEdsb2JhbExvY2FsZShvbGRMb2NhbGUpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbG9jYWxlc1tuYW1lXTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgbG9hZCBsb2NhbGUgYW5kIHRoZW4gc2V0IHRoZSBnbG9iYWwgbG9jYWxlLiAgSWZcbiAgICAvLyBubyBhcmd1bWVudHMgYXJlIHBhc3NlZCBpbiwgaXQgd2lsbCBzaW1wbHkgcmV0dXJuIHRoZSBjdXJyZW50IGdsb2JhbFxuICAgIC8vIGxvY2FsZSBrZXkuXG4gICAgZnVuY3Rpb24gZ2V0U2V0R2xvYmFsTG9jYWxlIChrZXksIHZhbHVlcykge1xuICAgICAgICB2YXIgZGF0YTtcbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlcykpIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZ2V0TG9jYWxlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZGVmaW5lTG9jYWxlKGtleSwgdmFsdWVzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAvLyBtb21lbnQuZHVyYXRpb24uX2xvY2FsZSA9IG1vbWVudC5fbG9jYWxlID0gZGF0YTtcbiAgICAgICAgICAgICAgICBnbG9iYWxMb2NhbGUgPSBkYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKCh0eXBlb2YgY29uc29sZSAhPT0gICd1bmRlZmluZWQnKSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICAgICAgICAgICAgLy93YXJuIHVzZXIgaWYgYXJndW1lbnRzIGFyZSBwYXNzZWQgYnV0IHRoZSBsb2NhbGUgY291bGQgbm90IGJlIHNldFxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0xvY2FsZSAnICsga2V5ICsgICcgbm90IGZvdW5kLiBEaWQgeW91IGZvcmdldCB0byBsb2FkIGl0PycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGUuX2FiYnI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmaW5lTG9jYWxlIChuYW1lLCBjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxvY2FsZSwgcGFyZW50Q29uZmlnID0gYmFzZUNvbmZpZztcbiAgICAgICAgICAgIGNvbmZpZy5hYmJyID0gbmFtZTtcbiAgICAgICAgICAgIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkZXByZWNhdGVTaW1wbGUoJ2RlZmluZUxvY2FsZU92ZXJyaWRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICd1c2UgbW9tZW50LnVwZGF0ZUxvY2FsZShsb2NhbGVOYW1lLCBjb25maWcpIHRvIGNoYW5nZSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdhbiBleGlzdGluZyBsb2NhbGUuIG1vbWVudC5kZWZpbmVMb2NhbGUobG9jYWxlTmFtZSwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnY29uZmlnKSBzaG91bGQgb25seSBiZSB1c2VkIGZvciBjcmVhdGluZyBhIG5ldyBsb2NhbGUgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnU2VlIGh0dHA6Ly9tb21lbnRqcy5jb20vZ3VpZGVzLyMvd2FybmluZ3MvZGVmaW5lLWxvY2FsZS8gZm9yIG1vcmUgaW5mby4nKTtcbiAgICAgICAgICAgICAgICBwYXJlbnRDb25maWcgPSBsb2NhbGVzW25hbWVdLl9jb25maWc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNvbmZpZy5wYXJlbnRMb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChsb2NhbGVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29uZmlnID0gbG9jYWxlc1tjb25maWcucGFyZW50TG9jYWxlXS5fY29uZmlnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvY2FsZSA9IGxvYWRMb2NhbGUoY29uZmlnLnBhcmVudExvY2FsZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29uZmlnID0gbG9jYWxlLl9jb25maWc7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWxvY2FsZUZhbWlsaWVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlRmFtaWxpZXNbY29uZmlnLnBhcmVudExvY2FsZV0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsZUZhbWlsaWVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnOiBjb25maWdcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhbGVzW25hbWVdID0gbmV3IExvY2FsZShtZXJnZUNvbmZpZ3MocGFyZW50Q29uZmlnLCBjb25maWcpKTtcblxuICAgICAgICAgICAgaWYgKGxvY2FsZUZhbWlsaWVzW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgbG9jYWxlRmFtaWxpZXNbbmFtZV0uZm9yRWFjaChmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgICAgICAgICBkZWZpbmVMb2NhbGUoeC5uYW1lLCB4LmNvbmZpZyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgZm9yIG5vdzogYWxzbyBzZXQgdGhlIGxvY2FsZVxuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHdlIHNldCB0aGUgbG9jYWxlIEFGVEVSIGFsbCBjaGlsZCBsb2NhbGVzIGhhdmUgYmVlblxuICAgICAgICAgICAgLy8gY3JlYXRlZCwgc28gd2Ugd29uJ3QgZW5kIHVwIHdpdGggdGhlIGNoaWxkIGxvY2FsZSBzZXQuXG4gICAgICAgICAgICBnZXRTZXRHbG9iYWxMb2NhbGUobmFtZSk7XG5cblxuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZXNbbmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyB1c2VmdWwgZm9yIHRlc3RpbmdcbiAgICAgICAgICAgIGRlbGV0ZSBsb2NhbGVzW25hbWVdO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1cGRhdGVMb2NhbGUobmFtZSwgY29uZmlnKSB7XG4gICAgICAgIGlmIChjb25maWcgIT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxvY2FsZSwgdG1wTG9jYWxlLCBwYXJlbnRDb25maWcgPSBiYXNlQ29uZmlnO1xuICAgICAgICAgICAgLy8gTUVSR0VcbiAgICAgICAgICAgIHRtcExvY2FsZSA9IGxvYWRMb2NhbGUobmFtZSk7XG4gICAgICAgICAgICBpZiAodG1wTG9jYWxlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnRDb25maWcgPSB0bXBMb2NhbGUuX2NvbmZpZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbmZpZyA9IG1lcmdlQ29uZmlncyhwYXJlbnRDb25maWcsIGNvbmZpZyk7XG4gICAgICAgICAgICBsb2NhbGUgPSBuZXcgTG9jYWxlKGNvbmZpZyk7XG4gICAgICAgICAgICBsb2NhbGUucGFyZW50TG9jYWxlID0gbG9jYWxlc1tuYW1lXTtcbiAgICAgICAgICAgIGxvY2FsZXNbbmFtZV0gPSBsb2NhbGU7XG5cbiAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgZm9yIG5vdzogYWxzbyBzZXQgdGhlIGxvY2FsZVxuICAgICAgICAgICAgZ2V0U2V0R2xvYmFsTG9jYWxlKG5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gcGFzcyBudWxsIGZvciBjb25maWcgdG8gdW51cGRhdGUsIHVzZWZ1bCBmb3IgdGVzdHNcbiAgICAgICAgICAgIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxlc1tuYW1lXS5wYXJlbnRMb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBsb2NhbGVzW25hbWVdID0gbG9jYWxlc1tuYW1lXS5wYXJlbnRMb2NhbGU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGxvY2FsZXNbbmFtZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsb2NhbGVzW25hbWVdO1xuICAgIH1cblxuICAgIC8vIHJldHVybnMgbG9jYWxlIGRhdGFcbiAgICBmdW5jdGlvbiBnZXRMb2NhbGUgKGtleSkge1xuICAgICAgICB2YXIgbG9jYWxlO1xuXG4gICAgICAgIGlmIChrZXkgJiYga2V5Ll9sb2NhbGUgJiYga2V5Ll9sb2NhbGUuX2FiYnIpIHtcbiAgICAgICAgICAgIGtleSA9IGtleS5fbG9jYWxlLl9hYmJyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFrZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzQXJyYXkoa2V5KSkge1xuICAgICAgICAgICAgLy9zaG9ydC1jaXJjdWl0IGV2ZXJ5dGhpbmcgZWxzZVxuICAgICAgICAgICAgbG9jYWxlID0gbG9hZExvY2FsZShrZXkpO1xuICAgICAgICAgICAgaWYgKGxvY2FsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBrZXkgPSBba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjaG9vc2VMb2NhbGUoa2V5KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0TG9jYWxlcygpIHtcbiAgICAgICAgcmV0dXJuIGtleXMobG9jYWxlcyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2tPdmVyZmxvdyAobSkge1xuICAgICAgICB2YXIgb3ZlcmZsb3c7XG4gICAgICAgIHZhciBhID0gbS5fYTtcblxuICAgICAgICBpZiAoYSAmJiBnZXRQYXJzaW5nRmxhZ3MobSkub3ZlcmZsb3cgPT09IC0yKSB7XG4gICAgICAgICAgICBvdmVyZmxvdyA9XG4gICAgICAgICAgICAgICAgYVtNT05USF0gICAgICAgPCAwIHx8IGFbTU9OVEhdICAgICAgID4gMTEgID8gTU9OVEggOlxuICAgICAgICAgICAgICAgIGFbREFURV0gICAgICAgIDwgMSB8fCBhW0RBVEVdICAgICAgICA+IGRheXNJbk1vbnRoKGFbWUVBUl0sIGFbTU9OVEhdKSA/IERBVEUgOlxuICAgICAgICAgICAgICAgIGFbSE9VUl0gICAgICAgIDwgMCB8fCBhW0hPVVJdICAgICAgICA+IDI0IHx8IChhW0hPVVJdID09PSAyNCAmJiAoYVtNSU5VVEVdICE9PSAwIHx8IGFbU0VDT05EXSAhPT0gMCB8fCBhW01JTExJU0VDT05EXSAhPT0gMCkpID8gSE9VUiA6XG4gICAgICAgICAgICAgICAgYVtNSU5VVEVdICAgICAgPCAwIHx8IGFbTUlOVVRFXSAgICAgID4gNTkgID8gTUlOVVRFIDpcbiAgICAgICAgICAgICAgICBhW1NFQ09ORF0gICAgICA8IDAgfHwgYVtTRUNPTkRdICAgICAgPiA1OSAgPyBTRUNPTkQgOlxuICAgICAgICAgICAgICAgIGFbTUlMTElTRUNPTkRdIDwgMCB8fCBhW01JTExJU0VDT05EXSA+IDk5OSA/IE1JTExJU0VDT05EIDpcbiAgICAgICAgICAgICAgICAtMTtcblxuICAgICAgICAgICAgaWYgKGdldFBhcnNpbmdGbGFncyhtKS5fb3ZlcmZsb3dEYXlPZlllYXIgJiYgKG92ZXJmbG93IDwgWUVBUiB8fCBvdmVyZmxvdyA+IERBVEUpKSB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3cgPSBEQVRFO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGdldFBhcnNpbmdGbGFncyhtKS5fb3ZlcmZsb3dXZWVrcyAmJiBvdmVyZmxvdyA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBvdmVyZmxvdyA9IFdFRUs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZ2V0UGFyc2luZ0ZsYWdzKG0pLl9vdmVyZmxvd1dlZWtkYXkgJiYgb3ZlcmZsb3cgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3cgPSBXRUVLREFZO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MobSkub3ZlcmZsb3cgPSBvdmVyZmxvdztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtO1xuICAgIH1cblxuICAgIC8vIFBpY2sgdGhlIGZpcnN0IGRlZmluZWQgb2YgdHdvIG9yIHRocmVlIGFyZ3VtZW50cy5cbiAgICBmdW5jdGlvbiBkZWZhdWx0cyhhLCBiLCBjKSB7XG4gICAgICAgIGlmIChhICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBhO1xuICAgICAgICB9XG4gICAgICAgIGlmIChiICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKSB7XG4gICAgICAgIC8vIGhvb2tzIGlzIGFjdHVhbGx5IHRoZSBleHBvcnRlZCBtb21lbnQgb2JqZWN0XG4gICAgICAgIHZhciBub3dWYWx1ZSA9IG5ldyBEYXRlKGhvb2tzLm5vdygpKTtcbiAgICAgICAgaWYgKGNvbmZpZy5fdXNlVVRDKSB7XG4gICAgICAgICAgICByZXR1cm4gW25vd1ZhbHVlLmdldFVUQ0Z1bGxZZWFyKCksIG5vd1ZhbHVlLmdldFVUQ01vbnRoKCksIG5vd1ZhbHVlLmdldFVUQ0RhdGUoKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtub3dWYWx1ZS5nZXRGdWxsWWVhcigpLCBub3dWYWx1ZS5nZXRNb250aCgpLCBub3dWYWx1ZS5nZXREYXRlKCldO1xuICAgIH1cblxuICAgIC8vIGNvbnZlcnQgYW4gYXJyYXkgdG8gYSBkYXRlLlxuICAgIC8vIHRoZSBhcnJheSBzaG91bGQgbWlycm9yIHRoZSBwYXJhbWV0ZXJzIGJlbG93XG4gICAgLy8gbm90ZTogYWxsIHZhbHVlcyBwYXN0IHRoZSB5ZWFyIGFyZSBvcHRpb25hbCBhbmQgd2lsbCBkZWZhdWx0IHRvIHRoZSBsb3dlc3QgcG9zc2libGUgdmFsdWUuXG4gICAgLy8gW3llYXIsIG1vbnRoLCBkYXkgLCBob3VyLCBtaW51dGUsIHNlY29uZCwgbWlsbGlzZWNvbmRdXG4gICAgZnVuY3Rpb24gY29uZmlnRnJvbUFycmF5IChjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGRhdGUsIGlucHV0ID0gW10sIGN1cnJlbnREYXRlLCBleHBlY3RlZFdlZWtkYXksIHllYXJUb1VzZTtcblxuICAgICAgICBpZiAoY29uZmlnLl9kKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50RGF0ZSA9IGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKTtcblxuICAgICAgICAvL2NvbXB1dGUgZGF5IG9mIHRoZSB5ZWFyIGZyb20gd2Vla3MgYW5kIHdlZWtkYXlzXG4gICAgICAgIGlmIChjb25maWcuX3cgJiYgY29uZmlnLl9hW0RBVEVdID09IG51bGwgJiYgY29uZmlnLl9hW01PTlRIXSA9PSBudWxsKSB7XG4gICAgICAgICAgICBkYXlPZlllYXJGcm9tV2Vla0luZm8oY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vaWYgdGhlIGRheSBvZiB0aGUgeWVhciBpcyBzZXQsIGZpZ3VyZSBvdXQgd2hhdCBpdCBpc1xuICAgICAgICBpZiAoY29uZmlnLl9kYXlPZlllYXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgeWVhclRvVXNlID0gZGVmYXVsdHMoY29uZmlnLl9hW1lFQVJdLCBjdXJyZW50RGF0ZVtZRUFSXSk7XG5cbiAgICAgICAgICAgIGlmIChjb25maWcuX2RheU9mWWVhciA+IGRheXNJblllYXIoeWVhclRvVXNlKSB8fCBjb25maWcuX2RheU9mWWVhciA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLl9vdmVyZmxvd0RheU9mWWVhciA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRhdGUgPSBjcmVhdGVVVENEYXRlKHllYXJUb1VzZSwgMCwgY29uZmlnLl9kYXlPZlllYXIpO1xuICAgICAgICAgICAgY29uZmlnLl9hW01PTlRIXSA9IGRhdGUuZ2V0VVRDTW9udGgoKTtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtEQVRFXSA9IGRhdGUuZ2V0VVRDRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGVmYXVsdCB0byBjdXJyZW50IGRhdGUuXG4gICAgICAgIC8vICogaWYgbm8geWVhciwgbW9udGgsIGRheSBvZiBtb250aCBhcmUgZ2l2ZW4sIGRlZmF1bHQgdG8gdG9kYXlcbiAgICAgICAgLy8gKiBpZiBkYXkgb2YgbW9udGggaXMgZ2l2ZW4sIGRlZmF1bHQgbW9udGggYW5kIHllYXJcbiAgICAgICAgLy8gKiBpZiBtb250aCBpcyBnaXZlbiwgZGVmYXVsdCBvbmx5IHllYXJcbiAgICAgICAgLy8gKiBpZiB5ZWFyIGlzIGdpdmVuLCBkb24ndCBkZWZhdWx0IGFueXRoaW5nXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAzICYmIGNvbmZpZy5fYVtpXSA9PSBudWxsOyArK2kpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gY3VycmVudERhdGVbaV07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBaZXJvIG91dCB3aGF0ZXZlciB3YXMgbm90IGRlZmF1bHRlZCwgaW5jbHVkaW5nIHRpbWVcbiAgICAgICAgZm9yICg7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gKGNvbmZpZy5fYVtpXSA9PSBudWxsKSA/IChpID09PSAyID8gMSA6IDApIDogY29uZmlnLl9hW2ldO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIDI0OjAwOjAwLjAwMFxuICAgICAgICBpZiAoY29uZmlnLl9hW0hPVVJdID09PSAyNCAmJlxuICAgICAgICAgICAgICAgIGNvbmZpZy5fYVtNSU5VVEVdID09PSAwICYmXG4gICAgICAgICAgICAgICAgY29uZmlnLl9hW1NFQ09ORF0gPT09IDAgJiZcbiAgICAgICAgICAgICAgICBjb25maWcuX2FbTUlMTElTRUNPTkRdID09PSAwKSB7XG4gICAgICAgICAgICBjb25maWcuX25leHREYXkgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9hW0hPVVJdID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZy5fZCA9IChjb25maWcuX3VzZVVUQyA/IGNyZWF0ZVVUQ0RhdGUgOiBjcmVhdGVEYXRlKS5hcHBseShudWxsLCBpbnB1dCk7XG4gICAgICAgIGV4cGVjdGVkV2Vla2RheSA9IGNvbmZpZy5fdXNlVVRDID8gY29uZmlnLl9kLmdldFVUQ0RheSgpIDogY29uZmlnLl9kLmdldERheSgpO1xuXG4gICAgICAgIC8vIEFwcGx5IHRpbWV6b25lIG9mZnNldCBmcm9tIGlucHV0LiBUaGUgYWN0dWFsIHV0Y09mZnNldCBjYW4gYmUgY2hhbmdlZFxuICAgICAgICAvLyB3aXRoIHBhcnNlWm9uZS5cbiAgICAgICAgaWYgKGNvbmZpZy5fdHptICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZC5zZXRVVENNaW51dGVzKGNvbmZpZy5fZC5nZXRVVENNaW51dGVzKCkgLSBjb25maWcuX3R6bSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLl9uZXh0RGF5KSB7XG4gICAgICAgICAgICBjb25maWcuX2FbSE9VUl0gPSAyNDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGZvciBtaXNtYXRjaGluZyBkYXkgb2Ygd2Vla1xuICAgICAgICBpZiAoY29uZmlnLl93ICYmIHR5cGVvZiBjb25maWcuX3cuZCAhPT0gJ3VuZGVmaW5lZCcgJiYgY29uZmlnLl93LmQgIT09IGV4cGVjdGVkV2Vla2RheSkge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykud2Vla2RheU1pc21hdGNoID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrSW5mbyhjb25maWcpIHtcbiAgICAgICAgdmFyIHcsIHdlZWtZZWFyLCB3ZWVrLCB3ZWVrZGF5LCBkb3csIGRveSwgdGVtcCwgd2Vla2RheU92ZXJmbG93O1xuXG4gICAgICAgIHcgPSBjb25maWcuX3c7XG4gICAgICAgIGlmICh3LkdHICE9IG51bGwgfHwgdy5XICE9IG51bGwgfHwgdy5FICE9IG51bGwpIHtcbiAgICAgICAgICAgIGRvdyA9IDE7XG4gICAgICAgICAgICBkb3kgPSA0O1xuXG4gICAgICAgICAgICAvLyBUT0RPOiBXZSBuZWVkIHRvIHRha2UgdGhlIGN1cnJlbnQgaXNvV2Vla1llYXIsIGJ1dCB0aGF0IGRlcGVuZHMgb25cbiAgICAgICAgICAgIC8vIGhvdyB3ZSBpbnRlcnByZXQgbm93IChsb2NhbCwgdXRjLCBmaXhlZCBvZmZzZXQpLiBTbyBjcmVhdGVcbiAgICAgICAgICAgIC8vIGEgbm93IHZlcnNpb24gb2YgY3VycmVudCBjb25maWcgKHRha2UgbG9jYWwvdXRjL29mZnNldCBmbGFncywgYW5kXG4gICAgICAgICAgICAvLyBjcmVhdGUgbm93KS5cbiAgICAgICAgICAgIHdlZWtZZWFyID0gZGVmYXVsdHMody5HRywgY29uZmlnLl9hW1lFQVJdLCB3ZWVrT2ZZZWFyKGNyZWF0ZUxvY2FsKCksIDEsIDQpLnllYXIpO1xuICAgICAgICAgICAgd2VlayA9IGRlZmF1bHRzKHcuVywgMSk7XG4gICAgICAgICAgICB3ZWVrZGF5ID0gZGVmYXVsdHMody5FLCAxKTtcbiAgICAgICAgICAgIGlmICh3ZWVrZGF5IDwgMSB8fCB3ZWVrZGF5ID4gNykge1xuICAgICAgICAgICAgICAgIHdlZWtkYXlPdmVyZmxvdyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkb3cgPSBjb25maWcuX2xvY2FsZS5fd2Vlay5kb3c7XG4gICAgICAgICAgICBkb3kgPSBjb25maWcuX2xvY2FsZS5fd2Vlay5kb3k7XG5cbiAgICAgICAgICAgIHZhciBjdXJXZWVrID0gd2Vla09mWWVhcihjcmVhdGVMb2NhbCgpLCBkb3csIGRveSk7XG5cbiAgICAgICAgICAgIHdlZWtZZWFyID0gZGVmYXVsdHMody5nZywgY29uZmlnLl9hW1lFQVJdLCBjdXJXZWVrLnllYXIpO1xuXG4gICAgICAgICAgICAvLyBEZWZhdWx0IHRvIGN1cnJlbnQgd2Vlay5cbiAgICAgICAgICAgIHdlZWsgPSBkZWZhdWx0cyh3LncsIGN1cldlZWsud2Vlayk7XG5cbiAgICAgICAgICAgIGlmICh3LmQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIHdlZWtkYXkgLS0gbG93IGRheSBudW1iZXJzIGFyZSBjb25zaWRlcmVkIG5leHQgd2Vla1xuICAgICAgICAgICAgICAgIHdlZWtkYXkgPSB3LmQ7XG4gICAgICAgICAgICAgICAgaWYgKHdlZWtkYXkgPCAwIHx8IHdlZWtkYXkgPiA2KSB7XG4gICAgICAgICAgICAgICAgICAgIHdlZWtkYXlPdmVyZmxvdyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh3LmUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIGxvY2FsIHdlZWtkYXkgLS0gY291bnRpbmcgc3RhcnRzIGZyb20gYmVnaW5uaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gdy5lICsgZG93O1xuICAgICAgICAgICAgICAgIGlmICh3LmUgPCAwIHx8IHcuZSA+IDYpIHtcbiAgICAgICAgICAgICAgICAgICAgd2Vla2RheU92ZXJmbG93ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGRlZmF1bHQgdG8gYmVnaW5uaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gZG93O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh3ZWVrIDwgMSB8fCB3ZWVrID4gd2Vla3NJblllYXIod2Vla1llYXIsIGRvdywgZG95KSkge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuX292ZXJmbG93V2Vla3MgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHdlZWtkYXlPdmVyZmxvdyAhPSBudWxsKSB7XG4gICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5fb3ZlcmZsb3dXZWVrZGF5ID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRlbXAgPSBkYXlPZlllYXJGcm9tV2Vla3Mod2Vla1llYXIsIHdlZWssIHdlZWtkYXksIGRvdywgZG95KTtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtZRUFSXSA9IHRlbXAueWVhcjtcbiAgICAgICAgICAgIGNvbmZpZy5fZGF5T2ZZZWFyID0gdGVtcC5kYXlPZlllYXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpc28gODYwMSByZWdleFxuICAgIC8vIDAwMDAtMDAtMDAgMDAwMC1XMDAgb3IgMDAwMC1XMDAtMCArIFQgKyAwMCBvciAwMDowMCBvciAwMDowMDowMCBvciAwMDowMDowMC4wMDAgKyArMDA6MDAgb3IgKzAwMDAgb3IgKzAwKVxuICAgIHZhciBleHRlbmRlZElzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KS0oPzpcXGRcXGQtXFxkXFxkfFdcXGRcXGQtXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86OlxcZFxcZCg/OjpcXGRcXGQoPzpbLixdXFxkKyk/KT8pPykoW1xcK1xcLV1cXGRcXGQoPzo6P1xcZFxcZCk/fFxccypaKT8pPyQvO1xuICAgIHZhciBiYXNpY0lzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KSg/OlxcZFxcZFxcZFxcZHxXXFxkXFxkXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86XFxkXFxkKD86XFxkXFxkKD86Wy4sXVxcZCspPyk/KT8pKFtcXCtcXC1dXFxkXFxkKD86Oj9cXGRcXGQpP3xcXHMqWik/KT8kLztcblxuICAgIHZhciB0elJlZ2V4ID0gL1p8WystXVxcZFxcZCg/Ojo/XFxkXFxkKT8vO1xuXG4gICAgdmFyIGlzb0RhdGVzID0gW1xuICAgICAgICBbJ1lZWVlZWS1NTS1ERCcsIC9bKy1dXFxkezZ9LVxcZFxcZC1cXGRcXGQvXSxcbiAgICAgICAgWydZWVlZLU1NLUREJywgL1xcZHs0fS1cXGRcXGQtXFxkXFxkL10sXG4gICAgICAgIFsnR0dHRy1bV11XVy1FJywgL1xcZHs0fS1XXFxkXFxkLVxcZC9dLFxuICAgICAgICBbJ0dHR0ctW1ddV1cnLCAvXFxkezR9LVdcXGRcXGQvLCBmYWxzZV0sXG4gICAgICAgIFsnWVlZWS1EREQnLCAvXFxkezR9LVxcZHszfS9dLFxuICAgICAgICBbJ1lZWVktTU0nLCAvXFxkezR9LVxcZFxcZC8sIGZhbHNlXSxcbiAgICAgICAgWydZWVlZWVlNTUREJywgL1srLV1cXGR7MTB9L10sXG4gICAgICAgIFsnWVlZWU1NREQnLCAvXFxkezh9L10sXG4gICAgICAgIC8vIFlZWVlNTSBpcyBOT1QgYWxsb3dlZCBieSB0aGUgc3RhbmRhcmRcbiAgICAgICAgWydHR0dHW1ddV1dFJywgL1xcZHs0fVdcXGR7M30vXSxcbiAgICAgICAgWydHR0dHW1ddV1cnLCAvXFxkezR9V1xcZHsyfS8sIGZhbHNlXSxcbiAgICAgICAgWydZWVlZREREJywgL1xcZHs3fS9dXG4gICAgXTtcblxuICAgIC8vIGlzbyB0aW1lIGZvcm1hdHMgYW5kIHJlZ2V4ZXNcbiAgICB2YXIgaXNvVGltZXMgPSBbXG4gICAgICAgIFsnSEg6bW06c3MuU1NTUycsIC9cXGRcXGQ6XFxkXFxkOlxcZFxcZFxcLlxcZCsvXSxcbiAgICAgICAgWydISDptbTpzcyxTU1NTJywgL1xcZFxcZDpcXGRcXGQ6XFxkXFxkLFxcZCsvXSxcbiAgICAgICAgWydISDptbTpzcycsIC9cXGRcXGQ6XFxkXFxkOlxcZFxcZC9dLFxuICAgICAgICBbJ0hIOm1tJywgL1xcZFxcZDpcXGRcXGQvXSxcbiAgICAgICAgWydISG1tc3MuU1NTUycsIC9cXGRcXGRcXGRcXGRcXGRcXGRcXC5cXGQrL10sXG4gICAgICAgIFsnSEhtbXNzLFNTU1MnLCAvXFxkXFxkXFxkXFxkXFxkXFxkLFxcZCsvXSxcbiAgICAgICAgWydISG1tc3MnLCAvXFxkXFxkXFxkXFxkXFxkXFxkL10sXG4gICAgICAgIFsnSEhtbScsIC9cXGRcXGRcXGRcXGQvXSxcbiAgICAgICAgWydISCcsIC9cXGRcXGQvXVxuICAgIF07XG5cbiAgICB2YXIgYXNwTmV0SnNvblJlZ2V4ID0gL15cXC8/RGF0ZVxcKChcXC0/XFxkKykvaTtcblxuICAgIC8vIGRhdGUgZnJvbSBpc28gZm9ybWF0XG4gICAgZnVuY3Rpb24gY29uZmlnRnJvbUlTTyhjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGwsXG4gICAgICAgICAgICBzdHJpbmcgPSBjb25maWcuX2ksXG4gICAgICAgICAgICBtYXRjaCA9IGV4dGVuZGVkSXNvUmVnZXguZXhlYyhzdHJpbmcpIHx8IGJhc2ljSXNvUmVnZXguZXhlYyhzdHJpbmcpLFxuICAgICAgICAgICAgYWxsb3dUaW1lLCBkYXRlRm9ybWF0LCB0aW1lRm9ybWF0LCB0ekZvcm1hdDtcblxuICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmlzbyA9IHRydWU7XG5cbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBpc29EYXRlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNvRGF0ZXNbaV1bMV0uZXhlYyhtYXRjaFsxXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdCA9IGlzb0RhdGVzW2ldWzBdO1xuICAgICAgICAgICAgICAgICAgICBhbGxvd1RpbWUgPSBpc29EYXRlc1tpXVsyXSAhPT0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRlRm9ybWF0ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25maWcuX2lzVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWF0Y2hbM10pIHtcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gaXNvVGltZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc29UaW1lc1tpXVsxXS5leGVjKG1hdGNoWzNdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWF0Y2hbMl0gc2hvdWxkIGJlICdUJyBvciBzcGFjZVxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZUZvcm1hdCA9IChtYXRjaFsyXSB8fCAnICcpICsgaXNvVGltZXNbaV1bMF07XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGltZUZvcm1hdCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFhbGxvd1RpbWUgJiYgdGltZUZvcm1hdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1hdGNoWzRdKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR6UmVnZXguZXhlYyhtYXRjaFs0XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHpGb3JtYXQgPSAnWic7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25maWcuX2YgPSBkYXRlRm9ybWF0ICsgKHRpbWVGb3JtYXQgfHwgJycpICsgKHR6Rm9ybWF0IHx8ICcnKTtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUkZDIDI4MjIgcmVnZXg6IEZvciBkZXRhaWxzIHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMjgyMiNzZWN0aW9uLTMuM1xuICAgIHZhciByZmMyODIyID0gL14oPzooTW9ufFR1ZXxXZWR8VGh1fEZyaXxTYXR8U3VuKSw/XFxzKT8oXFxkezEsMn0pXFxzKEphbnxGZWJ8TWFyfEFwcnxNYXl8SnVufEp1bHxBdWd8U2VwfE9jdHxOb3Z8RGVjKVxccyhcXGR7Miw0fSlcXHMoXFxkXFxkKTooXFxkXFxkKSg/OjooXFxkXFxkKSk/XFxzKD86KFVUfEdNVHxbRUNNUF1bU0RdVCl8KFtael0pfChbKy1dXFxkezR9KSkkLztcblxuICAgIGZ1bmN0aW9uIGV4dHJhY3RGcm9tUkZDMjgyMlN0cmluZ3MoeWVhclN0ciwgbW9udGhTdHIsIGRheVN0ciwgaG91clN0ciwgbWludXRlU3RyLCBzZWNvbmRTdHIpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtcbiAgICAgICAgICAgIHVudHJ1bmNhdGVZZWFyKHllYXJTdHIpLFxuICAgICAgICAgICAgZGVmYXVsdExvY2FsZU1vbnRoc1Nob3J0LmluZGV4T2YobW9udGhTdHIpLFxuICAgICAgICAgICAgcGFyc2VJbnQoZGF5U3RyLCAxMCksXG4gICAgICAgICAgICBwYXJzZUludChob3VyU3RyLCAxMCksXG4gICAgICAgICAgICBwYXJzZUludChtaW51dGVTdHIsIDEwKVxuICAgICAgICBdO1xuXG4gICAgICAgIGlmIChzZWNvbmRTdHIpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBhcnNlSW50KHNlY29uZFN0ciwgMTApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdW50cnVuY2F0ZVllYXIoeWVhclN0cikge1xuICAgICAgICB2YXIgeWVhciA9IHBhcnNlSW50KHllYXJTdHIsIDEwKTtcbiAgICAgICAgaWYgKHllYXIgPD0gNDkpIHtcbiAgICAgICAgICAgIHJldHVybiAyMDAwICsgeWVhcjtcbiAgICAgICAgfSBlbHNlIGlmICh5ZWFyIDw9IDk5OSkge1xuICAgICAgICAgICAgcmV0dXJuIDE5MDAgKyB5ZWFyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB5ZWFyO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByZXByb2Nlc3NSRkMyODIyKHMpIHtcbiAgICAgICAgLy8gUmVtb3ZlIGNvbW1lbnRzIGFuZCBmb2xkaW5nIHdoaXRlc3BhY2UgYW5kIHJlcGxhY2UgbXVsdGlwbGUtc3BhY2VzIHdpdGggYSBzaW5nbGUgc3BhY2VcbiAgICAgICAgcmV0dXJuIHMucmVwbGFjZSgvXFwoW14pXSpcXCl8W1xcblxcdF0vZywgJyAnKS5yZXBsYWNlKC8oXFxzXFxzKykvZywgJyAnKS5yZXBsYWNlKC9eXFxzXFxzKi8sICcnKS5yZXBsYWNlKC9cXHNcXHMqJC8sICcnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja1dlZWtkYXkod2Vla2RheVN0ciwgcGFyc2VkSW5wdXQsIGNvbmZpZykge1xuICAgICAgICBpZiAod2Vla2RheVN0cikge1xuICAgICAgICAgICAgLy8gVE9ETzogUmVwbGFjZSB0aGUgdmFuaWxsYSBKUyBEYXRlIG9iamVjdCB3aXRoIGFuIGluZGVwZW50ZW50IGRheS1vZi13ZWVrIGNoZWNrLlxuICAgICAgICAgICAgdmFyIHdlZWtkYXlQcm92aWRlZCA9IGRlZmF1bHRMb2NhbGVXZWVrZGF5c1Nob3J0LmluZGV4T2Yod2Vla2RheVN0ciksXG4gICAgICAgICAgICAgICAgd2Vla2RheUFjdHVhbCA9IG5ldyBEYXRlKHBhcnNlZElucHV0WzBdLCBwYXJzZWRJbnB1dFsxXSwgcGFyc2VkSW5wdXRbMl0pLmdldERheSgpO1xuICAgICAgICAgICAgaWYgKHdlZWtkYXlQcm92aWRlZCAhPT0gd2Vla2RheUFjdHVhbCkge1xuICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLndlZWtkYXlNaXNtYXRjaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciBvYnNPZmZzZXRzID0ge1xuICAgICAgICBVVDogMCxcbiAgICAgICAgR01UOiAwLFxuICAgICAgICBFRFQ6IC00ICogNjAsXG4gICAgICAgIEVTVDogLTUgKiA2MCxcbiAgICAgICAgQ0RUOiAtNSAqIDYwLFxuICAgICAgICBDU1Q6IC02ICogNjAsXG4gICAgICAgIE1EVDogLTYgKiA2MCxcbiAgICAgICAgTVNUOiAtNyAqIDYwLFxuICAgICAgICBQRFQ6IC03ICogNjAsXG4gICAgICAgIFBTVDogLTggKiA2MFxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBjYWxjdWxhdGVPZmZzZXQob2JzT2Zmc2V0LCBtaWxpdGFyeU9mZnNldCwgbnVtT2Zmc2V0KSB7XG4gICAgICAgIGlmIChvYnNPZmZzZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBvYnNPZmZzZXRzW29ic09mZnNldF07XG4gICAgICAgIH0gZWxzZSBpZiAobWlsaXRhcnlPZmZzZXQpIHtcbiAgICAgICAgICAgIC8vIHRoZSBvbmx5IGFsbG93ZWQgbWlsaXRhcnkgdHogaXMgWlxuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaG0gPSBwYXJzZUludChudW1PZmZzZXQsIDEwKTtcbiAgICAgICAgICAgIHZhciBtID0gaG0gJSAxMDAsIGggPSAoaG0gLSBtKSAvIDEwMDtcbiAgICAgICAgICAgIHJldHVybiBoICogNjAgKyBtO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZGF0ZSBhbmQgdGltZSBmcm9tIHJlZiAyODIyIGZvcm1hdFxuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21SRkMyODIyKGNvbmZpZykge1xuICAgICAgICB2YXIgbWF0Y2ggPSByZmMyODIyLmV4ZWMocHJlcHJvY2Vzc1JGQzI4MjIoY29uZmlnLl9pKSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgdmFyIHBhcnNlZEFycmF5ID0gZXh0cmFjdEZyb21SRkMyODIyU3RyaW5ncyhtYXRjaFs0XSwgbWF0Y2hbM10sIG1hdGNoWzJdLCBtYXRjaFs1XSwgbWF0Y2hbNl0sIG1hdGNoWzddKTtcbiAgICAgICAgICAgIGlmICghY2hlY2tXZWVrZGF5KG1hdGNoWzFdLCBwYXJzZWRBcnJheSwgY29uZmlnKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uZmlnLl9hID0gcGFyc2VkQXJyYXk7XG4gICAgICAgICAgICBjb25maWcuX3R6bSA9IGNhbGN1bGF0ZU9mZnNldChtYXRjaFs4XSwgbWF0Y2hbOV0sIG1hdGNoWzEwXSk7XG5cbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IGNyZWF0ZVVUQ0RhdGUuYXBwbHkobnVsbCwgY29uZmlnLl9hKTtcbiAgICAgICAgICAgIGNvbmZpZy5fZC5zZXRVVENNaW51dGVzKGNvbmZpZy5fZC5nZXRVVENNaW51dGVzKCkgLSBjb25maWcuX3R6bSk7XG5cbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnJmYzI4MjIgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gaXNvIGZvcm1hdCBvciBmYWxsYmFja1xuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21TdHJpbmcoY29uZmlnKSB7XG4gICAgICAgIHZhciBtYXRjaGVkID0gYXNwTmV0SnNvblJlZ2V4LmV4ZWMoY29uZmlnLl9pKTtcblxuICAgICAgICBpZiAobWF0Y2hlZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoK21hdGNoZWRbMV0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uZmlnRnJvbUlTTyhjb25maWcpO1xuICAgICAgICBpZiAoY29uZmlnLl9pc1ZhbGlkID09PSBmYWxzZSkge1xuICAgICAgICAgICAgZGVsZXRlIGNvbmZpZy5faXNWYWxpZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZ0Zyb21SRkMyODIyKGNvbmZpZyk7XG4gICAgICAgIGlmIChjb25maWcuX2lzVmFsaWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBkZWxldGUgY29uZmlnLl9pc1ZhbGlkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluYWwgYXR0ZW1wdCwgdXNlIElucHV0IEZhbGxiYWNrXG4gICAgICAgIGhvb2tzLmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgfVxuXG4gICAgaG9va3MuY3JlYXRlRnJvbUlucHV0RmFsbGJhY2sgPSBkZXByZWNhdGUoXG4gICAgICAgICd2YWx1ZSBwcm92aWRlZCBpcyBub3QgaW4gYSByZWNvZ25pemVkIFJGQzI4MjIgb3IgSVNPIGZvcm1hdC4gbW9tZW50IGNvbnN0cnVjdGlvbiBmYWxscyBiYWNrIHRvIGpzIERhdGUoKSwgJyArXG4gICAgICAgICd3aGljaCBpcyBub3QgcmVsaWFibGUgYWNyb3NzIGFsbCBicm93c2VycyBhbmQgdmVyc2lvbnMuIE5vbiBSRkMyODIyL0lTTyBkYXRlIGZvcm1hdHMgYXJlICcgK1xuICAgICAgICAnZGlzY291cmFnZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhbiB1cGNvbWluZyBtYWpvciByZWxlYXNlLiBQbGVhc2UgcmVmZXIgdG8gJyArXG4gICAgICAgICdodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2pzLWRhdGUvIGZvciBtb3JlIGluZm8uJyxcbiAgICAgICAgZnVuY3Rpb24gKGNvbmZpZykge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoY29uZmlnLl9pICsgKGNvbmZpZy5fdXNlVVRDID8gJyBVVEMnIDogJycpKTtcbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBjb25zdGFudCB0aGF0IHJlZmVycyB0byB0aGUgSVNPIHN0YW5kYXJkXG4gICAgaG9va3MuSVNPXzg2MDEgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIGNvbnN0YW50IHRoYXQgcmVmZXJzIHRvIHRoZSBSRkMgMjgyMiBmb3JtXG4gICAgaG9va3MuUkZDXzI4MjIgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIGRhdGUgZnJvbSBzdHJpbmcgYW5kIGZvcm1hdCBzdHJpbmdcbiAgICBmdW5jdGlvbiBjb25maWdGcm9tU3RyaW5nQW5kRm9ybWF0KGNvbmZpZykge1xuICAgICAgICAvLyBUT0RPOiBNb3ZlIHRoaXMgdG8gYW5vdGhlciBwYXJ0IG9mIHRoZSBjcmVhdGlvbiBmbG93IHRvIHByZXZlbnQgY2lyY3VsYXIgZGVwc1xuICAgICAgICBpZiAoY29uZmlnLl9mID09PSBob29rcy5JU09fODYwMSkge1xuICAgICAgICAgICAgY29uZmlnRnJvbUlTTyhjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25maWcuX2YgPT09IGhvb2tzLlJGQ18yODIyKSB7XG4gICAgICAgICAgICBjb25maWdGcm9tUkZDMjgyMihjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbmZpZy5fYSA9IFtdO1xuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5lbXB0eSA9IHRydWU7XG5cbiAgICAgICAgLy8gVGhpcyBhcnJheSBpcyB1c2VkIHRvIG1ha2UgYSBEYXRlLCBlaXRoZXIgd2l0aCBgbmV3IERhdGVgIG9yIGBEYXRlLlVUQ2BcbiAgICAgICAgdmFyIHN0cmluZyA9ICcnICsgY29uZmlnLl9pLFxuICAgICAgICAgICAgaSwgcGFyc2VkSW5wdXQsIHRva2VucywgdG9rZW4sIHNraXBwZWQsXG4gICAgICAgICAgICBzdHJpbmdMZW5ndGggPSBzdHJpbmcubGVuZ3RoLFxuICAgICAgICAgICAgdG90YWxQYXJzZWRJbnB1dExlbmd0aCA9IDA7XG5cbiAgICAgICAgdG9rZW5zID0gZXhwYW5kRm9ybWF0KGNvbmZpZy5fZiwgY29uZmlnLl9sb2NhbGUpLm1hdGNoKGZvcm1hdHRpbmdUb2tlbnMpIHx8IFtdO1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRva2VuID0gdG9rZW5zW2ldO1xuICAgICAgICAgICAgcGFyc2VkSW5wdXQgPSAoc3RyaW5nLm1hdGNoKGdldFBhcnNlUmVnZXhGb3JUb2tlbih0b2tlbiwgY29uZmlnKSkgfHwgW10pWzBdO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ3Rva2VuJywgdG9rZW4sICdwYXJzZWRJbnB1dCcsIHBhcnNlZElucHV0LFxuICAgICAgICAgICAgLy8gICAgICAgICAncmVnZXgnLCBnZXRQYXJzZVJlZ2V4Rm9yVG9rZW4odG9rZW4sIGNvbmZpZykpO1xuICAgICAgICAgICAgaWYgKHBhcnNlZElucHV0KSB7XG4gICAgICAgICAgICAgICAgc2tpcHBlZCA9IHN0cmluZy5zdWJzdHIoMCwgc3RyaW5nLmluZGV4T2YocGFyc2VkSW5wdXQpKTtcbiAgICAgICAgICAgICAgICBpZiAoc2tpcHBlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnVudXNlZElucHV0LnB1c2goc2tpcHBlZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN0cmluZyA9IHN0cmluZy5zbGljZShzdHJpbmcuaW5kZXhPZihwYXJzZWRJbnB1dCkgKyBwYXJzZWRJbnB1dC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIHRvdGFsUGFyc2VkSW5wdXRMZW5ndGggKz0gcGFyc2VkSW5wdXQubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZG9uJ3QgcGFyc2UgaWYgaXQncyBub3QgYSBrbm93biB0b2tlblxuICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuRnVuY3Rpb25zW3Rva2VuXSkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZWRJbnB1dCkge1xuICAgICAgICAgICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5lbXB0eSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykudW51c2VkVG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhZGRUaW1lVG9BcnJheUZyb21Ub2tlbih0b2tlbiwgcGFyc2VkSW5wdXQsIGNvbmZpZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb25maWcuX3N0cmljdCAmJiAhcGFyc2VkSW5wdXQpIHtcbiAgICAgICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS51bnVzZWRUb2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGQgcmVtYWluaW5nIHVucGFyc2VkIGlucHV0IGxlbmd0aCB0byB0aGUgc3RyaW5nXG4gICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmNoYXJzTGVmdE92ZXIgPSBzdHJpbmdMZW5ndGggLSB0b3RhbFBhcnNlZElucHV0TGVuZ3RoO1xuICAgICAgICBpZiAoc3RyaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnVudXNlZElucHV0LnB1c2goc3RyaW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNsZWFyIF8xMmggZmxhZyBpZiBob3VyIGlzIDw9IDEyXG4gICAgICAgIGlmIChjb25maWcuX2FbSE9VUl0gPD0gMTIgJiZcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmJpZ0hvdXIgPT09IHRydWUgJiZcbiAgICAgICAgICAgIGNvbmZpZy5fYVtIT1VSXSA+IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmJpZ0hvdXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5wYXJzZWREYXRlUGFydHMgPSBjb25maWcuX2Euc2xpY2UoMCk7XG4gICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLm1lcmlkaWVtID0gY29uZmlnLl9tZXJpZGllbTtcbiAgICAgICAgLy8gaGFuZGxlIG1lcmlkaWVtXG4gICAgICAgIGNvbmZpZy5fYVtIT1VSXSA9IG1lcmlkaWVtRml4V3JhcChjb25maWcuX2xvY2FsZSwgY29uZmlnLl9hW0hPVVJdLCBjb25maWcuX21lcmlkaWVtKTtcblxuICAgICAgICBjb25maWdGcm9tQXJyYXkoY29uZmlnKTtcbiAgICAgICAgY2hlY2tPdmVyZmxvdyhjb25maWcpO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gbWVyaWRpZW1GaXhXcmFwIChsb2NhbGUsIGhvdXIsIG1lcmlkaWVtKSB7XG4gICAgICAgIHZhciBpc1BtO1xuXG4gICAgICAgIGlmIChtZXJpZGllbSA9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBub3RoaW5nIHRvIGRvXG4gICAgICAgICAgICByZXR1cm4gaG91cjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobG9jYWxlLm1lcmlkaWVtSG91ciAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbG9jYWxlLm1lcmlkaWVtSG91cihob3VyLCBtZXJpZGllbSk7XG4gICAgICAgIH0gZWxzZSBpZiAobG9jYWxlLmlzUE0gIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gRmFsbGJhY2tcbiAgICAgICAgICAgIGlzUG0gPSBsb2NhbGUuaXNQTShtZXJpZGllbSk7XG4gICAgICAgICAgICBpZiAoaXNQbSAmJiBob3VyIDwgMTIpIHtcbiAgICAgICAgICAgICAgICBob3VyICs9IDEyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc1BtICYmIGhvdXIgPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgaG91ciA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaG91cjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgbm90IHN1cHBvc2VkIHRvIGhhcHBlblxuICAgICAgICAgICAgcmV0dXJuIGhvdXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gc3RyaW5nIGFuZCBhcnJheSBvZiBmb3JtYXQgc3RyaW5nc1xuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21TdHJpbmdBbmRBcnJheShjb25maWcpIHtcbiAgICAgICAgdmFyIHRlbXBDb25maWcsXG4gICAgICAgICAgICBiZXN0TW9tZW50LFxuXG4gICAgICAgICAgICBzY29yZVRvQmVhdCxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBjdXJyZW50U2NvcmU7XG5cbiAgICAgICAgaWYgKGNvbmZpZy5fZi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmludmFsaWRGb3JtYXQgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoTmFOKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb25maWcuX2YubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGN1cnJlbnRTY29yZSA9IDA7XG4gICAgICAgICAgICB0ZW1wQ29uZmlnID0gY29weUNvbmZpZyh7fSwgY29uZmlnKTtcbiAgICAgICAgICAgIGlmIChjb25maWcuX3VzZVVUQyAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGVtcENvbmZpZy5fdXNlVVRDID0gY29uZmlnLl91c2VVVEM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZW1wQ29uZmlnLl9mID0gY29uZmlnLl9mW2ldO1xuICAgICAgICAgICAgY29uZmlnRnJvbVN0cmluZ0FuZEZvcm1hdCh0ZW1wQ29uZmlnKTtcblxuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKHRlbXBDb25maWcpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFueSBpbnB1dCB0aGF0IHdhcyBub3QgcGFyc2VkIGFkZCBhIHBlbmFsdHkgZm9yIHRoYXQgZm9ybWF0XG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgKz0gZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLmNoYXJzTGVmdE92ZXI7XG5cbiAgICAgICAgICAgIC8vb3IgdG9rZW5zXG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgKz0gZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLnVudXNlZFRva2Vucy5sZW5ndGggKiAxMDtcblxuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLnNjb3JlID0gY3VycmVudFNjb3JlO1xuXG4gICAgICAgICAgICBpZiAoc2NvcmVUb0JlYXQgPT0gbnVsbCB8fCBjdXJyZW50U2NvcmUgPCBzY29yZVRvQmVhdCkge1xuICAgICAgICAgICAgICAgIHNjb3JlVG9CZWF0ID0gY3VycmVudFNjb3JlO1xuICAgICAgICAgICAgICAgIGJlc3RNb21lbnQgPSB0ZW1wQ29uZmlnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZXh0ZW5kKGNvbmZpZywgYmVzdE1vbWVudCB8fCB0ZW1wQ29uZmlnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb25maWdGcm9tT2JqZWN0KGNvbmZpZykge1xuICAgICAgICBpZiAoY29uZmlnLl9kKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaSA9IG5vcm1hbGl6ZU9iamVjdFVuaXRzKGNvbmZpZy5faSk7XG4gICAgICAgIGNvbmZpZy5fYSA9IG1hcChbaS55ZWFyLCBpLm1vbnRoLCBpLmRheSB8fCBpLmRhdGUsIGkuaG91ciwgaS5taW51dGUsIGkuc2Vjb25kLCBpLm1pbGxpc2Vjb25kXSwgZnVuY3Rpb24gKG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIG9iaiAmJiBwYXJzZUludChvYmosIDEwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uZmlnRnJvbUFycmF5KGNvbmZpZyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlRnJvbUNvbmZpZyAoY29uZmlnKSB7XG4gICAgICAgIHZhciByZXMgPSBuZXcgTW9tZW50KGNoZWNrT3ZlcmZsb3cocHJlcGFyZUNvbmZpZyhjb25maWcpKSk7XG4gICAgICAgIGlmIChyZXMuX25leHREYXkpIHtcbiAgICAgICAgICAgIC8vIEFkZGluZyBpcyBzbWFydCBlbm91Z2ggYXJvdW5kIERTVFxuICAgICAgICAgICAgcmVzLmFkZCgxLCAnZCcpO1xuICAgICAgICAgICAgcmVzLl9uZXh0RGF5ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVwYXJlQ29uZmlnIChjb25maWcpIHtcbiAgICAgICAgdmFyIGlucHV0ID0gY29uZmlnLl9pLFxuICAgICAgICAgICAgZm9ybWF0ID0gY29uZmlnLl9mO1xuXG4gICAgICAgIGNvbmZpZy5fbG9jYWxlID0gY29uZmlnLl9sb2NhbGUgfHwgZ2V0TG9jYWxlKGNvbmZpZy5fbCk7XG5cbiAgICAgICAgaWYgKGlucHV0ID09PSBudWxsIHx8IChmb3JtYXQgPT09IHVuZGVmaW5lZCAmJiBpbnB1dCA9PT0gJycpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlSW52YWxpZCh7bnVsbElucHV0OiB0cnVlfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uZmlnLl9pID0gaW5wdXQgPSBjb25maWcuX2xvY2FsZS5wcmVwYXJzZShpbnB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNNb21lbnQoaW5wdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE1vbWVudChjaGVja092ZXJmbG93KGlucHV0KSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNEYXRlKGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gaW5wdXQ7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNBcnJheShmb3JtYXQpKSB7XG4gICAgICAgICAgICBjb25maWdGcm9tU3RyaW5nQW5kQXJyYXkoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQpIHtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgfSAgZWxzZSB7XG4gICAgICAgICAgICBjb25maWdGcm9tSW5wdXQoY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNWYWxpZChjb25maWcpKSB7XG4gICAgICAgICAgICBjb25maWcuX2QgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb25maWdGcm9tSW5wdXQoY29uZmlnKSB7XG4gICAgICAgIHZhciBpbnB1dCA9IGNvbmZpZy5faTtcbiAgICAgICAgaWYgKGlzVW5kZWZpbmVkKGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoaG9va3Mubm93KCkpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzRGF0ZShpbnB1dCkpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKGlucHV0LnZhbHVlT2YoKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uZmlnRnJvbVN0cmluZyhjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkoaW5wdXQpKSB7XG4gICAgICAgICAgICBjb25maWcuX2EgPSBtYXAoaW5wdXQuc2xpY2UoMCksIGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQob2JqLCAxMCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21BcnJheShjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnRnJvbU9iamVjdChjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKGlucHV0KSkge1xuICAgICAgICAgICAgLy8gZnJvbSBtaWxsaXNlY29uZHNcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKGlucHV0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhvb2tzLmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVMb2NhbE9yVVRDIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCwgaXNVVEMpIHtcbiAgICAgICAgdmFyIGMgPSB7fTtcblxuICAgICAgICBpZiAobG9jYWxlID09PSB0cnVlIHx8IGxvY2FsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHN0cmljdCA9IGxvY2FsZTtcbiAgICAgICAgICAgIGxvY2FsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgoaXNPYmplY3QoaW5wdXQpICYmIGlzT2JqZWN0RW1wdHkoaW5wdXQpKSB8fFxuICAgICAgICAgICAgICAgIChpc0FycmF5KGlucHV0KSAmJiBpbnB1dC5sZW5ndGggPT09IDApKSB7XG4gICAgICAgICAgICBpbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBvYmplY3QgY29uc3RydWN0aW9uIG11c3QgYmUgZG9uZSB0aGlzIHdheS5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzE0MjNcbiAgICAgICAgYy5faXNBTW9tZW50T2JqZWN0ID0gdHJ1ZTtcbiAgICAgICAgYy5fdXNlVVRDID0gYy5faXNVVEMgPSBpc1VUQztcbiAgICAgICAgYy5fbCA9IGxvY2FsZTtcbiAgICAgICAgYy5faSA9IGlucHV0O1xuICAgICAgICBjLl9mID0gZm9ybWF0O1xuICAgICAgICBjLl9zdHJpY3QgPSBzdHJpY3Q7XG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZyb21Db25maWcoYyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlTG9jYWwgKGlucHV0LCBmb3JtYXQsIGxvY2FsZSwgc3RyaWN0KSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVMb2NhbE9yVVRDKGlucHV0LCBmb3JtYXQsIGxvY2FsZSwgc3RyaWN0LCBmYWxzZSk7XG4gICAgfVxuXG4gICAgdmFyIHByb3RvdHlwZU1pbiA9IGRlcHJlY2F0ZShcbiAgICAgICAgJ21vbWVudCgpLm1pbiBpcyBkZXByZWNhdGVkLCB1c2UgbW9tZW50Lm1heCBpbnN0ZWFkLiBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL21pbi1tYXgvJyxcbiAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIG90aGVyID0gY3JlYXRlTG9jYWwuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzVmFsaWQoKSAmJiBvdGhlci5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3RoZXIgPCB0aGlzID8gdGhpcyA6IG90aGVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlSW52YWxpZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIHZhciBwcm90b3R5cGVNYXggPSBkZXByZWNhdGUoXG4gICAgICAgICdtb21lbnQoKS5tYXggaXMgZGVwcmVjYXRlZCwgdXNlIG1vbWVudC5taW4gaW5zdGVhZC4gaHR0cDovL21vbWVudGpzLmNvbS9ndWlkZXMvIy93YXJuaW5ncy9taW4tbWF4LycsXG4gICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBvdGhlciA9IGNyZWF0ZUxvY2FsLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICBpZiAodGhpcy5pc1ZhbGlkKCkgJiYgb3RoZXIuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG90aGVyID4gdGhpcyA/IHRoaXMgOiBvdGhlcjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUludmFsaWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBQaWNrIGEgbW9tZW50IG0gZnJvbSBtb21lbnRzIHNvIHRoYXQgbVtmbl0ob3RoZXIpIGlzIHRydWUgZm9yIGFsbFxuICAgIC8vIG90aGVyLiBUaGlzIHJlbGllcyBvbiB0aGUgZnVuY3Rpb24gZm4gdG8gYmUgdHJhbnNpdGl2ZS5cbiAgICAvL1xuICAgIC8vIG1vbWVudHMgc2hvdWxkIGVpdGhlciBiZSBhbiBhcnJheSBvZiBtb21lbnQgb2JqZWN0cyBvciBhbiBhcnJheSwgd2hvc2VcbiAgICAvLyBmaXJzdCBlbGVtZW50IGlzIGFuIGFycmF5IG9mIG1vbWVudCBvYmplY3RzLlxuICAgIGZ1bmN0aW9uIHBpY2tCeShmbiwgbW9tZW50cykge1xuICAgICAgICB2YXIgcmVzLCBpO1xuICAgICAgICBpZiAobW9tZW50cy5sZW5ndGggPT09IDEgJiYgaXNBcnJheShtb21lbnRzWzBdKSkge1xuICAgICAgICAgICAgbW9tZW50cyA9IG1vbWVudHNbMF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtb21lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUxvY2FsKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzID0gbW9tZW50c1swXTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IG1vbWVudHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmICghbW9tZW50c1tpXS5pc1ZhbGlkKCkgfHwgbW9tZW50c1tpXVtmbl0ocmVzKSkge1xuICAgICAgICAgICAgICAgIHJlcyA9IG1vbWVudHNbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBVc2UgW10uc29ydCBpbnN0ZWFkP1xuICAgIGZ1bmN0aW9uIG1pbiAoKSB7XG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuXG4gICAgICAgIHJldHVybiBwaWNrQnkoJ2lzQmVmb3JlJywgYXJncyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF4ICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG5cbiAgICAgICAgcmV0dXJuIHBpY2tCeSgnaXNBZnRlcicsIGFyZ3MpO1xuICAgIH1cblxuICAgIHZhciBub3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBEYXRlLm5vdyA/IERhdGUubm93KCkgOiArKG5ldyBEYXRlKCkpO1xuICAgIH07XG5cbiAgICB2YXIgb3JkZXJpbmcgPSBbJ3llYXInLCAncXVhcnRlcicsICdtb250aCcsICd3ZWVrJywgJ2RheScsICdob3VyJywgJ21pbnV0ZScsICdzZWNvbmQnLCAnbWlsbGlzZWNvbmQnXTtcblxuICAgIGZ1bmN0aW9uIGlzRHVyYXRpb25WYWxpZChtKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBtKSB7XG4gICAgICAgICAgICBpZiAoIShpbmRleE9mLmNhbGwob3JkZXJpbmcsIGtleSkgIT09IC0xICYmIChtW2tleV0gPT0gbnVsbCB8fCAhaXNOYU4obVtrZXldKSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHVuaXRIYXNEZWNpbWFsID0gZmFsc2U7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3JkZXJpbmcubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChtW29yZGVyaW5nW2ldXSkge1xuICAgICAgICAgICAgICAgIGlmICh1bml0SGFzRGVjaW1hbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG9ubHkgYWxsb3cgbm9uLWludGVnZXJzIGZvciBzbWFsbGVzdCB1bml0XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChwYXJzZUZsb2F0KG1bb3JkZXJpbmdbaV1dKSAhPT0gdG9JbnQobVtvcmRlcmluZ1tpXV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHVuaXRIYXNEZWNpbWFsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkJDEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1ZhbGlkO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUludmFsaWQkMSgpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKE5hTik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gRHVyYXRpb24gKGR1cmF0aW9uKSB7XG4gICAgICAgIHZhciBub3JtYWxpemVkSW5wdXQgPSBub3JtYWxpemVPYmplY3RVbml0cyhkdXJhdGlvbiksXG4gICAgICAgICAgICB5ZWFycyA9IG5vcm1hbGl6ZWRJbnB1dC55ZWFyIHx8IDAsXG4gICAgICAgICAgICBxdWFydGVycyA9IG5vcm1hbGl6ZWRJbnB1dC5xdWFydGVyIHx8IDAsXG4gICAgICAgICAgICBtb250aHMgPSBub3JtYWxpemVkSW5wdXQubW9udGggfHwgMCxcbiAgICAgICAgICAgIHdlZWtzID0gbm9ybWFsaXplZElucHV0LndlZWsgfHwgbm9ybWFsaXplZElucHV0Lmlzb1dlZWsgfHwgMCxcbiAgICAgICAgICAgIGRheXMgPSBub3JtYWxpemVkSW5wdXQuZGF5IHx8IDAsXG4gICAgICAgICAgICBob3VycyA9IG5vcm1hbGl6ZWRJbnB1dC5ob3VyIHx8IDAsXG4gICAgICAgICAgICBtaW51dGVzID0gbm9ybWFsaXplZElucHV0Lm1pbnV0ZSB8fCAwLFxuICAgICAgICAgICAgc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5zZWNvbmQgfHwgMCxcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5taWxsaXNlY29uZCB8fCAwO1xuXG4gICAgICAgIHRoaXMuX2lzVmFsaWQgPSBpc0R1cmF0aW9uVmFsaWQobm9ybWFsaXplZElucHV0KTtcblxuICAgICAgICAvLyByZXByZXNlbnRhdGlvbiBmb3IgZGF0ZUFkZFJlbW92ZVxuICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgPSArbWlsbGlzZWNvbmRzICtcbiAgICAgICAgICAgIHNlY29uZHMgKiAxZTMgKyAvLyAxMDAwXG4gICAgICAgICAgICBtaW51dGVzICogNmU0ICsgLy8gMTAwMCAqIDYwXG4gICAgICAgICAgICBob3VycyAqIDEwMDAgKiA2MCAqIDYwOyAvL3VzaW5nIDEwMDAgKiA2MCAqIDYwIGluc3RlYWQgb2YgMzZlNSB0byBhdm9pZCBmbG9hdGluZyBwb2ludCByb3VuZGluZyBlcnJvcnMgaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzI5NzhcbiAgICAgICAgLy8gQmVjYXVzZSBvZiBkYXRlQWRkUmVtb3ZlIHRyZWF0cyAyNCBob3VycyBhcyBkaWZmZXJlbnQgZnJvbSBhXG4gICAgICAgIC8vIGRheSB3aGVuIHdvcmtpbmcgYXJvdW5kIERTVCwgd2UgbmVlZCB0byBzdG9yZSB0aGVtIHNlcGFyYXRlbHlcbiAgICAgICAgdGhpcy5fZGF5cyA9ICtkYXlzICtcbiAgICAgICAgICAgIHdlZWtzICogNztcbiAgICAgICAgLy8gSXQgaXMgaW1wb3NzaWJsZSB0byB0cmFuc2xhdGUgbW9udGhzIGludG8gZGF5cyB3aXRob3V0IGtub3dpbmdcbiAgICAgICAgLy8gd2hpY2ggbW9udGhzIHlvdSBhcmUgYXJlIHRhbGtpbmcgYWJvdXQsIHNvIHdlIGhhdmUgdG8gc3RvcmVcbiAgICAgICAgLy8gaXQgc2VwYXJhdGVseS5cbiAgICAgICAgdGhpcy5fbW9udGhzID0gK21vbnRocyArXG4gICAgICAgICAgICBxdWFydGVycyAqIDMgK1xuICAgICAgICAgICAgeWVhcnMgKiAxMjtcblxuICAgICAgICB0aGlzLl9kYXRhID0ge307XG5cbiAgICAgICAgdGhpcy5fbG9jYWxlID0gZ2V0TG9jYWxlKCk7XG5cbiAgICAgICAgdGhpcy5fYnViYmxlKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEdXJhdGlvbiAob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmogaW5zdGFuY2VvZiBEdXJhdGlvbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhYnNSb3VuZCAobnVtYmVyKSB7XG4gICAgICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCgtMSAqIG51bWJlcikgKiAtMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKG51bWJlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBmdW5jdGlvbiBvZmZzZXQgKHRva2VuLCBzZXBhcmF0b3IpIHtcbiAgICAgICAgYWRkRm9ybWF0VG9rZW4odG9rZW4sIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLnV0Y09mZnNldCgpO1xuICAgICAgICAgICAgdmFyIHNpZ24gPSAnKyc7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IC1vZmZzZXQ7XG4gICAgICAgICAgICAgICAgc2lnbiA9ICctJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzaWduICsgemVyb0ZpbGwofn4ob2Zmc2V0IC8gNjApLCAyKSArIHNlcGFyYXRvciArIHplcm9GaWxsKH5+KG9mZnNldCkgJSA2MCwgMik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9mZnNldCgnWicsICc6Jyk7XG4gICAgb2Zmc2V0KCdaWicsICcnKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1onLCAgbWF0Y2hTaG9ydE9mZnNldCk7XG4gICAgYWRkUmVnZXhUb2tlbignWlonLCBtYXRjaFNob3J0T2Zmc2V0KTtcbiAgICBhZGRQYXJzZVRva2VuKFsnWicsICdaWiddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgY29uZmlnLl91c2VVVEMgPSB0cnVlO1xuICAgICAgICBjb25maWcuX3R6bSA9IG9mZnNldEZyb21TdHJpbmcobWF0Y2hTaG9ydE9mZnNldCwgaW5wdXQpO1xuICAgIH0pO1xuXG4gICAgLy8gSEVMUEVSU1xuXG4gICAgLy8gdGltZXpvbmUgY2h1bmtlclxuICAgIC8vICcrMTA6MDAnID4gWycxMCcsICAnMDAnXVxuICAgIC8vICctMTUzMCcgID4gWyctMTUnLCAnMzAnXVxuICAgIHZhciBjaHVua09mZnNldCA9IC8oW1xcK1xcLV18XFxkXFxkKS9naTtcblxuICAgIGZ1bmN0aW9uIG9mZnNldEZyb21TdHJpbmcobWF0Y2hlciwgc3RyaW5nKSB7XG4gICAgICAgIHZhciBtYXRjaGVzID0gKHN0cmluZyB8fCAnJykubWF0Y2gobWF0Y2hlcik7XG5cbiAgICAgICAgaWYgKG1hdGNoZXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNodW5rICAgPSBtYXRjaGVzW21hdGNoZXMubGVuZ3RoIC0gMV0gfHwgW107XG4gICAgICAgIHZhciBwYXJ0cyAgID0gKGNodW5rICsgJycpLm1hdGNoKGNodW5rT2Zmc2V0KSB8fCBbJy0nLCAwLCAwXTtcbiAgICAgICAgdmFyIG1pbnV0ZXMgPSArKHBhcnRzWzFdICogNjApICsgdG9JbnQocGFydHNbMl0pO1xuXG4gICAgICAgIHJldHVybiBtaW51dGVzID09PSAwID9cbiAgICAgICAgICAwIDpcbiAgICAgICAgICBwYXJ0c1swXSA9PT0gJysnID8gbWludXRlcyA6IC1taW51dGVzO1xuICAgIH1cblxuICAgIC8vIFJldHVybiBhIG1vbWVudCBmcm9tIGlucHV0LCB0aGF0IGlzIGxvY2FsL3V0Yy96b25lIGVxdWl2YWxlbnQgdG8gbW9kZWwuXG4gICAgZnVuY3Rpb24gY2xvbmVXaXRoT2Zmc2V0KGlucHV0LCBtb2RlbCkge1xuICAgICAgICB2YXIgcmVzLCBkaWZmO1xuICAgICAgICBpZiAobW9kZWwuX2lzVVRDKSB7XG4gICAgICAgICAgICByZXMgPSBtb2RlbC5jbG9uZSgpO1xuICAgICAgICAgICAgZGlmZiA9IChpc01vbWVudChpbnB1dCkgfHwgaXNEYXRlKGlucHV0KSA/IGlucHV0LnZhbHVlT2YoKSA6IGNyZWF0ZUxvY2FsKGlucHV0KS52YWx1ZU9mKCkpIC0gcmVzLnZhbHVlT2YoKTtcbiAgICAgICAgICAgIC8vIFVzZSBsb3ctbGV2ZWwgYXBpLCBiZWNhdXNlIHRoaXMgZm4gaXMgbG93LWxldmVsIGFwaS5cbiAgICAgICAgICAgIHJlcy5fZC5zZXRUaW1lKHJlcy5fZC52YWx1ZU9mKCkgKyBkaWZmKTtcbiAgICAgICAgICAgIGhvb2tzLnVwZGF0ZU9mZnNldChyZXMsIGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwoaW5wdXQpLmxvY2FsKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXREYXRlT2Zmc2V0IChtKSB7XG4gICAgICAgIC8vIE9uIEZpcmVmb3guMjQgRGF0ZSNnZXRUaW1lem9uZU9mZnNldCByZXR1cm5zIGEgZmxvYXRpbmcgcG9pbnQuXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tb21lbnQvbW9tZW50L3B1bGwvMTg3MVxuICAgICAgICByZXR1cm4gLU1hdGgucm91bmQobS5fZC5nZXRUaW1lem9uZU9mZnNldCgpIC8gMTUpICogMTU7XG4gICAgfVxuXG4gICAgLy8gSE9PS1NcblxuICAgIC8vIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgd2hlbmV2ZXIgYSBtb21lbnQgaXMgbXV0YXRlZC5cbiAgICAvLyBJdCBpcyBpbnRlbmRlZCB0byBrZWVwIHRoZSBvZmZzZXQgaW4gc3luYyB3aXRoIHRoZSB0aW1lem9uZS5cbiAgICBob29rcy51cGRhdGVPZmZzZXQgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIC8vIGtlZXBMb2NhbFRpbWUgPSB0cnVlIG1lYW5zIG9ubHkgY2hhbmdlIHRoZSB0aW1lem9uZSwgd2l0aG91dFxuICAgIC8vIGFmZmVjdGluZyB0aGUgbG9jYWwgaG91ci4gU28gNTozMToyNiArMDMwMCAtLVt1dGNPZmZzZXQoMiwgdHJ1ZSldLS0+XG4gICAgLy8gNTozMToyNiArMDIwMCBJdCBpcyBwb3NzaWJsZSB0aGF0IDU6MzE6MjYgZG9lc24ndCBleGlzdCB3aXRoIG9mZnNldFxuICAgIC8vICswMjAwLCBzbyB3ZSBhZGp1c3QgdGhlIHRpbWUgYXMgbmVlZGVkLCB0byBiZSB2YWxpZC5cbiAgICAvL1xuICAgIC8vIEtlZXBpbmcgdGhlIHRpbWUgYWN0dWFsbHkgYWRkcy9zdWJ0cmFjdHMgKG9uZSBob3VyKVxuICAgIC8vIGZyb20gdGhlIGFjdHVhbCByZXByZXNlbnRlZCB0aW1lLiBUaGF0IGlzIHdoeSB3ZSBjYWxsIHVwZGF0ZU9mZnNldFxuICAgIC8vIGEgc2Vjb25kIHRpbWUuIEluIGNhc2UgaXQgd2FudHMgdXMgdG8gY2hhbmdlIHRoZSBvZmZzZXQgYWdhaW5cbiAgICAvLyBfY2hhbmdlSW5Qcm9ncmVzcyA9PSB0cnVlIGNhc2UsIHRoZW4gd2UgaGF2ZSB0byBhZGp1c3QsIGJlY2F1c2VcbiAgICAvLyB0aGVyZSBpcyBubyBzdWNoIHRpbWUgaW4gdGhlIGdpdmVuIHRpbWV6b25lLlxuICAgIGZ1bmN0aW9uIGdldFNldE9mZnNldCAoaW5wdXQsIGtlZXBMb2NhbFRpbWUsIGtlZXBNaW51dGVzKSB7XG4gICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLl9vZmZzZXQgfHwgMCxcbiAgICAgICAgICAgIGxvY2FsQWRqdXN0O1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgIT0gbnVsbCA/IHRoaXMgOiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSBvZmZzZXRGcm9tU3RyaW5nKG1hdGNoU2hvcnRPZmZzZXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChNYXRoLmFicyhpbnB1dCkgPCAxNiAmJiAha2VlcE1pbnV0ZXMpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IGlucHV0ICogNjA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuX2lzVVRDICYmIGtlZXBMb2NhbFRpbWUpIHtcbiAgICAgICAgICAgICAgICBsb2NhbEFkanVzdCA9IGdldERhdGVPZmZzZXQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9vZmZzZXQgPSBpbnB1dDtcbiAgICAgICAgICAgIHRoaXMuX2lzVVRDID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChsb2NhbEFkanVzdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGQobG9jYWxBZGp1c3QsICdtJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2Zmc2V0ICE9PSBpbnB1dCkge1xuICAgICAgICAgICAgICAgIGlmICgha2VlcExvY2FsVGltZSB8fCB0aGlzLl9jaGFuZ2VJblByb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZFN1YnRyYWN0KHRoaXMsIGNyZWF0ZUR1cmF0aW9uKGlucHV0IC0gb2Zmc2V0LCAnbScpLCAxLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5fY2hhbmdlSW5Qcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/IG9mZnNldCA6IGdldERhdGVPZmZzZXQodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRab25lIChpbnB1dCwga2VlcExvY2FsVGltZSkge1xuICAgICAgICBpZiAoaW5wdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IC1pbnB1dDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoaW5wdXQsIGtlZXBMb2NhbFRpbWUpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAtdGhpcy51dGNPZmZzZXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldE9mZnNldFRvVVRDIChrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnV0Y09mZnNldCgwLCBrZWVwTG9jYWxUaW1lKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRPZmZzZXRUb0xvY2FsIChrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9pc1VUQykge1xuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoMCwga2VlcExvY2FsVGltZSk7XG4gICAgICAgICAgICB0aGlzLl9pc1VUQyA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoa2VlcExvY2FsVGltZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3VidHJhY3QoZ2V0RGF0ZU9mZnNldCh0aGlzKSwgJ20nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRPZmZzZXRUb1BhcnNlZE9mZnNldCAoKSB7XG4gICAgICAgIGlmICh0aGlzLl90em0gIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQodGhpcy5fdHptLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuX2kgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB2YXIgdFpvbmUgPSBvZmZzZXRGcm9tU3RyaW5nKG1hdGNoT2Zmc2V0LCB0aGlzLl9pKTtcbiAgICAgICAgICAgIGlmICh0Wm9uZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQodFpvbmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoMCwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzQWxpZ25lZEhvdXJPZmZzZXQgKGlucHV0KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dCA9IGlucHV0ID8gY3JlYXRlTG9jYWwoaW5wdXQpLnV0Y09mZnNldCgpIDogMDtcblxuICAgICAgICByZXR1cm4gKHRoaXMudXRjT2Zmc2V0KCkgLSBpbnB1dCkgJSA2MCA9PT0gMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0RheWxpZ2h0U2F2aW5nVGltZSAoKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLnV0Y09mZnNldCgpID4gdGhpcy5jbG9uZSgpLm1vbnRoKDApLnV0Y09mZnNldCgpIHx8XG4gICAgICAgICAgICB0aGlzLnV0Y09mZnNldCgpID4gdGhpcy5jbG9uZSgpLm1vbnRoKDUpLnV0Y09mZnNldCgpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEYXlsaWdodFNhdmluZ1RpbWVTaGlmdGVkICgpIHtcbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9pc0RTVFNoaWZ0ZWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faXNEU1RTaGlmdGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGMgPSB7fTtcblxuICAgICAgICBjb3B5Q29uZmlnKGMsIHRoaXMpO1xuICAgICAgICBjID0gcHJlcGFyZUNvbmZpZyhjKTtcblxuICAgICAgICBpZiAoYy5fYSkge1xuICAgICAgICAgICAgdmFyIG90aGVyID0gYy5faXNVVEMgPyBjcmVhdGVVVEMoYy5fYSkgOiBjcmVhdGVMb2NhbChjLl9hKTtcbiAgICAgICAgICAgIHRoaXMuX2lzRFNUU2hpZnRlZCA9IHRoaXMuaXNWYWxpZCgpICYmXG4gICAgICAgICAgICAgICAgY29tcGFyZUFycmF5cyhjLl9hLCBvdGhlci50b0FycmF5KCkpID4gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2lzRFNUU2hpZnRlZCA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzRFNUU2hpZnRlZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0xvY2FsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gIXRoaXMuX2lzVVRDIDogZmFsc2U7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNVdGNPZmZzZXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1ZhbGlkKCkgPyB0aGlzLl9pc1VUQyA6IGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVXRjICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpcy5faXNVVEMgJiYgdGhpcy5fb2Zmc2V0ID09PSAwIDogZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQVNQLk5FVCBqc29uIGRhdGUgZm9ybWF0IHJlZ2V4XG4gICAgdmFyIGFzcE5ldFJlZ2V4ID0gL14oXFwtfFxcKyk/KD86KFxcZCopWy4gXSk/KFxcZCspXFw6KFxcZCspKD86XFw6KFxcZCspKFxcLlxcZCopPyk/JC87XG5cbiAgICAvLyBmcm9tIGh0dHA6Ly9kb2NzLmNsb3N1cmUtbGlicmFyeS5nb29nbGVjb2RlLmNvbS9naXQvY2xvc3VyZV9nb29nX2RhdGVfZGF0ZS5qcy5zb3VyY2UuaHRtbFxuICAgIC8vIHNvbWV3aGF0IG1vcmUgaW4gbGluZSB3aXRoIDQuNC4zLjIgMjAwNCBzcGVjLCBidXQgYWxsb3dzIGRlY2ltYWwgYW55d2hlcmVcbiAgICAvLyBhbmQgZnVydGhlciBtb2RpZmllZCB0byBhbGxvdyBmb3Igc3RyaW5ncyBjb250YWluaW5nIGJvdGggd2VlayBhbmQgZGF5XG4gICAgdmFyIGlzb1JlZ2V4ID0gL14oLXxcXCspP1AoPzooWy0rXT9bMC05LC5dKilZKT8oPzooWy0rXT9bMC05LC5dKilNKT8oPzooWy0rXT9bMC05LC5dKilXKT8oPzooWy0rXT9bMC05LC5dKilEKT8oPzpUKD86KFstK10/WzAtOSwuXSopSCk/KD86KFstK10/WzAtOSwuXSopTSk/KD86KFstK10/WzAtOSwuXSopUyk/KT8kLztcblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUR1cmF0aW9uIChpbnB1dCwga2V5KSB7XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IGlucHV0LFxuICAgICAgICAgICAgLy8gbWF0Y2hpbmcgYWdhaW5zdCByZWdleHAgaXMgZXhwZW5zaXZlLCBkbyBpdCBvbiBkZW1hbmRcbiAgICAgICAgICAgIG1hdGNoID0gbnVsbCxcbiAgICAgICAgICAgIHNpZ24sXG4gICAgICAgICAgICByZXQsXG4gICAgICAgICAgICBkaWZmUmVzO1xuXG4gICAgICAgIGlmIChpc0R1cmF0aW9uKGlucHV0KSkge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgbXMgOiBpbnB1dC5fbWlsbGlzZWNvbmRzLFxuICAgICAgICAgICAgICAgIGQgIDogaW5wdXQuX2RheXMsXG4gICAgICAgICAgICAgICAgTSAgOiBpbnB1dC5fbW9udGhzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKGlucHV0KSkge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbltrZXldID0gaW5wdXQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uLm1pbGxpc2Vjb25kcyA9IGlucHV0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEhKG1hdGNoID0gYXNwTmV0UmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeSAgOiAwLFxuICAgICAgICAgICAgICAgIGQgIDogdG9JbnQobWF0Y2hbREFURV0pICAgICAgICAgICAgICAgICAgICAgICAgICogc2lnbixcbiAgICAgICAgICAgICAgICBoICA6IHRvSW50KG1hdGNoW0hPVVJdKSAgICAgICAgICAgICAgICAgICAgICAgICAqIHNpZ24sXG4gICAgICAgICAgICAgICAgbSAgOiB0b0ludChtYXRjaFtNSU5VVEVdKSAgICAgICAgICAgICAgICAgICAgICAgKiBzaWduLFxuICAgICAgICAgICAgICAgIHMgIDogdG9JbnQobWF0Y2hbU0VDT05EXSkgICAgICAgICAgICAgICAgICAgICAgICogc2lnbixcbiAgICAgICAgICAgICAgICBtcyA6IHRvSW50KGFic1JvdW5kKG1hdGNoW01JTExJU0VDT05EXSAqIDEwMDApKSAqIHNpZ24gLy8gdGhlIG1pbGxpc2Vjb25kIGRlY2ltYWwgcG9pbnQgaXMgaW5jbHVkZWQgaW4gdGhlIG1hdGNoXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKCEhKG1hdGNoID0gaXNvUmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeSA6IHBhcnNlSXNvKG1hdGNoWzJdLCBzaWduKSxcbiAgICAgICAgICAgICAgICBNIDogcGFyc2VJc28obWF0Y2hbM10sIHNpZ24pLFxuICAgICAgICAgICAgICAgIHcgOiBwYXJzZUlzbyhtYXRjaFs0XSwgc2lnbiksXG4gICAgICAgICAgICAgICAgZCA6IHBhcnNlSXNvKG1hdGNoWzVdLCBzaWduKSxcbiAgICAgICAgICAgICAgICBoIDogcGFyc2VJc28obWF0Y2hbNl0sIHNpZ24pLFxuICAgICAgICAgICAgICAgIG0gOiBwYXJzZUlzbyhtYXRjaFs3XSwgc2lnbiksXG4gICAgICAgICAgICAgICAgcyA6IHBhcnNlSXNvKG1hdGNoWzhdLCBzaWduKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmIChkdXJhdGlvbiA9PSBudWxsKSB7Ly8gY2hlY2tzIGZvciBudWxsIG9yIHVuZGVmaW5lZFxuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZHVyYXRpb24gPT09ICdvYmplY3QnICYmICgnZnJvbScgaW4gZHVyYXRpb24gfHwgJ3RvJyBpbiBkdXJhdGlvbikpIHtcbiAgICAgICAgICAgIGRpZmZSZXMgPSBtb21lbnRzRGlmZmVyZW5jZShjcmVhdGVMb2NhbChkdXJhdGlvbi5mcm9tKSwgY3JlYXRlTG9jYWwoZHVyYXRpb24udG8pKTtcblxuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGR1cmF0aW9uLm1zID0gZGlmZlJlcy5taWxsaXNlY29uZHM7XG4gICAgICAgICAgICBkdXJhdGlvbi5NID0gZGlmZlJlcy5tb250aHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXQgPSBuZXcgRHVyYXRpb24oZHVyYXRpb24pO1xuXG4gICAgICAgIGlmIChpc0R1cmF0aW9uKGlucHV0KSAmJiBoYXNPd25Qcm9wKGlucHV0LCAnX2xvY2FsZScpKSB7XG4gICAgICAgICAgICByZXQuX2xvY2FsZSA9IGlucHV0Ll9sb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIGNyZWF0ZUR1cmF0aW9uLmZuID0gRHVyYXRpb24ucHJvdG90eXBlO1xuICAgIGNyZWF0ZUR1cmF0aW9uLmludmFsaWQgPSBjcmVhdGVJbnZhbGlkJDE7XG5cbiAgICBmdW5jdGlvbiBwYXJzZUlzbyAoaW5wLCBzaWduKSB7XG4gICAgICAgIC8vIFdlJ2Qgbm9ybWFsbHkgdXNlIH5+aW5wIGZvciB0aGlzLCBidXQgdW5mb3J0dW5hdGVseSBpdCBhbHNvXG4gICAgICAgIC8vIGNvbnZlcnRzIGZsb2F0cyB0byBpbnRzLlxuICAgICAgICAvLyBpbnAgbWF5IGJlIHVuZGVmaW5lZCwgc28gY2FyZWZ1bCBjYWxsaW5nIHJlcGxhY2Ugb24gaXQuXG4gICAgICAgIHZhciByZXMgPSBpbnAgJiYgcGFyc2VGbG9hdChpbnAucmVwbGFjZSgnLCcsICcuJykpO1xuICAgICAgICAvLyBhcHBseSBzaWduIHdoaWxlIHdlJ3JlIGF0IGl0XG4gICAgICAgIHJldHVybiAoaXNOYU4ocmVzKSA/IDAgOiByZXMpICogc2lnbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKSB7XG4gICAgICAgIHZhciByZXMgPSB7fTtcblxuICAgICAgICByZXMubW9udGhzID0gb3RoZXIubW9udGgoKSAtIGJhc2UubW9udGgoKSArXG4gICAgICAgICAgICAob3RoZXIueWVhcigpIC0gYmFzZS55ZWFyKCkpICogMTI7XG4gICAgICAgIGlmIChiYXNlLmNsb25lKCkuYWRkKHJlcy5tb250aHMsICdNJykuaXNBZnRlcihvdGhlcikpIHtcbiAgICAgICAgICAgIC0tcmVzLm1vbnRocztcbiAgICAgICAgfVxuXG4gICAgICAgIHJlcy5taWxsaXNlY29uZHMgPSArb3RoZXIgLSArKGJhc2UuY2xvbmUoKS5hZGQocmVzLm1vbnRocywgJ00nKSk7XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb21lbnRzRGlmZmVyZW5jZShiYXNlLCBvdGhlcikge1xuICAgICAgICB2YXIgcmVzO1xuICAgICAgICBpZiAoIShiYXNlLmlzVmFsaWQoKSAmJiBvdGhlci5pc1ZhbGlkKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4ge21pbGxpc2Vjb25kczogMCwgbW9udGhzOiAwfTtcbiAgICAgICAgfVxuXG4gICAgICAgIG90aGVyID0gY2xvbmVXaXRoT2Zmc2V0KG90aGVyLCBiYXNlKTtcbiAgICAgICAgaWYgKGJhc2UuaXNCZWZvcmUob3RoZXIpKSB7XG4gICAgICAgICAgICByZXMgPSBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcyA9IHBvc2l0aXZlTW9tZW50c0RpZmZlcmVuY2Uob3RoZXIsIGJhc2UpO1xuICAgICAgICAgICAgcmVzLm1pbGxpc2Vjb25kcyA9IC1yZXMubWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgcmVzLm1vbnRocyA9IC1yZXMubW9udGhzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvLyBUT0RPOiByZW1vdmUgJ25hbWUnIGFyZyBhZnRlciBkZXByZWNhdGlvbiBpcyByZW1vdmVkXG4gICAgZnVuY3Rpb24gY3JlYXRlQWRkZXIoZGlyZWN0aW9uLCBuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsLCBwZXJpb2QpIHtcbiAgICAgICAgICAgIHZhciBkdXIsIHRtcDtcbiAgICAgICAgICAgIC8vaW52ZXJ0IHRoZSBhcmd1bWVudHMsIGJ1dCBjb21wbGFpbiBhYm91dCBpdFxuICAgICAgICAgICAgaWYgKHBlcmlvZCAhPT0gbnVsbCAmJiAhaXNOYU4oK3BlcmlvZCkpIHtcbiAgICAgICAgICAgICAgICBkZXByZWNhdGVTaW1wbGUobmFtZSwgJ21vbWVudCgpLicgKyBuYW1lICArICcocGVyaW9kLCBudW1iZXIpIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgbW9tZW50KCkuJyArIG5hbWUgKyAnKG51bWJlciwgcGVyaW9kKS4gJyArXG4gICAgICAgICAgICAgICAgJ1NlZSBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2FkZC1pbnZlcnRlZC1wYXJhbS8gZm9yIG1vcmUgaW5mby4nKTtcbiAgICAgICAgICAgICAgICB0bXAgPSB2YWw7IHZhbCA9IHBlcmlvZDsgcGVyaW9kID0gdG1wO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YWwgPSB0eXBlb2YgdmFsID09PSAnc3RyaW5nJyA/ICt2YWwgOiB2YWw7XG4gICAgICAgICAgICBkdXIgPSBjcmVhdGVEdXJhdGlvbih2YWwsIHBlcmlvZCk7XG4gICAgICAgICAgICBhZGRTdWJ0cmFjdCh0aGlzLCBkdXIsIGRpcmVjdGlvbik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRTdWJ0cmFjdCAobW9tLCBkdXJhdGlvbiwgaXNBZGRpbmcsIHVwZGF0ZU9mZnNldCkge1xuICAgICAgICB2YXIgbWlsbGlzZWNvbmRzID0gZHVyYXRpb24uX21pbGxpc2Vjb25kcyxcbiAgICAgICAgICAgIGRheXMgPSBhYnNSb3VuZChkdXJhdGlvbi5fZGF5cyksXG4gICAgICAgICAgICBtb250aHMgPSBhYnNSb3VuZChkdXJhdGlvbi5fbW9udGhzKTtcblxuICAgICAgICBpZiAoIW1vbS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIC8vIE5vIG9wXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB1cGRhdGVPZmZzZXQgPSB1cGRhdGVPZmZzZXQgPT0gbnVsbCA/IHRydWUgOiB1cGRhdGVPZmZzZXQ7XG5cbiAgICAgICAgaWYgKG1vbnRocykge1xuICAgICAgICAgICAgc2V0TW9udGgobW9tLCBnZXQobW9tLCAnTW9udGgnKSArIG1vbnRocyAqIGlzQWRkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF5cykge1xuICAgICAgICAgICAgc2V0JDEobW9tLCAnRGF0ZScsIGdldChtb20sICdEYXRlJykgKyBkYXlzICogaXNBZGRpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtaWxsaXNlY29uZHMpIHtcbiAgICAgICAgICAgIG1vbS5fZC5zZXRUaW1lKG1vbS5fZC52YWx1ZU9mKCkgKyBtaWxsaXNlY29uZHMgKiBpc0FkZGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVwZGF0ZU9mZnNldCkge1xuICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KG1vbSwgZGF5cyB8fCBtb250aHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGFkZCAgICAgID0gY3JlYXRlQWRkZXIoMSwgJ2FkZCcpO1xuICAgIHZhciBzdWJ0cmFjdCA9IGNyZWF0ZUFkZGVyKC0xLCAnc3VidHJhY3QnKTtcblxuICAgIGZ1bmN0aW9uIGdldENhbGVuZGFyRm9ybWF0KG15TW9tZW50LCBub3cpIHtcbiAgICAgICAgdmFyIGRpZmYgPSBteU1vbWVudC5kaWZmKG5vdywgJ2RheXMnLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIGRpZmYgPCAtNiA/ICdzYW1lRWxzZScgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCAtMSA/ICdsYXN0V2VlaycgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCAwID8gJ2xhc3REYXknIDpcbiAgICAgICAgICAgICAgICBkaWZmIDwgMSA/ICdzYW1lRGF5JyA6XG4gICAgICAgICAgICAgICAgZGlmZiA8IDIgPyAnbmV4dERheScgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCA3ID8gJ25leHRXZWVrJyA6ICdzYW1lRWxzZSc7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsZW5kYXIkMSAodGltZSwgZm9ybWF0cykge1xuICAgICAgICAvLyBXZSB3YW50IHRvIGNvbXBhcmUgdGhlIHN0YXJ0IG9mIHRvZGF5LCB2cyB0aGlzLlxuICAgICAgICAvLyBHZXR0aW5nIHN0YXJ0LW9mLXRvZGF5IGRlcGVuZHMgb24gd2hldGhlciB3ZSdyZSBsb2NhbC91dGMvb2Zmc2V0IG9yIG5vdC5cbiAgICAgICAgdmFyIG5vdyA9IHRpbWUgfHwgY3JlYXRlTG9jYWwoKSxcbiAgICAgICAgICAgIHNvZCA9IGNsb25lV2l0aE9mZnNldChub3csIHRoaXMpLnN0YXJ0T2YoJ2RheScpLFxuICAgICAgICAgICAgZm9ybWF0ID0gaG9va3MuY2FsZW5kYXJGb3JtYXQodGhpcywgc29kKSB8fCAnc2FtZUVsc2UnO1xuXG4gICAgICAgIHZhciBvdXRwdXQgPSBmb3JtYXRzICYmIChpc0Z1bmN0aW9uKGZvcm1hdHNbZm9ybWF0XSkgPyBmb3JtYXRzW2Zvcm1hdF0uY2FsbCh0aGlzLCBub3cpIDogZm9ybWF0c1tmb3JtYXRdKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXQob3V0cHV0IHx8IHRoaXMubG9jYWxlRGF0YSgpLmNhbGVuZGFyKGZvcm1hdCwgdGhpcywgY3JlYXRlTG9jYWwobm93KSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsb25lICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBNb21lbnQodGhpcyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBZnRlciAoaW5wdXQsIHVuaXRzKSB7XG4gICAgICAgIHZhciBsb2NhbElucHV0ID0gaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBjcmVhdGVMb2NhbChpbnB1dCk7XG4gICAgICAgIGlmICghKHRoaXMuaXNWYWxpZCgpICYmIGxvY2FsSW5wdXQuaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpIHx8ICdtaWxsaXNlY29uZCc7XG4gICAgICAgIGlmICh1bml0cyA9PT0gJ21pbGxpc2Vjb25kJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpID4gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbG9jYWxJbnB1dC52YWx1ZU9mKCkgPCB0aGlzLmNsb25lKCkuc3RhcnRPZih1bml0cykudmFsdWVPZigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNCZWZvcmUgKGlucHV0LCB1bml0cykge1xuICAgICAgICB2YXIgbG9jYWxJbnB1dCA9IGlzTW9tZW50KGlucHV0KSA/IGlucHV0IDogY3JlYXRlTG9jYWwoaW5wdXQpO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbElucHV0LmlzVmFsaWQoKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB8fCAnbWlsbGlzZWNvbmQnO1xuICAgICAgICBpZiAodW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKSA8IGxvY2FsSW5wdXQudmFsdWVPZigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmRPZih1bml0cykudmFsdWVPZigpIDwgbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0JldHdlZW4gKGZyb20sIHRvLCB1bml0cywgaW5jbHVzaXZpdHkpIHtcbiAgICAgICAgdmFyIGxvY2FsRnJvbSA9IGlzTW9tZW50KGZyb20pID8gZnJvbSA6IGNyZWF0ZUxvY2FsKGZyb20pLFxuICAgICAgICAgICAgbG9jYWxUbyA9IGlzTW9tZW50KHRvKSA/IHRvIDogY3JlYXRlTG9jYWwodG8pO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbEZyb20uaXNWYWxpZCgpICYmIGxvY2FsVG8uaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGluY2x1c2l2aXR5ID0gaW5jbHVzaXZpdHkgfHwgJygpJztcbiAgICAgICAgcmV0dXJuIChpbmNsdXNpdml0eVswXSA9PT0gJygnID8gdGhpcy5pc0FmdGVyKGxvY2FsRnJvbSwgdW5pdHMpIDogIXRoaXMuaXNCZWZvcmUobG9jYWxGcm9tLCB1bml0cykpICYmXG4gICAgICAgICAgICAoaW5jbHVzaXZpdHlbMV0gPT09ICcpJyA/IHRoaXMuaXNCZWZvcmUobG9jYWxUbywgdW5pdHMpIDogIXRoaXMuaXNBZnRlcihsb2NhbFRvLCB1bml0cykpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzU2FtZSAoaW5wdXQsIHVuaXRzKSB7XG4gICAgICAgIHZhciBsb2NhbElucHV0ID0gaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBjcmVhdGVMb2NhbChpbnB1dCksXG4gICAgICAgICAgICBpbnB1dE1zO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbElucHV0LmlzVmFsaWQoKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB8fCAnbWlsbGlzZWNvbmQnO1xuICAgICAgICBpZiAodW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKSA9PT0gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbnB1dE1zID0gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jbG9uZSgpLnN0YXJ0T2YodW5pdHMpLnZhbHVlT2YoKSA8PSBpbnB1dE1zICYmIGlucHV0TXMgPD0gdGhpcy5jbG9uZSgpLmVuZE9mKHVuaXRzKS52YWx1ZU9mKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1NhbWVPckFmdGVyIChpbnB1dCwgdW5pdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNTYW1lKGlucHV0LCB1bml0cykgfHwgdGhpcy5pc0FmdGVyKGlucHV0LCB1bml0cyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNTYW1lT3JCZWZvcmUgKGlucHV0LCB1bml0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1NhbWUoaW5wdXQsIHVuaXRzKSB8fCB0aGlzLmlzQmVmb3JlKGlucHV0LCB1bml0cyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGlmZiAoaW5wdXQsIHVuaXRzLCBhc0Zsb2F0KSB7XG4gICAgICAgIHZhciB0aGF0LFxuICAgICAgICAgICAgem9uZURlbHRhLFxuICAgICAgICAgICAgb3V0cHV0O1xuXG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgIH1cblxuICAgICAgICB0aGF0ID0gY2xvbmVXaXRoT2Zmc2V0KGlucHV0LCB0aGlzKTtcblxuICAgICAgICBpZiAoIXRoYXQuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG5cbiAgICAgICAgem9uZURlbHRhID0gKHRoYXQudXRjT2Zmc2V0KCkgLSB0aGlzLnV0Y09mZnNldCgpKSAqIDZlNDtcblxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzogb3V0cHV0ID0gbW9udGhEaWZmKHRoaXMsIHRoYXQpIC8gMTI7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOiBvdXRwdXQgPSBtb250aERpZmYodGhpcywgdGhhdCk7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6IG91dHB1dCA9IG1vbnRoRGlmZih0aGlzLCB0aGF0KSAvIDM7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzogb3V0cHV0ID0gKHRoaXMgLSB0aGF0KSAvIDFlMzsgYnJlYWs7IC8vIDEwMDBcbiAgICAgICAgICAgIGNhc2UgJ21pbnV0ZSc6IG91dHB1dCA9ICh0aGlzIC0gdGhhdCkgLyA2ZTQ7IGJyZWFrOyAvLyAxMDAwICogNjBcbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOiBvdXRwdXQgPSAodGhpcyAtIHRoYXQpIC8gMzZlNTsgYnJlYWs7IC8vIDEwMDAgKiA2MCAqIDYwXG4gICAgICAgICAgICBjYXNlICdkYXknOiBvdXRwdXQgPSAodGhpcyAtIHRoYXQgLSB6b25lRGVsdGEpIC8gODY0ZTU7IGJyZWFrOyAvLyAxMDAwICogNjAgKiA2MCAqIDI0LCBuZWdhdGUgZHN0XG4gICAgICAgICAgICBjYXNlICd3ZWVrJzogb3V0cHV0ID0gKHRoaXMgLSB0aGF0IC0gem9uZURlbHRhKSAvIDYwNDhlNTsgYnJlYWs7IC8vIDEwMDAgKiA2MCAqIDYwICogMjQgKiA3LCBuZWdhdGUgZHN0XG4gICAgICAgICAgICBkZWZhdWx0OiBvdXRwdXQgPSB0aGlzIC0gdGhhdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhc0Zsb2F0ID8gb3V0cHV0IDogYWJzRmxvb3Iob3V0cHV0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb250aERpZmYgKGEsIGIpIHtcbiAgICAgICAgLy8gZGlmZmVyZW5jZSBpbiBtb250aHNcbiAgICAgICAgdmFyIHdob2xlTW9udGhEaWZmID0gKChiLnllYXIoKSAtIGEueWVhcigpKSAqIDEyKSArIChiLm1vbnRoKCkgLSBhLm1vbnRoKCkpLFxuICAgICAgICAgICAgLy8gYiBpcyBpbiAoYW5jaG9yIC0gMSBtb250aCwgYW5jaG9yICsgMSBtb250aClcbiAgICAgICAgICAgIGFuY2hvciA9IGEuY2xvbmUoKS5hZGQod2hvbGVNb250aERpZmYsICdtb250aHMnKSxcbiAgICAgICAgICAgIGFuY2hvcjIsIGFkanVzdDtcblxuICAgICAgICBpZiAoYiAtIGFuY2hvciA8IDApIHtcbiAgICAgICAgICAgIGFuY2hvcjIgPSBhLmNsb25lKCkuYWRkKHdob2xlTW9udGhEaWZmIC0gMSwgJ21vbnRocycpO1xuICAgICAgICAgICAgLy8gbGluZWFyIGFjcm9zcyB0aGUgbW9udGhcbiAgICAgICAgICAgIGFkanVzdCA9IChiIC0gYW5jaG9yKSAvIChhbmNob3IgLSBhbmNob3IyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFuY2hvcjIgPSBhLmNsb25lKCkuYWRkKHdob2xlTW9udGhEaWZmICsgMSwgJ21vbnRocycpO1xuICAgICAgICAgICAgLy8gbGluZWFyIGFjcm9zcyB0aGUgbW9udGhcbiAgICAgICAgICAgIGFkanVzdCA9IChiIC0gYW5jaG9yKSAvIChhbmNob3IyIC0gYW5jaG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vY2hlY2sgZm9yIG5lZ2F0aXZlIHplcm8sIHJldHVybiB6ZXJvIGlmIG5lZ2F0aXZlIHplcm9cbiAgICAgICAgcmV0dXJuIC0od2hvbGVNb250aERpZmYgKyBhZGp1c3QpIHx8IDA7XG4gICAgfVxuXG4gICAgaG9va3MuZGVmYXVsdEZvcm1hdCA9ICdZWVlZLU1NLUREVEhIOm1tOnNzWic7XG4gICAgaG9va3MuZGVmYXVsdEZvcm1hdFV0YyA9ICdZWVlZLU1NLUREVEhIOm1tOnNzW1pdJztcblxuICAgIGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5sb2NhbGUoJ2VuJykuZm9ybWF0KCdkZGQgTU1NIEREIFlZWVkgSEg6bW06c3MgW0dNVF1aWicpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvSVNPU3RyaW5nKGtlZXBPZmZzZXQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHV0YyA9IGtlZXBPZmZzZXQgIT09IHRydWU7XG4gICAgICAgIHZhciBtID0gdXRjID8gdGhpcy5jbG9uZSgpLnV0YygpIDogdGhpcztcbiAgICAgICAgaWYgKG0ueWVhcigpIDwgMCB8fCBtLnllYXIoKSA+IDk5OTkpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXRNb21lbnQobSwgdXRjID8gJ1lZWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1taXScgOiAnWVlZWVlZLU1NLUREW1RdSEg6bW06c3MuU1NTWicpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nKSkge1xuICAgICAgICAgICAgLy8gbmF0aXZlIGltcGxlbWVudGF0aW9uIGlzIH41MHggZmFzdGVyLCB1c2UgaXQgd2hlbiB3ZSBjYW5cbiAgICAgICAgICAgIGlmICh1dGMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0RhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkgKyB0aGlzLnV0Y09mZnNldCgpICogNjAgKiAxMDAwKS50b0lTT1N0cmluZygpLnJlcGxhY2UoJ1onLCBmb3JtYXRNb21lbnQobSwgJ1onKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdE1vbWVudChtLCB1dGMgPyAnWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1taXScgOiAnWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1onKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gYSBodW1hbiByZWFkYWJsZSByZXByZXNlbnRhdGlvbiBvZiBhIG1vbWVudCB0aGF0IGNhblxuICAgICAqIGFsc28gYmUgZXZhbHVhdGVkIHRvIGdldCBhIG5ldyBtb21lbnQgd2hpY2ggaXMgdGhlIHNhbWVcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHBzOi8vbm9kZWpzLm9yZy9kaXN0L2xhdGVzdC9kb2NzL2FwaS91dGlsLmh0bWwjdXRpbF9jdXN0b21faW5zcGVjdF9mdW5jdGlvbl9vbl9vYmplY3RzXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiAnbW9tZW50LmludmFsaWQoLyogJyArIHRoaXMuX2kgKyAnICovKSc7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZ1bmMgPSAnbW9tZW50JztcbiAgICAgICAgdmFyIHpvbmUgPSAnJztcbiAgICAgICAgaWYgKCF0aGlzLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgZnVuYyA9IHRoaXMudXRjT2Zmc2V0KCkgPT09IDAgPyAnbW9tZW50LnV0YycgOiAnbW9tZW50LnBhcnNlWm9uZSc7XG4gICAgICAgICAgICB6b25lID0gJ1onO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcmVmaXggPSAnWycgKyBmdW5jICsgJyhcIl0nO1xuICAgICAgICB2YXIgeWVhciA9ICgwIDw9IHRoaXMueWVhcigpICYmIHRoaXMueWVhcigpIDw9IDk5OTkpID8gJ1lZWVknIDogJ1lZWVlZWSc7XG4gICAgICAgIHZhciBkYXRldGltZSA9ICctTU0tRERbVF1ISDptbTpzcy5TU1MnO1xuICAgICAgICB2YXIgc3VmZml4ID0gem9uZSArICdbXCIpXSc7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0KHByZWZpeCArIHllYXIgKyBkYXRldGltZSArIHN1ZmZpeCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0IChpbnB1dFN0cmluZykge1xuICAgICAgICBpZiAoIWlucHV0U3RyaW5nKSB7XG4gICAgICAgICAgICBpbnB1dFN0cmluZyA9IHRoaXMuaXNVdGMoKSA/IGhvb2tzLmRlZmF1bHRGb3JtYXRVdGMgOiBob29rcy5kZWZhdWx0Rm9ybWF0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBvdXRwdXQgPSBmb3JtYXRNb21lbnQodGhpcywgaW5wdXRTdHJpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkucG9zdGZvcm1hdChvdXRwdXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZyb20gKHRpbWUsIHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNWYWxpZCgpICYmXG4gICAgICAgICAgICAgICAgKChpc01vbWVudCh0aW1lKSAmJiB0aW1lLmlzVmFsaWQoKSkgfHxcbiAgICAgICAgICAgICAgICAgY3JlYXRlTG9jYWwodGltZSkuaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKHt0bzogdGhpcywgZnJvbTogdGltZX0pLmxvY2FsZSh0aGlzLmxvY2FsZSgpKS5odW1hbml6ZSghd2l0aG91dFN1ZmZpeCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkuaW52YWxpZERhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZyb21Ob3cgKHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbShjcmVhdGVMb2NhbCgpLCB3aXRob3V0U3VmZml4KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0byAodGltZSwgd2l0aG91dFN1ZmZpeCkge1xuICAgICAgICBpZiAodGhpcy5pc1ZhbGlkKCkgJiZcbiAgICAgICAgICAgICAgICAoKGlzTW9tZW50KHRpbWUpICYmIHRpbWUuaXNWYWxpZCgpKSB8fFxuICAgICAgICAgICAgICAgICBjcmVhdGVMb2NhbCh0aW1lKS5pc1ZhbGlkKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlRHVyYXRpb24oe2Zyb206IHRoaXMsIHRvOiB0aW1lfSkubG9jYWxlKHRoaXMubG9jYWxlKCkpLmh1bWFuaXplKCF3aXRob3V0U3VmZml4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS5pbnZhbGlkRGF0ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9Ob3cgKHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG8oY3JlYXRlTG9jYWwoKSwgd2l0aG91dFN1ZmZpeCk7XG4gICAgfVxuXG4gICAgLy8gSWYgcGFzc2VkIGEgbG9jYWxlIGtleSwgaXQgd2lsbCBzZXQgdGhlIGxvY2FsZSBmb3IgdGhpc1xuICAgIC8vIGluc3RhbmNlLiAgT3RoZXJ3aXNlLCBpdCB3aWxsIHJldHVybiB0aGUgbG9jYWxlIGNvbmZpZ3VyYXRpb25cbiAgICAvLyB2YXJpYWJsZXMgZm9yIHRoaXMgaW5zdGFuY2UuXG4gICAgZnVuY3Rpb24gbG9jYWxlIChrZXkpIHtcbiAgICAgICAgdmFyIG5ld0xvY2FsZURhdGE7XG5cbiAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlLl9hYmJyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3TG9jYWxlRGF0YSA9IGdldExvY2FsZShrZXkpO1xuICAgICAgICAgICAgaWYgKG5ld0xvY2FsZURhdGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvY2FsZSA9IG5ld0xvY2FsZURhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBsYW5nID0gZGVwcmVjYXRlKFxuICAgICAgICAnbW9tZW50KCkubGFuZygpIGlzIGRlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZSBtb21lbnQoKS5sb2NhbGVEYXRhKCkgdG8gZ2V0IHRoZSBsYW5ndWFnZSBjb25maWd1cmF0aW9uLiBVc2UgbW9tZW50KCkubG9jYWxlKCkgdG8gY2hhbmdlIGxhbmd1YWdlcy4nLFxuICAgICAgICBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZShrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIGZ1bmN0aW9uIGxvY2FsZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlO1xuICAgIH1cblxuICAgIHZhciBNU19QRVJfU0VDT05EID0gMTAwMDtcbiAgICB2YXIgTVNfUEVSX01JTlVURSA9IDYwICogTVNfUEVSX1NFQ09ORDtcbiAgICB2YXIgTVNfUEVSX0hPVVIgPSA2MCAqIE1TX1BFUl9NSU5VVEU7XG4gICAgdmFyIE1TX1BFUl80MDBfWUVBUlMgPSAoMzY1ICogNDAwICsgOTcpICogMjQgKiBNU19QRVJfSE9VUjtcblxuICAgIC8vIGFjdHVhbCBtb2R1bG8gLSBoYW5kbGVzIG5lZ2F0aXZlIG51bWJlcnMgKGZvciBkYXRlcyBiZWZvcmUgMTk3MCk6XG4gICAgZnVuY3Rpb24gbW9kJDEoZGl2aWRlbmQsIGRpdmlzb3IpIHtcbiAgICAgICAgcmV0dXJuIChkaXZpZGVuZCAlIGRpdmlzb3IgKyBkaXZpc29yKSAlIGRpdmlzb3I7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9jYWxTdGFydE9mRGF0ZSh5LCBtLCBkKSB7XG4gICAgICAgIC8vIHRoZSBkYXRlIGNvbnN0cnVjdG9yIHJlbWFwcyB5ZWFycyAwLTk5IHRvIDE5MDAtMTk5OVxuICAgICAgICBpZiAoeSA8IDEwMCAmJiB5ID49IDApIHtcbiAgICAgICAgICAgIC8vIHByZXNlcnZlIGxlYXAgeWVhcnMgdXNpbmcgYSBmdWxsIDQwMCB5ZWFyIGN5Y2xlLCB0aGVuIHJlc2V0XG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoeSArIDQwMCwgbSwgZCkgLSBNU19QRVJfNDAwX1lFQVJTO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHksIG0sIGQpLnZhbHVlT2YoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHV0Y1N0YXJ0T2ZEYXRlKHksIG0sIGQpIHtcbiAgICAgICAgLy8gRGF0ZS5VVEMgcmVtYXBzIHllYXJzIDAtOTkgdG8gMTkwMC0xOTk5XG4gICAgICAgIGlmICh5IDwgMTAwICYmIHkgPj0gMCkge1xuICAgICAgICAgICAgLy8gcHJlc2VydmUgbGVhcCB5ZWFycyB1c2luZyBhIGZ1bGwgNDAwIHllYXIgY3ljbGUsIHRoZW4gcmVzZXRcbiAgICAgICAgICAgIHJldHVybiBEYXRlLlVUQyh5ICsgNDAwLCBtLCBkKSAtIE1TX1BFUl80MDBfWUVBUlM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gRGF0ZS5VVEMoeSwgbSwgZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdGFydE9mICh1bml0cykge1xuICAgICAgICB2YXIgdGltZTtcbiAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh1bml0cyk7XG4gICAgICAgIGlmICh1bml0cyA9PT0gdW5kZWZpbmVkIHx8IHVuaXRzID09PSAnbWlsbGlzZWNvbmQnIHx8ICF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc3RhcnRPZkRhdGUgPSB0aGlzLl9pc1VUQyA/IHV0Y1N0YXJ0T2ZEYXRlIDogbG9jYWxTdGFydE9mRGF0ZTtcblxuICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIDAsIDEpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCkgLSB0aGlzLm1vbnRoKCkgJSAzLCAxKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgMSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSB0aGlzLndlZWtkYXkoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdpc29XZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSAodGhpcy5pc29XZWVrZGF5KCkgLSAxKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdkYXknOlxuICAgICAgICAgICAgY2FzZSAnZGF0ZSc6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCksIHRoaXMuZGF0ZSgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOlxuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLl9kLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB0aW1lIC09IG1vZCQxKHRpbWUgKyAodGhpcy5faXNVVEMgPyAwIDogdGhpcy51dGNPZmZzZXQoKSAqIE1TX1BFUl9NSU5VVEUpLCBNU19QRVJfSE9VUik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLl9kLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB0aW1lIC09IG1vZCQxKHRpbWUsIE1TX1BFUl9NSU5VVEUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSAtPSBtb2QkMSh0aW1lLCBNU19QRVJfU0VDT05EKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2Quc2V0VGltZSh0aW1lKTtcbiAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMsIHRydWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBlbmRPZiAodW5pdHMpIHtcbiAgICAgICAgdmFyIHRpbWU7XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICBpZiAodW5pdHMgPT09IHVuZGVmaW5lZCB8fCB1bml0cyA9PT0gJ21pbGxpc2Vjb25kJyB8fCAhdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHN0YXJ0T2ZEYXRlID0gdGhpcy5faXNVVEMgPyB1dGNTdGFydE9mRGF0ZSA6IGxvY2FsU3RhcnRPZkRhdGU7XG5cbiAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpICsgMSwgMCwgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCkgLSB0aGlzLm1vbnRoKCkgJSAzICsgMywgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOlxuICAgICAgICAgICAgICAgIHRpbWUgPSBzdGFydE9mRGF0ZSh0aGlzLnllYXIoKSwgdGhpcy5tb250aCgpICsgMSwgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCksIHRoaXMuZGF0ZSgpIC0gdGhpcy53ZWVrZGF5KCkgKyA3KSAtIDE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdpc29XZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSAodGhpcy5pc29XZWVrZGF5KCkgLSAxKSArIDcpIC0gMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2RheSc6XG4gICAgICAgICAgICBjYXNlICdkYXRlJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgKyAxKSAtIDE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfSE9VUiAtIG1vZCQxKHRpbWUgKyAodGhpcy5faXNVVEMgPyAwIDogdGhpcy51dGNPZmZzZXQoKSAqIE1TX1BFUl9NSU5VVEUpLCBNU19QRVJfSE9VUikgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbWludXRlJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfTUlOVVRFIC0gbW9kJDEodGltZSwgTVNfUEVSX01JTlVURSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfU0VDT05EIC0gbW9kJDEodGltZSwgTVNfUEVSX1NFQ09ORCkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fZC5zZXRUaW1lKHRpbWUpO1xuICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbHVlT2YgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZC52YWx1ZU9mKCkgLSAoKHRoaXMuX29mZnNldCB8fCAwKSAqIDYwMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1bml4ICgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IodGhpcy52YWx1ZU9mKCkgLyAxMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0RhdGUgKCkge1xuICAgICAgICByZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvQXJyYXkgKCkge1xuICAgICAgICB2YXIgbSA9IHRoaXM7XG4gICAgICAgIHJldHVybiBbbS55ZWFyKCksIG0ubW9udGgoKSwgbS5kYXRlKCksIG0uaG91cigpLCBtLm1pbnV0ZSgpLCBtLnNlY29uZCgpLCBtLm1pbGxpc2Vjb25kKCldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvT2JqZWN0ICgpIHtcbiAgICAgICAgdmFyIG0gPSB0aGlzO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeWVhcnM6IG0ueWVhcigpLFxuICAgICAgICAgICAgbW9udGhzOiBtLm1vbnRoKCksXG4gICAgICAgICAgICBkYXRlOiBtLmRhdGUoKSxcbiAgICAgICAgICAgIGhvdXJzOiBtLmhvdXJzKCksXG4gICAgICAgICAgICBtaW51dGVzOiBtLm1pbnV0ZXMoKSxcbiAgICAgICAgICAgIHNlY29uZHM6IG0uc2Vjb25kcygpLFxuICAgICAgICAgICAgbWlsbGlzZWNvbmRzOiBtLm1pbGxpc2Vjb25kcygpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgICAgICAgLy8gbmV3IERhdGUoTmFOKS50b0pTT04oKSA9PT0gbnVsbFxuICAgICAgICByZXR1cm4gdGhpcy5pc1ZhbGlkKCkgPyB0aGlzLnRvSVNPU3RyaW5nKCkgOiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVmFsaWQkMiAoKSB7XG4gICAgICAgIHJldHVybiBpc1ZhbGlkKHRoaXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNpbmdGbGFncyAoKSB7XG4gICAgICAgIHJldHVybiBleHRlbmQoe30sIGdldFBhcnNpbmdGbGFncyh0aGlzKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW52YWxpZEF0ICgpIHtcbiAgICAgICAgcmV0dXJuIGdldFBhcnNpbmdGbGFncyh0aGlzKS5vdmVyZmxvdztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGlvbkRhdGEoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpbnB1dDogdGhpcy5faSxcbiAgICAgICAgICAgIGZvcm1hdDogdGhpcy5fZixcbiAgICAgICAgICAgIGxvY2FsZTogdGhpcy5fbG9jYWxlLFxuICAgICAgICAgICAgaXNVVEM6IHRoaXMuX2lzVVRDLFxuICAgICAgICAgICAgc3RyaWN0OiB0aGlzLl9zdHJpY3RcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ2dnJywgMl0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2Vla1llYXIoKSAlIDEwMDtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnR0cnLCAyXSwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc29XZWVrWWVhcigpICUgMTAwO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYWRkV2Vla1llYXJGb3JtYXRUb2tlbiAodG9rZW4sIGdldHRlcikge1xuICAgICAgICBhZGRGb3JtYXRUb2tlbigwLCBbdG9rZW4sIHRva2VuLmxlbmd0aF0sIDAsIGdldHRlcik7XG4gICAgfVxuXG4gICAgYWRkV2Vla1llYXJGb3JtYXRUb2tlbignZ2dnZycsICAgICAnd2Vla1llYXInKTtcbiAgICBhZGRXZWVrWWVhckZvcm1hdFRva2VuKCdnZ2dnZycsICAgICd3ZWVrWWVhcicpO1xuICAgIGFkZFdlZWtZZWFyRm9ybWF0VG9rZW4oJ0dHR0cnLCAgJ2lzb1dlZWtZZWFyJyk7XG4gICAgYWRkV2Vla1llYXJGb3JtYXRUb2tlbignR0dHR0cnLCAnaXNvV2Vla1llYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnd2Vla1llYXInLCAnZ2cnKTtcbiAgICBhZGRVbml0QWxpYXMoJ2lzb1dlZWtZZWFyJywgJ0dHJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCd3ZWVrWWVhcicsIDEpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2Vla1llYXInLCAxKTtcblxuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbignRycsICAgICAgbWF0Y2hTaWduZWQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2cnLCAgICAgIG1hdGNoU2lnbmVkKTtcbiAgICBhZGRSZWdleFRva2VuKCdHRycsICAgICBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignZ2cnLCAgICAgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0dHR0cnLCAgIG1hdGNoMXRvNCwgbWF0Y2g0KTtcbiAgICBhZGRSZWdleFRva2VuKCdnZ2dnJywgICBtYXRjaDF0bzQsIG1hdGNoNCk7XG4gICAgYWRkUmVnZXhUb2tlbignR0dHR0cnLCAgbWF0Y2gxdG82LCBtYXRjaDYpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2dnZ2dnJywgIG1hdGNoMXRvNiwgbWF0Y2g2KTtcblxuICAgIGFkZFdlZWtQYXJzZVRva2VuKFsnZ2dnZycsICdnZ2dnZycsICdHR0dHJywgJ0dHR0dHJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuLnN1YnN0cigwLCAyKV0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICBhZGRXZWVrUGFyc2VUb2tlbihbJ2dnJywgJ0dHJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuXSA9IGhvb2tzLnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICB9KTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFNldFdlZWtZZWFyIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gZ2V0U2V0V2Vla1llYXJIZWxwZXIuY2FsbCh0aGlzLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIHRoaXMud2VlaygpLFxuICAgICAgICAgICAgICAgIHRoaXMud2Vla2RheSgpLFxuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrLmRvdyxcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsZURhdGEoKS5fd2Vlay5kb3kpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNldElTT1dlZWtZZWFyIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gZ2V0U2V0V2Vla1llYXJIZWxwZXIuY2FsbCh0aGlzLFxuICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLmlzb1dlZWsoKSwgdGhpcy5pc29XZWVrZGF5KCksIDEsIDQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldElTT1dlZWtzSW5ZZWFyICgpIHtcbiAgICAgICAgcmV0dXJuIHdlZWtzSW5ZZWFyKHRoaXMueWVhcigpLCAxLCA0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRXZWVrc0luWWVhciAoKSB7XG4gICAgICAgIHZhciB3ZWVrSW5mbyA9IHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrO1xuICAgICAgICByZXR1cm4gd2Vla3NJblllYXIodGhpcy55ZWFyKCksIHdlZWtJbmZvLmRvdywgd2Vla0luZm8uZG95KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRXZWVrWWVhckhlbHBlcihpbnB1dCwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIHdlZWtzVGFyZ2V0O1xuICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHdlZWtPZlllYXIodGhpcywgZG93LCBkb3kpLnllYXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3ZWVrc1RhcmdldCA9IHdlZWtzSW5ZZWFyKGlucHV0LCBkb3csIGRveSk7XG4gICAgICAgICAgICBpZiAod2VlayA+IHdlZWtzVGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgd2VlayA9IHdlZWtzVGFyZ2V0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNldFdlZWtBbGwuY2FsbCh0aGlzLCBpbnB1dCwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0V2Vla0FsbCh3ZWVrWWVhciwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIGRheU9mWWVhckRhdGEgPSBkYXlPZlllYXJGcm9tV2Vla3Mod2Vla1llYXIsIHdlZWssIHdlZWtkYXksIGRvdywgZG95KSxcbiAgICAgICAgICAgIGRhdGUgPSBjcmVhdGVVVENEYXRlKGRheU9mWWVhckRhdGEueWVhciwgMCwgZGF5T2ZZZWFyRGF0YS5kYXlPZlllYXIpO1xuXG4gICAgICAgIHRoaXMueWVhcihkYXRlLmdldFVUQ0Z1bGxZZWFyKCkpO1xuICAgICAgICB0aGlzLm1vbnRoKGRhdGUuZ2V0VVRDTW9udGgoKSk7XG4gICAgICAgIHRoaXMuZGF0ZShkYXRlLmdldFVUQ0RhdGUoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdRJywgMCwgJ1FvJywgJ3F1YXJ0ZXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygncXVhcnRlcicsICdRJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdxdWFydGVyJywgNyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdRJywgbWF0Y2gxKTtcbiAgICBhZGRQYXJzZVRva2VuKCdRJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtNT05USF0gPSAodG9JbnQoaW5wdXQpIC0gMSkgKiAzO1xuICAgIH0pO1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgZnVuY3Rpb24gZ2V0U2V0UXVhcnRlciAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyBNYXRoLmNlaWwoKHRoaXMubW9udGgoKSArIDEpIC8gMykgOiB0aGlzLm1vbnRoKChpbnB1dCAtIDEpICogMyArIHRoaXMubW9udGgoKSAlIDMpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdEJywgWydERCcsIDJdLCAnRG8nLCAnZGF0ZScpO1xuXG4gICAgLy8gQUxJQVNFU1xuXG4gICAgYWRkVW5pdEFsaWFzKCdkYXRlJywgJ0QnKTtcblxuICAgIC8vIFBSSU9SSVRZXG4gICAgYWRkVW5pdFByaW9yaXR5KCdkYXRlJywgOSk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdEJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignREQnLCBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignRG8nLCBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICAvLyBUT0RPOiBSZW1vdmUgXCJvcmRpbmFsUGFyc2VcIiBmYWxsYmFjayBpbiBuZXh0IG1ham9yIHJlbGVhc2UuXG4gICAgICAgIHJldHVybiBpc1N0cmljdCA/XG4gICAgICAgICAgKGxvY2FsZS5fZGF5T2ZNb250aE9yZGluYWxQYXJzZSB8fCBsb2NhbGUuX29yZGluYWxQYXJzZSkgOlxuICAgICAgICAgIGxvY2FsZS5fZGF5T2ZNb250aE9yZGluYWxQYXJzZUxlbmllbnQ7XG4gICAgfSk7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnRCcsICdERCddLCBEQVRFKTtcbiAgICBhZGRQYXJzZVRva2VuKCdEbycsIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbREFURV0gPSB0b0ludChpbnB1dC5tYXRjaChtYXRjaDF0bzIpWzBdKTtcbiAgICB9KTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIHZhciBnZXRTZXREYXlPZk1vbnRoID0gbWFrZUdldFNldCgnRGF0ZScsIHRydWUpO1xuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ0RERCcsIFsnRERERCcsIDNdLCAnREREbycsICdkYXlPZlllYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnZGF5T2ZZZWFyJywgJ0RERCcpO1xuXG4gICAgLy8gUFJJT1JJVFlcbiAgICBhZGRVbml0UHJpb3JpdHkoJ2RheU9mWWVhcicsIDQpO1xuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbignREREJywgIG1hdGNoMXRvMyk7XG4gICAgYWRkUmVnZXhUb2tlbignRERERCcsIG1hdGNoMyk7XG4gICAgYWRkUGFyc2VUb2tlbihbJ0RERCcsICdEREREJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2RheU9mWWVhciA9IHRvSW50KGlucHV0KTtcbiAgICB9KTtcblxuICAgIC8vIEhFTFBFUlNcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFNldERheU9mWWVhciAoaW5wdXQpIHtcbiAgICAgICAgdmFyIGRheU9mWWVhciA9IE1hdGgucm91bmQoKHRoaXMuY2xvbmUoKS5zdGFydE9mKCdkYXknKSAtIHRoaXMuY2xvbmUoKS5zdGFydE9mKCd5ZWFyJykpIC8gODY0ZTUpICsgMTtcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyBkYXlPZlllYXIgOiB0aGlzLmFkZCgoaW5wdXQgLSBkYXlPZlllYXIpLCAnZCcpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdtJywgWydtbScsIDJdLCAwLCAnbWludXRlJyk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21pbnV0ZScsICdtJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdtaW51dGUnLCAxNCk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdtJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignbW0nLCBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUGFyc2VUb2tlbihbJ20nLCAnbW0nXSwgTUlOVVRFKTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIHZhciBnZXRTZXRNaW51dGUgPSBtYWtlR2V0U2V0KCdNaW51dGVzJywgZmFsc2UpO1xuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ3MnLCBbJ3NzJywgMl0sIDAsICdzZWNvbmQnKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnc2Vjb25kJywgJ3MnKTtcblxuICAgIC8vIFBSSU9SSVRZXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ3NlY29uZCcsIDE1KTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ3MnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdzcycsIG1hdGNoMXRvMiwgbWF0Y2gyKTtcbiAgICBhZGRQYXJzZVRva2VuKFsncycsICdzcyddLCBTRUNPTkQpO1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgdmFyIGdldFNldFNlY29uZCA9IG1ha2VHZXRTZXQoJ1NlY29uZHMnLCBmYWxzZSk7XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbignUycsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIH5+KHRoaXMubWlsbGlzZWNvbmQoKSAvIDEwMCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTJywgMl0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIH5+KHRoaXMubWlsbGlzZWNvbmQoKSAvIDEwKTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTJywgM10sIDAsICdtaWxsaXNlY29uZCcpO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTUycsIDRdLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTJywgNV0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWlsbGlzZWNvbmQoKSAqIDEwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTUycsIDZdLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwO1xuICAgIH0pO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTU1NTUycsIDddLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTU1NTJywgOF0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWlsbGlzZWNvbmQoKSAqIDEwMDAwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTU1NTUycsIDldLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwMDAwO1xuICAgIH0pO1xuXG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21pbGxpc2Vjb25kJywgJ21zJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdtaWxsaXNlY29uZCcsIDE2KTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1MnLCAgICBtYXRjaDF0bzMsIG1hdGNoMSk7XG4gICAgYWRkUmVnZXhUb2tlbignU1MnLCAgIG1hdGNoMXRvMywgbWF0Y2gyKTtcbiAgICBhZGRSZWdleFRva2VuKCdTU1MnLCAgbWF0Y2gxdG8zLCBtYXRjaDMpO1xuXG4gICAgdmFyIHRva2VuO1xuICAgIGZvciAodG9rZW4gPSAnU1NTUyc7IHRva2VuLmxlbmd0aCA8PSA5OyB0b2tlbiArPSAnUycpIHtcbiAgICAgICAgYWRkUmVnZXhUb2tlbih0b2tlbiwgbWF0Y2hVbnNpZ25lZCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VNcyhpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbTUlMTElTRUNPTkRdID0gdG9JbnQoKCcwLicgKyBpbnB1dCkgKiAxMDAwKTtcbiAgICB9XG5cbiAgICBmb3IgKHRva2VuID0gJ1MnOyB0b2tlbi5sZW5ndGggPD0gOTsgdG9rZW4gKz0gJ1MnKSB7XG4gICAgICAgIGFkZFBhcnNlVG9rZW4odG9rZW4sIHBhcnNlTXMpO1xuICAgIH1cbiAgICAvLyBNT01FTlRTXG5cbiAgICB2YXIgZ2V0U2V0TWlsbGlzZWNvbmQgPSBtYWtlR2V0U2V0KCdNaWxsaXNlY29uZHMnLCBmYWxzZSk7XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigneicsICAwLCAwLCAnem9uZUFiYnInKTtcbiAgICBhZGRGb3JtYXRUb2tlbignenonLCAwLCAwLCAnem9uZU5hbWUnKTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFpvbmVBYmJyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzVVRDID8gJ1VUQycgOiAnJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRab25lTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/ICdDb29yZGluYXRlZCBVbml2ZXJzYWwgVGltZScgOiAnJztcbiAgICB9XG5cbiAgICB2YXIgcHJvdG8gPSBNb21lbnQucHJvdG90eXBlO1xuXG4gICAgcHJvdG8uYWRkICAgICAgICAgICAgICAgPSBhZGQ7XG4gICAgcHJvdG8uY2FsZW5kYXIgICAgICAgICAgPSBjYWxlbmRhciQxO1xuICAgIHByb3RvLmNsb25lICAgICAgICAgICAgID0gY2xvbmU7XG4gICAgcHJvdG8uZGlmZiAgICAgICAgICAgICAgPSBkaWZmO1xuICAgIHByb3RvLmVuZE9mICAgICAgICAgICAgID0gZW5kT2Y7XG4gICAgcHJvdG8uZm9ybWF0ICAgICAgICAgICAgPSBmb3JtYXQ7XG4gICAgcHJvdG8uZnJvbSAgICAgICAgICAgICAgPSBmcm9tO1xuICAgIHByb3RvLmZyb21Ob3cgICAgICAgICAgID0gZnJvbU5vdztcbiAgICBwcm90by50byAgICAgICAgICAgICAgICA9IHRvO1xuICAgIHByb3RvLnRvTm93ICAgICAgICAgICAgID0gdG9Ob3c7XG4gICAgcHJvdG8uZ2V0ICAgICAgICAgICAgICAgPSBzdHJpbmdHZXQ7XG4gICAgcHJvdG8uaW52YWxpZEF0ICAgICAgICAgPSBpbnZhbGlkQXQ7XG4gICAgcHJvdG8uaXNBZnRlciAgICAgICAgICAgPSBpc0FmdGVyO1xuICAgIHByb3RvLmlzQmVmb3JlICAgICAgICAgID0gaXNCZWZvcmU7XG4gICAgcHJvdG8uaXNCZXR3ZWVuICAgICAgICAgPSBpc0JldHdlZW47XG4gICAgcHJvdG8uaXNTYW1lICAgICAgICAgICAgPSBpc1NhbWU7XG4gICAgcHJvdG8uaXNTYW1lT3JBZnRlciAgICAgPSBpc1NhbWVPckFmdGVyO1xuICAgIHByb3RvLmlzU2FtZU9yQmVmb3JlICAgID0gaXNTYW1lT3JCZWZvcmU7XG4gICAgcHJvdG8uaXNWYWxpZCAgICAgICAgICAgPSBpc1ZhbGlkJDI7XG4gICAgcHJvdG8ubGFuZyAgICAgICAgICAgICAgPSBsYW5nO1xuICAgIHByb3RvLmxvY2FsZSAgICAgICAgICAgID0gbG9jYWxlO1xuICAgIHByb3RvLmxvY2FsZURhdGEgICAgICAgID0gbG9jYWxlRGF0YTtcbiAgICBwcm90by5tYXggICAgICAgICAgICAgICA9IHByb3RvdHlwZU1heDtcbiAgICBwcm90by5taW4gICAgICAgICAgICAgICA9IHByb3RvdHlwZU1pbjtcbiAgICBwcm90by5wYXJzaW5nRmxhZ3MgICAgICA9IHBhcnNpbmdGbGFncztcbiAgICBwcm90by5zZXQgICAgICAgICAgICAgICA9IHN0cmluZ1NldDtcbiAgICBwcm90by5zdGFydE9mICAgICAgICAgICA9IHN0YXJ0T2Y7XG4gICAgcHJvdG8uc3VidHJhY3QgICAgICAgICAgPSBzdWJ0cmFjdDtcbiAgICBwcm90by50b0FycmF5ICAgICAgICAgICA9IHRvQXJyYXk7XG4gICAgcHJvdG8udG9PYmplY3QgICAgICAgICAgPSB0b09iamVjdDtcbiAgICBwcm90by50b0RhdGUgICAgICAgICAgICA9IHRvRGF0ZTtcbiAgICBwcm90by50b0lTT1N0cmluZyAgICAgICA9IHRvSVNPU3RyaW5nO1xuICAgIHByb3RvLmluc3BlY3QgICAgICAgICAgID0gaW5zcGVjdDtcbiAgICBwcm90by50b0pTT04gICAgICAgICAgICA9IHRvSlNPTjtcbiAgICBwcm90by50b1N0cmluZyAgICAgICAgICA9IHRvU3RyaW5nO1xuICAgIHByb3RvLnVuaXggICAgICAgICAgICAgID0gdW5peDtcbiAgICBwcm90by52YWx1ZU9mICAgICAgICAgICA9IHZhbHVlT2Y7XG4gICAgcHJvdG8uY3JlYXRpb25EYXRhICAgICAgPSBjcmVhdGlvbkRhdGE7XG4gICAgcHJvdG8ueWVhciAgICAgICA9IGdldFNldFllYXI7XG4gICAgcHJvdG8uaXNMZWFwWWVhciA9IGdldElzTGVhcFllYXI7XG4gICAgcHJvdG8ud2Vla1llYXIgICAgPSBnZXRTZXRXZWVrWWVhcjtcbiAgICBwcm90by5pc29XZWVrWWVhciA9IGdldFNldElTT1dlZWtZZWFyO1xuICAgIHByb3RvLnF1YXJ0ZXIgPSBwcm90by5xdWFydGVycyA9IGdldFNldFF1YXJ0ZXI7XG4gICAgcHJvdG8ubW9udGggICAgICAgPSBnZXRTZXRNb250aDtcbiAgICBwcm90by5kYXlzSW5Nb250aCA9IGdldERheXNJbk1vbnRoO1xuICAgIHByb3RvLndlZWsgICAgICAgICAgID0gcHJvdG8ud2Vla3MgICAgICAgID0gZ2V0U2V0V2VlaztcbiAgICBwcm90by5pc29XZWVrICAgICAgICA9IHByb3RvLmlzb1dlZWtzICAgICA9IGdldFNldElTT1dlZWs7XG4gICAgcHJvdG8ud2Vla3NJblllYXIgICAgPSBnZXRXZWVrc0luWWVhcjtcbiAgICBwcm90by5pc29XZWVrc0luWWVhciA9IGdldElTT1dlZWtzSW5ZZWFyO1xuICAgIHByb3RvLmRhdGUgICAgICAgPSBnZXRTZXREYXlPZk1vbnRoO1xuICAgIHByb3RvLmRheSAgICAgICAgPSBwcm90by5kYXlzICAgICAgICAgICAgID0gZ2V0U2V0RGF5T2ZXZWVrO1xuICAgIHByb3RvLndlZWtkYXkgICAgPSBnZXRTZXRMb2NhbGVEYXlPZldlZWs7XG4gICAgcHJvdG8uaXNvV2Vla2RheSA9IGdldFNldElTT0RheU9mV2VlaztcbiAgICBwcm90by5kYXlPZlllYXIgID0gZ2V0U2V0RGF5T2ZZZWFyO1xuICAgIHByb3RvLmhvdXIgPSBwcm90by5ob3VycyA9IGdldFNldEhvdXI7XG4gICAgcHJvdG8ubWludXRlID0gcHJvdG8ubWludXRlcyA9IGdldFNldE1pbnV0ZTtcbiAgICBwcm90by5zZWNvbmQgPSBwcm90by5zZWNvbmRzID0gZ2V0U2V0U2Vjb25kO1xuICAgIHByb3RvLm1pbGxpc2Vjb25kID0gcHJvdG8ubWlsbGlzZWNvbmRzID0gZ2V0U2V0TWlsbGlzZWNvbmQ7XG4gICAgcHJvdG8udXRjT2Zmc2V0ICAgICAgICAgICAgPSBnZXRTZXRPZmZzZXQ7XG4gICAgcHJvdG8udXRjICAgICAgICAgICAgICAgICAgPSBzZXRPZmZzZXRUb1VUQztcbiAgICBwcm90by5sb2NhbCAgICAgICAgICAgICAgICA9IHNldE9mZnNldFRvTG9jYWw7XG4gICAgcHJvdG8ucGFyc2Vab25lICAgICAgICAgICAgPSBzZXRPZmZzZXRUb1BhcnNlZE9mZnNldDtcbiAgICBwcm90by5oYXNBbGlnbmVkSG91ck9mZnNldCA9IGhhc0FsaWduZWRIb3VyT2Zmc2V0O1xuICAgIHByb3RvLmlzRFNUICAgICAgICAgICAgICAgID0gaXNEYXlsaWdodFNhdmluZ1RpbWU7XG4gICAgcHJvdG8uaXNMb2NhbCAgICAgICAgICAgICAgPSBpc0xvY2FsO1xuICAgIHByb3RvLmlzVXRjT2Zmc2V0ICAgICAgICAgID0gaXNVdGNPZmZzZXQ7XG4gICAgcHJvdG8uaXNVdGMgICAgICAgICAgICAgICAgPSBpc1V0YztcbiAgICBwcm90by5pc1VUQyAgICAgICAgICAgICAgICA9IGlzVXRjO1xuICAgIHByb3RvLnpvbmVBYmJyID0gZ2V0Wm9uZUFiYnI7XG4gICAgcHJvdG8uem9uZU5hbWUgPSBnZXRab25lTmFtZTtcbiAgICBwcm90by5kYXRlcyAgPSBkZXByZWNhdGUoJ2RhdGVzIGFjY2Vzc29yIGlzIGRlcHJlY2F0ZWQuIFVzZSBkYXRlIGluc3RlYWQuJywgZ2V0U2V0RGF5T2ZNb250aCk7XG4gICAgcHJvdG8ubW9udGhzID0gZGVwcmVjYXRlKCdtb250aHMgYWNjZXNzb3IgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbnRoIGluc3RlYWQnLCBnZXRTZXRNb250aCk7XG4gICAgcHJvdG8ueWVhcnMgID0gZGVwcmVjYXRlKCd5ZWFycyBhY2Nlc3NvciBpcyBkZXByZWNhdGVkLiBVc2UgeWVhciBpbnN0ZWFkJywgZ2V0U2V0WWVhcik7XG4gICAgcHJvdG8uem9uZSAgID0gZGVwcmVjYXRlKCdtb21lbnQoKS56b25lIGlzIGRlcHJlY2F0ZWQsIHVzZSBtb21lbnQoKS51dGNPZmZzZXQgaW5zdGVhZC4gaHR0cDovL21vbWVudGpzLmNvbS9ndWlkZXMvIy93YXJuaW5ncy96b25lLycsIGdldFNldFpvbmUpO1xuICAgIHByb3RvLmlzRFNUU2hpZnRlZCA9IGRlcHJlY2F0ZSgnaXNEU1RTaGlmdGVkIGlzIGRlcHJlY2F0ZWQuIFNlZSBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2RzdC1zaGlmdGVkLyBmb3IgbW9yZSBpbmZvcm1hdGlvbicsIGlzRGF5bGlnaHRTYXZpbmdUaW1lU2hpZnRlZCk7XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVVbml4IChpbnB1dCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwoaW5wdXQgKiAxMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVJblpvbmUgKCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwuYXBwbHkobnVsbCwgYXJndW1lbnRzKS5wYXJzZVpvbmUoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVQYXJzZVBvc3RGb3JtYXQgKHN0cmluZykge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgIH1cblxuICAgIHZhciBwcm90byQxID0gTG9jYWxlLnByb3RvdHlwZTtcblxuICAgIHByb3RvJDEuY2FsZW5kYXIgICAgICAgID0gY2FsZW5kYXI7XG4gICAgcHJvdG8kMS5sb25nRGF0ZUZvcm1hdCAgPSBsb25nRGF0ZUZvcm1hdDtcbiAgICBwcm90byQxLmludmFsaWREYXRlICAgICA9IGludmFsaWREYXRlO1xuICAgIHByb3RvJDEub3JkaW5hbCAgICAgICAgID0gb3JkaW5hbDtcbiAgICBwcm90byQxLnByZXBhcnNlICAgICAgICA9IHByZVBhcnNlUG9zdEZvcm1hdDtcbiAgICBwcm90byQxLnBvc3Rmb3JtYXQgICAgICA9IHByZVBhcnNlUG9zdEZvcm1hdDtcbiAgICBwcm90byQxLnJlbGF0aXZlVGltZSAgICA9IHJlbGF0aXZlVGltZTtcbiAgICBwcm90byQxLnBhc3RGdXR1cmUgICAgICA9IHBhc3RGdXR1cmU7XG4gICAgcHJvdG8kMS5zZXQgICAgICAgICAgICAgPSBzZXQ7XG5cbiAgICBwcm90byQxLm1vbnRocyAgICAgICAgICAgID0gICAgICAgIGxvY2FsZU1vbnRocztcbiAgICBwcm90byQxLm1vbnRoc1Nob3J0ICAgICAgID0gICAgICAgIGxvY2FsZU1vbnRoc1Nob3J0O1xuICAgIHByb3RvJDEubW9udGhzUGFyc2UgICAgICAgPSAgICAgICAgbG9jYWxlTW9udGhzUGFyc2U7XG4gICAgcHJvdG8kMS5tb250aHNSZWdleCAgICAgICA9IG1vbnRoc1JlZ2V4O1xuICAgIHByb3RvJDEubW9udGhzU2hvcnRSZWdleCAgPSBtb250aHNTaG9ydFJlZ2V4O1xuICAgIHByb3RvJDEud2VlayA9IGxvY2FsZVdlZWs7XG4gICAgcHJvdG8kMS5maXJzdERheU9mWWVhciA9IGxvY2FsZUZpcnN0RGF5T2ZZZWFyO1xuICAgIHByb3RvJDEuZmlyc3REYXlPZldlZWsgPSBsb2NhbGVGaXJzdERheU9mV2VlaztcblxuICAgIHByb3RvJDEud2Vla2RheXMgICAgICAgPSAgICAgICAgbG9jYWxlV2Vla2RheXM7XG4gICAgcHJvdG8kMS53ZWVrZGF5c01pbiAgICA9ICAgICAgICBsb2NhbGVXZWVrZGF5c01pbjtcbiAgICBwcm90byQxLndlZWtkYXlzU2hvcnQgID0gICAgICAgIGxvY2FsZVdlZWtkYXlzU2hvcnQ7XG4gICAgcHJvdG8kMS53ZWVrZGF5c1BhcnNlICA9ICAgICAgICBsb2NhbGVXZWVrZGF5c1BhcnNlO1xuXG4gICAgcHJvdG8kMS53ZWVrZGF5c1JlZ2V4ICAgICAgID0gICAgICAgIHdlZWtkYXlzUmVnZXg7XG4gICAgcHJvdG8kMS53ZWVrZGF5c1Nob3J0UmVnZXggID0gICAgICAgIHdlZWtkYXlzU2hvcnRSZWdleDtcbiAgICBwcm90byQxLndlZWtkYXlzTWluUmVnZXggICAgPSAgICAgICAgd2Vla2RheXNNaW5SZWdleDtcblxuICAgIHByb3RvJDEuaXNQTSA9IGxvY2FsZUlzUE07XG4gICAgcHJvdG8kMS5tZXJpZGllbSA9IGxvY2FsZU1lcmlkaWVtO1xuXG4gICAgZnVuY3Rpb24gZ2V0JDEgKGZvcm1hdCwgaW5kZXgsIGZpZWxkLCBzZXR0ZXIpIHtcbiAgICAgICAgdmFyIGxvY2FsZSA9IGdldExvY2FsZSgpO1xuICAgICAgICB2YXIgdXRjID0gY3JlYXRlVVRDKCkuc2V0KHNldHRlciwgaW5kZXgpO1xuICAgICAgICByZXR1cm4gbG9jYWxlW2ZpZWxkXSh1dGMsIGZvcm1hdCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdE1vbnRoc0ltcGwgKGZvcm1hdCwgaW5kZXgsIGZpZWxkKSB7XG4gICAgICAgIGlmIChpc051bWJlcihmb3JtYXQpKSB7XG4gICAgICAgICAgICBpbmRleCA9IGZvcm1hdDtcbiAgICAgICAgICAgIGZvcm1hdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvcm1hdCA9IGZvcm1hdCB8fCAnJztcblxuICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldCQxKGZvcm1hdCwgaW5kZXgsIGZpZWxkLCAnbW9udGgnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgb3V0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG4gICAgICAgICAgICBvdXRbaV0gPSBnZXQkMShmb3JtYXQsIGksIGZpZWxkLCAnbW9udGgnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH1cblxuICAgIC8vICgpXG4gICAgLy8gKDUpXG4gICAgLy8gKGZtdCwgNSlcbiAgICAvLyAoZm10KVxuICAgIC8vICh0cnVlKVxuICAgIC8vICh0cnVlLCA1KVxuICAgIC8vICh0cnVlLCBmbXQsIDUpXG4gICAgLy8gKHRydWUsIGZtdClcbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNJbXBsIChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgsIGZpZWxkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbG9jYWxlU29ydGVkID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIGlmIChpc051bWJlcihmb3JtYXQpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBmb3JtYXQ7XG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3JtYXQgPSBmb3JtYXQgfHwgJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3JtYXQgPSBsb2NhbGVTb3J0ZWQ7XG4gICAgICAgICAgICBpbmRleCA9IGZvcm1hdDtcbiAgICAgICAgICAgIGxvY2FsZVNvcnRlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoaXNOdW1iZXIoZm9ybWF0KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gZm9ybWF0O1xuICAgICAgICAgICAgICAgIGZvcm1hdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9ybWF0ID0gZm9ybWF0IHx8ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGxvY2FsZSA9IGdldExvY2FsZSgpLFxuICAgICAgICAgICAgc2hpZnQgPSBsb2NhbGVTb3J0ZWQgPyBsb2NhbGUuX3dlZWsuZG93IDogMDtcblxuICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldCQxKGZvcm1hdCwgKGluZGV4ICsgc2hpZnQpICUgNywgZmllbGQsICdkYXknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgb3V0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIG91dFtpXSA9IGdldCQxKGZvcm1hdCwgKGkgKyBzaGlmdCkgJSA3LCBmaWVsZCwgJ2RheScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdE1vbnRocyAoZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdE1vbnRoc0ltcGwoZm9ybWF0LCBpbmRleCwgJ21vbnRocycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpc3RNb250aHNTaG9ydCAoZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdE1vbnRoc0ltcGwoZm9ybWF0LCBpbmRleCwgJ21vbnRoc1Nob3J0Jyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdFdlZWtkYXlzIChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGxpc3RXZWVrZGF5c0ltcGwobG9jYWxlU29ydGVkLCBmb3JtYXQsIGluZGV4LCAnd2Vla2RheXMnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNTaG9ydCAobG9jYWxlU29ydGVkLCBmb3JtYXQsIGluZGV4KSB7XG4gICAgICAgIHJldHVybiBsaXN0V2Vla2RheXNJbXBsKGxvY2FsZVNvcnRlZCwgZm9ybWF0LCBpbmRleCwgJ3dlZWtkYXlzU2hvcnQnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNNaW4gKGxvY2FsZVNvcnRlZCwgZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdFdlZWtkYXlzSW1wbChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgsICd3ZWVrZGF5c01pbicpO1xuICAgIH1cblxuICAgIGdldFNldEdsb2JhbExvY2FsZSgnZW4nLCB7XG4gICAgICAgIGRheU9mTW9udGhPcmRpbmFsUGFyc2U6IC9cXGR7MSwyfSh0aHxzdHxuZHxyZCkvLFxuICAgICAgICBvcmRpbmFsIDogZnVuY3Rpb24gKG51bWJlcikge1xuICAgICAgICAgICAgdmFyIGIgPSBudW1iZXIgJSAxMCxcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSAodG9JbnQobnVtYmVyICUgMTAwIC8gMTApID09PSAxKSA/ICd0aCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAxKSA/ICdzdCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAyKSA/ICduZCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAzKSA/ICdyZCcgOiAndGgnO1xuICAgICAgICAgICAgcmV0dXJuIG51bWJlciArIG91dHB1dDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gU2lkZSBlZmZlY3QgaW1wb3J0c1xuXG4gICAgaG9va3MubGFuZyA9IGRlcHJlY2F0ZSgnbW9tZW50LmxhbmcgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGUgaW5zdGVhZC4nLCBnZXRTZXRHbG9iYWxMb2NhbGUpO1xuICAgIGhvb2tzLmxhbmdEYXRhID0gZGVwcmVjYXRlKCdtb21lbnQubGFuZ0RhdGEgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGVEYXRhIGluc3RlYWQuJywgZ2V0TG9jYWxlKTtcblxuICAgIHZhciBtYXRoQWJzID0gTWF0aC5hYnM7XG5cbiAgICBmdW5jdGlvbiBhYnMgKCkge1xuICAgICAgICB2YXIgZGF0YSAgICAgICAgICAgPSB0aGlzLl9kYXRhO1xuXG4gICAgICAgIHRoaXMuX21pbGxpc2Vjb25kcyA9IG1hdGhBYnModGhpcy5fbWlsbGlzZWNvbmRzKTtcbiAgICAgICAgdGhpcy5fZGF5cyAgICAgICAgID0gbWF0aEFicyh0aGlzLl9kYXlzKTtcbiAgICAgICAgdGhpcy5fbW9udGhzICAgICAgID0gbWF0aEFicyh0aGlzLl9tb250aHMpO1xuXG4gICAgICAgIGRhdGEubWlsbGlzZWNvbmRzICA9IG1hdGhBYnMoZGF0YS5taWxsaXNlY29uZHMpO1xuICAgICAgICBkYXRhLnNlY29uZHMgICAgICAgPSBtYXRoQWJzKGRhdGEuc2Vjb25kcyk7XG4gICAgICAgIGRhdGEubWludXRlcyAgICAgICA9IG1hdGhBYnMoZGF0YS5taW51dGVzKTtcbiAgICAgICAgZGF0YS5ob3VycyAgICAgICAgID0gbWF0aEFicyhkYXRhLmhvdXJzKTtcbiAgICAgICAgZGF0YS5tb250aHMgICAgICAgID0gbWF0aEFicyhkYXRhLm1vbnRocyk7XG4gICAgICAgIGRhdGEueWVhcnMgICAgICAgICA9IG1hdGhBYnMoZGF0YS55ZWFycyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWRkU3VidHJhY3QkMSAoZHVyYXRpb24sIGlucHV0LCB2YWx1ZSwgZGlyZWN0aW9uKSB7XG4gICAgICAgIHZhciBvdGhlciA9IGNyZWF0ZUR1cmF0aW9uKGlucHV0LCB2YWx1ZSk7XG5cbiAgICAgICAgZHVyYXRpb24uX21pbGxpc2Vjb25kcyArPSBkaXJlY3Rpb24gKiBvdGhlci5fbWlsbGlzZWNvbmRzO1xuICAgICAgICBkdXJhdGlvbi5fZGF5cyAgICAgICAgICs9IGRpcmVjdGlvbiAqIG90aGVyLl9kYXlzO1xuICAgICAgICBkdXJhdGlvbi5fbW9udGhzICAgICAgICs9IGRpcmVjdGlvbiAqIG90aGVyLl9tb250aHM7XG5cbiAgICAgICAgcmV0dXJuIGR1cmF0aW9uLl9idWJibGUoKTtcbiAgICB9XG5cbiAgICAvLyBzdXBwb3J0cyBvbmx5IDIuMC1zdHlsZSBhZGQoMSwgJ3MnKSBvciBhZGQoZHVyYXRpb24pXG4gICAgZnVuY3Rpb24gYWRkJDEgKGlucHV0LCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gYWRkU3VidHJhY3QkMSh0aGlzLCBpbnB1dCwgdmFsdWUsIDEpO1xuICAgIH1cblxuICAgIC8vIHN1cHBvcnRzIG9ubHkgMi4wLXN0eWxlIHN1YnRyYWN0KDEsICdzJykgb3Igc3VidHJhY3QoZHVyYXRpb24pXG4gICAgZnVuY3Rpb24gc3VidHJhY3QkMSAoaW5wdXQsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBhZGRTdWJ0cmFjdCQxKHRoaXMsIGlucHV0LCB2YWx1ZSwgLTEpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFic0NlaWwgKG51bWJlcikge1xuICAgICAgICBpZiAobnVtYmVyIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IobnVtYmVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmNlaWwobnVtYmVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJ1YmJsZSAoKSB7XG4gICAgICAgIHZhciBtaWxsaXNlY29uZHMgPSB0aGlzLl9taWxsaXNlY29uZHM7XG4gICAgICAgIHZhciBkYXlzICAgICAgICAgPSB0aGlzLl9kYXlzO1xuICAgICAgICB2YXIgbW9udGhzICAgICAgID0gdGhpcy5fbW9udGhzO1xuICAgICAgICB2YXIgZGF0YSAgICAgICAgID0gdGhpcy5fZGF0YTtcbiAgICAgICAgdmFyIHNlY29uZHMsIG1pbnV0ZXMsIGhvdXJzLCB5ZWFycywgbW9udGhzRnJvbURheXM7XG5cbiAgICAgICAgLy8gaWYgd2UgaGF2ZSBhIG1peCBvZiBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgdmFsdWVzLCBidWJibGUgZG93biBmaXJzdFxuICAgICAgICAvLyBjaGVjazogaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzIxNjZcbiAgICAgICAgaWYgKCEoKG1pbGxpc2Vjb25kcyA+PSAwICYmIGRheXMgPj0gMCAmJiBtb250aHMgPj0gMCkgfHxcbiAgICAgICAgICAgICAgICAobWlsbGlzZWNvbmRzIDw9IDAgJiYgZGF5cyA8PSAwICYmIG1vbnRocyA8PSAwKSkpIHtcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kcyArPSBhYnNDZWlsKG1vbnRoc1RvRGF5cyhtb250aHMpICsgZGF5cykgKiA4NjRlNTtcbiAgICAgICAgICAgIGRheXMgPSAwO1xuICAgICAgICAgICAgbW9udGhzID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgY29kZSBidWJibGVzIHVwIHZhbHVlcywgc2VlIHRoZSB0ZXN0cyBmb3JcbiAgICAgICAgLy8gZXhhbXBsZXMgb2Ygd2hhdCB0aGF0IG1lYW5zLlxuICAgICAgICBkYXRhLm1pbGxpc2Vjb25kcyA9IG1pbGxpc2Vjb25kcyAlIDEwMDA7XG5cbiAgICAgICAgc2Vjb25kcyAgICAgICAgICAgPSBhYnNGbG9vcihtaWxsaXNlY29uZHMgLyAxMDAwKTtcbiAgICAgICAgZGF0YS5zZWNvbmRzICAgICAgPSBzZWNvbmRzICUgNjA7XG5cbiAgICAgICAgbWludXRlcyAgICAgICAgICAgPSBhYnNGbG9vcihzZWNvbmRzIC8gNjApO1xuICAgICAgICBkYXRhLm1pbnV0ZXMgICAgICA9IG1pbnV0ZXMgJSA2MDtcblxuICAgICAgICBob3VycyAgICAgICAgICAgICA9IGFic0Zsb29yKG1pbnV0ZXMgLyA2MCk7XG4gICAgICAgIGRhdGEuaG91cnMgICAgICAgID0gaG91cnMgJSAyNDtcblxuICAgICAgICBkYXlzICs9IGFic0Zsb29yKGhvdXJzIC8gMjQpO1xuXG4gICAgICAgIC8vIGNvbnZlcnQgZGF5cyB0byBtb250aHNcbiAgICAgICAgbW9udGhzRnJvbURheXMgPSBhYnNGbG9vcihkYXlzVG9Nb250aHMoZGF5cykpO1xuICAgICAgICBtb250aHMgKz0gbW9udGhzRnJvbURheXM7XG4gICAgICAgIGRheXMgLT0gYWJzQ2VpbChtb250aHNUb0RheXMobW9udGhzRnJvbURheXMpKTtcblxuICAgICAgICAvLyAxMiBtb250aHMgLT4gMSB5ZWFyXG4gICAgICAgIHllYXJzID0gYWJzRmxvb3IobW9udGhzIC8gMTIpO1xuICAgICAgICBtb250aHMgJT0gMTI7XG5cbiAgICAgICAgZGF0YS5kYXlzICAgPSBkYXlzO1xuICAgICAgICBkYXRhLm1vbnRocyA9IG1vbnRocztcbiAgICAgICAgZGF0YS55ZWFycyAgPSB5ZWFycztcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlzVG9Nb250aHMgKGRheXMpIHtcbiAgICAgICAgLy8gNDAwIHllYXJzIGhhdmUgMTQ2MDk3IGRheXMgKHRha2luZyBpbnRvIGFjY291bnQgbGVhcCB5ZWFyIHJ1bGVzKVxuICAgICAgICAvLyA0MDAgeWVhcnMgaGF2ZSAxMiBtb250aHMgPT09IDQ4MDBcbiAgICAgICAgcmV0dXJuIGRheXMgKiA0ODAwIC8gMTQ2MDk3O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1vbnRoc1RvRGF5cyAobW9udGhzKSB7XG4gICAgICAgIC8vIHRoZSByZXZlcnNlIG9mIGRheXNUb01vbnRoc1xuICAgICAgICByZXR1cm4gbW9udGhzICogMTQ2MDk3IC8gNDgwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhcyAodW5pdHMpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIE5hTjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF5cztcbiAgICAgICAgdmFyIG1vbnRocztcbiAgICAgICAgdmFyIG1pbGxpc2Vjb25kcyA9IHRoaXMuX21pbGxpc2Vjb25kcztcblxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICBpZiAodW5pdHMgPT09ICdtb250aCcgfHwgdW5pdHMgPT09ICdxdWFydGVyJyB8fCB1bml0cyA9PT0gJ3llYXInKSB7XG4gICAgICAgICAgICBkYXlzID0gdGhpcy5fZGF5cyArIG1pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgbW9udGhzID0gdGhpcy5fbW9udGhzICsgZGF5c1RvTW9udGhzKGRheXMpO1xuICAgICAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgICAgIGNhc2UgJ21vbnRoJzogICByZXR1cm4gbW9udGhzO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3F1YXJ0ZXInOiByZXR1cm4gbW9udGhzIC8gMztcbiAgICAgICAgICAgICAgICBjYXNlICd5ZWFyJzogICAgcmV0dXJuIG1vbnRocyAvIDEyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaGFuZGxlIG1pbGxpc2Vjb25kcyBzZXBhcmF0ZWx5IGJlY2F1c2Ugb2YgZmxvYXRpbmcgcG9pbnQgbWF0aCBlcnJvcnMgKGlzc3VlICMxODY3KVxuICAgICAgICAgICAgZGF5cyA9IHRoaXMuX2RheXMgKyBNYXRoLnJvdW5kKG1vbnRoc1RvRGF5cyh0aGlzLl9tb250aHMpKTtcbiAgICAgICAgICAgIHN3aXRjaCAodW5pdHMpIHtcbiAgICAgICAgICAgICAgICBjYXNlICd3ZWVrJyAgIDogcmV0dXJuIGRheXMgLyA3ICAgICArIG1pbGxpc2Vjb25kcyAvIDYwNDhlNTtcbiAgICAgICAgICAgICAgICBjYXNlICdkYXknICAgIDogcmV0dXJuIGRheXMgICAgICAgICArIG1pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgICAgIGNhc2UgJ2hvdXInICAgOiByZXR1cm4gZGF5cyAqIDI0ICAgICsgbWlsbGlzZWNvbmRzIC8gMzZlNTtcbiAgICAgICAgICAgICAgICBjYXNlICdtaW51dGUnIDogcmV0dXJuIGRheXMgKiAxNDQwICArIG1pbGxpc2Vjb25kcyAvIDZlNDtcbiAgICAgICAgICAgICAgICBjYXNlICdzZWNvbmQnIDogcmV0dXJuIGRheXMgKiA4NjQwMCArIG1pbGxpc2Vjb25kcyAvIDEwMDA7XG4gICAgICAgICAgICAgICAgLy8gTWF0aC5mbG9vciBwcmV2ZW50cyBmbG9hdGluZyBwb2ludCBtYXRoIGVycm9ycyBoZXJlXG4gICAgICAgICAgICAgICAgY2FzZSAnbWlsbGlzZWNvbmQnOiByZXR1cm4gTWF0aC5mbG9vcihkYXlzICogODY0ZTUpICsgbWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcignVW5rbm93biB1bml0ICcgKyB1bml0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPOiBVc2UgdGhpcy5hcygnbXMnKT9cbiAgICBmdW5jdGlvbiB2YWx1ZU9mJDEgKCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgK1xuICAgICAgICAgICAgdGhpcy5fZGF5cyAqIDg2NGU1ICtcbiAgICAgICAgICAgICh0aGlzLl9tb250aHMgJSAxMikgKiAyNTkyZTYgK1xuICAgICAgICAgICAgdG9JbnQodGhpcy5fbW9udGhzIC8gMTIpICogMzE1MzZlNlxuICAgICAgICApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VBcyAoYWxpYXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFzKGFsaWFzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgYXNNaWxsaXNlY29uZHMgPSBtYWtlQXMoJ21zJyk7XG4gICAgdmFyIGFzU2Vjb25kcyAgICAgID0gbWFrZUFzKCdzJyk7XG4gICAgdmFyIGFzTWludXRlcyAgICAgID0gbWFrZUFzKCdtJyk7XG4gICAgdmFyIGFzSG91cnMgICAgICAgID0gbWFrZUFzKCdoJyk7XG4gICAgdmFyIGFzRGF5cyAgICAgICAgID0gbWFrZUFzKCdkJyk7XG4gICAgdmFyIGFzV2Vla3MgICAgICAgID0gbWFrZUFzKCd3Jyk7XG4gICAgdmFyIGFzTW9udGhzICAgICAgID0gbWFrZUFzKCdNJyk7XG4gICAgdmFyIGFzUXVhcnRlcnMgICAgID0gbWFrZUFzKCdRJyk7XG4gICAgdmFyIGFzWWVhcnMgICAgICAgID0gbWFrZUFzKCd5Jyk7XG5cbiAgICBmdW5jdGlvbiBjbG9uZSQxICgpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKHRoaXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldCQyICh1bml0cykge1xuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpc1t1bml0cyArICdzJ10oKSA6IE5hTjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlR2V0dGVyKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmlzVmFsaWQoKSA/IHRoaXMuX2RhdGFbbmFtZV0gOiBOYU47XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIG1pbGxpc2Vjb25kcyA9IG1ha2VHZXR0ZXIoJ21pbGxpc2Vjb25kcycpO1xuICAgIHZhciBzZWNvbmRzICAgICAgPSBtYWtlR2V0dGVyKCdzZWNvbmRzJyk7XG4gICAgdmFyIG1pbnV0ZXMgICAgICA9IG1ha2VHZXR0ZXIoJ21pbnV0ZXMnKTtcbiAgICB2YXIgaG91cnMgICAgICAgID0gbWFrZUdldHRlcignaG91cnMnKTtcbiAgICB2YXIgZGF5cyAgICAgICAgID0gbWFrZUdldHRlcignZGF5cycpO1xuICAgIHZhciBtb250aHMgICAgICAgPSBtYWtlR2V0dGVyKCdtb250aHMnKTtcbiAgICB2YXIgeWVhcnMgICAgICAgID0gbWFrZUdldHRlcigneWVhcnMnKTtcblxuICAgIGZ1bmN0aW9uIHdlZWtzICgpIHtcbiAgICAgICAgcmV0dXJuIGFic0Zsb29yKHRoaXMuZGF5cygpIC8gNyk7XG4gICAgfVxuXG4gICAgdmFyIHJvdW5kID0gTWF0aC5yb3VuZDtcbiAgICB2YXIgdGhyZXNob2xkcyA9IHtcbiAgICAgICAgc3M6IDQ0LCAgICAgICAgIC8vIGEgZmV3IHNlY29uZHMgdG8gc2Vjb25kc1xuICAgICAgICBzIDogNDUsICAgICAgICAgLy8gc2Vjb25kcyB0byBtaW51dGVcbiAgICAgICAgbSA6IDQ1LCAgICAgICAgIC8vIG1pbnV0ZXMgdG8gaG91clxuICAgICAgICBoIDogMjIsICAgICAgICAgLy8gaG91cnMgdG8gZGF5XG4gICAgICAgIGQgOiAyNiwgICAgICAgICAvLyBkYXlzIHRvIG1vbnRoXG4gICAgICAgIE0gOiAxMSAgICAgICAgICAvLyBtb250aHMgdG8geWVhclxuICAgIH07XG5cbiAgICAvLyBoZWxwZXIgZnVuY3Rpb24gZm9yIG1vbWVudC5mbi5mcm9tLCBtb21lbnQuZm4uZnJvbU5vdywgYW5kIG1vbWVudC5kdXJhdGlvbi5mbi5odW1hbml6ZVxuICAgIGZ1bmN0aW9uIHN1YnN0aXR1dGVUaW1lQWdvKHN0cmluZywgbnVtYmVyLCB3aXRob3V0U3VmZml4LCBpc0Z1dHVyZSwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUucmVsYXRpdmVUaW1lKG51bWJlciB8fCAxLCAhIXdpdGhvdXRTdWZmaXgsIHN0cmluZywgaXNGdXR1cmUpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbGF0aXZlVGltZSQxIChwb3NOZWdEdXJhdGlvbiwgd2l0aG91dFN1ZmZpeCwgbG9jYWxlKSB7XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IGNyZWF0ZUR1cmF0aW9uKHBvc05lZ0R1cmF0aW9uKS5hYnMoKTtcbiAgICAgICAgdmFyIHNlY29uZHMgID0gcm91bmQoZHVyYXRpb24uYXMoJ3MnKSk7XG4gICAgICAgIHZhciBtaW51dGVzICA9IHJvdW5kKGR1cmF0aW9uLmFzKCdtJykpO1xuICAgICAgICB2YXIgaG91cnMgICAgPSByb3VuZChkdXJhdGlvbi5hcygnaCcpKTtcbiAgICAgICAgdmFyIGRheXMgICAgID0gcm91bmQoZHVyYXRpb24uYXMoJ2QnKSk7XG4gICAgICAgIHZhciBtb250aHMgICA9IHJvdW5kKGR1cmF0aW9uLmFzKCdNJykpO1xuICAgICAgICB2YXIgeWVhcnMgICAgPSByb3VuZChkdXJhdGlvbi5hcygneScpKTtcblxuICAgICAgICB2YXIgYSA9IHNlY29uZHMgPD0gdGhyZXNob2xkcy5zcyAmJiBbJ3MnLCBzZWNvbmRzXSAgfHxcbiAgICAgICAgICAgICAgICBzZWNvbmRzIDwgdGhyZXNob2xkcy5zICAgJiYgWydzcycsIHNlY29uZHNdIHx8XG4gICAgICAgICAgICAgICAgbWludXRlcyA8PSAxICAgICAgICAgICAgICYmIFsnbSddICAgICAgICAgICB8fFxuICAgICAgICAgICAgICAgIG1pbnV0ZXMgPCB0aHJlc2hvbGRzLm0gICAmJiBbJ21tJywgbWludXRlc10gfHxcbiAgICAgICAgICAgICAgICBob3VycyAgIDw9IDEgICAgICAgICAgICAgJiYgWydoJ10gICAgICAgICAgIHx8XG4gICAgICAgICAgICAgICAgaG91cnMgICA8IHRocmVzaG9sZHMuaCAgICYmIFsnaGgnLCBob3Vyc10gICB8fFxuICAgICAgICAgICAgICAgIGRheXMgICAgPD0gMSAgICAgICAgICAgICAmJiBbJ2QnXSAgICAgICAgICAgfHxcbiAgICAgICAgICAgICAgICBkYXlzICAgIDwgdGhyZXNob2xkcy5kICAgJiYgWydkZCcsIGRheXNdICAgIHx8XG4gICAgICAgICAgICAgICAgbW9udGhzICA8PSAxICAgICAgICAgICAgICYmIFsnTSddICAgICAgICAgICB8fFxuICAgICAgICAgICAgICAgIG1vbnRocyAgPCB0aHJlc2hvbGRzLk0gICAmJiBbJ01NJywgbW9udGhzXSAgfHxcbiAgICAgICAgICAgICAgICB5ZWFycyAgIDw9IDEgICAgICAgICAgICAgJiYgWyd5J10gICAgICAgICAgIHx8IFsneXknLCB5ZWFyc107XG5cbiAgICAgICAgYVsyXSA9IHdpdGhvdXRTdWZmaXg7XG4gICAgICAgIGFbM10gPSArcG9zTmVnRHVyYXRpb24gPiAwO1xuICAgICAgICBhWzRdID0gbG9jYWxlO1xuICAgICAgICByZXR1cm4gc3Vic3RpdHV0ZVRpbWVBZ28uYXBwbHkobnVsbCwgYSk7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHNldCB0aGUgcm91bmRpbmcgZnVuY3Rpb24gZm9yIHJlbGF0aXZlIHRpbWUgc3RyaW5nc1xuICAgIGZ1bmN0aW9uIGdldFNldFJlbGF0aXZlVGltZVJvdW5kaW5nIChyb3VuZGluZ0Z1bmN0aW9uKSB7XG4gICAgICAgIGlmIChyb3VuZGluZ0Z1bmN0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiByb3VuZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mKHJvdW5kaW5nRnVuY3Rpb24pID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByb3VuZCA9IHJvdW5kaW5nRnVuY3Rpb247XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHNldCBhIHRocmVzaG9sZCBmb3IgcmVsYXRpdmUgdGltZSBzdHJpbmdzXG4gICAgZnVuY3Rpb24gZ2V0U2V0UmVsYXRpdmVUaW1lVGhyZXNob2xkICh0aHJlc2hvbGQsIGxpbWl0KSB7XG4gICAgICAgIGlmICh0aHJlc2hvbGRzW3RocmVzaG9sZF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW1pdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhyZXNob2xkc1t0aHJlc2hvbGRdO1xuICAgICAgICB9XG4gICAgICAgIHRocmVzaG9sZHNbdGhyZXNob2xkXSA9IGxpbWl0O1xuICAgICAgICBpZiAodGhyZXNob2xkID09PSAncycpIHtcbiAgICAgICAgICAgIHRocmVzaG9sZHMuc3MgPSBsaW1pdCAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaHVtYW5pemUgKHdpdGhTdWZmaXgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLmludmFsaWREYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbG9jYWxlID0gdGhpcy5sb2NhbGVEYXRhKCk7XG4gICAgICAgIHZhciBvdXRwdXQgPSByZWxhdGl2ZVRpbWUkMSh0aGlzLCAhd2l0aFN1ZmZpeCwgbG9jYWxlKTtcblxuICAgICAgICBpZiAod2l0aFN1ZmZpeCkge1xuICAgICAgICAgICAgb3V0cHV0ID0gbG9jYWxlLnBhc3RGdXR1cmUoK3RoaXMsIG91dHB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbG9jYWxlLnBvc3Rmb3JtYXQob3V0cHV0KTtcbiAgICB9XG5cbiAgICB2YXIgYWJzJDEgPSBNYXRoLmFicztcblxuICAgIGZ1bmN0aW9uIHNpZ24oeCkge1xuICAgICAgICByZXR1cm4gKCh4ID4gMCkgLSAoeCA8IDApKSB8fCAreDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0lTT1N0cmluZyQxKCkge1xuICAgICAgICAvLyBmb3IgSVNPIHN0cmluZ3Mgd2UgZG8gbm90IHVzZSB0aGUgbm9ybWFsIGJ1YmJsaW5nIHJ1bGVzOlxuICAgICAgICAvLyAgKiBtaWxsaXNlY29uZHMgYnViYmxlIHVwIHVudGlsIHRoZXkgYmVjb21lIGhvdXJzXG4gICAgICAgIC8vICAqIGRheXMgZG8gbm90IGJ1YmJsZSBhdCBhbGxcbiAgICAgICAgLy8gICogbW9udGhzIGJ1YmJsZSB1cCB1bnRpbCB0aGV5IGJlY29tZSB5ZWFyc1xuICAgICAgICAvLyBUaGlzIGlzIGJlY2F1c2UgdGhlcmUgaXMgbm8gY29udGV4dC1mcmVlIGNvbnZlcnNpb24gYmV0d2VlbiBob3VycyBhbmQgZGF5c1xuICAgICAgICAvLyAodGhpbmsgb2YgY2xvY2sgY2hhbmdlcylcbiAgICAgICAgLy8gYW5kIGFsc28gbm90IGJldHdlZW4gZGF5cyBhbmQgbW9udGhzICgyOC0zMSBkYXlzIHBlciBtb250aClcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLmludmFsaWREYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc2Vjb25kcyA9IGFicyQxKHRoaXMuX21pbGxpc2Vjb25kcykgLyAxMDAwO1xuICAgICAgICB2YXIgZGF5cyAgICAgICAgID0gYWJzJDEodGhpcy5fZGF5cyk7XG4gICAgICAgIHZhciBtb250aHMgICAgICAgPSBhYnMkMSh0aGlzLl9tb250aHMpO1xuICAgICAgICB2YXIgbWludXRlcywgaG91cnMsIHllYXJzO1xuXG4gICAgICAgIC8vIDM2MDAgc2Vjb25kcyAtPiA2MCBtaW51dGVzIC0+IDEgaG91clxuICAgICAgICBtaW51dGVzICAgICAgICAgICA9IGFic0Zsb29yKHNlY29uZHMgLyA2MCk7XG4gICAgICAgIGhvdXJzICAgICAgICAgICAgID0gYWJzRmxvb3IobWludXRlcyAvIDYwKTtcbiAgICAgICAgc2Vjb25kcyAlPSA2MDtcbiAgICAgICAgbWludXRlcyAlPSA2MDtcblxuICAgICAgICAvLyAxMiBtb250aHMgLT4gMSB5ZWFyXG4gICAgICAgIHllYXJzICA9IGFic0Zsb29yKG1vbnRocyAvIDEyKTtcbiAgICAgICAgbW9udGhzICU9IDEyO1xuXG5cbiAgICAgICAgLy8gaW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2RvcmRpbGxlL21vbWVudC1pc29kdXJhdGlvbi9ibG9iL21hc3Rlci9tb21lbnQuaXNvZHVyYXRpb24uanNcbiAgICAgICAgdmFyIFkgPSB5ZWFycztcbiAgICAgICAgdmFyIE0gPSBtb250aHM7XG4gICAgICAgIHZhciBEID0gZGF5cztcbiAgICAgICAgdmFyIGggPSBob3VycztcbiAgICAgICAgdmFyIG0gPSBtaW51dGVzO1xuICAgICAgICB2YXIgcyA9IHNlY29uZHMgPyBzZWNvbmRzLnRvRml4ZWQoMykucmVwbGFjZSgvXFwuPzArJC8sICcnKSA6ICcnO1xuICAgICAgICB2YXIgdG90YWwgPSB0aGlzLmFzU2Vjb25kcygpO1xuXG4gICAgICAgIGlmICghdG90YWwpIHtcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgdGhlIHNhbWUgYXMgQyMncyAoTm9kYSkgYW5kIHB5dGhvbiAoaXNvZGF0ZSkuLi5cbiAgICAgICAgICAgIC8vIGJ1dCBub3Qgb3RoZXIgSlMgKGdvb2cuZGF0ZSlcbiAgICAgICAgICAgIHJldHVybiAnUDBEJztcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0b3RhbFNpZ24gPSB0b3RhbCA8IDAgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIHltU2lnbiA9IHNpZ24odGhpcy5fbW9udGhzKSAhPT0gc2lnbih0b3RhbCkgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIGRheXNTaWduID0gc2lnbih0aGlzLl9kYXlzKSAhPT0gc2lnbih0b3RhbCkgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIGhtc1NpZ24gPSBzaWduKHRoaXMuX21pbGxpc2Vjb25kcykgIT09IHNpZ24odG90YWwpID8gJy0nIDogJyc7XG5cbiAgICAgICAgcmV0dXJuIHRvdGFsU2lnbiArICdQJyArXG4gICAgICAgICAgICAoWSA/IHltU2lnbiArIFkgKyAnWScgOiAnJykgK1xuICAgICAgICAgICAgKE0gPyB5bVNpZ24gKyBNICsgJ00nIDogJycpICtcbiAgICAgICAgICAgIChEID8gZGF5c1NpZ24gKyBEICsgJ0QnIDogJycpICtcbiAgICAgICAgICAgICgoaCB8fCBtIHx8IHMpID8gJ1QnIDogJycpICtcbiAgICAgICAgICAgIChoID8gaG1zU2lnbiArIGggKyAnSCcgOiAnJykgK1xuICAgICAgICAgICAgKG0gPyBobXNTaWduICsgbSArICdNJyA6ICcnKSArXG4gICAgICAgICAgICAocyA/IGhtc1NpZ24gKyBzICsgJ1MnIDogJycpO1xuICAgIH1cblxuICAgIHZhciBwcm90byQyID0gRHVyYXRpb24ucHJvdG90eXBlO1xuXG4gICAgcHJvdG8kMi5pc1ZhbGlkICAgICAgICA9IGlzVmFsaWQkMTtcbiAgICBwcm90byQyLmFicyAgICAgICAgICAgID0gYWJzO1xuICAgIHByb3RvJDIuYWRkICAgICAgICAgICAgPSBhZGQkMTtcbiAgICBwcm90byQyLnN1YnRyYWN0ICAgICAgID0gc3VidHJhY3QkMTtcbiAgICBwcm90byQyLmFzICAgICAgICAgICAgID0gYXM7XG4gICAgcHJvdG8kMi5hc01pbGxpc2Vjb25kcyA9IGFzTWlsbGlzZWNvbmRzO1xuICAgIHByb3RvJDIuYXNTZWNvbmRzICAgICAgPSBhc1NlY29uZHM7XG4gICAgcHJvdG8kMi5hc01pbnV0ZXMgICAgICA9IGFzTWludXRlcztcbiAgICBwcm90byQyLmFzSG91cnMgICAgICAgID0gYXNIb3VycztcbiAgICBwcm90byQyLmFzRGF5cyAgICAgICAgID0gYXNEYXlzO1xuICAgIHByb3RvJDIuYXNXZWVrcyAgICAgICAgPSBhc1dlZWtzO1xuICAgIHByb3RvJDIuYXNNb250aHMgICAgICAgPSBhc01vbnRocztcbiAgICBwcm90byQyLmFzUXVhcnRlcnMgICAgID0gYXNRdWFydGVycztcbiAgICBwcm90byQyLmFzWWVhcnMgICAgICAgID0gYXNZZWFycztcbiAgICBwcm90byQyLnZhbHVlT2YgICAgICAgID0gdmFsdWVPZiQxO1xuICAgIHByb3RvJDIuX2J1YmJsZSAgICAgICAgPSBidWJibGU7XG4gICAgcHJvdG8kMi5jbG9uZSAgICAgICAgICA9IGNsb25lJDE7XG4gICAgcHJvdG8kMi5nZXQgICAgICAgICAgICA9IGdldCQyO1xuICAgIHByb3RvJDIubWlsbGlzZWNvbmRzICAgPSBtaWxsaXNlY29uZHM7XG4gICAgcHJvdG8kMi5zZWNvbmRzICAgICAgICA9IHNlY29uZHM7XG4gICAgcHJvdG8kMi5taW51dGVzICAgICAgICA9IG1pbnV0ZXM7XG4gICAgcHJvdG8kMi5ob3VycyAgICAgICAgICA9IGhvdXJzO1xuICAgIHByb3RvJDIuZGF5cyAgICAgICAgICAgPSBkYXlzO1xuICAgIHByb3RvJDIud2Vla3MgICAgICAgICAgPSB3ZWVrcztcbiAgICBwcm90byQyLm1vbnRocyAgICAgICAgID0gbW9udGhzO1xuICAgIHByb3RvJDIueWVhcnMgICAgICAgICAgPSB5ZWFycztcbiAgICBwcm90byQyLmh1bWFuaXplICAgICAgID0gaHVtYW5pemU7XG4gICAgcHJvdG8kMi50b0lTT1N0cmluZyAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi50b1N0cmluZyAgICAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi50b0pTT04gICAgICAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi5sb2NhbGUgICAgICAgICA9IGxvY2FsZTtcbiAgICBwcm90byQyLmxvY2FsZURhdGEgICAgID0gbG9jYWxlRGF0YTtcblxuICAgIHByb3RvJDIudG9Jc29TdHJpbmcgPSBkZXByZWNhdGUoJ3RvSXNvU3RyaW5nKCkgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSB0b0lTT1N0cmluZygpIGluc3RlYWQgKG5vdGljZSB0aGUgY2FwaXRhbHMpJywgdG9JU09TdHJpbmckMSk7XG4gICAgcHJvdG8kMi5sYW5nID0gbGFuZztcblxuICAgIC8vIFNpZGUgZWZmZWN0IGltcG9ydHNcblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdYJywgMCwgMCwgJ3VuaXgnKTtcbiAgICBhZGRGb3JtYXRUb2tlbigneCcsIDAsIDAsICd2YWx1ZU9mJyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCd4JywgbWF0Y2hTaWduZWQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1gnLCBtYXRjaFRpbWVzdGFtcCk7XG4gICAgYWRkUGFyc2VUb2tlbignWCcsIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2QgPSBuZXcgRGF0ZShwYXJzZUZsb2F0KGlucHV0LCAxMCkgKiAxMDAwKTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCd4JywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKHRvSW50KGlucHV0KSk7XG4gICAgfSk7XG5cbiAgICAvLyBTaWRlIGVmZmVjdCBpbXBvcnRzXG5cblxuICAgIGhvb2tzLnZlcnNpb24gPSAnMi4yNC4wJztcblxuICAgIHNldEhvb2tDYWxsYmFjayhjcmVhdGVMb2NhbCk7XG5cbiAgICBob29rcy5mbiAgICAgICAgICAgICAgICAgICAgPSBwcm90bztcbiAgICBob29rcy5taW4gICAgICAgICAgICAgICAgICAgPSBtaW47XG4gICAgaG9va3MubWF4ICAgICAgICAgICAgICAgICAgID0gbWF4O1xuICAgIGhvb2tzLm5vdyAgICAgICAgICAgICAgICAgICA9IG5vdztcbiAgICBob29rcy51dGMgICAgICAgICAgICAgICAgICAgPSBjcmVhdGVVVEM7XG4gICAgaG9va3MudW5peCAgICAgICAgICAgICAgICAgID0gY3JlYXRlVW5peDtcbiAgICBob29rcy5tb250aHMgICAgICAgICAgICAgICAgPSBsaXN0TW9udGhzO1xuICAgIGhvb2tzLmlzRGF0ZSAgICAgICAgICAgICAgICA9IGlzRGF0ZTtcbiAgICBob29rcy5sb2NhbGUgICAgICAgICAgICAgICAgPSBnZXRTZXRHbG9iYWxMb2NhbGU7XG4gICAgaG9va3MuaW52YWxpZCAgICAgICAgICAgICAgID0gY3JlYXRlSW52YWxpZDtcbiAgICBob29rcy5kdXJhdGlvbiAgICAgICAgICAgICAgPSBjcmVhdGVEdXJhdGlvbjtcbiAgICBob29rcy5pc01vbWVudCAgICAgICAgICAgICAgPSBpc01vbWVudDtcbiAgICBob29rcy53ZWVrZGF5cyAgICAgICAgICAgICAgPSBsaXN0V2Vla2RheXM7XG4gICAgaG9va3MucGFyc2Vab25lICAgICAgICAgICAgID0gY3JlYXRlSW5ab25lO1xuICAgIGhvb2tzLmxvY2FsZURhdGEgICAgICAgICAgICA9IGdldExvY2FsZTtcbiAgICBob29rcy5pc0R1cmF0aW9uICAgICAgICAgICAgPSBpc0R1cmF0aW9uO1xuICAgIGhvb2tzLm1vbnRoc1Nob3J0ICAgICAgICAgICA9IGxpc3RNb250aHNTaG9ydDtcbiAgICBob29rcy53ZWVrZGF5c01pbiAgICAgICAgICAgPSBsaXN0V2Vla2RheXNNaW47XG4gICAgaG9va3MuZGVmaW5lTG9jYWxlICAgICAgICAgID0gZGVmaW5lTG9jYWxlO1xuICAgIGhvb2tzLnVwZGF0ZUxvY2FsZSAgICAgICAgICA9IHVwZGF0ZUxvY2FsZTtcbiAgICBob29rcy5sb2NhbGVzICAgICAgICAgICAgICAgPSBsaXN0TG9jYWxlcztcbiAgICBob29rcy53ZWVrZGF5c1Nob3J0ICAgICAgICAgPSBsaXN0V2Vla2RheXNTaG9ydDtcbiAgICBob29rcy5ub3JtYWxpemVVbml0cyAgICAgICAgPSBub3JtYWxpemVVbml0cztcbiAgICBob29rcy5yZWxhdGl2ZVRpbWVSb3VuZGluZyAgPSBnZXRTZXRSZWxhdGl2ZVRpbWVSb3VuZGluZztcbiAgICBob29rcy5yZWxhdGl2ZVRpbWVUaHJlc2hvbGQgPSBnZXRTZXRSZWxhdGl2ZVRpbWVUaHJlc2hvbGQ7XG4gICAgaG9va3MuY2FsZW5kYXJGb3JtYXQgICAgICAgID0gZ2V0Q2FsZW5kYXJGb3JtYXQ7XG4gICAgaG9va3MucHJvdG90eXBlICAgICAgICAgICAgID0gcHJvdG87XG5cbiAgICAvLyBjdXJyZW50bHkgSFRNTDUgaW5wdXQgdHlwZSBvbmx5IHN1cHBvcnRzIDI0LWhvdXIgZm9ybWF0c1xuICAgIGhvb2tzLkhUTUw1X0ZNVCA9IHtcbiAgICAgICAgREFURVRJTUVfTE9DQUw6ICdZWVlZLU1NLUREVEhIOm1tJywgICAgICAgICAgICAgLy8gPGlucHV0IHR5cGU9XCJkYXRldGltZS1sb2NhbFwiIC8+XG4gICAgICAgIERBVEVUSU1FX0xPQ0FMX1NFQ09ORFM6ICdZWVlZLU1NLUREVEhIOm1tOnNzJywgIC8vIDxpbnB1dCB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIiBzdGVwPVwiMVwiIC8+XG4gICAgICAgIERBVEVUSU1FX0xPQ0FMX01TOiAnWVlZWS1NTS1ERFRISDptbTpzcy5TU1MnLCAgIC8vIDxpbnB1dCB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIiBzdGVwPVwiMC4wMDFcIiAvPlxuICAgICAgICBEQVRFOiAnWVlZWS1NTS1ERCcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cImRhdGVcIiAvPlxuICAgICAgICBUSU1FOiAnSEg6bW0nLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cInRpbWVcIiAvPlxuICAgICAgICBUSU1FX1NFQ09ORFM6ICdISDptbTpzcycsICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cInRpbWVcIiBzdGVwPVwiMVwiIC8+XG4gICAgICAgIFRJTUVfTVM6ICdISDptbTpzcy5TU1MnLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwidGltZVwiIHN0ZXA9XCIwLjAwMVwiIC8+XG4gICAgICAgIFdFRUs6ICdHR0dHLVtXXVdXJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwid2Vla1wiIC8+XG4gICAgICAgIE1PTlRIOiAnWVlZWS1NTScgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwibW9udGhcIiAvPlxuICAgIH07XG5cbiAgICByZXR1cm4gaG9va3M7XG5cbn0pKSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///da01\n")}}]);

TODO found
Open

    // TODO: enforce spot.driver === 'client'
Severity: Minor
Found in docs/api/app.js.html by fixme

FIXME found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.ampersand-state"],{ef45:function(module,exports,__webpack_require__){"use strict";eval("\n/*$AMPERSAND_VERSION*/\nvar uniqueId = __webpack_require__(/*! lodash/uniqueId */ \"6d0d\");\nvar assign = __webpack_require__(/*! lodash/assign */ \"5ad5\");\nvar cloneObj = function(obj) { return assign({}, obj); };\nvar omit = __webpack_require__(/*! lodash/omit */ \"4633\");\nvar escape = __webpack_require__(/*! lodash/escape */ \"740c\");\nvar forOwn = __webpack_require__(/*! lodash/forOwn */ \"436f\");\nvar includes = __webpack_require__(/*! lodash/includes */ \"e2c7\");\nvar isString = __webpack_require__(/*! lodash/isString */ \"5fa3\");\nvar isObject = __webpack_require__(/*! lodash/isObject */ \"d3a8\");\nvar isDate = __webpack_require__(/*! lodash/isDate */ \"7f93\");\nvar isFunction = __webpack_require__(/*! lodash/isFunction */ \"f3b0\");\nvar _isEqual = __webpack_require__(/*! lodash/isEqual */ \"f8a3\"); // to avoid shadowing\nvar has = __webpack_require__(/*! lodash/has */ \"b055\");\nvar result = __webpack_require__(/*! lodash/result */ \"80c9\");\nvar union = __webpack_require__(/*! lodash/union */ \"c80f\");\nvar Events = __webpack_require__(/*! ampersand-events */ \"13c2\");\nvar KeyTree = __webpack_require__(/*! key-tree-store */ \"8849\");\nvar arrayNext = __webpack_require__(/*! array-next */ \"d1bb\");\nvar changeRE = /^change:/;\nvar noop = function () {};\n\nfunction Base(attrs, options) {\n    options || (options = {});\n    this.cid || (this.cid = uniqueId('state'));\n    this._events = {};\n    this._values = {};\n    this._eventBubblingHandlerCache = {};\n    this._definition = Object.create(this._definition);\n    if (options.parse) attrs = this.parse(attrs, options);\n    this.parent = options.parent;\n    this.collection = options.collection;\n    this._keyTree = new KeyTree();\n    this._initCollections();\n    this._initChildren();\n    this._cache = {};\n    this._previousAttributes = {};\n    if (attrs) this.set(attrs, assign({silent: true, initial: true}, options));\n    this._changed = {};\n    if (this._derived) this._initDerived();\n    if (options.init !== false) this.initialize.apply(this, arguments);\n}\n\nassign(Base.prototype, Events, {\n    // can be allow, ignore, reject\n    extraProperties: 'ignore',\n\n    idAttribute: 'id',\n\n    namespaceAttribute: 'namespace',\n\n    typeAttribute: 'modelType',\n\n    // Stubbed out to be overwritten\n    initialize: function () {\n        return this;\n    },\n\n    // Get ID of model per configuration.\n    // Should *always* be how ID is determined by other code.\n    getId: function () {\n        return this[this.idAttribute];\n    },\n\n    // Get namespace of model per configuration.\n    // Should *always* be how namespace is determined by other code.\n    getNamespace: function () {\n        return this[this.namespaceAttribute];\n    },\n\n    // Get type of model per configuration.\n    // Should *always* be how type is determined by other code.\n    getType: function () {\n        return this[this.typeAttribute];\n    },\n\n    // A model is new if it has never been saved to the server, and lacks an id.\n    isNew: function () {\n        return this.getId() == null;\n    },\n\n    // get HTML-escaped value of attribute\n    escape: function (attr) {\n        return escape(this.get(attr));\n    },\n\n    // Check if the model is currently in a valid state.\n    isValid: function (options) {\n        return this._validate({}, assign(options || {}, { validate: true }));\n    },\n\n    // Parse can be used remap/restructure/rename incoming properties\n    // before they are applied to attributes.\n    parse: function (resp, options) {\n        //jshint unused:false\n        return resp;\n    },\n\n    // Serialize is the inverse of `parse` it lets you massage data\n    // on the way out. Before, sending to server, for example.\n    serialize: function (options) {\n        var attrOpts = assign({props: true}, options);\n        var res = this.getAttributes(attrOpts, true);\n        \n        var setFromSerializedValue = function (value, key) {\n\t        res[key] = this[key].serialize();\n        }.bind(this);\n        \n        forOwn(this._children, setFromSerializedValue);\n        forOwn(this._collections, setFromSerializedValue);\n        return res;\n    },\n\n    // Main set method used by generated setters/getters and can\n    // be used directly if you need to pass options or set multiple\n    // properties at once.\n    set: function (key, value, options) {\n        var self = this;\n        var extraProperties = this.extraProperties;\n        var wasChanging, changeEvents, newType, newVal, def, cast, err, attr,\n            attrs, dataType, silent, unset, currentVal, initial, hasChanged, isEqual, onChange;\n\n        // Handle both `\"key\", value` and `{key: value}` -style arguments.\n        if (isObject(key) || key === null) {\n            attrs = key;\n            options = value;\n        } else {\n            attrs = {};\n            attrs[key] = value;\n        }\n\n        options = options || {};\n\n        if (!this._validate(attrs, options)) return false;\n\n        // Extract attributes and options.\n        unset = options.unset;\n        silent = options.silent;\n        initial = options.initial;\n\n        // Initialize change tracking.\n        wasChanging = this._changing;\n        this._changing = true;\n        changeEvents = [];\n\n        // if not already changing, store previous\n        if (initial) {\n            this._previousAttributes = {};\n        } else if (!wasChanging) {\n            this._previousAttributes = this.attributes;\n            this._changed = {};\n        }\n\n        // For each `set` attribute...\n        for (var i = 0, keys = Object.keys(attrs), len = keys.length; i < len; i++) {\n            attr = keys[i];\n            newVal = attrs[attr];\n            newType = typeof newVal;\n            currentVal = this._values[attr];\n            def = this._definition[attr];\n\n            if (!def) {\n                // if this is a child model or collection\n                if (this._children[attr] || this._collections[attr]) {\n                    if (!isObject(newVal)) {\n                        newVal = {};\n                    }\n\n                    this[attr].set(newVal, options);\n                    continue;\n                } else if (extraProperties === 'ignore') {\n                    continue;\n                } else if (extraProperties === 'reject') {\n                    throw new TypeError('No \"' + attr + '\" property defined on ' + (this.type || 'this') + ' model and extraProperties not set to \"ignore\" or \"allow\"');\n                } else if (extraProperties === 'allow') {\n                    def = this._createPropertyDefinition(attr, 'any');\n                } else if (extraProperties) {\n                    throw new TypeError('Invalid value for extraProperties: \"' + extraProperties + '\"');\n                }\n            }\n\n            isEqual = this._getCompareForType(def.type);\n            onChange = this._getOnChangeForType(def.type);\n            dataType = this._dataTypes[def.type];\n\n            // check type if we have one\n            if (dataType && dataType.set) {\n                cast = dataType.set(newVal);\n                newVal = cast.val;\n                newType = cast.type;\n            }\n\n            // If we've defined a test, run it\n            if (def.test) {\n                err = def.test.call(this, newVal, newType);\n                if (err) {\n                    throw new TypeError('Property \\'' + attr + '\\' failed validation with error: ' + err);\n                }\n            }\n\n            // If we are required but undefined, throw error.\n            // If we are null and are not allowing null, throw error\n            // If we have a defined type and the new type doesn't match, and we are not null, throw error.\n            // If we require specific value and new one is not one of them, throw error (unless it has default value or we're unsetting it with undefined).\n\n            if (newVal === undefined && def.required) {\n                throw new TypeError('Required property \\'' + attr + '\\' must be of type ' + def.type + '. Tried to set ' + newVal);\n            }\n            if (newVal === null && def.required && !def.allowNull) {\n                throw new TypeError('Property \\'' + attr + '\\' must be of type ' + def.type + ' (cannot be null). Tried to set ' + newVal);\n            }\n            if ((def.type && def.type !== 'any' && def.type !== newType) && newVal !== null && newVal !== undefined) {\n                throw new TypeError('Property \\'' + attr + '\\' must be of type ' + def.type + '. Tried to set ' + newVal);\n            }\n            if (def.values && !includes(def.values, newVal)) {\n                var defaultValue = result(def, 'default');\n                if (unset && defaultValue !== undefined) {\n                    newVal = defaultValue;\n                } else if (!unset || (unset && newVal !== undefined)) {\n                    throw new TypeError('Property \\'' + attr + '\\' must be one of values: ' + def.values.join(', ') + '. Tried to set ' + newVal);\n                }\n            }\n\n            // We know this has 'changed' if it's the initial set, so skip a potentially expensive isEqual check.\n            hasChanged = initial || !isEqual(currentVal, newVal, attr);\n\n            // enforce `setOnce` for properties if set\n            if (def.setOnce && currentVal !== undefined && hasChanged) {\n                throw new TypeError('Property \\'' + attr + '\\' can only be set once.');\n            }\n\n            // set/unset attributes.\n            // If this is not the initial set, keep track of changed attributes\n            // and push to changeEvents array so we can fire events.\n            if (hasChanged) {\n\n                // This fires no matter what, even on initial set.\n                onChange(newVal, currentVal, attr);\n\n                // If this is a change (not an initial set), mark the change.\n                // Note it's impossible to unset on the initial set (it will already be unset),\n                // so we only include that logic here.\n                if (!initial) {\n                    this._changed[attr] = newVal;\n                    this._previousAttributes[attr] = currentVal;\n                    if (unset) {\n                        // FIXME delete is very slow. Can we get away with setting to undefined?\n                        delete this._values[attr];\n                    }\n                    if (!silent) {\n                        changeEvents.push({prev: currentVal, val: newVal, key: attr});\n                    }\n                }\n                if (!unset) {\n                    this._values[attr] = newVal;\n                }\n            } else {\n                // Not changed\n                // FIXME delete is very slow. Can we get away with setting to undefined?\n                delete this._changed[attr];\n            }\n        }\n\n        // Fire events. This array is not populated if we are told to be silent.\n        if (changeEvents.length) this._pending = true;\n        changeEvents.forEach(function (change) {\n            self.trigger('change:' + change.key, self, change.val, options);\n        });\n\n        // You might be wondering why there's a `while` loop here. Changes can\n        // be recursively nested within `\"change\"` events.\n        if (wasChanging) return this;\n        while (this._pending) {\n            this._pending = false;\n            this.trigger('change', this, options);\n        }\n        this._pending = false;\n        this._changing = false;\n        return this;\n    },\n\n    get: function (attr) {\n        return this[attr];\n    },\n\n    // Toggle boolean properties or properties that have a `values`\n    // array in its definition.\n    toggle: function (property) {\n        var def = this._definition[property];\n        if (def.type === 'boolean') {\n            // if it's a bool, just flip it\n            this[property] = !this[property];\n        } else if (def && def.values) {\n            // If it's a property with an array of values\n            // skip to the next one looping back if at end.\n            this[property] = arrayNext(def.values, this[property]);\n        } else {\n            throw new TypeError('Can only toggle properties that are type `boolean` or have `values` array.');\n        }\n        return this;\n    },\n\n    // Get all of the attributes of the model at the time of the previous\n    // `\"change\"` event.\n    previousAttributes: function () {\n        return cloneObj(this._previousAttributes);\n    },\n\n    // Determine if the model has changed since the last `\"change\"` event.\n    // If you specify an attribute name, determine if that attribute has changed.\n    hasChanged: function (attr) {\n        if (attr == null) return !!Object.keys(this._changed).length;\n        if (has(this._derived, attr)) {\n            return this._derived[attr].depList.some(function (dep) {\n                return this.hasChanged(dep);\n            }, this);\n        }\n        return has(this._changed, attr);\n    },\n\n    // Return an object containing all the attributes that have changed, or\n    // false if there are no changed attributes. Useful for determining what\n    // parts of a view need to be updated and/or what attributes need to be\n    // persisted to the server. Unset attributes will be set to undefined.\n    // You can also pass an attributes object to diff against the model,\n    // determining if there *would be* a change.\n    changedAttributes: function (diff) {\n        if (!diff) return this.hasChanged() ? cloneObj(this._changed) : false;\n        var val, changed = false;\n        var old = this._changing ? this._previousAttributes : this.attributes;\n        var def, isEqual;\n        for (var attr in diff) {\n            def = this._definition[attr];\n            if (!def) continue;\n            isEqual = this._getCompareForType(def.type);\n            if (isEqual(old[attr], (val = diff[attr]))) continue;\n            (changed || (changed = {}))[attr] = val;\n        }\n        return changed;\n    },\n\n    toJSON: function () {\n        return this.serialize();\n    },\n\n    unset: function (attrs, options) {\n        var self = this;\n        attrs = Array.isArray(attrs) ? attrs : [attrs];\n        attrs.forEach(function (key) {\n            var def = self._definition[key];\n            if (!def) return;\n            var val;\n            if (def.required) {\n                val = result(def, 'default');\n                return self.set(key, val, options);\n            } else {\n                return self.set(key, val, assign({}, options, {unset: true}));\n            }\n        });\n    },\n\n    clear: function (options) {\n        var self = this;\n        Object.keys(this.attributes).forEach(function (key) {\n            self.unset(key, options);\n        });\n        return this;\n    },\n\n    previous: function (attr) {\n        if (attr == null || !Object.keys(this._previousAttributes).length) return null;\n        return this._previousAttributes[attr];\n    },\n\n    // Get default values for a certain type\n    _getDefaultForType: function (type) {\n        var dataType = this._dataTypes[type];\n        return dataType && dataType['default'];\n    },\n\n    // Determine which comparison algorithm to use for comparing a property\n    _getCompareForType: function (type) {\n        var dataType = this._dataTypes[type];\n        if (dataType && dataType.compare) return dataType.compare.bind(this);\n        return _isEqual; // if no compare function is defined, use _.isEqual\n    },\n\n    _getOnChangeForType : function(type){\n        var dataType = this._dataTypes[type];\n        if (dataType && dataType.onChange) return dataType.onChange.bind(this);\n        return noop;\n    },\n\n    // Run validation against the next complete set of model attributes,\n    // returning `true` if all is well. Otherwise, fire an `\"invalid\"` event.\n    _validate: function (attrs, options) {\n        if (!options.validate || !this.validate) return true;\n        attrs = assign({}, this.attributes, attrs);\n        var error = this.validationError = this.validate(attrs, options) || null;\n        if (!error) return true;\n        this.trigger('invalid', this, error, assign(options || {}, {validationError: error}));\n        return false;\n    },\n\n    _createPropertyDefinition: function (name, desc, isSession) {\n        return createPropertyDefinition(this, name, desc, isSession);\n    },\n\n    // just makes friendlier errors when trying to define a new model\n    // only used when setting up original property definitions\n    _ensureValidType: function (type) {\n        return includes(['string', 'number', 'boolean', 'array', 'object', 'date', 'state', 'any']\n            .concat(Object.keys(this._dataTypes)), type) ? type : undefined;\n    },\n\n    getAttributes: function (options, raw) {\n        options = assign({\n            session: false,\n            props: false,\n            derived: false\n        }, options || {});\n        var res = {};\n        var val, def;\n        for (var item in this._definition) {\n            def = this._definition[item];\n            if ((options.session && def.session) || (options.props && !def.session)) {\n                val = raw ? this._values[item] : this[item];\n                if (raw && val && isFunction(val.serialize)) val = val.serialize();\n                if (typeof val === 'undefined') val = result(def, 'default');\n                if (typeof val !== 'undefined') res[item] = val;\n            }\n        }\n        if (options.derived) {\n            for (var derivedItem in this._derived) res[derivedItem] = this[derivedItem];\n        }\n        return res;\n    },\n\n    _initDerived: function () {\n        var self = this;\n\n        forOwn(this._derived, function (value, name) {\n            var def = self._derived[name];\n            def.deps = def.depList;\n\n            var update = function () {\n                var newVal = def.fn.call(self);\n\n                if (self._cache[name] !== newVal || !def.cache) {\n                    if (def.cache) {\n                        self._previousAttributes[name] = self._cache[name];\n                    }\n                    self._cache[name] = newVal;\n                    self.trigger('change:' + name, self, self._cache[name]);\n                }\n            };\n\n            def.deps.forEach(function (propString) {\n                self._keyTree.add(propString, update);\n            });\n        });\n\n        this.on('all', function (eventName) {\n            if (changeRE.test(eventName)) {\n                self._keyTree.get(eventName.split(':')[1]).forEach(function (fn) {\n                    fn();\n                });\n            }\n        }, this);\n    },\n\n    _getDerivedProperty: function (name, flushCache) {\n        // is this a derived property that is cached\n        if (this._derived[name].cache) {\n            //set if this is the first time, or flushCache is set\n            if (flushCache || !this._cache.hasOwnProperty(name)) {\n                this._cache[name] = this._derived[name].fn.apply(this);\n            }\n            return this._cache[name];\n        } else {\n            return this._derived[name].fn.apply(this);\n        }\n    },\n\n    _initCollections: function () {\n        var coll;\n        if (!this._collections) return;\n        for (coll in this._collections) {\n            this._safeSet(coll, new this._collections[coll](null, {parent: this}));\n        }\n    },\n\n    _initChildren: function () {\n        var child;\n        if (!this._children) return;\n        for (child in this._children) {\n            this._safeSet(child, new this._children[child]({}, {parent: this}));\n            this.listenTo(this[child], 'all', this._getCachedEventBubblingHandler(child));\n        }\n    },\n\n    // Returns a bound handler for doing event bubbling while\n    // adding a name to the change string.\n    _getCachedEventBubblingHandler: function (propertyName) {\n        if (!this._eventBubblingHandlerCache[propertyName]) {\n            this._eventBubblingHandlerCache[propertyName] = function (name, model, newValue) {\n                if (changeRE.test(name)) {\n                    this.trigger('change:' + propertyName + '.' + name.split(':')[1], model, newValue);\n                } else if (name === 'change') {\n                    this.trigger('change', this);\n                }\n            }.bind(this);\n        }\n        return this._eventBubblingHandlerCache[propertyName];\n    },\n\n    // Check that all required attributes are present\n    _verifyRequired: function () {\n        var attrs = this.attributes; // should include session\n        for (var def in this._definition) {\n            if (this._definition[def].required && typeof attrs[def] === 'undefined') {\n                return false;\n            }\n        }\n        return true;\n    },\n\n    // expose safeSet method\n    _safeSet: function safeSet(property, value) {\n        if (property in this) {\n            throw new Error('Encountered namespace collision while setting instance property `' + property + '`');\n        }\n        this[property] = value;\n        return this;\n    }\n});\n\n// getter for attributes\nObject.defineProperties(Base.prototype, {\n    attributes: {\n        get: function () {\n            return this.getAttributes({props: true, session: true});\n        }\n    },\n    all: {\n        get: function () {\n            return this.getAttributes({\n                session: true,\n                props: true,\n                derived: true\n            });\n        }\n    },\n    isState: {\n        get: function () { return true; },\n        set: function () { }\n    }\n});\n\n// helper for creating/storing property definitions and creating\n// appropriate getters/setters\nfunction createPropertyDefinition(object, name, desc, isSession) {\n    var def = object._definition[name] = {};\n    var type, descArray;\n\n    if (isString(desc)) {\n        // grab our type if all we've got is a string\n        type = object._ensureValidType(desc);\n        if (type) def.type = type;\n    } else {\n        //Transform array of ['type', required, default] to object form\n        if (Array.isArray(desc)) {\n            descArray = desc;\n            desc = {\n                type: descArray[0],\n                required: descArray[1],\n                'default': descArray[2]\n            };\n        }\n\n        type = object._ensureValidType(desc.type);\n        if (type) def.type = type;\n\n        if (desc.required) def.required = true;\n\n        if (desc['default'] && typeof desc['default'] === 'object') {\n            throw new TypeError('The default value for ' + name + ' cannot be an object/array, must be a value or a function which returns a value/object/array');\n        }\n\n        def['default'] = desc['default'];\n\n        def.allowNull = desc.allowNull ? desc.allowNull : false;\n        if (desc.setOnce) def.setOnce = true;\n        if (def.required && def['default'] === undefined && !def.setOnce) def['default'] = object._getDefaultForType(type);\n        def.test = desc.test;\n        def.values = desc.values;\n    }\n    if (isSession) def.session = true;\n\n    if (!type) {\n        type = isString(desc) ? desc : desc.type;\n        // TODO: start throwing a TypeError in future major versions instead of warning\n        console.warn('Invalid data type of `' + type + '` for `' + name + '` property. Use one of the default types or define your own');\n    }\n\n    // define a getter/setter on the prototype\n    // but they get/set on the instance\n    Object.defineProperty(object, name, {\n        set: function (val) {\n            this.set(name, val);\n        },\n        get: function () {\n            if (!this._values) {\n                throw Error('You may be trying to `extend` a state object with \"' + name + '\" which has been defined in `props` on the object being extended');\n            }\n            var value = this._values[name];\n            var typeDef = this._dataTypes[def.type];\n            if (typeof value !== 'undefined') {\n                if (typeDef && typeDef.get) {\n                    value = typeDef.get(value);\n                }\n                return value;\n            }\n            var defaultValue = result(def, 'default');\n            this._values[name] = defaultValue;\n            // If we've set a defaultValue, fire a change handler effectively marking\n            // its change from undefined to the default value.\n            if (typeof defaultValue !== 'undefined') {\n                var onChange = this._getOnChangeForType(def.type);\n                onChange(defaultValue, value, name);\n            }\n            return defaultValue;\n        }\n    });\n\n    return def;\n}\n\n// helper for creating derived property definitions\nfunction createDerivedProperty(modelProto, name, definition) {\n    var def = modelProto._derived[name] = {\n        fn: isFunction(definition) ? definition : definition.fn,\n        cache: (definition.cache !== false),\n        depList: definition.deps || []\n    };\n\n    // add to our shared dependency list\n    def.depList.forEach(function (dep) {\n        modelProto._deps[dep] = union(modelProto._deps[dep] || [], [name]);\n    });\n\n    // defined a top-level getter for derived names\n    Object.defineProperty(modelProto, name, {\n        get: function () {\n            return this._getDerivedProperty(name);\n        },\n        set: function () {\n            throw new TypeError(\"`\" + name + \"` is a derived property, it can't be set directly.\");\n        }\n    });\n}\n\nvar dataTypes = {\n    string: {\n        'default': function () {\n            return '';\n        }\n    },\n    date: {\n        set: function (newVal) {\n            var newType;\n            if (newVal == null) {\n                newType = typeof null;\n            } else if (!isDate(newVal)) {\n                var err = null;\n                var dateVal = new Date(newVal).valueOf();\n                if (isNaN(dateVal)) {\n                    // If the newVal cant be parsed, then try parseInt first\n                    dateVal = new Date(parseInt(newVal, 10)).valueOf();\n                    if (isNaN(dateVal)) err = true;\n                }\n                newVal = dateVal;\n                newType = 'date';\n                if (err) {\n                    newType = typeof newVal;\n                }\n            } else {\n                newType = 'date';\n                newVal = newVal.valueOf();\n            }\n\n            return {\n                val: newVal,\n                type: newType\n            };\n        },\n        get: function (val) {\n            if (val == null) { return val; }\n            return new Date(val);\n        },\n        'default': function () {\n            return new Date();\n        }\n    },\n    array: {\n        set: function (newVal) {\n            return {\n                val: newVal,\n                type: Array.isArray(newVal) ? 'array' : typeof newVal\n            };\n        },\n        'default': function () {\n            return [];\n        }\n    },\n    object: {\n        set: function (newVal) {\n            var newType = typeof newVal;\n            // we have to have a way of supporting \"missing\" objects.\n            // Null is an object, but setting a value to undefined\n            // should work too, IMO. We just override it, in that case.\n            if (newType !== 'object' && newVal === undefined) {\n                newVal = null;\n                newType = 'object';\n            }\n            return {\n                val: newVal,\n                type: newType\n            };\n        },\n        'default': function () {\n            return {};\n        }\n    },\n    // the `state` data type is a bit special in that setting it should\n    // also bubble events\n    state: {\n        set: function (newVal) {\n            var isInstance = newVal instanceof Base || (newVal && newVal.isState);\n            if (isInstance) {\n                return {\n                    val: newVal,\n                    type: 'state'\n                };\n            } else {\n                return {\n                    val: newVal,\n                    type: typeof newVal\n                };\n            }\n        },\n        compare: function (currentVal, newVal) {\n            return currentVal === newVal;\n        },\n\n        onChange : function(newVal, previousVal, attributeName){\n            // if this has changed we want to also handle\n            // event propagation\n            if (previousVal) {\n                this.stopListening(previousVal, 'all', this._getCachedEventBubblingHandler(attributeName));\n            }\n\n            if (newVal != null) {\n                this.listenTo(newVal, 'all', this._getCachedEventBubblingHandler(attributeName));\n            }\n        }\n    }\n};\n\n// the extend method used to extend prototypes, maintain inheritance chains for instanceof\n// and allow for additions to the model definitions.\nfunction extend(protoProps) {\n    /*jshint validthis:true*/\n    var parent = this;\n    var child;\n\n    // The constructor function for the new subclass is either defined by you\n    // (the \"constructor\" property in your `extend` definition), or defaulted\n    // by us to simply call the parent's constructor.\n    if (protoProps && protoProps.hasOwnProperty('constructor')) {\n        child = protoProps.constructor;\n    } else {\n        child = function () {\n            return parent.apply(this, arguments);\n        };\n    }\n\n    // Add static properties to the constructor function from parent\n    assign(child, parent);\n\n    // Set the prototype chain to inherit from `parent`, without calling\n    // `parent`'s constructor function.\n    var Surrogate = function () { this.constructor = child; };\n    Surrogate.prototype = parent.prototype;\n    child.prototype = new Surrogate();\n\n    // set prototype level objects\n    child.prototype._derived =  assign({}, parent.prototype._derived);\n    child.prototype._deps = assign({}, parent.prototype._deps);\n    child.prototype._definition = assign({}, parent.prototype._definition);\n    child.prototype._collections = assign({}, parent.prototype._collections);\n    child.prototype._children = assign({}, parent.prototype._children);\n    child.prototype._dataTypes = assign({}, parent.prototype._dataTypes || dataTypes);\n\n    // Mix in all prototype properties to the subclass if supplied.\n    if (protoProps) {\n        var omitFromExtend = [\n            'dataTypes', 'props', 'session', 'derived', 'collections', 'children'\n        ];\n        for(var i = 0; i < arguments.length; i++) {\n            var def = arguments[i];\n            if (def.dataTypes) {\n                forOwn(def.dataTypes, function (def, name) {\n                    child.prototype._dataTypes[name] = def;\n                });\n            }\n            if (def.props) {\n                forOwn(def.props, function (def, name) {\n                    createPropertyDefinition(child.prototype, name, def);\n                });\n            }\n            if (def.session) {\n                forOwn(def.session, function (def, name) {\n                    createPropertyDefinition(child.prototype, name, def, true);\n                });\n            }\n            if (def.derived) {\n                forOwn(def.derived, function (def, name) {\n                    createDerivedProperty(child.prototype, name, def);\n                });\n            }\n            if (def.collections) {\n                forOwn(def.collections, function (constructor, name) {\n                    child.prototype._collections[name] = constructor;\n                });\n            }\n            if (def.children) {\n                forOwn(def.children, function (constructor, name) {\n                    child.prototype._children[name] = constructor;\n                });\n            }\n            assign(child.prototype, omit(def, omitFromExtend));\n        }\n    }\n\n    // Set a convenience property in case the parent's prototype is needed\n    // later.\n    child.__super__ = parent.prototype;\n\n    return child;\n}\n\nBase.extend = extend;\n\n// Our main exports\nmodule.exports = Base;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWY0NS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9hbXBlcnNhbmQtc3RhdGUvYW1wZXJzYW5kLXN0YXRlLmpzPzYzZDQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuLyokQU1QRVJTQU5EX1ZFUlNJT04qL1xudmFyIHVuaXF1ZUlkID0gcmVxdWlyZSgnbG9kYXNoL3VuaXF1ZUlkJyk7XG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpO1xudmFyIGNsb25lT2JqID0gZnVuY3Rpb24ob2JqKSB7IHJldHVybiBhc3NpZ24oe30sIG9iaik7IH07XG52YXIgb21pdCA9IHJlcXVpcmUoJ2xvZGFzaC9vbWl0Jyk7XG52YXIgZXNjYXBlID0gcmVxdWlyZSgnbG9kYXNoL2VzY2FwZScpO1xudmFyIGZvck93biA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JPd24nKTtcbnZhciBpbmNsdWRlcyA9IHJlcXVpcmUoJ2xvZGFzaC9pbmNsdWRlcycpO1xudmFyIGlzU3RyaW5nID0gcmVxdWlyZSgnbG9kYXNoL2lzU3RyaW5nJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCdsb2Rhc2gvaXNPYmplY3QnKTtcbnZhciBpc0RhdGUgPSByZXF1aXJlKCdsb2Rhc2gvaXNEYXRlJyk7XG52YXIgaXNGdW5jdGlvbiA9IHJlcXVpcmUoJ2xvZGFzaC9pc0Z1bmN0aW9uJyk7XG52YXIgX2lzRXF1YWwgPSByZXF1aXJlKCdsb2Rhc2gvaXNFcXVhbCcpOyAvLyB0byBhdm9pZCBzaGFkb3dpbmdcbnZhciBoYXMgPSByZXF1aXJlKCdsb2Rhc2gvaGFzJyk7XG52YXIgcmVzdWx0ID0gcmVxdWlyZSgnbG9kYXNoL3Jlc3VsdCcpO1xudmFyIHVuaW9uID0gcmVxdWlyZSgnbG9kYXNoL3VuaW9uJyk7XG52YXIgRXZlbnRzID0gcmVxdWlyZSgnYW1wZXJzYW5kLWV2ZW50cycpO1xudmFyIEtleVRyZWUgPSByZXF1aXJlKCdrZXktdHJlZS1zdG9yZScpO1xudmFyIGFycmF5TmV4dCA9IHJlcXVpcmUoJ2FycmF5LW5leHQnKTtcbnZhciBjaGFuZ2VSRSA9IC9eY2hhbmdlOi87XG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuXG5mdW5jdGlvbiBCYXNlKGF0dHJzLCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcbiAgICB0aGlzLmNpZCB8fCAodGhpcy5jaWQgPSB1bmlxdWVJZCgnc3RhdGUnKSk7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgdGhpcy5fdmFsdWVzID0ge307XG4gICAgdGhpcy5fZXZlbnRCdWJibGluZ0hhbmRsZXJDYWNoZSA9IHt9O1xuICAgIHRoaXMuX2RlZmluaXRpb24gPSBPYmplY3QuY3JlYXRlKHRoaXMuX2RlZmluaXRpb24pO1xuICAgIGlmIChvcHRpb25zLnBhcnNlKSBhdHRycyA9IHRoaXMucGFyc2UoYXR0cnMsIG9wdGlvbnMpO1xuICAgIHRoaXMucGFyZW50ID0gb3B0aW9ucy5wYXJlbnQ7XG4gICAgdGhpcy5jb2xsZWN0aW9uID0gb3B0aW9ucy5jb2xsZWN0aW9uO1xuICAgIHRoaXMuX2tleVRyZWUgPSBuZXcgS2V5VHJlZSgpO1xuICAgIHRoaXMuX2luaXRDb2xsZWN0aW9ucygpO1xuICAgIHRoaXMuX2luaXRDaGlsZHJlbigpO1xuICAgIHRoaXMuX2NhY2hlID0ge307XG4gICAgdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzID0ge307XG4gICAgaWYgKGF0dHJzKSB0aGlzLnNldChhdHRycywgYXNzaWduKHtzaWxlbnQ6IHRydWUsIGluaXRpYWw6IHRydWV9LCBvcHRpb25zKSk7XG4gICAgdGhpcy5fY2hhbmdlZCA9IHt9O1xuICAgIGlmICh0aGlzLl9kZXJpdmVkKSB0aGlzLl9pbml0RGVyaXZlZCgpO1xuICAgIGlmIChvcHRpb25zLmluaXQgIT09IGZhbHNlKSB0aGlzLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuYXNzaWduKEJhc2UucHJvdG90eXBlLCBFdmVudHMsIHtcbiAgICAvLyBjYW4gYmUgYWxsb3csIGlnbm9yZSwgcmVqZWN0XG4gICAgZXh0cmFQcm9wZXJ0aWVzOiAnaWdub3JlJyxcblxuICAgIGlkQXR0cmlidXRlOiAnaWQnLFxuXG4gICAgbmFtZXNwYWNlQXR0cmlidXRlOiAnbmFtZXNwYWNlJyxcblxuICAgIHR5cGVBdHRyaWJ1dGU6ICdtb2RlbFR5cGUnLFxuXG4gICAgLy8gU3R1YmJlZCBvdXQgdG8gYmUgb3ZlcndyaXR0ZW5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvLyBHZXQgSUQgb2YgbW9kZWwgcGVyIGNvbmZpZ3VyYXRpb24uXG4gICAgLy8gU2hvdWxkICphbHdheXMqIGJlIGhvdyBJRCBpcyBkZXRlcm1pbmVkIGJ5IG90aGVyIGNvZGUuXG4gICAgZ2V0SWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbdGhpcy5pZEF0dHJpYnV0ZV07XG4gICAgfSxcblxuICAgIC8vIEdldCBuYW1lc3BhY2Ugb2YgbW9kZWwgcGVyIGNvbmZpZ3VyYXRpb24uXG4gICAgLy8gU2hvdWxkICphbHdheXMqIGJlIGhvdyBuYW1lc3BhY2UgaXMgZGV0ZXJtaW5lZCBieSBvdGhlciBjb2RlLlxuICAgIGdldE5hbWVzcGFjZTogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpc1t0aGlzLm5hbWVzcGFjZUF0dHJpYnV0ZV07XG4gICAgfSxcblxuICAgIC8vIEdldCB0eXBlIG9mIG1vZGVsIHBlciBjb25maWd1cmF0aW9uLlxuICAgIC8vIFNob3VsZCAqYWx3YXlzKiBiZSBob3cgdHlwZSBpcyBkZXRlcm1pbmVkIGJ5IG90aGVyIGNvZGUuXG4gICAgZ2V0VHlwZTogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpc1t0aGlzLnR5cGVBdHRyaWJ1dGVdO1xuICAgIH0sXG5cbiAgICAvLyBBIG1vZGVsIGlzIG5ldyBpZiBpdCBoYXMgbmV2ZXIgYmVlbiBzYXZlZCB0byB0aGUgc2VydmVyLCBhbmQgbGFja3MgYW4gaWQuXG4gICAgaXNOZXc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SWQoKSA9PSBudWxsO1xuICAgIH0sXG5cbiAgICAvLyBnZXQgSFRNTC1lc2NhcGVkIHZhbHVlIG9mIGF0dHJpYnV0ZVxuICAgIGVzY2FwZTogZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgICAgcmV0dXJuIGVzY2FwZSh0aGlzLmdldChhdHRyKSk7XG4gICAgfSxcblxuICAgIC8vIENoZWNrIGlmIHRoZSBtb2RlbCBpcyBjdXJyZW50bHkgaW4gYSB2YWxpZCBzdGF0ZS5cbiAgICBpc1ZhbGlkOiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGUoe30sIGFzc2lnbihvcHRpb25zIHx8IHt9LCB7IHZhbGlkYXRlOiB0cnVlIH0pKTtcbiAgICB9LFxuXG4gICAgLy8gUGFyc2UgY2FuIGJlIHVzZWQgcmVtYXAvcmVzdHJ1Y3R1cmUvcmVuYW1lIGluY29taW5nIHByb3BlcnRpZXNcbiAgICAvLyBiZWZvcmUgdGhleSBhcmUgYXBwbGllZCB0byBhdHRyaWJ1dGVzLlxuICAgIHBhcnNlOiBmdW5jdGlvbiAocmVzcCwgb3B0aW9ucykge1xuICAgICAgICAvL2pzaGludCB1bnVzZWQ6ZmFsc2VcbiAgICAgICAgcmV0dXJuIHJlc3A7XG4gICAgfSxcblxuICAgIC8vIFNlcmlhbGl6ZSBpcyB0aGUgaW52ZXJzZSBvZiBgcGFyc2VgIGl0IGxldHMgeW91IG1hc3NhZ2UgZGF0YVxuICAgIC8vIG9uIHRoZSB3YXkgb3V0LiBCZWZvcmUsIHNlbmRpbmcgdG8gc2VydmVyLCBmb3IgZXhhbXBsZS5cbiAgICBzZXJpYWxpemU6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIHZhciBhdHRyT3B0cyA9IGFzc2lnbih7cHJvcHM6IHRydWV9LCBvcHRpb25zKTtcbiAgICAgICAgdmFyIHJlcyA9IHRoaXMuZ2V0QXR0cmlidXRlcyhhdHRyT3B0cywgdHJ1ZSk7XG4gICAgICAgIFxuICAgICAgICB2YXIgc2V0RnJvbVNlcmlhbGl6ZWRWYWx1ZSA9IGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG5cdCAgICAgICAgcmVzW2tleV0gPSB0aGlzW2tleV0uc2VyaWFsaXplKCk7XG4gICAgICAgIH0uYmluZCh0aGlzKTtcbiAgICAgICAgXG4gICAgICAgIGZvck93bih0aGlzLl9jaGlsZHJlbiwgc2V0RnJvbVNlcmlhbGl6ZWRWYWx1ZSk7XG4gICAgICAgIGZvck93bih0aGlzLl9jb2xsZWN0aW9ucywgc2V0RnJvbVNlcmlhbGl6ZWRWYWx1ZSk7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfSxcblxuICAgIC8vIE1haW4gc2V0IG1ldGhvZCB1c2VkIGJ5IGdlbmVyYXRlZCBzZXR0ZXJzL2dldHRlcnMgYW5kIGNhblxuICAgIC8vIGJlIHVzZWQgZGlyZWN0bHkgaWYgeW91IG5lZWQgdG8gcGFzcyBvcHRpb25zIG9yIHNldCBtdWx0aXBsZVxuICAgIC8vIHByb3BlcnRpZXMgYXQgb25jZS5cbiAgICBzZXQ6IGZ1bmN0aW9uIChrZXksIHZhbHVlLCBvcHRpb25zKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGV4dHJhUHJvcGVydGllcyA9IHRoaXMuZXh0cmFQcm9wZXJ0aWVzO1xuICAgICAgICB2YXIgd2FzQ2hhbmdpbmcsIGNoYW5nZUV2ZW50cywgbmV3VHlwZSwgbmV3VmFsLCBkZWYsIGNhc3QsIGVyciwgYXR0cixcbiAgICAgICAgICAgIGF0dHJzLCBkYXRhVHlwZSwgc2lsZW50LCB1bnNldCwgY3VycmVudFZhbCwgaW5pdGlhbCwgaGFzQ2hhbmdlZCwgaXNFcXVhbCwgb25DaGFuZ2U7XG5cbiAgICAgICAgLy8gSGFuZGxlIGJvdGggYFwia2V5XCIsIHZhbHVlYCBhbmQgYHtrZXk6IHZhbHVlfWAgLXN0eWxlIGFyZ3VtZW50cy5cbiAgICAgICAgaWYgKGlzT2JqZWN0KGtleSkgfHwga2V5ID09PSBudWxsKSB7XG4gICAgICAgICAgICBhdHRycyA9IGtleTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSB2YWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGF0dHJzID0ge307XG4gICAgICAgICAgICBhdHRyc1trZXldID0gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgICAgICBpZiAoIXRoaXMuX3ZhbGlkYXRlKGF0dHJzLCBvcHRpb25zKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIEV4dHJhY3QgYXR0cmlidXRlcyBhbmQgb3B0aW9ucy5cbiAgICAgICAgdW5zZXQgPSBvcHRpb25zLnVuc2V0O1xuICAgICAgICBzaWxlbnQgPSBvcHRpb25zLnNpbGVudDtcbiAgICAgICAgaW5pdGlhbCA9IG9wdGlvbnMuaW5pdGlhbDtcblxuICAgICAgICAvLyBJbml0aWFsaXplIGNoYW5nZSB0cmFja2luZy5cbiAgICAgICAgd2FzQ2hhbmdpbmcgPSB0aGlzLl9jaGFuZ2luZztcbiAgICAgICAgdGhpcy5fY2hhbmdpbmcgPSB0cnVlO1xuICAgICAgICBjaGFuZ2VFdmVudHMgPSBbXTtcblxuICAgICAgICAvLyBpZiBub3QgYWxyZWFkeSBjaGFuZ2luZywgc3RvcmUgcHJldmlvdXNcbiAgICAgICAgaWYgKGluaXRpYWwpIHtcbiAgICAgICAgICAgIHRoaXMuX3ByZXZpb3VzQXR0cmlidXRlcyA9IHt9O1xuICAgICAgICB9IGVsc2UgaWYgKCF3YXNDaGFuZ2luZykge1xuICAgICAgICAgICAgdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzID0gdGhpcy5hdHRyaWJ1dGVzO1xuICAgICAgICAgICAgdGhpcy5fY2hhbmdlZCA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIGVhY2ggYHNldGAgYXR0cmlidXRlLi4uXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBrZXlzID0gT2JqZWN0LmtleXMoYXR0cnMpLCBsZW4gPSBrZXlzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBhdHRyID0ga2V5c1tpXTtcbiAgICAgICAgICAgIG5ld1ZhbCA9IGF0dHJzW2F0dHJdO1xuICAgICAgICAgICAgbmV3VHlwZSA9IHR5cGVvZiBuZXdWYWw7XG4gICAgICAgICAgICBjdXJyZW50VmFsID0gdGhpcy5fdmFsdWVzW2F0dHJdO1xuICAgICAgICAgICAgZGVmID0gdGhpcy5fZGVmaW5pdGlvblthdHRyXTtcblxuICAgICAgICAgICAgaWYgKCFkZWYpIHtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGlzIGlzIGEgY2hpbGQgbW9kZWwgb3IgY29sbGVjdGlvblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jaGlsZHJlblthdHRyXSB8fCB0aGlzLl9jb2xsZWN0aW9uc1thdHRyXSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWlzT2JqZWN0KG5ld1ZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbCA9IHt9O1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpc1thdHRyXS5zZXQobmV3VmFsLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChleHRyYVByb3BlcnRpZXMgPT09ICdpZ25vcmUnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXh0cmFQcm9wZXJ0aWVzID09PSAncmVqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdObyBcIicgKyBhdHRyICsgJ1wiIHByb3BlcnR5IGRlZmluZWQgb24gJyArICh0aGlzLnR5cGUgfHwgJ3RoaXMnKSArICcgbW9kZWwgYW5kIGV4dHJhUHJvcGVydGllcyBub3Qgc2V0IHRvIFwiaWdub3JlXCIgb3IgXCJhbGxvd1wiJyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChleHRyYVByb3BlcnRpZXMgPT09ICdhbGxvdycpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmID0gdGhpcy5fY3JlYXRlUHJvcGVydHlEZWZpbml0aW9uKGF0dHIsICdhbnknKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV4dHJhUHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIHZhbHVlIGZvciBleHRyYVByb3BlcnRpZXM6IFwiJyArIGV4dHJhUHJvcGVydGllcyArICdcIicpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaXNFcXVhbCA9IHRoaXMuX2dldENvbXBhcmVGb3JUeXBlKGRlZi50eXBlKTtcbiAgICAgICAgICAgIG9uQ2hhbmdlID0gdGhpcy5fZ2V0T25DaGFuZ2VGb3JUeXBlKGRlZi50eXBlKTtcbiAgICAgICAgICAgIGRhdGFUeXBlID0gdGhpcy5fZGF0YVR5cGVzW2RlZi50eXBlXTtcblxuICAgICAgICAgICAgLy8gY2hlY2sgdHlwZSBpZiB3ZSBoYXZlIG9uZVxuICAgICAgICAgICAgaWYgKGRhdGFUeXBlICYmIGRhdGFUeXBlLnNldCkge1xuICAgICAgICAgICAgICAgIGNhc3QgPSBkYXRhVHlwZS5zZXQobmV3VmFsKTtcbiAgICAgICAgICAgICAgICBuZXdWYWwgPSBjYXN0LnZhbDtcbiAgICAgICAgICAgICAgICBuZXdUeXBlID0gY2FzdC50eXBlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB3ZSd2ZSBkZWZpbmVkIGEgdGVzdCwgcnVuIGl0XG4gICAgICAgICAgICBpZiAoZGVmLnRlc3QpIHtcbiAgICAgICAgICAgICAgICBlcnIgPSBkZWYudGVzdC5jYWxsKHRoaXMsIG5ld1ZhbCwgbmV3VHlwZSk7XG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQcm9wZXJ0eSBcXCcnICsgYXR0ciArICdcXCcgZmFpbGVkIHZhbGlkYXRpb24gd2l0aCBlcnJvcjogJyArIGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB3ZSBhcmUgcmVxdWlyZWQgYnV0IHVuZGVmaW5lZCwgdGhyb3cgZXJyb3IuXG4gICAgICAgICAgICAvLyBJZiB3ZSBhcmUgbnVsbCBhbmQgYXJlIG5vdCBhbGxvd2luZyBudWxsLCB0aHJvdyBlcnJvclxuICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBhIGRlZmluZWQgdHlwZSBhbmQgdGhlIG5ldyB0eXBlIGRvZXNuJ3QgbWF0Y2gsIGFuZCB3ZSBhcmUgbm90IG51bGwsIHRocm93IGVycm9yLlxuICAgICAgICAgICAgLy8gSWYgd2UgcmVxdWlyZSBzcGVjaWZpYyB2YWx1ZSBhbmQgbmV3IG9uZSBpcyBub3Qgb25lIG9mIHRoZW0sIHRocm93IGVycm9yICh1bmxlc3MgaXQgaGFzIGRlZmF1bHQgdmFsdWUgb3Igd2UncmUgdW5zZXR0aW5nIGl0IHdpdGggdW5kZWZpbmVkKS5cblxuICAgICAgICAgICAgaWYgKG5ld1ZhbCA9PT0gdW5kZWZpbmVkICYmIGRlZi5yZXF1aXJlZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1JlcXVpcmVkIHByb3BlcnR5IFxcJycgKyBhdHRyICsgJ1xcJyBtdXN0IGJlIG9mIHR5cGUgJyArIGRlZi50eXBlICsgJy4gVHJpZWQgdG8gc2V0ICcgKyBuZXdWYWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5ld1ZhbCA9PT0gbnVsbCAmJiBkZWYucmVxdWlyZWQgJiYgIWRlZi5hbGxvd051bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQcm9wZXJ0eSBcXCcnICsgYXR0ciArICdcXCcgbXVzdCBiZSBvZiB0eXBlICcgKyBkZWYudHlwZSArICcgKGNhbm5vdCBiZSBudWxsKS4gVHJpZWQgdG8gc2V0ICcgKyBuZXdWYWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKChkZWYudHlwZSAmJiBkZWYudHlwZSAhPT0gJ2FueScgJiYgZGVmLnR5cGUgIT09IG5ld1R5cGUpICYmIG5ld1ZhbCAhPT0gbnVsbCAmJiBuZXdWYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Byb3BlcnR5IFxcJycgKyBhdHRyICsgJ1xcJyBtdXN0IGJlIG9mIHR5cGUgJyArIGRlZi50eXBlICsgJy4gVHJpZWQgdG8gc2V0ICcgKyBuZXdWYWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRlZi52YWx1ZXMgJiYgIWluY2x1ZGVzKGRlZi52YWx1ZXMsIG5ld1ZhbCkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdFZhbHVlID0gcmVzdWx0KGRlZiwgJ2RlZmF1bHQnKTtcbiAgICAgICAgICAgICAgICBpZiAodW5zZXQgJiYgZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsID0gZGVmYXVsdFZhbHVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXVuc2V0IHx8ICh1bnNldCAmJiBuZXdWYWwgIT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUHJvcGVydHkgXFwnJyArIGF0dHIgKyAnXFwnIG11c3QgYmUgb25lIG9mIHZhbHVlczogJyArIGRlZi52YWx1ZXMuam9pbignLCAnKSArICcuIFRyaWVkIHRvIHNldCAnICsgbmV3VmFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFdlIGtub3cgdGhpcyBoYXMgJ2NoYW5nZWQnIGlmIGl0J3MgdGhlIGluaXRpYWwgc2V0LCBzbyBza2lwIGEgcG90ZW50aWFsbHkgZXhwZW5zaXZlIGlzRXF1YWwgY2hlY2suXG4gICAgICAgICAgICBoYXNDaGFuZ2VkID0gaW5pdGlhbCB8fCAhaXNFcXVhbChjdXJyZW50VmFsLCBuZXdWYWwsIGF0dHIpO1xuXG4gICAgICAgICAgICAvLyBlbmZvcmNlIGBzZXRPbmNlYCBmb3IgcHJvcGVydGllcyBpZiBzZXRcbiAgICAgICAgICAgIGlmIChkZWYuc2V0T25jZSAmJiBjdXJyZW50VmFsICE9PSB1bmRlZmluZWQgJiYgaGFzQ2hhbmdlZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Byb3BlcnR5IFxcJycgKyBhdHRyICsgJ1xcJyBjYW4gb25seSBiZSBzZXQgb25jZS4nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gc2V0L3Vuc2V0IGF0dHJpYnV0ZXMuXG4gICAgICAgICAgICAvLyBJZiB0aGlzIGlzIG5vdCB0aGUgaW5pdGlhbCBzZXQsIGtlZXAgdHJhY2sgb2YgY2hhbmdlZCBhdHRyaWJ1dGVzXG4gICAgICAgICAgICAvLyBhbmQgcHVzaCB0byBjaGFuZ2VFdmVudHMgYXJyYXkgc28gd2UgY2FuIGZpcmUgZXZlbnRzLlxuICAgICAgICAgICAgaWYgKGhhc0NoYW5nZWQpIHtcblxuICAgICAgICAgICAgICAgIC8vIFRoaXMgZmlyZXMgbm8gbWF0dGVyIHdoYXQsIGV2ZW4gb24gaW5pdGlhbCBzZXQuXG4gICAgICAgICAgICAgICAgb25DaGFuZ2UobmV3VmFsLCBjdXJyZW50VmFsLCBhdHRyKTtcblxuICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgYSBjaGFuZ2UgKG5vdCBhbiBpbml0aWFsIHNldCksIG1hcmsgdGhlIGNoYW5nZS5cbiAgICAgICAgICAgICAgICAvLyBOb3RlIGl0J3MgaW1wb3NzaWJsZSB0byB1bnNldCBvbiB0aGUgaW5pdGlhbCBzZXQgKGl0IHdpbGwgYWxyZWFkeSBiZSB1bnNldCksXG4gICAgICAgICAgICAgICAgLy8gc28gd2Ugb25seSBpbmNsdWRlIHRoYXQgbG9naWMgaGVyZS5cbiAgICAgICAgICAgICAgICBpZiAoIWluaXRpYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hhbmdlZFthdHRyXSA9IG5ld1ZhbDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzW2F0dHJdID0gY3VycmVudFZhbDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVuc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGSVhNRSBkZWxldGUgaXMgdmVyeSBzbG93LiBDYW4gd2UgZ2V0IGF3YXkgd2l0aCBzZXR0aW5nIHRvIHVuZGVmaW5lZD9cbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl92YWx1ZXNbYXR0cl07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzaWxlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUV2ZW50cy5wdXNoKHtwcmV2OiBjdXJyZW50VmFsLCB2YWw6IG5ld1ZhbCwga2V5OiBhdHRyfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCF1bnNldCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXNbYXR0cl0gPSBuZXdWYWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBOb3QgY2hhbmdlZFxuICAgICAgICAgICAgICAgIC8vIEZJWE1FIGRlbGV0ZSBpcyB2ZXJ5IHNsb3cuIENhbiB3ZSBnZXQgYXdheSB3aXRoIHNldHRpbmcgdG8gdW5kZWZpbmVkP1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9jaGFuZ2VkW2F0dHJdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmlyZSBldmVudHMuIFRoaXMgYXJyYXkgaXMgbm90IHBvcHVsYXRlZCBpZiB3ZSBhcmUgdG9sZCB0byBiZSBzaWxlbnQuXG4gICAgICAgIGlmIChjaGFuZ2VFdmVudHMubGVuZ3RoKSB0aGlzLl9wZW5kaW5nID0gdHJ1ZTtcbiAgICAgICAgY2hhbmdlRXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKGNoYW5nZSkge1xuICAgICAgICAgICAgc2VsZi50cmlnZ2VyKCdjaGFuZ2U6JyArIGNoYW5nZS5rZXksIHNlbGYsIGNoYW5nZS52YWwsIG9wdGlvbnMpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBZb3UgbWlnaHQgYmUgd29uZGVyaW5nIHdoeSB0aGVyZSdzIGEgYHdoaWxlYCBsb29wIGhlcmUuIENoYW5nZXMgY2FuXG4gICAgICAgIC8vIGJlIHJlY3Vyc2l2ZWx5IG5lc3RlZCB3aXRoaW4gYFwiY2hhbmdlXCJgIGV2ZW50cy5cbiAgICAgICAgaWYgKHdhc0NoYW5naW5nKSByZXR1cm4gdGhpcztcbiAgICAgICAgd2hpbGUgKHRoaXMuX3BlbmRpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuX3BlbmRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlcignY2hhbmdlJywgdGhpcywgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcGVuZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9jaGFuZ2luZyA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgZ2V0OiBmdW5jdGlvbiAoYXR0cikge1xuICAgICAgICByZXR1cm4gdGhpc1thdHRyXTtcbiAgICB9LFxuXG4gICAgLy8gVG9nZ2xlIGJvb2xlYW4gcHJvcGVydGllcyBvciBwcm9wZXJ0aWVzIHRoYXQgaGF2ZSBhIGB2YWx1ZXNgXG4gICAgLy8gYXJyYXkgaW4gaXRzIGRlZmluaXRpb24uXG4gICAgdG9nZ2xlOiBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgdmFyIGRlZiA9IHRoaXMuX2RlZmluaXRpb25bcHJvcGVydHldO1xuICAgICAgICBpZiAoZGVmLnR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgLy8gaWYgaXQncyBhIGJvb2wsIGp1c3QgZmxpcCBpdFxuICAgICAgICAgICAgdGhpc1twcm9wZXJ0eV0gPSAhdGhpc1twcm9wZXJ0eV07XG4gICAgICAgIH0gZWxzZSBpZiAoZGVmICYmIGRlZi52YWx1ZXMpIHtcbiAgICAgICAgICAgIC8vIElmIGl0J3MgYSBwcm9wZXJ0eSB3aXRoIGFuIGFycmF5IG9mIHZhbHVlc1xuICAgICAgICAgICAgLy8gc2tpcCB0byB0aGUgbmV4dCBvbmUgbG9vcGluZyBiYWNrIGlmIGF0IGVuZC5cbiAgICAgICAgICAgIHRoaXNbcHJvcGVydHldID0gYXJyYXlOZXh0KGRlZi52YWx1ZXMsIHRoaXNbcHJvcGVydHldKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0NhbiBvbmx5IHRvZ2dsZSBwcm9wZXJ0aWVzIHRoYXQgYXJlIHR5cGUgYGJvb2xlYW5gIG9yIGhhdmUgYHZhbHVlc2AgYXJyYXkuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8vIEdldCBhbGwgb2YgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG1vZGVsIGF0IHRoZSB0aW1lIG9mIHRoZSBwcmV2aW91c1xuICAgIC8vIGBcImNoYW5nZVwiYCBldmVudC5cbiAgICBwcmV2aW91c0F0dHJpYnV0ZXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNsb25lT2JqKHRoaXMuX3ByZXZpb3VzQXR0cmlidXRlcyk7XG4gICAgfSxcblxuICAgIC8vIERldGVybWluZSBpZiB0aGUgbW9kZWwgaGFzIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgYFwiY2hhbmdlXCJgIGV2ZW50LlxuICAgIC8vIElmIHlvdSBzcGVjaWZ5IGFuIGF0dHJpYnV0ZSBuYW1lLCBkZXRlcm1pbmUgaWYgdGhhdCBhdHRyaWJ1dGUgaGFzIGNoYW5nZWQuXG4gICAgaGFzQ2hhbmdlZDogZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgICAgaWYgKGF0dHIgPT0gbnVsbCkgcmV0dXJuICEhT2JqZWN0LmtleXModGhpcy5fY2hhbmdlZCkubGVuZ3RoO1xuICAgICAgICBpZiAoaGFzKHRoaXMuX2Rlcml2ZWQsIGF0dHIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVyaXZlZFthdHRyXS5kZXBMaXN0LnNvbWUoZnVuY3Rpb24gKGRlcCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhc0NoYW5nZWQoZGVwKTtcbiAgICAgICAgICAgIH0sIHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoYXModGhpcy5fY2hhbmdlZCwgYXR0cik7XG4gICAgfSxcblxuICAgIC8vIFJldHVybiBhbiBvYmplY3QgY29udGFpbmluZyBhbGwgdGhlIGF0dHJpYnV0ZXMgdGhhdCBoYXZlIGNoYW5nZWQsIG9yXG4gICAgLy8gZmFsc2UgaWYgdGhlcmUgYXJlIG5vIGNoYW5nZWQgYXR0cmlidXRlcy4gVXNlZnVsIGZvciBkZXRlcm1pbmluZyB3aGF0XG4gICAgLy8gcGFydHMgb2YgYSB2aWV3IG5lZWQgdG8gYmUgdXBkYXRlZCBhbmQvb3Igd2hhdCBhdHRyaWJ1dGVzIG5lZWQgdG8gYmVcbiAgICAvLyBwZXJzaXN0ZWQgdG8gdGhlIHNlcnZlci4gVW5zZXQgYXR0cmlidXRlcyB3aWxsIGJlIHNldCB0byB1bmRlZmluZWQuXG4gICAgLy8gWW91IGNhbiBhbHNvIHBhc3MgYW4gYXR0cmlidXRlcyBvYmplY3QgdG8gZGlmZiBhZ2FpbnN0IHRoZSBtb2RlbCxcbiAgICAvLyBkZXRlcm1pbmluZyBpZiB0aGVyZSAqd291bGQgYmUqIGEgY2hhbmdlLlxuICAgIGNoYW5nZWRBdHRyaWJ1dGVzOiBmdW5jdGlvbiAoZGlmZikge1xuICAgICAgICBpZiAoIWRpZmYpIHJldHVybiB0aGlzLmhhc0NoYW5nZWQoKSA/IGNsb25lT2JqKHRoaXMuX2NoYW5nZWQpIDogZmFsc2U7XG4gICAgICAgIHZhciB2YWwsIGNoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgdmFyIG9sZCA9IHRoaXMuX2NoYW5naW5nID8gdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzIDogdGhpcy5hdHRyaWJ1dGVzO1xuICAgICAgICB2YXIgZGVmLCBpc0VxdWFsO1xuICAgICAgICBmb3IgKHZhciBhdHRyIGluIGRpZmYpIHtcbiAgICAgICAgICAgIGRlZiA9IHRoaXMuX2RlZmluaXRpb25bYXR0cl07XG4gICAgICAgICAgICBpZiAoIWRlZikgY29udGludWU7XG4gICAgICAgICAgICBpc0VxdWFsID0gdGhpcy5fZ2V0Q29tcGFyZUZvclR5cGUoZGVmLnR5cGUpO1xuICAgICAgICAgICAgaWYgKGlzRXF1YWwob2xkW2F0dHJdLCAodmFsID0gZGlmZlthdHRyXSkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIChjaGFuZ2VkIHx8IChjaGFuZ2VkID0ge30pKVthdHRyXSA9IHZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2hhbmdlZDtcbiAgICB9LFxuXG4gICAgdG9KU09OOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlcmlhbGl6ZSgpO1xuICAgIH0sXG5cbiAgICB1bnNldDogZnVuY3Rpb24gKGF0dHJzLCBvcHRpb25zKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgYXR0cnMgPSBBcnJheS5pc0FycmF5KGF0dHJzKSA/IGF0dHJzIDogW2F0dHJzXTtcbiAgICAgICAgYXR0cnMuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICB2YXIgZGVmID0gc2VsZi5fZGVmaW5pdGlvbltrZXldO1xuICAgICAgICAgICAgaWYgKCFkZWYpIHJldHVybjtcbiAgICAgICAgICAgIHZhciB2YWw7XG4gICAgICAgICAgICBpZiAoZGVmLnJlcXVpcmVkKSB7XG4gICAgICAgICAgICAgICAgdmFsID0gcmVzdWx0KGRlZiwgJ2RlZmF1bHQnKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5zZXQoa2V5LCB2YWwsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5zZXQoa2V5LCB2YWwsIGFzc2lnbih7fSwgb3B0aW9ucywge3Vuc2V0OiB0cnVlfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9LFxuXG4gICAgY2xlYXI6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5hdHRyaWJ1dGVzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgIHNlbGYudW5zZXQoa2V5LCBvcHRpb25zKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBwcmV2aW91czogZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgICAgaWYgKGF0dHIgPT0gbnVsbCB8fCAhT2JqZWN0LmtleXModGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzKS5sZW5ndGgpIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzW2F0dHJdO1xuICAgIH0sXG5cbiAgICAvLyBHZXQgZGVmYXVsdCB2YWx1ZXMgZm9yIGEgY2VydGFpbiB0eXBlXG4gICAgX2dldERlZmF1bHRGb3JUeXBlOiBmdW5jdGlvbiAodHlwZSkge1xuICAgICAgICB2YXIgZGF0YVR5cGUgPSB0aGlzLl9kYXRhVHlwZXNbdHlwZV07XG4gICAgICAgIHJldHVybiBkYXRhVHlwZSAmJiBkYXRhVHlwZVsnZGVmYXVsdCddO1xuICAgIH0sXG5cbiAgICAvLyBEZXRlcm1pbmUgd2hpY2ggY29tcGFyaXNvbiBhbGdvcml0aG0gdG8gdXNlIGZvciBjb21wYXJpbmcgYSBwcm9wZXJ0eVxuICAgIF9nZXRDb21wYXJlRm9yVHlwZTogZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgICAgdmFyIGRhdGFUeXBlID0gdGhpcy5fZGF0YVR5cGVzW3R5cGVdO1xuICAgICAgICBpZiAoZGF0YVR5cGUgJiYgZGF0YVR5cGUuY29tcGFyZSkgcmV0dXJuIGRhdGFUeXBlLmNvbXBhcmUuYmluZCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIF9pc0VxdWFsOyAvLyBpZiBubyBjb21wYXJlIGZ1bmN0aW9uIGlzIGRlZmluZWQsIHVzZSBfLmlzRXF1YWxcbiAgICB9LFxuXG4gICAgX2dldE9uQ2hhbmdlRm9yVHlwZSA6IGZ1bmN0aW9uKHR5cGUpe1xuICAgICAgICB2YXIgZGF0YVR5cGUgPSB0aGlzLl9kYXRhVHlwZXNbdHlwZV07XG4gICAgICAgIGlmIChkYXRhVHlwZSAmJiBkYXRhVHlwZS5vbkNoYW5nZSkgcmV0dXJuIGRhdGFUeXBlLm9uQ2hhbmdlLmJpbmQodGhpcyk7XG4gICAgICAgIHJldHVybiBub29wO1xuICAgIH0sXG5cbiAgICAvLyBSdW4gdmFsaWRhdGlvbiBhZ2FpbnN0IHRoZSBuZXh0IGNvbXBsZXRlIHNldCBvZiBtb2RlbCBhdHRyaWJ1dGVzLFxuICAgIC8vIHJldHVybmluZyBgdHJ1ZWAgaWYgYWxsIGlzIHdlbGwuIE90aGVyd2lzZSwgZmlyZSBhbiBgXCJpbnZhbGlkXCJgIGV2ZW50LlxuICAgIF92YWxpZGF0ZTogZnVuY3Rpb24gKGF0dHJzLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghb3B0aW9ucy52YWxpZGF0ZSB8fCAhdGhpcy52YWxpZGF0ZSkgcmV0dXJuIHRydWU7XG4gICAgICAgIGF0dHJzID0gYXNzaWduKHt9LCB0aGlzLmF0dHJpYnV0ZXMsIGF0dHJzKTtcbiAgICAgICAgdmFyIGVycm9yID0gdGhpcy52YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlKGF0dHJzLCBvcHRpb25zKSB8fCBudWxsO1xuICAgICAgICBpZiAoIWVycm9yKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgdGhpcy50cmlnZ2VyKCdpbnZhbGlkJywgdGhpcywgZXJyb3IsIGFzc2lnbihvcHRpb25zIHx8IHt9LCB7dmFsaWRhdGlvbkVycm9yOiBlcnJvcn0pKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICBfY3JlYXRlUHJvcGVydHlEZWZpbml0aW9uOiBmdW5jdGlvbiAobmFtZSwgZGVzYywgaXNTZXNzaW9uKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVQcm9wZXJ0eURlZmluaXRpb24odGhpcywgbmFtZSwgZGVzYywgaXNTZXNzaW9uKTtcbiAgICB9LFxuXG4gICAgLy8ganVzdCBtYWtlcyBmcmllbmRsaWVyIGVycm9ycyB3aGVuIHRyeWluZyB0byBkZWZpbmUgYSBuZXcgbW9kZWxcbiAgICAvLyBvbmx5IHVzZWQgd2hlbiBzZXR0aW5nIHVwIG9yaWdpbmFsIHByb3BlcnR5IGRlZmluaXRpb25zXG4gICAgX2Vuc3VyZVZhbGlkVHlwZTogZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIGluY2x1ZGVzKFsnc3RyaW5nJywgJ251bWJlcicsICdib29sZWFuJywgJ2FycmF5JywgJ29iamVjdCcsICdkYXRlJywgJ3N0YXRlJywgJ2FueSddXG4gICAgICAgICAgICAuY29uY2F0KE9iamVjdC5rZXlzKHRoaXMuX2RhdGFUeXBlcykpLCB0eXBlKSA/IHR5cGUgOiB1bmRlZmluZWQ7XG4gICAgfSxcblxuICAgIGdldEF0dHJpYnV0ZXM6IGZ1bmN0aW9uIChvcHRpb25zLCByYXcpIHtcbiAgICAgICAgb3B0aW9ucyA9IGFzc2lnbih7XG4gICAgICAgICAgICBzZXNzaW9uOiBmYWxzZSxcbiAgICAgICAgICAgIHByb3BzOiBmYWxzZSxcbiAgICAgICAgICAgIGRlcml2ZWQ6IGZhbHNlXG4gICAgICAgIH0sIG9wdGlvbnMgfHwge30pO1xuICAgICAgICB2YXIgcmVzID0ge307XG4gICAgICAgIHZhciB2YWwsIGRlZjtcbiAgICAgICAgZm9yICh2YXIgaXRlbSBpbiB0aGlzLl9kZWZpbml0aW9uKSB7XG4gICAgICAgICAgICBkZWYgPSB0aGlzLl9kZWZpbml0aW9uW2l0ZW1dO1xuICAgICAgICAgICAgaWYgKChvcHRpb25zLnNlc3Npb24gJiYgZGVmLnNlc3Npb24pIHx8IChvcHRpb25zLnByb3BzICYmICFkZWYuc2Vzc2lvbikpIHtcbiAgICAgICAgICAgICAgICB2YWwgPSByYXcgPyB0aGlzLl92YWx1ZXNbaXRlbV0gOiB0aGlzW2l0ZW1dO1xuICAgICAgICAgICAgICAgIGlmIChyYXcgJiYgdmFsICYmIGlzRnVuY3Rpb24odmFsLnNlcmlhbGl6ZSkpIHZhbCA9IHZhbC5zZXJpYWxpemUoKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ3VuZGVmaW5lZCcpIHZhbCA9IHJlc3VsdChkZWYsICdkZWZhdWx0Jyk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWwgIT09ICd1bmRlZmluZWQnKSByZXNbaXRlbV0gPSB2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuZGVyaXZlZCkge1xuICAgICAgICAgICAgZm9yICh2YXIgZGVyaXZlZEl0ZW0gaW4gdGhpcy5fZGVyaXZlZCkgcmVzW2Rlcml2ZWRJdGVtXSA9IHRoaXNbZGVyaXZlZEl0ZW1dO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfSxcblxuICAgIF9pbml0RGVyaXZlZDogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgZm9yT3duKHRoaXMuX2Rlcml2ZWQsIGZ1bmN0aW9uICh2YWx1ZSwgbmFtZSkge1xuICAgICAgICAgICAgdmFyIGRlZiA9IHNlbGYuX2Rlcml2ZWRbbmFtZV07XG4gICAgICAgICAgICBkZWYuZGVwcyA9IGRlZi5kZXBMaXN0O1xuXG4gICAgICAgICAgICB2YXIgdXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBuZXdWYWwgPSBkZWYuZm4uY2FsbChzZWxmKTtcblxuICAgICAgICAgICAgICAgIGlmIChzZWxmLl9jYWNoZVtuYW1lXSAhPT0gbmV3VmFsIHx8ICFkZWYuY2FjaGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlZi5jYWNoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcHJldmlvdXNBdHRyaWJ1dGVzW25hbWVdID0gc2VsZi5fY2FjaGVbbmFtZV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc2VsZi5fY2FjaGVbbmFtZV0gPSBuZXdWYWw7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYudHJpZ2dlcignY2hhbmdlOicgKyBuYW1lLCBzZWxmLCBzZWxmLl9jYWNoZVtuYW1lXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgZGVmLmRlcHMuZm9yRWFjaChmdW5jdGlvbiAocHJvcFN0cmluZykge1xuICAgICAgICAgICAgICAgIHNlbGYuX2tleVRyZWUuYWRkKHByb3BTdHJpbmcsIHVwZGF0ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5vbignYWxsJywgZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xuICAgICAgICAgICAgaWYgKGNoYW5nZVJFLnRlc3QoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgICAgIHNlbGYuX2tleVRyZWUuZ2V0KGV2ZW50TmFtZS5zcGxpdCgnOicpWzFdKS5mb3JFYWNoKGZ1bmN0aW9uIChmbikge1xuICAgICAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB0aGlzKTtcbiAgICB9LFxuXG4gICAgX2dldERlcml2ZWRQcm9wZXJ0eTogZnVuY3Rpb24gKG5hbWUsIGZsdXNoQ2FjaGUpIHtcbiAgICAgICAgLy8gaXMgdGhpcyBhIGRlcml2ZWQgcHJvcGVydHkgdGhhdCBpcyBjYWNoZWRcbiAgICAgICAgaWYgKHRoaXMuX2Rlcml2ZWRbbmFtZV0uY2FjaGUpIHtcbiAgICAgICAgICAgIC8vc2V0IGlmIHRoaXMgaXMgdGhlIGZpcnN0IHRpbWUsIG9yIGZsdXNoQ2FjaGUgaXMgc2V0XG4gICAgICAgICAgICBpZiAoZmx1c2hDYWNoZSB8fCAhdGhpcy5fY2FjaGUuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZVtuYW1lXSA9IHRoaXMuX2Rlcml2ZWRbbmFtZV0uZm4uYXBwbHkodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY2FjaGVbbmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVyaXZlZFtuYW1lXS5mbi5hcHBseSh0aGlzKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBfaW5pdENvbGxlY3Rpb25zOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb2xsO1xuICAgICAgICBpZiAoIXRoaXMuX2NvbGxlY3Rpb25zKSByZXR1cm47XG4gICAgICAgIGZvciAoY29sbCBpbiB0aGlzLl9jb2xsZWN0aW9ucykge1xuICAgICAgICAgICAgdGhpcy5fc2FmZVNldChjb2xsLCBuZXcgdGhpcy5fY29sbGVjdGlvbnNbY29sbF0obnVsbCwge3BhcmVudDogdGhpc30pKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBfaW5pdENoaWxkcmVuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjaGlsZDtcbiAgICAgICAgaWYgKCF0aGlzLl9jaGlsZHJlbikgcmV0dXJuO1xuICAgICAgICBmb3IgKGNoaWxkIGluIHRoaXMuX2NoaWxkcmVuKSB7XG4gICAgICAgICAgICB0aGlzLl9zYWZlU2V0KGNoaWxkLCBuZXcgdGhpcy5fY2hpbGRyZW5bY2hpbGRdKHt9LCB7cGFyZW50OiB0aGlzfSkpO1xuICAgICAgICAgICAgdGhpcy5saXN0ZW5Ubyh0aGlzW2NoaWxkXSwgJ2FsbCcsIHRoaXMuX2dldENhY2hlZEV2ZW50QnViYmxpbmdIYW5kbGVyKGNoaWxkKSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLy8gUmV0dXJucyBhIGJvdW5kIGhhbmRsZXIgZm9yIGRvaW5nIGV2ZW50IGJ1YmJsaW5nIHdoaWxlXG4gICAgLy8gYWRkaW5nIGEgbmFtZSB0byB0aGUgY2hhbmdlIHN0cmluZy5cbiAgICBfZ2V0Q2FjaGVkRXZlbnRCdWJibGluZ0hhbmRsZXI6IGZ1bmN0aW9uIChwcm9wZXJ0eU5hbWUpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9ldmVudEJ1YmJsaW5nSGFuZGxlckNhY2hlW3Byb3BlcnR5TmFtZV0pIHtcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50QnViYmxpbmdIYW5kbGVyQ2FjaGVbcHJvcGVydHlOYW1lXSA9IGZ1bmN0aW9uIChuYW1lLCBtb2RlbCwgbmV3VmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2hhbmdlUkUudGVzdChuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoJ2NoYW5nZTonICsgcHJvcGVydHlOYW1lICsgJy4nICsgbmFtZS5zcGxpdCgnOicpWzFdLCBtb2RlbCwgbmV3VmFsdWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ2NoYW5nZScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKCdjaGFuZ2UnLCB0aGlzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LmJpbmQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50QnViYmxpbmdIYW5kbGVyQ2FjaGVbcHJvcGVydHlOYW1lXTtcbiAgICB9LFxuXG4gICAgLy8gQ2hlY2sgdGhhdCBhbGwgcmVxdWlyZWQgYXR0cmlidXRlcyBhcmUgcHJlc2VudFxuICAgIF92ZXJpZnlSZXF1aXJlZDogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHJpYnV0ZXM7IC8vIHNob3VsZCBpbmNsdWRlIHNlc3Npb25cbiAgICAgICAgZm9yICh2YXIgZGVmIGluIHRoaXMuX2RlZmluaXRpb24pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9kZWZpbml0aW9uW2RlZl0ucmVxdWlyZWQgJiYgdHlwZW9mIGF0dHJzW2RlZl0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICAvLyBleHBvc2Ugc2FmZVNldCBtZXRob2RcbiAgICBfc2FmZVNldDogZnVuY3Rpb24gc2FmZVNldChwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKHByb3BlcnR5IGluIHRoaXMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRW5jb3VudGVyZWQgbmFtZXNwYWNlIGNvbGxpc2lvbiB3aGlsZSBzZXR0aW5nIGluc3RhbmNlIHByb3BlcnR5IGAnICsgcHJvcGVydHkgKyAnYCcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXNbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn0pO1xuXG4vLyBnZXR0ZXIgZm9yIGF0dHJpYnV0ZXNcbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEJhc2UucHJvdG90eXBlLCB7XG4gICAgYXR0cmlidXRlczoge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZXMoe3Byb3BzOiB0cnVlLCBzZXNzaW9uOiB0cnVlfSk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGFsbDoge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgIHNlc3Npb246IHRydWUsXG4gICAgICAgICAgICAgICAgcHJvcHM6IHRydWUsXG4gICAgICAgICAgICAgICAgZGVyaXZlZDogdHJ1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGlzU3RhdGU6IHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlOyB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uICgpIHsgfVxuICAgIH1cbn0pO1xuXG4vLyBoZWxwZXIgZm9yIGNyZWF0aW5nL3N0b3JpbmcgcHJvcGVydHkgZGVmaW5pdGlvbnMgYW5kIGNyZWF0aW5nXG4vLyBhcHByb3ByaWF0ZSBnZXR0ZXJzL3NldHRlcnNcbmZ1bmN0aW9uIGNyZWF0ZVByb3BlcnR5RGVmaW5pdGlvbihvYmplY3QsIG5hbWUsIGRlc2MsIGlzU2Vzc2lvbikge1xuICAgIHZhciBkZWYgPSBvYmplY3QuX2RlZmluaXRpb25bbmFtZV0gPSB7fTtcbiAgICB2YXIgdHlwZSwgZGVzY0FycmF5O1xuXG4gICAgaWYgKGlzU3RyaW5nKGRlc2MpKSB7XG4gICAgICAgIC8vIGdyYWIgb3VyIHR5cGUgaWYgYWxsIHdlJ3ZlIGdvdCBpcyBhIHN0cmluZ1xuICAgICAgICB0eXBlID0gb2JqZWN0Ll9lbnN1cmVWYWxpZFR5cGUoZGVzYyk7XG4gICAgICAgIGlmICh0eXBlKSBkZWYudHlwZSA9IHR5cGU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy9UcmFuc2Zvcm0gYXJyYXkgb2YgWyd0eXBlJywgcmVxdWlyZWQsIGRlZmF1bHRdIHRvIG9iamVjdCBmb3JtXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRlc2MpKSB7XG4gICAgICAgICAgICBkZXNjQXJyYXkgPSBkZXNjO1xuICAgICAgICAgICAgZGVzYyA9IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBkZXNjQXJyYXlbMF0sXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGRlc2NBcnJheVsxXSxcbiAgICAgICAgICAgICAgICAnZGVmYXVsdCc6IGRlc2NBcnJheVsyXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHR5cGUgPSBvYmplY3QuX2Vuc3VyZVZhbGlkVHlwZShkZXNjLnR5cGUpO1xuICAgICAgICBpZiAodHlwZSkgZGVmLnR5cGUgPSB0eXBlO1xuXG4gICAgICAgIGlmIChkZXNjLnJlcXVpcmVkKSBkZWYucmVxdWlyZWQgPSB0cnVlO1xuXG4gICAgICAgIGlmIChkZXNjWydkZWZhdWx0J10gJiYgdHlwZW9mIGRlc2NbJ2RlZmF1bHQnXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBkZWZhdWx0IHZhbHVlIGZvciAnICsgbmFtZSArICcgY2Fubm90IGJlIGFuIG9iamVjdC9hcnJheSwgbXVzdCBiZSBhIHZhbHVlIG9yIGEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhIHZhbHVlL29iamVjdC9hcnJheScpO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVmWydkZWZhdWx0J10gPSBkZXNjWydkZWZhdWx0J107XG5cbiAgICAgICAgZGVmLmFsbG93TnVsbCA9IGRlc2MuYWxsb3dOdWxsID8gZGVzYy5hbGxvd051bGwgOiBmYWxzZTtcbiAgICAgICAgaWYgKGRlc2Muc2V0T25jZSkgZGVmLnNldE9uY2UgPSB0cnVlO1xuICAgICAgICBpZiAoZGVmLnJlcXVpcmVkICYmIGRlZlsnZGVmYXVsdCddID09PSB1bmRlZmluZWQgJiYgIWRlZi5zZXRPbmNlKSBkZWZbJ2RlZmF1bHQnXSA9IG9iamVjdC5fZ2V0RGVmYXVsdEZvclR5cGUodHlwZSk7XG4gICAgICAgIGRlZi50ZXN0ID0gZGVzYy50ZXN0O1xuICAgICAgICBkZWYudmFsdWVzID0gZGVzYy52YWx1ZXM7XG4gICAgfVxuICAgIGlmIChpc1Nlc3Npb24pIGRlZi5zZXNzaW9uID0gdHJ1ZTtcblxuICAgIGlmICghdHlwZSkge1xuICAgICAgICB0eXBlID0gaXNTdHJpbmcoZGVzYykgPyBkZXNjIDogZGVzYy50eXBlO1xuICAgICAgICAvLyBUT0RPOiBzdGFydCB0aHJvd2luZyBhIFR5cGVFcnJvciBpbiBmdXR1cmUgbWFqb3IgdmVyc2lvbnMgaW5zdGVhZCBvZiB3YXJuaW5nXG4gICAgICAgIGNvbnNvbGUud2FybignSW52YWxpZCBkYXRhIHR5cGUgb2YgYCcgKyB0eXBlICsgJ2AgZm9yIGAnICsgbmFtZSArICdgIHByb3BlcnR5LiBVc2Ugb25lIG9mIHRoZSBkZWZhdWx0IHR5cGVzIG9yIGRlZmluZSB5b3VyIG93bicpO1xuICAgIH1cblxuICAgIC8vIGRlZmluZSBhIGdldHRlci9zZXR0ZXIgb24gdGhlIHByb3RvdHlwZVxuICAgIC8vIGJ1dCB0aGV5IGdldC9zZXQgb24gdGhlIGluc3RhbmNlXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iamVjdCwgbmFtZSwge1xuICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0KG5hbWUsIHZhbCk7XG4gICAgICAgIH0sXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLl92YWx1ZXMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcignWW91IG1heSBiZSB0cnlpbmcgdG8gYGV4dGVuZGAgYSBzdGF0ZSBvYmplY3Qgd2l0aCBcIicgKyBuYW1lICsgJ1wiIHdoaWNoIGhhcyBiZWVuIGRlZmluZWQgaW4gYHByb3BzYCBvbiB0aGUgb2JqZWN0IGJlaW5nIGV4dGVuZGVkJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLl92YWx1ZXNbbmFtZV07XG4gICAgICAgICAgICB2YXIgdHlwZURlZiA9IHRoaXMuX2RhdGFUeXBlc1tkZWYudHlwZV07XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlRGVmICYmIHR5cGVEZWYuZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdHlwZURlZi5nZXQodmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGVmYXVsdFZhbHVlID0gcmVzdWx0KGRlZiwgJ2RlZmF1bHQnKTtcbiAgICAgICAgICAgIHRoaXMuX3ZhbHVlc1tuYW1lXSA9IGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgIC8vIElmIHdlJ3ZlIHNldCBhIGRlZmF1bHRWYWx1ZSwgZmlyZSBhIGNoYW5nZSBoYW5kbGVyIGVmZmVjdGl2ZWx5IG1hcmtpbmdcbiAgICAgICAgICAgIC8vIGl0cyBjaGFuZ2UgZnJvbSB1bmRlZmluZWQgdG8gdGhlIGRlZmF1bHQgdmFsdWUuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGRlZmF1bHRWYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICB2YXIgb25DaGFuZ2UgPSB0aGlzLl9nZXRPbkNoYW5nZUZvclR5cGUoZGVmLnR5cGUpO1xuICAgICAgICAgICAgICAgIG9uQ2hhbmdlKGRlZmF1bHRWYWx1ZSwgdmFsdWUsIG5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGRlZjtcbn1cblxuLy8gaGVscGVyIGZvciBjcmVhdGluZyBkZXJpdmVkIHByb3BlcnR5IGRlZmluaXRpb25zXG5mdW5jdGlvbiBjcmVhdGVEZXJpdmVkUHJvcGVydHkobW9kZWxQcm90bywgbmFtZSwgZGVmaW5pdGlvbikge1xuICAgIHZhciBkZWYgPSBtb2RlbFByb3RvLl9kZXJpdmVkW25hbWVdID0ge1xuICAgICAgICBmbjogaXNGdW5jdGlvbihkZWZpbml0aW9uKSA/IGRlZmluaXRpb24gOiBkZWZpbml0aW9uLmZuLFxuICAgICAgICBjYWNoZTogKGRlZmluaXRpb24uY2FjaGUgIT09IGZhbHNlKSxcbiAgICAgICAgZGVwTGlzdDogZGVmaW5pdGlvbi5kZXBzIHx8IFtdXG4gICAgfTtcblxuICAgIC8vIGFkZCB0byBvdXIgc2hhcmVkIGRlcGVuZGVuY3kgbGlzdFxuICAgIGRlZi5kZXBMaXN0LmZvckVhY2goZnVuY3Rpb24gKGRlcCkge1xuICAgICAgICBtb2RlbFByb3RvLl9kZXBzW2RlcF0gPSB1bmlvbihtb2RlbFByb3RvLl9kZXBzW2RlcF0gfHwgW10sIFtuYW1lXSk7XG4gICAgfSk7XG5cbiAgICAvLyBkZWZpbmVkIGEgdG9wLWxldmVsIGdldHRlciBmb3IgZGVyaXZlZCBuYW1lc1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2RlbFByb3RvLCBuYW1lLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldERlcml2ZWRQcm9wZXJ0eShuYW1lKTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYFwiICsgbmFtZSArIFwiYCBpcyBhIGRlcml2ZWQgcHJvcGVydHksIGl0IGNhbid0IGJlIHNldCBkaXJlY3RseS5cIik7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxudmFyIGRhdGFUeXBlcyA9IHtcbiAgICBzdHJpbmc6IHtcbiAgICAgICAgJ2RlZmF1bHQnOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGRhdGU6IHtcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAobmV3VmFsKSB7XG4gICAgICAgICAgICB2YXIgbmV3VHlwZTtcbiAgICAgICAgICAgIGlmIChuZXdWYWwgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIG5ld1R5cGUgPSB0eXBlb2YgbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzRGF0ZShuZXdWYWwpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVyciA9IG51bGw7XG4gICAgICAgICAgICAgICAgdmFyIGRhdGVWYWwgPSBuZXcgRGF0ZShuZXdWYWwpLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICBpZiAoaXNOYU4oZGF0ZVZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIG5ld1ZhbCBjYW50IGJlIHBhcnNlZCwgdGhlbiB0cnkgcGFyc2VJbnQgZmlyc3RcbiAgICAgICAgICAgICAgICAgICAgZGF0ZVZhbCA9IG5ldyBEYXRlKHBhcnNlSW50KG5ld1ZhbCwgMTApKS52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihkYXRlVmFsKSkgZXJyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbmV3VmFsID0gZGF0ZVZhbDtcbiAgICAgICAgICAgICAgICBuZXdUeXBlID0gJ2RhdGUnO1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3VHlwZSA9IHR5cGVvZiBuZXdWYWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXdUeXBlID0gJ2RhdGUnO1xuICAgICAgICAgICAgICAgIG5ld1ZhbCA9IG5ld1ZhbC52YWx1ZU9mKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdmFsOiBuZXdWYWwsXG4gICAgICAgICAgICAgICAgdHlwZTogbmV3VHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgICAgICBpZiAodmFsID09IG51bGwpIHsgcmV0dXJuIHZhbDsgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHZhbCk7XG4gICAgICAgIH0sXG4gICAgICAgICdkZWZhdWx0JzogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKCk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGFycmF5OiB7XG4gICAgICAgIHNldDogZnVuY3Rpb24gKG5ld1ZhbCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB2YWw6IG5ld1ZhbCxcbiAgICAgICAgICAgICAgICB0eXBlOiBBcnJheS5pc0FycmF5KG5ld1ZhbCkgPyAnYXJyYXknIDogdHlwZW9mIG5ld1ZhbFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgJ2RlZmF1bHQnOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9LFxuICAgIG9iamVjdDoge1xuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdWYWwpIHtcbiAgICAgICAgICAgIHZhciBuZXdUeXBlID0gdHlwZW9mIG5ld1ZhbDtcbiAgICAgICAgICAgIC8vIHdlIGhhdmUgdG8gaGF2ZSBhIHdheSBvZiBzdXBwb3J0aW5nIFwibWlzc2luZ1wiIG9iamVjdHMuXG4gICAgICAgICAgICAvLyBOdWxsIGlzIGFuIG9iamVjdCwgYnV0IHNldHRpbmcgYSB2YWx1ZSB0byB1bmRlZmluZWRcbiAgICAgICAgICAgIC8vIHNob3VsZCB3b3JrIHRvbywgSU1PLiBXZSBqdXN0IG92ZXJyaWRlIGl0LCBpbiB0aGF0IGNhc2UuXG4gICAgICAgICAgICBpZiAobmV3VHlwZSAhPT0gJ29iamVjdCcgJiYgbmV3VmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBuZXdWYWwgPSBudWxsO1xuICAgICAgICAgICAgICAgIG5ld1R5cGUgPSAnb2JqZWN0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdmFsOiBuZXdWYWwsXG4gICAgICAgICAgICAgICAgdHlwZTogbmV3VHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgJ2RlZmF1bHQnOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8vIHRoZSBgc3RhdGVgIGRhdGEgdHlwZSBpcyBhIGJpdCBzcGVjaWFsIGluIHRoYXQgc2V0dGluZyBpdCBzaG91bGRcbiAgICAvLyBhbHNvIGJ1YmJsZSBldmVudHNcbiAgICBzdGF0ZToge1xuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdWYWwpIHtcbiAgICAgICAgICAgIHZhciBpc0luc3RhbmNlID0gbmV3VmFsIGluc3RhbmNlb2YgQmFzZSB8fCAobmV3VmFsICYmIG5ld1ZhbC5pc1N0YXRlKTtcbiAgICAgICAgICAgIGlmIChpc0luc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsOiBuZXdWYWwsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdGF0ZSdcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB2YWw6IG5ld1ZhbCxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogdHlwZW9mIG5ld1ZhbFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGNvbXBhcmU6IGZ1bmN0aW9uIChjdXJyZW50VmFsLCBuZXdWYWwpIHtcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50VmFsID09PSBuZXdWYWw7XG4gICAgICAgIH0sXG5cbiAgICAgICAgb25DaGFuZ2UgOiBmdW5jdGlvbihuZXdWYWwsIHByZXZpb3VzVmFsLCBhdHRyaWJ1dGVOYW1lKXtcbiAgICAgICAgICAgIC8vIGlmIHRoaXMgaGFzIGNoYW5nZWQgd2Ugd2FudCB0byBhbHNvIGhhbmRsZVxuICAgICAgICAgICAgLy8gZXZlbnQgcHJvcGFnYXRpb25cbiAgICAgICAgICAgIGlmIChwcmV2aW91c1ZhbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RvcExpc3RlbmluZyhwcmV2aW91c1ZhbCwgJ2FsbCcsIHRoaXMuX2dldENhY2hlZEV2ZW50QnViYmxpbmdIYW5kbGVyKGF0dHJpYnV0ZU5hbWUpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG5ld1ZhbCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5UbyhuZXdWYWwsICdhbGwnLCB0aGlzLl9nZXRDYWNoZWRFdmVudEJ1YmJsaW5nSGFuZGxlcihhdHRyaWJ1dGVOYW1lKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG4vLyB0aGUgZXh0ZW5kIG1ldGhvZCB1c2VkIHRvIGV4dGVuZCBwcm90b3R5cGVzLCBtYWludGFpbiBpbmhlcml0YW5jZSBjaGFpbnMgZm9yIGluc3RhbmNlb2Zcbi8vIGFuZCBhbGxvdyBmb3IgYWRkaXRpb25zIHRvIHRoZSBtb2RlbCBkZWZpbml0aW9ucy5cbmZ1bmN0aW9uIGV4dGVuZChwcm90b1Byb3BzKSB7XG4gICAgLypqc2hpbnQgdmFsaWR0aGlzOnRydWUqL1xuICAgIHZhciBwYXJlbnQgPSB0aGlzO1xuICAgIHZhciBjaGlsZDtcblxuICAgIC8vIFRoZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBmb3IgdGhlIG5ldyBzdWJjbGFzcyBpcyBlaXRoZXIgZGVmaW5lZCBieSB5b3VcbiAgICAvLyAodGhlIFwiY29uc3RydWN0b3JcIiBwcm9wZXJ0eSBpbiB5b3VyIGBleHRlbmRgIGRlZmluaXRpb24pLCBvciBkZWZhdWx0ZWRcbiAgICAvLyBieSB1cyB0byBzaW1wbHkgY2FsbCB0aGUgcGFyZW50J3MgY29uc3RydWN0b3IuXG4gICAgaWYgKHByb3RvUHJvcHMgJiYgcHJvdG9Qcm9wcy5oYXNPd25Qcm9wZXJ0eSgnY29uc3RydWN0b3InKSkge1xuICAgICAgICBjaGlsZCA9IHByb3RvUHJvcHMuY29uc3RydWN0b3I7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY2hpbGQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gQWRkIHN0YXRpYyBwcm9wZXJ0aWVzIHRvIHRoZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBmcm9tIHBhcmVudFxuICAgIGFzc2lnbihjaGlsZCwgcGFyZW50KTtcblxuICAgIC8vIFNldCB0aGUgcHJvdG90eXBlIGNoYWluIHRvIGluaGVyaXQgZnJvbSBgcGFyZW50YCwgd2l0aG91dCBjYWxsaW5nXG4gICAgLy8gYHBhcmVudGAncyBjb25zdHJ1Y3RvciBmdW5jdGlvbi5cbiAgICB2YXIgU3Vycm9nYXRlID0gZnVuY3Rpb24gKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH07XG4gICAgU3Vycm9nYXRlLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7XG4gICAgY2hpbGQucHJvdG90eXBlID0gbmV3IFN1cnJvZ2F0ZSgpO1xuXG4gICAgLy8gc2V0IHByb3RvdHlwZSBsZXZlbCBvYmplY3RzXG4gICAgY2hpbGQucHJvdG90eXBlLl9kZXJpdmVkID0gIGFzc2lnbih7fSwgcGFyZW50LnByb3RvdHlwZS5fZGVyaXZlZCk7XG4gICAgY2hpbGQucHJvdG90eXBlLl9kZXBzID0gYXNzaWduKHt9LCBwYXJlbnQucHJvdG90eXBlLl9kZXBzKTtcbiAgICBjaGlsZC5wcm90b3R5cGUuX2RlZmluaXRpb24gPSBhc3NpZ24oe30sIHBhcmVudC5wcm90b3R5cGUuX2RlZmluaXRpb24pO1xuICAgIGNoaWxkLnByb3RvdHlwZS5fY29sbGVjdGlvbnMgPSBhc3NpZ24oe30sIHBhcmVudC5wcm90b3R5cGUuX2NvbGxlY3Rpb25zKTtcbiAgICBjaGlsZC5wcm90b3R5cGUuX2NoaWxkcmVuID0gYXNzaWduKHt9LCBwYXJlbnQucHJvdG90eXBlLl9jaGlsZHJlbik7XG4gICAgY2hpbGQucHJvdG90eXBlLl9kYXRhVHlwZXMgPSBhc3NpZ24oe30sIHBhcmVudC5wcm90b3R5cGUuX2RhdGFUeXBlcyB8fCBkYXRhVHlwZXMpO1xuXG4gICAgLy8gTWl4IGluIGFsbCBwcm90b3R5cGUgcHJvcGVydGllcyB0byB0aGUgc3ViY2xhc3MgaWYgc3VwcGxpZWQuXG4gICAgaWYgKHByb3RvUHJvcHMpIHtcbiAgICAgICAgdmFyIG9taXRGcm9tRXh0ZW5kID0gW1xuICAgICAgICAgICAgJ2RhdGFUeXBlcycsICdwcm9wcycsICdzZXNzaW9uJywgJ2Rlcml2ZWQnLCAnY29sbGVjdGlvbnMnLCAnY2hpbGRyZW4nXG4gICAgICAgIF07XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBkZWYgPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICBpZiAoZGVmLmRhdGFUeXBlcykge1xuICAgICAgICAgICAgICAgIGZvck93bihkZWYuZGF0YVR5cGVzLCBmdW5jdGlvbiAoZGVmLCBuYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkLnByb3RvdHlwZS5fZGF0YVR5cGVzW25hbWVdID0gZGVmO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRlZi5wcm9wcykge1xuICAgICAgICAgICAgICAgIGZvck93bihkZWYucHJvcHMsIGZ1bmN0aW9uIChkZWYsIG5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlUHJvcGVydHlEZWZpbml0aW9uKGNoaWxkLnByb3RvdHlwZSwgbmFtZSwgZGVmKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkZWYuc2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIGZvck93bihkZWYuc2Vzc2lvbiwgZnVuY3Rpb24gKGRlZiwgbmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBjcmVhdGVQcm9wZXJ0eURlZmluaXRpb24oY2hpbGQucHJvdG90eXBlLCBuYW1lLCBkZWYsIHRydWUpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRlZi5kZXJpdmVkKSB7XG4gICAgICAgICAgICAgICAgZm9yT3duKGRlZi5kZXJpdmVkLCBmdW5jdGlvbiAoZGVmLCBuYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZURlcml2ZWRQcm9wZXJ0eShjaGlsZC5wcm90b3R5cGUsIG5hbWUsIGRlZik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGVmLmNvbGxlY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgZm9yT3duKGRlZi5jb2xsZWN0aW9ucywgZnVuY3Rpb24gKGNvbnN0cnVjdG9yLCBuYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkLnByb3RvdHlwZS5fY29sbGVjdGlvbnNbbmFtZV0gPSBjb25zdHJ1Y3RvcjtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkZWYuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICBmb3JPd24oZGVmLmNoaWxkcmVuLCBmdW5jdGlvbiAoY29uc3RydWN0b3IsIG5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGQucHJvdG90eXBlLl9jaGlsZHJlbltuYW1lXSA9IGNvbnN0cnVjdG9yO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduKGNoaWxkLnByb3RvdHlwZSwgb21pdChkZWYsIG9taXRGcm9tRXh0ZW5kKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTZXQgYSBjb252ZW5pZW5jZSBwcm9wZXJ0eSBpbiBjYXNlIHRoZSBwYXJlbnQncyBwcm90b3R5cGUgaXMgbmVlZGVkXG4gICAgLy8gbGF0ZXIuXG4gICAgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTtcblxuICAgIHJldHVybiBjaGlsZDtcbn1cblxuQmFzZS5leHRlbmQgPSBleHRlbmQ7XG5cbi8vIE91ciBtYWluIGV4cG9ydHNcbm1vZHVsZS5leHBvcnRzID0gQmFzZTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///ef45\n")}}]);

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.ampersand-state"],{ef45:function(module,exports,__webpack_require__){"use strict";eval("\n/*$AMPERSAND_VERSION*/\nvar uniqueId = __webpack_require__(/*! lodash/uniqueId */ \"6d0d\");\nvar assign = __webpack_require__(/*! lodash/assign */ \"5ad5\");\nvar cloneObj = function(obj) { return assign({}, obj); };\nvar omit = __webpack_require__(/*! lodash/omit */ \"4633\");\nvar escape = __webpack_require__(/*! lodash/escape */ \"740c\");\nvar forOwn = __webpack_require__(/*! lodash/forOwn */ \"436f\");\nvar includes = __webpack_require__(/*! lodash/includes */ \"e2c7\");\nvar isString = __webpack_require__(/*! lodash/isString */ \"5fa3\");\nvar isObject = __webpack_require__(/*! lodash/isObject */ \"d3a8\");\nvar isDate = __webpack_require__(/*! lodash/isDate */ \"7f93\");\nvar isFunction = __webpack_require__(/*! lodash/isFunction */ \"f3b0\");\nvar _isEqual = __webpack_require__(/*! lodash/isEqual */ \"f8a3\"); // to avoid shadowing\nvar has = __webpack_require__(/*! lodash/has */ \"b055\");\nvar result = __webpack_require__(/*! lodash/result */ \"80c9\");\nvar union = __webpack_require__(/*! lodash/union */ \"c80f\");\nvar Events = __webpack_require__(/*! ampersand-events */ \"13c2\");\nvar KeyTree = __webpack_require__(/*! key-tree-store */ \"8849\");\nvar arrayNext = __webpack_require__(/*! array-next */ \"d1bb\");\nvar changeRE = /^change:/;\nvar noop = function () {};\n\nfunction Base(attrs, options) {\n    options || (options = {});\n    this.cid || (this.cid = uniqueId('state'));\n    this._events = {};\n    this._values = {};\n    this._eventBubblingHandlerCache = {};\n    this._definition = Object.create(this._definition);\n    if (options.parse) attrs = this.parse(attrs, options);\n    this.parent = options.parent;\n    this.collection = options.collection;\n    this._keyTree = new KeyTree();\n    this._initCollections();\n    this._initChildren();\n    this._cache = {};\n    this._previousAttributes = {};\n    if (attrs) this.set(attrs, assign({silent: true, initial: true}, options));\n    this._changed = {};\n    if (this._derived) this._initDerived();\n    if (options.init !== false) this.initialize.apply(this, arguments);\n}\n\nassign(Base.prototype, Events, {\n    // can be allow, ignore, reject\n    extraProperties: 'ignore',\n\n    idAttribute: 'id',\n\n    namespaceAttribute: 'namespace',\n\n    typeAttribute: 'modelType',\n\n    // Stubbed out to be overwritten\n    initialize: function () {\n        return this;\n    },\n\n    // Get ID of model per configuration.\n    // Should *always* be how ID is determined by other code.\n    getId: function () {\n        return this[this.idAttribute];\n    },\n\n    // Get namespace of model per configuration.\n    // Should *always* be how namespace is determined by other code.\n    getNamespace: function () {\n        return this[this.namespaceAttribute];\n    },\n\n    // Get type of model per configuration.\n    // Should *always* be how type is determined by other code.\n    getType: function () {\n        return this[this.typeAttribute];\n    },\n\n    // A model is new if it has never been saved to the server, and lacks an id.\n    isNew: function () {\n        return this.getId() == null;\n    },\n\n    // get HTML-escaped value of attribute\n    escape: function (attr) {\n        return escape(this.get(attr));\n    },\n\n    // Check if the model is currently in a valid state.\n    isValid: function (options) {\n        return this._validate({}, assign(options || {}, { validate: true }));\n    },\n\n    // Parse can be used remap/restructure/rename incoming properties\n    // before they are applied to attributes.\n    parse: function (resp, options) {\n        //jshint unused:false\n        return resp;\n    },\n\n    // Serialize is the inverse of `parse` it lets you massage data\n    // on the way out. Before, sending to server, for example.\n    serialize: function (options) {\n        var attrOpts = assign({props: true}, options);\n        var res = this.getAttributes(attrOpts, true);\n        \n        var setFromSerializedValue = function (value, key) {\n\t        res[key] = this[key].serialize();\n        }.bind(this);\n        \n        forOwn(this._children, setFromSerializedValue);\n        forOwn(this._collections, setFromSerializedValue);\n        return res;\n    },\n\n    // Main set method used by generated setters/getters and can\n    // be used directly if you need to pass options or set multiple\n    // properties at once.\n    set: function (key, value, options) {\n        var self = this;\n        var extraProperties = this.extraProperties;\n        var wasChanging, changeEvents, newType, newVal, def, cast, err, attr,\n            attrs, dataType, silent, unset, currentVal, initial, hasChanged, isEqual, onChange;\n\n        // Handle both `\"key\", value` and `{key: value}` -style arguments.\n        if (isObject(key) || key === null) {\n            attrs = key;\n            options = value;\n        } else {\n            attrs = {};\n            attrs[key] = value;\n        }\n\n        options = options || {};\n\n        if (!this._validate(attrs, options)) return false;\n\n        // Extract attributes and options.\n        unset = options.unset;\n        silent = options.silent;\n        initial = options.initial;\n\n        // Initialize change tracking.\n        wasChanging = this._changing;\n        this._changing = true;\n        changeEvents = [];\n\n        // if not already changing, store previous\n        if (initial) {\n            this._previousAttributes = {};\n        } else if (!wasChanging) {\n            this._previousAttributes = this.attributes;\n            this._changed = {};\n        }\n\n        // For each `set` attribute...\n        for (var i = 0, keys = Object.keys(attrs), len = keys.length; i < len; i++) {\n            attr = keys[i];\n            newVal = attrs[attr];\n            newType = typeof newVal;\n            currentVal = this._values[attr];\n            def = this._definition[attr];\n\n            if (!def) {\n                // if this is a child model or collection\n                if (this._children[attr] || this._collections[attr]) {\n                    if (!isObject(newVal)) {\n                        newVal = {};\n                    }\n\n                    this[attr].set(newVal, options);\n                    continue;\n                } else if (extraProperties === 'ignore') {\n                    continue;\n                } else if (extraProperties === 'reject') {\n                    throw new TypeError('No \"' + attr + '\" property defined on ' + (this.type || 'this') + ' model and extraProperties not set to \"ignore\" or \"allow\"');\n                } else if (extraProperties === 'allow') {\n                    def = this._createPropertyDefinition(attr, 'any');\n                } else if (extraProperties) {\n                    throw new TypeError('Invalid value for extraProperties: \"' + extraProperties + '\"');\n                }\n            }\n\n            isEqual = this._getCompareForType(def.type);\n            onChange = this._getOnChangeForType(def.type);\n            dataType = this._dataTypes[def.type];\n\n            // check type if we have one\n            if (dataType && dataType.set) {\n                cast = dataType.set(newVal);\n                newVal = cast.val;\n                newType = cast.type;\n            }\n\n            // If we've defined a test, run it\n            if (def.test) {\n                err = def.test.call(this, newVal, newType);\n                if (err) {\n                    throw new TypeError('Property \\'' + attr + '\\' failed validation with error: ' + err);\n                }\n            }\n\n            // If we are required but undefined, throw error.\n            // If we are null and are not allowing null, throw error\n            // If we have a defined type and the new type doesn't match, and we are not null, throw error.\n            // If we require specific value and new one is not one of them, throw error (unless it has default value or we're unsetting it with undefined).\n\n            if (newVal === undefined && def.required) {\n                throw new TypeError('Required property \\'' + attr + '\\' must be of type ' + def.type + '. Tried to set ' + newVal);\n            }\n            if (newVal === null && def.required && !def.allowNull) {\n                throw new TypeError('Property \\'' + attr + '\\' must be of type ' + def.type + ' (cannot be null). Tried to set ' + newVal);\n            }\n            if ((def.type && def.type !== 'any' && def.type !== newType) && newVal !== null && newVal !== undefined) {\n                throw new TypeError('Property \\'' + attr + '\\' must be of type ' + def.type + '. Tried to set ' + newVal);\n            }\n            if (def.values && !includes(def.values, newVal)) {\n                var defaultValue = result(def, 'default');\n                if (unset && defaultValue !== undefined) {\n                    newVal = defaultValue;\n                } else if (!unset || (unset && newVal !== undefined)) {\n                    throw new TypeError('Property \\'' + attr + '\\' must be one of values: ' + def.values.join(', ') + '. Tried to set ' + newVal);\n                }\n            }\n\n            // We know this has 'changed' if it's the initial set, so skip a potentially expensive isEqual check.\n            hasChanged = initial || !isEqual(currentVal, newVal, attr);\n\n            // enforce `setOnce` for properties if set\n            if (def.setOnce && currentVal !== undefined && hasChanged) {\n                throw new TypeError('Property \\'' + attr + '\\' can only be set once.');\n            }\n\n            // set/unset attributes.\n            // If this is not the initial set, keep track of changed attributes\n            // and push to changeEvents array so we can fire events.\n            if (hasChanged) {\n\n                // This fires no matter what, even on initial set.\n                onChange(newVal, currentVal, attr);\n\n                // If this is a change (not an initial set), mark the change.\n                // Note it's impossible to unset on the initial set (it will already be unset),\n                // so we only include that logic here.\n                if (!initial) {\n                    this._changed[attr] = newVal;\n                    this._previousAttributes[attr] = currentVal;\n                    if (unset) {\n                        // FIXME delete is very slow. Can we get away with setting to undefined?\n                        delete this._values[attr];\n                    }\n                    if (!silent) {\n                        changeEvents.push({prev: currentVal, val: newVal, key: attr});\n                    }\n                }\n                if (!unset) {\n                    this._values[attr] = newVal;\n                }\n            } else {\n                // Not changed\n                // FIXME delete is very slow. Can we get away with setting to undefined?\n                delete this._changed[attr];\n            }\n        }\n\n        // Fire events. This array is not populated if we are told to be silent.\n        if (changeEvents.length) this._pending = true;\n        changeEvents.forEach(function (change) {\n            self.trigger('change:' + change.key, self, change.val, options);\n        });\n\n        // You might be wondering why there's a `while` loop here. Changes can\n        // be recursively nested within `\"change\"` events.\n        if (wasChanging) return this;\n        while (this._pending) {\n            this._pending = false;\n            this.trigger('change', this, options);\n        }\n        this._pending = false;\n        this._changing = false;\n        return this;\n    },\n\n    get: function (attr) {\n        return this[attr];\n    },\n\n    // Toggle boolean properties or properties that have a `values`\n    // array in its definition.\n    toggle: function (property) {\n        var def = this._definition[property];\n        if (def.type === 'boolean') {\n            // if it's a bool, just flip it\n            this[property] = !this[property];\n        } else if (def && def.values) {\n            // If it's a property with an array of values\n            // skip to the next one looping back if at end.\n            this[property] = arrayNext(def.values, this[property]);\n        } else {\n            throw new TypeError('Can only toggle properties that are type `boolean` or have `values` array.');\n        }\n        return this;\n    },\n\n    // Get all of the attributes of the model at the time of the previous\n    // `\"change\"` event.\n    previousAttributes: function () {\n        return cloneObj(this._previousAttributes);\n    },\n\n    // Determine if the model has changed since the last `\"change\"` event.\n    // If you specify an attribute name, determine if that attribute has changed.\n    hasChanged: function (attr) {\n        if (attr == null) return !!Object.keys(this._changed).length;\n        if (has(this._derived, attr)) {\n            return this._derived[attr].depList.some(function (dep) {\n                return this.hasChanged(dep);\n            }, this);\n        }\n        return has(this._changed, attr);\n    },\n\n    // Return an object containing all the attributes that have changed, or\n    // false if there are no changed attributes. Useful for determining what\n    // parts of a view need to be updated and/or what attributes need to be\n    // persisted to the server. Unset attributes will be set to undefined.\n    // You can also pass an attributes object to diff against the model,\n    // determining if there *would be* a change.\n    changedAttributes: function (diff) {\n        if (!diff) return this.hasChanged() ? cloneObj(this._changed) : false;\n        var val, changed = false;\n        var old = this._changing ? this._previousAttributes : this.attributes;\n        var def, isEqual;\n        for (var attr in diff) {\n            def = this._definition[attr];\n            if (!def) continue;\n            isEqual = this._getCompareForType(def.type);\n            if (isEqual(old[attr], (val = diff[attr]))) continue;\n            (changed || (changed = {}))[attr] = val;\n        }\n        return changed;\n    },\n\n    toJSON: function () {\n        return this.serialize();\n    },\n\n    unset: function (attrs, options) {\n        var self = this;\n        attrs = Array.isArray(attrs) ? attrs : [attrs];\n        attrs.forEach(function (key) {\n            var def = self._definition[key];\n            if (!def) return;\n            var val;\n            if (def.required) {\n                val = result(def, 'default');\n                return self.set(key, val, options);\n            } else {\n                return self.set(key, val, assign({}, options, {unset: true}));\n            }\n        });\n    },\n\n    clear: function (options) {\n        var self = this;\n        Object.keys(this.attributes).forEach(function (key) {\n            self.unset(key, options);\n        });\n        return this;\n    },\n\n    previous: function (attr) {\n        if (attr == null || !Object.keys(this._previousAttributes).length) return null;\n        return this._previousAttributes[attr];\n    },\n\n    // Get default values for a certain type\n    _getDefaultForType: function (type) {\n        var dataType = this._dataTypes[type];\n        return dataType && dataType['default'];\n    },\n\n    // Determine which comparison algorithm to use for comparing a property\n    _getCompareForType: function (type) {\n        var dataType = this._dataTypes[type];\n        if (dataType && dataType.compare) return dataType.compare.bind(this);\n        return _isEqual; // if no compare function is defined, use _.isEqual\n    },\n\n    _getOnChangeForType : function(type){\n        var dataType = this._dataTypes[type];\n        if (dataType && dataType.onChange) return dataType.onChange.bind(this);\n        return noop;\n    },\n\n    // Run validation against the next complete set of model attributes,\n    // returning `true` if all is well. Otherwise, fire an `\"invalid\"` event.\n    _validate: function (attrs, options) {\n        if (!options.validate || !this.validate) return true;\n        attrs = assign({}, this.attributes, attrs);\n        var error = this.validationError = this.validate(attrs, options) || null;\n        if (!error) return true;\n        this.trigger('invalid', this, error, assign(options || {}, {validationError: error}));\n        return false;\n    },\n\n    _createPropertyDefinition: function (name, desc, isSession) {\n        return createPropertyDefinition(this, name, desc, isSession);\n    },\n\n    // just makes friendlier errors when trying to define a new model\n    // only used when setting up original property definitions\n    _ensureValidType: function (type) {\n        return includes(['string', 'number', 'boolean', 'array', 'object', 'date', 'state', 'any']\n            .concat(Object.keys(this._dataTypes)), type) ? type : undefined;\n    },\n\n    getAttributes: function (options, raw) {\n        options = assign({\n            session: false,\n            props: false,\n            derived: false\n        }, options || {});\n        var res = {};\n        var val, def;\n        for (var item in this._definition) {\n            def = this._definition[item];\n            if ((options.session && def.session) || (options.props && !def.session)) {\n                val = raw ? this._values[item] : this[item];\n                if (raw && val && isFunction(val.serialize)) val = val.serialize();\n                if (typeof val === 'undefined') val = result(def, 'default');\n                if (typeof val !== 'undefined') res[item] = val;\n            }\n        }\n        if (options.derived) {\n            for (var derivedItem in this._derived) res[derivedItem] = this[derivedItem];\n        }\n        return res;\n    },\n\n    _initDerived: function () {\n        var self = this;\n\n        forOwn(this._derived, function (value, name) {\n            var def = self._derived[name];\n            def.deps = def.depList;\n\n            var update = function () {\n                var newVal = def.fn.call(self);\n\n                if (self._cache[name] !== newVal || !def.cache) {\n                    if (def.cache) {\n                        self._previousAttributes[name] = self._cache[name];\n                    }\n                    self._cache[name] = newVal;\n                    self.trigger('change:' + name, self, self._cache[name]);\n                }\n            };\n\n            def.deps.forEach(function (propString) {\n                self._keyTree.add(propString, update);\n            });\n        });\n\n        this.on('all', function (eventName) {\n            if (changeRE.test(eventName)) {\n                self._keyTree.get(eventName.split(':')[1]).forEach(function (fn) {\n                    fn();\n                });\n            }\n        }, this);\n    },\n\n    _getDerivedProperty: function (name, flushCache) {\n        // is this a derived property that is cached\n        if (this._derived[name].cache) {\n            //set if this is the first time, or flushCache is set\n            if (flushCache || !this._cache.hasOwnProperty(name)) {\n                this._cache[name] = this._derived[name].fn.apply(this);\n            }\n            return this._cache[name];\n        } else {\n            return this._derived[name].fn.apply(this);\n        }\n    },\n\n    _initCollections: function () {\n        var coll;\n        if (!this._collections) return;\n        for (coll in this._collections) {\n            this._safeSet(coll, new this._collections[coll](null, {parent: this}));\n        }\n    },\n\n    _initChildren: function () {\n        var child;\n        if (!this._children) return;\n        for (child in this._children) {\n            this._safeSet(child, new this._children[child]({}, {parent: this}));\n            this.listenTo(this[child], 'all', this._getCachedEventBubblingHandler(child));\n        }\n    },\n\n    // Returns a bound handler for doing event bubbling while\n    // adding a name to the change string.\n    _getCachedEventBubblingHandler: function (propertyName) {\n        if (!this._eventBubblingHandlerCache[propertyName]) {\n            this._eventBubblingHandlerCache[propertyName] = function (name, model, newValue) {\n                if (changeRE.test(name)) {\n                    this.trigger('change:' + propertyName + '.' + name.split(':')[1], model, newValue);\n                } else if (name === 'change') {\n                    this.trigger('change', this);\n                }\n            }.bind(this);\n        }\n        return this._eventBubblingHandlerCache[propertyName];\n    },\n\n    // Check that all required attributes are present\n    _verifyRequired: function () {\n        var attrs = this.attributes; // should include session\n        for (var def in this._definition) {\n            if (this._definition[def].required && typeof attrs[def] === 'undefined') {\n                return false;\n            }\n        }\n        return true;\n    },\n\n    // expose safeSet method\n    _safeSet: function safeSet(property, value) {\n        if (property in this) {\n            throw new Error('Encountered namespace collision while setting instance property `' + property + '`');\n        }\n        this[property] = value;\n        return this;\n    }\n});\n\n// getter for attributes\nObject.defineProperties(Base.prototype, {\n    attributes: {\n        get: function () {\n            return this.getAttributes({props: true, session: true});\n        }\n    },\n    all: {\n        get: function () {\n            return this.getAttributes({\n                session: true,\n                props: true,\n                derived: true\n            });\n        }\n    },\n    isState: {\n        get: function () { return true; },\n        set: function () { }\n    }\n});\n\n// helper for creating/storing property definitions and creating\n// appropriate getters/setters\nfunction createPropertyDefinition(object, name, desc, isSession) {\n    var def = object._definition[name] = {};\n    var type, descArray;\n\n    if (isString(desc)) {\n        // grab our type if all we've got is a string\n        type = object._ensureValidType(desc);\n        if (type) def.type = type;\n    } else {\n        //Transform array of ['type', required, default] to object form\n        if (Array.isArray(desc)) {\n            descArray = desc;\n            desc = {\n                type: descArray[0],\n                required: descArray[1],\n                'default': descArray[2]\n            };\n        }\n\n        type = object._ensureValidType(desc.type);\n        if (type) def.type = type;\n\n        if (desc.required) def.required = true;\n\n        if (desc['default'] && typeof desc['default'] === 'object') {\n            throw new TypeError('The default value for ' + name + ' cannot be an object/array, must be a value or a function which returns a value/object/array');\n        }\n\n        def['default'] = desc['default'];\n\n        def.allowNull = desc.allowNull ? desc.allowNull : false;\n        if (desc.setOnce) def.setOnce = true;\n        if (def.required && def['default'] === undefined && !def.setOnce) def['default'] = object._getDefaultForType(type);\n        def.test = desc.test;\n        def.values = desc.values;\n    }\n    if (isSession) def.session = true;\n\n    if (!type) {\n        type = isString(desc) ? desc : desc.type;\n        // TODO: start throwing a TypeError in future major versions instead of warning\n        console.warn('Invalid data type of `' + type + '` for `' + name + '` property. Use one of the default types or define your own');\n    }\n\n    // define a getter/setter on the prototype\n    // but they get/set on the instance\n    Object.defineProperty(object, name, {\n        set: function (val) {\n            this.set(name, val);\n        },\n        get: function () {\n            if (!this._values) {\n                throw Error('You may be trying to `extend` a state object with \"' + name + '\" which has been defined in `props` on the object being extended');\n            }\n            var value = this._values[name];\n            var typeDef = this._dataTypes[def.type];\n            if (typeof value !== 'undefined') {\n                if (typeDef && typeDef.get) {\n                    value = typeDef.get(value);\n                }\n                return value;\n            }\n            var defaultValue = result(def, 'default');\n            this._values[name] = defaultValue;\n            // If we've set a defaultValue, fire a change handler effectively marking\n            // its change from undefined to the default value.\n            if (typeof defaultValue !== 'undefined') {\n                var onChange = this._getOnChangeForType(def.type);\n                onChange(defaultValue, value, name);\n            }\n            return defaultValue;\n        }\n    });\n\n    return def;\n}\n\n// helper for creating derived property definitions\nfunction createDerivedProperty(modelProto, name, definition) {\n    var def = modelProto._derived[name] = {\n        fn: isFunction(definition) ? definition : definition.fn,\n        cache: (definition.cache !== false),\n        depList: definition.deps || []\n    };\n\n    // add to our shared dependency list\n    def.depList.forEach(function (dep) {\n        modelProto._deps[dep] = union(modelProto._deps[dep] || [], [name]);\n    });\n\n    // defined a top-level getter for derived names\n    Object.defineProperty(modelProto, name, {\n        get: function () {\n            return this._getDerivedProperty(name);\n        },\n        set: function () {\n            throw new TypeError(\"`\" + name + \"` is a derived property, it can't be set directly.\");\n        }\n    });\n}\n\nvar dataTypes = {\n    string: {\n        'default': function () {\n            return '';\n        }\n    },\n    date: {\n        set: function (newVal) {\n            var newType;\n            if (newVal == null) {\n                newType = typeof null;\n            } else if (!isDate(newVal)) {\n                var err = null;\n                var dateVal = new Date(newVal).valueOf();\n                if (isNaN(dateVal)) {\n                    // If the newVal cant be parsed, then try parseInt first\n                    dateVal = new Date(parseInt(newVal, 10)).valueOf();\n                    if (isNaN(dateVal)) err = true;\n                }\n                newVal = dateVal;\n                newType = 'date';\n                if (err) {\n                    newType = typeof newVal;\n                }\n            } else {\n                newType = 'date';\n                newVal = newVal.valueOf();\n            }\n\n            return {\n                val: newVal,\n                type: newType\n            };\n        },\n        get: function (val) {\n            if (val == null) { return val; }\n            return new Date(val);\n        },\n        'default': function () {\n            return new Date();\n        }\n    },\n    array: {\n        set: function (newVal) {\n            return {\n                val: newVal,\n                type: Array.isArray(newVal) ? 'array' : typeof newVal\n            };\n        },\n        'default': function () {\n            return [];\n        }\n    },\n    object: {\n        set: function (newVal) {\n            var newType = typeof newVal;\n            // we have to have a way of supporting \"missing\" objects.\n            // Null is an object, but setting a value to undefined\n            // should work too, IMO. We just override it, in that case.\n            if (newType !== 'object' && newVal === undefined) {\n                newVal = null;\n                newType = 'object';\n            }\n            return {\n                val: newVal,\n                type: newType\n            };\n        },\n        'default': function () {\n            return {};\n        }\n    },\n    // the `state` data type is a bit special in that setting it should\n    // also bubble events\n    state: {\n        set: function (newVal) {\n            var isInstance = newVal instanceof Base || (newVal && newVal.isState);\n            if (isInstance) {\n                return {\n                    val: newVal,\n                    type: 'state'\n                };\n            } else {\n                return {\n                    val: newVal,\n                    type: typeof newVal\n                };\n            }\n        },\n        compare: function (currentVal, newVal) {\n            return currentVal === newVal;\n        },\n\n        onChange : function(newVal, previousVal, attributeName){\n            // if this has changed we want to also handle\n            // event propagation\n            if (previousVal) {\n                this.stopListening(previousVal, 'all', this._getCachedEventBubblingHandler(attributeName));\n            }\n\n            if (newVal != null) {\n                this.listenTo(newVal, 'all', this._getCachedEventBubblingHandler(attributeName));\n            }\n        }\n    }\n};\n\n// the extend method used to extend prototypes, maintain inheritance chains for instanceof\n// and allow for additions to the model definitions.\nfunction extend(protoProps) {\n    /*jshint validthis:true*/\n    var parent = this;\n    var child;\n\n    // The constructor function for the new subclass is either defined by you\n    // (the \"constructor\" property in your `extend` definition), or defaulted\n    // by us to simply call the parent's constructor.\n    if (protoProps && protoProps.hasOwnProperty('constructor')) {\n        child = protoProps.constructor;\n    } else {\n        child = function () {\n            return parent.apply(this, arguments);\n        };\n    }\n\n    // Add static properties to the constructor function from parent\n    assign(child, parent);\n\n    // Set the prototype chain to inherit from `parent`, without calling\n    // `parent`'s constructor function.\n    var Surrogate = function () { this.constructor = child; };\n    Surrogate.prototype = parent.prototype;\n    child.prototype = new Surrogate();\n\n    // set prototype level objects\n    child.prototype._derived =  assign({}, parent.prototype._derived);\n    child.prototype._deps = assign({}, parent.prototype._deps);\n    child.prototype._definition = assign({}, parent.prototype._definition);\n    child.prototype._collections = assign({}, parent.prototype._collections);\n    child.prototype._children = assign({}, parent.prototype._children);\n    child.prototype._dataTypes = assign({}, parent.prototype._dataTypes || dataTypes);\n\n    // Mix in all prototype properties to the subclass if supplied.\n    if (protoProps) {\n        var omitFromExtend = [\n            'dataTypes', 'props', 'session', 'derived', 'collections', 'children'\n        ];\n        for(var i = 0; i < arguments.length; i++) {\n            var def = arguments[i];\n            if (def.dataTypes) {\n                forOwn(def.dataTypes, function (def, name) {\n                    child.prototype._dataTypes[name] = def;\n                });\n            }\n            if (def.props) {\n                forOwn(def.props, function (def, name) {\n                    createPropertyDefinition(child.prototype, name, def);\n                });\n            }\n            if (def.session) {\n                forOwn(def.session, function (def, name) {\n                    createPropertyDefinition(child.prototype, name, def, true);\n                });\n            }\n            if (def.derived) {\n                forOwn(def.derived, function (def, name) {\n                    createDerivedProperty(child.prototype, name, def);\n                });\n            }\n            if (def.collections) {\n                forOwn(def.collections, function (constructor, name) {\n                    child.prototype._collections[name] = constructor;\n                });\n            }\n            if (def.children) {\n                forOwn(def.children, function (constructor, name) {\n                    child.prototype._children[name] = constructor;\n                });\n            }\n            assign(child.prototype, omit(def, omitFromExtend));\n        }\n    }\n\n    // Set a convenience property in case the parent's prototype is needed\n    // later.\n    child.__super__ = parent.prototype;\n\n    return child;\n}\n\nBase.extend = extend;\n\n// Our main exports\nmodule.exports = Base;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWY0NS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9hbXBlcnNhbmQtc3RhdGUvYW1wZXJzYW5kLXN0YXRlLmpzPzYzZDQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuLyokQU1QRVJTQU5EX1ZFUlNJT04qL1xudmFyIHVuaXF1ZUlkID0gcmVxdWlyZSgnbG9kYXNoL3VuaXF1ZUlkJyk7XG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpO1xudmFyIGNsb25lT2JqID0gZnVuY3Rpb24ob2JqKSB7IHJldHVybiBhc3NpZ24oe30sIG9iaik7IH07XG52YXIgb21pdCA9IHJlcXVpcmUoJ2xvZGFzaC9vbWl0Jyk7XG52YXIgZXNjYXBlID0gcmVxdWlyZSgnbG9kYXNoL2VzY2FwZScpO1xudmFyIGZvck93biA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JPd24nKTtcbnZhciBpbmNsdWRlcyA9IHJlcXVpcmUoJ2xvZGFzaC9pbmNsdWRlcycpO1xudmFyIGlzU3RyaW5nID0gcmVxdWlyZSgnbG9kYXNoL2lzU3RyaW5nJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCdsb2Rhc2gvaXNPYmplY3QnKTtcbnZhciBpc0RhdGUgPSByZXF1aXJlKCdsb2Rhc2gvaXNEYXRlJyk7XG52YXIgaXNGdW5jdGlvbiA9IHJlcXVpcmUoJ2xvZGFzaC9pc0Z1bmN0aW9uJyk7XG52YXIgX2lzRXF1YWwgPSByZXF1aXJlKCdsb2Rhc2gvaXNFcXVhbCcpOyAvLyB0byBhdm9pZCBzaGFkb3dpbmdcbnZhciBoYXMgPSByZXF1aXJlKCdsb2Rhc2gvaGFzJyk7XG52YXIgcmVzdWx0ID0gcmVxdWlyZSgnbG9kYXNoL3Jlc3VsdCcpO1xudmFyIHVuaW9uID0gcmVxdWlyZSgnbG9kYXNoL3VuaW9uJyk7XG52YXIgRXZlbnRzID0gcmVxdWlyZSgnYW1wZXJzYW5kLWV2ZW50cycpO1xudmFyIEtleVRyZWUgPSByZXF1aXJlKCdrZXktdHJlZS1zdG9yZScpO1xudmFyIGFycmF5TmV4dCA9IHJlcXVpcmUoJ2FycmF5LW5leHQnKTtcbnZhciBjaGFuZ2VSRSA9IC9eY2hhbmdlOi87XG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuXG5mdW5jdGlvbiBCYXNlKGF0dHJzLCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcbiAgICB0aGlzLmNpZCB8fCAodGhpcy5jaWQgPSB1bmlxdWVJZCgnc3RhdGUnKSk7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgdGhpcy5fdmFsdWVzID0ge307XG4gICAgdGhpcy5fZXZlbnRCdWJibGluZ0hhbmRsZXJDYWNoZSA9IHt9O1xuICAgIHRoaXMuX2RlZmluaXRpb24gPSBPYmplY3QuY3JlYXRlKHRoaXMuX2RlZmluaXRpb24pO1xuICAgIGlmIChvcHRpb25zLnBhcnNlKSBhdHRycyA9IHRoaXMucGFyc2UoYXR0cnMsIG9wdGlvbnMpO1xuICAgIHRoaXMucGFyZW50ID0gb3B0aW9ucy5wYXJlbnQ7XG4gICAgdGhpcy5jb2xsZWN0aW9uID0gb3B0aW9ucy5jb2xsZWN0aW9uO1xuICAgIHRoaXMuX2tleVRyZWUgPSBuZXcgS2V5VHJlZSgpO1xuICAgIHRoaXMuX2luaXRDb2xsZWN0aW9ucygpO1xuICAgIHRoaXMuX2luaXRDaGlsZHJlbigpO1xuICAgIHRoaXMuX2NhY2hlID0ge307XG4gICAgdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzID0ge307XG4gICAgaWYgKGF0dHJzKSB0aGlzLnNldChhdHRycywgYXNzaWduKHtzaWxlbnQ6IHRydWUsIGluaXRpYWw6IHRydWV9LCBvcHRpb25zKSk7XG4gICAgdGhpcy5fY2hhbmdlZCA9IHt9O1xuICAgIGlmICh0aGlzLl9kZXJpdmVkKSB0aGlzLl9pbml0RGVyaXZlZCgpO1xuICAgIGlmIChvcHRpb25zLmluaXQgIT09IGZhbHNlKSB0aGlzLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuYXNzaWduKEJhc2UucHJvdG90eXBlLCBFdmVudHMsIHtcbiAgICAvLyBjYW4gYmUgYWxsb3csIGlnbm9yZSwgcmVqZWN0XG4gICAgZXh0cmFQcm9wZXJ0aWVzOiAnaWdub3JlJyxcblxuICAgIGlkQXR0cmlidXRlOiAnaWQnLFxuXG4gICAgbmFtZXNwYWNlQXR0cmlidXRlOiAnbmFtZXNwYWNlJyxcblxuICAgIHR5cGVBdHRyaWJ1dGU6ICdtb2RlbFR5cGUnLFxuXG4gICAgLy8gU3R1YmJlZCBvdXQgdG8gYmUgb3ZlcndyaXR0ZW5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvLyBHZXQgSUQgb2YgbW9kZWwgcGVyIGNvbmZpZ3VyYXRpb24uXG4gICAgLy8gU2hvdWxkICphbHdheXMqIGJlIGhvdyBJRCBpcyBkZXRlcm1pbmVkIGJ5IG90aGVyIGNvZGUuXG4gICAgZ2V0SWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbdGhpcy5pZEF0dHJpYnV0ZV07XG4gICAgfSxcblxuICAgIC8vIEdldCBuYW1lc3BhY2Ugb2YgbW9kZWwgcGVyIGNvbmZpZ3VyYXRpb24uXG4gICAgLy8gU2hvdWxkICphbHdheXMqIGJlIGhvdyBuYW1lc3BhY2UgaXMgZGV0ZXJtaW5lZCBieSBvdGhlciBjb2RlLlxuICAgIGdldE5hbWVzcGFjZTogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpc1t0aGlzLm5hbWVzcGFjZUF0dHJpYnV0ZV07XG4gICAgfSxcblxuICAgIC8vIEdldCB0eXBlIG9mIG1vZGVsIHBlciBjb25maWd1cmF0aW9uLlxuICAgIC8vIFNob3VsZCAqYWx3YXlzKiBiZSBob3cgdHlwZSBpcyBkZXRlcm1pbmVkIGJ5IG90aGVyIGNvZGUuXG4gICAgZ2V0VHlwZTogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpc1t0aGlzLnR5cGVBdHRyaWJ1dGVdO1xuICAgIH0sXG5cbiAgICAvLyBBIG1vZGVsIGlzIG5ldyBpZiBpdCBoYXMgbmV2ZXIgYmVlbiBzYXZlZCB0byB0aGUgc2VydmVyLCBhbmQgbGFja3MgYW4gaWQuXG4gICAgaXNOZXc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SWQoKSA9PSBudWxsO1xuICAgIH0sXG5cbiAgICAvLyBnZXQgSFRNTC1lc2NhcGVkIHZhbHVlIG9mIGF0dHJpYnV0ZVxuICAgIGVzY2FwZTogZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgICAgcmV0dXJuIGVzY2FwZSh0aGlzLmdldChhdHRyKSk7XG4gICAgfSxcblxuICAgIC8vIENoZWNrIGlmIHRoZSBtb2RlbCBpcyBjdXJyZW50bHkgaW4gYSB2YWxpZCBzdGF0ZS5cbiAgICBpc1ZhbGlkOiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGUoe30sIGFzc2lnbihvcHRpb25zIHx8IHt9LCB7IHZhbGlkYXRlOiB0cnVlIH0pKTtcbiAgICB9LFxuXG4gICAgLy8gUGFyc2UgY2FuIGJlIHVzZWQgcmVtYXAvcmVzdHJ1Y3R1cmUvcmVuYW1lIGluY29taW5nIHByb3BlcnRpZXNcbiAgICAvLyBiZWZvcmUgdGhleSBhcmUgYXBwbGllZCB0byBhdHRyaWJ1dGVzLlxuICAgIHBhcnNlOiBmdW5jdGlvbiAocmVzcCwgb3B0aW9ucykge1xuICAgICAgICAvL2pzaGludCB1bnVzZWQ6ZmFsc2VcbiAgICAgICAgcmV0dXJuIHJlc3A7XG4gICAgfSxcblxuICAgIC8vIFNlcmlhbGl6ZSBpcyB0aGUgaW52ZXJzZSBvZiBgcGFyc2VgIGl0IGxldHMgeW91IG1hc3NhZ2UgZGF0YVxuICAgIC8vIG9uIHRoZSB3YXkgb3V0LiBCZWZvcmUsIHNlbmRpbmcgdG8gc2VydmVyLCBmb3IgZXhhbXBsZS5cbiAgICBzZXJpYWxpemU6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIHZhciBhdHRyT3B0cyA9IGFzc2lnbih7cHJvcHM6IHRydWV9LCBvcHRpb25zKTtcbiAgICAgICAgdmFyIHJlcyA9IHRoaXMuZ2V0QXR0cmlidXRlcyhhdHRyT3B0cywgdHJ1ZSk7XG4gICAgICAgIFxuICAgICAgICB2YXIgc2V0RnJvbVNlcmlhbGl6ZWRWYWx1ZSA9IGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG5cdCAgICAgICAgcmVzW2tleV0gPSB0aGlzW2tleV0uc2VyaWFsaXplKCk7XG4gICAgICAgIH0uYmluZCh0aGlzKTtcbiAgICAgICAgXG4gICAgICAgIGZvck93bih0aGlzLl9jaGlsZHJlbiwgc2V0RnJvbVNlcmlhbGl6ZWRWYWx1ZSk7XG4gICAgICAgIGZvck93bih0aGlzLl9jb2xsZWN0aW9ucywgc2V0RnJvbVNlcmlhbGl6ZWRWYWx1ZSk7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfSxcblxuICAgIC8vIE1haW4gc2V0IG1ldGhvZCB1c2VkIGJ5IGdlbmVyYXRlZCBzZXR0ZXJzL2dldHRlcnMgYW5kIGNhblxuICAgIC8vIGJlIHVzZWQgZGlyZWN0bHkgaWYgeW91IG5lZWQgdG8gcGFzcyBvcHRpb25zIG9yIHNldCBtdWx0aXBsZVxuICAgIC8vIHByb3BlcnRpZXMgYXQgb25jZS5cbiAgICBzZXQ6IGZ1bmN0aW9uIChrZXksIHZhbHVlLCBvcHRpb25zKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGV4dHJhUHJvcGVydGllcyA9IHRoaXMuZXh0cmFQcm9wZXJ0aWVzO1xuICAgICAgICB2YXIgd2FzQ2hhbmdpbmcsIGNoYW5nZUV2ZW50cywgbmV3VHlwZSwgbmV3VmFsLCBkZWYsIGNhc3QsIGVyciwgYXR0cixcbiAgICAgICAgICAgIGF0dHJzLCBkYXRhVHlwZSwgc2lsZW50LCB1bnNldCwgY3VycmVudFZhbCwgaW5pdGlhbCwgaGFzQ2hhbmdlZCwgaXNFcXVhbCwgb25DaGFuZ2U7XG5cbiAgICAgICAgLy8gSGFuZGxlIGJvdGggYFwia2V5XCIsIHZhbHVlYCBhbmQgYHtrZXk6IHZhbHVlfWAgLXN0eWxlIGFyZ3VtZW50cy5cbiAgICAgICAgaWYgKGlzT2JqZWN0KGtleSkgfHwga2V5ID09PSBudWxsKSB7XG4gICAgICAgICAgICBhdHRycyA9IGtleTtcbiAgICAgICAgICAgIG9wdGlvbnMgPSB2YWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGF0dHJzID0ge307XG4gICAgICAgICAgICBhdHRyc1trZXldID0gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgICAgICBpZiAoIXRoaXMuX3ZhbGlkYXRlKGF0dHJzLCBvcHRpb25zKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIEV4dHJhY3QgYXR0cmlidXRlcyBhbmQgb3B0aW9ucy5cbiAgICAgICAgdW5zZXQgPSBvcHRpb25zLnVuc2V0O1xuICAgICAgICBzaWxlbnQgPSBvcHRpb25zLnNpbGVudDtcbiAgICAgICAgaW5pdGlhbCA9IG9wdGlvbnMuaW5pdGlhbDtcblxuICAgICAgICAvLyBJbml0aWFsaXplIGNoYW5nZSB0cmFja2luZy5cbiAgICAgICAgd2FzQ2hhbmdpbmcgPSB0aGlzLl9jaGFuZ2luZztcbiAgICAgICAgdGhpcy5fY2hhbmdpbmcgPSB0cnVlO1xuICAgICAgICBjaGFuZ2VFdmVudHMgPSBbXTtcblxuICAgICAgICAvLyBpZiBub3QgYWxyZWFkeSBjaGFuZ2luZywgc3RvcmUgcHJldmlvdXNcbiAgICAgICAgaWYgKGluaXRpYWwpIHtcbiAgICAgICAgICAgIHRoaXMuX3ByZXZpb3VzQXR0cmlidXRlcyA9IHt9O1xuICAgICAgICB9IGVsc2UgaWYgKCF3YXNDaGFuZ2luZykge1xuICAgICAgICAgICAgdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzID0gdGhpcy5hdHRyaWJ1dGVzO1xuICAgICAgICAgICAgdGhpcy5fY2hhbmdlZCA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIGVhY2ggYHNldGAgYXR0cmlidXRlLi4uXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBrZXlzID0gT2JqZWN0LmtleXMoYXR0cnMpLCBsZW4gPSBrZXlzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBhdHRyID0ga2V5c1tpXTtcbiAgICAgICAgICAgIG5ld1ZhbCA9IGF0dHJzW2F0dHJdO1xuICAgICAgICAgICAgbmV3VHlwZSA9IHR5cGVvZiBuZXdWYWw7XG4gICAgICAgICAgICBjdXJyZW50VmFsID0gdGhpcy5fdmFsdWVzW2F0dHJdO1xuICAgICAgICAgICAgZGVmID0gdGhpcy5fZGVmaW5pdGlvblthdHRyXTtcblxuICAgICAgICAgICAgaWYgKCFkZWYpIHtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGlzIGlzIGEgY2hpbGQgbW9kZWwgb3IgY29sbGVjdGlvblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jaGlsZHJlblthdHRyXSB8fCB0aGlzLl9jb2xsZWN0aW9uc1thdHRyXSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWlzT2JqZWN0KG5ld1ZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbCA9IHt9O1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpc1thdHRyXS5zZXQobmV3VmFsLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChleHRyYVByb3BlcnRpZXMgPT09ICdpZ25vcmUnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXh0cmFQcm9wZXJ0aWVzID09PSAncmVqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdObyBcIicgKyBhdHRyICsgJ1wiIHByb3BlcnR5IGRlZmluZWQgb24gJyArICh0aGlzLnR5cGUgfHwgJ3RoaXMnKSArICcgbW9kZWwgYW5kIGV4dHJhUHJvcGVydGllcyBub3Qgc2V0IHRvIFwiaWdub3JlXCIgb3IgXCJhbGxvd1wiJyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChleHRyYVByb3BlcnRpZXMgPT09ICdhbGxvdycpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmID0gdGhpcy5fY3JlYXRlUHJvcGVydHlEZWZpbml0aW9uKGF0dHIsICdhbnknKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV4dHJhUHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIHZhbHVlIGZvciBleHRyYVByb3BlcnRpZXM6IFwiJyArIGV4dHJhUHJvcGVydGllcyArICdcIicpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaXNFcXVhbCA9IHRoaXMuX2dldENvbXBhcmVGb3JUeXBlKGRlZi50eXBlKTtcbiAgICAgICAgICAgIG9uQ2hhbmdlID0gdGhpcy5fZ2V0T25DaGFuZ2VGb3JUeXBlKGRlZi50eXBlKTtcbiAgICAgICAgICAgIGRhdGFUeXBlID0gdGhpcy5fZGF0YVR5cGVzW2RlZi50eXBlXTtcblxuICAgICAgICAgICAgLy8gY2hlY2sgdHlwZSBpZiB3ZSBoYXZlIG9uZVxuICAgICAgICAgICAgaWYgKGRhdGFUeXBlICYmIGRhdGFUeXBlLnNldCkge1xuICAgICAgICAgICAgICAgIGNhc3QgPSBkYXRhVHlwZS5zZXQobmV3VmFsKTtcbiAgICAgICAgICAgICAgICBuZXdWYWwgPSBjYXN0LnZhbDtcbiAgICAgICAgICAgICAgICBuZXdUeXBlID0gY2FzdC50eXBlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB3ZSd2ZSBkZWZpbmVkIGEgdGVzdCwgcnVuIGl0XG4gICAgICAgICAgICBpZiAoZGVmLnRlc3QpIHtcbiAgICAgICAgICAgICAgICBlcnIgPSBkZWYudGVzdC5jYWxsKHRoaXMsIG5ld1ZhbCwgbmV3VHlwZSk7XG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQcm9wZXJ0eSBcXCcnICsgYXR0ciArICdcXCcgZmFpbGVkIHZhbGlkYXRpb24gd2l0aCBlcnJvcjogJyArIGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB3ZSBhcmUgcmVxdWlyZWQgYnV0IHVuZGVmaW5lZCwgdGhyb3cgZXJyb3IuXG4gICAgICAgICAgICAvLyBJZiB3ZSBhcmUgbnVsbCBhbmQgYXJlIG5vdCBhbGxvd2luZyBudWxsLCB0aHJvdyBlcnJvclxuICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBhIGRlZmluZWQgdHlwZSBhbmQgdGhlIG5ldyB0eXBlIGRvZXNuJ3QgbWF0Y2gsIGFuZCB3ZSBhcmUgbm90IG51bGwsIHRocm93IGVycm9yLlxuICAgICAgICAgICAgLy8gSWYgd2UgcmVxdWlyZSBzcGVjaWZpYyB2YWx1ZSBhbmQgbmV3IG9uZSBpcyBub3Qgb25lIG9mIHRoZW0sIHRocm93IGVycm9yICh1bmxlc3MgaXQgaGFzIGRlZmF1bHQgdmFsdWUgb3Igd2UncmUgdW5zZXR0aW5nIGl0IHdpdGggdW5kZWZpbmVkKS5cblxuICAgICAgICAgICAgaWYgKG5ld1ZhbCA9PT0gdW5kZWZpbmVkICYmIGRlZi5yZXF1aXJlZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1JlcXVpcmVkIHByb3BlcnR5IFxcJycgKyBhdHRyICsgJ1xcJyBtdXN0IGJlIG9mIHR5cGUgJyArIGRlZi50eXBlICsgJy4gVHJpZWQgdG8gc2V0ICcgKyBuZXdWYWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5ld1ZhbCA9PT0gbnVsbCAmJiBkZWYucmVxdWlyZWQgJiYgIWRlZi5hbGxvd051bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQcm9wZXJ0eSBcXCcnICsgYXR0ciArICdcXCcgbXVzdCBiZSBvZiB0eXBlICcgKyBkZWYudHlwZSArICcgKGNhbm5vdCBiZSBudWxsKS4gVHJpZWQgdG8gc2V0ICcgKyBuZXdWYWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKChkZWYudHlwZSAmJiBkZWYudHlwZSAhPT0gJ2FueScgJiYgZGVmLnR5cGUgIT09IG5ld1R5cGUpICYmIG5ld1ZhbCAhPT0gbnVsbCAmJiBuZXdWYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Byb3BlcnR5IFxcJycgKyBhdHRyICsgJ1xcJyBtdXN0IGJlIG9mIHR5cGUgJyArIGRlZi50eXBlICsgJy4gVHJpZWQgdG8gc2V0ICcgKyBuZXdWYWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRlZi52YWx1ZXMgJiYgIWluY2x1ZGVzKGRlZi52YWx1ZXMsIG5ld1ZhbCkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdFZhbHVlID0gcmVzdWx0KGRlZiwgJ2RlZmF1bHQnKTtcbiAgICAgICAgICAgICAgICBpZiAodW5zZXQgJiYgZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsID0gZGVmYXVsdFZhbHVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXVuc2V0IHx8ICh1bnNldCAmJiBuZXdWYWwgIT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUHJvcGVydHkgXFwnJyArIGF0dHIgKyAnXFwnIG11c3QgYmUgb25lIG9mIHZhbHVlczogJyArIGRlZi52YWx1ZXMuam9pbignLCAnKSArICcuIFRyaWVkIHRvIHNldCAnICsgbmV3VmFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFdlIGtub3cgdGhpcyBoYXMgJ2NoYW5nZWQnIGlmIGl0J3MgdGhlIGluaXRpYWwgc2V0LCBzbyBza2lwIGEgcG90ZW50aWFsbHkgZXhwZW5zaXZlIGlzRXF1YWwgY2hlY2suXG4gICAgICAgICAgICBoYXNDaGFuZ2VkID0gaW5pdGlhbCB8fCAhaXNFcXVhbChjdXJyZW50VmFsLCBuZXdWYWwsIGF0dHIpO1xuXG4gICAgICAgICAgICAvLyBlbmZvcmNlIGBzZXRPbmNlYCBmb3IgcHJvcGVydGllcyBpZiBzZXRcbiAgICAgICAgICAgIGlmIChkZWYuc2V0T25jZSAmJiBjdXJyZW50VmFsICE9PSB1bmRlZmluZWQgJiYgaGFzQ2hhbmdlZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Byb3BlcnR5IFxcJycgKyBhdHRyICsgJ1xcJyBjYW4gb25seSBiZSBzZXQgb25jZS4nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gc2V0L3Vuc2V0IGF0dHJpYnV0ZXMuXG4gICAgICAgICAgICAvLyBJZiB0aGlzIGlzIG5vdCB0aGUgaW5pdGlhbCBzZXQsIGtlZXAgdHJhY2sgb2YgY2hhbmdlZCBhdHRyaWJ1dGVzXG4gICAgICAgICAgICAvLyBhbmQgcHVzaCB0byBjaGFuZ2VFdmVudHMgYXJyYXkgc28gd2UgY2FuIGZpcmUgZXZlbnRzLlxuICAgICAgICAgICAgaWYgKGhhc0NoYW5nZWQpIHtcblxuICAgICAgICAgICAgICAgIC8vIFRoaXMgZmlyZXMgbm8gbWF0dGVyIHdoYXQsIGV2ZW4gb24gaW5pdGlhbCBzZXQuXG4gICAgICAgICAgICAgICAgb25DaGFuZ2UobmV3VmFsLCBjdXJyZW50VmFsLCBhdHRyKTtcblxuICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgYSBjaGFuZ2UgKG5vdCBhbiBpbml0aWFsIHNldCksIG1hcmsgdGhlIGNoYW5nZS5cbiAgICAgICAgICAgICAgICAvLyBOb3RlIGl0J3MgaW1wb3NzaWJsZSB0byB1bnNldCBvbiB0aGUgaW5pdGlhbCBzZXQgKGl0IHdpbGwgYWxyZWFkeSBiZSB1bnNldCksXG4gICAgICAgICAgICAgICAgLy8gc28gd2Ugb25seSBpbmNsdWRlIHRoYXQgbG9naWMgaGVyZS5cbiAgICAgICAgICAgICAgICBpZiAoIWluaXRpYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hhbmdlZFthdHRyXSA9IG5ld1ZhbDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzW2F0dHJdID0gY3VycmVudFZhbDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVuc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGSVhNRSBkZWxldGUgaXMgdmVyeSBzbG93LiBDYW4gd2UgZ2V0IGF3YXkgd2l0aCBzZXR0aW5nIHRvIHVuZGVmaW5lZD9cbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl92YWx1ZXNbYXR0cl07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzaWxlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUV2ZW50cy5wdXNoKHtwcmV2OiBjdXJyZW50VmFsLCB2YWw6IG5ld1ZhbCwga2V5OiBhdHRyfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCF1bnNldCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZXNbYXR0cl0gPSBuZXdWYWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBOb3QgY2hhbmdlZFxuICAgICAgICAgICAgICAgIC8vIEZJWE1FIGRlbGV0ZSBpcyB2ZXJ5IHNsb3cuIENhbiB3ZSBnZXQgYXdheSB3aXRoIHNldHRpbmcgdG8gdW5kZWZpbmVkP1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9jaGFuZ2VkW2F0dHJdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmlyZSBldmVudHMuIFRoaXMgYXJyYXkgaXMgbm90IHBvcHVsYXRlZCBpZiB3ZSBhcmUgdG9sZCB0byBiZSBzaWxlbnQuXG4gICAgICAgIGlmIChjaGFuZ2VFdmVudHMubGVuZ3RoKSB0aGlzLl9wZW5kaW5nID0gdHJ1ZTtcbiAgICAgICAgY2hhbmdlRXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKGNoYW5nZSkge1xuICAgICAgICAgICAgc2VsZi50cmlnZ2VyKCdjaGFuZ2U6JyArIGNoYW5nZS5rZXksIHNlbGYsIGNoYW5nZS52YWwsIG9wdGlvbnMpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBZb3UgbWlnaHQgYmUgd29uZGVyaW5nIHdoeSB0aGVyZSdzIGEgYHdoaWxlYCBsb29wIGhlcmUuIENoYW5nZXMgY2FuXG4gICAgICAgIC8vIGJlIHJlY3Vyc2l2ZWx5IG5lc3RlZCB3aXRoaW4gYFwiY2hhbmdlXCJgIGV2ZW50cy5cbiAgICAgICAgaWYgKHdhc0NoYW5naW5nKSByZXR1cm4gdGhpcztcbiAgICAgICAgd2hpbGUgKHRoaXMuX3BlbmRpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuX3BlbmRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlcignY2hhbmdlJywgdGhpcywgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcGVuZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9jaGFuZ2luZyA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgZ2V0OiBmdW5jdGlvbiAoYXR0cikge1xuICAgICAgICByZXR1cm4gdGhpc1thdHRyXTtcbiAgICB9LFxuXG4gICAgLy8gVG9nZ2xlIGJvb2xlYW4gcHJvcGVydGllcyBvciBwcm9wZXJ0aWVzIHRoYXQgaGF2ZSBhIGB2YWx1ZXNgXG4gICAgLy8gYXJyYXkgaW4gaXRzIGRlZmluaXRpb24uXG4gICAgdG9nZ2xlOiBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgdmFyIGRlZiA9IHRoaXMuX2RlZmluaXRpb25bcHJvcGVydHldO1xuICAgICAgICBpZiAoZGVmLnR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgLy8gaWYgaXQncyBhIGJvb2wsIGp1c3QgZmxpcCBpdFxuICAgICAgICAgICAgdGhpc1twcm9wZXJ0eV0gPSAhdGhpc1twcm9wZXJ0eV07XG4gICAgICAgIH0gZWxzZSBpZiAoZGVmICYmIGRlZi52YWx1ZXMpIHtcbiAgICAgICAgICAgIC8vIElmIGl0J3MgYSBwcm9wZXJ0eSB3aXRoIGFuIGFycmF5IG9mIHZhbHVlc1xuICAgICAgICAgICAgLy8gc2tpcCB0byB0aGUgbmV4dCBvbmUgbG9vcGluZyBiYWNrIGlmIGF0IGVuZC5cbiAgICAgICAgICAgIHRoaXNbcHJvcGVydHldID0gYXJyYXlOZXh0KGRlZi52YWx1ZXMsIHRoaXNbcHJvcGVydHldKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0NhbiBvbmx5IHRvZ2dsZSBwcm9wZXJ0aWVzIHRoYXQgYXJlIHR5cGUgYGJvb2xlYW5gIG9yIGhhdmUgYHZhbHVlc2AgYXJyYXkuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8vIEdldCBhbGwgb2YgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG1vZGVsIGF0IHRoZSB0aW1lIG9mIHRoZSBwcmV2aW91c1xuICAgIC8vIGBcImNoYW5nZVwiYCBldmVudC5cbiAgICBwcmV2aW91c0F0dHJpYnV0ZXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNsb25lT2JqKHRoaXMuX3ByZXZpb3VzQXR0cmlidXRlcyk7XG4gICAgfSxcblxuICAgIC8vIERldGVybWluZSBpZiB0aGUgbW9kZWwgaGFzIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgYFwiY2hhbmdlXCJgIGV2ZW50LlxuICAgIC8vIElmIHlvdSBzcGVjaWZ5IGFuIGF0dHJpYnV0ZSBuYW1lLCBkZXRlcm1pbmUgaWYgdGhhdCBhdHRyaWJ1dGUgaGFzIGNoYW5nZWQuXG4gICAgaGFzQ2hhbmdlZDogZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgICAgaWYgKGF0dHIgPT0gbnVsbCkgcmV0dXJuICEhT2JqZWN0LmtleXModGhpcy5fY2hhbmdlZCkubGVuZ3RoO1xuICAgICAgICBpZiAoaGFzKHRoaXMuX2Rlcml2ZWQsIGF0dHIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVyaXZlZFthdHRyXS5kZXBMaXN0LnNvbWUoZnVuY3Rpb24gKGRlcCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhc0NoYW5nZWQoZGVwKTtcbiAgICAgICAgICAgIH0sIHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoYXModGhpcy5fY2hhbmdlZCwgYXR0cik7XG4gICAgfSxcblxuICAgIC8vIFJldHVybiBhbiBvYmplY3QgY29udGFpbmluZyBhbGwgdGhlIGF0dHJpYnV0ZXMgdGhhdCBoYXZlIGNoYW5nZWQsIG9yXG4gICAgLy8gZmFsc2UgaWYgdGhlcmUgYXJlIG5vIGNoYW5nZWQgYXR0cmlidXRlcy4gVXNlZnVsIGZvciBkZXRlcm1pbmluZyB3aGF0XG4gICAgLy8gcGFydHMgb2YgYSB2aWV3IG5lZWQgdG8gYmUgdXBkYXRlZCBhbmQvb3Igd2hhdCBhdHRyaWJ1dGVzIG5lZWQgdG8gYmVcbiAgICAvLyBwZXJzaXN0ZWQgdG8gdGhlIHNlcnZlci4gVW5zZXQgYXR0cmlidXRlcyB3aWxsIGJlIHNldCB0byB1bmRlZmluZWQuXG4gICAgLy8gWW91IGNhbiBhbHNvIHBhc3MgYW4gYXR0cmlidXRlcyBvYmplY3QgdG8gZGlmZiBhZ2FpbnN0IHRoZSBtb2RlbCxcbiAgICAvLyBkZXRlcm1pbmluZyBpZiB0aGVyZSAqd291bGQgYmUqIGEgY2hhbmdlLlxuICAgIGNoYW5nZWRBdHRyaWJ1dGVzOiBmdW5jdGlvbiAoZGlmZikge1xuICAgICAgICBpZiAoIWRpZmYpIHJldHVybiB0aGlzLmhhc0NoYW5nZWQoKSA/IGNsb25lT2JqKHRoaXMuX2NoYW5nZWQpIDogZmFsc2U7XG4gICAgICAgIHZhciB2YWwsIGNoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgdmFyIG9sZCA9IHRoaXMuX2NoYW5naW5nID8gdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzIDogdGhpcy5hdHRyaWJ1dGVzO1xuICAgICAgICB2YXIgZGVmLCBpc0VxdWFsO1xuICAgICAgICBmb3IgKHZhciBhdHRyIGluIGRpZmYpIHtcbiAgICAgICAgICAgIGRlZiA9IHRoaXMuX2RlZmluaXRpb25bYXR0cl07XG4gICAgICAgICAgICBpZiAoIWRlZikgY29udGludWU7XG4gICAgICAgICAgICBpc0VxdWFsID0gdGhpcy5fZ2V0Q29tcGFyZUZvclR5cGUoZGVmLnR5cGUpO1xuICAgICAgICAgICAgaWYgKGlzRXF1YWwob2xkW2F0dHJdLCAodmFsID0gZGlmZlthdHRyXSkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIChjaGFuZ2VkIHx8IChjaGFuZ2VkID0ge30pKVthdHRyXSA9IHZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2hhbmdlZDtcbiAgICB9LFxuXG4gICAgdG9KU09OOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlcmlhbGl6ZSgpO1xuICAgIH0sXG5cbiAgICB1bnNldDogZnVuY3Rpb24gKGF0dHJzLCBvcHRpb25zKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgYXR0cnMgPSBBcnJheS5pc0FycmF5KGF0dHJzKSA/IGF0dHJzIDogW2F0dHJzXTtcbiAgICAgICAgYXR0cnMuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICB2YXIgZGVmID0gc2VsZi5fZGVmaW5pdGlvbltrZXldO1xuICAgICAgICAgICAgaWYgKCFkZWYpIHJldHVybjtcbiAgICAgICAgICAgIHZhciB2YWw7XG4gICAgICAgICAgICBpZiAoZGVmLnJlcXVpcmVkKSB7XG4gICAgICAgICAgICAgICAgdmFsID0gcmVzdWx0KGRlZiwgJ2RlZmF1bHQnKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5zZXQoa2V5LCB2YWwsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5zZXQoa2V5LCB2YWwsIGFzc2lnbih7fSwgb3B0aW9ucywge3Vuc2V0OiB0cnVlfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9LFxuXG4gICAgY2xlYXI6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5hdHRyaWJ1dGVzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgIHNlbGYudW5zZXQoa2V5LCBvcHRpb25zKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBwcmV2aW91czogZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgICAgaWYgKGF0dHIgPT0gbnVsbCB8fCAhT2JqZWN0LmtleXModGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzKS5sZW5ndGgpIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzW2F0dHJdO1xuICAgIH0sXG5cbiAgICAvLyBHZXQgZGVmYXVsdCB2YWx1ZXMgZm9yIGEgY2VydGFpbiB0eXBlXG4gICAgX2dldERlZmF1bHRGb3JUeXBlOiBmdW5jdGlvbiAodHlwZSkge1xuICAgICAgICB2YXIgZGF0YVR5cGUgPSB0aGlzLl9kYXRhVHlwZXNbdHlwZV07XG4gICAgICAgIHJldHVybiBkYXRhVHlwZSAmJiBkYXRhVHlwZVsnZGVmYXVsdCddO1xuICAgIH0sXG5cbiAgICAvLyBEZXRlcm1pbmUgd2hpY2ggY29tcGFyaXNvbiBhbGdvcml0aG0gdG8gdXNlIGZvciBjb21wYXJpbmcgYSBwcm9wZXJ0eVxuICAgIF9nZXRDb21wYXJlRm9yVHlwZTogZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgICAgdmFyIGRhdGFUeXBlID0gdGhpcy5fZGF0YVR5cGVzW3R5cGVdO1xuICAgICAgICBpZiAoZGF0YVR5cGUgJiYgZGF0YVR5cGUuY29tcGFyZSkgcmV0dXJuIGRhdGFUeXBlLmNvbXBhcmUuYmluZCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIF9pc0VxdWFsOyAvLyBpZiBubyBjb21wYXJlIGZ1bmN0aW9uIGlzIGRlZmluZWQsIHVzZSBfLmlzRXF1YWxcbiAgICB9LFxuXG4gICAgX2dldE9uQ2hhbmdlRm9yVHlwZSA6IGZ1bmN0aW9uKHR5cGUpe1xuICAgICAgICB2YXIgZGF0YVR5cGUgPSB0aGlzLl9kYXRhVHlwZXNbdHlwZV07XG4gICAgICAgIGlmIChkYXRhVHlwZSAmJiBkYXRhVHlwZS5vbkNoYW5nZSkgcmV0dXJuIGRhdGFUeXBlLm9uQ2hhbmdlLmJpbmQodGhpcyk7XG4gICAgICAgIHJldHVybiBub29wO1xuICAgIH0sXG5cbiAgICAvLyBSdW4gdmFsaWRhdGlvbiBhZ2FpbnN0IHRoZSBuZXh0IGNvbXBsZXRlIHNldCBvZiBtb2RlbCBhdHRyaWJ1dGVzLFxuICAgIC8vIHJldHVybmluZyBgdHJ1ZWAgaWYgYWxsIGlzIHdlbGwuIE90aGVyd2lzZSwgZmlyZSBhbiBgXCJpbnZhbGlkXCJgIGV2ZW50LlxuICAgIF92YWxpZGF0ZTogZnVuY3Rpb24gKGF0dHJzLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghb3B0aW9ucy52YWxpZGF0ZSB8fCAhdGhpcy52YWxpZGF0ZSkgcmV0dXJuIHRydWU7XG4gICAgICAgIGF0dHJzID0gYXNzaWduKHt9LCB0aGlzLmF0dHJpYnV0ZXMsIGF0dHJzKTtcbiAgICAgICAgdmFyIGVycm9yID0gdGhpcy52YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlKGF0dHJzLCBvcHRpb25zKSB8fCBudWxsO1xuICAgICAgICBpZiAoIWVycm9yKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgdGhpcy50cmlnZ2VyKCdpbnZhbGlkJywgdGhpcywgZXJyb3IsIGFzc2lnbihvcHRpb25zIHx8IHt9LCB7dmFsaWRhdGlvbkVycm9yOiBlcnJvcn0pKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICBfY3JlYXRlUHJvcGVydHlEZWZpbml0aW9uOiBmdW5jdGlvbiAobmFtZSwgZGVzYywgaXNTZXNzaW9uKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVQcm9wZXJ0eURlZmluaXRpb24odGhpcywgbmFtZSwgZGVzYywgaXNTZXNzaW9uKTtcbiAgICB9LFxuXG4gICAgLy8ganVzdCBtYWtlcyBmcmllbmRsaWVyIGVycm9ycyB3aGVuIHRyeWluZyB0byBkZWZpbmUgYSBuZXcgbW9kZWxcbiAgICAvLyBvbmx5IHVzZWQgd2hlbiBzZXR0aW5nIHVwIG9yaWdpbmFsIHByb3BlcnR5IGRlZmluaXRpb25zXG4gICAgX2Vuc3VyZVZhbGlkVHlwZTogZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIGluY2x1ZGVzKFsnc3RyaW5nJywgJ251bWJlcicsICdib29sZWFuJywgJ2FycmF5JywgJ29iamVjdCcsICdkYXRlJywgJ3N0YXRlJywgJ2FueSddXG4gICAgICAgICAgICAuY29uY2F0KE9iamVjdC5rZXlzKHRoaXMuX2RhdGFUeXBlcykpLCB0eXBlKSA/IHR5cGUgOiB1bmRlZmluZWQ7XG4gICAgfSxcblxuICAgIGdldEF0dHJpYnV0ZXM6IGZ1bmN0aW9uIChvcHRpb25zLCByYXcpIHtcbiAgICAgICAgb3B0aW9ucyA9IGFzc2lnbih7XG4gICAgICAgICAgICBzZXNzaW9uOiBmYWxzZSxcbiAgICAgICAgICAgIHByb3BzOiBmYWxzZSxcbiAgICAgICAgICAgIGRlcml2ZWQ6IGZhbHNlXG4gICAgICAgIH0sIG9wdGlvbnMgfHwge30pO1xuICAgICAgICB2YXIgcmVzID0ge307XG4gICAgICAgIHZhciB2YWwsIGRlZjtcbiAgICAgICAgZm9yICh2YXIgaXRlbSBpbiB0aGlzLl9kZWZpbml0aW9uKSB7XG4gICAgICAgICAgICBkZWYgPSB0aGlzLl9kZWZpbml0aW9uW2l0ZW1dO1xuICAgICAgICAgICAgaWYgKChvcHRpb25zLnNlc3Npb24gJiYgZGVmLnNlc3Npb24pIHx8IChvcHRpb25zLnByb3BzICYmICFkZWYuc2Vzc2lvbikpIHtcbiAgICAgICAgICAgICAgICB2YWwgPSByYXcgPyB0aGlzLl92YWx1ZXNbaXRlbV0gOiB0aGlzW2l0ZW1dO1xuICAgICAgICAgICAgICAgIGlmIChyYXcgJiYgdmFsICYmIGlzRnVuY3Rpb24odmFsLnNlcmlhbGl6ZSkpIHZhbCA9IHZhbC5zZXJpYWxpemUoKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ3VuZGVmaW5lZCcpIHZhbCA9IHJlc3VsdChkZWYsICdkZWZhdWx0Jyk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWwgIT09ICd1bmRlZmluZWQnKSByZXNbaXRlbV0gPSB2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuZGVyaXZlZCkge1xuICAgICAgICAgICAgZm9yICh2YXIgZGVyaXZlZEl0ZW0gaW4gdGhpcy5fZGVyaXZlZCkgcmVzW2Rlcml2ZWRJdGVtXSA9IHRoaXNbZGVyaXZlZEl0ZW1dO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfSxcblxuICAgIF9pbml0RGVyaXZlZDogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgZm9yT3duKHRoaXMuX2Rlcml2ZWQsIGZ1bmN0aW9uICh2YWx1ZSwgbmFtZSkge1xuICAgICAgICAgICAgdmFyIGRlZiA9IHNlbGYuX2Rlcml2ZWRbbmFtZV07XG4gICAgICAgICAgICBkZWYuZGVwcyA9IGRlZi5kZXBMaXN0O1xuXG4gICAgICAgICAgICB2YXIgdXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBuZXdWYWwgPSBkZWYuZm4uY2FsbChzZWxmKTtcblxuICAgICAgICAgICAgICAgIGlmIChzZWxmLl9jYWNoZVtuYW1lXSAhPT0gbmV3VmFsIHx8ICFkZWYuY2FjaGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlZi5jYWNoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcHJldmlvdXNBdHRyaWJ1dGVzW25hbWVdID0gc2VsZi5fY2FjaGVbbmFtZV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc2VsZi5fY2FjaGVbbmFtZV0gPSBuZXdWYWw7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYudHJpZ2dlcignY2hhbmdlOicgKyBuYW1lLCBzZWxmLCBzZWxmLl9jYWNoZVtuYW1lXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgZGVmLmRlcHMuZm9yRWFjaChmdW5jdGlvbiAocHJvcFN0cmluZykge1xuICAgICAgICAgICAgICAgIHNlbGYuX2tleVRyZWUuYWRkKHByb3BTdHJpbmcsIHVwZGF0ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5vbignYWxsJywgZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xuICAgICAgICAgICAgaWYgKGNoYW5nZVJFLnRlc3QoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgICAgIHNlbGYuX2tleVRyZWUuZ2V0KGV2ZW50TmFtZS5zcGxpdCgnOicpWzFdKS5mb3JFYWNoKGZ1bmN0aW9uIChmbikge1xuICAgICAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB0aGlzKTtcbiAgICB9LFxuXG4gICAgX2dldERlcml2ZWRQcm9wZXJ0eTogZnVuY3Rpb24gKG5hbWUsIGZsdXNoQ2FjaGUpIHtcbiAgICAgICAgLy8gaXMgdGhpcyBhIGRlcml2ZWQgcHJvcGVydHkgdGhhdCBpcyBjYWNoZWRcbiAgICAgICAgaWYgKHRoaXMuX2Rlcml2ZWRbbmFtZV0uY2FjaGUpIHtcbiAgICAgICAgICAgIC8vc2V0IGlmIHRoaXMgaXMgdGhlIGZpcnN0IHRpbWUsIG9yIGZsdXNoQ2FjaGUgaXMgc2V0XG4gICAgICAgICAgICBpZiAoZmx1c2hDYWNoZSB8fCAhdGhpcy5fY2FjaGUuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZVtuYW1lXSA9IHRoaXMuX2Rlcml2ZWRbbmFtZV0uZm4uYXBwbHkodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY2FjaGVbbmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVyaXZlZFtuYW1lXS5mbi5hcHBseSh0aGlzKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBfaW5pdENvbGxlY3Rpb25zOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjb2xsO1xuICAgICAgICBpZiAoIXRoaXMuX2NvbGxlY3Rpb25zKSByZXR1cm47XG4gICAgICAgIGZvciAoY29sbCBpbiB0aGlzLl9jb2xsZWN0aW9ucykge1xuICAgICAgICAgICAgdGhpcy5fc2FmZVNldChjb2xsLCBuZXcgdGhpcy5fY29sbGVjdGlvbnNbY29sbF0obnVsbCwge3BhcmVudDogdGhpc30pKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBfaW5pdENoaWxkcmVuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjaGlsZDtcbiAgICAgICAgaWYgKCF0aGlzLl9jaGlsZHJlbikgcmV0dXJuO1xuICAgICAgICBmb3IgKGNoaWxkIGluIHRoaXMuX2NoaWxkcmVuKSB7XG4gICAgICAgICAgICB0aGlzLl9zYWZlU2V0KGNoaWxkLCBuZXcgdGhpcy5fY2hpbGRyZW5bY2hpbGRdKHt9LCB7cGFyZW50OiB0aGlzfSkpO1xuICAgICAgICAgICAgdGhpcy5saXN0ZW5Ubyh0aGlzW2NoaWxkXSwgJ2FsbCcsIHRoaXMuX2dldENhY2hlZEV2ZW50QnViYmxpbmdIYW5kbGVyKGNoaWxkKSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLy8gUmV0dXJucyBhIGJvdW5kIGhhbmRsZXIgZm9yIGRvaW5nIGV2ZW50IGJ1YmJsaW5nIHdoaWxlXG4gICAgLy8gYWRkaW5nIGEgbmFtZSB0byB0aGUgY2hhbmdlIHN0cmluZy5cbiAgICBfZ2V0Q2FjaGVkRXZlbnRCdWJibGluZ0hhbmRsZXI6IGZ1bmN0aW9uIChwcm9wZXJ0eU5hbWUpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9ldmVudEJ1YmJsaW5nSGFuZGxlckNhY2hlW3Byb3BlcnR5TmFtZV0pIHtcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50QnViYmxpbmdIYW5kbGVyQ2FjaGVbcHJvcGVydHlOYW1lXSA9IGZ1bmN0aW9uIChuYW1lLCBtb2RlbCwgbmV3VmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2hhbmdlUkUudGVzdChuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoJ2NoYW5nZTonICsgcHJvcGVydHlOYW1lICsgJy4nICsgbmFtZS5zcGxpdCgnOicpWzFdLCBtb2RlbCwgbmV3VmFsdWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ2NoYW5nZScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKCdjaGFuZ2UnLCB0aGlzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LmJpbmQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50QnViYmxpbmdIYW5kbGVyQ2FjaGVbcHJvcGVydHlOYW1lXTtcbiAgICB9LFxuXG4gICAgLy8gQ2hlY2sgdGhhdCBhbGwgcmVxdWlyZWQgYXR0cmlidXRlcyBhcmUgcHJlc2VudFxuICAgIF92ZXJpZnlSZXF1aXJlZDogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXR0cnMgPSB0aGlzLmF0dHJpYnV0ZXM7IC8vIHNob3VsZCBpbmNsdWRlIHNlc3Npb25cbiAgICAgICAgZm9yICh2YXIgZGVmIGluIHRoaXMuX2RlZmluaXRpb24pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9kZWZpbml0aW9uW2RlZl0ucmVxdWlyZWQgJiYgdHlwZW9mIGF0dHJzW2RlZl0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICAvLyBleHBvc2Ugc2FmZVNldCBtZXRob2RcbiAgICBfc2FmZVNldDogZnVuY3Rpb24gc2FmZVNldChwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKHByb3BlcnR5IGluIHRoaXMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRW5jb3VudGVyZWQgbmFtZXNwYWNlIGNvbGxpc2lvbiB3aGlsZSBzZXR0aW5nIGluc3RhbmNlIHByb3BlcnR5IGAnICsgcHJvcGVydHkgKyAnYCcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXNbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn0pO1xuXG4vLyBnZXR0ZXIgZm9yIGF0dHJpYnV0ZXNcbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEJhc2UucHJvdG90eXBlLCB7XG4gICAgYXR0cmlidXRlczoge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZXMoe3Byb3BzOiB0cnVlLCBzZXNzaW9uOiB0cnVlfSk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGFsbDoge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZXMoe1xuICAgICAgICAgICAgICAgIHNlc3Npb246IHRydWUsXG4gICAgICAgICAgICAgICAgcHJvcHM6IHRydWUsXG4gICAgICAgICAgICAgICAgZGVyaXZlZDogdHJ1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGlzU3RhdGU6IHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlOyB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uICgpIHsgfVxuICAgIH1cbn0pO1xuXG4vLyBoZWxwZXIgZm9yIGNyZWF0aW5nL3N0b3JpbmcgcHJvcGVydHkgZGVmaW5pdGlvbnMgYW5kIGNyZWF0aW5nXG4vLyBhcHByb3ByaWF0ZSBnZXR0ZXJzL3NldHRlcnNcbmZ1bmN0aW9uIGNyZWF0ZVByb3BlcnR5RGVmaW5pdGlvbihvYmplY3QsIG5hbWUsIGRlc2MsIGlzU2Vzc2lvbikge1xuICAgIHZhciBkZWYgPSBvYmplY3QuX2RlZmluaXRpb25bbmFtZV0gPSB7fTtcbiAgICB2YXIgdHlwZSwgZGVzY0FycmF5O1xuXG4gICAgaWYgKGlzU3RyaW5nKGRlc2MpKSB7XG4gICAgICAgIC8vIGdyYWIgb3VyIHR5cGUgaWYgYWxsIHdlJ3ZlIGdvdCBpcyBhIHN0cmluZ1xuICAgICAgICB0eXBlID0gb2JqZWN0Ll9lbnN1cmVWYWxpZFR5cGUoZGVzYyk7XG4gICAgICAgIGlmICh0eXBlKSBkZWYudHlwZSA9IHR5cGU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy9UcmFuc2Zvcm0gYXJyYXkgb2YgWyd0eXBlJywgcmVxdWlyZWQsIGRlZmF1bHRdIHRvIG9iamVjdCBmb3JtXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRlc2MpKSB7XG4gICAgICAgICAgICBkZXNjQXJyYXkgPSBkZXNjO1xuICAgICAgICAgICAgZGVzYyA9IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBkZXNjQXJyYXlbMF0sXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGRlc2NBcnJheVsxXSxcbiAgICAgICAgICAgICAgICAnZGVmYXVsdCc6IGRlc2NBcnJheVsyXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHR5cGUgPSBvYmplY3QuX2Vuc3VyZVZhbGlkVHlwZShkZXNjLnR5cGUpO1xuICAgICAgICBpZiAodHlwZSkgZGVmLnR5cGUgPSB0eXBlO1xuXG4gICAgICAgIGlmIChkZXNjLnJlcXVpcmVkKSBkZWYucmVxdWlyZWQgPSB0cnVlO1xuXG4gICAgICAgIGlmIChkZXNjWydkZWZhdWx0J10gJiYgdHlwZW9mIGRlc2NbJ2RlZmF1bHQnXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBkZWZhdWx0IHZhbHVlIGZvciAnICsgbmFtZSArICcgY2Fubm90IGJlIGFuIG9iamVjdC9hcnJheSwgbXVzdCBiZSBhIHZhbHVlIG9yIGEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhIHZhbHVlL29iamVjdC9hcnJheScpO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVmWydkZWZhdWx0J10gPSBkZXNjWydkZWZhdWx0J107XG5cbiAgICAgICAgZGVmLmFsbG93TnVsbCA9IGRlc2MuYWxsb3dOdWxsID8gZGVzYy5hbGxvd051bGwgOiBmYWxzZTtcbiAgICAgICAgaWYgKGRlc2Muc2V0T25jZSkgZGVmLnNldE9uY2UgPSB0cnVlO1xuICAgICAgICBpZiAoZGVmLnJlcXVpcmVkICYmIGRlZlsnZGVmYXVsdCddID09PSB1bmRlZmluZWQgJiYgIWRlZi5zZXRPbmNlKSBkZWZbJ2RlZmF1bHQnXSA9IG9iamVjdC5fZ2V0RGVmYXVsdEZvclR5cGUodHlwZSk7XG4gICAgICAgIGRlZi50ZXN0ID0gZGVzYy50ZXN0O1xuICAgICAgICBkZWYudmFsdWVzID0gZGVzYy52YWx1ZXM7XG4gICAgfVxuICAgIGlmIChpc1Nlc3Npb24pIGRlZi5zZXNzaW9uID0gdHJ1ZTtcblxuICAgIGlmICghdHlwZSkge1xuICAgICAgICB0eXBlID0gaXNTdHJpbmcoZGVzYykgPyBkZXNjIDogZGVzYy50eXBlO1xuICAgICAgICAvLyBUT0RPOiBzdGFydCB0aHJvd2luZyBhIFR5cGVFcnJvciBpbiBmdXR1cmUgbWFqb3IgdmVyc2lvbnMgaW5zdGVhZCBvZiB3YXJuaW5nXG4gICAgICAgIGNvbnNvbGUud2FybignSW52YWxpZCBkYXRhIHR5cGUgb2YgYCcgKyB0eXBlICsgJ2AgZm9yIGAnICsgbmFtZSArICdgIHByb3BlcnR5LiBVc2Ugb25lIG9mIHRoZSBkZWZhdWx0IHR5cGVzIG9yIGRlZmluZSB5b3VyIG93bicpO1xuICAgIH1cblxuICAgIC8vIGRlZmluZSBhIGdldHRlci9zZXR0ZXIgb24gdGhlIHByb3RvdHlwZVxuICAgIC8vIGJ1dCB0aGV5IGdldC9zZXQgb24gdGhlIGluc3RhbmNlXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iamVjdCwgbmFtZSwge1xuICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0KG5hbWUsIHZhbCk7XG4gICAgICAgIH0sXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLl92YWx1ZXMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcignWW91IG1heSBiZSB0cnlpbmcgdG8gYGV4dGVuZGAgYSBzdGF0ZSBvYmplY3Qgd2l0aCBcIicgKyBuYW1lICsgJ1wiIHdoaWNoIGhhcyBiZWVuIGRlZmluZWQgaW4gYHByb3BzYCBvbiB0aGUgb2JqZWN0IGJlaW5nIGV4dGVuZGVkJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLl92YWx1ZXNbbmFtZV07XG4gICAgICAgICAgICB2YXIgdHlwZURlZiA9IHRoaXMuX2RhdGFUeXBlc1tkZWYudHlwZV07XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlRGVmICYmIHR5cGVEZWYuZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdHlwZURlZi5nZXQodmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGVmYXVsdFZhbHVlID0gcmVzdWx0KGRlZiwgJ2RlZmF1bHQnKTtcbiAgICAgICAgICAgIHRoaXMuX3ZhbHVlc1tuYW1lXSA9IGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgIC8vIElmIHdlJ3ZlIHNldCBhIGRlZmF1bHRWYWx1ZSwgZmlyZSBhIGNoYW5nZSBoYW5kbGVyIGVmZmVjdGl2ZWx5IG1hcmtpbmdcbiAgICAgICAgICAgIC8vIGl0cyBjaGFuZ2UgZnJvbSB1bmRlZmluZWQgdG8gdGhlIGRlZmF1bHQgdmFsdWUuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGRlZmF1bHRWYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICB2YXIgb25DaGFuZ2UgPSB0aGlzLl9nZXRPbkNoYW5nZUZvclR5cGUoZGVmLnR5cGUpO1xuICAgICAgICAgICAgICAgIG9uQ2hhbmdlKGRlZmF1bHRWYWx1ZSwgdmFsdWUsIG5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGRlZjtcbn1cblxuLy8gaGVscGVyIGZvciBjcmVhdGluZyBkZXJpdmVkIHByb3BlcnR5IGRlZmluaXRpb25zXG5mdW5jdGlvbiBjcmVhdGVEZXJpdmVkUHJvcGVydHkobW9kZWxQcm90bywgbmFtZSwgZGVmaW5pdGlvbikge1xuICAgIHZhciBkZWYgPSBtb2RlbFByb3RvLl9kZXJpdmVkW25hbWVdID0ge1xuICAgICAgICBmbjogaXNGdW5jdGlvbihkZWZpbml0aW9uKSA/IGRlZmluaXRpb24gOiBkZWZpbml0aW9uLmZuLFxuICAgICAgICBjYWNoZTogKGRlZmluaXRpb24uY2FjaGUgIT09IGZhbHNlKSxcbiAgICAgICAgZGVwTGlzdDogZGVmaW5pdGlvbi5kZXBzIHx8IFtdXG4gICAgfTtcblxuICAgIC8vIGFkZCB0byBvdXIgc2hhcmVkIGRlcGVuZGVuY3kgbGlzdFxuICAgIGRlZi5kZXBMaXN0LmZvckVhY2goZnVuY3Rpb24gKGRlcCkge1xuICAgICAgICBtb2RlbFByb3RvLl9kZXBzW2RlcF0gPSB1bmlvbihtb2RlbFByb3RvLl9kZXBzW2RlcF0gfHwgW10sIFtuYW1lXSk7XG4gICAgfSk7XG5cbiAgICAvLyBkZWZpbmVkIGEgdG9wLWxldmVsIGdldHRlciBmb3IgZGVyaXZlZCBuYW1lc1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2RlbFByb3RvLCBuYW1lLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldERlcml2ZWRQcm9wZXJ0eShuYW1lKTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYFwiICsgbmFtZSArIFwiYCBpcyBhIGRlcml2ZWQgcHJvcGVydHksIGl0IGNhbid0IGJlIHNldCBkaXJlY3RseS5cIik7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxudmFyIGRhdGFUeXBlcyA9IHtcbiAgICBzdHJpbmc6IHtcbiAgICAgICAgJ2RlZmF1bHQnOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGRhdGU6IHtcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAobmV3VmFsKSB7XG4gICAgICAgICAgICB2YXIgbmV3VHlwZTtcbiAgICAgICAgICAgIGlmIChuZXdWYWwgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIG5ld1R5cGUgPSB0eXBlb2YgbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzRGF0ZShuZXdWYWwpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVyciA9IG51bGw7XG4gICAgICAgICAgICAgICAgdmFyIGRhdGVWYWwgPSBuZXcgRGF0ZShuZXdWYWwpLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICBpZiAoaXNOYU4oZGF0ZVZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIG5ld1ZhbCBjYW50IGJlIHBhcnNlZCwgdGhlbiB0cnkgcGFyc2VJbnQgZmlyc3RcbiAgICAgICAgICAgICAgICAgICAgZGF0ZVZhbCA9IG5ldyBEYXRlKHBhcnNlSW50KG5ld1ZhbCwgMTApKS52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihkYXRlVmFsKSkgZXJyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbmV3VmFsID0gZGF0ZVZhbDtcbiAgICAgICAgICAgICAgICBuZXdUeXBlID0gJ2RhdGUnO1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3VHlwZSA9IHR5cGVvZiBuZXdWYWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXdUeXBlID0gJ2RhdGUnO1xuICAgICAgICAgICAgICAgIG5ld1ZhbCA9IG5ld1ZhbC52YWx1ZU9mKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdmFsOiBuZXdWYWwsXG4gICAgICAgICAgICAgICAgdHlwZTogbmV3VHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgICAgICBpZiAodmFsID09IG51bGwpIHsgcmV0dXJuIHZhbDsgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHZhbCk7XG4gICAgICAgIH0sXG4gICAgICAgICdkZWZhdWx0JzogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKCk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGFycmF5OiB7XG4gICAgICAgIHNldDogZnVuY3Rpb24gKG5ld1ZhbCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB2YWw6IG5ld1ZhbCxcbiAgICAgICAgICAgICAgICB0eXBlOiBBcnJheS5pc0FycmF5KG5ld1ZhbCkgPyAnYXJyYXknIDogdHlwZW9mIG5ld1ZhbFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgJ2RlZmF1bHQnOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9LFxuICAgIG9iamVjdDoge1xuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdWYWwpIHtcbiAgICAgICAgICAgIHZhciBuZXdUeXBlID0gdHlwZW9mIG5ld1ZhbDtcbiAgICAgICAgICAgIC8vIHdlIGhhdmUgdG8gaGF2ZSBhIHdheSBvZiBzdXBwb3J0aW5nIFwibWlzc2luZ1wiIG9iamVjdHMuXG4gICAgICAgICAgICAvLyBOdWxsIGlzIGFuIG9iamVjdCwgYnV0IHNldHRpbmcgYSB2YWx1ZSB0byB1bmRlZmluZWRcbiAgICAgICAgICAgIC8vIHNob3VsZCB3b3JrIHRvbywgSU1PLiBXZSBqdXN0IG92ZXJyaWRlIGl0LCBpbiB0aGF0IGNhc2UuXG4gICAgICAgICAgICBpZiAobmV3VHlwZSAhPT0gJ29iamVjdCcgJiYgbmV3VmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBuZXdWYWwgPSBudWxsO1xuICAgICAgICAgICAgICAgIG5ld1R5cGUgPSAnb2JqZWN0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdmFsOiBuZXdWYWwsXG4gICAgICAgICAgICAgICAgdHlwZTogbmV3VHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgJ2RlZmF1bHQnOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8vIHRoZSBgc3RhdGVgIGRhdGEgdHlwZSBpcyBhIGJpdCBzcGVjaWFsIGluIHRoYXQgc2V0dGluZyBpdCBzaG91bGRcbiAgICAvLyBhbHNvIGJ1YmJsZSBldmVudHNcbiAgICBzdGF0ZToge1xuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdWYWwpIHtcbiAgICAgICAgICAgIHZhciBpc0luc3RhbmNlID0gbmV3VmFsIGluc3RhbmNlb2YgQmFzZSB8fCAobmV3VmFsICYmIG5ld1ZhbC5pc1N0YXRlKTtcbiAgICAgICAgICAgIGlmIChpc0luc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsOiBuZXdWYWwsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdGF0ZSdcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB2YWw6IG5ld1ZhbCxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogdHlwZW9mIG5ld1ZhbFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGNvbXBhcmU6IGZ1bmN0aW9uIChjdXJyZW50VmFsLCBuZXdWYWwpIHtcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50VmFsID09PSBuZXdWYWw7XG4gICAgICAgIH0sXG5cbiAgICAgICAgb25DaGFuZ2UgOiBmdW5jdGlvbihuZXdWYWwsIHByZXZpb3VzVmFsLCBhdHRyaWJ1dGVOYW1lKXtcbiAgICAgICAgICAgIC8vIGlmIHRoaXMgaGFzIGNoYW5nZWQgd2Ugd2FudCB0byBhbHNvIGhhbmRsZVxuICAgICAgICAgICAgLy8gZXZlbnQgcHJvcGFnYXRpb25cbiAgICAgICAgICAgIGlmIChwcmV2aW91c1ZhbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RvcExpc3RlbmluZyhwcmV2aW91c1ZhbCwgJ2FsbCcsIHRoaXMuX2dldENhY2hlZEV2ZW50QnViYmxpbmdIYW5kbGVyKGF0dHJpYnV0ZU5hbWUpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG5ld1ZhbCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5UbyhuZXdWYWwsICdhbGwnLCB0aGlzLl9nZXRDYWNoZWRFdmVudEJ1YmJsaW5nSGFuZGxlcihhdHRyaWJ1dGVOYW1lKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG4vLyB0aGUgZXh0ZW5kIG1ldGhvZCB1c2VkIHRvIGV4dGVuZCBwcm90b3R5cGVzLCBtYWludGFpbiBpbmhlcml0YW5jZSBjaGFpbnMgZm9yIGluc3RhbmNlb2Zcbi8vIGFuZCBhbGxvdyBmb3IgYWRkaXRpb25zIHRvIHRoZSBtb2RlbCBkZWZpbml0aW9ucy5cbmZ1bmN0aW9uIGV4dGVuZChwcm90b1Byb3BzKSB7XG4gICAgLypqc2hpbnQgdmFsaWR0aGlzOnRydWUqL1xuICAgIHZhciBwYXJlbnQgPSB0aGlzO1xuICAgIHZhciBjaGlsZDtcblxuICAgIC8vIFRoZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBmb3IgdGhlIG5ldyBzdWJjbGFzcyBpcyBlaXRoZXIgZGVmaW5lZCBieSB5b3VcbiAgICAvLyAodGhlIFwiY29uc3RydWN0b3JcIiBwcm9wZXJ0eSBpbiB5b3VyIGBleHRlbmRgIGRlZmluaXRpb24pLCBvciBkZWZhdWx0ZWRcbiAgICAvLyBieSB1cyB0byBzaW1wbHkgY2FsbCB0aGUgcGFyZW50J3MgY29uc3RydWN0b3IuXG4gICAgaWYgKHByb3RvUHJvcHMgJiYgcHJvdG9Qcm9wcy5oYXNPd25Qcm9wZXJ0eSgnY29uc3RydWN0b3InKSkge1xuICAgICAgICBjaGlsZCA9IHByb3RvUHJvcHMuY29uc3RydWN0b3I7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY2hpbGQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gQWRkIHN0YXRpYyBwcm9wZXJ0aWVzIHRvIHRoZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBmcm9tIHBhcmVudFxuICAgIGFzc2lnbihjaGlsZCwgcGFyZW50KTtcblxuICAgIC8vIFNldCB0aGUgcHJvdG90eXBlIGNoYWluIHRvIGluaGVyaXQgZnJvbSBgcGFyZW50YCwgd2l0aG91dCBjYWxsaW5nXG4gICAgLy8gYHBhcmVudGAncyBjb25zdHJ1Y3RvciBmdW5jdGlvbi5cbiAgICB2YXIgU3Vycm9nYXRlID0gZnVuY3Rpb24gKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH07XG4gICAgU3Vycm9nYXRlLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7XG4gICAgY2hpbGQucHJvdG90eXBlID0gbmV3IFN1cnJvZ2F0ZSgpO1xuXG4gICAgLy8gc2V0IHByb3RvdHlwZSBsZXZlbCBvYmplY3RzXG4gICAgY2hpbGQucHJvdG90eXBlLl9kZXJpdmVkID0gIGFzc2lnbih7fSwgcGFyZW50LnByb3RvdHlwZS5fZGVyaXZlZCk7XG4gICAgY2hpbGQucHJvdG90eXBlLl9kZXBzID0gYXNzaWduKHt9LCBwYXJlbnQucHJvdG90eXBlLl9kZXBzKTtcbiAgICBjaGlsZC5wcm90b3R5cGUuX2RlZmluaXRpb24gPSBhc3NpZ24oe30sIHBhcmVudC5wcm90b3R5cGUuX2RlZmluaXRpb24pO1xuICAgIGNoaWxkLnByb3RvdHlwZS5fY29sbGVjdGlvbnMgPSBhc3NpZ24oe30sIHBhcmVudC5wcm90b3R5cGUuX2NvbGxlY3Rpb25zKTtcbiAgICBjaGlsZC5wcm90b3R5cGUuX2NoaWxkcmVuID0gYXNzaWduKHt9LCBwYXJlbnQucHJvdG90eXBlLl9jaGlsZHJlbik7XG4gICAgY2hpbGQucHJvdG90eXBlLl9kYXRhVHlwZXMgPSBhc3NpZ24oe30sIHBhcmVudC5wcm90b3R5cGUuX2RhdGFUeXBlcyB8fCBkYXRhVHlwZXMpO1xuXG4gICAgLy8gTWl4IGluIGFsbCBwcm90b3R5cGUgcHJvcGVydGllcyB0byB0aGUgc3ViY2xhc3MgaWYgc3VwcGxpZWQuXG4gICAgaWYgKHByb3RvUHJvcHMpIHtcbiAgICAgICAgdmFyIG9taXRGcm9tRXh0ZW5kID0gW1xuICAgICAgICAgICAgJ2RhdGFUeXBlcycsICdwcm9wcycsICdzZXNzaW9uJywgJ2Rlcml2ZWQnLCAnY29sbGVjdGlvbnMnLCAnY2hpbGRyZW4nXG4gICAgICAgIF07XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBkZWYgPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICBpZiAoZGVmLmRhdGFUeXBlcykge1xuICAgICAgICAgICAgICAgIGZvck93bihkZWYuZGF0YVR5cGVzLCBmdW5jdGlvbiAoZGVmLCBuYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkLnByb3RvdHlwZS5fZGF0YVR5cGVzW25hbWVdID0gZGVmO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRlZi5wcm9wcykge1xuICAgICAgICAgICAgICAgIGZvck93bihkZWYucHJvcHMsIGZ1bmN0aW9uIChkZWYsIG5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlUHJvcGVydHlEZWZpbml0aW9uKGNoaWxkLnByb3RvdHlwZSwgbmFtZSwgZGVmKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkZWYuc2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIGZvck93bihkZWYuc2Vzc2lvbiwgZnVuY3Rpb24gKGRlZiwgbmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBjcmVhdGVQcm9wZXJ0eURlZmluaXRpb24oY2hpbGQucHJvdG90eXBlLCBuYW1lLCBkZWYsIHRydWUpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRlZi5kZXJpdmVkKSB7XG4gICAgICAgICAgICAgICAgZm9yT3duKGRlZi5kZXJpdmVkLCBmdW5jdGlvbiAoZGVmLCBuYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZURlcml2ZWRQcm9wZXJ0eShjaGlsZC5wcm90b3R5cGUsIG5hbWUsIGRlZik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGVmLmNvbGxlY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgZm9yT3duKGRlZi5jb2xsZWN0aW9ucywgZnVuY3Rpb24gKGNvbnN0cnVjdG9yLCBuYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkLnByb3RvdHlwZS5fY29sbGVjdGlvbnNbbmFtZV0gPSBjb25zdHJ1Y3RvcjtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkZWYuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICBmb3JPd24oZGVmLmNoaWxkcmVuLCBmdW5jdGlvbiAoY29uc3RydWN0b3IsIG5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGQucHJvdG90eXBlLl9jaGlsZHJlbltuYW1lXSA9IGNvbnN0cnVjdG9yO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXNzaWduKGNoaWxkLnByb3RvdHlwZSwgb21pdChkZWYsIG9taXRGcm9tRXh0ZW5kKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTZXQgYSBjb252ZW5pZW5jZSBwcm9wZXJ0eSBpbiBjYXNlIHRoZSBwYXJlbnQncyBwcm90b3R5cGUgaXMgbmVlZGVkXG4gICAgLy8gbGF0ZXIuXG4gICAgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTtcblxuICAgIHJldHVybiBjaGlsZDtcbn1cblxuQmFzZS5leHRlbmQgPSBleHRlbmQ7XG5cbi8vIE91ciBtYWluIGV4cG9ydHNcbm1vZHVsZS5leHBvcnRzID0gQmFzZTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///ef45\n")}}]);

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.moment"],{da01:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js\n\n;(function (global, factory) {\n     true ? module.exports = factory() :\n    undefined\n}(this, (function () { 'use strict';\n\n    var hookCallback;\n\n    function hooks () {\n        return hookCallback.apply(null, arguments);\n    }\n\n    // This is done to register the method called with moment()\n    // without creating circular dependencies.\n    function setHookCallback (callback) {\n        hookCallback = callback;\n    }\n\n    function isArray(input) {\n        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n    }\n\n    function isObject(input) {\n        // IE8 will treat undefined and null as object if it wasn't for\n        // input != null\n        return input != null && Object.prototype.toString.call(input) === '[object Object]';\n    }\n\n    function isObjectEmpty(obj) {\n        if (Object.getOwnPropertyNames) {\n            return (Object.getOwnPropertyNames(obj).length === 0);\n        } else {\n            var k;\n            for (k in obj) {\n                if (obj.hasOwnProperty(k)) {\n                    return false;\n                }\n            }\n            return true;\n        }\n    }\n\n    function isUndefined(input) {\n        return input === void 0;\n    }\n\n    function isNumber(input) {\n        return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n    }\n\n    function isDate(input) {\n        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n    }\n\n    function map(arr, fn) {\n        var res = [], i;\n        for (i = 0; i < arr.length; ++i) {\n            res.push(fn(arr[i], i));\n        }\n        return res;\n    }\n\n    function hasOwnProp(a, b) {\n        return Object.prototype.hasOwnProperty.call(a, b);\n    }\n\n    function extend(a, b) {\n        for (var i in b) {\n            if (hasOwnProp(b, i)) {\n                a[i] = b[i];\n            }\n        }\n\n        if (hasOwnProp(b, 'toString')) {\n            a.toString = b.toString;\n        }\n\n        if (hasOwnProp(b, 'valueOf')) {\n            a.valueOf = b.valueOf;\n        }\n\n        return a;\n    }\n\n    function createUTC (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, true).utc();\n    }\n\n    function defaultParsingFlags() {\n        // We need to deep clone this object.\n        return {\n            empty           : false,\n            unusedTokens    : [],\n            unusedInput     : [],\n            overflow        : -2,\n            charsLeftOver   : 0,\n            nullInput       : false,\n            invalidMonth    : null,\n            invalidFormat   : false,\n            userInvalidated : false,\n            iso             : false,\n            parsedDateParts : [],\n            meridiem        : null,\n            rfc2822         : false,\n            weekdayMismatch : false\n        };\n    }\n\n    function getParsingFlags(m) {\n        if (m._pf == null) {\n            m._pf = defaultParsingFlags();\n        }\n        return m._pf;\n    }\n\n    var some;\n    if (Array.prototype.some) {\n        some = Array.prototype.some;\n    } else {\n        some = function (fun) {\n            var t = Object(this);\n            var len = t.length >>> 0;\n\n            for (var i = 0; i < len; i++) {\n                if (i in t && fun.call(this, t[i], i, t)) {\n                    return true;\n                }\n            }\n\n            return false;\n        };\n    }\n\n    function isValid(m) {\n        if (m._isValid == null) {\n            var flags = getParsingFlags(m);\n            var parsedParts = some.call(flags.parsedDateParts, function (i) {\n                return i != null;\n            });\n            var isNowValid = !isNaN(m._d.getTime()) &&\n                flags.overflow < 0 &&\n                !flags.empty &&\n                !flags.invalidMonth &&\n                !flags.invalidWeekday &&\n                !flags.weekdayMismatch &&\n                !flags.nullInput &&\n                !flags.invalidFormat &&\n                !flags.userInvalidated &&\n                (!flags.meridiem || (flags.meridiem && parsedParts));\n\n            if (m._strict) {\n                isNowValid = isNowValid &&\n                    flags.charsLeftOver === 0 &&\n                    flags.unusedTokens.length === 0 &&\n                    flags.bigHour === undefined;\n            }\n\n            if (Object.isFrozen == null || !Object.isFrozen(m)) {\n                m._isValid = isNowValid;\n            }\n            else {\n                return isNowValid;\n            }\n        }\n        return m._isValid;\n    }\n\n    function createInvalid (flags) {\n        var m = createUTC(NaN);\n        if (flags != null) {\n            extend(getParsingFlags(m), flags);\n        }\n        else {\n            getParsingFlags(m).userInvalidated = true;\n        }\n\n        return m;\n    }\n\n    // Plugins that add properties should also add the key here (null value),\n    // so we can properly clone ourselves.\n    var momentProperties = hooks.momentProperties = [];\n\n    function copyConfig(to, from) {\n        var i, prop, val;\n\n        if (!isUndefined(from._isAMomentObject)) {\n            to._isAMomentObject = from._isAMomentObject;\n        }\n        if (!isUndefined(from._i)) {\n            to._i = from._i;\n        }\n        if (!isUndefined(from._f)) {\n            to._f = from._f;\n        }\n        if (!isUndefined(from._l)) {\n            to._l = from._l;\n        }\n        if (!isUndefined(from._strict)) {\n            to._strict = from._strict;\n        }\n        if (!isUndefined(from._tzm)) {\n            to._tzm = from._tzm;\n        }\n        if (!isUndefined(from._isUTC)) {\n            to._isUTC = from._isUTC;\n        }\n        if (!isUndefined(from._offset)) {\n            to._offset = from._offset;\n        }\n        if (!isUndefined(from._pf)) {\n            to._pf = getParsingFlags(from);\n        }\n        if (!isUndefined(from._locale)) {\n            to._locale = from._locale;\n        }\n\n        if (momentProperties.length > 0) {\n            for (i = 0; i < momentProperties.length; i++) {\n                prop = momentProperties[i];\n                val = from[prop];\n                if (!isUndefined(val)) {\n                    to[prop] = val;\n                }\n            }\n        }\n\n        return to;\n    }\n\n    var updateInProgress = false;\n\n    // Moment prototype object\n    function Moment(config) {\n        copyConfig(this, config);\n        this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n        if (!this.isValid()) {\n            this._d = new Date(NaN);\n        }\n        // Prevent infinite loop in case updateOffset creates new moment\n        // objects.\n        if (updateInProgress === false) {\n            updateInProgress = true;\n            hooks.updateOffset(this);\n            updateInProgress = false;\n        }\n    }\n\n    function isMoment (obj) {\n        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n    }\n\n    function absFloor (number) {\n        if (number < 0) {\n            // -0 -> 0\n            return Math.ceil(number) || 0;\n        } else {\n            return Math.floor(number);\n        }\n    }\n\n    function toInt(argumentForCoercion) {\n        var coercedNumber = +argumentForCoercion,\n            value = 0;\n\n        if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n            value = absFloor(coercedNumber);\n        }\n\n        return value;\n    }\n\n    // compare two arrays, return the number of differences\n    function compareArrays(array1, array2, dontConvert) {\n        var len = Math.min(array1.length, array2.length),\n            lengthDiff = Math.abs(array1.length - array2.length),\n            diffs = 0,\n            i;\n        for (i = 0; i < len; i++) {\n            if ((dontConvert && array1[i] !== array2[i]) ||\n                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n                diffs++;\n            }\n        }\n        return diffs + lengthDiff;\n    }\n\n    function warn(msg) {\n        if (hooks.suppressDeprecationWarnings === false &&\n                (typeof console !==  'undefined') && console.warn) {\n            console.warn('Deprecation warning: ' + msg);\n        }\n    }\n\n    function deprecate(msg, fn) {\n        var firstTime = true;\n\n        return extend(function () {\n            if (hooks.deprecationHandler != null) {\n                hooks.deprecationHandler(null, msg);\n            }\n            if (firstTime) {\n                var args = [];\n                var arg;\n                for (var i = 0; i < arguments.length; i++) {\n                    arg = '';\n                    if (typeof arguments[i] === 'object') {\n                        arg += '\\n[' + i + '] ';\n                        for (var key in arguments[0]) {\n                            arg += key + ': ' + arguments[0][key] + ', ';\n                        }\n                        arg = arg.slice(0, -2); // Remove trailing comma and space\n                    } else {\n                        arg = arguments[i];\n                    }\n                    args.push(arg);\n                }\n                warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n                firstTime = false;\n            }\n            return fn.apply(this, arguments);\n        }, fn);\n    }\n\n    var deprecations = {};\n\n    function deprecateSimple(name, msg) {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(name, msg);\n        }\n        if (!deprecations[name]) {\n            warn(msg);\n            deprecations[name] = true;\n        }\n    }\n\n    hooks.suppressDeprecationWarnings = false;\n    hooks.deprecationHandler = null;\n\n    function isFunction(input) {\n        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n    }\n\n    function set (config) {\n        var prop, i;\n        for (i in config) {\n            prop = config[i];\n            if (isFunction(prop)) {\n                this[i] = prop;\n            } else {\n                this['_' + i] = prop;\n            }\n        }\n        this._config = config;\n        // Lenient ordinal parsing accepts just a number in addition to\n        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n        // TODO: Remove \"ordinalParse\" fallback in next major release.\n        this._dayOfMonthOrdinalParseLenient = new RegExp(\n            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n                '|' + (/\\d{1,2}/).source);\n    }\n\n    function mergeConfigs(parentConfig, childConfig) {\n        var res = extend({}, parentConfig), prop;\n        for (prop in childConfig) {\n            if (hasOwnProp(childConfig, prop)) {\n                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                    res[prop] = {};\n                    extend(res[prop], parentConfig[prop]);\n                    extend(res[prop], childConfig[prop]);\n                } else if (childConfig[prop] != null) {\n                    res[prop] = childConfig[prop];\n                } else {\n                    delete res[prop];\n                }\n            }\n        }\n        for (prop in parentConfig) {\n            if (hasOwnProp(parentConfig, prop) &&\n                    !hasOwnProp(childConfig, prop) &&\n                    isObject(parentConfig[prop])) {\n                // make sure changes to properties don't modify parent config\n                res[prop] = extend({}, res[prop]);\n            }\n        }\n        return res;\n    }\n\n    function Locale(config) {\n        if (config != null) {\n            this.set(config);\n        }\n    }\n\n    var keys;\n\n    if (Object.keys) {\n        keys = Object.keys;\n    } else {\n        keys = function (obj) {\n            var i, res = [];\n            for (i in obj) {\n                if (hasOwnProp(obj, i)) {\n                    res.push(i);\n                }\n            }\n            return res;\n        };\n    }\n\n    var defaultCalendar = {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    };\n\n    function calendar (key, mom, now) {\n        var output = this._calendar[key] || this._calendar['sameElse'];\n        return isFunction(output) ? output.call(mom, now) : output;\n    }\n\n    var defaultLongDateFormat = {\n        LTS  : 'h:mm:ss A',\n        LT   : 'h:mm A',\n        L    : 'MM/DD/YYYY',\n        LL   : 'MMMM D, YYYY',\n        LLL  : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    };\n\n    function longDateFormat (key) {\n        var format = this._longDateFormat[key],\n            formatUpper = this._longDateFormat[key.toUpperCase()];\n\n        if (format || !formatUpper) {\n            return format;\n        }\n\n        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n            return val.slice(1);\n        });\n\n        return this._longDateFormat[key];\n    }\n\n    var defaultInvalidDate = 'Invalid date';\n\n    function invalidDate () {\n        return this._invalidDate;\n    }\n\n    var defaultOrdinal = '%d';\n    var defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\n    function ordinal (number) {\n        return this._ordinal.replace('%d', number);\n    }\n\n    var defaultRelativeTime = {\n        future : 'in %s',\n        past   : '%s ago',\n        s  : 'a few seconds',\n        ss : '%d seconds',\n        m  : 'a minute',\n        mm : '%d minutes',\n        h  : 'an hour',\n        hh : '%d hours',\n        d  : 'a day',\n        dd : '%d days',\n        M  : 'a month',\n        MM : '%d months',\n        y  : 'a year',\n        yy : '%d years'\n    };\n\n    function relativeTime (number, withoutSuffix, string, isFuture) {\n        var output = this._relativeTime[string];\n        return (isFunction(output)) ?\n            output(number, withoutSuffix, string, isFuture) :\n            output.replace(/%d/i, number);\n    }\n\n    function pastFuture (diff, output) {\n        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n        return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n    }\n\n    var aliases = {};\n\n    function addUnitAlias (unit, shorthand) {\n        var lowerCase = unit.toLowerCase();\n        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n    }\n\n    function normalizeUnits(units) {\n        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n    }\n\n    function normalizeObjectUnits(inputObject) {\n        var normalizedInput = {},\n            normalizedProp,\n            prop;\n\n        for (prop in inputObject) {\n            if (hasOwnProp(inputObject, prop)) {\n                normalizedProp = normalizeUnits(prop);\n                if (normalizedProp) {\n                    normalizedInput[normalizedProp] = inputObject[prop];\n                }\n            }\n        }\n\n        return normalizedInput;\n    }\n\n    var priorities = {};\n\n    function addUnitPriority(unit, priority) {\n        priorities[unit] = priority;\n    }\n\n    function getPrioritizedUnits(unitsObj) {\n        var units = [];\n        for (var u in unitsObj) {\n            units.push({unit: u, priority: priorities[u]});\n        }\n        units.sort(function (a, b) {\n            return a.priority - b.priority;\n        });\n        return units;\n    }\n\n    function zeroFill(number, targetLength, forceSign) {\n        var absNumber = '' + Math.abs(number),\n            zerosToFill = targetLength - absNumber.length,\n            sign = number >= 0;\n        return (sign ? (forceSign ? '+' : '') : '-') +\n            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n    }\n\n    var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\n    var localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\n    var formatFunctions = {};\n\n    var formatTokenFunctions = {};\n\n    // token:    'M'\n    // padded:   ['MM', 2]\n    // ordinal:  'Mo'\n    // callback: function () { this.month() + 1 }\n    function addFormatToken (token, padded, ordinal, callback) {\n        var func = callback;\n        if (typeof callback === 'string') {\n            func = function () {\n                return this[callback]();\n            };\n        }\n        if (token) {\n            formatTokenFunctions[token] = func;\n        }\n        if (padded) {\n            formatTokenFunctions[padded[0]] = function () {\n                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n            };\n        }\n        if (ordinal) {\n            formatTokenFunctions[ordinal] = function () {\n                return this.localeData().ordinal(func.apply(this, arguments), token);\n            };\n        }\n    }\n\n    function removeFormattingTokens(input) {\n        if (input.match(/\\[[\\s\\S]/)) {\n            return input.replace(/^\\[|\\]$/g, '');\n        }\n        return input.replace(/\\\\/g, '');\n    }\n\n    function makeFormatFunction(format) {\n        var array = format.match(formattingTokens), i, length;\n\n        for (i = 0, length = array.length; i < length; i++) {\n            if (formatTokenFunctions[array[i]]) {\n                array[i] = formatTokenFunctions[array[i]];\n            } else {\n                array[i] = removeFormattingTokens(array[i]);\n            }\n        }\n\n        return function (mom) {\n            var output = '', i;\n            for (i = 0; i < length; i++) {\n                output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n            }\n            return output;\n        };\n    }\n\n    // format date using native date object\n    function formatMoment(m, format) {\n        if (!m.isValid()) {\n            return m.localeData().invalidDate();\n        }\n\n        format = expandFormat(format, m.localeData());\n        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n        return formatFunctions[format](m);\n    }\n\n    function expandFormat(format, locale) {\n        var i = 5;\n\n        function replaceLongDateFormatTokens(input) {\n            return locale.longDateFormat(input) || input;\n        }\n\n        localFormattingTokens.lastIndex = 0;\n        while (i >= 0 && localFormattingTokens.test(format)) {\n            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n            localFormattingTokens.lastIndex = 0;\n            i -= 1;\n        }\n\n        return format;\n    }\n\n    var match1         = /\\d/;            //       0 - 9\n    var match2         = /\\d\\d/;          //      00 - 99\n    var match3         = /\\d{3}/;         //     000 - 999\n    var match4         = /\\d{4}/;         //    0000 - 9999\n    var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\n    var match1to2      = /\\d\\d?/;         //       0 - 99\n    var match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\n    var match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\n    var match1to3      = /\\d{1,3}/;       //       0 - 999\n    var match1to4      = /\\d{1,4}/;       //       0 - 9999\n    var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\n    var matchUnsigned  = /\\d+/;           //       0 - inf\n    var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\n    var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n    var matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\n    var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n    // any word (or two) characters or numbers including two/three word month in arabic.\n    // includes scottish gaelic two word and hyphenated months\n    var matchWord = /[0-9]{0,256}['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFF07\\uFF10-\\uFFEF]{1,256}|[\\u0600-\\u06FF\\/]{1,256}(\\s*?[\\u0600-\\u06FF]{1,256}){1,2}/i;\n\n    var regexes = {};\n\n    function addRegexToken (token, regex, strictRegex) {\n        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n            return (isStrict && strictRegex) ? strictRegex : regex;\n        };\n    }\n\n    function getParseRegexForToken (token, config) {\n        if (!hasOwnProp(regexes, token)) {\n            return new RegExp(unescapeFormat(token));\n        }\n\n        return regexes[token](config._strict, config._locale);\n    }\n\n    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\n    function unescapeFormat(s) {\n        return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n            return p1 || p2 || p3 || p4;\n        }));\n    }\n\n    function regexEscape(s) {\n        return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n    }\n\n    var tokens = {};\n\n    function addParseToken (token, callback) {\n        var i, func = callback;\n        if (typeof token === 'string') {\n            token = [token];\n        }\n        if (isNumber(callback)) {\n            func = function (input, array) {\n                array[callback] = toInt(input);\n            };\n        }\n        for (i = 0; i < token.length; i++) {\n            tokens[token[i]] = func;\n        }\n    }\n\n    function addWeekParseToken (token, callback) {\n        addParseToken(token, function (input, array, config, token) {\n            config._w = config._w || {};\n            callback(input, config._w, config, token);\n        });\n    }\n\n    function addTimeToArrayFromToken(token, input, config) {\n        if (input != null && hasOwnProp(tokens, token)) {\n            tokens[token](input, config._a, config, token);\n        }\n    }\n\n    var YEAR = 0;\n    var MONTH = 1;\n    var DATE = 2;\n    var HOUR = 3;\n    var MINUTE = 4;\n    var SECOND = 5;\n    var MILLISECOND = 6;\n    var WEEK = 7;\n    var WEEKDAY = 8;\n\n    // FORMATTING\n\n    addFormatToken('Y', 0, 0, function () {\n        var y = this.year();\n        return y <= 9999 ? '' + y : '+' + y;\n    });\n\n    addFormatToken(0, ['YY', 2], 0, function () {\n        return this.year() % 100;\n    });\n\n    addFormatToken(0, ['YYYY',   4],       0, 'year');\n    addFormatToken(0, ['YYYYY',  5],       0, 'year');\n    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n    // ALIASES\n\n    addUnitAlias('year', 'y');\n\n    // PRIORITIES\n\n    addUnitPriority('year', 1);\n\n    // PARSING\n\n    addRegexToken('Y',      matchSigned);\n    addRegexToken('YY',     match1to2, match2);\n    addRegexToken('YYYY',   match1to4, match4);\n    addRegexToken('YYYYY',  match1to6, match6);\n    addRegexToken('YYYYYY', match1to6, match6);\n\n    addParseToken(['YYYYY', 'YYYYYY'], YEAR);\n    addParseToken('YYYY', function (input, array) {\n        array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n    });\n    addParseToken('YY', function (input, array) {\n        array[YEAR] = hooks.parseTwoDigitYear(input);\n    });\n    addParseToken('Y', function (input, array) {\n        array[YEAR] = parseInt(input, 10);\n    });\n\n    // HELPERS\n\n    function daysInYear(year) {\n        return isLeapYear(year) ? 366 : 365;\n    }\n\n    function isLeapYear(year) {\n        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n    }\n\n    // HOOKS\n\n    hooks.parseTwoDigitYear = function (input) {\n        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n    };\n\n    // MOMENTS\n\n    var getSetYear = makeGetSet('FullYear', true);\n\n    function getIsLeapYear () {\n        return isLeapYear(this.year());\n    }\n\n    function makeGetSet (unit, keepTime) {\n        return function (value) {\n            if (value != null) {\n                set$1(this, unit, value);\n                hooks.updateOffset(this, keepTime);\n                return this;\n            } else {\n                return get(this, unit);\n            }\n        };\n    }\n\n    function get (mom, unit) {\n        return mom.isValid() ?\n            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n    }\n\n    function set$1 (mom, unit, value) {\n        if (mom.isValid() && !isNaN(value)) {\n            if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {\n                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));\n            }\n            else {\n                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function stringGet (units) {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units]();\n        }\n        return this;\n    }\n\n\n    function stringSet (units, value) {\n        if (typeof units === 'object') {\n            units = normalizeObjectUnits(units);\n            var prioritized = getPrioritizedUnits(units);\n            for (var i = 0; i < prioritized.length; i++) {\n                this[prioritized[i].unit](units[prioritized[i].unit]);\n            }\n        } else {\n            units = normalizeUnits(units);\n            if (isFunction(this[units])) {\n                return this[units](value);\n            }\n        }\n        return this;\n    }\n\n    function mod(n, x) {\n        return ((n % x) + x) % x;\n    }\n\n    var indexOf;\n\n    if (Array.prototype.indexOf) {\n        indexOf = Array.prototype.indexOf;\n    } else {\n        indexOf = function (o) {\n            // I know\n            var i;\n            for (i = 0; i < this.length; ++i) {\n                if (this[i] === o) {\n                    return i;\n                }\n            }\n            return -1;\n        };\n    }\n\n    function daysInMonth(year, month) {\n        if (isNaN(year) || isNaN(month)) {\n            return NaN;\n        }\n        var modMonth = mod(month, 12);\n        year += (month - modMonth) / 12;\n        return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);\n    }\n\n    // FORMATTING\n\n    addFormatToken('M', ['MM', 2], 'Mo', function () {\n        return this.month() + 1;\n    });\n\n    addFormatToken('MMM', 0, 0, function (format) {\n        return this.localeData().monthsShort(this, format);\n    });\n\n    addFormatToken('MMMM', 0, 0, function (format) {\n        return this.localeData().months(this, format);\n    });\n\n    // ALIASES\n\n    addUnitAlias('month', 'M');\n\n    // PRIORITY\n\n    addUnitPriority('month', 8);\n\n    // PARSING\n\n    addRegexToken('M',    match1to2);\n    addRegexToken('MM',   match1to2, match2);\n    addRegexToken('MMM',  function (isStrict, locale) {\n        return locale.monthsShortRegex(isStrict);\n    });\n    addRegexToken('MMMM', function (isStrict, locale) {\n        return locale.monthsRegex(isStrict);\n    });\n\n    addParseToken(['M', 'MM'], function (input, array) {\n        array[MONTH] = toInt(input) - 1;\n    });\n\n    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n        var month = config._locale.monthsParse(input, token, config._strict);\n        // if we didn't find a month name, mark the date as invalid.\n        if (month != null) {\n            array[MONTH] = month;\n        } else {\n            getParsingFlags(config).invalidMonth = input;\n        }\n    });\n\n    // LOCALES\n\n    var MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\n    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\n    function localeMonths (m, format) {\n        if (!m) {\n            return isArray(this._months) ? this._months :\n                this._months['standalone'];\n        }\n        return isArray(this._months) ? this._months[m.month()] :\n            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n    }\n\n    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\n    function localeMonthsShort (m, format) {\n        if (!m) {\n            return isArray(this._monthsShort) ? this._monthsShort :\n                this._monthsShort['standalone'];\n        }\n        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n    }\n\n    function handleStrictParse(monthName, format, strict) {\n        var i, ii, mom, llc = monthName.toLocaleLowerCase();\n        if (!this._monthsParse) {\n            // this is not used\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n            for (i = 0; i < 12; ++i) {\n                mom = createUTC([2000, i]);\n                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n            }\n        }\n\n        if (strict) {\n            if (format === 'MMM') {\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._longMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        } else {\n            if (format === 'MMM') {\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._longMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._longMonthsParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        }\n    }\n\n    function localeMonthsParse (monthName, format, strict) {\n        var i, mom, regex;\n\n        if (this._monthsParseExact) {\n            return handleStrictParse.call(this, monthName, format, strict);\n        }\n\n        if (!this._monthsParse) {\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n        }\n\n        // TODO: add sorting\n        // Sorting makes sure if one month (or abbr) is a prefix of another\n        // see sorting in computeMonthsParse\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, i]);\n            if (strict && !this._longMonthsParse[i]) {\n                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n            }\n            if (!strict && !this._monthsParse[i]) {\n                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (!strict && this._monthsParse[i].test(monthName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function setMonth (mom, value) {\n        var dayOfMonth;\n\n        if (!mom.isValid()) {\n            // No op\n            return mom;\n        }\n\n        if (typeof value === 'string') {\n            if (/^\\d+$/.test(value)) {\n                value = toInt(value);\n            } else {\n                value = mom.localeData().monthsParse(value);\n                // TODO: Another silent failure?\n                if (!isNumber(value)) {\n                    return mom;\n                }\n            }\n        }\n\n        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n        return mom;\n    }\n\n    function getSetMonth (value) {\n        if (value != null) {\n            setMonth(this, value);\n            hooks.updateOffset(this, true);\n            return this;\n        } else {\n            return get(this, 'Month');\n        }\n    }\n\n    function getDaysInMonth () {\n        return daysInMonth(this.year(), this.month());\n    }\n\n    var defaultMonthsShortRegex = matchWord;\n    function monthsShortRegex (isStrict) {\n        if (this._monthsParseExact) {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                computeMonthsParse.call(this);\n            }\n            if (isStrict) {\n                return this._monthsShortStrictRegex;\n            } else {\n                return this._monthsShortRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_monthsShortRegex')) {\n                this._monthsShortRegex = defaultMonthsShortRegex;\n            }\n            return this._monthsShortStrictRegex && isStrict ?\n                this._monthsShortStrictRegex : this._monthsShortRegex;\n        }\n    }\n\n    var defaultMonthsRegex = matchWord;\n    function monthsRegex (isStrict) {\n        if (this._monthsParseExact) {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                computeMonthsParse.call(this);\n            }\n            if (isStrict) {\n                return this._monthsStrictRegex;\n            } else {\n                return this._monthsRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                this._monthsRegex = defaultMonthsRegex;\n            }\n            return this._monthsStrictRegex && isStrict ?\n                this._monthsStrictRegex : this._monthsRegex;\n        }\n    }\n\n    function computeMonthsParse () {\n        function cmpLenRev(a, b) {\n            return b.length - a.length;\n        }\n\n        var shortPieces = [], longPieces = [], mixedPieces = [],\n            i, mom;\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, i]);\n            shortPieces.push(this.monthsShort(mom, ''));\n            longPieces.push(this.months(mom, ''));\n            mixedPieces.push(this.months(mom, ''));\n            mixedPieces.push(this.monthsShort(mom, ''));\n        }\n        // Sorting makes sure if one month (or abbr) is a prefix of another it\n        // will match the longer piece.\n        shortPieces.sort(cmpLenRev);\n        longPieces.sort(cmpLenRev);\n        mixedPieces.sort(cmpLenRev);\n        for (i = 0; i < 12; i++) {\n            shortPieces[i] = regexEscape(shortPieces[i]);\n            longPieces[i] = regexEscape(longPieces[i]);\n        }\n        for (i = 0; i < 24; i++) {\n            mixedPieces[i] = regexEscape(mixedPieces[i]);\n        }\n\n        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n        this._monthsShortRegex = this._monthsRegex;\n        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    }\n\n    function createDate (y, m, d, h, M, s, ms) {\n        // can't just apply() to create a date:\n        // https://stackoverflow.com/q/181348\n        var date;\n        // the date constructor remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            date = new Date(y + 400, m, d, h, M, s, ms);\n            if (isFinite(date.getFullYear())) {\n                date.setFullYear(y);\n            }\n        } else {\n            date = new Date(y, m, d, h, M, s, ms);\n        }\n\n        return date;\n    }\n\n    function createUTCDate (y) {\n        var date;\n        // the Date.UTC function remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            var args = Array.prototype.slice.call(arguments);\n            // preserve leap years using a full 400 year cycle, then reset\n            args[0] = y + 400;\n            date = new Date(Date.UTC.apply(null, args));\n            if (isFinite(date.getUTCFullYear())) {\n                date.setUTCFullYear(y);\n            }\n        } else {\n            date = new Date(Date.UTC.apply(null, arguments));\n        }\n\n        return date;\n    }\n\n    // start-of-first-week - start-of-year\n    function firstWeekOffset(year, dow, doy) {\n        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n            fwd = 7 + dow - doy,\n            // first-week day local weekday -- which local weekday is fwd\n            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n        return -fwdlw + fwd - 1;\n    }\n\n    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\n    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n        var localWeekday = (7 + weekday - dow) % 7,\n            weekOffset = firstWeekOffset(year, dow, doy),\n            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n            resYear, resDayOfYear;\n\n        if (dayOfYear <= 0) {\n            resYear = year - 1;\n            resDayOfYear = daysInYear(resYear) + dayOfYear;\n        } else if (dayOfYear > daysInYear(year)) {\n            resYear = year + 1;\n            resDayOfYear = dayOfYear - daysInYear(year);\n        } else {\n            resYear = year;\n            resDayOfYear = dayOfYear;\n        }\n\n        return {\n            year: resYear,\n            dayOfYear: resDayOfYear\n        };\n    }\n\n    function weekOfYear(mom, dow, doy) {\n        var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n            resWeek, resYear;\n\n        if (week < 1) {\n            resYear = mom.year() - 1;\n            resWeek = week + weeksInYear(resYear, dow, doy);\n        } else if (week > weeksInYear(mom.year(), dow, doy)) {\n            resWeek = week - weeksInYear(mom.year(), dow, doy);\n            resYear = mom.year() + 1;\n        } else {\n            resYear = mom.year();\n            resWeek = week;\n        }\n\n        return {\n            week: resWeek,\n            year: resYear\n        };\n    }\n\n    function weeksInYear(year, dow, doy) {\n        var weekOffset = firstWeekOffset(year, dow, doy),\n            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n    }\n\n    // FORMATTING\n\n    addFormatToken('w', ['ww', 2], 'wo', 'week');\n    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n    // ALIASES\n\n    addUnitAlias('week', 'w');\n    addUnitAlias('isoWeek', 'W');\n\n    // PRIORITIES\n\n    addUnitPriority('week', 5);\n    addUnitPriority('isoWeek', 5);\n\n    // PARSING\n\n    addRegexToken('w',  match1to2);\n    addRegexToken('ww', match1to2, match2);\n    addRegexToken('W',  match1to2);\n    addRegexToken('WW', match1to2, match2);\n\n    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n        week[token.substr(0, 1)] = toInt(input);\n    });\n\n    // HELPERS\n\n    // LOCALES\n\n    function localeWeek (mom) {\n        return weekOfYear(mom, this._week.dow, this._week.doy).week;\n    }\n\n    var defaultLocaleWeek = {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 6th is the first week of the year.\n    };\n\n    function localeFirstDayOfWeek () {\n        return this._week.dow;\n    }\n\n    function localeFirstDayOfYear () {\n        return this._week.doy;\n    }\n\n    // MOMENTS\n\n    function getSetWeek (input) {\n        var week = this.localeData().week(this);\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    function getSetISOWeek (input) {\n        var week = weekOfYear(this, 1, 4).week;\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    // FORMATTING\n\n    addFormatToken('d', 0, 'do', 'day');\n\n    addFormatToken('dd', 0, 0, function (format) {\n        return this.localeData().weekdaysMin(this, format);\n    });\n\n    addFormatToken('ddd', 0, 0, function (format) {\n        return this.localeData().weekdaysShort(this, format);\n    });\n\n    addFormatToken('dddd', 0, 0, function (format) {\n        return this.localeData().weekdays(this, format);\n    });\n\n    addFormatToken('e', 0, 0, 'weekday');\n    addFormatToken('E', 0, 0, 'isoWeekday');\n\n    // ALIASES\n\n    addUnitAlias('day', 'd');\n    addUnitAlias('weekday', 'e');\n    addUnitAlias('isoWeekday', 'E');\n\n    // PRIORITY\n    addUnitPriority('day', 11);\n    addUnitPriority('weekday', 11);\n    addUnitPriority('isoWeekday', 11);\n\n    // PARSING\n\n    addRegexToken('d',    match1to2);\n    addRegexToken('e',    match1to2);\n    addRegexToken('E',    match1to2);\n    addRegexToken('dd',   function (isStrict, locale) {\n        return locale.weekdaysMinRegex(isStrict);\n    });\n    addRegexToken('ddd',   function (isStrict, locale) {\n        return locale.weekdaysShortRegex(isStrict);\n    });\n    addRegexToken('dddd',   function (isStrict, locale) {\n        return locale.weekdaysRegex(isStrict);\n    });\n\n    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n        var weekday = config._locale.weekdaysParse(input, token, config._strict);\n        // if we didn't get a weekday name, mark the date as invalid\n        if (weekday != null) {\n            week.d = weekday;\n        } else {\n            getParsingFlags(config).invalidWeekday = input;\n        }\n    });\n\n    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n        week[token] = toInt(input);\n    });\n\n    // HELPERS\n\n    function parseWeekday(input, locale) {\n        if (typeof input !== 'string') {\n            return input;\n        }\n\n        if (!isNaN(input)) {\n            return parseInt(input, 10);\n        }\n\n        input = locale.weekdaysParse(input);\n        if (typeof input === 'number') {\n            return input;\n        }\n\n        return null;\n    }\n\n    function parseIsoWeekday(input, locale) {\n        if (typeof input === 'string') {\n            return locale.weekdaysParse(input) % 7 || 7;\n        }\n        return isNaN(input) ? null : input;\n    }\n\n    // LOCALES\n    function shiftWeekdays (ws, n) {\n        return ws.slice(n, 7).concat(ws.slice(0, n));\n    }\n\n    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\n    function localeWeekdays (m, format) {\n        var weekdays = isArray(this._weekdays) ? this._weekdays :\n            this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone'];\n        return (m === true) ? shiftWeekdays(weekdays, this._week.dow)\n            : (m) ? weekdays[m.day()] : weekdays;\n    }\n\n    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\n    function localeWeekdaysShort (m) {\n        return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow)\n            : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n    }\n\n    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\n    function localeWeekdaysMin (m) {\n        return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow)\n            : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n    }\n\n    function handleStrictParse$1(weekdayName, format, strict) {\n        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n            this._shortWeekdaysParse = [];\n            this._minWeekdaysParse = [];\n\n            for (i = 0; i < 7; ++i) {\n                mom = createUTC([2000, 1]).day(i);\n                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n            }\n        }\n\n        if (strict) {\n            if (format === 'dddd') {\n                ii = indexOf.call(this._weekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else if (format === 'ddd') {\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        } else {\n            if (format === 'dddd') {\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else if (format === 'ddd') {\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        }\n    }\n\n    function localeWeekdaysParse (weekdayName, format, strict) {\n        var i, mom, regex;\n\n        if (this._weekdaysParseExact) {\n            return handleStrictParse$1.call(this, weekdayName, format, strict);\n        }\n\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n            this._minWeekdaysParse = [];\n            this._shortWeekdaysParse = [];\n            this._fullWeekdaysParse = [];\n        }\n\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n\n            mom = createUTC([2000, 1]).day(i);\n            if (strict && !this._fullWeekdaysParse[i]) {\n                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\\\.?') + '$', 'i');\n                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\\\.?') + '$', 'i');\n                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\\\.?') + '$', 'i');\n            }\n            if (!this._weekdaysParse[i]) {\n                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function getSetDayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n        if (input != null) {\n            input = parseWeekday(input, this.localeData());\n            return this.add(input - day, 'd');\n        } else {\n            return day;\n        }\n    }\n\n    function getSetLocaleDayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n        return input == null ? weekday : this.add(input - weekday, 'd');\n    }\n\n    function getSetISODayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n\n        // behaves the same as moment#day except\n        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n        // as a setter, sunday should belong to the previous week.\n\n        if (input != null) {\n            var weekday = parseIsoWeekday(input, this.localeData());\n            return this.day(this.day() % 7 ? weekday : weekday - 7);\n        } else {\n            return this.day() || 7;\n        }\n    }\n\n    var defaultWeekdaysRegex = matchWord;\n    function weekdaysRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysStrictRegex;\n            } else {\n                return this._weekdaysRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                this._weekdaysRegex = defaultWeekdaysRegex;\n            }\n            return this._weekdaysStrictRegex && isStrict ?\n                this._weekdaysStrictRegex : this._weekdaysRegex;\n        }\n    }\n\n    var defaultWeekdaysShortRegex = matchWord;\n    function weekdaysShortRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysShortStrictRegex;\n            } else {\n                return this._weekdaysShortRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n                this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n            }\n            return this._weekdaysShortStrictRegex && isStrict ?\n                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n        }\n    }\n\n    var defaultWeekdaysMinRegex = matchWord;\n    function weekdaysMinRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysMinStrictRegex;\n            } else {\n                return this._weekdaysMinRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n                this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n            }\n            return this._weekdaysMinStrictRegex && isStrict ?\n                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n        }\n    }\n\n\n    function computeWeekdaysParse () {\n        function cmpLenRev(a, b) {\n            return b.length - a.length;\n        }\n\n        var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n            i, mom, minp, shortp, longp;\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, 1]).day(i);\n            minp = this.weekdaysMin(mom, '');\n            shortp = this.weekdaysShort(mom, '');\n            longp = this.weekdays(mom, '');\n            minPieces.push(minp);\n            shortPieces.push(shortp);\n            longPieces.push(longp);\n            mixedPieces.push(minp);\n            mixedPieces.push(shortp);\n            mixedPieces.push(longp);\n        }\n        // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n        // will match the longer piece.\n        minPieces.sort(cmpLenRev);\n        shortPieces.sort(cmpLenRev);\n        longPieces.sort(cmpLenRev);\n        mixedPieces.sort(cmpLenRev);\n        for (i = 0; i < 7; i++) {\n            shortPieces[i] = regexEscape(shortPieces[i]);\n            longPieces[i] = regexEscape(longPieces[i]);\n            mixedPieces[i] = regexEscape(mixedPieces[i]);\n        }\n\n        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n        this._weekdaysShortRegex = this._weekdaysRegex;\n        this._weekdaysMinRegex = this._weekdaysRegex;\n\n        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n    }\n\n    // FORMATTING\n\n    function hFormat() {\n        return this.hours() % 12 || 12;\n    }\n\n    function kFormat() {\n        return this.hours() || 24;\n    }\n\n    addFormatToken('H', ['HH', 2], 0, 'hour');\n    addFormatToken('h', ['hh', 2], 0, hFormat);\n    addFormatToken('k', ['kk', 2], 0, kFormat);\n\n    addFormatToken('hmm', 0, 0, function () {\n        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n    });\n\n    addFormatToken('hmmss', 0, 0, function () {\n        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n            zeroFill(this.seconds(), 2);\n    });\n\n    addFormatToken('Hmm', 0, 0, function () {\n        return '' + this.hours() + zeroFill(this.minutes(), 2);\n    });\n\n    addFormatToken('Hmmss', 0, 0, function () {\n        return '' + this.hours() + zeroFill(this.minutes(), 2) +\n            zeroFill(this.seconds(), 2);\n    });\n\n    function meridiem (token, lowercase) {\n        addFormatToken(token, 0, 0, function () {\n            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n        });\n    }\n\n    meridiem('a', true);\n    meridiem('A', false);\n\n    // ALIASES\n\n    addUnitAlias('hour', 'h');\n\n    // PRIORITY\n    addUnitPriority('hour', 13);\n\n    // PARSING\n\n    function matchMeridiem (isStrict, locale) {\n        return locale._meridiemParse;\n    }\n\n    addRegexToken('a',  matchMeridiem);\n    addRegexToken('A',  matchMeridiem);\n    addRegexToken('H',  match1to2);\n    addRegexToken('h',  match1to2);\n    addRegexToken('k',  match1to2);\n    addRegexToken('HH', match1to2, match2);\n    addRegexToken('hh', match1to2, match2);\n    addRegexToken('kk', match1to2, match2);\n\n    addRegexToken('hmm', match3to4);\n    addRegexToken('hmmss', match5to6);\n    addRegexToken('Hmm', match3to4);\n    addRegexToken('Hmmss', match5to6);\n\n    addParseToken(['H', 'HH'], HOUR);\n    addParseToken(['k', 'kk'], function (input, array, config) {\n        var kInput = toInt(input);\n        array[HOUR] = kInput === 24 ? 0 : kInput;\n    });\n    addParseToken(['a', 'A'], function (input, array, config) {\n        config._isPm = config._locale.isPM(input);\n        config._meridiem = input;\n    });\n    addParseToken(['h', 'hh'], function (input, array, config) {\n        array[HOUR] = toInt(input);\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('hmm', function (input, array, config) {\n        var pos = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos));\n        array[MINUTE] = toInt(input.substr(pos));\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('hmmss', function (input, array, config) {\n        var pos1 = input.length - 4;\n        var pos2 = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos1));\n        array[MINUTE] = toInt(input.substr(pos1, 2));\n        array[SECOND] = toInt(input.substr(pos2));\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('Hmm', function (input, array, config) {\n        var pos = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos));\n        array[MINUTE] = toInt(input.substr(pos));\n    });\n    addParseToken('Hmmss', function (input, array, config) {\n        var pos1 = input.length - 4;\n        var pos2 = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos1));\n        array[MINUTE] = toInt(input.substr(pos1, 2));\n        array[SECOND] = toInt(input.substr(pos2));\n    });\n\n    // LOCALES\n\n    function localeIsPM (input) {\n        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n        // Using charAt should be more compatible.\n        return ((input + '').toLowerCase().charAt(0) === 'p');\n    }\n\n    var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\n    function localeMeridiem (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'pm' : 'PM';\n        } else {\n            return isLower ? 'am' : 'AM';\n        }\n    }\n\n\n    // MOMENTS\n\n    // Setting the hour should keep the time, because the user explicitly\n    // specified which hour they want. So trying to maintain the same hour (in\n    // a new timezone) makes sense. Adding/subtracting hours does not follow\n    // this rule.\n    var getSetHour = makeGetSet('Hours', true);\n\n    var baseConfig = {\n        calendar: defaultCalendar,\n        longDateFormat: defaultLongDateFormat,\n        invalidDate: defaultInvalidDate,\n        ordinal: defaultOrdinal,\n        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n        relativeTime: defaultRelativeTime,\n\n        months: defaultLocaleMonths,\n        monthsShort: defaultLocaleMonthsShort,\n\n        week: defaultLocaleWeek,\n\n        weekdays: defaultLocaleWeekdays,\n        weekdaysMin: defaultLocaleWeekdaysMin,\n        weekdaysShort: defaultLocaleWeekdaysShort,\n\n        meridiemParse: defaultLocaleMeridiemParse\n    };\n\n    // internal storage for locale config files\n    var locales = {};\n    var localeFamilies = {};\n    var globalLocale;\n\n    function normalizeLocale(key) {\n        return key ? key.toLowerCase().replace('_', '-') : key;\n    }\n\n    // pick the locale from the array\n    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\n    function chooseLocale(names) {\n        var i = 0, j, next, locale, split;\n\n        while (i < names.length) {\n            split = normalizeLocale(names[i]).split('-');\n            j = split.length;\n            next = normalizeLocale(names[i + 1]);\n            next = next ? next.split('-') : null;\n            while (j > 0) {\n                locale = loadLocale(split.slice(0, j).join('-'));\n                if (locale) {\n                    return locale;\n                }\n                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                    //the next array item is better than a shallower substring of this one\n                    break;\n                }\n                j--;\n            }\n            i++;\n        }\n        return globalLocale;\n    }\n\n    function loadLocale(name) {\n        var oldLocale = null;\n        // TODO: Find a better way to register and load all the locales in Node\n        if (!locales[name] && (typeof module !== 'undefined') &&\n                module && module.exports) {\n            try {\n                oldLocale = globalLocale._abbr;\n                var aliasedRequire = require;\n                !(function webpackMissingModule() { var e = new Error(\"Cannot find module 'undefined'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }());\n                getSetGlobalLocale(oldLocale);\n            } catch (e) {}\n        }\n        return locales[name];\n    }\n\n    // This function will load locale and then set the global locale.  If\n    // no arguments are passed in, it will simply return the current global\n    // locale key.\n    function getSetGlobalLocale (key, values) {\n        var data;\n        if (key) {\n            if (isUndefined(values)) {\n                data = getLocale(key);\n            }\n            else {\n                data = defineLocale(key, values);\n            }\n\n            if (data) {\n                // moment.duration._locale = moment._locale = data;\n                globalLocale = data;\n            }\n            else {\n                if ((typeof console !==  'undefined') && console.warn) {\n                    //warn user if arguments are passed but the locale could not be set\n                    console.warn('Locale ' + key +  ' not found. Did you forget to load it?');\n                }\n            }\n        }\n\n        return globalLocale._abbr;\n    }\n\n    function defineLocale (name, config) {\n        if (config !== null) {\n            var locale, parentConfig = baseConfig;\n            config.abbr = name;\n            if (locales[name] != null) {\n                deprecateSimple('defineLocaleOverride',\n                        'use moment.updateLocale(localeName, config) to change ' +\n                        'an existing locale. moment.defineLocale(localeName, ' +\n                        'config) should only be used for creating a new locale ' +\n                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n                parentConfig = locales[name]._config;\n            } else if (config.parentLocale != null) {\n                if (locales[config.parentLocale] != null) {\n                    parentConfig = locales[config.parentLocale]._config;\n                } else {\n                    locale = loadLocale(config.parentLocale);\n                    if (locale != null) {\n                        parentConfig = locale._config;\n                    } else {\n                        if (!localeFamilies[config.parentLocale]) {\n                            localeFamilies[config.parentLocale] = [];\n                        }\n                        localeFamilies[config.parentLocale].push({\n                            name: name,\n                            config: config\n                        });\n                        return null;\n                    }\n                }\n            }\n            locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n            if (localeFamilies[name]) {\n                localeFamilies[name].forEach(function (x) {\n                    defineLocale(x.name, x.config);\n                });\n            }\n\n            // backwards compat for now: also set the locale\n            // make sure we set the locale AFTER all child locales have been\n            // created, so we won't end up with the child locale set.\n            getSetGlobalLocale(name);\n\n\n            return locales[name];\n        } else {\n            // useful for testing\n            delete locales[name];\n            return null;\n        }\n    }\n\n    function updateLocale(name, config) {\n        if (config != null) {\n            var locale, tmpLocale, parentConfig = baseConfig;\n            // MERGE\n            tmpLocale = loadLocale(name);\n            if (tmpLocale != null) {\n                parentConfig = tmpLocale._config;\n            }\n            config = mergeConfigs(parentConfig, config);\n            locale = new Locale(config);\n            locale.parentLocale = locales[name];\n            locales[name] = locale;\n\n            // backwards compat for now: also set the locale\n            getSetGlobalLocale(name);\n        } else {\n            // pass null for config to unupdate, useful for tests\n            if (locales[name] != null) {\n                if (locales[name].parentLocale != null) {\n                    locales[name] = locales[name].parentLocale;\n                } else if (locales[name] != null) {\n                    delete locales[name];\n                }\n            }\n        }\n        return locales[name];\n    }\n\n    // returns locale data\n    function getLocale (key) {\n        var locale;\n\n        if (key && key._locale && key._locale._abbr) {\n            key = key._locale._abbr;\n        }\n\n        if (!key) {\n            return globalLocale;\n        }\n\n        if (!isArray(key)) {\n            //short-circuit everything else\n            locale = loadLocale(key);\n            if (locale) {\n                return locale;\n            }\n            key = [key];\n        }\n\n        return chooseLocale(key);\n    }\n\n    function listLocales() {\n        return keys(locales);\n    }\n\n    function checkOverflow (m) {\n        var overflow;\n        var a = m._a;\n\n        if (a && getParsingFlags(m).overflow === -2) {\n            overflow =\n                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n                -1;\n\n            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n                overflow = DATE;\n            }\n            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n                overflow = WEEK;\n            }\n            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n                overflow = WEEKDAY;\n            }\n\n            getParsingFlags(m).overflow = overflow;\n        }\n\n        return m;\n    }\n\n    // Pick the first defined of two or three arguments.\n    function defaults(a, b, c) {\n        if (a != null) {\n            return a;\n        }\n        if (b != null) {\n            return b;\n        }\n        return c;\n    }\n\n    function currentDateArray(config) {\n        // hooks is actually the exported moment object\n        var nowValue = new Date(hooks.now());\n        if (config._useUTC) {\n            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n        }\n        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n    }\n\n    // convert an array to a date.\n    // the array should mirror the parameters below\n    // note: all values past the year are optional and will default to the lowest possible value.\n    // [year, month, day , hour, minute, second, millisecond]\n    function configFromArray (config) {\n        var i, date, input = [], currentDate, expectedWeekday, yearToUse;\n\n        if (config._d) {\n            return;\n        }\n\n        currentDate = currentDateArray(config);\n\n        //compute day of the year from weeks and weekdays\n        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n            dayOfYearFromWeekInfo(config);\n        }\n\n        //if the day of the year is set, figure out what it is\n        if (config._dayOfYear != null) {\n            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n            if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n                getParsingFlags(config)._overflowDayOfYear = true;\n            }\n\n            date = createUTCDate(yearToUse, 0, config._dayOfYear);\n            config._a[MONTH] = date.getUTCMonth();\n            config._a[DATE] = date.getUTCDate();\n        }\n\n        // Default to current date.\n        // * if no year, month, day of month are given, default to today\n        // * if day of month is given, default month and year\n        // * if month is given, default only year\n        // * if year is given, don't default anything\n        for (i = 0; i < 3 && config._a[i] == null; ++i) {\n            config._a[i] = input[i] = currentDate[i];\n        }\n\n        // Zero out whatever was not defaulted, including time\n        for (; i < 7; i++) {\n            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n        }\n\n        // Check for 24:00:00.000\n        if (config._a[HOUR] === 24 &&\n                config._a[MINUTE] === 0 &&\n                config._a[SECOND] === 0 &&\n                config._a[MILLISECOND] === 0) {\n            config._nextDay = true;\n            config._a[HOUR] = 0;\n        }\n\n        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n        expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();\n\n        // Apply timezone offset from input. The actual utcOffset can be changed\n        // with parseZone.\n        if (config._tzm != null) {\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n        }\n\n        if (config._nextDay) {\n            config._a[HOUR] = 24;\n        }\n\n        // check for mismatching day of week\n        if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {\n            getParsingFlags(config).weekdayMismatch = true;\n        }\n    }\n\n    function dayOfYearFromWeekInfo(config) {\n        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n        w = config._w;\n        if (w.GG != null || w.W != null || w.E != null) {\n            dow = 1;\n            doy = 4;\n\n            // TODO: We need to take the current isoWeekYear, but that depends on\n            // how we interpret now (local, utc, fixed offset). So create\n            // a now version of current config (take local/utc/offset flags, and\n            // create now).\n            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n            week = defaults(w.W, 1);\n            weekday = defaults(w.E, 1);\n            if (weekday < 1 || weekday > 7) {\n                weekdayOverflow = true;\n            }\n        } else {\n            dow = config._locale._week.dow;\n            doy = config._locale._week.doy;\n\n            var curWeek = weekOfYear(createLocal(), dow, doy);\n\n            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n            // Default to current week.\n            week = defaults(w.w, curWeek.week);\n\n            if (w.d != null) {\n                // weekday -- low day numbers are considered next week\n                weekday = w.d;\n                if (weekday < 0 || weekday > 6) {\n                    weekdayOverflow = true;\n                }\n            } else if (w.e != null) {\n                // local weekday -- counting starts from beginning of week\n                weekday = w.e + dow;\n                if (w.e < 0 || w.e > 6) {\n                    weekdayOverflow = true;\n                }\n            } else {\n                // default to beginning of week\n                weekday = dow;\n            }\n        }\n        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n            getParsingFlags(config)._overflowWeeks = true;\n        } else if (weekdayOverflow != null) {\n            getParsingFlags(config)._overflowWeekday = true;\n        } else {\n            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n            config._a[YEAR] = temp.year;\n            config._dayOfYear = temp.dayOfYear;\n        }\n    }\n\n    // iso 8601 regex\n    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\n    var extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n    var basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\n    var tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\n    var isoDates = [\n        ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n        ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n        ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n        ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n        ['YYYY-DDD', /\\d{4}-\\d{3}/],\n        ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n        ['YYYYYYMMDD', /[+-]\\d{10}/],\n        ['YYYYMMDD', /\\d{8}/],\n        // YYYYMM is NOT allowed by the standard\n        ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n        ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n        ['YYYYDDD', /\\d{7}/]\n    ];\n\n    // iso time formats and regexes\n    var isoTimes = [\n        ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n        ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n        ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n        ['HH:mm', /\\d\\d:\\d\\d/],\n        ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n        ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n        ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n        ['HHmm', /\\d\\d\\d\\d/],\n        ['HH', /\\d\\d/]\n    ];\n\n    var aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n    // date from iso format\n    function configFromISO(config) {\n        var i, l,\n            string = config._i,\n            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n            allowTime, dateFormat, timeFormat, tzFormat;\n\n        if (match) {\n            getParsingFlags(config).iso = true;\n\n            for (i = 0, l = isoDates.length; i < l; i++) {\n                if (isoDates[i][1].exec(match[1])) {\n                    dateFormat = isoDates[i][0];\n                    allowTime = isoDates[i][2] !== false;\n                    break;\n                }\n            }\n            if (dateFormat == null) {\n                config._isValid = false;\n                return;\n            }\n            if (match[3]) {\n                for (i = 0, l = isoTimes.length; i < l; i++) {\n                    if (isoTimes[i][1].exec(match[3])) {\n                        // match[2] should be 'T' or space\n                        timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                        break;\n                    }\n                }\n                if (timeFormat == null) {\n                    config._isValid = false;\n                    return;\n                }\n            }\n            if (!allowTime && timeFormat != null) {\n                config._isValid = false;\n                return;\n            }\n            if (match[4]) {\n                if (tzRegex.exec(match[4])) {\n                    tzFormat = 'Z';\n                } else {\n                    config._isValid = false;\n                    return;\n                }\n            }\n            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n            configFromStringAndFormat(config);\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\n    var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d{1,2})\\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(\\d{2,4})\\s(\\d\\d):(\\d\\d)(?::(\\d\\d))?\\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\\d{4}))$/;\n\n    function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {\n        var result = [\n            untruncateYear(yearStr),\n            defaultLocaleMonthsShort.indexOf(monthStr),\n            parseInt(dayStr, 10),\n            parseInt(hourStr, 10),\n            parseInt(minuteStr, 10)\n        ];\n\n        if (secondStr) {\n            result.push(parseInt(secondStr, 10));\n        }\n\n        return result;\n    }\n\n    function untruncateYear(yearStr) {\n        var year = parseInt(yearStr, 10);\n        if (year <= 49) {\n            return 2000 + year;\n        } else if (year <= 999) {\n            return 1900 + year;\n        }\n        return year;\n    }\n\n    function preprocessRFC2822(s) {\n        // Remove comments and folding whitespace and replace multiple-spaces with a single space\n        return s.replace(/\\([^)]*\\)|[\\n\\t]/g, ' ').replace(/(\\s\\s+)/g, ' ').replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n    }\n\n    function checkWeekday(weekdayStr, parsedInput, config) {\n        if (weekdayStr) {\n            // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),\n                weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();\n            if (weekdayProvided !== weekdayActual) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return false;\n            }\n        }\n        return true;\n    }\n\n    var obsOffsets = {\n        UT: 0,\n        GMT: 0,\n        EDT: -4 * 60,\n        EST: -5 * 60,\n        CDT: -5 * 60,\n        CST: -6 * 60,\n        MDT: -6 * 60,\n        MST: -7 * 60,\n        PDT: -7 * 60,\n        PST: -8 * 60\n    };\n\n    function calculateOffset(obsOffset, militaryOffset, numOffset) {\n        if (obsOffset) {\n            return obsOffsets[obsOffset];\n        } else if (militaryOffset) {\n            // the only allowed military tz is Z\n            return 0;\n        } else {\n            var hm = parseInt(numOffset, 10);\n            var m = hm % 100, h = (hm - m) / 100;\n            return h * 60 + m;\n        }\n    }\n\n    // date and time from ref 2822 format\n    function configFromRFC2822(config) {\n        var match = rfc2822.exec(preprocessRFC2822(config._i));\n        if (match) {\n            var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);\n            if (!checkWeekday(match[1], parsedArray, config)) {\n                return;\n            }\n\n            config._a = parsedArray;\n            config._tzm = calculateOffset(match[8], match[9], match[10]);\n\n            config._d = createUTCDate.apply(null, config._a);\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n\n            getParsingFlags(config).rfc2822 = true;\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // date from iso format or fallback\n    function configFromString(config) {\n        var matched = aspNetJsonRegex.exec(config._i);\n\n        if (matched !== null) {\n            config._d = new Date(+matched[1]);\n            return;\n        }\n\n        configFromISO(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n        } else {\n            return;\n        }\n\n        configFromRFC2822(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n        } else {\n            return;\n        }\n\n        // Final attempt, use Input Fallback\n        hooks.createFromInputFallback(config);\n    }\n\n    hooks.createFromInputFallback = deprecate(\n        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n        'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n        'discouraged and will be removed in an upcoming major release. Please refer to ' +\n        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n        function (config) {\n            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n        }\n    );\n\n    // constant that refers to the ISO standard\n    hooks.ISO_8601 = function () {};\n\n    // constant that refers to the RFC 2822 form\n    hooks.RFC_2822 = function () {};\n\n    // date from string and format string\n    function configFromStringAndFormat(config) {\n        // TODO: Move this to another part of the creation flow to prevent circular deps\n        if (config._f === hooks.ISO_8601) {\n            configFromISO(config);\n            return;\n        }\n        if (config._f === hooks.RFC_2822) {\n            configFromRFC2822(config);\n            return;\n        }\n        config._a = [];\n        getParsingFlags(config).empty = true;\n\n        // This array is used to make a Date, either with `new Date` or `Date.UTC`\n        var string = '' + config._i,\n            i, parsedInput, tokens, token, skipped,\n            stringLength = string.length,\n            totalParsedInputLength = 0;\n\n        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n        for (i = 0; i < tokens.length; i++) {\n            token = tokens[i];\n            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n            // console.log('token', token, 'parsedInput', parsedInput,\n            //         'regex', getParseRegexForToken(token, config));\n            if (parsedInput) {\n                skipped = string.substr(0, string.indexOf(parsedInput));\n                if (skipped.length > 0) {\n                    getParsingFlags(config).unusedInput.push(skipped);\n                }\n                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n                totalParsedInputLength += parsedInput.length;\n            }\n            // don't parse if it's not a known token\n            if (formatTokenFunctions[token]) {\n                if (parsedInput) {\n                    getParsingFlags(config).empty = false;\n                }\n                else {\n                    getParsingFlags(config).unusedTokens.push(token);\n                }\n                addTimeToArrayFromToken(token, parsedInput, config);\n            }\n            else if (config._strict && !parsedInput) {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n        }\n\n        // add remaining unparsed input length to the string\n        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n        if (string.length > 0) {\n            getParsingFlags(config).unusedInput.push(string);\n        }\n\n        // clear _12h flag if hour is <= 12\n        if (config._a[HOUR] <= 12 &&\n            getParsingFlags(config).bigHour === true &&\n            config._a[HOUR] > 0) {\n            getParsingFlags(config).bigHour = undefined;\n        }\n\n        getParsingFlags(config).parsedDateParts = config._a.slice(0);\n        getParsingFlags(config).meridiem = config._meridiem;\n        // handle meridiem\n        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n        configFromArray(config);\n        checkOverflow(config);\n    }\n\n\n    function meridiemFixWrap (locale, hour, meridiem) {\n        var isPm;\n\n        if (meridiem == null) {\n            // nothing to do\n            return hour;\n        }\n        if (locale.meridiemHour != null) {\n            return locale.meridiemHour(hour, meridiem);\n        } else if (locale.isPM != null) {\n            // Fallback\n            isPm = locale.isPM(meridiem);\n            if (isPm && hour < 12) {\n                hour += 12;\n            }\n            if (!isPm && hour === 12) {\n                hour = 0;\n            }\n            return hour;\n        } else {\n            // this is not supposed to happen\n            return hour;\n        }\n    }\n\n    // date from string and array of format strings\n    function configFromStringAndArray(config) {\n        var tempConfig,\n            bestMoment,\n\n            scoreToBeat,\n            i,\n            currentScore;\n\n        if (config._f.length === 0) {\n            getParsingFlags(config).invalidFormat = true;\n            config._d = new Date(NaN);\n            return;\n        }\n\n        for (i = 0; i < config._f.length; i++) {\n            currentScore = 0;\n            tempConfig = copyConfig({}, config);\n            if (config._useUTC != null) {\n                tempConfig._useUTC = config._useUTC;\n            }\n            tempConfig._f = config._f[i];\n            configFromStringAndFormat(tempConfig);\n\n            if (!isValid(tempConfig)) {\n                continue;\n            }\n\n            // if there is any input that was not parsed add a penalty for that format\n            currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n            //or tokens\n            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n            getParsingFlags(tempConfig).score = currentScore;\n\n            if (scoreToBeat == null || currentScore < scoreToBeat) {\n                scoreToBeat = currentScore;\n                bestMoment = tempConfig;\n            }\n        }\n\n        extend(config, bestMoment || tempConfig);\n    }\n\n    function configFromObject(config) {\n        if (config._d) {\n            return;\n        }\n\n        var i = normalizeObjectUnits(config._i);\n        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n            return obj && parseInt(obj, 10);\n        });\n\n        configFromArray(config);\n    }\n\n    function createFromConfig (config) {\n        var res = new Moment(checkOverflow(prepareConfig(config)));\n        if (res._nextDay) {\n            // Adding is smart enough around DST\n            res.add(1, 'd');\n            res._nextDay = undefined;\n        }\n\n        return res;\n    }\n\n    function prepareConfig (config) {\n        var input = config._i,\n            format = config._f;\n\n        config._locale = config._locale || getLocale(config._l);\n\n        if (input === null || (format === undefined && input === '')) {\n            return createInvalid({nullInput: true});\n        }\n\n        if (typeof input === 'string') {\n            config._i = input = config._locale.preparse(input);\n        }\n\n        if (isMoment(input)) {\n            return new Moment(checkOverflow(input));\n        } else if (isDate(input)) {\n            config._d = input;\n        } else if (isArray(format)) {\n            configFromStringAndArray(config);\n        } else if (format) {\n            configFromStringAndFormat(config);\n        }  else {\n            configFromInput(config);\n        }\n\n        if (!isValid(config)) {\n            config._d = null;\n        }\n\n        return config;\n    }\n\n    function configFromInput(config) {\n        var input = config._i;\n        if (isUndefined(input)) {\n            config._d = new Date(hooks.now());\n        } else if (isDate(input)) {\n            config._d = new Date(input.valueOf());\n        } else if (typeof input === 'string') {\n            configFromString(config);\n        } else if (isArray(input)) {\n            config._a = map(input.slice(0), function (obj) {\n                return parseInt(obj, 10);\n            });\n            configFromArray(config);\n        } else if (isObject(input)) {\n            configFromObject(config);\n        } else if (isNumber(input)) {\n            // from milliseconds\n            config._d = new Date(input);\n        } else {\n            hooks.createFromInputFallback(config);\n        }\n    }\n\n    function createLocalOrUTC (input, format, locale, strict, isUTC) {\n        var c = {};\n\n        if (locale === true || locale === false) {\n            strict = locale;\n            locale = undefined;\n        }\n\n        if ((isObject(input) && isObjectEmpty(input)) ||\n                (isArray(input) && input.length === 0)) {\n            input = undefined;\n        }\n        // object construction must be done this way.\n        // https://github.com/moment/moment/issues/1423\n        c._isAMomentObject = true;\n        c._useUTC = c._isUTC = isUTC;\n        c._l = locale;\n        c._i = input;\n        c._f = format;\n        c._strict = strict;\n\n        return createFromConfig(c);\n    }\n\n    function createLocal (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, false);\n    }\n\n    var prototypeMin = deprecate(\n        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n        function () {\n            var other = createLocal.apply(null, arguments);\n            if (this.isValid() && other.isValid()) {\n                return other < this ? this : other;\n            } else {\n                return createInvalid();\n            }\n        }\n    );\n\n    var prototypeMax = deprecate(\n        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n        function () {\n            var other = createLocal.apply(null, arguments);\n            if (this.isValid() && other.isValid()) {\n                return other > this ? this : other;\n            } else {\n                return createInvalid();\n            }\n        }\n    );\n\n    // Pick a moment m from moments so that m[fn](other) is true for all\n    // other. This relies on the function fn to be transitive.\n    //\n    // moments should either be an array of moment objects or an array, whose\n    // first element is an array of moment objects.\n    function pickBy(fn, moments) {\n        var res, i;\n        if (moments.length === 1 && isArray(moments[0])) {\n            moments = moments[0];\n        }\n        if (!moments.length) {\n            return createLocal();\n        }\n        res = moments[0];\n        for (i = 1; i < moments.length; ++i) {\n            if (!moments[i].isValid() || moments[i][fn](res)) {\n                res = moments[i];\n            }\n        }\n        return res;\n    }\n\n    // TODO: Use [].sort instead?\n    function min () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isBefore', args);\n    }\n\n    function max () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isAfter', args);\n    }\n\n    var now = function () {\n        return Date.now ? Date.now() : +(new Date());\n    };\n\n    var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\n    function isDurationValid(m) {\n        for (var key in m) {\n            if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n                return false;\n            }\n        }\n\n        var unitHasDecimal = false;\n        for (var i = 0; i < ordering.length; ++i) {\n            if (m[ordering[i]]) {\n                if (unitHasDecimal) {\n                    return false; // only allow non-integers for smallest unit\n                }\n                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                    unitHasDecimal = true;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    function isValid$1() {\n        return this._isValid;\n    }\n\n    function createInvalid$1() {\n        return createDuration(NaN);\n    }\n\n    function Duration (duration) {\n        var normalizedInput = normalizeObjectUnits(duration),\n            years = normalizedInput.year || 0,\n            quarters = normalizedInput.quarter || 0,\n            months = normalizedInput.month || 0,\n            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,\n            days = normalizedInput.day || 0,\n            hours = normalizedInput.hour || 0,\n            minutes = normalizedInput.minute || 0,\n            seconds = normalizedInput.second || 0,\n            milliseconds = normalizedInput.millisecond || 0;\n\n        this._isValid = isDurationValid(normalizedInput);\n\n        // representation for dateAddRemove\n        this._milliseconds = +milliseconds +\n            seconds * 1e3 + // 1000\n            minutes * 6e4 + // 1000 * 60\n            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n        // Because of dateAddRemove treats 24 hours as different from a\n        // day when working around DST, we need to store them separately\n        this._days = +days +\n            weeks * 7;\n        // It is impossible to translate months into days without knowing\n        // which months you are are talking about, so we have to store\n        // it separately.\n        this._months = +months +\n            quarters * 3 +\n            years * 12;\n\n        this._data = {};\n\n        this._locale = getLocale();\n\n        this._bubble();\n    }\n\n    function isDuration (obj) {\n        return obj instanceof Duration;\n    }\n\n    function absRound (number) {\n        if (number < 0) {\n            return Math.round(-1 * number) * -1;\n        } else {\n            return Math.round(number);\n        }\n    }\n\n    // FORMATTING\n\n    function offset (token, separator) {\n        addFormatToken(token, 0, 0, function () {\n            var offset = this.utcOffset();\n            var sign = '+';\n            if (offset < 0) {\n                offset = -offset;\n                sign = '-';\n            }\n            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n        });\n    }\n\n    offset('Z', ':');\n    offset('ZZ', '');\n\n    // PARSING\n\n    addRegexToken('Z',  matchShortOffset);\n    addRegexToken('ZZ', matchShortOffset);\n    addParseToken(['Z', 'ZZ'], function (input, array, config) {\n        config._useUTC = true;\n        config._tzm = offsetFromString(matchShortOffset, input);\n    });\n\n    // HELPERS\n\n    // timezone chunker\n    // '+10:00' > ['10',  '00']\n    // '-1530'  > ['-15', '30']\n    var chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\n    function offsetFromString(matcher, string) {\n        var matches = (string || '').match(matcher);\n\n        if (matches === null) {\n            return null;\n        }\n\n        var chunk   = matches[matches.length - 1] || [];\n        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n        var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n        return minutes === 0 ?\n          0 :\n          parts[0] === '+' ? minutes : -minutes;\n    }\n\n    // Return a moment from input, that is local/utc/zone equivalent to model.\n    function cloneWithOffset(input, model) {\n        var res, diff;\n        if (model._isUTC) {\n            res = model.clone();\n            diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n            // Use low-level api, because this fn is low-level api.\n            res._d.setTime(res._d.valueOf() + diff);\n            hooks.updateOffset(res, false);\n            return res;\n        } else {\n            return createLocal(input).local();\n        }\n    }\n\n    function getDateOffset (m) {\n        // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n        // https://github.com/moment/moment/pull/1871\n        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n    }\n\n    // HOOKS\n\n    // This function will be called whenever a moment is mutated.\n    // It is intended to keep the offset in sync with the timezone.\n    hooks.updateOffset = function () {};\n\n    // MOMENTS\n\n    // keepLocalTime = true means only change the timezone, without\n    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--\x3e\n    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n    // +0200, so we adjust the time as needed, to be valid.\n    //\n    // Keeping the time actually adds/subtracts (one hour)\n    // from the actual represented time. That is why we call updateOffset\n    // a second time. In case it wants us to change the offset again\n    // _changeInProgress == true case, then we have to adjust, because\n    // there is no such time in the given timezone.\n    function getSetOffset (input, keepLocalTime, keepMinutes) {\n        var offset = this._offset || 0,\n            localAdjust;\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        if (input != null) {\n            if (typeof input === 'string') {\n                input = offsetFromString(matchShortOffset, input);\n                if (input === null) {\n                    return this;\n                }\n            } else if (Math.abs(input) < 16 && !keepMinutes) {\n                input = input * 60;\n            }\n            if (!this._isUTC && keepLocalTime) {\n                localAdjust = getDateOffset(this);\n            }\n            this._offset = input;\n            this._isUTC = true;\n            if (localAdjust != null) {\n                this.add(localAdjust, 'm');\n            }\n            if (offset !== input) {\n                if (!keepLocalTime || this._changeInProgress) {\n                    addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n                } else if (!this._changeInProgress) {\n                    this._changeInProgress = true;\n                    hooks.updateOffset(this, true);\n                    this._changeInProgress = null;\n                }\n            }\n            return this;\n        } else {\n            return this._isUTC ? offset : getDateOffset(this);\n        }\n    }\n\n    function getSetZone (input, keepLocalTime) {\n        if (input != null) {\n            if (typeof input !== 'string') {\n                input = -input;\n            }\n\n            this.utcOffset(input, keepLocalTime);\n\n            return this;\n        } else {\n            return -this.utcOffset();\n        }\n    }\n\n    function setOffsetToUTC (keepLocalTime) {\n        return this.utcOffset(0, keepLocalTime);\n    }\n\n    function setOffsetToLocal (keepLocalTime) {\n        if (this._isUTC) {\n            this.utcOffset(0, keepLocalTime);\n            this._isUTC = false;\n\n            if (keepLocalTime) {\n                this.subtract(getDateOffset(this), 'm');\n            }\n        }\n        return this;\n    }\n\n    function setOffsetToParsedOffset () {\n        if (this._tzm != null) {\n            this.utcOffset(this._tzm, false, true);\n        } else if (typeof this._i === 'string') {\n            var tZone = offsetFromString(matchOffset, this._i);\n            if (tZone != null) {\n                this.utcOffset(tZone);\n            }\n            else {\n                this.utcOffset(0, true);\n            }\n        }\n        return this;\n    }\n\n    function hasAlignedHourOffset (input) {\n        if (!this.isValid()) {\n            return false;\n        }\n        input = input ? createLocal(input).utcOffset() : 0;\n\n        return (this.utcOffset() - input) % 60 === 0;\n    }\n\n    function isDaylightSavingTime () {\n        return (\n            this.utcOffset() > this.clone().month(0).utcOffset() ||\n            this.utcOffset() > this.clone().month(5).utcOffset()\n        );\n    }\n\n    function isDaylightSavingTimeShifted () {\n        if (!isUndefined(this._isDSTShifted)) {\n            return this._isDSTShifted;\n        }\n\n        var c = {};\n\n        copyConfig(c, this);\n        c = prepareConfig(c);\n\n        if (c._a) {\n            var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n            this._isDSTShifted = this.isValid() &&\n                compareArrays(c._a, other.toArray()) > 0;\n        } else {\n            this._isDSTShifted = false;\n        }\n\n        return this._isDSTShifted;\n    }\n\n    function isLocal () {\n        return this.isValid() ? !this._isUTC : false;\n    }\n\n    function isUtcOffset () {\n        return this.isValid() ? this._isUTC : false;\n    }\n\n    function isUtc () {\n        return this.isValid() ? this._isUTC && this._offset === 0 : false;\n    }\n\n    // ASP.NET json date format regex\n    var aspNetRegex = /^(\\-|\\+)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n    // and further modified to allow for strings containing both week and day\n    var isoRegex = /^(-|\\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;\n\n    function createDuration (input, key) {\n        var duration = input,\n            // matching against regexp is expensive, do it on demand\n            match = null,\n            sign,\n            ret,\n            diffRes;\n\n        if (isDuration(input)) {\n            duration = {\n                ms : input._milliseconds,\n                d  : input._days,\n                M  : input._months\n            };\n        } else if (isNumber(input)) {\n            duration = {};\n            if (key) {\n                duration[key] = input;\n            } else {\n                duration.milliseconds = input;\n            }\n        } else if (!!(match = aspNetRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y  : 0,\n                d  : toInt(match[DATE])                         * sign,\n                h  : toInt(match[HOUR])                         * sign,\n                m  : toInt(match[MINUTE])                       * sign,\n                s  : toInt(match[SECOND])                       * sign,\n                ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n            };\n        } else if (!!(match = isoRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y : parseIso(match[2], sign),\n                M : parseIso(match[3], sign),\n                w : parseIso(match[4], sign),\n                d : parseIso(match[5], sign),\n                h : parseIso(match[6], sign),\n                m : parseIso(match[7], sign),\n                s : parseIso(match[8], sign)\n            };\n        } else if (duration == null) {// checks for null or undefined\n            duration = {};\n        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n            diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n            duration = {};\n            duration.ms = diffRes.milliseconds;\n            duration.M = diffRes.months;\n        }\n\n        ret = new Duration(duration);\n\n        if (isDuration(input) && hasOwnProp(input, '_locale')) {\n            ret._locale = input._locale;\n        }\n\n        return ret;\n    }\n\n    createDuration.fn = Duration.prototype;\n    createDuration.invalid = createInvalid$1;\n\n    function parseIso (inp, sign) {\n        // We'd normally use ~~inp for this, but unfortunately it also\n        // converts floats to ints.\n        // inp may be undefined, so careful calling replace on it.\n        var res = inp && parseFloat(inp.replace(',', '.'));\n        // apply sign while we're at it\n        return (isNaN(res) ? 0 : res) * sign;\n    }\n\n    function positiveMomentsDifference(base, other) {\n        var res = {};\n\n        res.months = other.month() - base.month() +\n            (other.year() - base.year()) * 12;\n        if (base.clone().add(res.months, 'M').isAfter(other)) {\n            --res.months;\n        }\n\n        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n        return res;\n    }\n\n    function momentsDifference(base, other) {\n        var res;\n        if (!(base.isValid() && other.isValid())) {\n            return {milliseconds: 0, months: 0};\n        }\n\n        other = cloneWithOffset(other, base);\n        if (base.isBefore(other)) {\n            res = positiveMomentsDifference(base, other);\n        } else {\n            res = positiveMomentsDifference(other, base);\n            res.milliseconds = -res.milliseconds;\n            res.months = -res.months;\n        }\n\n        return res;\n    }\n\n    // TODO: remove 'name' arg after deprecation is removed\n    function createAdder(direction, name) {\n        return function (val, period) {\n            var dur, tmp;\n            //invert the arguments, but complain about it\n            if (period !== null && !isNaN(+period)) {\n                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n                'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n                tmp = val; val = period; period = tmp;\n            }\n\n            val = typeof val === 'string' ? +val : val;\n            dur = createDuration(val, period);\n            addSubtract(this, dur, direction);\n            return this;\n        };\n    }\n\n    function addSubtract (mom, duration, isAdding, updateOffset) {\n        var milliseconds = duration._milliseconds,\n            days = absRound(duration._days),\n            months = absRound(duration._months);\n\n        if (!mom.isValid()) {\n            // No op\n            return;\n        }\n\n        updateOffset = updateOffset == null ? true : updateOffset;\n\n        if (months) {\n            setMonth(mom, get(mom, 'Month') + months * isAdding);\n        }\n        if (days) {\n            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n        }\n        if (milliseconds) {\n            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n        }\n        if (updateOffset) {\n            hooks.updateOffset(mom, days || months);\n        }\n    }\n\n    var add      = createAdder(1, 'add');\n    var subtract = createAdder(-1, 'subtract');\n\n    function getCalendarFormat(myMoment, now) {\n        var diff = myMoment.diff(now, 'days', true);\n        return diff < -6 ? 'sameElse' :\n                diff < -1 ? 'lastWeek' :\n                diff < 0 ? 'lastDay' :\n                diff < 1 ? 'sameDay' :\n                diff < 2 ? 'nextDay' :\n                diff < 7 ? 'nextWeek' : 'sameElse';\n    }\n\n    function calendar$1 (time, formats) {\n        // We want to compare the start of today, vs this.\n        // Getting start-of-today depends on whether we're local/utc/offset or not.\n        var now = time || createLocal(),\n            sod = cloneWithOffset(now, this).startOf('day'),\n            format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n        return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n    }\n\n    function clone () {\n        return new Moment(this);\n    }\n\n    function isAfter (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input);\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() > localInput.valueOf();\n        } else {\n            return localInput.valueOf() < this.clone().startOf(units).valueOf();\n        }\n    }\n\n    function isBefore (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input);\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() < localInput.valueOf();\n        } else {\n            return this.clone().endOf(units).valueOf() < localInput.valueOf();\n        }\n    }\n\n    function isBetween (from, to, units, inclusivity) {\n        var localFrom = isMoment(from) ? from : createLocal(from),\n            localTo = isMoment(to) ? to : createLocal(to);\n        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {\n            return false;\n        }\n        inclusivity = inclusivity || '()';\n        return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) &&\n            (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));\n    }\n\n    function isSame (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input),\n            inputMs;\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() === localInput.valueOf();\n        } else {\n            inputMs = localInput.valueOf();\n            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n        }\n    }\n\n    function isSameOrAfter (input, units) {\n        return this.isSame(input, units) || this.isAfter(input, units);\n    }\n\n    function isSameOrBefore (input, units) {\n        return this.isSame(input, units) || this.isBefore(input, units);\n    }\n\n    function diff (input, units, asFloat) {\n        var that,\n            zoneDelta,\n            output;\n\n        if (!this.isValid()) {\n            return NaN;\n        }\n\n        that = cloneWithOffset(input, this);\n\n        if (!that.isValid()) {\n            return NaN;\n        }\n\n        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n        units = normalizeUnits(units);\n\n        switch (units) {\n            case 'year': output = monthDiff(this, that) / 12; break;\n            case 'month': output = monthDiff(this, that); break;\n            case 'quarter': output = monthDiff(this, that) / 3; break;\n            case 'second': output = (this - that) / 1e3; break; // 1000\n            case 'minute': output = (this - that) / 6e4; break; // 1000 * 60\n            case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60\n            case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst\n            case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst\n            default: output = this - that;\n        }\n\n        return asFloat ? output : absFloor(output);\n    }\n\n    function monthDiff (a, b) {\n        // difference in months\n        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n            // b is in (anchor - 1 month, anchor + 1 month)\n            anchor = a.clone().add(wholeMonthDiff, 'months'),\n            anchor2, adjust;\n\n        if (b - anchor < 0) {\n            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor - anchor2);\n        } else {\n            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor2 - anchor);\n        }\n\n        //check for negative zero, return zero if negative zero\n        return -(wholeMonthDiff + adjust) || 0;\n    }\n\n    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\n    function toString () {\n        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n    }\n\n    function toISOString(keepOffset) {\n        if (!this.isValid()) {\n            return null;\n        }\n        var utc = keepOffset !== true;\n        var m = utc ? this.clone().utc() : this;\n        if (m.year() < 0 || m.year() > 9999) {\n            return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');\n        }\n        if (isFunction(Date.prototype.toISOString)) {\n            // native implementation is ~50x faster, use it when we can\n            if (utc) {\n                return this.toDate().toISOString();\n            } else {\n                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));\n            }\n        }\n        return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');\n    }\n\n    /**\n     * Return a human readable representation of a moment that can\n     * also be evaluated to get a new moment which is the same\n     *\n     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n     */\n    function inspect () {\n        if (!this.isValid()) {\n            return 'moment.invalid(/* ' + this._i + ' */)';\n        }\n        var func = 'moment';\n        var zone = '';\n        if (!this.isLocal()) {\n            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n            zone = 'Z';\n        }\n        var prefix = '[' + func + '(\"]';\n        var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n        var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n        var suffix = zone + '[\")]';\n\n        return this.format(prefix + year + datetime + suffix);\n    }\n\n    function format (inputString) {\n        if (!inputString) {\n            inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n        }\n        var output = formatMoment(this, inputString);\n        return this.localeData().postformat(output);\n    }\n\n    function from (time, withoutSuffix) {\n        if (this.isValid() &&\n                ((isMoment(time) && time.isValid()) ||\n                 createLocal(time).isValid())) {\n            return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n        } else {\n            return this.localeData().invalidDate();\n        }\n    }\n\n    function fromNow (withoutSuffix) {\n        return this.from(createLocal(), withoutSuffix);\n    }\n\n    function to (time, withoutSuffix) {\n        if (this.isValid() &&\n                ((isMoment(time) && time.isValid()) ||\n                 createLocal(time).isValid())) {\n            return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n        } else {\n            return this.localeData().invalidDate();\n        }\n    }\n\n    function toNow (withoutSuffix) {\n        return this.to(createLocal(), withoutSuffix);\n    }\n\n    // If passed a locale key, it will set the locale for this\n    // instance.  Otherwise, it will return the locale configuration\n    // variables for this instance.\n    function locale (key) {\n        var newLocaleData;\n\n        if (key === undefined) {\n            return this._locale._abbr;\n        } else {\n            newLocaleData = getLocale(key);\n            if (newLocaleData != null) {\n                this._locale = newLocaleData;\n            }\n            return this;\n        }\n    }\n\n    var lang = deprecate(\n        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n        function (key) {\n            if (key === undefined) {\n                return this.localeData();\n            } else {\n                return this.locale(key);\n            }\n        }\n    );\n\n    function localeData () {\n        return this._locale;\n    }\n\n    var MS_PER_SECOND = 1000;\n    var MS_PER_MINUTE = 60 * MS_PER_SECOND;\n    var MS_PER_HOUR = 60 * MS_PER_MINUTE;\n    var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;\n\n    // actual modulo - handles negative numbers (for dates before 1970):\n    function mod$1(dividend, divisor) {\n        return (dividend % divisor + divisor) % divisor;\n    }\n\n    function localStartOfDate(y, m, d) {\n        // the date constructor remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            return new Date(y + 400, m, d) - MS_PER_400_YEARS;\n        } else {\n            return new Date(y, m, d).valueOf();\n        }\n    }\n\n    function utcStartOfDate(y, m, d) {\n        // Date.UTC remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;\n        } else {\n            return Date.UTC(y, m, d);\n        }\n    }\n\n    function startOf (units) {\n        var time;\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond' || !this.isValid()) {\n            return this;\n        }\n\n        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;\n\n        switch (units) {\n            case 'year':\n                time = startOfDate(this.year(), 0, 1);\n                break;\n            case 'quarter':\n                time = startOfDate(this.year(), this.month() - this.month() % 3, 1);\n                break;\n            case 'month':\n                time = startOfDate(this.year(), this.month(), 1);\n                break;\n            case 'week':\n                time = startOfDate(this.year(), this.month(), this.date() - this.weekday());\n                break;\n            case 'isoWeek':\n                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));\n                break;\n            case 'day':\n            case 'date':\n                time = startOfDate(this.year(), this.month(), this.date());\n                break;\n            case 'hour':\n                time = this._d.valueOf();\n                time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);\n                break;\n            case 'minute':\n                time = this._d.valueOf();\n                time -= mod$1(time, MS_PER_MINUTE);\n                break;\n            case 'second':\n                time = this._d.valueOf();\n                time -= mod$1(time, MS_PER_SECOND);\n                break;\n        }\n\n        this._d.setTime(time);\n        hooks.updateOffset(this, true);\n        return this;\n    }\n\n    function endOf (units) {\n        var time;\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond' || !this.isValid()) {\n            return this;\n        }\n\n        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;\n\n        switch (units) {\n            case 'year':\n                time = startOfDate(this.year() + 1, 0, 1) - 1;\n                break;\n            case 'quarter':\n                time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;\n                break;\n            case 'month':\n                time = startOfDate(this.year(), this.month() + 1, 1) - 1;\n                break;\n            case 'week':\n                time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;\n                break;\n            case 'isoWeek':\n                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;\n                break;\n            case 'day':\n            case 'date':\n                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;\n                break;\n            case 'hour':\n                time = this._d.valueOf();\n                time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;\n                break;\n            case 'minute':\n                time = this._d.valueOf();\n                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;\n                break;\n            case 'second':\n                time = this._d.valueOf();\n                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;\n                break;\n        }\n\n        this._d.setTime(time);\n        hooks.updateOffset(this, true);\n        return this;\n    }\n\n    function valueOf () {\n        return this._d.valueOf() - ((this._offset || 0) * 60000);\n    }\n\n    function unix () {\n        return Math.floor(this.valueOf() / 1000);\n    }\n\n    function toDate () {\n        return new Date(this.valueOf());\n    }\n\n    function toArray () {\n        var m = this;\n        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n    }\n\n    function toObject () {\n        var m = this;\n        return {\n            years: m.year(),\n            months: m.month(),\n            date: m.date(),\n            hours: m.hours(),\n            minutes: m.minutes(),\n            seconds: m.seconds(),\n            milliseconds: m.milliseconds()\n        };\n    }\n\n    function toJSON () {\n        // new Date(NaN).toJSON() === null\n        return this.isValid() ? this.toISOString() : null;\n    }\n\n    function isValid$2 () {\n        return isValid(this);\n    }\n\n    function parsingFlags () {\n        return extend({}, getParsingFlags(this));\n    }\n\n    function invalidAt () {\n        return getParsingFlags(this).overflow;\n    }\n\n    function creationData() {\n        return {\n            input: this._i,\n            format: this._f,\n            locale: this._locale,\n            isUTC: this._isUTC,\n            strict: this._strict\n        };\n    }\n\n    // FORMATTING\n\n    addFormatToken(0, ['gg', 2], 0, function () {\n        return this.weekYear() % 100;\n    });\n\n    addFormatToken(0, ['GG', 2], 0, function () {\n        return this.isoWeekYear() % 100;\n    });\n\n    function addWeekYearFormatToken (token, getter) {\n        addFormatToken(0, [token, token.length], 0, getter);\n    }\n\n    addWeekYearFormatToken('gggg',     'weekYear');\n    addWeekYearFormatToken('ggggg',    'weekYear');\n    addWeekYearFormatToken('GGGG',  'isoWeekYear');\n    addWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n    // ALIASES\n\n    addUnitAlias('weekYear', 'gg');\n    addUnitAlias('isoWeekYear', 'GG');\n\n    // PRIORITY\n\n    addUnitPriority('weekYear', 1);\n    addUnitPriority('isoWeekYear', 1);\n\n\n    // PARSING\n\n    addRegexToken('G',      matchSigned);\n    addRegexToken('g',      matchSigned);\n    addRegexToken('GG',     match1to2, match2);\n    addRegexToken('gg',     match1to2, match2);\n    addRegexToken('GGGG',   match1to4, match4);\n    addRegexToken('gggg',   match1to4, match4);\n    addRegexToken('GGGGG',  match1to6, match6);\n    addRegexToken('ggggg',  match1to6, match6);\n\n    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n        week[token.substr(0, 2)] = toInt(input);\n    });\n\n    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n        week[token] = hooks.parseTwoDigitYear(input);\n    });\n\n    // MOMENTS\n\n    function getSetWeekYear (input) {\n        return getSetWeekYearHelper.call(this,\n                input,\n                this.week(),\n                this.weekday(),\n                this.localeData()._week.dow,\n                this.localeData()._week.doy);\n    }\n\n    function getSetISOWeekYear (input) {\n        return getSetWeekYearHelper.call(this,\n                input, this.isoWeek(), this.isoWeekday(), 1, 4);\n    }\n\n    function getISOWeeksInYear () {\n        return weeksInYear(this.year(), 1, 4);\n    }\n\n    function getWeeksInYear () {\n        var weekInfo = this.localeData()._week;\n        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n    }\n\n    function getSetWeekYearHelper(input, week, weekday, dow, doy) {\n        var weeksTarget;\n        if (input == null) {\n            return weekOfYear(this, dow, doy).year;\n        } else {\n            weeksTarget = weeksInYear(input, dow, doy);\n            if (week > weeksTarget) {\n                week = weeksTarget;\n            }\n            return setWeekAll.call(this, input, week, weekday, dow, doy);\n        }\n    }\n\n    function setWeekAll(weekYear, week, weekday, dow, doy) {\n        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n        this.year(date.getUTCFullYear());\n        this.month(date.getUTCMonth());\n        this.date(date.getUTCDate());\n        return this;\n    }\n\n    // FORMATTING\n\n    addFormatToken('Q', 0, 'Qo', 'quarter');\n\n    // ALIASES\n\n    addUnitAlias('quarter', 'Q');\n\n    // PRIORITY\n\n    addUnitPriority('quarter', 7);\n\n    // PARSING\n\n    addRegexToken('Q', match1);\n    addParseToken('Q', function (input, array) {\n        array[MONTH] = (toInt(input) - 1) * 3;\n    });\n\n    // MOMENTS\n\n    function getSetQuarter (input) {\n        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n    }\n\n    // FORMATTING\n\n    addFormatToken('D', ['DD', 2], 'Do', 'date');\n\n    // ALIASES\n\n    addUnitAlias('date', 'D');\n\n    // PRIORITY\n    addUnitPriority('date', 9);\n\n    // PARSING\n\n    addRegexToken('D',  match1to2);\n    addRegexToken('DD', match1to2, match2);\n    addRegexToken('Do', function (isStrict, locale) {\n        // TODO: Remove \"ordinalParse\" fallback in next major release.\n        return isStrict ?\n          (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n          locale._dayOfMonthOrdinalParseLenient;\n    });\n\n    addParseToken(['D', 'DD'], DATE);\n    addParseToken('Do', function (input, array) {\n        array[DATE] = toInt(input.match(match1to2)[0]);\n    });\n\n    // MOMENTS\n\n    var getSetDayOfMonth = makeGetSet('Date', true);\n\n    // FORMATTING\n\n    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n    // ALIASES\n\n    addUnitAlias('dayOfYear', 'DDD');\n\n    // PRIORITY\n    addUnitPriority('dayOfYear', 4);\n\n    // PARSING\n\n    addRegexToken('DDD',  match1to3);\n    addRegexToken('DDDD', match3);\n    addParseToken(['DDD', 'DDDD'], function (input, array, config) {\n        config._dayOfYear = toInt(input);\n    });\n\n    // HELPERS\n\n    // MOMENTS\n\n    function getSetDayOfYear (input) {\n        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n    }\n\n    // FORMATTING\n\n    addFormatToken('m', ['mm', 2], 0, 'minute');\n\n    // ALIASES\n\n    addUnitAlias('minute', 'm');\n\n    // PRIORITY\n\n    addUnitPriority('minute', 14);\n\n    // PARSING\n\n    addRegexToken('m',  match1to2);\n    addRegexToken('mm', match1to2, match2);\n    addParseToken(['m', 'mm'], MINUTE);\n\n    // MOMENTS\n\n    var getSetMinute = makeGetSet('Minutes', false);\n\n    // FORMATTING\n\n    addFormatToken('s', ['ss', 2], 0, 'second');\n\n    // ALIASES\n\n    addUnitAlias('second', 's');\n\n    // PRIORITY\n\n    addUnitPriority('second', 15);\n\n    // PARSING\n\n    addRegexToken('s',  match1to2);\n    addRegexToken('ss', match1to2, match2);\n    addParseToken(['s', 'ss'], SECOND);\n\n    // MOMENTS\n\n    var getSetSecond = makeGetSet('Seconds', false);\n\n    // FORMATTING\n\n    addFormatToken('S', 0, 0, function () {\n        return ~~(this.millisecond() / 100);\n    });\n\n    addFormatToken(0, ['SS', 2], 0, function () {\n        return ~~(this.millisecond() / 10);\n    });\n\n    addFormatToken(0, ['SSS', 3], 0, 'millisecond');\n    addFormatToken(0, ['SSSS', 4], 0, function () {\n        return this.millisecond() * 10;\n    });\n    addFormatToken(0, ['SSSSS', 5], 0, function () {\n        return this.millisecond() * 100;\n    });\n    addFormatToken(0, ['SSSSSS', 6], 0, function () {\n        return this.millisecond() * 1000;\n    });\n    addFormatToken(0, ['SSSSSSS', 7], 0, function () {\n        return this.millisecond() * 10000;\n    });\n    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n        return this.millisecond() * 100000;\n    });\n    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n        return this.millisecond() * 1000000;\n    });\n\n\n    // ALIASES\n\n    addUnitAlias('millisecond', 'ms');\n\n    // PRIORITY\n\n    addUnitPriority('millisecond', 16);\n\n    // PARSING\n\n    addRegexToken('S',    match1to3, match1);\n    addRegexToken('SS',   match1to3, match2);\n    addRegexToken('SSS',  match1to3, match3);\n\n    var token;\n    for (token = 'SSSS'; token.length <= 9; token += 'S') {\n        addRegexToken(token, matchUnsigned);\n    }\n\n    function parseMs(input, array) {\n        array[MILLISECOND] = toInt(('0.' + input) * 1000);\n    }\n\n    for (token = 'S'; token.length <= 9; token += 'S') {\n        addParseToken(token, parseMs);\n    }\n    // MOMENTS\n\n    var getSetMillisecond = makeGetSet('Milliseconds', false);\n\n    // FORMATTING\n\n    addFormatToken('z',  0, 0, 'zoneAbbr');\n    addFormatToken('zz', 0, 0, 'zoneName');\n\n    // MOMENTS\n\n    function getZoneAbbr () {\n        return this._isUTC ? 'UTC' : '';\n    }\n\n    function getZoneName () {\n        return this._isUTC ? 'Coordinated Universal Time' : '';\n    }\n\n    var proto = Moment.prototype;\n\n    proto.add               = add;\n    proto.calendar          = calendar$1;\n    proto.clone             = clone;\n    proto.diff              = diff;\n    proto.endOf             = endOf;\n    proto.format            = format;\n    proto.from              = from;\n    proto.fromNow           = fromNow;\n    proto.to                = to;\n    proto.toNow             = toNow;\n    proto.get               = stringGet;\n    proto.invalidAt         = invalidAt;\n    proto.isAfter           = isAfter;\n    proto.isBefore          = isBefore;\n    proto.isBetween         = isBetween;\n    proto.isSame            = isSame;\n    proto.isSameOrAfter     = isSameOrAfter;\n    proto.isSameOrBefore    = isSameOrBefore;\n    proto.isValid           = isValid$2;\n    proto.lang              = lang;\n    proto.locale            = locale;\n    proto.localeData        = localeData;\n    proto.max               = prototypeMax;\n    proto.min               = prototypeMin;\n    proto.parsingFlags      = parsingFlags;\n    proto.set               = stringSet;\n    proto.startOf           = startOf;\n    proto.subtract          = subtract;\n    proto.toArray           = toArray;\n    proto.toObject          = toObject;\n    proto.toDate            = toDate;\n    proto.toISOString       = toISOString;\n    proto.inspect           = inspect;\n    proto.toJSON            = toJSON;\n    proto.toString          = toString;\n    proto.unix              = unix;\n    proto.valueOf           = valueOf;\n    proto.creationData      = creationData;\n    proto.year       = getSetYear;\n    proto.isLeapYear = getIsLeapYear;\n    proto.weekYear    = getSetWeekYear;\n    proto.isoWeekYear = getSetISOWeekYear;\n    proto.quarter = proto.quarters = getSetQuarter;\n    proto.month       = getSetMonth;\n    proto.daysInMonth = getDaysInMonth;\n    proto.week           = proto.weeks        = getSetWeek;\n    proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\n    proto.weeksInYear    = getWeeksInYear;\n    proto.isoWeeksInYear = getISOWeeksInYear;\n    proto.date       = getSetDayOfMonth;\n    proto.day        = proto.days             = getSetDayOfWeek;\n    proto.weekday    = getSetLocaleDayOfWeek;\n    proto.isoWeekday = getSetISODayOfWeek;\n    proto.dayOfYear  = getSetDayOfYear;\n    proto.hour = proto.hours = getSetHour;\n    proto.minute = proto.minutes = getSetMinute;\n    proto.second = proto.seconds = getSetSecond;\n    proto.millisecond = proto.milliseconds = getSetMillisecond;\n    proto.utcOffset            = getSetOffset;\n    proto.utc                  = setOffsetToUTC;\n    proto.local                = setOffsetToLocal;\n    proto.parseZone            = setOffsetToParsedOffset;\n    proto.hasAlignedHourOffset = hasAlignedHourOffset;\n    proto.isDST                = isDaylightSavingTime;\n    proto.isLocal              = isLocal;\n    proto.isUtcOffset          = isUtcOffset;\n    proto.isUtc                = isUtc;\n    proto.isUTC                = isUtc;\n    proto.zoneAbbr = getZoneAbbr;\n    proto.zoneName = getZoneName;\n    proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\n    proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\n    proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\n    proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\n    proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\n    function createUnix (input) {\n        return createLocal(input * 1000);\n    }\n\n    function createInZone () {\n        return createLocal.apply(null, arguments).parseZone();\n    }\n\n    function preParsePostFormat (string) {\n        return string;\n    }\n\n    var proto$1 = Locale.prototype;\n\n    proto$1.calendar        = calendar;\n    proto$1.longDateFormat  = longDateFormat;\n    proto$1.invalidDate     = invalidDate;\n    proto$1.ordinal         = ordinal;\n    proto$1.preparse        = preParsePostFormat;\n    proto$1.postformat      = preParsePostFormat;\n    proto$1.relativeTime    = relativeTime;\n    proto$1.pastFuture      = pastFuture;\n    proto$1.set             = set;\n\n    proto$1.months            =        localeMonths;\n    proto$1.monthsShort       =        localeMonthsShort;\n    proto$1.monthsParse       =        localeMonthsParse;\n    proto$1.monthsRegex       = monthsRegex;\n    proto$1.monthsShortRegex  = monthsShortRegex;\n    proto$1.week = localeWeek;\n    proto$1.firstDayOfYear = localeFirstDayOfYear;\n    proto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n    proto$1.weekdays       =        localeWeekdays;\n    proto$1.weekdaysMin    =        localeWeekdaysMin;\n    proto$1.weekdaysShort  =        localeWeekdaysShort;\n    proto$1.weekdaysParse  =        localeWeekdaysParse;\n\n    proto$1.weekdaysRegex       =        weekdaysRegex;\n    proto$1.weekdaysShortRegex  =        weekdaysShortRegex;\n    proto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n    proto$1.isPM = localeIsPM;\n    proto$1.meridiem = localeMeridiem;\n\n    function get$1 (format, index, field, setter) {\n        var locale = getLocale();\n        var utc = createUTC().set(setter, index);\n        return locale[field](utc, format);\n    }\n\n    function listMonthsImpl (format, index, field) {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n\n        if (index != null) {\n            return get$1(format, index, field, 'month');\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < 12; i++) {\n            out[i] = get$1(format, i, field, 'month');\n        }\n        return out;\n    }\n\n    // ()\n    // (5)\n    // (fmt, 5)\n    // (fmt)\n    // (true)\n    // (true, 5)\n    // (true, fmt, 5)\n    // (true, fmt)\n    function listWeekdaysImpl (localeSorted, format, index, field) {\n        if (typeof localeSorted === 'boolean') {\n            if (isNumber(format)) {\n                index = format;\n                format = undefined;\n            }\n\n            format = format || '';\n        } else {\n            format = localeSorted;\n            index = format;\n            localeSorted = false;\n\n            if (isNumber(format)) {\n                index = format;\n                format = undefined;\n            }\n\n            format = format || '';\n        }\n\n        var locale = getLocale(),\n            shift = localeSorted ? locale._week.dow : 0;\n\n        if (index != null) {\n            return get$1(format, (index + shift) % 7, field, 'day');\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < 7; i++) {\n            out[i] = get$1(format, (i + shift) % 7, field, 'day');\n        }\n        return out;\n    }\n\n    function listMonths (format, index) {\n        return listMonthsImpl(format, index, 'months');\n    }\n\n    function listMonthsShort (format, index) {\n        return listMonthsImpl(format, index, 'monthsShort');\n    }\n\n    function listWeekdays (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n    }\n\n    function listWeekdaysShort (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n    }\n\n    function listWeekdaysMin (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n    }\n\n    getSetGlobalLocale('en', {\n        dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (toInt(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    // Side effect imports\n\n    hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\n    hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\n    var mathAbs = Math.abs;\n\n    function abs () {\n        var data           = this._data;\n\n        this._milliseconds = mathAbs(this._milliseconds);\n        this._days         = mathAbs(this._days);\n        this._months       = mathAbs(this._months);\n\n        data.milliseconds  = mathAbs(data.milliseconds);\n        data.seconds       = mathAbs(data.seconds);\n        data.minutes       = mathAbs(data.minutes);\n        data.hours         = mathAbs(data.hours);\n        data.months        = mathAbs(data.months);\n        data.years         = mathAbs(data.years);\n\n        return this;\n    }\n\n    function addSubtract$1 (duration, input, value, direction) {\n        var other = createDuration(input, value);\n\n        duration._milliseconds += direction * other._milliseconds;\n        duration._days         += direction * other._days;\n        duration._months       += direction * other._months;\n\n        return duration._bubble();\n    }\n\n    // supports only 2.0-style add(1, 's') or add(duration)\n    function add$1 (input, value) {\n        return addSubtract$1(this, input, value, 1);\n    }\n\n    // supports only 2.0-style subtract(1, 's') or subtract(duration)\n    function subtract$1 (input, value) {\n        return addSubtract$1(this, input, value, -1);\n    }\n\n    function absCeil (number) {\n        if (number < 0) {\n            return Math.floor(number);\n        } else {\n            return Math.ceil(number);\n        }\n    }\n\n    function bubble () {\n        var milliseconds = this._milliseconds;\n        var days         = this._days;\n        var months       = this._months;\n        var data         = this._data;\n        var seconds, minutes, hours, years, monthsFromDays;\n\n        // if we have a mix of positive and negative values, bubble down first\n        // check: https://github.com/moment/moment/issues/2166\n        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n                (milliseconds <= 0 && days <= 0 && months <= 0))) {\n            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n            days = 0;\n            months = 0;\n        }\n\n        // The following code bubbles up values, see the tests for\n        // examples of what that means.\n        data.milliseconds = milliseconds % 1000;\n\n        seconds           = absFloor(milliseconds / 1000);\n        data.seconds      = seconds % 60;\n\n        minutes           = absFloor(seconds / 60);\n        data.minutes      = minutes % 60;\n\n        hours             = absFloor(minutes / 60);\n        data.hours        = hours % 24;\n\n        days += absFloor(hours / 24);\n\n        // convert days to months\n        monthsFromDays = absFloor(daysToMonths(days));\n        months += monthsFromDays;\n        days -= absCeil(monthsToDays(monthsFromDays));\n\n        // 12 months -> 1 year\n        years = absFloor(months / 12);\n        months %= 12;\n\n        data.days   = days;\n        data.months = months;\n        data.years  = years;\n\n        return this;\n    }\n\n    function daysToMonths (days) {\n        // 400 years have 146097 days (taking into account leap year rules)\n        // 400 years have 12 months === 4800\n        return days * 4800 / 146097;\n    }\n\n    function monthsToDays (months) {\n        // the reverse of daysToMonths\n        return months * 146097 / 4800;\n    }\n\n    function as (units) {\n        if (!this.isValid()) {\n            return NaN;\n        }\n        var days;\n        var months;\n        var milliseconds = this._milliseconds;\n\n        units = normalizeUnits(units);\n\n        if (units === 'month' || units === 'quarter' || units === 'year') {\n            days = this._days + milliseconds / 864e5;\n            months = this._months + daysToMonths(days);\n            switch (units) {\n                case 'month':   return months;\n                case 'quarter': return months / 3;\n                case 'year':    return months / 12;\n            }\n        } else {\n            // handle milliseconds separately because of floating point math errors (issue #1867)\n            days = this._days + Math.round(monthsToDays(this._months));\n            switch (units) {\n                case 'week'   : return days / 7     + milliseconds / 6048e5;\n                case 'day'    : return days         + milliseconds / 864e5;\n                case 'hour'   : return days * 24    + milliseconds / 36e5;\n                case 'minute' : return days * 1440  + milliseconds / 6e4;\n                case 'second' : return days * 86400 + milliseconds / 1000;\n                // Math.floor prevents floating point math errors here\n                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n                default: throw new Error('Unknown unit ' + units);\n            }\n        }\n    }\n\n    // TODO: Use this.as('ms')?\n    function valueOf$1 () {\n        if (!this.isValid()) {\n            return NaN;\n        }\n        return (\n            this._milliseconds +\n            this._days * 864e5 +\n            (this._months % 12) * 2592e6 +\n            toInt(this._months / 12) * 31536e6\n        );\n    }\n\n    function makeAs (alias) {\n        return function () {\n            return this.as(alias);\n        };\n    }\n\n    var asMilliseconds = makeAs('ms');\n    var asSeconds      = makeAs('s');\n    var asMinutes      = makeAs('m');\n    var asHours        = makeAs('h');\n    var asDays         = makeAs('d');\n    var asWeeks        = makeAs('w');\n    var asMonths       = makeAs('M');\n    var asQuarters     = makeAs('Q');\n    var asYears        = makeAs('y');\n\n    function clone$1 () {\n        return createDuration(this);\n    }\n\n    function get$2 (units) {\n        units = normalizeUnits(units);\n        return this.isValid() ? this[units + 's']() : NaN;\n    }\n\n    function makeGetter(name) {\n        return function () {\n            return this.isValid() ? this._data[name] : NaN;\n        };\n    }\n\n    var milliseconds = makeGetter('milliseconds');\n    var seconds      = makeGetter('seconds');\n    var minutes      = makeGetter('minutes');\n    var hours        = makeGetter('hours');\n    var days         = makeGetter('days');\n    var months       = makeGetter('months');\n    var years        = makeGetter('years');\n\n    function weeks () {\n        return absFloor(this.days() / 7);\n    }\n\n    var round = Math.round;\n    var thresholds = {\n        ss: 44,         // a few seconds to seconds\n        s : 45,         // seconds to minute\n        m : 45,         // minutes to hour\n        h : 22,         // hours to day\n        d : 26,         // days to month\n        M : 11          // months to year\n    };\n\n    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\n    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n    }\n\n    function relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n        var duration = createDuration(posNegDuration).abs();\n        var seconds  = round(duration.as('s'));\n        var minutes  = round(duration.as('m'));\n        var hours    = round(duration.as('h'));\n        var days     = round(duration.as('d'));\n        var months   = round(duration.as('M'));\n        var years    = round(duration.as('y'));\n\n        var a = seconds <= thresholds.ss && ['s', seconds]  ||\n                seconds < thresholds.s   && ['ss', seconds] ||\n                minutes <= 1             && ['m']           ||\n                minutes < thresholds.m   && ['mm', minutes] ||\n                hours   <= 1             && ['h']           ||\n                hours   < thresholds.h   && ['hh', hours]   ||\n                days    <= 1             && ['d']           ||\n                days    < thresholds.d   && ['dd', days]    ||\n                months  <= 1             && ['M']           ||\n                months  < thresholds.M   && ['MM', months]  ||\n                years   <= 1             && ['y']           || ['yy', years];\n\n        a[2] = withoutSuffix;\n        a[3] = +posNegDuration > 0;\n        a[4] = locale;\n        return substituteTimeAgo.apply(null, a);\n    }\n\n    // This function allows you to set the rounding function for relative time strings\n    function getSetRelativeTimeRounding (roundingFunction) {\n        if (roundingFunction === undefined) {\n            return round;\n        }\n        if (typeof(roundingFunction) === 'function') {\n            round = roundingFunction;\n            return true;\n        }\n        return false;\n    }\n\n    // This function allows you to set a threshold for relative time strings\n    function getSetRelativeTimeThreshold (threshold, limit) {\n        if (thresholds[threshold] === undefined) {\n            return false;\n        }\n        if (limit === undefined) {\n            return thresholds[threshold];\n        }\n        thresholds[threshold] = limit;\n        if (threshold === 's') {\n            thresholds.ss = limit - 1;\n        }\n        return true;\n    }\n\n    function humanize (withSuffix) {\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n\n        var locale = this.localeData();\n        var output = relativeTime$1(this, !withSuffix, locale);\n\n        if (withSuffix) {\n            output = locale.pastFuture(+this, output);\n        }\n\n        return locale.postformat(output);\n    }\n\n    var abs$1 = Math.abs;\n\n    function sign(x) {\n        return ((x > 0) - (x < 0)) || +x;\n    }\n\n    function toISOString$1() {\n        // for ISO strings we do not use the normal bubbling rules:\n        //  * milliseconds bubble up until they become hours\n        //  * days do not bubble at all\n        //  * months bubble up until they become years\n        // This is because there is no context-free conversion between hours and days\n        // (think of clock changes)\n        // and also not between days and months (28-31 days per month)\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n\n        var seconds = abs$1(this._milliseconds) / 1000;\n        var days         = abs$1(this._days);\n        var months       = abs$1(this._months);\n        var minutes, hours, years;\n\n        // 3600 seconds -> 60 minutes -> 1 hour\n        minutes           = absFloor(seconds / 60);\n        hours             = absFloor(minutes / 60);\n        seconds %= 60;\n        minutes %= 60;\n\n        // 12 months -> 1 year\n        years  = absFloor(months / 12);\n        months %= 12;\n\n\n        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n        var Y = years;\n        var M = months;\n        var D = days;\n        var h = hours;\n        var m = minutes;\n        var s = seconds ? seconds.toFixed(3).replace(/\\.?0+$/, '') : '';\n        var total = this.asSeconds();\n\n        if (!total) {\n            // this is the same as C#'s (Noda) and python (isodate)...\n            // but not other JS (goog.date)\n            return 'P0D';\n        }\n\n        var totalSign = total < 0 ? '-' : '';\n        var ymSign = sign(this._months) !== sign(total) ? '-' : '';\n        var daysSign = sign(this._days) !== sign(total) ? '-' : '';\n        var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';\n\n        return totalSign + 'P' +\n            (Y ? ymSign + Y + 'Y' : '') +\n            (M ? ymSign + M + 'M' : '') +\n            (D ? daysSign + D + 'D' : '') +\n            ((h || m || s) ? 'T' : '') +\n            (h ? hmsSign + h + 'H' : '') +\n            (m ? hmsSign + m + 'M' : '') +\n            (s ? hmsSign + s + 'S' : '');\n    }\n\n    var proto$2 = Duration.prototype;\n\n    proto$2.isValid        = isValid$1;\n    proto$2.abs            = abs;\n    proto$2.add            = add$1;\n    proto$2.subtract       = subtract$1;\n    proto$2.as             = as;\n    proto$2.asMilliseconds = asMilliseconds;\n    proto$2.asSeconds      = asSeconds;\n    proto$2.asMinutes      = asMinutes;\n    proto$2.asHours        = asHours;\n    proto$2.asDays         = asDays;\n    proto$2.asWeeks        = asWeeks;\n    proto$2.asMonths       = asMonths;\n    proto$2.asQuarters     = asQuarters;\n    proto$2.asYears        = asYears;\n    proto$2.valueOf        = valueOf$1;\n    proto$2._bubble        = bubble;\n    proto$2.clone          = clone$1;\n    proto$2.get            = get$2;\n    proto$2.milliseconds   = milliseconds;\n    proto$2.seconds        = seconds;\n    proto$2.minutes        = minutes;\n    proto$2.hours          = hours;\n    proto$2.days           = days;\n    proto$2.weeks          = weeks;\n    proto$2.months         = months;\n    proto$2.years          = years;\n    proto$2.humanize       = humanize;\n    proto$2.toISOString    = toISOString$1;\n    proto$2.toString       = toISOString$1;\n    proto$2.toJSON         = toISOString$1;\n    proto$2.locale         = locale;\n    proto$2.localeData     = localeData;\n\n    proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\n    proto$2.lang = lang;\n\n    // Side effect imports\n\n    // FORMATTING\n\n    addFormatToken('X', 0, 0, 'unix');\n    addFormatToken('x', 0, 0, 'valueOf');\n\n    // PARSING\n\n    addRegexToken('x', matchSigned);\n    addRegexToken('X', matchTimestamp);\n    addParseToken('X', function (input, array, config) {\n        config._d = new Date(parseFloat(input, 10) * 1000);\n    });\n    addParseToken('x', function (input, array, config) {\n        config._d = new Date(toInt(input));\n    });\n\n    // Side effect imports\n\n\n    hooks.version = '2.24.0';\n\n    setHookCallback(createLocal);\n\n    hooks.fn                    = proto;\n    hooks.min                   = min;\n    hooks.max                   = max;\n    hooks.now                   = now;\n    hooks.utc                   = createUTC;\n    hooks.unix                  = createUnix;\n    hooks.months                = listMonths;\n    hooks.isDate                = isDate;\n    hooks.locale                = getSetGlobalLocale;\n    hooks.invalid               = createInvalid;\n    hooks.duration              = createDuration;\n    hooks.isMoment              = isMoment;\n    hooks.weekdays              = listWeekdays;\n    hooks.parseZone             = createInZone;\n    hooks.localeData            = getLocale;\n    hooks.isDuration            = isDuration;\n    hooks.monthsShort           = listMonthsShort;\n    hooks.weekdaysMin           = listWeekdaysMin;\n    hooks.defineLocale          = defineLocale;\n    hooks.updateLocale          = updateLocale;\n    hooks.locales               = listLocales;\n    hooks.weekdaysShort         = listWeekdaysShort;\n    hooks.normalizeUnits        = normalizeUnits;\n    hooks.relativeTimeRounding  = getSetRelativeTimeRounding;\n    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\n    hooks.calendarFormat        = getCalendarFormat;\n    hooks.prototype             = proto;\n\n    // currently HTML5 input type only supports 24-hour formats\n    hooks.HTML5_FMT = {\n        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type=\"datetime-local\" />\n        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type=\"datetime-local\" step=\"1\" />\n        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type=\"datetime-local\" step=\"0.001\" />\n        DATE: 'YYYY-MM-DD',                             // <input type=\"date\" />\n        TIME: 'HH:mm',                                  // <input type=\"time\" />\n        TIME_SECONDS: 'HH:mm:ss',                       // <input type=\"time\" step=\"1\" />\n        TIME_MS: 'HH:mm:ss.SSS',                        // <input type=\"time\" step=\"0.001\" />\n        WEEK: 'GGGG-[W]WW',                             // <input type=\"week\" />\n        MONTH: 'YYYY-MM'                                // <input type=\"month\" />\n    };\n\n    return hooks;\n\n})));\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/module.js */ \"f586\")(module)))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGEwMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9tb21lbnQvbW9tZW50LmpzP2MxZGYiXSwic291cmNlc0NvbnRlbnQiOlsiLy8hIG1vbWVudC5qc1xuXG47KGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG4gICAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgICBnbG9iYWwubW9tZW50ID0gZmFjdG9yeSgpXG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuICAgIHZhciBob29rQ2FsbGJhY2s7XG5cbiAgICBmdW5jdGlvbiBob29rcyAoKSB7XG4gICAgICAgIHJldHVybiBob29rQ2FsbGJhY2suYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGlzIGRvbmUgdG8gcmVnaXN0ZXIgdGhlIG1ldGhvZCBjYWxsZWQgd2l0aCBtb21lbnQoKVxuICAgIC8vIHdpdGhvdXQgY3JlYXRpbmcgY2lyY3VsYXIgZGVwZW5kZW5jaWVzLlxuICAgIGZ1bmN0aW9uIHNldEhvb2tDYWxsYmFjayAoY2FsbGJhY2spIHtcbiAgICAgICAgaG9va0NhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBcnJheShpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXQgaW5zdGFuY2VvZiBBcnJheSB8fCBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaW5wdXQpID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzT2JqZWN0KGlucHV0KSB7XG4gICAgICAgIC8vIElFOCB3aWxsIHRyZWF0IHVuZGVmaW5lZCBhbmQgbnVsbCBhcyBvYmplY3QgaWYgaXQgd2Fzbid0IGZvclxuICAgICAgICAvLyBpbnB1dCAhPSBudWxsXG4gICAgICAgIHJldHVybiBpbnB1dCAhPSBudWxsICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IE9iamVjdF0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzT2JqZWN0RW1wdHkob2JqKSB7XG4gICAgICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcykge1xuICAgICAgICAgICAgcmV0dXJuIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCA9PT0gMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaztcbiAgICAgICAgICAgIGZvciAoayBpbiBvYmopIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVW5kZWZpbmVkKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBpbnB1dCA9PT0gdm9pZCAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzTnVtYmVyKGlucHV0KSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IE51bWJlcl0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzRGF0ZShpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXQgaW5zdGFuY2VvZiBEYXRlIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IERhdGVdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXAoYXJyLCBmbikge1xuICAgICAgICB2YXIgcmVzID0gW10sIGk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHJlcy5wdXNoKGZuKGFycltpXSwgaSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzT3duUHJvcChhLCBiKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSwgYik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXh0ZW5kKGEsIGIpIHtcbiAgICAgICAgZm9yICh2YXIgaSBpbiBiKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChiLCBpKSkge1xuICAgICAgICAgICAgICAgIGFbaV0gPSBiW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc093blByb3AoYiwgJ3RvU3RyaW5nJykpIHtcbiAgICAgICAgICAgIGEudG9TdHJpbmcgPSBiLnRvU3RyaW5nO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc093blByb3AoYiwgJ3ZhbHVlT2YnKSkge1xuICAgICAgICAgICAgYS52YWx1ZU9mID0gYi52YWx1ZU9mO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlVVRDIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWxPclVUQyhpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCwgdHJ1ZSkudXRjKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmYXVsdFBhcnNpbmdGbGFncygpIHtcbiAgICAgICAgLy8gV2UgbmVlZCB0byBkZWVwIGNsb25lIHRoaXMgb2JqZWN0LlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZW1wdHkgICAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICB1bnVzZWRUb2tlbnMgICAgOiBbXSxcbiAgICAgICAgICAgIHVudXNlZElucHV0ICAgICA6IFtdLFxuICAgICAgICAgICAgb3ZlcmZsb3cgICAgICAgIDogLTIsXG4gICAgICAgICAgICBjaGFyc0xlZnRPdmVyICAgOiAwLFxuICAgICAgICAgICAgbnVsbElucHV0ICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICBpbnZhbGlkTW9udGggICAgOiBudWxsLFxuICAgICAgICAgICAgaW52YWxpZEZvcm1hdCAgIDogZmFsc2UsXG4gICAgICAgICAgICB1c2VySW52YWxpZGF0ZWQgOiBmYWxzZSxcbiAgICAgICAgICAgIGlzbyAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICAgICAgcGFyc2VkRGF0ZVBhcnRzIDogW10sXG4gICAgICAgICAgICBtZXJpZGllbSAgICAgICAgOiBudWxsLFxuICAgICAgICAgICAgcmZjMjgyMiAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICB3ZWVrZGF5TWlzbWF0Y2ggOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFBhcnNpbmdGbGFncyhtKSB7XG4gICAgICAgIGlmIChtLl9wZiA9PSBudWxsKSB7XG4gICAgICAgICAgICBtLl9wZiA9IGRlZmF1bHRQYXJzaW5nRmxhZ3MoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbS5fcGY7XG4gICAgfVxuXG4gICAgdmFyIHNvbWU7XG4gICAgaWYgKEFycmF5LnByb3RvdHlwZS5zb21lKSB7XG4gICAgICAgIHNvbWUgPSBBcnJheS5wcm90b3R5cGUuc29tZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBzb21lID0gZnVuY3Rpb24gKGZ1bikge1xuICAgICAgICAgICAgdmFyIHQgPSBPYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgbGVuID0gdC5sZW5ndGggPj4+IDA7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiB0ICYmIGZ1bi5jYWxsKHRoaXMsIHRbaV0sIGksIHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVmFsaWQobSkge1xuICAgICAgICBpZiAobS5faXNWYWxpZCA9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgZmxhZ3MgPSBnZXRQYXJzaW5nRmxhZ3MobSk7XG4gICAgICAgICAgICB2YXIgcGFyc2VkUGFydHMgPSBzb21lLmNhbGwoZmxhZ3MucGFyc2VkRGF0ZVBhcnRzLCBmdW5jdGlvbiAoaSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpICE9IG51bGw7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhciBpc05vd1ZhbGlkID0gIWlzTmFOKG0uX2QuZ2V0VGltZSgpKSAmJlxuICAgICAgICAgICAgICAgIGZsYWdzLm92ZXJmbG93IDwgMCAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5lbXB0eSAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5pbnZhbGlkTW9udGggJiZcbiAgICAgICAgICAgICAgICAhZmxhZ3MuaW52YWxpZFdlZWtkYXkgJiZcbiAgICAgICAgICAgICAgICAhZmxhZ3Mud2Vla2RheU1pc21hdGNoICYmXG4gICAgICAgICAgICAgICAgIWZsYWdzLm51bGxJbnB1dCAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5pbnZhbGlkRm9ybWF0ICYmXG4gICAgICAgICAgICAgICAgIWZsYWdzLnVzZXJJbnZhbGlkYXRlZCAmJlxuICAgICAgICAgICAgICAgICghZmxhZ3MubWVyaWRpZW0gfHwgKGZsYWdzLm1lcmlkaWVtICYmIHBhcnNlZFBhcnRzKSk7XG5cbiAgICAgICAgICAgIGlmIChtLl9zdHJpY3QpIHtcbiAgICAgICAgICAgICAgICBpc05vd1ZhbGlkID0gaXNOb3dWYWxpZCAmJlxuICAgICAgICAgICAgICAgICAgICBmbGFncy5jaGFyc0xlZnRPdmVyID09PSAwICYmXG4gICAgICAgICAgICAgICAgICAgIGZsYWdzLnVudXNlZFRva2Vucy5sZW5ndGggPT09IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgZmxhZ3MuYmlnSG91ciA9PT0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoT2JqZWN0LmlzRnJvemVuID09IG51bGwgfHwgIU9iamVjdC5pc0Zyb3plbihtKSkge1xuICAgICAgICAgICAgICAgIG0uX2lzVmFsaWQgPSBpc05vd1ZhbGlkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzTm93VmFsaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG0uX2lzVmFsaWQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlSW52YWxpZCAoZmxhZ3MpIHtcbiAgICAgICAgdmFyIG0gPSBjcmVhdGVVVEMoTmFOKTtcbiAgICAgICAgaWYgKGZsYWdzICE9IG51bGwpIHtcbiAgICAgICAgICAgIGV4dGVuZChnZXRQYXJzaW5nRmxhZ3MobSksIGZsYWdzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhtKS51c2VySW52YWxpZGF0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG07XG4gICAgfVxuXG4gICAgLy8gUGx1Z2lucyB0aGF0IGFkZCBwcm9wZXJ0aWVzIHNob3VsZCBhbHNvIGFkZCB0aGUga2V5IGhlcmUgKG51bGwgdmFsdWUpLFxuICAgIC8vIHNvIHdlIGNhbiBwcm9wZXJseSBjbG9uZSBvdXJzZWx2ZXMuXG4gICAgdmFyIG1vbWVudFByb3BlcnRpZXMgPSBob29rcy5tb21lbnRQcm9wZXJ0aWVzID0gW107XG5cbiAgICBmdW5jdGlvbiBjb3B5Q29uZmlnKHRvLCBmcm9tKSB7XG4gICAgICAgIHZhciBpLCBwcm9wLCB2YWw7XG5cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9pc0FNb21lbnRPYmplY3QpKSB7XG4gICAgICAgICAgICB0by5faXNBTW9tZW50T2JqZWN0ID0gZnJvbS5faXNBTW9tZW50T2JqZWN0O1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5faSkpIHtcbiAgICAgICAgICAgIHRvLl9pID0gZnJvbS5faTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX2YpKSB7XG4gICAgICAgICAgICB0by5fZiA9IGZyb20uX2Y7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9sKSkge1xuICAgICAgICAgICAgdG8uX2wgPSBmcm9tLl9sO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fc3RyaWN0KSkge1xuICAgICAgICAgICAgdG8uX3N0cmljdCA9IGZyb20uX3N0cmljdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX3R6bSkpIHtcbiAgICAgICAgICAgIHRvLl90em0gPSBmcm9tLl90em07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9pc1VUQykpIHtcbiAgICAgICAgICAgIHRvLl9pc1VUQyA9IGZyb20uX2lzVVRDO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fb2Zmc2V0KSkge1xuICAgICAgICAgICAgdG8uX29mZnNldCA9IGZyb20uX29mZnNldDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX3BmKSkge1xuICAgICAgICAgICAgdG8uX3BmID0gZ2V0UGFyc2luZ0ZsYWdzKGZyb20pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fbG9jYWxlKSkge1xuICAgICAgICAgICAgdG8uX2xvY2FsZSA9IGZyb20uX2xvY2FsZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtb21lbnRQcm9wZXJ0aWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBtb21lbnRQcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcHJvcCA9IG1vbWVudFByb3BlcnRpZXNbaV07XG4gICAgICAgICAgICAgICAgdmFsID0gZnJvbVtwcm9wXTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKHZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9bcHJvcF0gPSB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRvO1xuICAgIH1cblxuICAgIHZhciB1cGRhdGVJblByb2dyZXNzID0gZmFsc2U7XG5cbiAgICAvLyBNb21lbnQgcHJvdG90eXBlIG9iamVjdFxuICAgIGZ1bmN0aW9uIE1vbWVudChjb25maWcpIHtcbiAgICAgICAgY29weUNvbmZpZyh0aGlzLCBjb25maWcpO1xuICAgICAgICB0aGlzLl9kID0gbmV3IERhdGUoY29uZmlnLl9kICE9IG51bGwgPyBjb25maWcuX2QuZ2V0VGltZSgpIDogTmFOKTtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgdGhpcy5fZCA9IG5ldyBEYXRlKE5hTik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUHJldmVudCBpbmZpbml0ZSBsb29wIGluIGNhc2UgdXBkYXRlT2Zmc2V0IGNyZWF0ZXMgbmV3IG1vbWVudFxuICAgICAgICAvLyBvYmplY3RzLlxuICAgICAgICBpZiAodXBkYXRlSW5Qcm9ncmVzcyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHVwZGF0ZUluUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMpO1xuICAgICAgICAgICAgdXBkYXRlSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNNb21lbnQgKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgTW9tZW50IHx8IChvYmogIT0gbnVsbCAmJiBvYmouX2lzQU1vbWVudE9iamVjdCAhPSBudWxsKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhYnNGbG9vciAobnVtYmVyKSB7XG4gICAgICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICAgICAgICAvLyAtMCAtPiAwXG4gICAgICAgICAgICByZXR1cm4gTWF0aC5jZWlsKG51bWJlcikgfHwgMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKG51bWJlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0ludChhcmd1bWVudEZvckNvZXJjaW9uKSB7XG4gICAgICAgIHZhciBjb2VyY2VkTnVtYmVyID0gK2FyZ3VtZW50Rm9yQ29lcmNpb24sXG4gICAgICAgICAgICB2YWx1ZSA9IDA7XG5cbiAgICAgICAgaWYgKGNvZXJjZWROdW1iZXIgIT09IDAgJiYgaXNGaW5pdGUoY29lcmNlZE51bWJlcikpIHtcbiAgICAgICAgICAgIHZhbHVlID0gYWJzRmxvb3IoY29lcmNlZE51bWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gY29tcGFyZSB0d28gYXJyYXlzLCByZXR1cm4gdGhlIG51bWJlciBvZiBkaWZmZXJlbmNlc1xuICAgIGZ1bmN0aW9uIGNvbXBhcmVBcnJheXMoYXJyYXkxLCBhcnJheTIsIGRvbnRDb252ZXJ0KSB7XG4gICAgICAgIHZhciBsZW4gPSBNYXRoLm1pbihhcnJheTEubGVuZ3RoLCBhcnJheTIubGVuZ3RoKSxcbiAgICAgICAgICAgIGxlbmd0aERpZmYgPSBNYXRoLmFicyhhcnJheTEubGVuZ3RoIC0gYXJyYXkyLmxlbmd0aCksXG4gICAgICAgICAgICBkaWZmcyA9IDAsXG4gICAgICAgICAgICBpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmICgoZG9udENvbnZlcnQgJiYgYXJyYXkxW2ldICE9PSBhcnJheTJbaV0pIHx8XG4gICAgICAgICAgICAgICAgKCFkb250Q29udmVydCAmJiB0b0ludChhcnJheTFbaV0pICE9PSB0b0ludChhcnJheTJbaV0pKSkge1xuICAgICAgICAgICAgICAgIGRpZmZzKys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRpZmZzICsgbGVuZ3RoRGlmZjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3YXJuKG1zZykge1xuICAgICAgICBpZiAoaG9va3Muc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmdzID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICh0eXBlb2YgY29uc29sZSAhPT0gICd1bmRlZmluZWQnKSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRGVwcmVjYXRpb24gd2FybmluZzogJyArIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkZXByZWNhdGUobXNnLCBmbikge1xuICAgICAgICB2YXIgZmlyc3RUaW1lID0gdHJ1ZTtcblxuICAgICAgICByZXR1cm4gZXh0ZW5kKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChob29rcy5kZXByZWNhdGlvbkhhbmRsZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGhvb2tzLmRlcHJlY2F0aW9uSGFuZGxlcihudWxsLCBtc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZpcnN0VGltZSkge1xuICAgICAgICAgICAgICAgIHZhciBhcmdzID0gW107XG4gICAgICAgICAgICAgICAgdmFyIGFyZztcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBhcmcgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbaV0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgKz0gJ1xcblsnICsgaSArICddICc7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gYXJndW1lbnRzWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnICs9IGtleSArICc6ICcgKyBhcmd1bWVudHNbMF1ba2V5XSArICcsICc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBhcmcuc2xpY2UoMCwgLTIpOyAvLyBSZW1vdmUgdHJhaWxpbmcgY29tbWEgYW5kIHNwYWNlXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKGFyZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdhcm4obXNnICsgJ1xcbkFyZ3VtZW50czogJyArIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MpLmpvaW4oJycpICsgJ1xcbicgKyAobmV3IEVycm9yKCkpLnN0YWNrKTtcbiAgICAgICAgICAgICAgICBmaXJzdFRpbWUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9LCBmbik7XG4gICAgfVxuXG4gICAgdmFyIGRlcHJlY2F0aW9ucyA9IHt9O1xuXG4gICAgZnVuY3Rpb24gZGVwcmVjYXRlU2ltcGxlKG5hbWUsIG1zZykge1xuICAgICAgICBpZiAoaG9va3MuZGVwcmVjYXRpb25IYW5kbGVyICE9IG51bGwpIHtcbiAgICAgICAgICAgIGhvb2tzLmRlcHJlY2F0aW9uSGFuZGxlcihuYW1lLCBtc2cpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZGVwcmVjYXRpb25zW25hbWVdKSB7XG4gICAgICAgICAgICB3YXJuKG1zZyk7XG4gICAgICAgICAgICBkZXByZWNhdGlvbnNbbmFtZV0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaG9va3Muc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmdzID0gZmFsc2U7XG4gICAgaG9va3MuZGVwcmVjYXRpb25IYW5kbGVyID0gbnVsbDtcblxuICAgIGZ1bmN0aW9uIGlzRnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0IGluc3RhbmNlb2YgRnVuY3Rpb24gfHwgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGlucHV0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXQgKGNvbmZpZykge1xuICAgICAgICB2YXIgcHJvcCwgaTtcbiAgICAgICAgZm9yIChpIGluIGNvbmZpZykge1xuICAgICAgICAgICAgcHJvcCA9IGNvbmZpZ1tpXTtcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHByb3ApKSB7XG4gICAgICAgICAgICAgICAgdGhpc1tpXSA9IHByb3A7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXNbJ18nICsgaV0gPSBwcm9wO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgLy8gTGVuaWVudCBvcmRpbmFsIHBhcnNpbmcgYWNjZXB0cyBqdXN0IGEgbnVtYmVyIGluIGFkZGl0aW9uIHRvXG4gICAgICAgIC8vIG51bWJlciArIChwb3NzaWJseSkgc3R1ZmYgY29taW5nIGZyb20gX2RheU9mTW9udGhPcmRpbmFsUGFyc2UuXG4gICAgICAgIC8vIFRPRE86IFJlbW92ZSBcIm9yZGluYWxQYXJzZVwiIGZhbGxiYWNrIGluIG5leHQgbWFqb3IgcmVsZWFzZS5cbiAgICAgICAgdGhpcy5fZGF5T2ZNb250aE9yZGluYWxQYXJzZUxlbmllbnQgPSBuZXcgUmVnRXhwKFxuICAgICAgICAgICAgKHRoaXMuX2RheU9mTW9udGhPcmRpbmFsUGFyc2Uuc291cmNlIHx8IHRoaXMuX29yZGluYWxQYXJzZS5zb3VyY2UpICtcbiAgICAgICAgICAgICAgICAnfCcgKyAoL1xcZHsxLDJ9Lykuc291cmNlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtZXJnZUNvbmZpZ3MocGFyZW50Q29uZmlnLCBjaGlsZENvbmZpZykge1xuICAgICAgICB2YXIgcmVzID0gZXh0ZW5kKHt9LCBwYXJlbnRDb25maWcpLCBwcm9wO1xuICAgICAgICBmb3IgKHByb3AgaW4gY2hpbGRDb25maWcpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd25Qcm9wKGNoaWxkQ29uZmlnLCBwcm9wKSkge1xuICAgICAgICAgICAgICAgIGlmIChpc09iamVjdChwYXJlbnRDb25maWdbcHJvcF0pICYmIGlzT2JqZWN0KGNoaWxkQ29uZmlnW3Byb3BdKSkge1xuICAgICAgICAgICAgICAgICAgICByZXNbcHJvcF0gPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kKHJlc1twcm9wXSwgcGFyZW50Q29uZmlnW3Byb3BdKTtcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kKHJlc1twcm9wXSwgY2hpbGRDb25maWdbcHJvcF0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hpbGRDb25maWdbcHJvcF0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXNbcHJvcF0gPSBjaGlsZENvbmZpZ1twcm9wXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcmVzW3Byb3BdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKHByb3AgaW4gcGFyZW50Q29uZmlnKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChwYXJlbnRDb25maWcsIHByb3ApICYmXG4gICAgICAgICAgICAgICAgICAgICFoYXNPd25Qcm9wKGNoaWxkQ29uZmlnLCBwcm9wKSAmJlxuICAgICAgICAgICAgICAgICAgICBpc09iamVjdChwYXJlbnRDb25maWdbcHJvcF0pKSB7XG4gICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGNoYW5nZXMgdG8gcHJvcGVydGllcyBkb24ndCBtb2RpZnkgcGFyZW50IGNvbmZpZ1xuICAgICAgICAgICAgICAgIHJlc1twcm9wXSA9IGV4dGVuZCh7fSwgcmVzW3Byb3BdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIExvY2FsZShjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZyAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnNldChjb25maWcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGtleXM7XG5cbiAgICBpZiAoT2JqZWN0LmtleXMpIHtcbiAgICAgICAga2V5cyA9IE9iamVjdC5rZXlzO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGtleXMgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICB2YXIgaSwgcmVzID0gW107XG4gICAgICAgICAgICBmb3IgKGkgaW4gb2JqKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhc093blByb3Aob2JqLCBpKSkge1xuICAgICAgICAgICAgICAgICAgICByZXMucHVzaChpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0Q2FsZW5kYXIgPSB7XG4gICAgICAgIHNhbWVEYXkgOiAnW1RvZGF5IGF0XSBMVCcsXG4gICAgICAgIG5leHREYXkgOiAnW1RvbW9ycm93IGF0XSBMVCcsXG4gICAgICAgIG5leHRXZWVrIDogJ2RkZGQgW2F0XSBMVCcsXG4gICAgICAgIGxhc3REYXkgOiAnW1llc3RlcmRheSBhdF0gTFQnLFxuICAgICAgICBsYXN0V2VlayA6ICdbTGFzdF0gZGRkZCBbYXRdIExUJyxcbiAgICAgICAgc2FtZUVsc2UgOiAnTCdcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gY2FsZW5kYXIgKGtleSwgbW9tLCBub3cpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX2NhbGVuZGFyW2tleV0gfHwgdGhpcy5fY2FsZW5kYXJbJ3NhbWVFbHNlJ107XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKG91dHB1dCkgPyBvdXRwdXQuY2FsbChtb20sIG5vdykgOiBvdXRwdXQ7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb25nRGF0ZUZvcm1hdCA9IHtcbiAgICAgICAgTFRTICA6ICdoOm1tOnNzIEEnLFxuICAgICAgICBMVCAgIDogJ2g6bW0gQScsXG4gICAgICAgIEwgICAgOiAnTU0vREQvWVlZWScsXG4gICAgICAgIExMICAgOiAnTU1NTSBELCBZWVlZJyxcbiAgICAgICAgTExMICA6ICdNTU1NIEQsIFlZWVkgaDptbSBBJyxcbiAgICAgICAgTExMTCA6ICdkZGRkLCBNTU1NIEQsIFlZWVkgaDptbSBBJ1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb25nRGF0ZUZvcm1hdCAoa2V5KSB7XG4gICAgICAgIHZhciBmb3JtYXQgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldLFxuICAgICAgICAgICAgZm9ybWF0VXBwZXIgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXkudG9VcHBlckNhc2UoKV07XG5cbiAgICAgICAgaWYgKGZvcm1hdCB8fCAhZm9ybWF0VXBwZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldID0gZm9ybWF0VXBwZXIucmVwbGFjZSgvTU1NTXxNTXxERHxkZGRkL2csIGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWwuc2xpY2UoMSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0SW52YWxpZERhdGUgPSAnSW52YWxpZCBkYXRlJztcblxuICAgIGZ1bmN0aW9uIGludmFsaWREYXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ludmFsaWREYXRlO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0T3JkaW5hbCA9ICclZCc7XG4gICAgdmFyIGRlZmF1bHREYXlPZk1vbnRoT3JkaW5hbFBhcnNlID0gL1xcZHsxLDJ9LztcblxuICAgIGZ1bmN0aW9uIG9yZGluYWwgKG51bWJlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3JkaW5hbC5yZXBsYWNlKCclZCcsIG51bWJlcik7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRSZWxhdGl2ZVRpbWUgPSB7XG4gICAgICAgIGZ1dHVyZSA6ICdpbiAlcycsXG4gICAgICAgIHBhc3QgICA6ICclcyBhZ28nLFxuICAgICAgICBzICA6ICdhIGZldyBzZWNvbmRzJyxcbiAgICAgICAgc3MgOiAnJWQgc2Vjb25kcycsXG4gICAgICAgIG0gIDogJ2EgbWludXRlJyxcbiAgICAgICAgbW0gOiAnJWQgbWludXRlcycsXG4gICAgICAgIGggIDogJ2FuIGhvdXInLFxuICAgICAgICBoaCA6ICclZCBob3VycycsXG4gICAgICAgIGQgIDogJ2EgZGF5JyxcbiAgICAgICAgZGQgOiAnJWQgZGF5cycsXG4gICAgICAgIE0gIDogJ2EgbW9udGgnLFxuICAgICAgICBNTSA6ICclZCBtb250aHMnLFxuICAgICAgICB5ICA6ICdhIHllYXInLFxuICAgICAgICB5eSA6ICclZCB5ZWFycydcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcmVsYXRpdmVUaW1lIChudW1iZXIsIHdpdGhvdXRTdWZmaXgsIHN0cmluZywgaXNGdXR1cmUpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX3JlbGF0aXZlVGltZVtzdHJpbmddO1xuICAgICAgICByZXR1cm4gKGlzRnVuY3Rpb24ob3V0cHV0KSkgP1xuICAgICAgICAgICAgb3V0cHV0KG51bWJlciwgd2l0aG91dFN1ZmZpeCwgc3RyaW5nLCBpc0Z1dHVyZSkgOlxuICAgICAgICAgICAgb3V0cHV0LnJlcGxhY2UoLyVkL2ksIG51bWJlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFzdEZ1dHVyZSAoZGlmZiwgb3V0cHV0KSB7XG4gICAgICAgIHZhciBmb3JtYXQgPSB0aGlzLl9yZWxhdGl2ZVRpbWVbZGlmZiA+IDAgPyAnZnV0dXJlJyA6ICdwYXN0J107XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKGZvcm1hdCkgPyBmb3JtYXQob3V0cHV0KSA6IGZvcm1hdC5yZXBsYWNlKC8lcy9pLCBvdXRwdXQpO1xuICAgIH1cblxuICAgIHZhciBhbGlhc2VzID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRVbml0QWxpYXMgKHVuaXQsIHNob3J0aGFuZCkge1xuICAgICAgICB2YXIgbG93ZXJDYXNlID0gdW5pdC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBhbGlhc2VzW2xvd2VyQ2FzZV0gPSBhbGlhc2VzW2xvd2VyQ2FzZSArICdzJ10gPSBhbGlhc2VzW3Nob3J0aGFuZF0gPSB1bml0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdW5pdHMgPT09ICdzdHJpbmcnID8gYWxpYXNlc1t1bml0c10gfHwgYWxpYXNlc1t1bml0cy50b0xvd2VyQ2FzZSgpXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBub3JtYWxpemVPYmplY3RVbml0cyhpbnB1dE9iamVjdCkge1xuICAgICAgICB2YXIgbm9ybWFsaXplZElucHV0ID0ge30sXG4gICAgICAgICAgICBub3JtYWxpemVkUHJvcCxcbiAgICAgICAgICAgIHByb3A7XG5cbiAgICAgICAgZm9yIChwcm9wIGluIGlucHV0T2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChpbnB1dE9iamVjdCwgcHJvcCkpIHtcbiAgICAgICAgICAgICAgICBub3JtYWxpemVkUHJvcCA9IG5vcm1hbGl6ZVVuaXRzKHByb3ApO1xuICAgICAgICAgICAgICAgIGlmIChub3JtYWxpemVkUHJvcCkge1xuICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkSW5wdXRbbm9ybWFsaXplZFByb3BdID0gaW5wdXRPYmplY3RbcHJvcF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRJbnB1dDtcbiAgICB9XG5cbiAgICB2YXIgcHJpb3JpdGllcyA9IHt9O1xuXG4gICAgZnVuY3Rpb24gYWRkVW5pdFByaW9yaXR5KHVuaXQsIHByaW9yaXR5KSB7XG4gICAgICAgIHByaW9yaXRpZXNbdW5pdF0gPSBwcmlvcml0eTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRQcmlvcml0aXplZFVuaXRzKHVuaXRzT2JqKSB7XG4gICAgICAgIHZhciB1bml0cyA9IFtdO1xuICAgICAgICBmb3IgKHZhciB1IGluIHVuaXRzT2JqKSB7XG4gICAgICAgICAgICB1bml0cy5wdXNoKHt1bml0OiB1LCBwcmlvcml0eTogcHJpb3JpdGllc1t1XX0pO1xuICAgICAgICB9XG4gICAgICAgIHVuaXRzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgIHJldHVybiBhLnByaW9yaXR5IC0gYi5wcmlvcml0eTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB1bml0cztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB6ZXJvRmlsbChudW1iZXIsIHRhcmdldExlbmd0aCwgZm9yY2VTaWduKSB7XG4gICAgICAgIHZhciBhYnNOdW1iZXIgPSAnJyArIE1hdGguYWJzKG51bWJlciksXG4gICAgICAgICAgICB6ZXJvc1RvRmlsbCA9IHRhcmdldExlbmd0aCAtIGFic051bWJlci5sZW5ndGgsXG4gICAgICAgICAgICBzaWduID0gbnVtYmVyID49IDA7XG4gICAgICAgIHJldHVybiAoc2lnbiA/IChmb3JjZVNpZ24gPyAnKycgOiAnJykgOiAnLScpICtcbiAgICAgICAgICAgIE1hdGgucG93KDEwLCBNYXRoLm1heCgwLCB6ZXJvc1RvRmlsbCkpLnRvU3RyaW5nKCkuc3Vic3RyKDEpICsgYWJzTnVtYmVyO1xuICAgIH1cblxuICAgIHZhciBmb3JtYXR0aW5nVG9rZW5zID0gLyhcXFtbXlxcW10qXFxdKXwoXFxcXCk/KFtIaF1tbShzcyk/fE1vfE1NP00/TT98RG98REREb3xERD9EP0Q/fGRkZD9kP3xkbz98d1tvfHddP3xXW298V10/fFFvP3xZWVlZWVl8WVlZWVl8WVlZWXxZWXxnZyhnZ2c/KT98R0coR0dHPyk/fGV8RXxhfEF8aGg/fEhIP3xraz98bW0/fHNzP3xTezEsOX18eHxYfHp6P3xaWj98LikvZztcblxuICAgIHZhciBsb2NhbEZvcm1hdHRpbmdUb2tlbnMgPSAvKFxcW1teXFxbXSpcXF0pfChcXFxcKT8oTFRTfExUfExMP0w/TD98bHsxLDR9KS9nO1xuXG4gICAgdmFyIGZvcm1hdEZ1bmN0aW9ucyA9IHt9O1xuXG4gICAgdmFyIGZvcm1hdFRva2VuRnVuY3Rpb25zID0ge307XG5cbiAgICAvLyB0b2tlbjogICAgJ00nXG4gICAgLy8gcGFkZGVkOiAgIFsnTU0nLCAyXVxuICAgIC8vIG9yZGluYWw6ICAnTW8nXG4gICAgLy8gY2FsbGJhY2s6IGZ1bmN0aW9uICgpIHsgdGhpcy5tb250aCgpICsgMSB9XG4gICAgZnVuY3Rpb24gYWRkRm9ybWF0VG9rZW4gKHRva2VuLCBwYWRkZWQsIG9yZGluYWwsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBmdW5jID0gY2FsbGJhY2s7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBmdW5jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW2NhbGxiYWNrXSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9rZW4pIHtcbiAgICAgICAgICAgIGZvcm1hdFRva2VuRnVuY3Rpb25zW3Rva2VuXSA9IGZ1bmM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhZGRlZCkge1xuICAgICAgICAgICAgZm9ybWF0VG9rZW5GdW5jdGlvbnNbcGFkZGVkWzBdXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gemVyb0ZpbGwoZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpLCBwYWRkZWRbMV0sIHBhZGRlZFsyXSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcmRpbmFsKSB7XG4gICAgICAgICAgICBmb3JtYXRUb2tlbkZ1bmN0aW9uc1tvcmRpbmFsXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkub3JkaW5hbChmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIHRva2VuKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGlucHV0KSB7XG4gICAgICAgIGlmIChpbnB1dC5tYXRjaCgvXFxbW1xcc1xcU10vKSkge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL15cXFt8XFxdJC9nLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL1xcXFwvZywgJycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VGb3JtYXRGdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgICAgdmFyIGFycmF5ID0gZm9ybWF0Lm1hdGNoKGZvcm1hdHRpbmdUb2tlbnMpLCBpLCBsZW5ndGg7XG5cbiAgICAgICAgZm9yIChpID0gMCwgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXRUb2tlbkZ1bmN0aW9uc1thcnJheVtpXV0pIHtcbiAgICAgICAgICAgICAgICBhcnJheVtpXSA9IGZvcm1hdFRva2VuRnVuY3Rpb25zW2FycmF5W2ldXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXJyYXlbaV0gPSByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGFycmF5W2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAobW9tKSB7XG4gICAgICAgICAgICB2YXIgb3V0cHV0ID0gJycsIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gaXNGdW5jdGlvbihhcnJheVtpXSkgPyBhcnJheVtpXS5jYWxsKG1vbSwgZm9ybWF0KSA6IGFycmF5W2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBmb3JtYXQgZGF0ZSB1c2luZyBuYXRpdmUgZGF0ZSBvYmplY3RcbiAgICBmdW5jdGlvbiBmb3JtYXRNb21lbnQobSwgZm9ybWF0KSB7XG4gICAgICAgIGlmICghbS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBtLmxvY2FsZURhdGEoKS5pbnZhbGlkRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9ybWF0ID0gZXhwYW5kRm9ybWF0KGZvcm1hdCwgbS5sb2NhbGVEYXRhKCkpO1xuICAgICAgICBmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XSA9IGZvcm1hdEZ1bmN0aW9uc1tmb3JtYXRdIHx8IG1ha2VGb3JtYXRGdW5jdGlvbihmb3JtYXQpO1xuXG4gICAgICAgIHJldHVybiBmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XShtKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBleHBhbmRGb3JtYXQoZm9ybWF0LCBsb2NhbGUpIHtcbiAgICAgICAgdmFyIGkgPSA1O1xuXG4gICAgICAgIGZ1bmN0aW9uIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2VucyhpbnB1dCkge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS5sb25nRGF0ZUZvcm1hdChpbnB1dCkgfHwgaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPj0gMCAmJiBsb2NhbEZvcm1hdHRpbmdUb2tlbnMudGVzdChmb3JtYXQpKSB7XG4gICAgICAgICAgICBmb3JtYXQgPSBmb3JtYXQucmVwbGFjZShsb2NhbEZvcm1hdHRpbmdUb2tlbnMsIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2Vucyk7XG4gICAgICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgfVxuXG4gICAgdmFyIG1hdGNoMSAgICAgICAgID0gL1xcZC87ICAgICAgICAgICAgLy8gICAgICAgMCAtIDlcbiAgICB2YXIgbWF0Y2gyICAgICAgICAgPSAvXFxkXFxkLzsgICAgICAgICAgLy8gICAgICAwMCAtIDk5XG4gICAgdmFyIG1hdGNoMyAgICAgICAgID0gL1xcZHszfS87ICAgICAgICAgLy8gICAgIDAwMCAtIDk5OVxuICAgIHZhciBtYXRjaDQgICAgICAgICA9IC9cXGR7NH0vOyAgICAgICAgIC8vICAgIDAwMDAgLSA5OTk5XG4gICAgdmFyIG1hdGNoNiAgICAgICAgID0gL1srLV0/XFxkezZ9LzsgICAgLy8gLTk5OTk5OSAtIDk5OTk5OVxuICAgIHZhciBtYXRjaDF0bzIgICAgICA9IC9cXGRcXGQ/LzsgICAgICAgICAvLyAgICAgICAwIC0gOTlcbiAgICB2YXIgbWF0Y2gzdG80ICAgICAgPSAvXFxkXFxkXFxkXFxkPy87ICAgICAvLyAgICAgOTk5IC0gOTk5OVxuICAgIHZhciBtYXRjaDV0bzYgICAgICA9IC9cXGRcXGRcXGRcXGRcXGRcXGQ/LzsgLy8gICA5OTk5OSAtIDk5OTk5OVxuICAgIHZhciBtYXRjaDF0bzMgICAgICA9IC9cXGR7MSwzfS87ICAgICAgIC8vICAgICAgIDAgLSA5OTlcbiAgICB2YXIgbWF0Y2gxdG80ICAgICAgPSAvXFxkezEsNH0vOyAgICAgICAvLyAgICAgICAwIC0gOTk5OVxuICAgIHZhciBtYXRjaDF0bzYgICAgICA9IC9bKy1dP1xcZHsxLDZ9LzsgIC8vIC05OTk5OTkgLSA5OTk5OTlcblxuICAgIHZhciBtYXRjaFVuc2lnbmVkICA9IC9cXGQrLzsgICAgICAgICAgIC8vICAgICAgIDAgLSBpbmZcbiAgICB2YXIgbWF0Y2hTaWduZWQgICAgPSAvWystXT9cXGQrLzsgICAgICAvLyAgICAtaW5mIC0gaW5mXG5cbiAgICB2YXIgbWF0Y2hPZmZzZXQgICAgPSAvWnxbKy1dXFxkXFxkOj9cXGRcXGQvZ2k7IC8vICswMDowMCAtMDA6MDAgKzAwMDAgLTAwMDAgb3IgWlxuICAgIHZhciBtYXRjaFNob3J0T2Zmc2V0ID0gL1p8WystXVxcZFxcZCg/Ojo/XFxkXFxkKT8vZ2k7IC8vICswMCAtMDAgKzAwOjAwIC0wMDowMCArMDAwMCAtMDAwMCBvciBaXG5cbiAgICB2YXIgbWF0Y2hUaW1lc3RhbXAgPSAvWystXT9cXGQrKFxcLlxcZHsxLDN9KT8vOyAvLyAxMjM0NTY3ODkgMTIzNDU2Nzg5LjEyM1xuXG4gICAgLy8gYW55IHdvcmQgKG9yIHR3bykgY2hhcmFjdGVycyBvciBudW1iZXJzIGluY2x1ZGluZyB0d28vdGhyZWUgd29yZCBtb250aCBpbiBhcmFiaWMuXG4gICAgLy8gaW5jbHVkZXMgc2NvdHRpc2ggZ2FlbGljIHR3byB3b3JkIGFuZCBoeXBoZW5hdGVkIG1vbnRoc1xuICAgIHZhciBtYXRjaFdvcmQgPSAvWzAtOV17MCwyNTZ9WydhLXpcXHUwMEEwLVxcdTA1RkZcXHUwNzAwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGMDdcXHVGRjEwLVxcdUZGRUZdezEsMjU2fXxbXFx1MDYwMC1cXHUwNkZGXFwvXXsxLDI1Nn0oXFxzKj9bXFx1MDYwMC1cXHUwNkZGXXsxLDI1Nn0pezEsMn0vaTtcblxuICAgIHZhciByZWdleGVzID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRSZWdleFRva2VuICh0b2tlbiwgcmVnZXgsIHN0cmljdFJlZ2V4KSB7XG4gICAgICAgIHJlZ2V4ZXNbdG9rZW5dID0gaXNGdW5jdGlvbihyZWdleCkgPyByZWdleCA6IGZ1bmN0aW9uIChpc1N0cmljdCwgbG9jYWxlRGF0YSkge1xuICAgICAgICAgICAgcmV0dXJuIChpc1N0cmljdCAmJiBzdHJpY3RSZWdleCkgPyBzdHJpY3RSZWdleCA6IHJlZ2V4O1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFBhcnNlUmVnZXhGb3JUb2tlbiAodG9rZW4sIGNvbmZpZykge1xuICAgICAgICBpZiAoIWhhc093blByb3AocmVnZXhlcywgdG9rZW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cCh1bmVzY2FwZUZvcm1hdCh0b2tlbikpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlZ2V4ZXNbdG9rZW5dKGNvbmZpZy5fc3RyaWN0LCBjb25maWcuX2xvY2FsZSk7XG4gICAgfVxuXG4gICAgLy8gQ29kZSBmcm9tIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzU2MTQ5My9pcy10aGVyZS1hLXJlZ2V4cC1lc2NhcGUtZnVuY3Rpb24taW4tamF2YXNjcmlwdFxuICAgIGZ1bmN0aW9uIHVuZXNjYXBlRm9ybWF0KHMpIHtcbiAgICAgICAgcmV0dXJuIHJlZ2V4RXNjYXBlKHMucmVwbGFjZSgnXFxcXCcsICcnKS5yZXBsYWNlKC9cXFxcKFxcWyl8XFxcXChcXF0pfFxcWyhbXlxcXVxcW10qKVxcXXxcXFxcKC4pL2csIGZ1bmN0aW9uIChtYXRjaGVkLCBwMSwgcDIsIHAzLCBwNCkge1xuICAgICAgICAgICAgcmV0dXJuIHAxIHx8IHAyIHx8IHAzIHx8IHA0O1xuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVnZXhFc2NhcGUocykge1xuICAgICAgICByZXR1cm4gcy5yZXBsYWNlKC9bLVxcL1xcXFxeJCorPy4oKXxbXFxde31dL2csICdcXFxcJCYnKTtcbiAgICB9XG5cbiAgICB2YXIgdG9rZW5zID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRQYXJzZVRva2VuICh0b2tlbiwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGksIGZ1bmMgPSBjYWxsYmFjaztcbiAgICAgICAgaWYgKHR5cGVvZiB0b2tlbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRva2VuID0gW3Rva2VuXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNOdW1iZXIoY2FsbGJhY2spKSB7XG4gICAgICAgICAgICBmdW5jID0gZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICAgICAgICAgIGFycmF5W2NhbGxiYWNrXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRva2VuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0b2tlbnNbdG9rZW5baV1dID0gZnVuYztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFdlZWtQYXJzZVRva2VuICh0b2tlbiwgY2FsbGJhY2spIHtcbiAgICAgICAgYWRkUGFyc2VUb2tlbih0b2tlbiwgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnLCB0b2tlbikge1xuICAgICAgICAgICAgY29uZmlnLl93ID0gY29uZmlnLl93IHx8IHt9O1xuICAgICAgICAgICAgY2FsbGJhY2soaW5wdXQsIGNvbmZpZy5fdywgY29uZmlnLCB0b2tlbik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFRpbWVUb0FycmF5RnJvbVRva2VuKHRva2VuLCBpbnB1dCwgY29uZmlnKSB7XG4gICAgICAgIGlmIChpbnB1dCAhPSBudWxsICYmIGhhc093blByb3AodG9rZW5zLCB0b2tlbikpIHtcbiAgICAgICAgICAgIHRva2Vuc1t0b2tlbl0oaW5wdXQsIGNvbmZpZy5fYSwgY29uZmlnLCB0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgWUVBUiA9IDA7XG4gICAgdmFyIE1PTlRIID0gMTtcbiAgICB2YXIgREFURSA9IDI7XG4gICAgdmFyIEhPVVIgPSAzO1xuICAgIHZhciBNSU5VVEUgPSA0O1xuICAgIHZhciBTRUNPTkQgPSA1O1xuICAgIHZhciBNSUxMSVNFQ09ORCA9IDY7XG4gICAgdmFyIFdFRUsgPSA3O1xuICAgIHZhciBXRUVLREFZID0gODtcblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdZJywgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgeSA9IHRoaXMueWVhcigpO1xuICAgICAgICByZXR1cm4geSA8PSA5OTk5ID8gJycgKyB5IDogJysnICsgeTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnWVknLCAyXSwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy55ZWFyKCkgJSAxMDA7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1lZWVknLCAgIDRdLCAgICAgICAwLCAneWVhcicpO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnWVlZWVknLCAgNV0sICAgICAgIDAsICd5ZWFyJyk7XG4gICAgYWRkRm9ybWF0VG9rZW4oMCwgWydZWVlZWVknLCA2LCB0cnVlXSwgMCwgJ3llYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygneWVhcicsICd5Jyk7XG5cbiAgICAvLyBQUklPUklUSUVTXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ3llYXInLCAxKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1knLCAgICAgIG1hdGNoU2lnbmVkKTtcbiAgICBhZGRSZWdleFRva2VuKCdZWScsICAgICBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignWVlZWScsICAgbWF0Y2gxdG80LCBtYXRjaDQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1lZWVlZJywgIG1hdGNoMXRvNiwgbWF0Y2g2KTtcbiAgICBhZGRSZWdleFRva2VuKCdZWVlZWVknLCBtYXRjaDF0bzYsIG1hdGNoNik7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnWVlZWVknLCAnWVlZWVlZJ10sIFlFQVIpO1xuICAgIGFkZFBhcnNlVG9rZW4oJ1lZWVknLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5KSB7XG4gICAgICAgIGFycmF5W1lFQVJdID0gaW5wdXQubGVuZ3RoID09PSAyID8gaG9va3MucGFyc2VUd29EaWdpdFllYXIoaW5wdXQpIDogdG9JbnQoaW5wdXQpO1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oJ1lZJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtZRUFSXSA9IGhvb2tzLnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCdZJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtZRUFSXSA9IHBhcnNlSW50KGlucHV0LCAxMCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICBmdW5jdGlvbiBkYXlzSW5ZZWFyKHllYXIpIHtcbiAgICAgICAgcmV0dXJuIGlzTGVhcFllYXIoeWVhcikgPyAzNjYgOiAzNjU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNMZWFwWWVhcih5ZWFyKSB7XG4gICAgICAgIHJldHVybiAoeWVhciAlIDQgPT09IDAgJiYgeWVhciAlIDEwMCAhPT0gMCkgfHwgeWVhciAlIDQwMCA9PT0gMDtcbiAgICB9XG5cbiAgICAvLyBIT09LU1xuXG4gICAgaG9va3MucGFyc2VUd29EaWdpdFllYXIgPSBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHRvSW50KGlucHV0KSArICh0b0ludChpbnB1dCkgPiA2OCA/IDE5MDAgOiAyMDAwKTtcbiAgICB9O1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgdmFyIGdldFNldFllYXIgPSBtYWtlR2V0U2V0KCdGdWxsWWVhcicsIHRydWUpO1xuXG4gICAgZnVuY3Rpb24gZ2V0SXNMZWFwWWVhciAoKSB7XG4gICAgICAgIHJldHVybiBpc0xlYXBZZWFyKHRoaXMueWVhcigpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlR2V0U2V0ICh1bml0LCBrZWVwVGltZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHNldCQxKHRoaXMsIHVuaXQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywga2VlcFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0KHRoaXMsIHVuaXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldCAobW9tLCB1bml0KSB7XG4gICAgICAgIHJldHVybiBtb20uaXNWYWxpZCgpID9cbiAgICAgICAgICAgIG1vbS5fZFsnZ2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyB1bml0XSgpIDogTmFOO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldCQxIChtb20sIHVuaXQsIHZhbHVlKSB7XG4gICAgICAgIGlmIChtb20uaXNWYWxpZCgpICYmICFpc05hTih2YWx1ZSkpIHtcbiAgICAgICAgICAgIGlmICh1bml0ID09PSAnRnVsbFllYXInICYmIGlzTGVhcFllYXIobW9tLnllYXIoKSkgJiYgbW9tLm1vbnRoKCkgPT09IDEgJiYgbW9tLmRhdGUoKSA9PT0gMjkpIHtcbiAgICAgICAgICAgICAgICBtb20uX2RbJ3NldCcgKyAobW9tLl9pc1VUQyA/ICdVVEMnIDogJycpICsgdW5pdF0odmFsdWUsIG1vbS5tb250aCgpLCBkYXlzSW5Nb250aCh2YWx1ZSwgbW9tLm1vbnRoKCkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyB1bml0XSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBzdHJpbmdHZXQgKHVuaXRzKSB7XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICBpZiAoaXNGdW5jdGlvbih0aGlzW3VuaXRzXSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzXSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gc3RyaW5nU2V0ICh1bml0cywgdmFsdWUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB1bml0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHVuaXRzID0gbm9ybWFsaXplT2JqZWN0VW5pdHModW5pdHMpO1xuICAgICAgICAgICAgdmFyIHByaW9yaXRpemVkID0gZ2V0UHJpb3JpdGl6ZWRVbml0cyh1bml0cyk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByaW9yaXRpemVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpc1twcmlvcml0aXplZFtpXS51bml0XSh1bml0c1twcmlvcml0aXplZFtpXS51bml0XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHRoaXNbdW5pdHNdKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzXSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbW9kKG4sIHgpIHtcbiAgICAgICAgcmV0dXJuICgobiAlIHgpICsgeCkgJSB4O1xuICAgIH1cblxuICAgIHZhciBpbmRleE9mO1xuXG4gICAgaWYgKEFycmF5LnByb3RvdHlwZS5pbmRleE9mKSB7XG4gICAgICAgIGluZGV4T2YgPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZjtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpbmRleE9mID0gZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgICAgIC8vIEkga25vd1xuICAgICAgICAgICAgdmFyIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSBvKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlzSW5Nb250aCh5ZWFyLCBtb250aCkge1xuICAgICAgICBpZiAoaXNOYU4oeWVhcikgfHwgaXNOYU4obW9udGgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtb2RNb250aCA9IG1vZChtb250aCwgMTIpO1xuICAgICAgICB5ZWFyICs9IChtb250aCAtIG1vZE1vbnRoKSAvIDEyO1xuICAgICAgICByZXR1cm4gbW9kTW9udGggPT09IDEgPyAoaXNMZWFwWWVhcih5ZWFyKSA/IDI5IDogMjgpIDogKDMxIC0gbW9kTW9udGggJSA3ICUgMik7XG4gICAgfVxuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ00nLCBbJ01NJywgMl0sICdNbycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9udGgoKSArIDE7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignTU1NJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzU2hvcnQodGhpcywgZm9ybWF0KTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdNTU1NJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzKHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21vbnRoJywgJ00nKTtcblxuICAgIC8vIFBSSU9SSVRZXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ21vbnRoJywgOCk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdNJywgICAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdNTScsICAgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ01NTScsICBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLm1vbnRoc1Nob3J0UmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ01NTU0nLCBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLm1vbnRoc1JlZ2V4KGlzU3RyaWN0KTtcbiAgICB9KTtcblxuICAgIGFkZFBhcnNlVG9rZW4oWydNJywgJ01NJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbTU9OVEhdID0gdG9JbnQoaW5wdXQpIC0gMTtcbiAgICB9KTtcblxuICAgIGFkZFBhcnNlVG9rZW4oWydNTU0nLCAnTU1NTSddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcsIHRva2VuKSB7XG4gICAgICAgIHZhciBtb250aCA9IGNvbmZpZy5fbG9jYWxlLm1vbnRoc1BhcnNlKGlucHV0LCB0b2tlbiwgY29uZmlnLl9zdHJpY3QpO1xuICAgICAgICAvLyBpZiB3ZSBkaWRuJ3QgZmluZCBhIG1vbnRoIG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZC5cbiAgICAgICAgaWYgKG1vbnRoICE9IG51bGwpIHtcbiAgICAgICAgICAgIGFycmF5W01PTlRIXSA9IG1vbnRoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuaW52YWxpZE1vbnRoID0gaW5wdXQ7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIExPQ0FMRVNcblxuICAgIHZhciBNT05USFNfSU5fRk9STUFUID0gL0Rbb0RdPyhcXFtbXlxcW1xcXV0qXFxdfFxccykrTU1NTT8vO1xuICAgIHZhciBkZWZhdWx0TG9jYWxlTW9udGhzID0gJ0phbnVhcnlfRmVicnVhcnlfTWFyY2hfQXByaWxfTWF5X0p1bmVfSnVseV9BdWd1c3RfU2VwdGVtYmVyX09jdG9iZXJfTm92ZW1iZXJfRGVjZW1iZXInLnNwbGl0KCdfJyk7XG4gICAgZnVuY3Rpb24gbG9jYWxlTW9udGhzIChtLCBmb3JtYXQpIHtcbiAgICAgICAgaWYgKCFtKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNBcnJheSh0aGlzLl9tb250aHMpID8gdGhpcy5fbW9udGhzIDpcbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNbJ3N0YW5kYWxvbmUnXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNBcnJheSh0aGlzLl9tb250aHMpID8gdGhpcy5fbW9udGhzW20ubW9udGgoKV0gOlxuICAgICAgICAgICAgdGhpcy5fbW9udGhzWyh0aGlzLl9tb250aHMuaXNGb3JtYXQgfHwgTU9OVEhTX0lOX0ZPUk1BVCkudGVzdChmb3JtYXQpID8gJ2Zvcm1hdCcgOiAnc3RhbmRhbG9uZSddW20ubW9udGgoKV07XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb2NhbGVNb250aHNTaG9ydCA9ICdKYW5fRmViX01hcl9BcHJfTWF5X0p1bl9KdWxfQXVnX1NlcF9PY3RfTm92X0RlYycuc3BsaXQoJ18nKTtcbiAgICBmdW5jdGlvbiBsb2NhbGVNb250aHNTaG9ydCAobSwgZm9ybWF0KSB7XG4gICAgICAgIGlmICghbSkge1xuICAgICAgICAgICAgcmV0dXJuIGlzQXJyYXkodGhpcy5fbW9udGhzU2hvcnQpID8gdGhpcy5fbW9udGhzU2hvcnQgOlxuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1Nob3J0WydzdGFuZGFsb25lJ107XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlzQXJyYXkodGhpcy5fbW9udGhzU2hvcnQpID8gdGhpcy5fbW9udGhzU2hvcnRbbS5tb250aCgpXSA6XG4gICAgICAgICAgICB0aGlzLl9tb250aHNTaG9ydFtNT05USFNfSU5fRk9STUFULnRlc3QoZm9ybWF0KSA/ICdmb3JtYXQnIDogJ3N0YW5kYWxvbmUnXVttLm1vbnRoKCldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZVN0cmljdFBhcnNlKG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGksIGlpLCBtb20sIGxsYyA9IG1vbnRoTmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoIXRoaXMuX21vbnRoc1BhcnNlKSB7XG4gICAgICAgICAgICAvLyB0aGlzIGlzIG5vdCB1c2VkXG4gICAgICAgICAgICB0aGlzLl9tb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTI7ICsraSkge1xuICAgICAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgaV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Nob3J0TW9udGhzUGFyc2VbaV0gPSB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldID0gdGhpcy5tb250aHMobW9tLCAnJykudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdNTU0nKSB7XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9sb25nTW9udGhzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdNTU0nKSB7XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fbG9uZ01vbnRoc1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpaSAhPT0gLTEgPyBpaSA6IG51bGw7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX2xvbmdNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9jYWxlTW9udGhzUGFyc2UgKG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGksIG1vbSwgcmVnZXg7XG5cbiAgICAgICAgaWYgKHRoaXMuX21vbnRoc1BhcnNlRXhhY3QpIHtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVTdHJpY3RQYXJzZS5jYWxsKHRoaXMsIG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLl9tb250aHNQYXJzZSkge1xuICAgICAgICAgICAgdGhpcy5fbW9udGhzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX2xvbmdNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVE9ETzogYWRkIHNvcnRpbmdcbiAgICAgICAgLy8gU29ydGluZyBtYWtlcyBzdXJlIGlmIG9uZSBtb250aCAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlclxuICAgICAgICAvLyBzZWUgc29ydGluZyBpbiBjb21wdXRlTW9udGhzUGFyc2VcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuICAgICAgICAgICAgbW9tID0gY3JlYXRlVVRDKFsyMDAwLCBpXSk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmICF0aGlzLl9sb25nTW9udGhzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb25nTW9udGhzUGFyc2VbaV0gPSBuZXcgUmVnRXhwKCdeJyArIHRoaXMubW9udGhzKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnJykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZVtpXSA9IG5ldyBSZWdFeHAoJ14nICsgdGhpcy5tb250aHNTaG9ydChtb20sICcnKS5yZXBsYWNlKCcuJywgJycpICsgJyQnLCAnaScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFzdHJpY3QgJiYgIXRoaXMuX21vbnRoc1BhcnNlW2ldKSB7XG4gICAgICAgICAgICAgICAgcmVnZXggPSAnXicgKyB0aGlzLm1vbnRocyhtb20sICcnKSArICd8XicgKyB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1BhcnNlW2ldID0gbmV3IFJlZ0V4cChyZWdleC5yZXBsYWNlKCcuJywgJycpLCAnaScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdGVzdCB0aGUgcmVnZXhcbiAgICAgICAgICAgIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NTScgJiYgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NJyAmJiB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghc3RyaWN0ICYmIHRoaXMuX21vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgZnVuY3Rpb24gc2V0TW9udGggKG1vbSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIGRheU9mTW9udGg7XG5cbiAgICAgICAgaWYgKCFtb20uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICAvLyBObyBvcFxuICAgICAgICAgICAgcmV0dXJuIG1vbTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAoL15cXGQrJC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRvSW50KHZhbHVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBtb20ubG9jYWxlRGF0YSgpLm1vbnRoc1BhcnNlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBBbm90aGVyIHNpbGVudCBmYWlsdXJlP1xuICAgICAgICAgICAgICAgIGlmICghaXNOdW1iZXIodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtb207XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZGF5T2ZNb250aCA9IE1hdGgubWluKG1vbS5kYXRlKCksIGRheXNJbk1vbnRoKG1vbS55ZWFyKCksIHZhbHVlKSk7XG4gICAgICAgIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyAnTW9udGgnXSh2YWx1ZSwgZGF5T2ZNb250aCk7XG4gICAgICAgIHJldHVybiBtb207XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2V0TW9udGggKHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBzZXRNb250aCh0aGlzLCB2YWx1ZSk7XG4gICAgICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBnZXQodGhpcywgJ01vbnRoJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXREYXlzSW5Nb250aCAoKSB7XG4gICAgICAgIHJldHVybiBkYXlzSW5Nb250aCh0aGlzLnllYXIoKSwgdGhpcy5tb250aCgpKTtcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdE1vbnRoc1Nob3J0UmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gbW9udGhzU2hvcnRSZWdleCAoaXNTdHJpY3QpIHtcbiAgICAgICAgaWYgKHRoaXMuX21vbnRoc1BhcnNlRXhhY3QpIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlTW9udGhzUGFyc2UuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1N0cmljdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1Nob3J0UmVnZXgnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1Nob3J0UmVnZXggPSBkZWZhdWx0TW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4ICYmIGlzU3RyaWN0ID9cbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4IDogdGhpcy5fbW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TW9udGhzUmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gbW9udGhzUmVnZXggKGlzU3RyaWN0KSB7XG4gICAgICAgIGlmICh0aGlzLl9tb250aHNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ19tb250aHNSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgY29tcHV0ZU1vbnRoc1BhcnNlLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNTdHJpY3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNSZWdleCA9IGRlZmF1bHRNb250aHNSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTdHJpY3RSZWdleCAmJiBpc1N0cmljdCA/XG4gICAgICAgICAgICAgICAgdGhpcy5fbW9udGhzU3RyaWN0UmVnZXggOiB0aGlzLl9tb250aHNSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbXB1dGVNb250aHNQYXJzZSAoKSB7XG4gICAgICAgIGZ1bmN0aW9uIGNtcExlblJldihhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi5sZW5ndGggLSBhLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzaG9ydFBpZWNlcyA9IFtdLCBsb25nUGllY2VzID0gW10sIG1peGVkUGllY2VzID0gW10sXG4gICAgICAgICAgICBpLCBtb207XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG4gICAgICAgICAgICAvLyBtYWtlIHRoZSByZWdleCBpZiB3ZSBkb24ndCBoYXZlIGl0IGFscmVhZHlcbiAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgaV0pO1xuICAgICAgICAgICAgc2hvcnRQaWVjZXMucHVzaCh0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpKTtcbiAgICAgICAgICAgIGxvbmdQaWVjZXMucHVzaCh0aGlzLm1vbnRocyhtb20sICcnKSk7XG4gICAgICAgICAgICBtaXhlZFBpZWNlcy5wdXNoKHRoaXMubW9udGhzKG1vbSwgJycpKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2godGhpcy5tb250aHNTaG9ydChtb20sICcnKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU29ydGluZyBtYWtlcyBzdXJlIGlmIG9uZSBtb250aCAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlciBpdFxuICAgICAgICAvLyB3aWxsIG1hdGNoIHRoZSBsb25nZXIgcGllY2UuXG4gICAgICAgIHNob3J0UGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgbG9uZ1BpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIG1peGVkUGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgIHNob3J0UGllY2VzW2ldID0gcmVnZXhFc2NhcGUoc2hvcnRQaWVjZXNbaV0pO1xuICAgICAgICAgICAgbG9uZ1BpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKGxvbmdQaWVjZXNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNDsgaSsrKSB7XG4gICAgICAgICAgICBtaXhlZFBpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKG1peGVkUGllY2VzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX21vbnRoc1JlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbWl4ZWRQaWVjZXMuam9pbignfCcpICsgJyknLCAnaScpO1xuICAgICAgICB0aGlzLl9tb250aHNTaG9ydFJlZ2V4ID0gdGhpcy5fbW9udGhzUmVnZXg7XG4gICAgICAgIHRoaXMuX21vbnRoc1N0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbG9uZ1BpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgICAgIHRoaXMuX21vbnRoc1Nob3J0U3RyaWN0UmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBzaG9ydFBpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlRGF0ZSAoeSwgbSwgZCwgaCwgTSwgcywgbXMpIHtcbiAgICAgICAgLy8gY2FuJ3QganVzdCBhcHBseSgpIHRvIGNyZWF0ZSBhIGRhdGU6XG4gICAgICAgIC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcS8xODEzNDhcbiAgICAgICAgdmFyIGRhdGU7XG4gICAgICAgIC8vIHRoZSBkYXRlIGNvbnN0cnVjdG9yIHJlbWFwcyB5ZWFycyAwLTk5IHRvIDE5MDAtMTk5OVxuICAgICAgICBpZiAoeSA8IDEwMCAmJiB5ID49IDApIHtcbiAgICAgICAgICAgIC8vIHByZXNlcnZlIGxlYXAgeWVhcnMgdXNpbmcgYSBmdWxsIDQwMCB5ZWFyIGN5Y2xlLCB0aGVuIHJlc2V0XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoeSArIDQwMCwgbSwgZCwgaCwgTSwgcywgbXMpO1xuICAgICAgICAgICAgaWYgKGlzRmluaXRlKGRhdGUuZ2V0RnVsbFllYXIoKSkpIHtcbiAgICAgICAgICAgICAgICBkYXRlLnNldEZ1bGxZZWFyKHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKHksIG0sIGQsIGgsIE0sIHMsIG1zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkYXRlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZVVUQ0RhdGUgKHkpIHtcbiAgICAgICAgdmFyIGRhdGU7XG4gICAgICAgIC8vIHRoZSBEYXRlLlVUQyBmdW5jdGlvbiByZW1hcHMgeWVhcnMgMC05OSB0byAxOTAwLTE5OTlcbiAgICAgICAgaWYgKHkgPCAxMDAgJiYgeSA+PSAwKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAvLyBwcmVzZXJ2ZSBsZWFwIHllYXJzIHVzaW5nIGEgZnVsbCA0MDAgeWVhciBjeWNsZSwgdGhlbiByZXNldFxuICAgICAgICAgICAgYXJnc1swXSA9IHkgKyA0MDA7XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoRGF0ZS5VVEMuYXBwbHkobnVsbCwgYXJncykpO1xuICAgICAgICAgICAgaWYgKGlzRmluaXRlKGRhdGUuZ2V0VVRDRnVsbFllYXIoKSkpIHtcbiAgICAgICAgICAgICAgICBkYXRlLnNldFVUQ0Z1bGxZZWFyKHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDLmFwcGx5KG51bGwsIGFyZ3VtZW50cykpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgLy8gc3RhcnQtb2YtZmlyc3Qtd2VlayAtIHN0YXJ0LW9mLXllYXJcbiAgICBmdW5jdGlvbiBmaXJzdFdlZWtPZmZzZXQoeWVhciwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIC8vIGZpcnN0LXdlZWsgZGF5IC0tIHdoaWNoIGphbnVhcnkgaXMgYWx3YXlzIGluIHRoZSBmaXJzdCB3ZWVrICg0IGZvciBpc28sIDEgZm9yIG90aGVyKVxuICAgICAgICAgICAgZndkID0gNyArIGRvdyAtIGRveSxcbiAgICAgICAgICAgIC8vIGZpcnN0LXdlZWsgZGF5IGxvY2FsIHdlZWtkYXkgLS0gd2hpY2ggbG9jYWwgd2Vla2RheSBpcyBmd2RcbiAgICAgICAgICAgIGZ3ZGx3ID0gKDcgKyBjcmVhdGVVVENEYXRlKHllYXIsIDAsIGZ3ZCkuZ2V0VVRDRGF5KCkgLSBkb3cpICUgNztcblxuICAgICAgICByZXR1cm4gLWZ3ZGx3ICsgZndkIC0gMTtcbiAgICB9XG5cbiAgICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlI0NhbGN1bGF0aW5nX2FfZGF0ZV9naXZlbl90aGVfeWVhci4yQ193ZWVrX251bWJlcl9hbmRfd2Vla2RheVxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrcyh5ZWFyLCB3ZWVrLCB3ZWVrZGF5LCBkb3csIGRveSkge1xuICAgICAgICB2YXIgbG9jYWxXZWVrZGF5ID0gKDcgKyB3ZWVrZGF5IC0gZG93KSAlIDcsXG4gICAgICAgICAgICB3ZWVrT2Zmc2V0ID0gZmlyc3RXZWVrT2Zmc2V0KHllYXIsIGRvdywgZG95KSxcbiAgICAgICAgICAgIGRheU9mWWVhciA9IDEgKyA3ICogKHdlZWsgLSAxKSArIGxvY2FsV2Vla2RheSArIHdlZWtPZmZzZXQsXG4gICAgICAgICAgICByZXNZZWFyLCByZXNEYXlPZlllYXI7XG5cbiAgICAgICAgaWYgKGRheU9mWWVhciA8PSAwKSB7XG4gICAgICAgICAgICByZXNZZWFyID0geWVhciAtIDE7XG4gICAgICAgICAgICByZXNEYXlPZlllYXIgPSBkYXlzSW5ZZWFyKHJlc1llYXIpICsgZGF5T2ZZZWFyO1xuICAgICAgICB9IGVsc2UgaWYgKGRheU9mWWVhciA+IGRheXNJblllYXIoeWVhcikpIHtcbiAgICAgICAgICAgIHJlc1llYXIgPSB5ZWFyICsgMTtcbiAgICAgICAgICAgIHJlc0RheU9mWWVhciA9IGRheU9mWWVhciAtIGRheXNJblllYXIoeWVhcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNZZWFyID0geWVhcjtcbiAgICAgICAgICAgIHJlc0RheU9mWWVhciA9IGRheU9mWWVhcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB5ZWFyOiByZXNZZWFyLFxuICAgICAgICAgICAgZGF5T2ZZZWFyOiByZXNEYXlPZlllYXJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3ZWVrT2ZZZWFyKG1vbSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIHdlZWtPZmZzZXQgPSBmaXJzdFdlZWtPZmZzZXQobW9tLnllYXIoKSwgZG93LCBkb3kpLFxuICAgICAgICAgICAgd2VlayA9IE1hdGguZmxvb3IoKG1vbS5kYXlPZlllYXIoKSAtIHdlZWtPZmZzZXQgLSAxKSAvIDcpICsgMSxcbiAgICAgICAgICAgIHJlc1dlZWssIHJlc1llYXI7XG5cbiAgICAgICAgaWYgKHdlZWsgPCAxKSB7XG4gICAgICAgICAgICByZXNZZWFyID0gbW9tLnllYXIoKSAtIDE7XG4gICAgICAgICAgICByZXNXZWVrID0gd2VlayArIHdlZWtzSW5ZZWFyKHJlc1llYXIsIGRvdywgZG95KTtcbiAgICAgICAgfSBlbHNlIGlmICh3ZWVrID4gd2Vla3NJblllYXIobW9tLnllYXIoKSwgZG93LCBkb3kpKSB7XG4gICAgICAgICAgICByZXNXZWVrID0gd2VlayAtIHdlZWtzSW5ZZWFyKG1vbS55ZWFyKCksIGRvdywgZG95KTtcbiAgICAgICAgICAgIHJlc1llYXIgPSBtb20ueWVhcigpICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc1llYXIgPSBtb20ueWVhcigpO1xuICAgICAgICAgICAgcmVzV2VlayA9IHdlZWs7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgd2VlazogcmVzV2VlayxcbiAgICAgICAgICAgIHllYXI6IHJlc1llYXJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3ZWVrc0luWWVhcih5ZWFyLCBkb3csIGRveSkge1xuICAgICAgICB2YXIgd2Vla09mZnNldCA9IGZpcnN0V2Vla09mZnNldCh5ZWFyLCBkb3csIGRveSksXG4gICAgICAgICAgICB3ZWVrT2Zmc2V0TmV4dCA9IGZpcnN0V2Vla09mZnNldCh5ZWFyICsgMSwgZG93LCBkb3kpO1xuICAgICAgICByZXR1cm4gKGRheXNJblllYXIoeWVhcikgLSB3ZWVrT2Zmc2V0ICsgd2Vla09mZnNldE5leHQpIC8gNztcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigndycsIFsnd3cnLCAyXSwgJ3dvJywgJ3dlZWsnKTtcbiAgICBhZGRGb3JtYXRUb2tlbignVycsIFsnV1cnLCAyXSwgJ1dvJywgJ2lzb1dlZWsnKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnd2VlaycsICd3Jyk7XG4gICAgYWRkVW5pdEFsaWFzKCdpc29XZWVrJywgJ1cnKTtcblxuICAgIC8vIFBSSU9SSVRJRVNcblxuICAgIGFkZFVuaXRQcmlvcml0eSgnd2VlaycsIDUpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2VlaycsIDUpO1xuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbigndycsICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ3d3JywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1cnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdXVycsIG1hdGNoMXRvMiwgbWF0Y2gyKTtcblxuICAgIGFkZFdlZWtQYXJzZVRva2VuKFsndycsICd3dycsICdXJywgJ1dXJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuLnN1YnN0cigwLCAxKV0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICAvLyBMT0NBTEVTXG5cbiAgICBmdW5jdGlvbiBsb2NhbGVXZWVrIChtb20pIHtcbiAgICAgICAgcmV0dXJuIHdlZWtPZlllYXIobW9tLCB0aGlzLl93ZWVrLmRvdywgdGhpcy5fd2Vlay5kb3kpLndlZWs7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb2NhbGVXZWVrID0ge1xuICAgICAgICBkb3cgOiAwLCAvLyBTdW5kYXkgaXMgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2Vlay5cbiAgICAgICAgZG95IDogNiAgLy8gVGhlIHdlZWsgdGhhdCBjb250YWlucyBKYW4gNnRoIGlzIHRoZSBmaXJzdCB3ZWVrIG9mIHRoZSB5ZWFyLlxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2NhbGVGaXJzdERheU9mV2VlayAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93ZWVrLmRvdztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsb2NhbGVGaXJzdERheU9mWWVhciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93ZWVrLmRveTtcbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBnZXRTZXRXZWVrIChpbnB1dCkge1xuICAgICAgICB2YXIgd2VlayA9IHRoaXMubG9jYWxlRGF0YSgpLndlZWsodGhpcyk7XG4gICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8gd2VlayA6IHRoaXMuYWRkKChpbnB1dCAtIHdlZWspICogNywgJ2QnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRJU09XZWVrIChpbnB1dCkge1xuICAgICAgICB2YXIgd2VlayA9IHdlZWtPZlllYXIodGhpcywgMSwgNCkud2VlaztcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrIDogdGhpcy5hZGQoKGlucHV0IC0gd2VlaykgKiA3LCAnZCcpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdkJywgMCwgJ2RvJywgJ2RheScpO1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ2RkJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkud2Vla2RheXNNaW4odGhpcywgZm9ybWF0KTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdkZGQnLCAwLCAwLCBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS53ZWVrZGF5c1Nob3J0KHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignZGRkZCcsIDAsIDAsIGZ1bmN0aW9uIChmb3JtYXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLndlZWtkYXlzKHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignZScsIDAsIDAsICd3ZWVrZGF5Jyk7XG4gICAgYWRkRm9ybWF0VG9rZW4oJ0UnLCAwLCAwLCAnaXNvV2Vla2RheScpO1xuXG4gICAgLy8gQUxJQVNFU1xuXG4gICAgYWRkVW5pdEFsaWFzKCdkYXknLCAnZCcpO1xuICAgIGFkZFVuaXRBbGlhcygnd2Vla2RheScsICdlJyk7XG4gICAgYWRkVW5pdEFsaWFzKCdpc29XZWVrZGF5JywgJ0UnKTtcblxuICAgIC8vIFBSSU9SSVRZXG4gICAgYWRkVW5pdFByaW9yaXR5KCdkYXknLCAxMSk7XG4gICAgYWRkVW5pdFByaW9yaXR5KCd3ZWVrZGF5JywgMTEpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2Vla2RheScsIDExKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ2QnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2UnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0UnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkJywgICBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLndlZWtkYXlzTWluUmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkZCcsICAgZnVuY3Rpb24gKGlzU3RyaWN0LCBsb2NhbGUpIHtcbiAgICAgICAgcmV0dXJuIGxvY2FsZS53ZWVrZGF5c1Nob3J0UmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkZGQnLCAgIGZ1bmN0aW9uIChpc1N0cmljdCwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUud2Vla2RheXNSZWdleChpc1N0cmljdCk7XG4gICAgfSk7XG5cbiAgICBhZGRXZWVrUGFyc2VUb2tlbihbJ2RkJywgJ2RkZCcsICdkZGRkJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB2YXIgd2Vla2RheSA9IGNvbmZpZy5fbG9jYWxlLndlZWtkYXlzUGFyc2UoaW5wdXQsIHRva2VuLCBjb25maWcuX3N0cmljdCk7XG4gICAgICAgIC8vIGlmIHdlIGRpZG4ndCBnZXQgYSB3ZWVrZGF5IG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZFxuICAgICAgICBpZiAod2Vla2RheSAhPSBudWxsKSB7XG4gICAgICAgICAgICB3ZWVrLmQgPSB3ZWVrZGF5O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuaW52YWxpZFdlZWtkYXkgPSBpbnB1dDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgYWRkV2Vla1BhcnNlVG9rZW4oWydkJywgJ2UnLCAnRSddLCBmdW5jdGlvbiAoaW5wdXQsIHdlZWssIGNvbmZpZywgdG9rZW4pIHtcbiAgICAgICAgd2Vla1t0b2tlbl0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICBmdW5jdGlvbiBwYXJzZVdlZWtkYXkoaW5wdXQsIGxvY2FsZSkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc05hTihpbnB1dCkpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUludChpbnB1dCwgMTApO1xuICAgICAgICB9XG5cbiAgICAgICAgaW5wdXQgPSBsb2NhbGUud2Vla2RheXNQYXJzZShpbnB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZUlzb1dlZWtkYXkoaW5wdXQsIGxvY2FsZSkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS53ZWVrZGF5c1BhcnNlKGlucHV0KSAlIDcgfHwgNztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNOYU4oaW5wdXQpID8gbnVsbCA6IGlucHV0O1xuICAgIH1cblxuICAgIC8vIExPQ0FMRVNcbiAgICBmdW5jdGlvbiBzaGlmdFdlZWtkYXlzICh3cywgbikge1xuICAgICAgICByZXR1cm4gd3Muc2xpY2UobiwgNykuY29uY2F0KHdzLnNsaWNlKDAsIG4pKTtcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdExvY2FsZVdlZWtkYXlzID0gJ1N1bmRheV9Nb25kYXlfVHVlc2RheV9XZWRuZXNkYXlfVGh1cnNkYXlfRnJpZGF5X1NhdHVyZGF5Jy5zcGxpdCgnXycpO1xuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzIChtLCBmb3JtYXQpIHtcbiAgICAgICAgdmFyIHdlZWtkYXlzID0gaXNBcnJheSh0aGlzLl93ZWVrZGF5cykgPyB0aGlzLl93ZWVrZGF5cyA6XG4gICAgICAgICAgICB0aGlzLl93ZWVrZGF5c1sobSAmJiBtICE9PSB0cnVlICYmIHRoaXMuX3dlZWtkYXlzLmlzRm9ybWF0LnRlc3QoZm9ybWF0KSkgPyAnZm9ybWF0JyA6ICdzdGFuZGFsb25lJ107XG4gICAgICAgIHJldHVybiAobSA9PT0gdHJ1ZSkgPyBzaGlmdFdlZWtkYXlzKHdlZWtkYXlzLCB0aGlzLl93ZWVrLmRvdylcbiAgICAgICAgICAgIDogKG0pID8gd2Vla2RheXNbbS5kYXkoKV0gOiB3ZWVrZGF5cztcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdExvY2FsZVdlZWtkYXlzU2hvcnQgPSAnU3VuX01vbl9UdWVfV2VkX1RodV9GcmlfU2F0Jy5zcGxpdCgnXycpO1xuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzU2hvcnQgKG0pIHtcbiAgICAgICAgcmV0dXJuIChtID09PSB0cnVlKSA/IHNoaWZ0V2Vla2RheXModGhpcy5fd2Vla2RheXNTaG9ydCwgdGhpcy5fd2Vlay5kb3cpXG4gICAgICAgICAgICA6IChtKSA/IHRoaXMuX3dlZWtkYXlzU2hvcnRbbS5kYXkoKV0gOiB0aGlzLl93ZWVrZGF5c1Nob3J0O1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TG9jYWxlV2Vla2RheXNNaW4gPSAnU3VfTW9fVHVfV2VfVGhfRnJfU2EnLnNwbGl0KCdfJyk7XG4gICAgZnVuY3Rpb24gbG9jYWxlV2Vla2RheXNNaW4gKG0pIHtcbiAgICAgICAgcmV0dXJuIChtID09PSB0cnVlKSA/IHNoaWZ0V2Vla2RheXModGhpcy5fd2Vla2RheXNNaW4sIHRoaXMuX3dlZWsuZG93KVxuICAgICAgICAgICAgOiAobSkgPyB0aGlzLl93ZWVrZGF5c01pblttLmRheSgpXSA6IHRoaXMuX3dlZWtkYXlzTWluO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZVN0cmljdFBhcnNlJDEod2Vla2RheU5hbWUsIGZvcm1hdCwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBpLCBpaSwgbW9tLCBsbGMgPSB3ZWVrZGF5TmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fbWluV2Vla2RheXNQYXJzZSA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNzsgKytpKSB7XG4gICAgICAgICAgICAgICAgbW9tID0gY3JlYXRlVVRDKFsyMDAwLCAxXSkuZGF5KGkpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21pbldlZWtkYXlzUGFyc2VbaV0gPSB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRXZWVrZGF5c1BhcnNlW2ldID0gdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZVtpXSA9IHRoaXMud2Vla2RheXMobW9tLCAnJykudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdkZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3dlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9taW5XZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpaSAhPT0gLTEgPyBpaSA6IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoZm9ybWF0ID09PSAnZGRkZCcpIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl93ZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9zaG9ydFdlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgaWYgKGlpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX21pbldlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fd2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fbWluV2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9taW5XZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl93ZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9zaG9ydFdlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzUGFyc2UgKHdlZWtkYXlOYW1lLCBmb3JtYXQsIHN0cmljdCkge1xuICAgICAgICB2YXIgaSwgbW9tLCByZWdleDtcblxuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlU3RyaWN0UGFyc2UkMS5jYWxsKHRoaXMsIHdlZWtkYXlOYW1lLCBmb3JtYXQsIHN0cmljdCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX21pbldlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fZnVsbFdlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuXG4gICAgICAgICAgICBtb20gPSBjcmVhdGVVVEMoWzIwMDAsIDFdKS5kYXkoaSk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmICF0aGlzLl9mdWxsV2Vla2RheXNQYXJzZVtpXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2Z1bGxXZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnXFxcXC4/JykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRXZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzU2hvcnQobW9tLCAnJykucmVwbGFjZSgnLicsICdcXFxcLj8nKSArICckJywgJ2knKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9taW5XZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnXFxcXC4/JykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICByZWdleCA9ICdeJyArIHRoaXMud2Vla2RheXMobW9tLCAnJykgKyAnfF4nICsgdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpICsgJ3xeJyArIHRoaXMud2Vla2RheXNNaW4obW9tLCAnJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZVtpXSA9IG5ldyBSZWdFeHAocmVnZXgucmVwbGFjZSgnLicsICcnKSwgJ2knKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHRlc3QgdGhlIHJlZ2V4XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmIGZvcm1hdCA9PT0gJ2RkZGQnICYmIHRoaXMuX2Z1bGxXZWVrZGF5c1BhcnNlW2ldLnRlc3Qod2Vla2RheU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmljdCAmJiBmb3JtYXQgPT09ICdkZGQnICYmIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZVtpXS50ZXN0KHdlZWtkYXlOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnZGQnICYmIHRoaXMuX21pbldlZWtkYXlzUGFyc2VbaV0udGVzdCh3ZWVrZGF5TmFtZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXN0cmljdCAmJiB0aGlzLl93ZWVrZGF5c1BhcnNlW2ldLnRlc3Qod2Vla2RheU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBnZXRTZXREYXlPZldlZWsgKGlucHV0KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnB1dCAhPSBudWxsID8gdGhpcyA6IE5hTjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF5ID0gdGhpcy5faXNVVEMgPyB0aGlzLl9kLmdldFVUQ0RheSgpIDogdGhpcy5fZC5nZXREYXkoKTtcbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlucHV0ID0gcGFyc2VXZWVrZGF5KGlucHV0LCB0aGlzLmxvY2FsZURhdGEoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGQoaW5wdXQgLSBkYXksICdkJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZGF5O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2V0TG9jYWxlRGF5T2ZXZWVrIChpbnB1dCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgIT0gbnVsbCA/IHRoaXMgOiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHdlZWtkYXkgPSAodGhpcy5kYXkoKSArIDcgLSB0aGlzLmxvY2FsZURhdGEoKS5fd2Vlay5kb3cpICUgNztcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrZGF5IDogdGhpcy5hZGQoaW5wdXQgLSB3ZWVrZGF5LCAnZCcpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNldElTT0RheU9mV2VlayAoaW5wdXQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0ICE9IG51bGwgPyB0aGlzIDogTmFOO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYmVoYXZlcyB0aGUgc2FtZSBhcyBtb21lbnQjZGF5IGV4Y2VwdFxuICAgICAgICAvLyBhcyBhIGdldHRlciwgcmV0dXJucyA3IGluc3RlYWQgb2YgMCAoMS03IHJhbmdlIGluc3RlYWQgb2YgMC02KVxuICAgICAgICAvLyBhcyBhIHNldHRlciwgc3VuZGF5IHNob3VsZCBiZWxvbmcgdG8gdGhlIHByZXZpb3VzIHdlZWsuXG5cbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhciB3ZWVrZGF5ID0gcGFyc2VJc29XZWVrZGF5KGlucHV0LCB0aGlzLmxvY2FsZURhdGEoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kYXkodGhpcy5kYXkoKSAlIDcgPyB3ZWVrZGF5IDogd2Vla2RheSAtIDcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF5KCkgfHwgNztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0V2Vla2RheXNSZWdleCA9IG1hdGNoV29yZDtcbiAgICBmdW5jdGlvbiB3ZWVrZGF5c1JlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wKHRoaXMsICdfd2Vla2RheXNSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNSZWdleCA9IGRlZmF1bHRXZWVrZGF5c1JlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggOiB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRXZWVrZGF5c1Nob3J0UmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gd2Vla2RheXNTaG9ydFJlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU2hvcnRTdHJpY3RSZWdleDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX3dlZWtkYXlzU2hvcnRSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNTaG9ydFJlZ2V4ID0gZGVmYXVsdFdlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c1Nob3J0U3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzU2hvcnRTdHJpY3RSZWdleCA6IHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0V2Vla2RheXNNaW5SZWdleCA9IG1hdGNoV29yZDtcbiAgICBmdW5jdGlvbiB3ZWVrZGF5c01pblJlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wKHRoaXMsICdfd2Vla2RheXNNaW5SZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNNaW5SZWdleCA9IGRlZmF1bHRXZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXggOiB0aGlzLl93ZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjb21wdXRlV2Vla2RheXNQYXJzZSAoKSB7XG4gICAgICAgIGZ1bmN0aW9uIGNtcExlblJldihhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi5sZW5ndGggLSBhLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtaW5QaWVjZXMgPSBbXSwgc2hvcnRQaWVjZXMgPSBbXSwgbG9uZ1BpZWNlcyA9IFtdLCBtaXhlZFBpZWNlcyA9IFtdLFxuICAgICAgICAgICAgaSwgbW9tLCBtaW5wLCBzaG9ydHAsIGxvbmdwO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNzsgaSsrKSB7XG4gICAgICAgICAgICAvLyBtYWtlIHRoZSByZWdleCBpZiB3ZSBkb24ndCBoYXZlIGl0IGFscmVhZHlcbiAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgMV0pLmRheShpKTtcbiAgICAgICAgICAgIG1pbnAgPSB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpO1xuICAgICAgICAgICAgc2hvcnRwID0gdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpO1xuICAgICAgICAgICAgbG9uZ3AgPSB0aGlzLndlZWtkYXlzKG1vbSwgJycpO1xuICAgICAgICAgICAgbWluUGllY2VzLnB1c2gobWlucCk7XG4gICAgICAgICAgICBzaG9ydFBpZWNlcy5wdXNoKHNob3J0cCk7XG4gICAgICAgICAgICBsb25nUGllY2VzLnB1c2gobG9uZ3ApO1xuICAgICAgICAgICAgbWl4ZWRQaWVjZXMucHVzaChtaW5wKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2goc2hvcnRwKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2gobG9uZ3ApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNvcnRpbmcgbWFrZXMgc3VyZSBpZiBvbmUgd2Vla2RheSAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlciBpdFxuICAgICAgICAvLyB3aWxsIG1hdGNoIHRoZSBsb25nZXIgcGllY2UuXG4gICAgICAgIG1pblBpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIHNob3J0UGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgbG9uZ1BpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIG1peGVkUGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDc7IGkrKykge1xuICAgICAgICAgICAgc2hvcnRQaWVjZXNbaV0gPSByZWdleEVzY2FwZShzaG9ydFBpZWNlc1tpXSk7XG4gICAgICAgICAgICBsb25nUGllY2VzW2ldID0gcmVnZXhFc2NhcGUobG9uZ1BpZWNlc1tpXSk7XG4gICAgICAgICAgICBtaXhlZFBpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKG1peGVkUGllY2VzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3dlZWtkYXlzUmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBtaXhlZFBpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgICAgIHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleCA9IHRoaXMuX3dlZWtkYXlzUmVnZXg7XG4gICAgICAgIHRoaXMuX3dlZWtkYXlzTWluUmVnZXggPSB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuXG4gICAgICAgIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBsb25nUGllY2VzLmpvaW4oJ3wnKSArICcpJywgJ2knKTtcbiAgICAgICAgdGhpcy5fd2Vla2RheXNTaG9ydFN0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgc2hvcnRQaWVjZXMuam9pbignfCcpICsgJyknLCAnaScpO1xuICAgICAgICB0aGlzLl93ZWVrZGF5c01pblN0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbWluUGllY2VzLmpvaW4oJ3wnKSArICcpJywgJ2knKTtcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBmdW5jdGlvbiBoRm9ybWF0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ob3VycygpICUgMTIgfHwgMTI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24ga0Zvcm1hdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaG91cnMoKSB8fCAyNDtcbiAgICB9XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSCcsIFsnSEgnLCAyXSwgMCwgJ2hvdXInKTtcbiAgICBhZGRGb3JtYXRUb2tlbignaCcsIFsnaGgnLCAyXSwgMCwgaEZvcm1hdCk7XG4gICAgYWRkRm9ybWF0VG9rZW4oJ2snLCBbJ2trJywgMl0sIDAsIGtGb3JtYXQpO1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ2htbScsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnICsgaEZvcm1hdC5hcHBseSh0aGlzKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdobW1zcycsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnICsgaEZvcm1hdC5hcHBseSh0aGlzKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKSArXG4gICAgICAgICAgICB6ZXJvRmlsbCh0aGlzLnNlY29uZHMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSG1tJywgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gJycgKyB0aGlzLmhvdXJzKCkgKyB6ZXJvRmlsbCh0aGlzLm1pbnV0ZXMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSG1tc3MnLCAwLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAnJyArIHRoaXMuaG91cnMoKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKSArXG4gICAgICAgICAgICB6ZXJvRmlsbCh0aGlzLnNlY29uZHMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBtZXJpZGllbSAodG9rZW4sIGxvd2VyY2FzZSkge1xuICAgICAgICBhZGRGb3JtYXRUb2tlbih0b2tlbiwgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLm1lcmlkaWVtKHRoaXMuaG91cnMoKSwgdGhpcy5taW51dGVzKCksIGxvd2VyY2FzZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG1lcmlkaWVtKCdhJywgdHJ1ZSk7XG4gICAgbWVyaWRpZW0oJ0EnLCBmYWxzZSk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ2hvdXInLCAnaCcpO1xuXG4gICAgLy8gUFJJT1JJVFlcbiAgICBhZGRVbml0UHJpb3JpdHkoJ2hvdXInLCAxMyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBmdW5jdGlvbiBtYXRjaE1lcmlkaWVtIChpc1N0cmljdCwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUuX21lcmlkaWVtUGFyc2U7XG4gICAgfVxuXG4gICAgYWRkUmVnZXhUb2tlbignYScsICBtYXRjaE1lcmlkaWVtKTtcbiAgICBhZGRSZWdleFRva2VuKCdBJywgIG1hdGNoTWVyaWRpZW0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0gnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdoJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignaycsICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0hIJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2hoJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2trJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuXG4gICAgYWRkUmVnZXhUb2tlbignaG1tJywgbWF0Y2gzdG80KTtcbiAgICBhZGRSZWdleFRva2VuKCdobW1zcycsIG1hdGNoNXRvNik7XG4gICAgYWRkUmVnZXhUb2tlbignSG1tJywgbWF0Y2gzdG80KTtcbiAgICBhZGRSZWdleFRva2VuKCdIbW1zcycsIG1hdGNoNXRvNik7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnSCcsICdISCddLCBIT1VSKTtcbiAgICBhZGRQYXJzZVRva2VuKFsnaycsICdrayddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIGtJbnB1dCA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgYXJyYXlbSE9VUl0gPSBrSW5wdXQgPT09IDI0ID8gMCA6IGtJbnB1dDtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKFsnYScsICdBJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2lzUG0gPSBjb25maWcuX2xvY2FsZS5pc1BNKGlucHV0KTtcbiAgICAgICAgY29uZmlnLl9tZXJpZGllbSA9IGlucHV0O1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oWydoJywgJ2hoJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuYmlnSG91ciA9IHRydWU7XG4gICAgfSk7XG4gICAgYWRkUGFyc2VUb2tlbignaG1tJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIHZhciBwb3MgPSBpbnB1dC5sZW5ndGggLSAyO1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0LnN1YnN0cigwLCBwb3MpKTtcbiAgICAgICAgYXJyYXlbTUlOVVRFXSA9IHRvSW50KGlucHV0LnN1YnN0cihwb3MpKTtcbiAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuYmlnSG91ciA9IHRydWU7XG4gICAgfSk7XG4gICAgYWRkUGFyc2VUb2tlbignaG1tc3MnLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIHBvczEgPSBpbnB1dC5sZW5ndGggLSA0O1xuICAgICAgICB2YXIgcG9zMiA9IGlucHV0Lmxlbmd0aCAtIDI7XG4gICAgICAgIGFycmF5W0hPVVJdID0gdG9JbnQoaW5wdXQuc3Vic3RyKDAsIHBvczEpKTtcbiAgICAgICAgYXJyYXlbTUlOVVRFXSA9IHRvSW50KGlucHV0LnN1YnN0cihwb3MxLCAyKSk7XG4gICAgICAgIGFycmF5W1NFQ09ORF0gPSB0b0ludChpbnB1dC5zdWJzdHIocG9zMikpO1xuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5iaWdIb3VyID0gdHJ1ZTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCdIbW0nLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIHBvcyA9IGlucHV0Lmxlbmd0aCAtIDI7XG4gICAgICAgIGFycmF5W0hPVVJdID0gdG9JbnQoaW5wdXQuc3Vic3RyKDAsIHBvcykpO1xuICAgICAgICBhcnJheVtNSU5VVEVdID0gdG9JbnQoaW5wdXQuc3Vic3RyKHBvcykpO1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oJ0htbXNzJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIHZhciBwb3MxID0gaW5wdXQubGVuZ3RoIC0gNDtcbiAgICAgICAgdmFyIHBvczIgPSBpbnB1dC5sZW5ndGggLSAyO1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0LnN1YnN0cigwLCBwb3MxKSk7XG4gICAgICAgIGFycmF5W01JTlVURV0gPSB0b0ludChpbnB1dC5zdWJzdHIocG9zMSwgMikpO1xuICAgICAgICBhcnJheVtTRUNPTkRdID0gdG9JbnQoaW5wdXQuc3Vic3RyKHBvczIpKTtcbiAgICB9KTtcblxuICAgIC8vIExPQ0FMRVNcblxuICAgIGZ1bmN0aW9uIGxvY2FsZUlzUE0gKGlucHV0KSB7XG4gICAgICAgIC8vIElFOCBRdWlya3MgTW9kZSAmIElFNyBTdGFuZGFyZHMgTW9kZSBkbyBub3QgYWxsb3cgYWNjZXNzaW5nIHN0cmluZ3MgbGlrZSBhcnJheXNcbiAgICAgICAgLy8gVXNpbmcgY2hhckF0IHNob3VsZCBiZSBtb3JlIGNvbXBhdGlibGUuXG4gICAgICAgIHJldHVybiAoKGlucHV0ICsgJycpLnRvTG93ZXJDYXNlKCkuY2hhckF0KDApID09PSAncCcpO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TG9jYWxlTWVyaWRpZW1QYXJzZSA9IC9bYXBdXFwuP20/XFwuPy9pO1xuICAgIGZ1bmN0aW9uIGxvY2FsZU1lcmlkaWVtIChob3VycywgbWludXRlcywgaXNMb3dlcikge1xuICAgICAgICBpZiAoaG91cnMgPiAxMSkge1xuICAgICAgICAgICAgcmV0dXJuIGlzTG93ZXIgPyAncG0nIDogJ1BNJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBpc0xvd2VyID8gJ2FtJyA6ICdBTSc7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8vIE1PTUVOVFNcblxuICAgIC8vIFNldHRpbmcgdGhlIGhvdXIgc2hvdWxkIGtlZXAgdGhlIHRpbWUsIGJlY2F1c2UgdGhlIHVzZXIgZXhwbGljaXRseVxuICAgIC8vIHNwZWNpZmllZCB3aGljaCBob3VyIHRoZXkgd2FudC4gU28gdHJ5aW5nIHRvIG1haW50YWluIHRoZSBzYW1lIGhvdXIgKGluXG4gICAgLy8gYSBuZXcgdGltZXpvbmUpIG1ha2VzIHNlbnNlLiBBZGRpbmcvc3VidHJhY3RpbmcgaG91cnMgZG9lcyBub3QgZm9sbG93XG4gICAgLy8gdGhpcyBydWxlLlxuICAgIHZhciBnZXRTZXRIb3VyID0gbWFrZUdldFNldCgnSG91cnMnLCB0cnVlKTtcblxuICAgIHZhciBiYXNlQ29uZmlnID0ge1xuICAgICAgICBjYWxlbmRhcjogZGVmYXVsdENhbGVuZGFyLFxuICAgICAgICBsb25nRGF0ZUZvcm1hdDogZGVmYXVsdExvbmdEYXRlRm9ybWF0LFxuICAgICAgICBpbnZhbGlkRGF0ZTogZGVmYXVsdEludmFsaWREYXRlLFxuICAgICAgICBvcmRpbmFsOiBkZWZhdWx0T3JkaW5hbCxcbiAgICAgICAgZGF5T2ZNb250aE9yZGluYWxQYXJzZTogZGVmYXVsdERheU9mTW9udGhPcmRpbmFsUGFyc2UsXG4gICAgICAgIHJlbGF0aXZlVGltZTogZGVmYXVsdFJlbGF0aXZlVGltZSxcblxuICAgICAgICBtb250aHM6IGRlZmF1bHRMb2NhbGVNb250aHMsXG4gICAgICAgIG1vbnRoc1Nob3J0OiBkZWZhdWx0TG9jYWxlTW9udGhzU2hvcnQsXG5cbiAgICAgICAgd2VlazogZGVmYXVsdExvY2FsZVdlZWssXG5cbiAgICAgICAgd2Vla2RheXM6IGRlZmF1bHRMb2NhbGVXZWVrZGF5cyxcbiAgICAgICAgd2Vla2RheXNNaW46IGRlZmF1bHRMb2NhbGVXZWVrZGF5c01pbixcbiAgICAgICAgd2Vla2RheXNTaG9ydDogZGVmYXVsdExvY2FsZVdlZWtkYXlzU2hvcnQsXG5cbiAgICAgICAgbWVyaWRpZW1QYXJzZTogZGVmYXVsdExvY2FsZU1lcmlkaWVtUGFyc2VcbiAgICB9O1xuXG4gICAgLy8gaW50ZXJuYWwgc3RvcmFnZSBmb3IgbG9jYWxlIGNvbmZpZyBmaWxlc1xuICAgIHZhciBsb2NhbGVzID0ge307XG4gICAgdmFyIGxvY2FsZUZhbWlsaWVzID0ge307XG4gICAgdmFyIGdsb2JhbExvY2FsZTtcblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZUxvY2FsZShrZXkpIHtcbiAgICAgICAgcmV0dXJuIGtleSA/IGtleS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoJ18nLCAnLScpIDoga2V5O1xuICAgIH1cblxuICAgIC8vIHBpY2sgdGhlIGxvY2FsZSBmcm9tIHRoZSBhcnJheVxuICAgIC8vIHRyeSBbJ2VuLWF1JywgJ2VuLWdiJ10gYXMgJ2VuLWF1JywgJ2VuLWdiJywgJ2VuJywgYXMgaW4gbW92ZSB0aHJvdWdoIHRoZSBsaXN0IHRyeWluZyBlYWNoXG4gICAgLy8gc3Vic3RyaW5nIGZyb20gbW9zdCBzcGVjaWZpYyB0byBsZWFzdCwgYnV0IG1vdmUgdG8gdGhlIG5leHQgYXJyYXkgaXRlbSBpZiBpdCdzIGEgbW9yZSBzcGVjaWZpYyB2YXJpYW50IHRoYW4gdGhlIGN1cnJlbnQgcm9vdFxuICAgIGZ1bmN0aW9uIGNob29zZUxvY2FsZShuYW1lcykge1xuICAgICAgICB2YXIgaSA9IDAsIGosIG5leHQsIGxvY2FsZSwgc3BsaXQ7XG5cbiAgICAgICAgd2hpbGUgKGkgPCBuYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHNwbGl0ID0gbm9ybWFsaXplTG9jYWxlKG5hbWVzW2ldKS5zcGxpdCgnLScpO1xuICAgICAgICAgICAgaiA9IHNwbGl0Lmxlbmd0aDtcbiAgICAgICAgICAgIG5leHQgPSBub3JtYWxpemVMb2NhbGUobmFtZXNbaSArIDFdKTtcbiAgICAgICAgICAgIG5leHQgPSBuZXh0ID8gbmV4dC5zcGxpdCgnLScpIDogbnVsbDtcbiAgICAgICAgICAgIHdoaWxlIChqID4gMCkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGxvYWRMb2NhbGUoc3BsaXQuc2xpY2UoMCwgaikuam9pbignLScpKTtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChuZXh0ICYmIG5leHQubGVuZ3RoID49IGogJiYgY29tcGFyZUFycmF5cyhzcGxpdCwgbmV4dCwgdHJ1ZSkgPj0gaiAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgLy90aGUgbmV4dCBhcnJheSBpdGVtIGlzIGJldHRlciB0aGFuIGEgc2hhbGxvd2VyIHN1YnN0cmluZyBvZiB0aGlzIG9uZVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgai0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9hZExvY2FsZShuYW1lKSB7XG4gICAgICAgIHZhciBvbGRMb2NhbGUgPSBudWxsO1xuICAgICAgICAvLyBUT0RPOiBGaW5kIGEgYmV0dGVyIHdheSB0byByZWdpc3RlciBhbmQgbG9hZCBhbGwgdGhlIGxvY2FsZXMgaW4gTm9kZVxuICAgICAgICBpZiAoIWxvY2FsZXNbbmFtZV0gJiYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgICAgICAgICAgIG1vZHVsZSAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBvbGRMb2NhbGUgPSBnbG9iYWxMb2NhbGUuX2FiYnI7XG4gICAgICAgICAgICAgICAgdmFyIGFsaWFzZWRSZXF1aXJlID0gcmVxdWlyZTtcbiAgICAgICAgICAgICAgICBhbGlhc2VkUmVxdWlyZSgnLi9sb2NhbGUvJyArIG5hbWUpO1xuICAgICAgICAgICAgICAgIGdldFNldEdsb2JhbExvY2FsZShvbGRMb2NhbGUpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbG9jYWxlc1tuYW1lXTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgbG9hZCBsb2NhbGUgYW5kIHRoZW4gc2V0IHRoZSBnbG9iYWwgbG9jYWxlLiAgSWZcbiAgICAvLyBubyBhcmd1bWVudHMgYXJlIHBhc3NlZCBpbiwgaXQgd2lsbCBzaW1wbHkgcmV0dXJuIHRoZSBjdXJyZW50IGdsb2JhbFxuICAgIC8vIGxvY2FsZSBrZXkuXG4gICAgZnVuY3Rpb24gZ2V0U2V0R2xvYmFsTG9jYWxlIChrZXksIHZhbHVlcykge1xuICAgICAgICB2YXIgZGF0YTtcbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlcykpIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZ2V0TG9jYWxlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZGVmaW5lTG9jYWxlKGtleSwgdmFsdWVzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAvLyBtb21lbnQuZHVyYXRpb24uX2xvY2FsZSA9IG1vbWVudC5fbG9jYWxlID0gZGF0YTtcbiAgICAgICAgICAgICAgICBnbG9iYWxMb2NhbGUgPSBkYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKCh0eXBlb2YgY29uc29sZSAhPT0gICd1bmRlZmluZWQnKSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICAgICAgICAgICAgLy93YXJuIHVzZXIgaWYgYXJndW1lbnRzIGFyZSBwYXNzZWQgYnV0IHRoZSBsb2NhbGUgY291bGQgbm90IGJlIHNldFxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0xvY2FsZSAnICsga2V5ICsgICcgbm90IGZvdW5kLiBEaWQgeW91IGZvcmdldCB0byBsb2FkIGl0PycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGUuX2FiYnI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmaW5lTG9jYWxlIChuYW1lLCBjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxvY2FsZSwgcGFyZW50Q29uZmlnID0gYmFzZUNvbmZpZztcbiAgICAgICAgICAgIGNvbmZpZy5hYmJyID0gbmFtZTtcbiAgICAgICAgICAgIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkZXByZWNhdGVTaW1wbGUoJ2RlZmluZUxvY2FsZU92ZXJyaWRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICd1c2UgbW9tZW50LnVwZGF0ZUxvY2FsZShsb2NhbGVOYW1lLCBjb25maWcpIHRvIGNoYW5nZSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdhbiBleGlzdGluZyBsb2NhbGUuIG1vbWVudC5kZWZpbmVMb2NhbGUobG9jYWxlTmFtZSwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnY29uZmlnKSBzaG91bGQgb25seSBiZSB1c2VkIGZvciBjcmVhdGluZyBhIG5ldyBsb2NhbGUgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnU2VlIGh0dHA6Ly9tb21lbnRqcy5jb20vZ3VpZGVzLyMvd2FybmluZ3MvZGVmaW5lLWxvY2FsZS8gZm9yIG1vcmUgaW5mby4nKTtcbiAgICAgICAgICAgICAgICBwYXJlbnRDb25maWcgPSBsb2NhbGVzW25hbWVdLl9jb25maWc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNvbmZpZy5wYXJlbnRMb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChsb2NhbGVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29uZmlnID0gbG9jYWxlc1tjb25maWcucGFyZW50TG9jYWxlXS5fY29uZmlnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvY2FsZSA9IGxvYWRMb2NhbGUoY29uZmlnLnBhcmVudExvY2FsZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29uZmlnID0gbG9jYWxlLl9jb25maWc7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWxvY2FsZUZhbWlsaWVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlRmFtaWxpZXNbY29uZmlnLnBhcmVudExvY2FsZV0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsZUZhbWlsaWVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnOiBjb25maWdcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhbGVzW25hbWVdID0gbmV3IExvY2FsZShtZXJnZUNvbmZpZ3MocGFyZW50Q29uZmlnLCBjb25maWcpKTtcblxuICAgICAgICAgICAgaWYgKGxvY2FsZUZhbWlsaWVzW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgbG9jYWxlRmFtaWxpZXNbbmFtZV0uZm9yRWFjaChmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgICAgICAgICBkZWZpbmVMb2NhbGUoeC5uYW1lLCB4LmNvbmZpZyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgZm9yIG5vdzogYWxzbyBzZXQgdGhlIGxvY2FsZVxuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHdlIHNldCB0aGUgbG9jYWxlIEFGVEVSIGFsbCBjaGlsZCBsb2NhbGVzIGhhdmUgYmVlblxuICAgICAgICAgICAgLy8gY3JlYXRlZCwgc28gd2Ugd29uJ3QgZW5kIHVwIHdpdGggdGhlIGNoaWxkIGxvY2FsZSBzZXQuXG4gICAgICAgICAgICBnZXRTZXRHbG9iYWxMb2NhbGUobmFtZSk7XG5cblxuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZXNbbmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyB1c2VmdWwgZm9yIHRlc3RpbmdcbiAgICAgICAgICAgIGRlbGV0ZSBsb2NhbGVzW25hbWVdO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1cGRhdGVMb2NhbGUobmFtZSwgY29uZmlnKSB7XG4gICAgICAgIGlmIChjb25maWcgIT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxvY2FsZSwgdG1wTG9jYWxlLCBwYXJlbnRDb25maWcgPSBiYXNlQ29uZmlnO1xuICAgICAgICAgICAgLy8gTUVSR0VcbiAgICAgICAgICAgIHRtcExvY2FsZSA9IGxvYWRMb2NhbGUobmFtZSk7XG4gICAgICAgICAgICBpZiAodG1wTG9jYWxlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnRDb25maWcgPSB0bXBMb2NhbGUuX2NvbmZpZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbmZpZyA9IG1lcmdlQ29uZmlncyhwYXJlbnRDb25maWcsIGNvbmZpZyk7XG4gICAgICAgICAgICBsb2NhbGUgPSBuZXcgTG9jYWxlKGNvbmZpZyk7XG4gICAgICAgICAgICBsb2NhbGUucGFyZW50TG9jYWxlID0gbG9jYWxlc1tuYW1lXTtcbiAgICAgICAgICAgIGxvY2FsZXNbbmFtZV0gPSBsb2NhbGU7XG5cbiAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgZm9yIG5vdzogYWxzbyBzZXQgdGhlIGxvY2FsZVxuICAgICAgICAgICAgZ2V0U2V0R2xvYmFsTG9jYWxlKG5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gcGFzcyBudWxsIGZvciBjb25maWcgdG8gdW51cGRhdGUsIHVzZWZ1bCBmb3IgdGVzdHNcbiAgICAgICAgICAgIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxlc1tuYW1lXS5wYXJlbnRMb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBsb2NhbGVzW25hbWVdID0gbG9jYWxlc1tuYW1lXS5wYXJlbnRMb2NhbGU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGxvY2FsZXNbbmFtZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsb2NhbGVzW25hbWVdO1xuICAgIH1cblxuICAgIC8vIHJldHVybnMgbG9jYWxlIGRhdGFcbiAgICBmdW5jdGlvbiBnZXRMb2NhbGUgKGtleSkge1xuICAgICAgICB2YXIgbG9jYWxlO1xuXG4gICAgICAgIGlmIChrZXkgJiYga2V5Ll9sb2NhbGUgJiYga2V5Ll9sb2NhbGUuX2FiYnIpIHtcbiAgICAgICAgICAgIGtleSA9IGtleS5fbG9jYWxlLl9hYmJyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFrZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzQXJyYXkoa2V5KSkge1xuICAgICAgICAgICAgLy9zaG9ydC1jaXJjdWl0IGV2ZXJ5dGhpbmcgZWxzZVxuICAgICAgICAgICAgbG9jYWxlID0gbG9hZExvY2FsZShrZXkpO1xuICAgICAgICAgICAgaWYgKGxvY2FsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBrZXkgPSBba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjaG9vc2VMb2NhbGUoa2V5KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0TG9jYWxlcygpIHtcbiAgICAgICAgcmV0dXJuIGtleXMobG9jYWxlcyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2tPdmVyZmxvdyAobSkge1xuICAgICAgICB2YXIgb3ZlcmZsb3c7XG4gICAgICAgIHZhciBhID0gbS5fYTtcblxuICAgICAgICBpZiAoYSAmJiBnZXRQYXJzaW5nRmxhZ3MobSkub3ZlcmZsb3cgPT09IC0yKSB7XG4gICAgICAgICAgICBvdmVyZmxvdyA9XG4gICAgICAgICAgICAgICAgYVtNT05USF0gICAgICAgPCAwIHx8IGFbTU9OVEhdICAgICAgID4gMTEgID8gTU9OVEggOlxuICAgICAgICAgICAgICAgIGFbREFURV0gICAgICAgIDwgMSB8fCBhW0RBVEVdICAgICAgICA+IGRheXNJbk1vbnRoKGFbWUVBUl0sIGFbTU9OVEhdKSA/IERBVEUgOlxuICAgICAgICAgICAgICAgIGFbSE9VUl0gICAgICAgIDwgMCB8fCBhW0hPVVJdICAgICAgICA+IDI0IHx8IChhW0hPVVJdID09PSAyNCAmJiAoYVtNSU5VVEVdICE9PSAwIHx8IGFbU0VDT05EXSAhPT0gMCB8fCBhW01JTExJU0VDT05EXSAhPT0gMCkpID8gSE9VUiA6XG4gICAgICAgICAgICAgICAgYVtNSU5VVEVdICAgICAgPCAwIHx8IGFbTUlOVVRFXSAgICAgID4gNTkgID8gTUlOVVRFIDpcbiAgICAgICAgICAgICAgICBhW1NFQ09ORF0gICAgICA8IDAgfHwgYVtTRUNPTkRdICAgICAgPiA1OSAgPyBTRUNPTkQgOlxuICAgICAgICAgICAgICAgIGFbTUlMTElTRUNPTkRdIDwgMCB8fCBhW01JTExJU0VDT05EXSA+IDk5OSA/IE1JTExJU0VDT05EIDpcbiAgICAgICAgICAgICAgICAtMTtcblxuICAgICAgICAgICAgaWYgKGdldFBhcnNpbmdGbGFncyhtKS5fb3ZlcmZsb3dEYXlPZlllYXIgJiYgKG92ZXJmbG93IDwgWUVBUiB8fCBvdmVyZmxvdyA+IERBVEUpKSB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3cgPSBEQVRFO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGdldFBhcnNpbmdGbGFncyhtKS5fb3ZlcmZsb3dXZWVrcyAmJiBvdmVyZmxvdyA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBvdmVyZmxvdyA9IFdFRUs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZ2V0UGFyc2luZ0ZsYWdzKG0pLl9vdmVyZmxvd1dlZWtkYXkgJiYgb3ZlcmZsb3cgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3cgPSBXRUVLREFZO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MobSkub3ZlcmZsb3cgPSBvdmVyZmxvdztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtO1xuICAgIH1cblxuICAgIC8vIFBpY2sgdGhlIGZpcnN0IGRlZmluZWQgb2YgdHdvIG9yIHRocmVlIGFyZ3VtZW50cy5cbiAgICBmdW5jdGlvbiBkZWZhdWx0cyhhLCBiLCBjKSB7XG4gICAgICAgIGlmIChhICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBhO1xuICAgICAgICB9XG4gICAgICAgIGlmIChiICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKSB7XG4gICAgICAgIC8vIGhvb2tzIGlzIGFjdHVhbGx5IHRoZSBleHBvcnRlZCBtb21lbnQgb2JqZWN0XG4gICAgICAgIHZhciBub3dWYWx1ZSA9IG5ldyBEYXRlKGhvb2tzLm5vdygpKTtcbiAgICAgICAgaWYgKGNvbmZpZy5fdXNlVVRDKSB7XG4gICAgICAgICAgICByZXR1cm4gW25vd1ZhbHVlLmdldFVUQ0Z1bGxZZWFyKCksIG5vd1ZhbHVlLmdldFVUQ01vbnRoKCksIG5vd1ZhbHVlLmdldFVUQ0RhdGUoKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtub3dWYWx1ZS5nZXRGdWxsWWVhcigpLCBub3dWYWx1ZS5nZXRNb250aCgpLCBub3dWYWx1ZS5nZXREYXRlKCldO1xuICAgIH1cblxuICAgIC8vIGNvbnZlcnQgYW4gYXJyYXkgdG8gYSBkYXRlLlxuICAgIC8vIHRoZSBhcnJheSBzaG91bGQgbWlycm9yIHRoZSBwYXJhbWV0ZXJzIGJlbG93XG4gICAgLy8gbm90ZTogYWxsIHZhbHVlcyBwYXN0IHRoZSB5ZWFyIGFyZSBvcHRpb25hbCBhbmQgd2lsbCBkZWZhdWx0IHRvIHRoZSBsb3dlc3QgcG9zc2libGUgdmFsdWUuXG4gICAgLy8gW3llYXIsIG1vbnRoLCBkYXkgLCBob3VyLCBtaW51dGUsIHNlY29uZCwgbWlsbGlzZWNvbmRdXG4gICAgZnVuY3Rpb24gY29uZmlnRnJvbUFycmF5IChjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGRhdGUsIGlucHV0ID0gW10sIGN1cnJlbnREYXRlLCBleHBlY3RlZFdlZWtkYXksIHllYXJUb1VzZTtcblxuICAgICAgICBpZiAoY29uZmlnLl9kKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50RGF0ZSA9IGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKTtcblxuICAgICAgICAvL2NvbXB1dGUgZGF5IG9mIHRoZSB5ZWFyIGZyb20gd2Vla3MgYW5kIHdlZWtkYXlzXG4gICAgICAgIGlmIChjb25maWcuX3cgJiYgY29uZmlnLl9hW0RBVEVdID09IG51bGwgJiYgY29uZmlnLl9hW01PTlRIXSA9PSBudWxsKSB7XG4gICAgICAgICAgICBkYXlPZlllYXJGcm9tV2Vla0luZm8oY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vaWYgdGhlIGRheSBvZiB0aGUgeWVhciBpcyBzZXQsIGZpZ3VyZSBvdXQgd2hhdCBpdCBpc1xuICAgICAgICBpZiAoY29uZmlnLl9kYXlPZlllYXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgeWVhclRvVXNlID0gZGVmYXVsdHMoY29uZmlnLl9hW1lFQVJdLCBjdXJyZW50RGF0ZVtZRUFSXSk7XG5cbiAgICAgICAgICAgIGlmIChjb25maWcuX2RheU9mWWVhciA+IGRheXNJblllYXIoeWVhclRvVXNlKSB8fCBjb25maWcuX2RheU9mWWVhciA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLl9vdmVyZmxvd0RheU9mWWVhciA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRhdGUgPSBjcmVhdGVVVENEYXRlKHllYXJUb1VzZSwgMCwgY29uZmlnLl9kYXlPZlllYXIpO1xuICAgICAgICAgICAgY29uZmlnLl9hW01PTlRIXSA9IGRhdGUuZ2V0VVRDTW9udGgoKTtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtEQVRFXSA9IGRhdGUuZ2V0VVRDRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGVmYXVsdCB0byBjdXJyZW50IGRhdGUuXG4gICAgICAgIC8vICogaWYgbm8geWVhciwgbW9udGgsIGRheSBvZiBtb250aCBhcmUgZ2l2ZW4sIGRlZmF1bHQgdG8gdG9kYXlcbiAgICAgICAgLy8gKiBpZiBkYXkgb2YgbW9udGggaXMgZ2l2ZW4sIGRlZmF1bHQgbW9udGggYW5kIHllYXJcbiAgICAgICAgLy8gKiBpZiBtb250aCBpcyBnaXZlbiwgZGVmYXVsdCBvbmx5IHllYXJcbiAgICAgICAgLy8gKiBpZiB5ZWFyIGlzIGdpdmVuLCBkb24ndCBkZWZhdWx0IGFueXRoaW5nXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAzICYmIGNvbmZpZy5fYVtpXSA9PSBudWxsOyArK2kpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gY3VycmVudERhdGVbaV07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBaZXJvIG91dCB3aGF0ZXZlciB3YXMgbm90IGRlZmF1bHRlZCwgaW5jbHVkaW5nIHRpbWVcbiAgICAgICAgZm9yICg7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gKGNvbmZpZy5fYVtpXSA9PSBudWxsKSA/IChpID09PSAyID8gMSA6IDApIDogY29uZmlnLl9hW2ldO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIDI0OjAwOjAwLjAwMFxuICAgICAgICBpZiAoY29uZmlnLl9hW0hPVVJdID09PSAyNCAmJlxuICAgICAgICAgICAgICAgIGNvbmZpZy5fYVtNSU5VVEVdID09PSAwICYmXG4gICAgICAgICAgICAgICAgY29uZmlnLl9hW1NFQ09ORF0gPT09IDAgJiZcbiAgICAgICAgICAgICAgICBjb25maWcuX2FbTUlMTElTRUNPTkRdID09PSAwKSB7XG4gICAgICAgICAgICBjb25maWcuX25leHREYXkgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9hW0hPVVJdID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZy5fZCA9IChjb25maWcuX3VzZVVUQyA/IGNyZWF0ZVVUQ0RhdGUgOiBjcmVhdGVEYXRlKS5hcHBseShudWxsLCBpbnB1dCk7XG4gICAgICAgIGV4cGVjdGVkV2Vla2RheSA9IGNvbmZpZy5fdXNlVVRDID8gY29uZmlnLl9kLmdldFVUQ0RheSgpIDogY29uZmlnLl9kLmdldERheSgpO1xuXG4gICAgICAgIC8vIEFwcGx5IHRpbWV6b25lIG9mZnNldCBmcm9tIGlucHV0LiBUaGUgYWN0dWFsIHV0Y09mZnNldCBjYW4gYmUgY2hhbmdlZFxuICAgICAgICAvLyB3aXRoIHBhcnNlWm9uZS5cbiAgICAgICAgaWYgKGNvbmZpZy5fdHptICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZC5zZXRVVENNaW51dGVzKGNvbmZpZy5fZC5nZXRVVENNaW51dGVzKCkgLSBjb25maWcuX3R6bSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLl9uZXh0RGF5KSB7XG4gICAgICAgICAgICBjb25maWcuX2FbSE9VUl0gPSAyNDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGZvciBtaXNtYXRjaGluZyBkYXkgb2Ygd2Vla1xuICAgICAgICBpZiAoY29uZmlnLl93ICYmIHR5cGVvZiBjb25maWcuX3cuZCAhPT0gJ3VuZGVmaW5lZCcgJiYgY29uZmlnLl93LmQgIT09IGV4cGVjdGVkV2Vla2RheSkge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykud2Vla2RheU1pc21hdGNoID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrSW5mbyhjb25maWcpIHtcbiAgICAgICAgdmFyIHcsIHdlZWtZZWFyLCB3ZWVrLCB3ZWVrZGF5LCBkb3csIGRveSwgdGVtcCwgd2Vla2RheU92ZXJmbG93O1xuXG4gICAgICAgIHcgPSBjb25maWcuX3c7XG4gICAgICAgIGlmICh3LkdHICE9IG51bGwgfHwgdy5XICE9IG51bGwgfHwgdy5FICE9IG51bGwpIHtcbiAgICAgICAgICAgIGRvdyA9IDE7XG4gICAgICAgICAgICBkb3kgPSA0O1xuXG4gICAgICAgICAgICAvLyBUT0RPOiBXZSBuZWVkIHRvIHRha2UgdGhlIGN1cnJlbnQgaXNvV2Vla1llYXIsIGJ1dCB0aGF0IGRlcGVuZHMgb25cbiAgICAgICAgICAgIC8vIGhvdyB3ZSBpbnRlcnByZXQgbm93IChsb2NhbCwgdXRjLCBmaXhlZCBvZmZzZXQpLiBTbyBjcmVhdGVcbiAgICAgICAgICAgIC8vIGEgbm93IHZlcnNpb24gb2YgY3VycmVudCBjb25maWcgKHRha2UgbG9jYWwvdXRjL29mZnNldCBmbGFncywgYW5kXG4gICAgICAgICAgICAvLyBjcmVhdGUgbm93KS5cbiAgICAgICAgICAgIHdlZWtZZWFyID0gZGVmYXVsdHMody5HRywgY29uZmlnLl9hW1lFQVJdLCB3ZWVrT2ZZZWFyKGNyZWF0ZUxvY2FsKCksIDEsIDQpLnllYXIpO1xuICAgICAgICAgICAgd2VlayA9IGRlZmF1bHRzKHcuVywgMSk7XG4gICAgICAgICAgICB3ZWVrZGF5ID0gZGVmYXVsdHMody5FLCAxKTtcbiAgICAgICAgICAgIGlmICh3ZWVrZGF5IDwgMSB8fCB3ZWVrZGF5ID4gNykge1xuICAgICAgICAgICAgICAgIHdlZWtkYXlPdmVyZmxvdyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkb3cgPSBjb25maWcuX2xvY2FsZS5fd2Vlay5kb3c7XG4gICAgICAgICAgICBkb3kgPSBjb25maWcuX2xvY2FsZS5fd2Vlay5kb3k7XG5cbiAgICAgICAgICAgIHZhciBjdXJXZWVrID0gd2Vla09mWWVhcihjcmVhdGVMb2NhbCgpLCBkb3csIGRveSk7XG5cbiAgICAgICAgICAgIHdlZWtZZWFyID0gZGVmYXVsdHMody5nZywgY29uZmlnLl9hW1lFQVJdLCBjdXJXZWVrLnllYXIpO1xuXG4gICAgICAgICAgICAvLyBEZWZhdWx0IHRvIGN1cnJlbnQgd2Vlay5cbiAgICAgICAgICAgIHdlZWsgPSBkZWZhdWx0cyh3LncsIGN1cldlZWsud2Vlayk7XG5cbiAgICAgICAgICAgIGlmICh3LmQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIHdlZWtkYXkgLS0gbG93IGRheSBudW1iZXJzIGFyZSBjb25zaWRlcmVkIG5leHQgd2Vla1xuICAgICAgICAgICAgICAgIHdlZWtkYXkgPSB3LmQ7XG4gICAgICAgICAgICAgICAgaWYgKHdlZWtkYXkgPCAwIHx8IHdlZWtkYXkgPiA2KSB7XG4gICAgICAgICAgICAgICAgICAgIHdlZWtkYXlPdmVyZmxvdyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh3LmUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIGxvY2FsIHdlZWtkYXkgLS0gY291bnRpbmcgc3RhcnRzIGZyb20gYmVnaW5uaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gdy5lICsgZG93O1xuICAgICAgICAgICAgICAgIGlmICh3LmUgPCAwIHx8IHcuZSA+IDYpIHtcbiAgICAgICAgICAgICAgICAgICAgd2Vla2RheU92ZXJmbG93ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGRlZmF1bHQgdG8gYmVnaW5uaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gZG93O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh3ZWVrIDwgMSB8fCB3ZWVrID4gd2Vla3NJblllYXIod2Vla1llYXIsIGRvdywgZG95KSkge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuX292ZXJmbG93V2Vla3MgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHdlZWtkYXlPdmVyZmxvdyAhPSBudWxsKSB7XG4gICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5fb3ZlcmZsb3dXZWVrZGF5ID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRlbXAgPSBkYXlPZlllYXJGcm9tV2Vla3Mod2Vla1llYXIsIHdlZWssIHdlZWtkYXksIGRvdywgZG95KTtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtZRUFSXSA9IHRlbXAueWVhcjtcbiAgICAgICAgICAgIGNvbmZpZy5fZGF5T2ZZZWFyID0gdGVtcC5kYXlPZlllYXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpc28gODYwMSByZWdleFxuICAgIC8vIDAwMDAtMDAtMDAgMDAwMC1XMDAgb3IgMDAwMC1XMDAtMCArIFQgKyAwMCBvciAwMDowMCBvciAwMDowMDowMCBvciAwMDowMDowMC4wMDAgKyArMDA6MDAgb3IgKzAwMDAgb3IgKzAwKVxuICAgIHZhciBleHRlbmRlZElzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KS0oPzpcXGRcXGQtXFxkXFxkfFdcXGRcXGQtXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86OlxcZFxcZCg/OjpcXGRcXGQoPzpbLixdXFxkKyk/KT8pPykoW1xcK1xcLV1cXGRcXGQoPzo6P1xcZFxcZCk/fFxccypaKT8pPyQvO1xuICAgIHZhciBiYXNpY0lzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KSg/OlxcZFxcZFxcZFxcZHxXXFxkXFxkXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86XFxkXFxkKD86XFxkXFxkKD86Wy4sXVxcZCspPyk/KT8pKFtcXCtcXC1dXFxkXFxkKD86Oj9cXGRcXGQpP3xcXHMqWik/KT8kLztcblxuICAgIHZhciB0elJlZ2V4ID0gL1p8WystXVxcZFxcZCg/Ojo/XFxkXFxkKT8vO1xuXG4gICAgdmFyIGlzb0RhdGVzID0gW1xuICAgICAgICBbJ1lZWVlZWS1NTS1ERCcsIC9bKy1dXFxkezZ9LVxcZFxcZC1cXGRcXGQvXSxcbiAgICAgICAgWydZWVlZLU1NLUREJywgL1xcZHs0fS1cXGRcXGQtXFxkXFxkL10sXG4gICAgICAgIFsnR0dHRy1bV11XVy1FJywgL1xcZHs0fS1XXFxkXFxkLVxcZC9dLFxuICAgICAgICBbJ0dHR0ctW1ddV1cnLCAvXFxkezR9LVdcXGRcXGQvLCBmYWxzZV0sXG4gICAgICAgIFsnWVlZWS1EREQnLCAvXFxkezR9LVxcZHszfS9dLFxuICAgICAgICBbJ1lZWVktTU0nLCAvXFxkezR9LVxcZFxcZC8sIGZhbHNlXSxcbiAgICAgICAgWydZWVlZWVlNTUREJywgL1srLV1cXGR7MTB9L10sXG4gICAgICAgIFsnWVlZWU1NREQnLCAvXFxkezh9L10sXG4gICAgICAgIC8vIFlZWVlNTSBpcyBOT1QgYWxsb3dlZCBieSB0aGUgc3RhbmRhcmRcbiAgICAgICAgWydHR0dHW1ddV1dFJywgL1xcZHs0fVdcXGR7M30vXSxcbiAgICAgICAgWydHR0dHW1ddV1cnLCAvXFxkezR9V1xcZHsyfS8sIGZhbHNlXSxcbiAgICAgICAgWydZWVlZREREJywgL1xcZHs3fS9dXG4gICAgXTtcblxuICAgIC8vIGlzbyB0aW1lIGZvcm1hdHMgYW5kIHJlZ2V4ZXNcbiAgICB2YXIgaXNvVGltZXMgPSBbXG4gICAgICAgIFsnSEg6bW06c3MuU1NTUycsIC9cXGRcXGQ6XFxkXFxkOlxcZFxcZFxcLlxcZCsvXSxcbiAgICAgICAgWydISDptbTpzcyxTU1NTJywgL1xcZFxcZDpcXGRcXGQ6XFxkXFxkLFxcZCsvXSxcbiAgICAgICAgWydISDptbTpzcycsIC9cXGRcXGQ6XFxkXFxkOlxcZFxcZC9dLFxuICAgICAgICBbJ0hIOm1tJywgL1xcZFxcZDpcXGRcXGQvXSxcbiAgICAgICAgWydISG1tc3MuU1NTUycsIC9cXGRcXGRcXGRcXGRcXGRcXGRcXC5cXGQrL10sXG4gICAgICAgIFsnSEhtbXNzLFNTU1MnLCAvXFxkXFxkXFxkXFxkXFxkXFxkLFxcZCsvXSxcbiAgICAgICAgWydISG1tc3MnLCAvXFxkXFxkXFxkXFxkXFxkXFxkL10sXG4gICAgICAgIFsnSEhtbScsIC9cXGRcXGRcXGRcXGQvXSxcbiAgICAgICAgWydISCcsIC9cXGRcXGQvXVxuICAgIF07XG5cbiAgICB2YXIgYXNwTmV0SnNvblJlZ2V4ID0gL15cXC8/RGF0ZVxcKChcXC0/XFxkKykvaTtcblxuICAgIC8vIGRhdGUgZnJvbSBpc28gZm9ybWF0XG4gICAgZnVuY3Rpb24gY29uZmlnRnJvbUlTTyhjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGwsXG4gICAgICAgICAgICBzdHJpbmcgPSBjb25maWcuX2ksXG4gICAgICAgICAgICBtYXRjaCA9IGV4dGVuZGVkSXNvUmVnZXguZXhlYyhzdHJpbmcpIHx8IGJhc2ljSXNvUmVnZXguZXhlYyhzdHJpbmcpLFxuICAgICAgICAgICAgYWxsb3dUaW1lLCBkYXRlRm9ybWF0LCB0aW1lRm9ybWF0LCB0ekZvcm1hdDtcblxuICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmlzbyA9IHRydWU7XG5cbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBpc29EYXRlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNvRGF0ZXNbaV1bMV0uZXhlYyhtYXRjaFsxXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdCA9IGlzb0RhdGVzW2ldWzBdO1xuICAgICAgICAgICAgICAgICAgICBhbGxvd1RpbWUgPSBpc29EYXRlc1tpXVsyXSAhPT0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRlRm9ybWF0ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25maWcuX2lzVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWF0Y2hbM10pIHtcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gaXNvVGltZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc29UaW1lc1tpXVsxXS5leGVjKG1hdGNoWzNdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWF0Y2hbMl0gc2hvdWxkIGJlICdUJyBvciBzcGFjZVxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZUZvcm1hdCA9IChtYXRjaFsyXSB8fCAnICcpICsgaXNvVGltZXNbaV1bMF07XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGltZUZvcm1hdCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFhbGxvd1RpbWUgJiYgdGltZUZvcm1hdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1hdGNoWzRdKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR6UmVnZXguZXhlYyhtYXRjaFs0XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHpGb3JtYXQgPSAnWic7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25maWcuX2YgPSBkYXRlRm9ybWF0ICsgKHRpbWVGb3JtYXQgfHwgJycpICsgKHR6Rm9ybWF0IHx8ICcnKTtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUkZDIDI4MjIgcmVnZXg6IEZvciBkZXRhaWxzIHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMjgyMiNzZWN0aW9uLTMuM1xuICAgIHZhciByZmMyODIyID0gL14oPzooTW9ufFR1ZXxXZWR8VGh1fEZyaXxTYXR8U3VuKSw/XFxzKT8oXFxkezEsMn0pXFxzKEphbnxGZWJ8TWFyfEFwcnxNYXl8SnVufEp1bHxBdWd8U2VwfE9jdHxOb3Z8RGVjKVxccyhcXGR7Miw0fSlcXHMoXFxkXFxkKTooXFxkXFxkKSg/OjooXFxkXFxkKSk/XFxzKD86KFVUfEdNVHxbRUNNUF1bU0RdVCl8KFtael0pfChbKy1dXFxkezR9KSkkLztcblxuICAgIGZ1bmN0aW9uIGV4dHJhY3RGcm9tUkZDMjgyMlN0cmluZ3MoeWVhclN0ciwgbW9udGhTdHIsIGRheVN0ciwgaG91clN0ciwgbWludXRlU3RyLCBzZWNvbmRTdHIpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtcbiAgICAgICAgICAgIHVudHJ1bmNhdGVZZWFyKHllYXJTdHIpLFxuICAgICAgICAgICAgZGVmYXVsdExvY2FsZU1vbnRoc1Nob3J0LmluZGV4T2YobW9udGhTdHIpLFxuICAgICAgICAgICAgcGFyc2VJbnQoZGF5U3RyLCAxMCksXG4gICAgICAgICAgICBwYXJzZUludChob3VyU3RyLCAxMCksXG4gICAgICAgICAgICBwYXJzZUludChtaW51dGVTdHIsIDEwKVxuICAgICAgICBdO1xuXG4gICAgICAgIGlmIChzZWNvbmRTdHIpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBhcnNlSW50KHNlY29uZFN0ciwgMTApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdW50cnVuY2F0ZVllYXIoeWVhclN0cikge1xuICAgICAgICB2YXIgeWVhciA9IHBhcnNlSW50KHllYXJTdHIsIDEwKTtcbiAgICAgICAgaWYgKHllYXIgPD0gNDkpIHtcbiAgICAgICAgICAgIHJldHVybiAyMDAwICsgeWVhcjtcbiAgICAgICAgfSBlbHNlIGlmICh5ZWFyIDw9IDk5OSkge1xuICAgICAgICAgICAgcmV0dXJuIDE5MDAgKyB5ZWFyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB5ZWFyO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByZXByb2Nlc3NSRkMyODIyKHMpIHtcbiAgICAgICAgLy8gUmVtb3ZlIGNvbW1lbnRzIGFuZCBmb2xkaW5nIHdoaXRlc3BhY2UgYW5kIHJlcGxhY2UgbXVsdGlwbGUtc3BhY2VzIHdpdGggYSBzaW5nbGUgc3BhY2VcbiAgICAgICAgcmV0dXJuIHMucmVwbGFjZSgvXFwoW14pXSpcXCl8W1xcblxcdF0vZywgJyAnKS5yZXBsYWNlKC8oXFxzXFxzKykvZywgJyAnKS5yZXBsYWNlKC9eXFxzXFxzKi8sICcnKS5yZXBsYWNlKC9cXHNcXHMqJC8sICcnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja1dlZWtkYXkod2Vla2RheVN0ciwgcGFyc2VkSW5wdXQsIGNvbmZpZykge1xuICAgICAgICBpZiAod2Vla2RheVN0cikge1xuICAgICAgICAgICAgLy8gVE9ETzogUmVwbGFjZSB0aGUgdmFuaWxsYSBKUyBEYXRlIG9iamVjdCB3aXRoIGFuIGluZGVwZW50ZW50IGRheS1vZi13ZWVrIGNoZWNrLlxuICAgICAgICAgICAgdmFyIHdlZWtkYXlQcm92aWRlZCA9IGRlZmF1bHRMb2NhbGVXZWVrZGF5c1Nob3J0LmluZGV4T2Yod2Vla2RheVN0ciksXG4gICAgICAgICAgICAgICAgd2Vla2RheUFjdHVhbCA9IG5ldyBEYXRlKHBhcnNlZElucHV0WzBdLCBwYXJzZWRJbnB1dFsxXSwgcGFyc2VkSW5wdXRbMl0pLmdldERheSgpO1xuICAgICAgICAgICAgaWYgKHdlZWtkYXlQcm92aWRlZCAhPT0gd2Vla2RheUFjdHVhbCkge1xuICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLndlZWtkYXlNaXNtYXRjaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciBvYnNPZmZzZXRzID0ge1xuICAgICAgICBVVDogMCxcbiAgICAgICAgR01UOiAwLFxuICAgICAgICBFRFQ6IC00ICogNjAsXG4gICAgICAgIEVTVDogLTUgKiA2MCxcbiAgICAgICAgQ0RUOiAtNSAqIDYwLFxuICAgICAgICBDU1Q6IC02ICogNjAsXG4gICAgICAgIE1EVDogLTYgKiA2MCxcbiAgICAgICAgTVNUOiAtNyAqIDYwLFxuICAgICAgICBQRFQ6IC03ICogNjAsXG4gICAgICAgIFBTVDogLTggKiA2MFxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBjYWxjdWxhdGVPZmZzZXQob2JzT2Zmc2V0LCBtaWxpdGFyeU9mZnNldCwgbnVtT2Zmc2V0KSB7XG4gICAgICAgIGlmIChvYnNPZmZzZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBvYnNPZmZzZXRzW29ic09mZnNldF07XG4gICAgICAgIH0gZWxzZSBpZiAobWlsaXRhcnlPZmZzZXQpIHtcbiAgICAgICAgICAgIC8vIHRoZSBvbmx5IGFsbG93ZWQgbWlsaXRhcnkgdHogaXMgWlxuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaG0gPSBwYXJzZUludChudW1PZmZzZXQsIDEwKTtcbiAgICAgICAgICAgIHZhciBtID0gaG0gJSAxMDAsIGggPSAoaG0gLSBtKSAvIDEwMDtcbiAgICAgICAgICAgIHJldHVybiBoICogNjAgKyBtO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZGF0ZSBhbmQgdGltZSBmcm9tIHJlZiAyODIyIGZvcm1hdFxuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21SRkMyODIyKGNvbmZpZykge1xuICAgICAgICB2YXIgbWF0Y2ggPSByZmMyODIyLmV4ZWMocHJlcHJvY2Vzc1JGQzI4MjIoY29uZmlnLl9pKSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgdmFyIHBhcnNlZEFycmF5ID0gZXh0cmFjdEZyb21SRkMyODIyU3RyaW5ncyhtYXRjaFs0XSwgbWF0Y2hbM10sIG1hdGNoWzJdLCBtYXRjaFs1XSwgbWF0Y2hbNl0sIG1hdGNoWzddKTtcbiAgICAgICAgICAgIGlmICghY2hlY2tXZWVrZGF5KG1hdGNoWzFdLCBwYXJzZWRBcnJheSwgY29uZmlnKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uZmlnLl9hID0gcGFyc2VkQXJyYXk7XG4gICAgICAgICAgICBjb25maWcuX3R6bSA9IGNhbGN1bGF0ZU9mZnNldChtYXRjaFs4XSwgbWF0Y2hbOV0sIG1hdGNoWzEwXSk7XG5cbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IGNyZWF0ZVVUQ0RhdGUuYXBwbHkobnVsbCwgY29uZmlnLl9hKTtcbiAgICAgICAgICAgIGNvbmZpZy5fZC5zZXRVVENNaW51dGVzKGNvbmZpZy5fZC5nZXRVVENNaW51dGVzKCkgLSBjb25maWcuX3R6bSk7XG5cbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnJmYzI4MjIgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gaXNvIGZvcm1hdCBvciBmYWxsYmFja1xuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21TdHJpbmcoY29uZmlnKSB7XG4gICAgICAgIHZhciBtYXRjaGVkID0gYXNwTmV0SnNvblJlZ2V4LmV4ZWMoY29uZmlnLl9pKTtcblxuICAgICAgICBpZiAobWF0Y2hlZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoK21hdGNoZWRbMV0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uZmlnRnJvbUlTTyhjb25maWcpO1xuICAgICAgICBpZiAoY29uZmlnLl9pc1ZhbGlkID09PSBmYWxzZSkge1xuICAgICAgICAgICAgZGVsZXRlIGNvbmZpZy5faXNWYWxpZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZ0Zyb21SRkMyODIyKGNvbmZpZyk7XG4gICAgICAgIGlmIChjb25maWcuX2lzVmFsaWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBkZWxldGUgY29uZmlnLl9pc1ZhbGlkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluYWwgYXR0ZW1wdCwgdXNlIElucHV0IEZhbGxiYWNrXG4gICAgICAgIGhvb2tzLmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgfVxuXG4gICAgaG9va3MuY3JlYXRlRnJvbUlucHV0RmFsbGJhY2sgPSBkZXByZWNhdGUoXG4gICAgICAgICd2YWx1ZSBwcm92aWRlZCBpcyBub3QgaW4gYSByZWNvZ25pemVkIFJGQzI4MjIgb3IgSVNPIGZvcm1hdC4gbW9tZW50IGNvbnN0cnVjdGlvbiBmYWxscyBiYWNrIHRvIGpzIERhdGUoKSwgJyArXG4gICAgICAgICd3aGljaCBpcyBub3QgcmVsaWFibGUgYWNyb3NzIGFsbCBicm93c2VycyBhbmQgdmVyc2lvbnMuIE5vbiBSRkMyODIyL0lTTyBkYXRlIGZvcm1hdHMgYXJlICcgK1xuICAgICAgICAnZGlzY291cmFnZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhbiB1cGNvbWluZyBtYWpvciByZWxlYXNlLiBQbGVhc2UgcmVmZXIgdG8gJyArXG4gICAgICAgICdodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2pzLWRhdGUvIGZvciBtb3JlIGluZm8uJyxcbiAgICAgICAgZnVuY3Rpb24gKGNvbmZpZykge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoY29uZmlnLl9pICsgKGNvbmZpZy5fdXNlVVRDID8gJyBVVEMnIDogJycpKTtcbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBjb25zdGFudCB0aGF0IHJlZmVycyB0byB0aGUgSVNPIHN0YW5kYXJkXG4gICAgaG9va3MuSVNPXzg2MDEgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIGNvbnN0YW50IHRoYXQgcmVmZXJzIHRvIHRoZSBSRkMgMjgyMiBmb3JtXG4gICAgaG9va3MuUkZDXzI4MjIgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIGRhdGUgZnJvbSBzdHJpbmcgYW5kIGZvcm1hdCBzdHJpbmdcbiAgICBmdW5jdGlvbiBjb25maWdGcm9tU3RyaW5nQW5kRm9ybWF0KGNvbmZpZykge1xuICAgICAgICAvLyBUT0RPOiBNb3ZlIHRoaXMgdG8gYW5vdGhlciBwYXJ0IG9mIHRoZSBjcmVhdGlvbiBmbG93IHRvIHByZXZlbnQgY2lyY3VsYXIgZGVwc1xuICAgICAgICBpZiAoY29uZmlnLl9mID09PSBob29rcy5JU09fODYwMSkge1xuICAgICAgICAgICAgY29uZmlnRnJvbUlTTyhjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25maWcuX2YgPT09IGhvb2tzLlJGQ18yODIyKSB7XG4gICAgICAgICAgICBjb25maWdGcm9tUkZDMjgyMihjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbmZpZy5fYSA9IFtdO1xuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5lbXB0eSA9IHRydWU7XG5cbiAgICAgICAgLy8gVGhpcyBhcnJheSBpcyB1c2VkIHRvIG1ha2UgYSBEYXRlLCBlaXRoZXIgd2l0aCBgbmV3IERhdGVgIG9yIGBEYXRlLlVUQ2BcbiAgICAgICAgdmFyIHN0cmluZyA9ICcnICsgY29uZmlnLl9pLFxuICAgICAgICAgICAgaSwgcGFyc2VkSW5wdXQsIHRva2VucywgdG9rZW4sIHNraXBwZWQsXG4gICAgICAgICAgICBzdHJpbmdMZW5ndGggPSBzdHJpbmcubGVuZ3RoLFxuICAgICAgICAgICAgdG90YWxQYXJzZWRJbnB1dExlbmd0aCA9IDA7XG5cbiAgICAgICAgdG9rZW5zID0gZXhwYW5kRm9ybWF0KGNvbmZpZy5fZiwgY29uZmlnLl9sb2NhbGUpLm1hdGNoKGZvcm1hdHRpbmdUb2tlbnMpIHx8IFtdO1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRva2VuID0gdG9rZW5zW2ldO1xuICAgICAgICAgICAgcGFyc2VkSW5wdXQgPSAoc3RyaW5nLm1hdGNoKGdldFBhcnNlUmVnZXhGb3JUb2tlbih0b2tlbiwgY29uZmlnKSkgfHwgW10pWzBdO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ3Rva2VuJywgdG9rZW4sICdwYXJzZWRJbnB1dCcsIHBhcnNlZElucHV0LFxuICAgICAgICAgICAgLy8gICAgICAgICAncmVnZXgnLCBnZXRQYXJzZVJlZ2V4Rm9yVG9rZW4odG9rZW4sIGNvbmZpZykpO1xuICAgICAgICAgICAgaWYgKHBhcnNlZElucHV0KSB7XG4gICAgICAgICAgICAgICAgc2tpcHBlZCA9IHN0cmluZy5zdWJzdHIoMCwgc3RyaW5nLmluZGV4T2YocGFyc2VkSW5wdXQpKTtcbiAgICAgICAgICAgICAgICBpZiAoc2tpcHBlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnVudXNlZElucHV0LnB1c2goc2tpcHBlZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN0cmluZyA9IHN0cmluZy5zbGljZShzdHJpbmcuaW5kZXhPZihwYXJzZWRJbnB1dCkgKyBwYXJzZWRJbnB1dC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIHRvdGFsUGFyc2VkSW5wdXRMZW5ndGggKz0gcGFyc2VkSW5wdXQubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZG9uJ3QgcGFyc2UgaWYgaXQncyBub3QgYSBrbm93biB0b2tlblxuICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuRnVuY3Rpb25zW3Rva2VuXSkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZWRJbnB1dCkge1xuICAgICAgICAgICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5lbXB0eSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykudW51c2VkVG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhZGRUaW1lVG9BcnJheUZyb21Ub2tlbih0b2tlbiwgcGFyc2VkSW5wdXQsIGNvbmZpZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb25maWcuX3N0cmljdCAmJiAhcGFyc2VkSW5wdXQpIHtcbiAgICAgICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS51bnVzZWRUb2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGQgcmVtYWluaW5nIHVucGFyc2VkIGlucHV0IGxlbmd0aCB0byB0aGUgc3RyaW5nXG4gICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmNoYXJzTGVmdE92ZXIgPSBzdHJpbmdMZW5ndGggLSB0b3RhbFBhcnNlZElucHV0TGVuZ3RoO1xuICAgICAgICBpZiAoc3RyaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnVudXNlZElucHV0LnB1c2goc3RyaW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNsZWFyIF8xMmggZmxhZyBpZiBob3VyIGlzIDw9IDEyXG4gICAgICAgIGlmIChjb25maWcuX2FbSE9VUl0gPD0gMTIgJiZcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmJpZ0hvdXIgPT09IHRydWUgJiZcbiAgICAgICAgICAgIGNvbmZpZy5fYVtIT1VSXSA+IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmJpZ0hvdXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5wYXJzZWREYXRlUGFydHMgPSBjb25maWcuX2Euc2xpY2UoMCk7XG4gICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLm1lcmlkaWVtID0gY29uZmlnLl9tZXJpZGllbTtcbiAgICAgICAgLy8gaGFuZGxlIG1lcmlkaWVtXG4gICAgICAgIGNvbmZpZy5fYVtIT1VSXSA9IG1lcmlkaWVtRml4V3JhcChjb25maWcuX2xvY2FsZSwgY29uZmlnLl9hW0hPVVJdLCBjb25maWcuX21lcmlkaWVtKTtcblxuICAgICAgICBjb25maWdGcm9tQXJyYXkoY29uZmlnKTtcbiAgICAgICAgY2hlY2tPdmVyZmxvdyhjb25maWcpO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gbWVyaWRpZW1GaXhXcmFwIChsb2NhbGUsIGhvdXIsIG1lcmlkaWVtKSB7XG4gICAgICAgIHZhciBpc1BtO1xuXG4gICAgICAgIGlmIChtZXJpZGllbSA9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBub3RoaW5nIHRvIGRvXG4gICAgICAgICAgICByZXR1cm4gaG91cjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobG9jYWxlLm1lcmlkaWVtSG91ciAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbG9jYWxlLm1lcmlkaWVtSG91cihob3VyLCBtZXJpZGllbSk7XG4gICAgICAgIH0gZWxzZSBpZiAobG9jYWxlLmlzUE0gIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gRmFsbGJhY2tcbiAgICAgICAgICAgIGlzUG0gPSBsb2NhbGUuaXNQTShtZXJpZGllbSk7XG4gICAgICAgICAgICBpZiAoaXNQbSAmJiBob3VyIDwgMTIpIHtcbiAgICAgICAgICAgICAgICBob3VyICs9IDEyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc1BtICYmIGhvdXIgPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgaG91ciA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaG91cjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgbm90IHN1cHBvc2VkIHRvIGhhcHBlblxuICAgICAgICAgICAgcmV0dXJuIGhvdXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gc3RyaW5nIGFuZCBhcnJheSBvZiBmb3JtYXQgc3RyaW5nc1xuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21TdHJpbmdBbmRBcnJheShjb25maWcpIHtcbiAgICAgICAgdmFyIHRlbXBDb25maWcsXG4gICAgICAgICAgICBiZXN0TW9tZW50LFxuXG4gICAgICAgICAgICBzY29yZVRvQmVhdCxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBjdXJyZW50U2NvcmU7XG5cbiAgICAgICAgaWYgKGNvbmZpZy5fZi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmludmFsaWRGb3JtYXQgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoTmFOKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb25maWcuX2YubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGN1cnJlbnRTY29yZSA9IDA7XG4gICAgICAgICAgICB0ZW1wQ29uZmlnID0gY29weUNvbmZpZyh7fSwgY29uZmlnKTtcbiAgICAgICAgICAgIGlmIChjb25maWcuX3VzZVVUQyAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGVtcENvbmZpZy5fdXNlVVRDID0gY29uZmlnLl91c2VVVEM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZW1wQ29uZmlnLl9mID0gY29uZmlnLl9mW2ldO1xuICAgICAgICAgICAgY29uZmlnRnJvbVN0cmluZ0FuZEZvcm1hdCh0ZW1wQ29uZmlnKTtcblxuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKHRlbXBDb25maWcpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFueSBpbnB1dCB0aGF0IHdhcyBub3QgcGFyc2VkIGFkZCBhIHBlbmFsdHkgZm9yIHRoYXQgZm9ybWF0XG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgKz0gZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLmNoYXJzTGVmdE92ZXI7XG5cbiAgICAgICAgICAgIC8vb3IgdG9rZW5zXG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgKz0gZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLnVudXNlZFRva2Vucy5sZW5ndGggKiAxMDtcblxuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLnNjb3JlID0gY3VycmVudFNjb3JlO1xuXG4gICAgICAgICAgICBpZiAoc2NvcmVUb0JlYXQgPT0gbnVsbCB8fCBjdXJyZW50U2NvcmUgPCBzY29yZVRvQmVhdCkge1xuICAgICAgICAgICAgICAgIHNjb3JlVG9CZWF0ID0gY3VycmVudFNjb3JlO1xuICAgICAgICAgICAgICAgIGJlc3RNb21lbnQgPSB0ZW1wQ29uZmlnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZXh0ZW5kKGNvbmZpZywgYmVzdE1vbWVudCB8fCB0ZW1wQ29uZmlnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb25maWdGcm9tT2JqZWN0KGNvbmZpZykge1xuICAgICAgICBpZiAoY29uZmlnLl9kKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaSA9IG5vcm1hbGl6ZU9iamVjdFVuaXRzKGNvbmZpZy5faSk7XG4gICAgICAgIGNvbmZpZy5fYSA9IG1hcChbaS55ZWFyLCBpLm1vbnRoLCBpLmRheSB8fCBpLmRhdGUsIGkuaG91ciwgaS5taW51dGUsIGkuc2Vjb25kLCBpLm1pbGxpc2Vjb25kXSwgZnVuY3Rpb24gKG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIG9iaiAmJiBwYXJzZUludChvYmosIDEwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uZmlnRnJvbUFycmF5KGNvbmZpZyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlRnJvbUNvbmZpZyAoY29uZmlnKSB7XG4gICAgICAgIHZhciByZXMgPSBuZXcgTW9tZW50KGNoZWNrT3ZlcmZsb3cocHJlcGFyZUNvbmZpZyhjb25maWcpKSk7XG4gICAgICAgIGlmIChyZXMuX25leHREYXkpIHtcbiAgICAgICAgICAgIC8vIEFkZGluZyBpcyBzbWFydCBlbm91Z2ggYXJvdW5kIERTVFxuICAgICAgICAgICAgcmVzLmFkZCgxLCAnZCcpO1xuICAgICAgICAgICAgcmVzLl9uZXh0RGF5ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVwYXJlQ29uZmlnIChjb25maWcpIHtcbiAgICAgICAgdmFyIGlucHV0ID0gY29uZmlnLl9pLFxuICAgICAgICAgICAgZm9ybWF0ID0gY29uZmlnLl9mO1xuXG4gICAgICAgIGNvbmZpZy5fbG9jYWxlID0gY29uZmlnLl9sb2NhbGUgfHwgZ2V0TG9jYWxlKGNvbmZpZy5fbCk7XG5cbiAgICAgICAgaWYgKGlucHV0ID09PSBudWxsIHx8IChmb3JtYXQgPT09IHVuZGVmaW5lZCAmJiBpbnB1dCA9PT0gJycpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlSW52YWxpZCh7bnVsbElucHV0OiB0cnVlfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uZmlnLl9pID0gaW5wdXQgPSBjb25maWcuX2xvY2FsZS5wcmVwYXJzZShpbnB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNNb21lbnQoaW5wdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE1vbWVudChjaGVja092ZXJmbG93KGlucHV0KSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNEYXRlKGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gaW5wdXQ7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNBcnJheShmb3JtYXQpKSB7XG4gICAgICAgICAgICBjb25maWdGcm9tU3RyaW5nQW5kQXJyYXkoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQpIHtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgfSAgZWxzZSB7XG4gICAgICAgICAgICBjb25maWdGcm9tSW5wdXQoY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNWYWxpZChjb25maWcpKSB7XG4gICAgICAgICAgICBjb25maWcuX2QgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb25maWdGcm9tSW5wdXQoY29uZmlnKSB7XG4gICAgICAgIHZhciBpbnB1dCA9IGNvbmZpZy5faTtcbiAgICAgICAgaWYgKGlzVW5kZWZpbmVkKGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoaG9va3Mubm93KCkpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzRGF0ZShpbnB1dCkpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKGlucHV0LnZhbHVlT2YoKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uZmlnRnJvbVN0cmluZyhjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkoaW5wdXQpKSB7XG4gICAgICAgICAgICBjb25maWcuX2EgPSBtYXAoaW5wdXQuc2xpY2UoMCksIGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQob2JqLCAxMCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21BcnJheShjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnRnJvbU9iamVjdChjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKGlucHV0KSkge1xuICAgICAgICAgICAgLy8gZnJvbSBtaWxsaXNlY29uZHNcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKGlucHV0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhvb2tzLmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVMb2NhbE9yVVRDIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCwgaXNVVEMpIHtcbiAgICAgICAgdmFyIGMgPSB7fTtcblxuICAgICAgICBpZiAobG9jYWxlID09PSB0cnVlIHx8IGxvY2FsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHN0cmljdCA9IGxvY2FsZTtcbiAgICAgICAgICAgIGxvY2FsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgoaXNPYmplY3QoaW5wdXQpICYmIGlzT2JqZWN0RW1wdHkoaW5wdXQpKSB8fFxuICAgICAgICAgICAgICAgIChpc0FycmF5KGlucHV0KSAmJiBpbnB1dC5sZW5ndGggPT09IDApKSB7XG4gICAgICAgICAgICBpbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBvYmplY3QgY29uc3RydWN0aW9uIG11c3QgYmUgZG9uZSB0aGlzIHdheS5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzE0MjNcbiAgICAgICAgYy5faXNBTW9tZW50T2JqZWN0ID0gdHJ1ZTtcbiAgICAgICAgYy5fdXNlVVRDID0gYy5faXNVVEMgPSBpc1VUQztcbiAgICAgICAgYy5fbCA9IGxvY2FsZTtcbiAgICAgICAgYy5faSA9IGlucHV0O1xuICAgICAgICBjLl9mID0gZm9ybWF0O1xuICAgICAgICBjLl9zdHJpY3QgPSBzdHJpY3Q7XG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZyb21Db25maWcoYyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlTG9jYWwgKGlucHV0LCBmb3JtYXQsIGxvY2FsZSwgc3RyaWN0KSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVMb2NhbE9yVVRDKGlucHV0LCBmb3JtYXQsIGxvY2FsZSwgc3RyaWN0LCBmYWxzZSk7XG4gICAgfVxuXG4gICAgdmFyIHByb3RvdHlwZU1pbiA9IGRlcHJlY2F0ZShcbiAgICAgICAgJ21vbWVudCgpLm1pbiBpcyBkZXByZWNhdGVkLCB1c2UgbW9tZW50Lm1heCBpbnN0ZWFkLiBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL21pbi1tYXgvJyxcbiAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIG90aGVyID0gY3JlYXRlTG9jYWwuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzVmFsaWQoKSAmJiBvdGhlci5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3RoZXIgPCB0aGlzID8gdGhpcyA6IG90aGVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlSW52YWxpZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIHZhciBwcm90b3R5cGVNYXggPSBkZXByZWNhdGUoXG4gICAgICAgICdtb21lbnQoKS5tYXggaXMgZGVwcmVjYXRlZCwgdXNlIG1vbWVudC5taW4gaW5zdGVhZC4gaHR0cDovL21vbWVudGpzLmNvbS9ndWlkZXMvIy93YXJuaW5ncy9taW4tbWF4LycsXG4gICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBvdGhlciA9IGNyZWF0ZUxvY2FsLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICBpZiAodGhpcy5pc1ZhbGlkKCkgJiYgb3RoZXIuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG90aGVyID4gdGhpcyA/IHRoaXMgOiBvdGhlcjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUludmFsaWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBQaWNrIGEgbW9tZW50IG0gZnJvbSBtb21lbnRzIHNvIHRoYXQgbVtmbl0ob3RoZXIpIGlzIHRydWUgZm9yIGFsbFxuICAgIC8vIG90aGVyLiBUaGlzIHJlbGllcyBvbiB0aGUgZnVuY3Rpb24gZm4gdG8gYmUgdHJhbnNpdGl2ZS5cbiAgICAvL1xuICAgIC8vIG1vbWVudHMgc2hvdWxkIGVpdGhlciBiZSBhbiBhcnJheSBvZiBtb21lbnQgb2JqZWN0cyBvciBhbiBhcnJheSwgd2hvc2VcbiAgICAvLyBmaXJzdCBlbGVtZW50IGlzIGFuIGFycmF5IG9mIG1vbWVudCBvYmplY3RzLlxuICAgIGZ1bmN0aW9uIHBpY2tCeShmbiwgbW9tZW50cykge1xuICAgICAgICB2YXIgcmVzLCBpO1xuICAgICAgICBpZiAobW9tZW50cy5sZW5ndGggPT09IDEgJiYgaXNBcnJheShtb21lbnRzWzBdKSkge1xuICAgICAgICAgICAgbW9tZW50cyA9IG1vbWVudHNbMF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtb21lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUxvY2FsKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzID0gbW9tZW50c1swXTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IG1vbWVudHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmICghbW9tZW50c1tpXS5pc1ZhbGlkKCkgfHwgbW9tZW50c1tpXVtmbl0ocmVzKSkge1xuICAgICAgICAgICAgICAgIHJlcyA9IG1vbWVudHNbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBVc2UgW10uc29ydCBpbnN0ZWFkP1xuICAgIGZ1bmN0aW9uIG1pbiAoKSB7XG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuXG4gICAgICAgIHJldHVybiBwaWNrQnkoJ2lzQmVmb3JlJywgYXJncyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF4ICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG5cbiAgICAgICAgcmV0dXJuIHBpY2tCeSgnaXNBZnRlcicsIGFyZ3MpO1xuICAgIH1cblxuICAgIHZhciBub3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBEYXRlLm5vdyA/IERhdGUubm93KCkgOiArKG5ldyBEYXRlKCkpO1xuICAgIH07XG5cbiAgICB2YXIgb3JkZXJpbmcgPSBbJ3llYXInLCAncXVhcnRlcicsICdtb250aCcsICd3ZWVrJywgJ2RheScsICdob3VyJywgJ21pbnV0ZScsICdzZWNvbmQnLCAnbWlsbGlzZWNvbmQnXTtcblxuICAgIGZ1bmN0aW9uIGlzRHVyYXRpb25WYWxpZChtKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBtKSB7XG4gICAgICAgICAgICBpZiAoIShpbmRleE9mLmNhbGwob3JkZXJpbmcsIGtleSkgIT09IC0xICYmIChtW2tleV0gPT0gbnVsbCB8fCAhaXNOYU4obVtrZXldKSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHVuaXRIYXNEZWNpbWFsID0gZmFsc2U7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3JkZXJpbmcubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChtW29yZGVyaW5nW2ldXSkge1xuICAgICAgICAgICAgICAgIGlmICh1bml0SGFzRGVjaW1hbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG9ubHkgYWxsb3cgbm9uLWludGVnZXJzIGZvciBzbWFsbGVzdCB1bml0XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChwYXJzZUZsb2F0KG1bb3JkZXJpbmdbaV1dKSAhPT0gdG9JbnQobVtvcmRlcmluZ1tpXV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHVuaXRIYXNEZWNpbWFsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkJDEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1ZhbGlkO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUludmFsaWQkMSgpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKE5hTik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gRHVyYXRpb24gKGR1cmF0aW9uKSB7XG4gICAgICAgIHZhciBub3JtYWxpemVkSW5wdXQgPSBub3JtYWxpemVPYmplY3RVbml0cyhkdXJhdGlvbiksXG4gICAgICAgICAgICB5ZWFycyA9IG5vcm1hbGl6ZWRJbnB1dC55ZWFyIHx8IDAsXG4gICAgICAgICAgICBxdWFydGVycyA9IG5vcm1hbGl6ZWRJbnB1dC5xdWFydGVyIHx8IDAsXG4gICAgICAgICAgICBtb250aHMgPSBub3JtYWxpemVkSW5wdXQubW9udGggfHwgMCxcbiAgICAgICAgICAgIHdlZWtzID0gbm9ybWFsaXplZElucHV0LndlZWsgfHwgbm9ybWFsaXplZElucHV0Lmlzb1dlZWsgfHwgMCxcbiAgICAgICAgICAgIGRheXMgPSBub3JtYWxpemVkSW5wdXQuZGF5IHx8IDAsXG4gICAgICAgICAgICBob3VycyA9IG5vcm1hbGl6ZWRJbnB1dC5ob3VyIHx8IDAsXG4gICAgICAgICAgICBtaW51dGVzID0gbm9ybWFsaXplZElucHV0Lm1pbnV0ZSB8fCAwLFxuICAgICAgICAgICAgc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5zZWNvbmQgfHwgMCxcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5taWxsaXNlY29uZCB8fCAwO1xuXG4gICAgICAgIHRoaXMuX2lzVmFsaWQgPSBpc0R1cmF0aW9uVmFsaWQobm9ybWFsaXplZElucHV0KTtcblxuICAgICAgICAvLyByZXByZXNlbnRhdGlvbiBmb3IgZGF0ZUFkZFJlbW92ZVxuICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgPSArbWlsbGlzZWNvbmRzICtcbiAgICAgICAgICAgIHNlY29uZHMgKiAxZTMgKyAvLyAxMDAwXG4gICAgICAgICAgICBtaW51dGVzICogNmU0ICsgLy8gMTAwMCAqIDYwXG4gICAgICAgICAgICBob3VycyAqIDEwMDAgKiA2MCAqIDYwOyAvL3VzaW5nIDEwMDAgKiA2MCAqIDYwIGluc3RlYWQgb2YgMzZlNSB0byBhdm9pZCBmbG9hdGluZyBwb2ludCByb3VuZGluZyBlcnJvcnMgaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzI5NzhcbiAgICAgICAgLy8gQmVjYXVzZSBvZiBkYXRlQWRkUmVtb3ZlIHRyZWF0cyAyNCBob3VycyBhcyBkaWZmZXJlbnQgZnJvbSBhXG4gICAgICAgIC8vIGRheSB3aGVuIHdvcmtpbmcgYXJvdW5kIERTVCwgd2UgbmVlZCB0byBzdG9yZSB0aGVtIHNlcGFyYXRlbHlcbiAgICAgICAgdGhpcy5fZGF5cyA9ICtkYXlzICtcbiAgICAgICAgICAgIHdlZWtzICogNztcbiAgICAgICAgLy8gSXQgaXMgaW1wb3NzaWJsZSB0byB0cmFuc2xhdGUgbW9udGhzIGludG8gZGF5cyB3aXRob3V0IGtub3dpbmdcbiAgICAgICAgLy8gd2hpY2ggbW9udGhzIHlvdSBhcmUgYXJlIHRhbGtpbmcgYWJvdXQsIHNvIHdlIGhhdmUgdG8gc3RvcmVcbiAgICAgICAgLy8gaXQgc2VwYXJhdGVseS5cbiAgICAgICAgdGhpcy5fbW9udGhzID0gK21vbnRocyArXG4gICAgICAgICAgICBxdWFydGVycyAqIDMgK1xuICAgICAgICAgICAgeWVhcnMgKiAxMjtcblxuICAgICAgICB0aGlzLl9kYXRhID0ge307XG5cbiAgICAgICAgdGhpcy5fbG9jYWxlID0gZ2V0TG9jYWxlKCk7XG5cbiAgICAgICAgdGhpcy5fYnViYmxlKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEdXJhdGlvbiAob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmogaW5zdGFuY2VvZiBEdXJhdGlvbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhYnNSb3VuZCAobnVtYmVyKSB7XG4gICAgICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCgtMSAqIG51bWJlcikgKiAtMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKG51bWJlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBmdW5jdGlvbiBvZmZzZXQgKHRva2VuLCBzZXBhcmF0b3IpIHtcbiAgICAgICAgYWRkRm9ybWF0VG9rZW4odG9rZW4sIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLnV0Y09mZnNldCgpO1xuICAgICAgICAgICAgdmFyIHNpZ24gPSAnKyc7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IC1vZmZzZXQ7XG4gICAgICAgICAgICAgICAgc2lnbiA9ICctJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzaWduICsgemVyb0ZpbGwofn4ob2Zmc2V0IC8gNjApLCAyKSArIHNlcGFyYXRvciArIHplcm9GaWxsKH5+KG9mZnNldCkgJSA2MCwgMik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9mZnNldCgnWicsICc6Jyk7XG4gICAgb2Zmc2V0KCdaWicsICcnKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1onLCAgbWF0Y2hTaG9ydE9mZnNldCk7XG4gICAgYWRkUmVnZXhUb2tlbignWlonLCBtYXRjaFNob3J0T2Zmc2V0KTtcbiAgICBhZGRQYXJzZVRva2VuKFsnWicsICdaWiddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgY29uZmlnLl91c2VVVEMgPSB0cnVlO1xuICAgICAgICBjb25maWcuX3R6bSA9IG9mZnNldEZyb21TdHJpbmcobWF0Y2hTaG9ydE9mZnNldCwgaW5wdXQpO1xuICAgIH0pO1xuXG4gICAgLy8gSEVMUEVSU1xuXG4gICAgLy8gdGltZXpvbmUgY2h1bmtlclxuICAgIC8vICcrMTA6MDAnID4gWycxMCcsICAnMDAnXVxuICAgIC8vICctMTUzMCcgID4gWyctMTUnLCAnMzAnXVxuICAgIHZhciBjaHVua09mZnNldCA9IC8oW1xcK1xcLV18XFxkXFxkKS9naTtcblxuICAgIGZ1bmN0aW9uIG9mZnNldEZyb21TdHJpbmcobWF0Y2hlciwgc3RyaW5nKSB7XG4gICAgICAgIHZhciBtYXRjaGVzID0gKHN0cmluZyB8fCAnJykubWF0Y2gobWF0Y2hlcik7XG5cbiAgICAgICAgaWYgKG1hdGNoZXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNodW5rICAgPSBtYXRjaGVzW21hdGNoZXMubGVuZ3RoIC0gMV0gfHwgW107XG4gICAgICAgIHZhciBwYXJ0cyAgID0gKGNodW5rICsgJycpLm1hdGNoKGNodW5rT2Zmc2V0KSB8fCBbJy0nLCAwLCAwXTtcbiAgICAgICAgdmFyIG1pbnV0ZXMgPSArKHBhcnRzWzFdICogNjApICsgdG9JbnQocGFydHNbMl0pO1xuXG4gICAgICAgIHJldHVybiBtaW51dGVzID09PSAwID9cbiAgICAgICAgICAwIDpcbiAgICAgICAgICBwYXJ0c1swXSA9PT0gJysnID8gbWludXRlcyA6IC1taW51dGVzO1xuICAgIH1cblxuICAgIC8vIFJldHVybiBhIG1vbWVudCBmcm9tIGlucHV0LCB0aGF0IGlzIGxvY2FsL3V0Yy96b25lIGVxdWl2YWxlbnQgdG8gbW9kZWwuXG4gICAgZnVuY3Rpb24gY2xvbmVXaXRoT2Zmc2V0KGlucHV0LCBtb2RlbCkge1xuICAgICAgICB2YXIgcmVzLCBkaWZmO1xuICAgICAgICBpZiAobW9kZWwuX2lzVVRDKSB7XG4gICAgICAgICAgICByZXMgPSBtb2RlbC5jbG9uZSgpO1xuICAgICAgICAgICAgZGlmZiA9IChpc01vbWVudChpbnB1dCkgfHwgaXNEYXRlKGlucHV0KSA/IGlucHV0LnZhbHVlT2YoKSA6IGNyZWF0ZUxvY2FsKGlucHV0KS52YWx1ZU9mKCkpIC0gcmVzLnZhbHVlT2YoKTtcbiAgICAgICAgICAgIC8vIFVzZSBsb3ctbGV2ZWwgYXBpLCBiZWNhdXNlIHRoaXMgZm4gaXMgbG93LWxldmVsIGFwaS5cbiAgICAgICAgICAgIHJlcy5fZC5zZXRUaW1lKHJlcy5fZC52YWx1ZU9mKCkgKyBkaWZmKTtcbiAgICAgICAgICAgIGhvb2tzLnVwZGF0ZU9mZnNldChyZXMsIGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwoaW5wdXQpLmxvY2FsKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXREYXRlT2Zmc2V0IChtKSB7XG4gICAgICAgIC8vIE9uIEZpcmVmb3guMjQgRGF0ZSNnZXRUaW1lem9uZU9mZnNldCByZXR1cm5zIGEgZmxvYXRpbmcgcG9pbnQuXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tb21lbnQvbW9tZW50L3B1bGwvMTg3MVxuICAgICAgICByZXR1cm4gLU1hdGgucm91bmQobS5fZC5nZXRUaW1lem9uZU9mZnNldCgpIC8gMTUpICogMTU7XG4gICAgfVxuXG4gICAgLy8gSE9PS1NcblxuICAgIC8vIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgd2hlbmV2ZXIgYSBtb21lbnQgaXMgbXV0YXRlZC5cbiAgICAvLyBJdCBpcyBpbnRlbmRlZCB0byBrZWVwIHRoZSBvZmZzZXQgaW4gc3luYyB3aXRoIHRoZSB0aW1lem9uZS5cbiAgICBob29rcy51cGRhdGVPZmZzZXQgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIC8vIGtlZXBMb2NhbFRpbWUgPSB0cnVlIG1lYW5zIG9ubHkgY2hhbmdlIHRoZSB0aW1lem9uZSwgd2l0aG91dFxuICAgIC8vIGFmZmVjdGluZyB0aGUgbG9jYWwgaG91ci4gU28gNTozMToyNiArMDMwMCAtLVt1dGNPZmZzZXQoMiwgdHJ1ZSldLS0+XG4gICAgLy8gNTozMToyNiArMDIwMCBJdCBpcyBwb3NzaWJsZSB0aGF0IDU6MzE6MjYgZG9lc24ndCBleGlzdCB3aXRoIG9mZnNldFxuICAgIC8vICswMjAwLCBzbyB3ZSBhZGp1c3QgdGhlIHRpbWUgYXMgbmVlZGVkLCB0byBiZSB2YWxpZC5cbiAgICAvL1xuICAgIC8vIEtlZXBpbmcgdGhlIHRpbWUgYWN0dWFsbHkgYWRkcy9zdWJ0cmFjdHMgKG9uZSBob3VyKVxuICAgIC8vIGZyb20gdGhlIGFjdHVhbCByZXByZXNlbnRlZCB0aW1lLiBUaGF0IGlzIHdoeSB3ZSBjYWxsIHVwZGF0ZU9mZnNldFxuICAgIC8vIGEgc2Vjb25kIHRpbWUuIEluIGNhc2UgaXQgd2FudHMgdXMgdG8gY2hhbmdlIHRoZSBvZmZzZXQgYWdhaW5cbiAgICAvLyBfY2hhbmdlSW5Qcm9ncmVzcyA9PSB0cnVlIGNhc2UsIHRoZW4gd2UgaGF2ZSB0byBhZGp1c3QsIGJlY2F1c2VcbiAgICAvLyB0aGVyZSBpcyBubyBzdWNoIHRpbWUgaW4gdGhlIGdpdmVuIHRpbWV6b25lLlxuICAgIGZ1bmN0aW9uIGdldFNldE9mZnNldCAoaW5wdXQsIGtlZXBMb2NhbFRpbWUsIGtlZXBNaW51dGVzKSB7XG4gICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLl9vZmZzZXQgfHwgMCxcbiAgICAgICAgICAgIGxvY2FsQWRqdXN0O1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgIT0gbnVsbCA/IHRoaXMgOiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSBvZmZzZXRGcm9tU3RyaW5nKG1hdGNoU2hvcnRPZmZzZXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChNYXRoLmFicyhpbnB1dCkgPCAxNiAmJiAha2VlcE1pbnV0ZXMpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IGlucHV0ICogNjA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuX2lzVVRDICYmIGtlZXBMb2NhbFRpbWUpIHtcbiAgICAgICAgICAgICAgICBsb2NhbEFkanVzdCA9IGdldERhdGVPZmZzZXQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9vZmZzZXQgPSBpbnB1dDtcbiAgICAgICAgICAgIHRoaXMuX2lzVVRDID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChsb2NhbEFkanVzdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGQobG9jYWxBZGp1c3QsICdtJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2Zmc2V0ICE9PSBpbnB1dCkge1xuICAgICAgICAgICAgICAgIGlmICgha2VlcExvY2FsVGltZSB8fCB0aGlzLl9jaGFuZ2VJblByb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZFN1YnRyYWN0KHRoaXMsIGNyZWF0ZUR1cmF0aW9uKGlucHV0IC0gb2Zmc2V0LCAnbScpLCAxLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5fY2hhbmdlSW5Qcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/IG9mZnNldCA6IGdldERhdGVPZmZzZXQodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRab25lIChpbnB1dCwga2VlcExvY2FsVGltZSkge1xuICAgICAgICBpZiAoaW5wdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IC1pbnB1dDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoaW5wdXQsIGtlZXBMb2NhbFRpbWUpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAtdGhpcy51dGNPZmZzZXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldE9mZnNldFRvVVRDIChrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnV0Y09mZnNldCgwLCBrZWVwTG9jYWxUaW1lKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRPZmZzZXRUb0xvY2FsIChrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9pc1VUQykge1xuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoMCwga2VlcExvY2FsVGltZSk7XG4gICAgICAgICAgICB0aGlzLl9pc1VUQyA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoa2VlcExvY2FsVGltZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3VidHJhY3QoZ2V0RGF0ZU9mZnNldCh0aGlzKSwgJ20nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRPZmZzZXRUb1BhcnNlZE9mZnNldCAoKSB7XG4gICAgICAgIGlmICh0aGlzLl90em0gIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQodGhpcy5fdHptLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuX2kgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB2YXIgdFpvbmUgPSBvZmZzZXRGcm9tU3RyaW5nKG1hdGNoT2Zmc2V0LCB0aGlzLl9pKTtcbiAgICAgICAgICAgIGlmICh0Wm9uZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQodFpvbmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoMCwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzQWxpZ25lZEhvdXJPZmZzZXQgKGlucHV0KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dCA9IGlucHV0ID8gY3JlYXRlTG9jYWwoaW5wdXQpLnV0Y09mZnNldCgpIDogMDtcblxuICAgICAgICByZXR1cm4gKHRoaXMudXRjT2Zmc2V0KCkgLSBpbnB1dCkgJSA2MCA9PT0gMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0RheWxpZ2h0U2F2aW5nVGltZSAoKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLnV0Y09mZnNldCgpID4gdGhpcy5jbG9uZSgpLm1vbnRoKDApLnV0Y09mZnNldCgpIHx8XG4gICAgICAgICAgICB0aGlzLnV0Y09mZnNldCgpID4gdGhpcy5jbG9uZSgpLm1vbnRoKDUpLnV0Y09mZnNldCgpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEYXlsaWdodFNhdmluZ1RpbWVTaGlmdGVkICgpIHtcbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9pc0RTVFNoaWZ0ZWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faXNEU1RTaGlmdGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGMgPSB7fTtcblxuICAgICAgICBjb3B5Q29uZmlnKGMsIHRoaXMpO1xuICAgICAgICBjID0gcHJlcGFyZUNvbmZpZyhjKTtcblxuICAgICAgICBpZiAoYy5fYSkge1xuICAgICAgICAgICAgdmFyIG90aGVyID0gYy5faXNVVEMgPyBjcmVhdGVVVEMoYy5fYSkgOiBjcmVhdGVMb2NhbChjLl9hKTtcbiAgICAgICAgICAgIHRoaXMuX2lzRFNUU2hpZnRlZCA9IHRoaXMuaXNWYWxpZCgpICYmXG4gICAgICAgICAgICAgICAgY29tcGFyZUFycmF5cyhjLl9hLCBvdGhlci50b0FycmF5KCkpID4gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2lzRFNUU2hpZnRlZCA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzRFNUU2hpZnRlZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0xvY2FsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gIXRoaXMuX2lzVVRDIDogZmFsc2U7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNVdGNPZmZzZXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1ZhbGlkKCkgPyB0aGlzLl9pc1VUQyA6IGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVXRjICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpcy5faXNVVEMgJiYgdGhpcy5fb2Zmc2V0ID09PSAwIDogZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQVNQLk5FVCBqc29uIGRhdGUgZm9ybWF0IHJlZ2V4XG4gICAgdmFyIGFzcE5ldFJlZ2V4ID0gL14oXFwtfFxcKyk/KD86KFxcZCopWy4gXSk/KFxcZCspXFw6KFxcZCspKD86XFw6KFxcZCspKFxcLlxcZCopPyk/JC87XG5cbiAgICAvLyBmcm9tIGh0dHA6Ly9kb2NzLmNsb3N1cmUtbGlicmFyeS5nb29nbGVjb2RlLmNvbS9naXQvY2xvc3VyZV9nb29nX2RhdGVfZGF0ZS5qcy5zb3VyY2UuaHRtbFxuICAgIC8vIHNvbWV3aGF0IG1vcmUgaW4gbGluZSB3aXRoIDQuNC4zLjIgMjAwNCBzcGVjLCBidXQgYWxsb3dzIGRlY2ltYWwgYW55d2hlcmVcbiAgICAvLyBhbmQgZnVydGhlciBtb2RpZmllZCB0byBhbGxvdyBmb3Igc3RyaW5ncyBjb250YWluaW5nIGJvdGggd2VlayBhbmQgZGF5XG4gICAgdmFyIGlzb1JlZ2V4ID0gL14oLXxcXCspP1AoPzooWy0rXT9bMC05LC5dKilZKT8oPzooWy0rXT9bMC05LC5dKilNKT8oPzooWy0rXT9bMC05LC5dKilXKT8oPzooWy0rXT9bMC05LC5dKilEKT8oPzpUKD86KFstK10/WzAtOSwuXSopSCk/KD86KFstK10/WzAtOSwuXSopTSk/KD86KFstK10/WzAtOSwuXSopUyk/KT8kLztcblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUR1cmF0aW9uIChpbnB1dCwga2V5KSB7XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IGlucHV0LFxuICAgICAgICAgICAgLy8gbWF0Y2hpbmcgYWdhaW5zdCByZWdleHAgaXMgZXhwZW5zaXZlLCBkbyBpdCBvbiBkZW1hbmRcbiAgICAgICAgICAgIG1hdGNoID0gbnVsbCxcbiAgICAgICAgICAgIHNpZ24sXG4gICAgICAgICAgICByZXQsXG4gICAgICAgICAgICBkaWZmUmVzO1xuXG4gICAgICAgIGlmIChpc0R1cmF0aW9uKGlucHV0KSkge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgbXMgOiBpbnB1dC5fbWlsbGlzZWNvbmRzLFxuICAgICAgICAgICAgICAgIGQgIDogaW5wdXQuX2RheXMsXG4gICAgICAgICAgICAgICAgTSAgOiBpbnB1dC5fbW9udGhzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKGlucHV0KSkge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbltrZXldID0gaW5wdXQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uLm1pbGxpc2Vjb25kcyA9IGlucHV0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEhKG1hdGNoID0gYXNwTmV0UmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeSAgOiAwLFxuICAgICAgICAgICAgICAgIGQgIDogdG9JbnQobWF0Y2hbREFURV0pICAgICAgICAgICAgICAgICAgICAgICAgICogc2lnbixcbiAgICAgICAgICAgICAgICBoICA6IHRvSW50KG1hdGNoW0hPVVJdKSAgICAgICAgICAgICAgICAgICAgICAgICAqIHNpZ24sXG4gICAgICAgICAgICAgICAgbSAgOiB0b0ludChtYXRjaFtNSU5VVEVdKSAgICAgICAgICAgICAgICAgICAgICAgKiBzaWduLFxuICAgICAgICAgICAgICAgIHMgIDogdG9JbnQobWF0Y2hbU0VDT05EXSkgICAgICAgICAgICAgICAgICAgICAgICogc2lnbixcbiAgICAgICAgICAgICAgICBtcyA6IHRvSW50KGFic1JvdW5kKG1hdGNoW01JTExJU0VDT05EXSAqIDEwMDApKSAqIHNpZ24gLy8gdGhlIG1pbGxpc2Vjb25kIGRlY2ltYWwgcG9pbnQgaXMgaW5jbHVkZWQgaW4gdGhlIG1hdGNoXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKCEhKG1hdGNoID0gaXNvUmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeSA6IHBhcnNlSXNvKG1hdGNoWzJdLCBzaWduKSxcbiAgICAgICAgICAgICAgICBNIDogcGFyc2VJc28obWF0Y2hbM10sIHNpZ24pLFxuICAgICAgICAgICAgICAgIHcgOiBwYXJzZUlzbyhtYXRjaFs0XSwgc2lnbiksXG4gICAgICAgICAgICAgICAgZCA6IHBhcnNlSXNvKG1hdGNoWzVdLCBzaWduKSxcbiAgICAgICAgICAgICAgICBoIDogcGFyc2VJc28obWF0Y2hbNl0sIHNpZ24pLFxuICAgICAgICAgICAgICAgIG0gOiBwYXJzZUlzbyhtYXRjaFs3XSwgc2lnbiksXG4gICAgICAgICAgICAgICAgcyA6IHBhcnNlSXNvKG1hdGNoWzhdLCBzaWduKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmIChkdXJhdGlvbiA9PSBudWxsKSB7Ly8gY2hlY2tzIGZvciBudWxsIG9yIHVuZGVmaW5lZFxuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZHVyYXRpb24gPT09ICdvYmplY3QnICYmICgnZnJvbScgaW4gZHVyYXRpb24gfHwgJ3RvJyBpbiBkdXJhdGlvbikpIHtcbiAgICAgICAgICAgIGRpZmZSZXMgPSBtb21lbnRzRGlmZmVyZW5jZShjcmVhdGVMb2NhbChkdXJhdGlvbi5mcm9tKSwgY3JlYXRlTG9jYWwoZHVyYXRpb24udG8pKTtcblxuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGR1cmF0aW9uLm1zID0gZGlmZlJlcy5taWxsaXNlY29uZHM7XG4gICAgICAgICAgICBkdXJhdGlvbi5NID0gZGlmZlJlcy5tb250aHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXQgPSBuZXcgRHVyYXRpb24oZHVyYXRpb24pO1xuXG4gICAgICAgIGlmIChpc0R1cmF0aW9uKGlucHV0KSAmJiBoYXNPd25Qcm9wKGlucHV0LCAnX2xvY2FsZScpKSB7XG4gICAgICAgICAgICByZXQuX2xvY2FsZSA9IGlucHV0Ll9sb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIGNyZWF0ZUR1cmF0aW9uLmZuID0gRHVyYXRpb24ucHJvdG90eXBlO1xuICAgIGNyZWF0ZUR1cmF0aW9uLmludmFsaWQgPSBjcmVhdGVJbnZhbGlkJDE7XG5cbiAgICBmdW5jdGlvbiBwYXJzZUlzbyAoaW5wLCBzaWduKSB7XG4gICAgICAgIC8vIFdlJ2Qgbm9ybWFsbHkgdXNlIH5+aW5wIGZvciB0aGlzLCBidXQgdW5mb3J0dW5hdGVseSBpdCBhbHNvXG4gICAgICAgIC8vIGNvbnZlcnRzIGZsb2F0cyB0byBpbnRzLlxuICAgICAgICAvLyBpbnAgbWF5IGJlIHVuZGVmaW5lZCwgc28gY2FyZWZ1bCBjYWxsaW5nIHJlcGxhY2Ugb24gaXQuXG4gICAgICAgIHZhciByZXMgPSBpbnAgJiYgcGFyc2VGbG9hdChpbnAucmVwbGFjZSgnLCcsICcuJykpO1xuICAgICAgICAvLyBhcHBseSBzaWduIHdoaWxlIHdlJ3JlIGF0IGl0XG4gICAgICAgIHJldHVybiAoaXNOYU4ocmVzKSA/IDAgOiByZXMpICogc2lnbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKSB7XG4gICAgICAgIHZhciByZXMgPSB7fTtcblxuICAgICAgICByZXMubW9udGhzID0gb3RoZXIubW9udGgoKSAtIGJhc2UubW9udGgoKSArXG4gICAgICAgICAgICAob3RoZXIueWVhcigpIC0gYmFzZS55ZWFyKCkpICogMTI7XG4gICAgICAgIGlmIChiYXNlLmNsb25lKCkuYWRkKHJlcy5tb250aHMsICdNJykuaXNBZnRlcihvdGhlcikpIHtcbiAgICAgICAgICAgIC0tcmVzLm1vbnRocztcbiAgICAgICAgfVxuXG4gICAgICAgIHJlcy5taWxsaXNlY29uZHMgPSArb3RoZXIgLSArKGJhc2UuY2xvbmUoKS5hZGQocmVzLm1vbnRocywgJ00nKSk7XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb21lbnRzRGlmZmVyZW5jZShiYXNlLCBvdGhlcikge1xuICAgICAgICB2YXIgcmVzO1xuICAgICAgICBpZiAoIShiYXNlLmlzVmFsaWQoKSAmJiBvdGhlci5pc1ZhbGlkKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4ge21pbGxpc2Vjb25kczogMCwgbW9udGhzOiAwfTtcbiAgICAgICAgfVxuXG4gICAgICAgIG90aGVyID0gY2xvbmVXaXRoT2Zmc2V0KG90aGVyLCBiYXNlKTtcbiAgICAgICAgaWYgKGJhc2UuaXNCZWZvcmUob3RoZXIpKSB7XG4gICAgICAgICAgICByZXMgPSBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcyA9IHBvc2l0aXZlTW9tZW50c0RpZmZlcmVuY2Uob3RoZXIsIGJhc2UpO1xuICAgICAgICAgICAgcmVzLm1pbGxpc2Vjb25kcyA9IC1yZXMubWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgcmVzLm1vbnRocyA9IC1yZXMubW9udGhzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvLyBUT0RPOiByZW1vdmUgJ25hbWUnIGFyZyBhZnRlciBkZXByZWNhdGlvbiBpcyByZW1vdmVkXG4gICAgZnVuY3Rpb24gY3JlYXRlQWRkZXIoZGlyZWN0aW9uLCBuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsLCBwZXJpb2QpIHtcbiAgICAgICAgICAgIHZhciBkdXIsIHRtcDtcbiAgICAgICAgICAgIC8vaW52ZXJ0IHRoZSBhcmd1bWVudHMsIGJ1dCBjb21wbGFpbiBhYm91dCBpdFxuICAgICAgICAgICAgaWYgKHBlcmlvZCAhPT0gbnVsbCAmJiAhaXNOYU4oK3BlcmlvZCkpIHtcbiAgICAgICAgICAgICAgICBkZXByZWNhdGVTaW1wbGUobmFtZSwgJ21vbWVudCgpLicgKyBuYW1lICArICcocGVyaW9kLCBudW1iZXIpIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgbW9tZW50KCkuJyArIG5hbWUgKyAnKG51bWJlciwgcGVyaW9kKS4gJyArXG4gICAgICAgICAgICAgICAgJ1NlZSBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2FkZC1pbnZlcnRlZC1wYXJhbS8gZm9yIG1vcmUgaW5mby4nKTtcbiAgICAgICAgICAgICAgICB0bXAgPSB2YWw7IHZhbCA9IHBlcmlvZDsgcGVyaW9kID0gdG1wO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YWwgPSB0eXBlb2YgdmFsID09PSAnc3RyaW5nJyA/ICt2YWwgOiB2YWw7XG4gICAgICAgICAgICBkdXIgPSBjcmVhdGVEdXJhdGlvbih2YWwsIHBlcmlvZCk7XG4gICAgICAgICAgICBhZGRTdWJ0cmFjdCh0aGlzLCBkdXIsIGRpcmVjdGlvbik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRTdWJ0cmFjdCAobW9tLCBkdXJhdGlvbiwgaXNBZGRpbmcsIHVwZGF0ZU9mZnNldCkge1xuICAgICAgICB2YXIgbWlsbGlzZWNvbmRzID0gZHVyYXRpb24uX21pbGxpc2Vjb25kcyxcbiAgICAgICAgICAgIGRheXMgPSBhYnNSb3VuZChkdXJhdGlvbi5fZGF5cyksXG4gICAgICAgICAgICBtb250aHMgPSBhYnNSb3VuZChkdXJhdGlvbi5fbW9udGhzKTtcblxuICAgICAgICBpZiAoIW1vbS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIC8vIE5vIG9wXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB1cGRhdGVPZmZzZXQgPSB1cGRhdGVPZmZzZXQgPT0gbnVsbCA/IHRydWUgOiB1cGRhdGVPZmZzZXQ7XG5cbiAgICAgICAgaWYgKG1vbnRocykge1xuICAgICAgICAgICAgc2V0TW9udGgobW9tLCBnZXQobW9tLCAnTW9udGgnKSArIG1vbnRocyAqIGlzQWRkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF5cykge1xuICAgICAgICAgICAgc2V0JDEobW9tLCAnRGF0ZScsIGdldChtb20sICdEYXRlJykgKyBkYXlzICogaXNBZGRpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtaWxsaXNlY29uZHMpIHtcbiAgICAgICAgICAgIG1vbS5fZC5zZXRUaW1lKG1vbS5fZC52YWx1ZU9mKCkgKyBtaWxsaXNlY29uZHMgKiBpc0FkZGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVwZGF0ZU9mZnNldCkge1xuICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KG1vbSwgZGF5cyB8fCBtb250aHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGFkZCAgICAgID0gY3JlYXRlQWRkZXIoMSwgJ2FkZCcpO1xuICAgIHZhciBzdWJ0cmFjdCA9IGNyZWF0ZUFkZGVyKC0xLCAnc3VidHJhY3QnKTtcblxuICAgIGZ1bmN0aW9uIGdldENhbGVuZGFyRm9ybWF0KG15TW9tZW50LCBub3cpIHtcbiAgICAgICAgdmFyIGRpZmYgPSBteU1vbWVudC5kaWZmKG5vdywgJ2RheXMnLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIGRpZmYgPCAtNiA/ICdzYW1lRWxzZScgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCAtMSA/ICdsYXN0V2VlaycgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCAwID8gJ2xhc3REYXknIDpcbiAgICAgICAgICAgICAgICBkaWZmIDwgMSA/ICdzYW1lRGF5JyA6XG4gICAgICAgICAgICAgICAgZGlmZiA8IDIgPyAnbmV4dERheScgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCA3ID8gJ25leHRXZWVrJyA6ICdzYW1lRWxzZSc7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsZW5kYXIkMSAodGltZSwgZm9ybWF0cykge1xuICAgICAgICAvLyBXZSB3YW50IHRvIGNvbXBhcmUgdGhlIHN0YXJ0IG9mIHRvZGF5LCB2cyB0aGlzLlxuICAgICAgICAvLyBHZXR0aW5nIHN0YXJ0LW9mLXRvZGF5IGRlcGVuZHMgb24gd2hldGhlciB3ZSdyZSBsb2NhbC91dGMvb2Zmc2V0IG9yIG5vdC5cbiAgICAgICAgdmFyIG5vdyA9IHRpbWUgfHwgY3JlYXRlTG9jYWwoKSxcbiAgICAgICAgICAgIHNvZCA9IGNsb25lV2l0aE9mZnNldChub3csIHRoaXMpLnN0YXJ0T2YoJ2RheScpLFxuICAgICAgICAgICAgZm9ybWF0ID0gaG9va3MuY2FsZW5kYXJGb3JtYXQodGhpcywgc29kKSB8fCAnc2FtZUVsc2UnO1xuXG4gICAgICAgIHZhciBvdXRwdXQgPSBmb3JtYXRzICYmIChpc0Z1bmN0aW9uKGZvcm1hdHNbZm9ybWF0XSkgPyBmb3JtYXRzW2Zvcm1hdF0uY2FsbCh0aGlzLCBub3cpIDogZm9ybWF0c1tmb3JtYXRdKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXQob3V0cHV0IHx8IHRoaXMubG9jYWxlRGF0YSgpLmNhbGVuZGFyKGZvcm1hdCwgdGhpcywgY3JlYXRlTG9jYWwobm93KSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsb25lICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBNb21lbnQodGhpcyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBZnRlciAoaW5wdXQsIHVuaXRzKSB7XG4gICAgICAgIHZhciBsb2NhbElucHV0ID0gaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBjcmVhdGVMb2NhbChpbnB1dCk7XG4gICAgICAgIGlmICghKHRoaXMuaXNWYWxpZCgpICYmIGxvY2FsSW5wdXQuaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpIHx8ICdtaWxsaXNlY29uZCc7XG4gICAgICAgIGlmICh1bml0cyA9PT0gJ21pbGxpc2Vjb25kJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpID4gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbG9jYWxJbnB1dC52YWx1ZU9mKCkgPCB0aGlzLmNsb25lKCkuc3RhcnRPZih1bml0cykudmFsdWVPZigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNCZWZvcmUgKGlucHV0LCB1bml0cykge1xuICAgICAgICB2YXIgbG9jYWxJbnB1dCA9IGlzTW9tZW50KGlucHV0KSA/IGlucHV0IDogY3JlYXRlTG9jYWwoaW5wdXQpO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbElucHV0LmlzVmFsaWQoKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB8fCAnbWlsbGlzZWNvbmQnO1xuICAgICAgICBpZiAodW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKSA8IGxvY2FsSW5wdXQudmFsdWVPZigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmRPZih1bml0cykudmFsdWVPZigpIDwgbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0JldHdlZW4gKGZyb20sIHRvLCB1bml0cywgaW5jbHVzaXZpdHkpIHtcbiAgICAgICAgdmFyIGxvY2FsRnJvbSA9IGlzTW9tZW50KGZyb20pID8gZnJvbSA6IGNyZWF0ZUxvY2FsKGZyb20pLFxuICAgICAgICAgICAgbG9jYWxUbyA9IGlzTW9tZW50KHRvKSA/IHRvIDogY3JlYXRlTG9jYWwodG8pO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbEZyb20uaXNWYWxpZCgpICYmIGxvY2FsVG8uaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGluY2x1c2l2aXR5ID0gaW5jbHVzaXZpdHkgfHwgJygpJztcbiAgICAgICAgcmV0dXJuIChpbmNsdXNpdml0eVswXSA9PT0gJygnID8gdGhpcy5pc0FmdGVyKGxvY2FsRnJvbSwgdW5pdHMpIDogIXRoaXMuaXNCZWZvcmUobG9jYWxGcm9tLCB1bml0cykpICYmXG4gICAgICAgICAgICAoaW5jbHVzaXZpdHlbMV0gPT09ICcpJyA/IHRoaXMuaXNCZWZvcmUobG9jYWxUbywgdW5pdHMpIDogIXRoaXMuaXNBZnRlcihsb2NhbFRvLCB1bml0cykpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzU2FtZSAoaW5wdXQsIHVuaXRzKSB7XG4gICAgICAgIHZhciBsb2NhbElucHV0ID0gaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBjcmVhdGVMb2NhbChpbnB1dCksXG4gICAgICAgICAgICBpbnB1dE1zO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbElucHV0LmlzVmFsaWQoKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB8fCAnbWlsbGlzZWNvbmQnO1xuICAgICAgICBpZiAodW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKSA9PT0gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbnB1dE1zID0gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jbG9uZSgpLnN0YXJ0T2YodW5pdHMpLnZhbHVlT2YoKSA8PSBpbnB1dE1zICYmIGlucHV0TXMgPD0gdGhpcy5jbG9uZSgpLmVuZE9mKHVuaXRzKS52YWx1ZU9mKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1NhbWVPckFmdGVyIChpbnB1dCwgdW5pdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNTYW1lKGlucHV0LCB1bml0cykgfHwgdGhpcy5pc0FmdGVyKGlucHV0LCB1bml0cyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNTYW1lT3JCZWZvcmUgKGlucHV0LCB1bml0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1NhbWUoaW5wdXQsIHVuaXRzKSB8fCB0aGlzLmlzQmVmb3JlKGlucHV0LCB1bml0cyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGlmZiAoaW5wdXQsIHVuaXRzLCBhc0Zsb2F0KSB7XG4gICAgICAgIHZhciB0aGF0LFxuICAgICAgICAgICAgem9uZURlbHRhLFxuICAgICAgICAgICAgb3V0cHV0O1xuXG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgIH1cblxuICAgICAgICB0aGF0ID0gY2xvbmVXaXRoT2Zmc2V0KGlucHV0LCB0aGlzKTtcblxuICAgICAgICBpZiAoIXRoYXQuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG5cbiAgICAgICAgem9uZURlbHRhID0gKHRoYXQudXRjT2Zmc2V0KCkgLSB0aGlzLnV0Y09mZnNldCgpKSAqIDZlNDtcblxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzogb3V0cHV0ID0gbW9udGhEaWZmKHRoaXMsIHRoYXQpIC8gMTI7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOiBvdXRwdXQgPSBtb250aERpZmYodGhpcywgdGhhdCk7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6IG91dHB1dCA9IG1vbnRoRGlmZih0aGlzLCB0aGF0KSAvIDM7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzogb3V0cHV0ID0gKHRoaXMgLSB0aGF0KSAvIDFlMzsgYnJlYWs7IC8vIDEwMDBcbiAgICAgICAgICAgIGNhc2UgJ21pbnV0ZSc6IG91dHB1dCA9ICh0aGlzIC0gdGhhdCkgLyA2ZTQ7IGJyZWFrOyAvLyAxMDAwICogNjBcbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOiBvdXRwdXQgPSAodGhpcyAtIHRoYXQpIC8gMzZlNTsgYnJlYWs7IC8vIDEwMDAgKiA2MCAqIDYwXG4gICAgICAgICAgICBjYXNlICdkYXknOiBvdXRwdXQgPSAodGhpcyAtIHRoYXQgLSB6b25lRGVsdGEpIC8gODY0ZTU7IGJyZWFrOyAvLyAxMDAwICogNjAgKiA2MCAqIDI0LCBuZWdhdGUgZHN0XG4gICAgICAgICAgICBjYXNlICd3ZWVrJzogb3V0cHV0ID0gKHRoaXMgLSB0aGF0IC0gem9uZURlbHRhKSAvIDYwNDhlNTsgYnJlYWs7IC8vIDEwMDAgKiA2MCAqIDYwICogMjQgKiA3LCBuZWdhdGUgZHN0XG4gICAgICAgICAgICBkZWZhdWx0OiBvdXRwdXQgPSB0aGlzIC0gdGhhdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhc0Zsb2F0ID8gb3V0cHV0IDogYWJzRmxvb3Iob3V0cHV0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb250aERpZmYgKGEsIGIpIHtcbiAgICAgICAgLy8gZGlmZmVyZW5jZSBpbiBtb250aHNcbiAgICAgICAgdmFyIHdob2xlTW9udGhEaWZmID0gKChiLnllYXIoKSAtIGEueWVhcigpKSAqIDEyKSArIChiLm1vbnRoKCkgLSBhLm1vbnRoKCkpLFxuICAgICAgICAgICAgLy8gYiBpcyBpbiAoYW5jaG9yIC0gMSBtb250aCwgYW5jaG9yICsgMSBtb250aClcbiAgICAgICAgICAgIGFuY2hvciA9IGEuY2xvbmUoKS5hZGQod2hvbGVNb250aERpZmYsICdtb250aHMnKSxcbiAgICAgICAgICAgIGFuY2hvcjIsIGFkanVzdDtcblxuICAgICAgICBpZiAoYiAtIGFuY2hvciA8IDApIHtcbiAgICAgICAgICAgIGFuY2hvcjIgPSBhLmNsb25lKCkuYWRkKHdob2xlTW9udGhEaWZmIC0gMSwgJ21vbnRocycpO1xuICAgICAgICAgICAgLy8gbGluZWFyIGFjcm9zcyB0aGUgbW9udGhcbiAgICAgICAgICAgIGFkanVzdCA9IChiIC0gYW5jaG9yKSAvIChhbmNob3IgLSBhbmNob3IyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFuY2hvcjIgPSBhLmNsb25lKCkuYWRkKHdob2xlTW9udGhEaWZmICsgMSwgJ21vbnRocycpO1xuICAgICAgICAgICAgLy8gbGluZWFyIGFjcm9zcyB0aGUgbW9udGhcbiAgICAgICAgICAgIGFkanVzdCA9IChiIC0gYW5jaG9yKSAvIChhbmNob3IyIC0gYW5jaG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vY2hlY2sgZm9yIG5lZ2F0aXZlIHplcm8sIHJldHVybiB6ZXJvIGlmIG5lZ2F0aXZlIHplcm9cbiAgICAgICAgcmV0dXJuIC0od2hvbGVNb250aERpZmYgKyBhZGp1c3QpIHx8IDA7XG4gICAgfVxuXG4gICAgaG9va3MuZGVmYXVsdEZvcm1hdCA9ICdZWVlZLU1NLUREVEhIOm1tOnNzWic7XG4gICAgaG9va3MuZGVmYXVsdEZvcm1hdFV0YyA9ICdZWVlZLU1NLUREVEhIOm1tOnNzW1pdJztcblxuICAgIGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5sb2NhbGUoJ2VuJykuZm9ybWF0KCdkZGQgTU1NIEREIFlZWVkgSEg6bW06c3MgW0dNVF1aWicpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvSVNPU3RyaW5nKGtlZXBPZmZzZXQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHV0YyA9IGtlZXBPZmZzZXQgIT09IHRydWU7XG4gICAgICAgIHZhciBtID0gdXRjID8gdGhpcy5jbG9uZSgpLnV0YygpIDogdGhpcztcbiAgICAgICAgaWYgKG0ueWVhcigpIDwgMCB8fCBtLnllYXIoKSA+IDk5OTkpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXRNb21lbnQobSwgdXRjID8gJ1lZWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1taXScgOiAnWVlZWVlZLU1NLUREW1RdSEg6bW06c3MuU1NTWicpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nKSkge1xuICAgICAgICAgICAgLy8gbmF0aXZlIGltcGxlbWVudGF0aW9uIGlzIH41MHggZmFzdGVyLCB1c2UgaXQgd2hlbiB3ZSBjYW5cbiAgICAgICAgICAgIGlmICh1dGMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0RhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkgKyB0aGlzLnV0Y09mZnNldCgpICogNjAgKiAxMDAwKS50b0lTT1N0cmluZygpLnJlcGxhY2UoJ1onLCBmb3JtYXRNb21lbnQobSwgJ1onKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdE1vbWVudChtLCB1dGMgPyAnWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1taXScgOiAnWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1onKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gYSBodW1hbiByZWFkYWJsZSByZXByZXNlbnRhdGlvbiBvZiBhIG1vbWVudCB0aGF0IGNhblxuICAgICAqIGFsc28gYmUgZXZhbHVhdGVkIHRvIGdldCBhIG5ldyBtb21lbnQgd2hpY2ggaXMgdGhlIHNhbWVcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHBzOi8vbm9kZWpzLm9yZy9kaXN0L2xhdGVzdC9kb2NzL2FwaS91dGlsLmh0bWwjdXRpbF9jdXN0b21faW5zcGVjdF9mdW5jdGlvbl9vbl9vYmplY3RzXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiAnbW9tZW50LmludmFsaWQoLyogJyArIHRoaXMuX2kgKyAnICovKSc7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZ1bmMgPSAnbW9tZW50JztcbiAgICAgICAgdmFyIHpvbmUgPSAnJztcbiAgICAgICAgaWYgKCF0aGlzLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgZnVuYyA9IHRoaXMudXRjT2Zmc2V0KCkgPT09IDAgPyAnbW9tZW50LnV0YycgOiAnbW9tZW50LnBhcnNlWm9uZSc7XG4gICAgICAgICAgICB6b25lID0gJ1onO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcmVmaXggPSAnWycgKyBmdW5jICsgJyhcIl0nO1xuICAgICAgICB2YXIgeWVhciA9ICgwIDw9IHRoaXMueWVhcigpICYmIHRoaXMueWVhcigpIDw9IDk5OTkpID8gJ1lZWVknIDogJ1lZWVlZWSc7XG4gICAgICAgIHZhciBkYXRldGltZSA9ICctTU0tRERbVF1ISDptbTpzcy5TU1MnO1xuICAgICAgICB2YXIgc3VmZml4ID0gem9uZSArICdbXCIpXSc7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0KHByZWZpeCArIHllYXIgKyBkYXRldGltZSArIHN1ZmZpeCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0IChpbnB1dFN0cmluZykge1xuICAgICAgICBpZiAoIWlucHV0U3RyaW5nKSB7XG4gICAgICAgICAgICBpbnB1dFN0cmluZyA9IHRoaXMuaXNVdGMoKSA/IGhvb2tzLmRlZmF1bHRGb3JtYXRVdGMgOiBob29rcy5kZWZhdWx0Rm9ybWF0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBvdXRwdXQgPSBmb3JtYXRNb21lbnQodGhpcywgaW5wdXRTdHJpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkucG9zdGZvcm1hdChvdXRwdXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZyb20gKHRpbWUsIHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNWYWxpZCgpICYmXG4gICAgICAgICAgICAgICAgKChpc01vbWVudCh0aW1lKSAmJiB0aW1lLmlzVmFsaWQoKSkgfHxcbiAgICAgICAgICAgICAgICAgY3JlYXRlTG9jYWwodGltZSkuaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKHt0bzogdGhpcywgZnJvbTogdGltZX0pLmxvY2FsZSh0aGlzLmxvY2FsZSgpKS5odW1hbml6ZSghd2l0aG91dFN1ZmZpeCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkuaW52YWxpZERhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZyb21Ob3cgKHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbShjcmVhdGVMb2NhbCgpLCB3aXRob3V0U3VmZml4KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0byAodGltZSwgd2l0aG91dFN1ZmZpeCkge1xuICAgICAgICBpZiAodGhpcy5pc1ZhbGlkKCkgJiZcbiAgICAgICAgICAgICAgICAoKGlzTW9tZW50KHRpbWUpICYmIHRpbWUuaXNWYWxpZCgpKSB8fFxuICAgICAgICAgICAgICAgICBjcmVhdGVMb2NhbCh0aW1lKS5pc1ZhbGlkKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlRHVyYXRpb24oe2Zyb206IHRoaXMsIHRvOiB0aW1lfSkubG9jYWxlKHRoaXMubG9jYWxlKCkpLmh1bWFuaXplKCF3aXRob3V0U3VmZml4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS5pbnZhbGlkRGF0ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9Ob3cgKHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG8oY3JlYXRlTG9jYWwoKSwgd2l0aG91dFN1ZmZpeCk7XG4gICAgfVxuXG4gICAgLy8gSWYgcGFzc2VkIGEgbG9jYWxlIGtleSwgaXQgd2lsbCBzZXQgdGhlIGxvY2FsZSBmb3IgdGhpc1xuICAgIC8vIGluc3RhbmNlLiAgT3RoZXJ3aXNlLCBpdCB3aWxsIHJldHVybiB0aGUgbG9jYWxlIGNvbmZpZ3VyYXRpb25cbiAgICAvLyB2YXJpYWJsZXMgZm9yIHRoaXMgaW5zdGFuY2UuXG4gICAgZnVuY3Rpb24gbG9jYWxlIChrZXkpIHtcbiAgICAgICAgdmFyIG5ld0xvY2FsZURhdGE7XG5cbiAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlLl9hYmJyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3TG9jYWxlRGF0YSA9IGdldExvY2FsZShrZXkpO1xuICAgICAgICAgICAgaWYgKG5ld0xvY2FsZURhdGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvY2FsZSA9IG5ld0xvY2FsZURhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBsYW5nID0gZGVwcmVjYXRlKFxuICAgICAgICAnbW9tZW50KCkubGFuZygpIGlzIGRlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZSBtb21lbnQoKS5sb2NhbGVEYXRhKCkgdG8gZ2V0IHRoZSBsYW5ndWFnZSBjb25maWd1cmF0aW9uLiBVc2UgbW9tZW50KCkubG9jYWxlKCkgdG8gY2hhbmdlIGxhbmd1YWdlcy4nLFxuICAgICAgICBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZShrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIGZ1bmN0aW9uIGxvY2FsZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlO1xuICAgIH1cblxuICAgIHZhciBNU19QRVJfU0VDT05EID0gMTAwMDtcbiAgICB2YXIgTVNfUEVSX01JTlVURSA9IDYwICogTVNfUEVSX1NFQ09ORDtcbiAgICB2YXIgTVNfUEVSX0hPVVIgPSA2MCAqIE1TX1BFUl9NSU5VVEU7XG4gICAgdmFyIE1TX1BFUl80MDBfWUVBUlMgPSAoMzY1ICogNDAwICsgOTcpICogMjQgKiBNU19QRVJfSE9VUjtcblxuICAgIC8vIGFjdHVhbCBtb2R1bG8gLSBoYW5kbGVzIG5lZ2F0aXZlIG51bWJlcnMgKGZvciBkYXRlcyBiZWZvcmUgMTk3MCk6XG4gICAgZnVuY3Rpb24gbW9kJDEoZGl2aWRlbmQsIGRpdmlzb3IpIHtcbiAgICAgICAgcmV0dXJuIChkaXZpZGVuZCAlIGRpdmlzb3IgKyBkaXZpc29yKSAlIGRpdmlzb3I7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9jYWxTdGFydE9mRGF0ZSh5LCBtLCBkKSB7XG4gICAgICAgIC8vIHRoZSBkYXRlIGNvbnN0cnVjdG9yIHJlbWFwcyB5ZWFycyAwLTk5IHRvIDE5MDAtMTk5OVxuICAgICAgICBpZiAoeSA8IDEwMCAmJiB5ID49IDApIHtcbiAgICAgICAgICAgIC8vIHByZXNlcnZlIGxlYXAgeWVhcnMgdXNpbmcgYSBmdWxsIDQwMCB5ZWFyIGN5Y2xlLCB0aGVuIHJlc2V0XG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoeSArIDQwMCwgbSwgZCkgLSBNU19QRVJfNDAwX1lFQVJTO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHksIG0sIGQpLnZhbHVlT2YoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHV0Y1N0YXJ0T2ZEYXRlKHksIG0sIGQpIHtcbiAgICAgICAgLy8gRGF0ZS5VVEMgcmVtYXBzIHllYXJzIDAtOTkgdG8gMTkwMC0xOTk5XG4gICAgICAgIGlmICh5IDwgMTAwICYmIHkgPj0gMCkge1xuICAgICAgICAgICAgLy8gcHJlc2VydmUgbGVhcCB5ZWFycyB1c2luZyBhIGZ1bGwgNDAwIHllYXIgY3ljbGUsIHRoZW4gcmVzZXRcbiAgICAgICAgICAgIHJldHVybiBEYXRlLlVUQyh5ICsgNDAwLCBtLCBkKSAtIE1TX1BFUl80MDBfWUVBUlM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gRGF0ZS5VVEMoeSwgbSwgZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdGFydE9mICh1bml0cykge1xuICAgICAgICB2YXIgdGltZTtcbiAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh1bml0cyk7XG4gICAgICAgIGlmICh1bml0cyA9PT0gdW5kZWZpbmVkIHx8IHVuaXRzID09PSAnbWlsbGlzZWNvbmQnIHx8ICF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc3RhcnRPZkRhdGUgPSB0aGlzLl9pc1VUQyA/IHV0Y1N0YXJ0T2ZEYXRlIDogbG9jYWxTdGFydE9mRGF0ZTtcblxuICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIDAsIDEpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCkgLSB0aGlzLm1vbnRoKCkgJSAzLCAxKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgMSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSB0aGlzLndlZWtkYXkoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdpc29XZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSAodGhpcy5pc29XZWVrZGF5KCkgLSAxKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdkYXknOlxuICAgICAgICAgICAgY2FzZSAnZGF0ZSc6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCksIHRoaXMuZGF0ZSgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOlxuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLl9kLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB0aW1lIC09IG1vZCQxKHRpbWUgKyAodGhpcy5faXNVVEMgPyAwIDogdGhpcy51dGNPZmZzZXQoKSAqIE1TX1BFUl9NSU5VVEUpLCBNU19QRVJfSE9VUik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLl9kLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB0aW1lIC09IG1vZCQxKHRpbWUsIE1TX1BFUl9NSU5VVEUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSAtPSBtb2QkMSh0aW1lLCBNU19QRVJfU0VDT05EKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2Quc2V0VGltZSh0aW1lKTtcbiAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMsIHRydWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBlbmRPZiAodW5pdHMpIHtcbiAgICAgICAgdmFyIHRpbWU7XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICBpZiAodW5pdHMgPT09IHVuZGVmaW5lZCB8fCB1bml0cyA9PT0gJ21pbGxpc2Vjb25kJyB8fCAhdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHN0YXJ0T2ZEYXRlID0gdGhpcy5faXNVVEMgPyB1dGNTdGFydE9mRGF0ZSA6IGxvY2FsU3RhcnRPZkRhdGU7XG5cbiAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpICsgMSwgMCwgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCkgLSB0aGlzLm1vbnRoKCkgJSAzICsgMywgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOlxuICAgICAgICAgICAgICAgIHRpbWUgPSBzdGFydE9mRGF0ZSh0aGlzLnllYXIoKSwgdGhpcy5tb250aCgpICsgMSwgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCksIHRoaXMuZGF0ZSgpIC0gdGhpcy53ZWVrZGF5KCkgKyA3KSAtIDE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdpc29XZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSAodGhpcy5pc29XZWVrZGF5KCkgLSAxKSArIDcpIC0gMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2RheSc6XG4gICAgICAgICAgICBjYXNlICdkYXRlJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgKyAxKSAtIDE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfSE9VUiAtIG1vZCQxKHRpbWUgKyAodGhpcy5faXNVVEMgPyAwIDogdGhpcy51dGNPZmZzZXQoKSAqIE1TX1BFUl9NSU5VVEUpLCBNU19QRVJfSE9VUikgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbWludXRlJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfTUlOVVRFIC0gbW9kJDEodGltZSwgTVNfUEVSX01JTlVURSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfU0VDT05EIC0gbW9kJDEodGltZSwgTVNfUEVSX1NFQ09ORCkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fZC5zZXRUaW1lKHRpbWUpO1xuICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbHVlT2YgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZC52YWx1ZU9mKCkgLSAoKHRoaXMuX29mZnNldCB8fCAwKSAqIDYwMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1bml4ICgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IodGhpcy52YWx1ZU9mKCkgLyAxMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0RhdGUgKCkge1xuICAgICAgICByZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvQXJyYXkgKCkge1xuICAgICAgICB2YXIgbSA9IHRoaXM7XG4gICAgICAgIHJldHVybiBbbS55ZWFyKCksIG0ubW9udGgoKSwgbS5kYXRlKCksIG0uaG91cigpLCBtLm1pbnV0ZSgpLCBtLnNlY29uZCgpLCBtLm1pbGxpc2Vjb25kKCldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvT2JqZWN0ICgpIHtcbiAgICAgICAgdmFyIG0gPSB0aGlzO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeWVhcnM6IG0ueWVhcigpLFxuICAgICAgICAgICAgbW9udGhzOiBtLm1vbnRoKCksXG4gICAgICAgICAgICBkYXRlOiBtLmRhdGUoKSxcbiAgICAgICAgICAgIGhvdXJzOiBtLmhvdXJzKCksXG4gICAgICAgICAgICBtaW51dGVzOiBtLm1pbnV0ZXMoKSxcbiAgICAgICAgICAgIHNlY29uZHM6IG0uc2Vjb25kcygpLFxuICAgICAgICAgICAgbWlsbGlzZWNvbmRzOiBtLm1pbGxpc2Vjb25kcygpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgICAgICAgLy8gbmV3IERhdGUoTmFOKS50b0pTT04oKSA9PT0gbnVsbFxuICAgICAgICByZXR1cm4gdGhpcy5pc1ZhbGlkKCkgPyB0aGlzLnRvSVNPU3RyaW5nKCkgOiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVmFsaWQkMiAoKSB7XG4gICAgICAgIHJldHVybiBpc1ZhbGlkKHRoaXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNpbmdGbGFncyAoKSB7XG4gICAgICAgIHJldHVybiBleHRlbmQoe30sIGdldFBhcnNpbmdGbGFncyh0aGlzKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW52YWxpZEF0ICgpIHtcbiAgICAgICAgcmV0dXJuIGdldFBhcnNpbmdGbGFncyh0aGlzKS5vdmVyZmxvdztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGlvbkRhdGEoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpbnB1dDogdGhpcy5faSxcbiAgICAgICAgICAgIGZvcm1hdDogdGhpcy5fZixcbiAgICAgICAgICAgIGxvY2FsZTogdGhpcy5fbG9jYWxlLFxuICAgICAgICAgICAgaXNVVEM6IHRoaXMuX2lzVVRDLFxuICAgICAgICAgICAgc3RyaWN0OiB0aGlzLl9zdHJpY3RcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ2dnJywgMl0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2Vla1llYXIoKSAlIDEwMDtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnR0cnLCAyXSwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc29XZWVrWWVhcigpICUgMTAwO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYWRkV2Vla1llYXJGb3JtYXRUb2tlbiAodG9rZW4sIGdldHRlcikge1xuICAgICAgICBhZGRGb3JtYXRUb2tlbigwLCBbdG9rZW4sIHRva2VuLmxlbmd0aF0sIDAsIGdldHRlcik7XG4gICAgfVxuXG4gICAgYWRkV2Vla1llYXJGb3JtYXRUb2tlbignZ2dnZycsICAgICAnd2Vla1llYXInKTtcbiAgICBhZGRXZWVrWWVhckZvcm1hdFRva2VuKCdnZ2dnZycsICAgICd3ZWVrWWVhcicpO1xuICAgIGFkZFdlZWtZZWFyRm9ybWF0VG9rZW4oJ0dHR0cnLCAgJ2lzb1dlZWtZZWFyJyk7XG4gICAgYWRkV2Vla1llYXJGb3JtYXRUb2tlbignR0dHR0cnLCAnaXNvV2Vla1llYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnd2Vla1llYXInLCAnZ2cnKTtcbiAgICBhZGRVbml0QWxpYXMoJ2lzb1dlZWtZZWFyJywgJ0dHJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCd3ZWVrWWVhcicsIDEpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2Vla1llYXInLCAxKTtcblxuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbignRycsICAgICAgbWF0Y2hTaWduZWQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2cnLCAgICAgIG1hdGNoU2lnbmVkKTtcbiAgICBhZGRSZWdleFRva2VuKCdHRycsICAgICBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignZ2cnLCAgICAgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0dHR0cnLCAgIG1hdGNoMXRvNCwgbWF0Y2g0KTtcbiAgICBhZGRSZWdleFRva2VuKCdnZ2dnJywgICBtYXRjaDF0bzQsIG1hdGNoNCk7XG4gICAgYWRkUmVnZXhUb2tlbignR0dHR0cnLCAgbWF0Y2gxdG82LCBtYXRjaDYpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2dnZ2dnJywgIG1hdGNoMXRvNiwgbWF0Y2g2KTtcblxuICAgIGFkZFdlZWtQYXJzZVRva2VuKFsnZ2dnZycsICdnZ2dnZycsICdHR0dHJywgJ0dHR0dHJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuLnN1YnN0cigwLCAyKV0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICBhZGRXZWVrUGFyc2VUb2tlbihbJ2dnJywgJ0dHJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuXSA9IGhvb2tzLnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICB9KTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFNldFdlZWtZZWFyIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gZ2V0U2V0V2Vla1llYXJIZWxwZXIuY2FsbCh0aGlzLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIHRoaXMud2VlaygpLFxuICAgICAgICAgICAgICAgIHRoaXMud2Vla2RheSgpLFxuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrLmRvdyxcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsZURhdGEoKS5fd2Vlay5kb3kpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNldElTT1dlZWtZZWFyIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gZ2V0U2V0V2Vla1llYXJIZWxwZXIuY2FsbCh0aGlzLFxuICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLmlzb1dlZWsoKSwgdGhpcy5pc29XZWVrZGF5KCksIDEsIDQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldElTT1dlZWtzSW5ZZWFyICgpIHtcbiAgICAgICAgcmV0dXJuIHdlZWtzSW5ZZWFyKHRoaXMueWVhcigpLCAxLCA0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRXZWVrc0luWWVhciAoKSB7XG4gICAgICAgIHZhciB3ZWVrSW5mbyA9IHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrO1xuICAgICAgICByZXR1cm4gd2Vla3NJblllYXIodGhpcy55ZWFyKCksIHdlZWtJbmZvLmRvdywgd2Vla0luZm8uZG95KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRXZWVrWWVhckhlbHBlcihpbnB1dCwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIHdlZWtzVGFyZ2V0O1xuICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHdlZWtPZlllYXIodGhpcywgZG93LCBkb3kpLnllYXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3ZWVrc1RhcmdldCA9IHdlZWtzSW5ZZWFyKGlucHV0LCBkb3csIGRveSk7XG4gICAgICAgICAgICBpZiAod2VlayA+IHdlZWtzVGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgd2VlayA9IHdlZWtzVGFyZ2V0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNldFdlZWtBbGwuY2FsbCh0aGlzLCBpbnB1dCwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0V2Vla0FsbCh3ZWVrWWVhciwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIGRheU9mWWVhckRhdGEgPSBkYXlPZlllYXJGcm9tV2Vla3Mod2Vla1llYXIsIHdlZWssIHdlZWtkYXksIGRvdywgZG95KSxcbiAgICAgICAgICAgIGRhdGUgPSBjcmVhdGVVVENEYXRlKGRheU9mWWVhckRhdGEueWVhciwgMCwgZGF5T2ZZZWFyRGF0YS5kYXlPZlllYXIpO1xuXG4gICAgICAgIHRoaXMueWVhcihkYXRlLmdldFVUQ0Z1bGxZZWFyKCkpO1xuICAgICAgICB0aGlzLm1vbnRoKGRhdGUuZ2V0VVRDTW9udGgoKSk7XG4gICAgICAgIHRoaXMuZGF0ZShkYXRlLmdldFVUQ0RhdGUoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdRJywgMCwgJ1FvJywgJ3F1YXJ0ZXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygncXVhcnRlcicsICdRJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdxdWFydGVyJywgNyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdRJywgbWF0Y2gxKTtcbiAgICBhZGRQYXJzZVRva2VuKCdRJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtNT05USF0gPSAodG9JbnQoaW5wdXQpIC0gMSkgKiAzO1xuICAgIH0pO1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgZnVuY3Rpb24gZ2V0U2V0UXVhcnRlciAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyBNYXRoLmNlaWwoKHRoaXMubW9udGgoKSArIDEpIC8gMykgOiB0aGlzLm1vbnRoKChpbnB1dCAtIDEpICogMyArIHRoaXMubW9udGgoKSAlIDMpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdEJywgWydERCcsIDJdLCAnRG8nLCAnZGF0ZScpO1xuXG4gICAgLy8gQUxJQVNFU1xuXG4gICAgYWRkVW5pdEFsaWFzKCdkYXRlJywgJ0QnKTtcblxuICAgIC8vIFBSSU9SSVRZXG4gICAgYWRkVW5pdFByaW9yaXR5KCdkYXRlJywgOSk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdEJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignREQnLCBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignRG8nLCBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICAvLyBUT0RPOiBSZW1vdmUgXCJvcmRpbmFsUGFyc2VcIiBmYWxsYmFjayBpbiBuZXh0IG1ham9yIHJlbGVhc2UuXG4gICAgICAgIHJldHVybiBpc1N0cmljdCA/XG4gICAgICAgICAgKGxvY2FsZS5fZGF5T2ZNb250aE9yZGluYWxQYXJzZSB8fCBsb2NhbGUuX29yZGluYWxQYXJzZSkgOlxuICAgICAgICAgIGxvY2FsZS5fZGF5T2ZNb250aE9yZGluYWxQYXJzZUxlbmllbnQ7XG4gICAgfSk7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnRCcsICdERCddLCBEQVRFKTtcbiAgICBhZGRQYXJzZVRva2VuKCdEbycsIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbREFURV0gPSB0b0ludChpbnB1dC5tYXRjaChtYXRjaDF0bzIpWzBdKTtcbiAgICB9KTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIHZhciBnZXRTZXREYXlPZk1vbnRoID0gbWFrZUdldFNldCgnRGF0ZScsIHRydWUpO1xuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ0RERCcsIFsnRERERCcsIDNdLCAnREREbycsICdkYXlPZlllYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnZGF5T2ZZZWFyJywgJ0RERCcpO1xuXG4gICAgLy8gUFJJT1JJVFlcbiAgICBhZGRVbml0UHJpb3JpdHkoJ2RheU9mWWVhcicsIDQpO1xuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbignREREJywgIG1hdGNoMXRvMyk7XG4gICAgYWRkUmVnZXhUb2tlbignRERERCcsIG1hdGNoMyk7XG4gICAgYWRkUGFyc2VUb2tlbihbJ0RERCcsICdEREREJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2RheU9mWWVhciA9IHRvSW50KGlucHV0KTtcbiAgICB9KTtcblxuICAgIC8vIEhFTFBFUlNcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFNldERheU9mWWVhciAoaW5wdXQpIHtcbiAgICAgICAgdmFyIGRheU9mWWVhciA9IE1hdGgucm91bmQoKHRoaXMuY2xvbmUoKS5zdGFydE9mKCdkYXknKSAtIHRoaXMuY2xvbmUoKS5zdGFydE9mKCd5ZWFyJykpIC8gODY0ZTUpICsgMTtcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyBkYXlPZlllYXIgOiB0aGlzLmFkZCgoaW5wdXQgLSBkYXlPZlllYXIpLCAnZCcpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdtJywgWydtbScsIDJdLCAwLCAnbWludXRlJyk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21pbnV0ZScsICdtJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdtaW51dGUnLCAxNCk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdtJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignbW0nLCBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUGFyc2VUb2tlbihbJ20nLCAnbW0nXSwgTUlOVVRFKTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIHZhciBnZXRTZXRNaW51dGUgPSBtYWtlR2V0U2V0KCdNaW51dGVzJywgZmFsc2UpO1xuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ3MnLCBbJ3NzJywgMl0sIDAsICdzZWNvbmQnKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnc2Vjb25kJywgJ3MnKTtcblxuICAgIC8vIFBSSU9SSVRZXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ3NlY29uZCcsIDE1KTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ3MnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdzcycsIG1hdGNoMXRvMiwgbWF0Y2gyKTtcbiAgICBhZGRQYXJzZVRva2VuKFsncycsICdzcyddLCBTRUNPTkQpO1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgdmFyIGdldFNldFNlY29uZCA9IG1ha2VHZXRTZXQoJ1NlY29uZHMnLCBmYWxzZSk7XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbignUycsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIH5+KHRoaXMubWlsbGlzZWNvbmQoKSAvIDEwMCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTJywgMl0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIH5+KHRoaXMubWlsbGlzZWNvbmQoKSAvIDEwKTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTJywgM10sIDAsICdtaWxsaXNlY29uZCcpO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTUycsIDRdLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTJywgNV0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWlsbGlzZWNvbmQoKSAqIDEwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTUycsIDZdLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwO1xuICAgIH0pO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTU1NTUycsIDddLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTU1NTJywgOF0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWlsbGlzZWNvbmQoKSAqIDEwMDAwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTU1NTUycsIDldLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwMDAwO1xuICAgIH0pO1xuXG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21pbGxpc2Vjb25kJywgJ21zJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdtaWxsaXNlY29uZCcsIDE2KTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1MnLCAgICBtYXRjaDF0bzMsIG1hdGNoMSk7XG4gICAgYWRkUmVnZXhUb2tlbignU1MnLCAgIG1hdGNoMXRvMywgbWF0Y2gyKTtcbiAgICBhZGRSZWdleFRva2VuKCdTU1MnLCAgbWF0Y2gxdG8zLCBtYXRjaDMpO1xuXG4gICAgdmFyIHRva2VuO1xuICAgIGZvciAodG9rZW4gPSAnU1NTUyc7IHRva2VuLmxlbmd0aCA8PSA5OyB0b2tlbiArPSAnUycpIHtcbiAgICAgICAgYWRkUmVnZXhUb2tlbih0b2tlbiwgbWF0Y2hVbnNpZ25lZCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VNcyhpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbTUlMTElTRUNPTkRdID0gdG9JbnQoKCcwLicgKyBpbnB1dCkgKiAxMDAwKTtcbiAgICB9XG5cbiAgICBmb3IgKHRva2VuID0gJ1MnOyB0b2tlbi5sZW5ndGggPD0gOTsgdG9rZW4gKz0gJ1MnKSB7XG4gICAgICAgIGFkZFBhcnNlVG9rZW4odG9rZW4sIHBhcnNlTXMpO1xuICAgIH1cbiAgICAvLyBNT01FTlRTXG5cbiAgICB2YXIgZ2V0U2V0TWlsbGlzZWNvbmQgPSBtYWtlR2V0U2V0KCdNaWxsaXNlY29uZHMnLCBmYWxzZSk7XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigneicsICAwLCAwLCAnem9uZUFiYnInKTtcbiAgICBhZGRGb3JtYXRUb2tlbignenonLCAwLCAwLCAnem9uZU5hbWUnKTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFpvbmVBYmJyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzVVRDID8gJ1VUQycgOiAnJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRab25lTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/ICdDb29yZGluYXRlZCBVbml2ZXJzYWwgVGltZScgOiAnJztcbiAgICB9XG5cbiAgICB2YXIgcHJvdG8gPSBNb21lbnQucHJvdG90eXBlO1xuXG4gICAgcHJvdG8uYWRkICAgICAgICAgICAgICAgPSBhZGQ7XG4gICAgcHJvdG8uY2FsZW5kYXIgICAgICAgICAgPSBjYWxlbmRhciQxO1xuICAgIHByb3RvLmNsb25lICAgICAgICAgICAgID0gY2xvbmU7XG4gICAgcHJvdG8uZGlmZiAgICAgICAgICAgICAgPSBkaWZmO1xuICAgIHByb3RvLmVuZE9mICAgICAgICAgICAgID0gZW5kT2Y7XG4gICAgcHJvdG8uZm9ybWF0ICAgICAgICAgICAgPSBmb3JtYXQ7XG4gICAgcHJvdG8uZnJvbSAgICAgICAgICAgICAgPSBmcm9tO1xuICAgIHByb3RvLmZyb21Ob3cgICAgICAgICAgID0gZnJvbU5vdztcbiAgICBwcm90by50byAgICAgICAgICAgICAgICA9IHRvO1xuICAgIHByb3RvLnRvTm93ICAgICAgICAgICAgID0gdG9Ob3c7XG4gICAgcHJvdG8uZ2V0ICAgICAgICAgICAgICAgPSBzdHJpbmdHZXQ7XG4gICAgcHJvdG8uaW52YWxpZEF0ICAgICAgICAgPSBpbnZhbGlkQXQ7XG4gICAgcHJvdG8uaXNBZnRlciAgICAgICAgICAgPSBpc0FmdGVyO1xuICAgIHByb3RvLmlzQmVmb3JlICAgICAgICAgID0gaXNCZWZvcmU7XG4gICAgcHJvdG8uaXNCZXR3ZWVuICAgICAgICAgPSBpc0JldHdlZW47XG4gICAgcHJvdG8uaXNTYW1lICAgICAgICAgICAgPSBpc1NhbWU7XG4gICAgcHJvdG8uaXNTYW1lT3JBZnRlciAgICAgPSBpc1NhbWVPckFmdGVyO1xuICAgIHByb3RvLmlzU2FtZU9yQmVmb3JlICAgID0gaXNTYW1lT3JCZWZvcmU7XG4gICAgcHJvdG8uaXNWYWxpZCAgICAgICAgICAgPSBpc1ZhbGlkJDI7XG4gICAgcHJvdG8ubGFuZyAgICAgICAgICAgICAgPSBsYW5nO1xuICAgIHByb3RvLmxvY2FsZSAgICAgICAgICAgID0gbG9jYWxlO1xuICAgIHByb3RvLmxvY2FsZURhdGEgICAgICAgID0gbG9jYWxlRGF0YTtcbiAgICBwcm90by5tYXggICAgICAgICAgICAgICA9IHByb3RvdHlwZU1heDtcbiAgICBwcm90by5taW4gICAgICAgICAgICAgICA9IHByb3RvdHlwZU1pbjtcbiAgICBwcm90by5wYXJzaW5nRmxhZ3MgICAgICA9IHBhcnNpbmdGbGFncztcbiAgICBwcm90by5zZXQgICAgICAgICAgICAgICA9IHN0cmluZ1NldDtcbiAgICBwcm90by5zdGFydE9mICAgICAgICAgICA9IHN0YXJ0T2Y7XG4gICAgcHJvdG8uc3VidHJhY3QgICAgICAgICAgPSBzdWJ0cmFjdDtcbiAgICBwcm90by50b0FycmF5ICAgICAgICAgICA9IHRvQXJyYXk7XG4gICAgcHJvdG8udG9PYmplY3QgICAgICAgICAgPSB0b09iamVjdDtcbiAgICBwcm90by50b0RhdGUgICAgICAgICAgICA9IHRvRGF0ZTtcbiAgICBwcm90by50b0lTT1N0cmluZyAgICAgICA9IHRvSVNPU3RyaW5nO1xuICAgIHByb3RvLmluc3BlY3QgICAgICAgICAgID0gaW5zcGVjdDtcbiAgICBwcm90by50b0pTT04gICAgICAgICAgICA9IHRvSlNPTjtcbiAgICBwcm90by50b1N0cmluZyAgICAgICAgICA9IHRvU3RyaW5nO1xuICAgIHByb3RvLnVuaXggICAgICAgICAgICAgID0gdW5peDtcbiAgICBwcm90by52YWx1ZU9mICAgICAgICAgICA9IHZhbHVlT2Y7XG4gICAgcHJvdG8uY3JlYXRpb25EYXRhICAgICAgPSBjcmVhdGlvbkRhdGE7XG4gICAgcHJvdG8ueWVhciAgICAgICA9IGdldFNldFllYXI7XG4gICAgcHJvdG8uaXNMZWFwWWVhciA9IGdldElzTGVhcFllYXI7XG4gICAgcHJvdG8ud2Vla1llYXIgICAgPSBnZXRTZXRXZWVrWWVhcjtcbiAgICBwcm90by5pc29XZWVrWWVhciA9IGdldFNldElTT1dlZWtZZWFyO1xuICAgIHByb3RvLnF1YXJ0ZXIgPSBwcm90by5xdWFydGVycyA9IGdldFNldFF1YXJ0ZXI7XG4gICAgcHJvdG8ubW9udGggICAgICAgPSBnZXRTZXRNb250aDtcbiAgICBwcm90by5kYXlzSW5Nb250aCA9IGdldERheXNJbk1vbnRoO1xuICAgIHByb3RvLndlZWsgICAgICAgICAgID0gcHJvdG8ud2Vla3MgICAgICAgID0gZ2V0U2V0V2VlaztcbiAgICBwcm90by5pc29XZWVrICAgICAgICA9IHByb3RvLmlzb1dlZWtzICAgICA9IGdldFNldElTT1dlZWs7XG4gICAgcHJvdG8ud2Vla3NJblllYXIgICAgPSBnZXRXZWVrc0luWWVhcjtcbiAgICBwcm90by5pc29XZWVrc0luWWVhciA9IGdldElTT1dlZWtzSW5ZZWFyO1xuICAgIHByb3RvLmRhdGUgICAgICAgPSBnZXRTZXREYXlPZk1vbnRoO1xuICAgIHByb3RvLmRheSAgICAgICAgPSBwcm90by5kYXlzICAgICAgICAgICAgID0gZ2V0U2V0RGF5T2ZXZWVrO1xuICAgIHByb3RvLndlZWtkYXkgICAgPSBnZXRTZXRMb2NhbGVEYXlPZldlZWs7XG4gICAgcHJvdG8uaXNvV2Vla2RheSA9IGdldFNldElTT0RheU9mV2VlaztcbiAgICBwcm90by5kYXlPZlllYXIgID0gZ2V0U2V0RGF5T2ZZZWFyO1xuICAgIHByb3RvLmhvdXIgPSBwcm90by5ob3VycyA9IGdldFNldEhvdXI7XG4gICAgcHJvdG8ubWludXRlID0gcHJvdG8ubWludXRlcyA9IGdldFNldE1pbnV0ZTtcbiAgICBwcm90by5zZWNvbmQgPSBwcm90by5zZWNvbmRzID0gZ2V0U2V0U2Vjb25kO1xuICAgIHByb3RvLm1pbGxpc2Vjb25kID0gcHJvdG8ubWlsbGlzZWNvbmRzID0gZ2V0U2V0TWlsbGlzZWNvbmQ7XG4gICAgcHJvdG8udXRjT2Zmc2V0ICAgICAgICAgICAgPSBnZXRTZXRPZmZzZXQ7XG4gICAgcHJvdG8udXRjICAgICAgICAgICAgICAgICAgPSBzZXRPZmZzZXRUb1VUQztcbiAgICBwcm90by5sb2NhbCAgICAgICAgICAgICAgICA9IHNldE9mZnNldFRvTG9jYWw7XG4gICAgcHJvdG8ucGFyc2Vab25lICAgICAgICAgICAgPSBzZXRPZmZzZXRUb1BhcnNlZE9mZnNldDtcbiAgICBwcm90by5oYXNBbGlnbmVkSG91ck9mZnNldCA9IGhhc0FsaWduZWRIb3VyT2Zmc2V0O1xuICAgIHByb3RvLmlzRFNUICAgICAgICAgICAgICAgID0gaXNEYXlsaWdodFNhdmluZ1RpbWU7XG4gICAgcHJvdG8uaXNMb2NhbCAgICAgICAgICAgICAgPSBpc0xvY2FsO1xuICAgIHByb3RvLmlzVXRjT2Zmc2V0ICAgICAgICAgID0gaXNVdGNPZmZzZXQ7XG4gICAgcHJvdG8uaXNVdGMgICAgICAgICAgICAgICAgPSBpc1V0YztcbiAgICBwcm90by5pc1VUQyAgICAgICAgICAgICAgICA9IGlzVXRjO1xuICAgIHByb3RvLnpvbmVBYmJyID0gZ2V0Wm9uZUFiYnI7XG4gICAgcHJvdG8uem9uZU5hbWUgPSBnZXRab25lTmFtZTtcbiAgICBwcm90by5kYXRlcyAgPSBkZXByZWNhdGUoJ2RhdGVzIGFjY2Vzc29yIGlzIGRlcHJlY2F0ZWQuIFVzZSBkYXRlIGluc3RlYWQuJywgZ2V0U2V0RGF5T2ZNb250aCk7XG4gICAgcHJvdG8ubW9udGhzID0gZGVwcmVjYXRlKCdtb250aHMgYWNjZXNzb3IgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbnRoIGluc3RlYWQnLCBnZXRTZXRNb250aCk7XG4gICAgcHJvdG8ueWVhcnMgID0gZGVwcmVjYXRlKCd5ZWFycyBhY2Nlc3NvciBpcyBkZXByZWNhdGVkLiBVc2UgeWVhciBpbnN0ZWFkJywgZ2V0U2V0WWVhcik7XG4gICAgcHJvdG8uem9uZSAgID0gZGVwcmVjYXRlKCdtb21lbnQoKS56b25lIGlzIGRlcHJlY2F0ZWQsIHVzZSBtb21lbnQoKS51dGNPZmZzZXQgaW5zdGVhZC4gaHR0cDovL21vbWVudGpzLmNvbS9ndWlkZXMvIy93YXJuaW5ncy96b25lLycsIGdldFNldFpvbmUpO1xuICAgIHByb3RvLmlzRFNUU2hpZnRlZCA9IGRlcHJlY2F0ZSgnaXNEU1RTaGlmdGVkIGlzIGRlcHJlY2F0ZWQuIFNlZSBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2RzdC1zaGlmdGVkLyBmb3IgbW9yZSBpbmZvcm1hdGlvbicsIGlzRGF5bGlnaHRTYXZpbmdUaW1lU2hpZnRlZCk7XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVVbml4IChpbnB1dCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwoaW5wdXQgKiAxMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVJblpvbmUgKCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwuYXBwbHkobnVsbCwgYXJndW1lbnRzKS5wYXJzZVpvbmUoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVQYXJzZVBvc3RGb3JtYXQgKHN0cmluZykge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgIH1cblxuICAgIHZhciBwcm90byQxID0gTG9jYWxlLnByb3RvdHlwZTtcblxuICAgIHByb3RvJDEuY2FsZW5kYXIgICAgICAgID0gY2FsZW5kYXI7XG4gICAgcHJvdG8kMS5sb25nRGF0ZUZvcm1hdCAgPSBsb25nRGF0ZUZvcm1hdDtcbiAgICBwcm90byQxLmludmFsaWREYXRlICAgICA9IGludmFsaWREYXRlO1xuICAgIHByb3RvJDEub3JkaW5hbCAgICAgICAgID0gb3JkaW5hbDtcbiAgICBwcm90byQxLnByZXBhcnNlICAgICAgICA9IHByZVBhcnNlUG9zdEZvcm1hdDtcbiAgICBwcm90byQxLnBvc3Rmb3JtYXQgICAgICA9IHByZVBhcnNlUG9zdEZvcm1hdDtcbiAgICBwcm90byQxLnJlbGF0aXZlVGltZSAgICA9IHJlbGF0aXZlVGltZTtcbiAgICBwcm90byQxLnBhc3RGdXR1cmUgICAgICA9IHBhc3RGdXR1cmU7XG4gICAgcHJvdG8kMS5zZXQgICAgICAgICAgICAgPSBzZXQ7XG5cbiAgICBwcm90byQxLm1vbnRocyAgICAgICAgICAgID0gICAgICAgIGxvY2FsZU1vbnRocztcbiAgICBwcm90byQxLm1vbnRoc1Nob3J0ICAgICAgID0gICAgICAgIGxvY2FsZU1vbnRoc1Nob3J0O1xuICAgIHByb3RvJDEubW9udGhzUGFyc2UgICAgICAgPSAgICAgICAgbG9jYWxlTW9udGhzUGFyc2U7XG4gICAgcHJvdG8kMS5tb250aHNSZWdleCAgICAgICA9IG1vbnRoc1JlZ2V4O1xuICAgIHByb3RvJDEubW9udGhzU2hvcnRSZWdleCAgPSBtb250aHNTaG9ydFJlZ2V4O1xuICAgIHByb3RvJDEud2VlayA9IGxvY2FsZVdlZWs7XG4gICAgcHJvdG8kMS5maXJzdERheU9mWWVhciA9IGxvY2FsZUZpcnN0RGF5T2ZZZWFyO1xuICAgIHByb3RvJDEuZmlyc3REYXlPZldlZWsgPSBsb2NhbGVGaXJzdERheU9mV2VlaztcblxuICAgIHByb3RvJDEud2Vla2RheXMgICAgICAgPSAgICAgICAgbG9jYWxlV2Vla2RheXM7XG4gICAgcHJvdG8kMS53ZWVrZGF5c01pbiAgICA9ICAgICAgICBsb2NhbGVXZWVrZGF5c01pbjtcbiAgICBwcm90byQxLndlZWtkYXlzU2hvcnQgID0gICAgICAgIGxvY2FsZVdlZWtkYXlzU2hvcnQ7XG4gICAgcHJvdG8kMS53ZWVrZGF5c1BhcnNlICA9ICAgICAgICBsb2NhbGVXZWVrZGF5c1BhcnNlO1xuXG4gICAgcHJvdG8kMS53ZWVrZGF5c1JlZ2V4ICAgICAgID0gICAgICAgIHdlZWtkYXlzUmVnZXg7XG4gICAgcHJvdG8kMS53ZWVrZGF5c1Nob3J0UmVnZXggID0gICAgICAgIHdlZWtkYXlzU2hvcnRSZWdleDtcbiAgICBwcm90byQxLndlZWtkYXlzTWluUmVnZXggICAgPSAgICAgICAgd2Vla2RheXNNaW5SZWdleDtcblxuICAgIHByb3RvJDEuaXNQTSA9IGxvY2FsZUlzUE07XG4gICAgcHJvdG8kMS5tZXJpZGllbSA9IGxvY2FsZU1lcmlkaWVtO1xuXG4gICAgZnVuY3Rpb24gZ2V0JDEgKGZvcm1hdCwgaW5kZXgsIGZpZWxkLCBzZXR0ZXIpIHtcbiAgICAgICAgdmFyIGxvY2FsZSA9IGdldExvY2FsZSgpO1xuICAgICAgICB2YXIgdXRjID0gY3JlYXRlVVRDKCkuc2V0KHNldHRlciwgaW5kZXgpO1xuICAgICAgICByZXR1cm4gbG9jYWxlW2ZpZWxkXSh1dGMsIGZvcm1hdCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdE1vbnRoc0ltcGwgKGZvcm1hdCwgaW5kZXgsIGZpZWxkKSB7XG4gICAgICAgIGlmIChpc051bWJlcihmb3JtYXQpKSB7XG4gICAgICAgICAgICBpbmRleCA9IGZvcm1hdDtcbiAgICAgICAgICAgIGZvcm1hdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvcm1hdCA9IGZvcm1hdCB8fCAnJztcblxuICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldCQxKGZvcm1hdCwgaW5kZXgsIGZpZWxkLCAnbW9udGgnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgb3V0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG4gICAgICAgICAgICBvdXRbaV0gPSBnZXQkMShmb3JtYXQsIGksIGZpZWxkLCAnbW9udGgnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH1cblxuICAgIC8vICgpXG4gICAgLy8gKDUpXG4gICAgLy8gKGZtdCwgNSlcbiAgICAvLyAoZm10KVxuICAgIC8vICh0cnVlKVxuICAgIC8vICh0cnVlLCA1KVxuICAgIC8vICh0cnVlLCBmbXQsIDUpXG4gICAgLy8gKHRydWUsIGZtdClcbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNJbXBsIChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgsIGZpZWxkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbG9jYWxlU29ydGVkID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIGlmIChpc051bWJlcihmb3JtYXQpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBmb3JtYXQ7XG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3JtYXQgPSBmb3JtYXQgfHwgJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3JtYXQgPSBsb2NhbGVTb3J0ZWQ7XG4gICAgICAgICAgICBpbmRleCA9IGZvcm1hdDtcbiAgICAgICAgICAgIGxvY2FsZVNvcnRlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoaXNOdW1iZXIoZm9ybWF0KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gZm9ybWF0O1xuICAgICAgICAgICAgICAgIGZvcm1hdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9ybWF0ID0gZm9ybWF0IHx8ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGxvY2FsZSA9IGdldExvY2FsZSgpLFxuICAgICAgICAgICAgc2hpZnQgPSBsb2NhbGVTb3J0ZWQgPyBsb2NhbGUuX3dlZWsuZG93IDogMDtcblxuICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldCQxKGZvcm1hdCwgKGluZGV4ICsgc2hpZnQpICUgNywgZmllbGQsICdkYXknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgb3V0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIG91dFtpXSA9IGdldCQxKGZvcm1hdCwgKGkgKyBzaGlmdCkgJSA3LCBmaWVsZCwgJ2RheScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdE1vbnRocyAoZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdE1vbnRoc0ltcGwoZm9ybWF0LCBpbmRleCwgJ21vbnRocycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpc3RNb250aHNTaG9ydCAoZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdE1vbnRoc0ltcGwoZm9ybWF0LCBpbmRleCwgJ21vbnRoc1Nob3J0Jyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdFdlZWtkYXlzIChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGxpc3RXZWVrZGF5c0ltcGwobG9jYWxlU29ydGVkLCBmb3JtYXQsIGluZGV4LCAnd2Vla2RheXMnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNTaG9ydCAobG9jYWxlU29ydGVkLCBmb3JtYXQsIGluZGV4KSB7XG4gICAgICAgIHJldHVybiBsaXN0V2Vla2RheXNJbXBsKGxvY2FsZVNvcnRlZCwgZm9ybWF0LCBpbmRleCwgJ3dlZWtkYXlzU2hvcnQnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNNaW4gKGxvY2FsZVNvcnRlZCwgZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdFdlZWtkYXlzSW1wbChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgsICd3ZWVrZGF5c01pbicpO1xuICAgIH1cblxuICAgIGdldFNldEdsb2JhbExvY2FsZSgnZW4nLCB7XG4gICAgICAgIGRheU9mTW9udGhPcmRpbmFsUGFyc2U6IC9cXGR7MSwyfSh0aHxzdHxuZHxyZCkvLFxuICAgICAgICBvcmRpbmFsIDogZnVuY3Rpb24gKG51bWJlcikge1xuICAgICAgICAgICAgdmFyIGIgPSBudW1iZXIgJSAxMCxcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSAodG9JbnQobnVtYmVyICUgMTAwIC8gMTApID09PSAxKSA/ICd0aCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAxKSA/ICdzdCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAyKSA/ICduZCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAzKSA/ICdyZCcgOiAndGgnO1xuICAgICAgICAgICAgcmV0dXJuIG51bWJlciArIG91dHB1dDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gU2lkZSBlZmZlY3QgaW1wb3J0c1xuXG4gICAgaG9va3MubGFuZyA9IGRlcHJlY2F0ZSgnbW9tZW50LmxhbmcgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGUgaW5zdGVhZC4nLCBnZXRTZXRHbG9iYWxMb2NhbGUpO1xuICAgIGhvb2tzLmxhbmdEYXRhID0gZGVwcmVjYXRlKCdtb21lbnQubGFuZ0RhdGEgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGVEYXRhIGluc3RlYWQuJywgZ2V0TG9jYWxlKTtcblxuICAgIHZhciBtYXRoQWJzID0gTWF0aC5hYnM7XG5cbiAgICBmdW5jdGlvbiBhYnMgKCkge1xuICAgICAgICB2YXIgZGF0YSAgICAgICAgICAgPSB0aGlzLl9kYXRhO1xuXG4gICAgICAgIHRoaXMuX21pbGxpc2Vjb25kcyA9IG1hdGhBYnModGhpcy5fbWlsbGlzZWNvbmRzKTtcbiAgICAgICAgdGhpcy5fZGF5cyAgICAgICAgID0gbWF0aEFicyh0aGlzLl9kYXlzKTtcbiAgICAgICAgdGhpcy5fbW9udGhzICAgICAgID0gbWF0aEFicyh0aGlzLl9tb250aHMpO1xuXG4gICAgICAgIGRhdGEubWlsbGlzZWNvbmRzICA9IG1hdGhBYnMoZGF0YS5taWxsaXNlY29uZHMpO1xuICAgICAgICBkYXRhLnNlY29uZHMgICAgICAgPSBtYXRoQWJzKGRhdGEuc2Vjb25kcyk7XG4gICAgICAgIGRhdGEubWludXRlcyAgICAgICA9IG1hdGhBYnMoZGF0YS5taW51dGVzKTtcbiAgICAgICAgZGF0YS5ob3VycyAgICAgICAgID0gbWF0aEFicyhkYXRhLmhvdXJzKTtcbiAgICAgICAgZGF0YS5tb250aHMgICAgICAgID0gbWF0aEFicyhkYXRhLm1vbnRocyk7XG4gICAgICAgIGRhdGEueWVhcnMgICAgICAgICA9IG1hdGhBYnMoZGF0YS55ZWFycyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWRkU3VidHJhY3QkMSAoZHVyYXRpb24sIGlucHV0LCB2YWx1ZSwgZGlyZWN0aW9uKSB7XG4gICAgICAgIHZhciBvdGhlciA9IGNyZWF0ZUR1cmF0aW9uKGlucHV0LCB2YWx1ZSk7XG5cbiAgICAgICAgZHVyYXRpb24uX21pbGxpc2Vjb25kcyArPSBkaXJlY3Rpb24gKiBvdGhlci5fbWlsbGlzZWNvbmRzO1xuICAgICAgICBkdXJhdGlvbi5fZGF5cyAgICAgICAgICs9IGRpcmVjdGlvbiAqIG90aGVyLl9kYXlzO1xuICAgICAgICBkdXJhdGlvbi5fbW9udGhzICAgICAgICs9IGRpcmVjdGlvbiAqIG90aGVyLl9tb250aHM7XG5cbiAgICAgICAgcmV0dXJuIGR1cmF0aW9uLl9idWJibGUoKTtcbiAgICB9XG5cbiAgICAvLyBzdXBwb3J0cyBvbmx5IDIuMC1zdHlsZSBhZGQoMSwgJ3MnKSBvciBhZGQoZHVyYXRpb24pXG4gICAgZnVuY3Rpb24gYWRkJDEgKGlucHV0LCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gYWRkU3VidHJhY3QkMSh0aGlzLCBpbnB1dCwgdmFsdWUsIDEpO1xuICAgIH1cblxuICAgIC8vIHN1cHBvcnRzIG9ubHkgMi4wLXN0eWxlIHN1YnRyYWN0KDEsICdzJykgb3Igc3VidHJhY3QoZHVyYXRpb24pXG4gICAgZnVuY3Rpb24gc3VidHJhY3QkMSAoaW5wdXQsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBhZGRTdWJ0cmFjdCQxKHRoaXMsIGlucHV0LCB2YWx1ZSwgLTEpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFic0NlaWwgKG51bWJlcikge1xuICAgICAgICBpZiAobnVtYmVyIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IobnVtYmVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmNlaWwobnVtYmVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJ1YmJsZSAoKSB7XG4gICAgICAgIHZhciBtaWxsaXNlY29uZHMgPSB0aGlzLl9taWxsaXNlY29uZHM7XG4gICAgICAgIHZhciBkYXlzICAgICAgICAgPSB0aGlzLl9kYXlzO1xuICAgICAgICB2YXIgbW9udGhzICAgICAgID0gdGhpcy5fbW9udGhzO1xuICAgICAgICB2YXIgZGF0YSAgICAgICAgID0gdGhpcy5fZGF0YTtcbiAgICAgICAgdmFyIHNlY29uZHMsIG1pbnV0ZXMsIGhvdXJzLCB5ZWFycywgbW9udGhzRnJvbURheXM7XG5cbiAgICAgICAgLy8gaWYgd2UgaGF2ZSBhIG1peCBvZiBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgdmFsdWVzLCBidWJibGUgZG93biBmaXJzdFxuICAgICAgICAvLyBjaGVjazogaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzIxNjZcbiAgICAgICAgaWYgKCEoKG1pbGxpc2Vjb25kcyA+PSAwICYmIGRheXMgPj0gMCAmJiBtb250aHMgPj0gMCkgfHxcbiAgICAgICAgICAgICAgICAobWlsbGlzZWNvbmRzIDw9IDAgJiYgZGF5cyA8PSAwICYmIG1vbnRocyA8PSAwKSkpIHtcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kcyArPSBhYnNDZWlsKG1vbnRoc1RvRGF5cyhtb250aHMpICsgZGF5cykgKiA4NjRlNTtcbiAgICAgICAgICAgIGRheXMgPSAwO1xuICAgICAgICAgICAgbW9udGhzID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgY29kZSBidWJibGVzIHVwIHZhbHVlcywgc2VlIHRoZSB0ZXN0cyBmb3JcbiAgICAgICAgLy8gZXhhbXBsZXMgb2Ygd2hhdCB0aGF0IG1lYW5zLlxuICAgICAgICBkYXRhLm1pbGxpc2Vjb25kcyA9IG1pbGxpc2Vjb25kcyAlIDEwMDA7XG5cbiAgICAgICAgc2Vjb25kcyAgICAgICAgICAgPSBhYnNGbG9vcihtaWxsaXNlY29uZHMgLyAxMDAwKTtcbiAgICAgICAgZGF0YS5zZWNvbmRzICAgICAgPSBzZWNvbmRzICUgNjA7XG5cbiAgICAgICAgbWludXRlcyAgICAgICAgICAgPSBhYnNGbG9vcihzZWNvbmRzIC8gNjApO1xuICAgICAgICBkYXRhLm1pbnV0ZXMgICAgICA9IG1pbnV0ZXMgJSA2MDtcblxuICAgICAgICBob3VycyAgICAgICAgICAgICA9IGFic0Zsb29yKG1pbnV0ZXMgLyA2MCk7XG4gICAgICAgIGRhdGEuaG91cnMgICAgICAgID0gaG91cnMgJSAyNDtcblxuICAgICAgICBkYXlzICs9IGFic0Zsb29yKGhvdXJzIC8gMjQpO1xuXG4gICAgICAgIC8vIGNvbnZlcnQgZGF5cyB0byBtb250aHNcbiAgICAgICAgbW9udGhzRnJvbURheXMgPSBhYnNGbG9vcihkYXlzVG9Nb250aHMoZGF5cykpO1xuICAgICAgICBtb250aHMgKz0gbW9udGhzRnJvbURheXM7XG4gICAgICAgIGRheXMgLT0gYWJzQ2VpbChtb250aHNUb0RheXMobW9udGhzRnJvbURheXMpKTtcblxuICAgICAgICAvLyAxMiBtb250aHMgLT4gMSB5ZWFyXG4gICAgICAgIHllYXJzID0gYWJzRmxvb3IobW9udGhzIC8gMTIpO1xuICAgICAgICBtb250aHMgJT0gMTI7XG5cbiAgICAgICAgZGF0YS5kYXlzICAgPSBkYXlzO1xuICAgICAgICBkYXRhLm1vbnRocyA9IG1vbnRocztcbiAgICAgICAgZGF0YS55ZWFycyAgPSB5ZWFycztcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlzVG9Nb250aHMgKGRheXMpIHtcbiAgICAgICAgLy8gNDAwIHllYXJzIGhhdmUgMTQ2MDk3IGRheXMgKHRha2luZyBpbnRvIGFjY291bnQgbGVhcCB5ZWFyIHJ1bGVzKVxuICAgICAgICAvLyA0MDAgeWVhcnMgaGF2ZSAxMiBtb250aHMgPT09IDQ4MDBcbiAgICAgICAgcmV0dXJuIGRheXMgKiA0ODAwIC8gMTQ2MDk3O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1vbnRoc1RvRGF5cyAobW9udGhzKSB7XG4gICAgICAgIC8vIHRoZSByZXZlcnNlIG9mIGRheXNUb01vbnRoc1xuICAgICAgICByZXR1cm4gbW9udGhzICogMTQ2MDk3IC8gNDgwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhcyAodW5pdHMpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIE5hTjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF5cztcbiAgICAgICAgdmFyIG1vbnRocztcbiAgICAgICAgdmFyIG1pbGxpc2Vjb25kcyA9IHRoaXMuX21pbGxpc2Vjb25kcztcblxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICBpZiAodW5pdHMgPT09ICdtb250aCcgfHwgdW5pdHMgPT09ICdxdWFydGVyJyB8fCB1bml0cyA9PT0gJ3llYXInKSB7XG4gICAgICAgICAgICBkYXlzID0gdGhpcy5fZGF5cyArIG1pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgbW9udGhzID0gdGhpcy5fbW9udGhzICsgZGF5c1RvTW9udGhzKGRheXMpO1xuICAgICAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgICAgIGNhc2UgJ21vbnRoJzogICByZXR1cm4gbW9udGhzO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3F1YXJ0ZXInOiByZXR1cm4gbW9udGhzIC8gMztcbiAgICAgICAgICAgICAgICBjYXNlICd5ZWFyJzogICAgcmV0dXJuIG1vbnRocyAvIDEyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaGFuZGxlIG1pbGxpc2Vjb25kcyBzZXBhcmF0ZWx5IGJlY2F1c2Ugb2YgZmxvYXRpbmcgcG9pbnQgbWF0aCBlcnJvcnMgKGlzc3VlICMxODY3KVxuICAgICAgICAgICAgZGF5cyA9IHRoaXMuX2RheXMgKyBNYXRoLnJvdW5kKG1vbnRoc1RvRGF5cyh0aGlzLl9tb250aHMpKTtcbiAgICAgICAgICAgIHN3aXRjaCAodW5pdHMpIHtcbiAgICAgICAgICAgICAgICBjYXNlICd3ZWVrJyAgIDogcmV0dXJuIGRheXMgLyA3ICAgICArIG1pbGxpc2Vjb25kcyAvIDYwNDhlNTtcbiAgICAgICAgICAgICAgICBjYXNlICdkYXknICAgIDogcmV0dXJuIGRheXMgICAgICAgICArIG1pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgICAgIGNhc2UgJ2hvdXInICAgOiByZXR1cm4gZGF5cyAqIDI0ICAgICsgbWlsbGlzZWNvbmRzIC8gMzZlNTtcbiAgICAgICAgICAgICAgICBjYXNlICdtaW51dGUnIDogcmV0dXJuIGRheXMgKiAxNDQwICArIG1pbGxpc2Vjb25kcyAvIDZlNDtcbiAgICAgICAgICAgICAgICBjYXNlICdzZWNvbmQnIDogcmV0dXJuIGRheXMgKiA4NjQwMCArIG1pbGxpc2Vjb25kcyAvIDEwMDA7XG4gICAgICAgICAgICAgICAgLy8gTWF0aC5mbG9vciBwcmV2ZW50cyBmbG9hdGluZyBwb2ludCBtYXRoIGVycm9ycyBoZXJlXG4gICAgICAgICAgICAgICAgY2FzZSAnbWlsbGlzZWNvbmQnOiByZXR1cm4gTWF0aC5mbG9vcihkYXlzICogODY0ZTUpICsgbWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcignVW5rbm93biB1bml0ICcgKyB1bml0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPOiBVc2UgdGhpcy5hcygnbXMnKT9cbiAgICBmdW5jdGlvbiB2YWx1ZU9mJDEgKCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgK1xuICAgICAgICAgICAgdGhpcy5fZGF5cyAqIDg2NGU1ICtcbiAgICAgICAgICAgICh0aGlzLl9tb250aHMgJSAxMikgKiAyNTkyZTYgK1xuICAgICAgICAgICAgdG9JbnQodGhpcy5fbW9udGhzIC8gMTIpICogMzE1MzZlNlxuICAgICAgICApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VBcyAoYWxpYXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFzKGFsaWFzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgYXNNaWxsaXNlY29uZHMgPSBtYWtlQXMoJ21zJyk7XG4gICAgdmFyIGFzU2Vjb25kcyAgICAgID0gbWFrZUFzKCdzJyk7XG4gICAgdmFyIGFzTWludXRlcyAgICAgID0gbWFrZUFzKCdtJyk7XG4gICAgdmFyIGFzSG91cnMgICAgICAgID0gbWFrZUFzKCdoJyk7XG4gICAgdmFyIGFzRGF5cyAgICAgICAgID0gbWFrZUFzKCdkJyk7XG4gICAgdmFyIGFzV2Vla3MgICAgICAgID0gbWFrZUFzKCd3Jyk7XG4gICAgdmFyIGFzTW9udGhzICAgICAgID0gbWFrZUFzKCdNJyk7XG4gICAgdmFyIGFzUXVhcnRlcnMgICAgID0gbWFrZUFzKCdRJyk7XG4gICAgdmFyIGFzWWVhcnMgICAgICAgID0gbWFrZUFzKCd5Jyk7XG5cbiAgICBmdW5jdGlvbiBjbG9uZSQxICgpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKHRoaXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldCQyICh1bml0cykge1xuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpc1t1bml0cyArICdzJ10oKSA6IE5hTjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlR2V0dGVyKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmlzVmFsaWQoKSA/IHRoaXMuX2RhdGFbbmFtZV0gOiBOYU47XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIG1pbGxpc2Vjb25kcyA9IG1ha2VHZXR0ZXIoJ21pbGxpc2Vjb25kcycpO1xuICAgIHZhciBzZWNvbmRzICAgICAgPSBtYWtlR2V0dGVyKCdzZWNvbmRzJyk7XG4gICAgdmFyIG1pbnV0ZXMgICAgICA9IG1ha2VHZXR0ZXIoJ21pbnV0ZXMnKTtcbiAgICB2YXIgaG91cnMgICAgICAgID0gbWFrZUdldHRlcignaG91cnMnKTtcbiAgICB2YXIgZGF5cyAgICAgICAgID0gbWFrZUdldHRlcignZGF5cycpO1xuICAgIHZhciBtb250aHMgICAgICAgPSBtYWtlR2V0dGVyKCdtb250aHMnKTtcbiAgICB2YXIgeWVhcnMgICAgICAgID0gbWFrZUdldHRlcigneWVhcnMnKTtcblxuICAgIGZ1bmN0aW9uIHdlZWtzICgpIHtcbiAgICAgICAgcmV0dXJuIGFic0Zsb29yKHRoaXMuZGF5cygpIC8gNyk7XG4gICAgfVxuXG4gICAgdmFyIHJvdW5kID0gTWF0aC5yb3VuZDtcbiAgICB2YXIgdGhyZXNob2xkcyA9IHtcbiAgICAgICAgc3M6IDQ0LCAgICAgICAgIC8vIGEgZmV3IHNlY29uZHMgdG8gc2Vjb25kc1xuICAgICAgICBzIDogNDUsICAgICAgICAgLy8gc2Vjb25kcyB0byBtaW51dGVcbiAgICAgICAgbSA6IDQ1LCAgICAgICAgIC8vIG1pbnV0ZXMgdG8gaG91clxuICAgICAgICBoIDogMjIsICAgICAgICAgLy8gaG91cnMgdG8gZGF5XG4gICAgICAgIGQgOiAyNiwgICAgICAgICAvLyBkYXlzIHRvIG1vbnRoXG4gICAgICAgIE0gOiAxMSAgICAgICAgICAvLyBtb250aHMgdG8geWVhclxuICAgIH07XG5cbiAgICAvLyBoZWxwZXIgZnVuY3Rpb24gZm9yIG1vbWVudC5mbi5mcm9tLCBtb21lbnQuZm4uZnJvbU5vdywgYW5kIG1vbWVudC5kdXJhdGlvbi5mbi5odW1hbml6ZVxuICAgIGZ1bmN0aW9uIHN1YnN0aXR1dGVUaW1lQWdvKHN0cmluZywgbnVtYmVyLCB3aXRob3V0U3VmZml4LCBpc0Z1dHVyZSwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUucmVsYXRpdmVUaW1lKG51bWJlciB8fCAxLCAhIXdpdGhvdXRTdWZmaXgsIHN0cmluZywgaXNGdXR1cmUpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbGF0aXZlVGltZSQxIChwb3NOZWdEdXJhdGlvbiwgd2l0aG91dFN1ZmZpeCwgbG9jYWxlKSB7XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IGNyZWF0ZUR1cmF0aW9uKHBvc05lZ0R1cmF0aW9uKS5hYnMoKTtcbiAgICAgICAgdmFyIHNlY29uZHMgID0gcm91bmQoZHVyYXRpb24uYXMoJ3MnKSk7XG4gICAgICAgIHZhciBtaW51dGVzICA9IHJvdW5kKGR1cmF0aW9uLmFzKCdtJykpO1xuICAgICAgICB2YXIgaG91cnMgICAgPSByb3VuZChkdXJhdGlvbi5hcygnaCcpKTtcbiAgICAgICAgdmFyIGRheXMgICAgID0gcm91bmQoZHVyYXRpb24uYXMoJ2QnKSk7XG4gICAgICAgIHZhciBtb250aHMgICA9IHJvdW5kKGR1cmF0aW9uLmFzKCdNJykpO1xuICAgICAgICB2YXIgeWVhcnMgICAgPSByb3VuZChkdXJhdGlvbi5hcygneScpKTtcblxuICAgICAgICB2YXIgYSA9IHNlY29uZHMgPD0gdGhyZXNob2xkcy5zcyAmJiBbJ3MnLCBzZWNvbmRzXSAgfHxcbiAgICAgICAgICAgICAgICBzZWNvbmRzIDwgdGhyZXNob2xkcy5zICAgJiYgWydzcycsIHNlY29uZHNdIHx8XG4gICAgICAgICAgICAgICAgbWludXRlcyA8PSAxICAgICAgICAgICAgICYmIFsnbSddICAgICAgICAgICB8fFxuICAgICAgICAgICAgICAgIG1pbnV0ZXMgPCB0aHJlc2hvbGRzLm0gICAmJiBbJ21tJywgbWludXRlc10gfHxcbiAgICAgICAgICAgICAgICBob3VycyAgIDw9IDEgICAgICAgICAgICAgJiYgWydoJ10gICAgICAgICAgIHx8XG4gICAgICAgICAgICAgICAgaG91cnMgICA8IHRocmVzaG9sZHMuaCAgICYmIFsnaGgnLCBob3Vyc10gICB8fFxuICAgICAgICAgICAgICAgIGRheXMgICAgPD0gMSAgICAgICAgICAgICAmJiBbJ2QnXSAgICAgICAgICAgfHxcbiAgICAgICAgICAgICAgICBkYXlzICAgIDwgdGhyZXNob2xkcy5kICAgJiYgWydkZCcsIGRheXNdICAgIHx8XG4gICAgICAgICAgICAgICAgbW9udGhzICA8PSAxICAgICAgICAgICAgICYmIFsnTSddICAgICAgICAgICB8fFxuICAgICAgICAgICAgICAgIG1vbnRocyAgPCB0aHJlc2hvbGRzLk0gICAmJiBbJ01NJywgbW9udGhzXSAgfHxcbiAgICAgICAgICAgICAgICB5ZWFycyAgIDw9IDEgICAgICAgICAgICAgJiYgWyd5J10gICAgICAgICAgIHx8IFsneXknLCB5ZWFyc107XG5cbiAgICAgICAgYVsyXSA9IHdpdGhvdXRTdWZmaXg7XG4gICAgICAgIGFbM10gPSArcG9zTmVnRHVyYXRpb24gPiAwO1xuICAgICAgICBhWzRdID0gbG9jYWxlO1xuICAgICAgICByZXR1cm4gc3Vic3RpdHV0ZVRpbWVBZ28uYXBwbHkobnVsbCwgYSk7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHNldCB0aGUgcm91bmRpbmcgZnVuY3Rpb24gZm9yIHJlbGF0aXZlIHRpbWUgc3RyaW5nc1xuICAgIGZ1bmN0aW9uIGdldFNldFJlbGF0aXZlVGltZVJvdW5kaW5nIChyb3VuZGluZ0Z1bmN0aW9uKSB7XG4gICAgICAgIGlmIChyb3VuZGluZ0Z1bmN0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiByb3VuZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mKHJvdW5kaW5nRnVuY3Rpb24pID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByb3VuZCA9IHJvdW5kaW5nRnVuY3Rpb247XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHNldCBhIHRocmVzaG9sZCBmb3IgcmVsYXRpdmUgdGltZSBzdHJpbmdzXG4gICAgZnVuY3Rpb24gZ2V0U2V0UmVsYXRpdmVUaW1lVGhyZXNob2xkICh0aHJlc2hvbGQsIGxpbWl0KSB7XG4gICAgICAgIGlmICh0aHJlc2hvbGRzW3RocmVzaG9sZF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW1pdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhyZXNob2xkc1t0aHJlc2hvbGRdO1xuICAgICAgICB9XG4gICAgICAgIHRocmVzaG9sZHNbdGhyZXNob2xkXSA9IGxpbWl0O1xuICAgICAgICBpZiAodGhyZXNob2xkID09PSAncycpIHtcbiAgICAgICAgICAgIHRocmVzaG9sZHMuc3MgPSBsaW1pdCAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaHVtYW5pemUgKHdpdGhTdWZmaXgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLmludmFsaWREYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbG9jYWxlID0gdGhpcy5sb2NhbGVEYXRhKCk7XG4gICAgICAgIHZhciBvdXRwdXQgPSByZWxhdGl2ZVRpbWUkMSh0aGlzLCAhd2l0aFN1ZmZpeCwgbG9jYWxlKTtcblxuICAgICAgICBpZiAod2l0aFN1ZmZpeCkge1xuICAgICAgICAgICAgb3V0cHV0ID0gbG9jYWxlLnBhc3RGdXR1cmUoK3RoaXMsIG91dHB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbG9jYWxlLnBvc3Rmb3JtYXQob3V0cHV0KTtcbiAgICB9XG5cbiAgICB2YXIgYWJzJDEgPSBNYXRoLmFicztcblxuICAgIGZ1bmN0aW9uIHNpZ24oeCkge1xuICAgICAgICByZXR1cm4gKCh4ID4gMCkgLSAoeCA8IDApKSB8fCAreDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0lTT1N0cmluZyQxKCkge1xuICAgICAgICAvLyBmb3IgSVNPIHN0cmluZ3Mgd2UgZG8gbm90IHVzZSB0aGUgbm9ybWFsIGJ1YmJsaW5nIHJ1bGVzOlxuICAgICAgICAvLyAgKiBtaWxsaXNlY29uZHMgYnViYmxlIHVwIHVudGlsIHRoZXkgYmVjb21lIGhvdXJzXG4gICAgICAgIC8vICAqIGRheXMgZG8gbm90IGJ1YmJsZSBhdCBhbGxcbiAgICAgICAgLy8gICogbW9udGhzIGJ1YmJsZSB1cCB1bnRpbCB0aGV5IGJlY29tZSB5ZWFyc1xuICAgICAgICAvLyBUaGlzIGlzIGJlY2F1c2UgdGhlcmUgaXMgbm8gY29udGV4dC1mcmVlIGNvbnZlcnNpb24gYmV0d2VlbiBob3VycyBhbmQgZGF5c1xuICAgICAgICAvLyAodGhpbmsgb2YgY2xvY2sgY2hhbmdlcylcbiAgICAgICAgLy8gYW5kIGFsc28gbm90IGJldHdlZW4gZGF5cyBhbmQgbW9udGhzICgyOC0zMSBkYXlzIHBlciBtb250aClcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLmludmFsaWREYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc2Vjb25kcyA9IGFicyQxKHRoaXMuX21pbGxpc2Vjb25kcykgLyAxMDAwO1xuICAgICAgICB2YXIgZGF5cyAgICAgICAgID0gYWJzJDEodGhpcy5fZGF5cyk7XG4gICAgICAgIHZhciBtb250aHMgICAgICAgPSBhYnMkMSh0aGlzLl9tb250aHMpO1xuICAgICAgICB2YXIgbWludXRlcywgaG91cnMsIHllYXJzO1xuXG4gICAgICAgIC8vIDM2MDAgc2Vjb25kcyAtPiA2MCBtaW51dGVzIC0+IDEgaG91clxuICAgICAgICBtaW51dGVzICAgICAgICAgICA9IGFic0Zsb29yKHNlY29uZHMgLyA2MCk7XG4gICAgICAgIGhvdXJzICAgICAgICAgICAgID0gYWJzRmxvb3IobWludXRlcyAvIDYwKTtcbiAgICAgICAgc2Vjb25kcyAlPSA2MDtcbiAgICAgICAgbWludXRlcyAlPSA2MDtcblxuICAgICAgICAvLyAxMiBtb250aHMgLT4gMSB5ZWFyXG4gICAgICAgIHllYXJzICA9IGFic0Zsb29yKG1vbnRocyAvIDEyKTtcbiAgICAgICAgbW9udGhzICU9IDEyO1xuXG5cbiAgICAgICAgLy8gaW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2RvcmRpbGxlL21vbWVudC1pc29kdXJhdGlvbi9ibG9iL21hc3Rlci9tb21lbnQuaXNvZHVyYXRpb24uanNcbiAgICAgICAgdmFyIFkgPSB5ZWFycztcbiAgICAgICAgdmFyIE0gPSBtb250aHM7XG4gICAgICAgIHZhciBEID0gZGF5cztcbiAgICAgICAgdmFyIGggPSBob3VycztcbiAgICAgICAgdmFyIG0gPSBtaW51dGVzO1xuICAgICAgICB2YXIgcyA9IHNlY29uZHMgPyBzZWNvbmRzLnRvRml4ZWQoMykucmVwbGFjZSgvXFwuPzArJC8sICcnKSA6ICcnO1xuICAgICAgICB2YXIgdG90YWwgPSB0aGlzLmFzU2Vjb25kcygpO1xuXG4gICAgICAgIGlmICghdG90YWwpIHtcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgdGhlIHNhbWUgYXMgQyMncyAoTm9kYSkgYW5kIHB5dGhvbiAoaXNvZGF0ZSkuLi5cbiAgICAgICAgICAgIC8vIGJ1dCBub3Qgb3RoZXIgSlMgKGdvb2cuZGF0ZSlcbiAgICAgICAgICAgIHJldHVybiAnUDBEJztcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0b3RhbFNpZ24gPSB0b3RhbCA8IDAgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIHltU2lnbiA9IHNpZ24odGhpcy5fbW9udGhzKSAhPT0gc2lnbih0b3RhbCkgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIGRheXNTaWduID0gc2lnbih0aGlzLl9kYXlzKSAhPT0gc2lnbih0b3RhbCkgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIGhtc1NpZ24gPSBzaWduKHRoaXMuX21pbGxpc2Vjb25kcykgIT09IHNpZ24odG90YWwpID8gJy0nIDogJyc7XG5cbiAgICAgICAgcmV0dXJuIHRvdGFsU2lnbiArICdQJyArXG4gICAgICAgICAgICAoWSA/IHltU2lnbiArIFkgKyAnWScgOiAnJykgK1xuICAgICAgICAgICAgKE0gPyB5bVNpZ24gKyBNICsgJ00nIDogJycpICtcbiAgICAgICAgICAgIChEID8gZGF5c1NpZ24gKyBEICsgJ0QnIDogJycpICtcbiAgICAgICAgICAgICgoaCB8fCBtIHx8IHMpID8gJ1QnIDogJycpICtcbiAgICAgICAgICAgIChoID8gaG1zU2lnbiArIGggKyAnSCcgOiAnJykgK1xuICAgICAgICAgICAgKG0gPyBobXNTaWduICsgbSArICdNJyA6ICcnKSArXG4gICAgICAgICAgICAocyA/IGhtc1NpZ24gKyBzICsgJ1MnIDogJycpO1xuICAgIH1cblxuICAgIHZhciBwcm90byQyID0gRHVyYXRpb24ucHJvdG90eXBlO1xuXG4gICAgcHJvdG8kMi5pc1ZhbGlkICAgICAgICA9IGlzVmFsaWQkMTtcbiAgICBwcm90byQyLmFicyAgICAgICAgICAgID0gYWJzO1xuICAgIHByb3RvJDIuYWRkICAgICAgICAgICAgPSBhZGQkMTtcbiAgICBwcm90byQyLnN1YnRyYWN0ICAgICAgID0gc3VidHJhY3QkMTtcbiAgICBwcm90byQyLmFzICAgICAgICAgICAgID0gYXM7XG4gICAgcHJvdG8kMi5hc01pbGxpc2Vjb25kcyA9IGFzTWlsbGlzZWNvbmRzO1xuICAgIHByb3RvJDIuYXNTZWNvbmRzICAgICAgPSBhc1NlY29uZHM7XG4gICAgcHJvdG8kMi5hc01pbnV0ZXMgICAgICA9IGFzTWludXRlcztcbiAgICBwcm90byQyLmFzSG91cnMgICAgICAgID0gYXNIb3VycztcbiAgICBwcm90byQyLmFzRGF5cyAgICAgICAgID0gYXNEYXlzO1xuICAgIHByb3RvJDIuYXNXZWVrcyAgICAgICAgPSBhc1dlZWtzO1xuICAgIHByb3RvJDIuYXNNb250aHMgICAgICAgPSBhc01vbnRocztcbiAgICBwcm90byQyLmFzUXVhcnRlcnMgICAgID0gYXNRdWFydGVycztcbiAgICBwcm90byQyLmFzWWVhcnMgICAgICAgID0gYXNZZWFycztcbiAgICBwcm90byQyLnZhbHVlT2YgICAgICAgID0gdmFsdWVPZiQxO1xuICAgIHByb3RvJDIuX2J1YmJsZSAgICAgICAgPSBidWJibGU7XG4gICAgcHJvdG8kMi5jbG9uZSAgICAgICAgICA9IGNsb25lJDE7XG4gICAgcHJvdG8kMi5nZXQgICAgICAgICAgICA9IGdldCQyO1xuICAgIHByb3RvJDIubWlsbGlzZWNvbmRzICAgPSBtaWxsaXNlY29uZHM7XG4gICAgcHJvdG8kMi5zZWNvbmRzICAgICAgICA9IHNlY29uZHM7XG4gICAgcHJvdG8kMi5taW51dGVzICAgICAgICA9IG1pbnV0ZXM7XG4gICAgcHJvdG8kMi5ob3VycyAgICAgICAgICA9IGhvdXJzO1xuICAgIHByb3RvJDIuZGF5cyAgICAgICAgICAgPSBkYXlzO1xuICAgIHByb3RvJDIud2Vla3MgICAgICAgICAgPSB3ZWVrcztcbiAgICBwcm90byQyLm1vbnRocyAgICAgICAgID0gbW9udGhzO1xuICAgIHByb3RvJDIueWVhcnMgICAgICAgICAgPSB5ZWFycztcbiAgICBwcm90byQyLmh1bWFuaXplICAgICAgID0gaHVtYW5pemU7XG4gICAgcHJvdG8kMi50b0lTT1N0cmluZyAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi50b1N0cmluZyAgICAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi50b0pTT04gICAgICAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi5sb2NhbGUgICAgICAgICA9IGxvY2FsZTtcbiAgICBwcm90byQyLmxvY2FsZURhdGEgICAgID0gbG9jYWxlRGF0YTtcblxuICAgIHByb3RvJDIudG9Jc29TdHJpbmcgPSBkZXByZWNhdGUoJ3RvSXNvU3RyaW5nKCkgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSB0b0lTT1N0cmluZygpIGluc3RlYWQgKG5vdGljZSB0aGUgY2FwaXRhbHMpJywgdG9JU09TdHJpbmckMSk7XG4gICAgcHJvdG8kMi5sYW5nID0gbGFuZztcblxuICAgIC8vIFNpZGUgZWZmZWN0IGltcG9ydHNcblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdYJywgMCwgMCwgJ3VuaXgnKTtcbiAgICBhZGRGb3JtYXRUb2tlbigneCcsIDAsIDAsICd2YWx1ZU9mJyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCd4JywgbWF0Y2hTaWduZWQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1gnLCBtYXRjaFRpbWVzdGFtcCk7XG4gICAgYWRkUGFyc2VUb2tlbignWCcsIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2QgPSBuZXcgRGF0ZShwYXJzZUZsb2F0KGlucHV0LCAxMCkgKiAxMDAwKTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCd4JywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKHRvSW50KGlucHV0KSk7XG4gICAgfSk7XG5cbiAgICAvLyBTaWRlIGVmZmVjdCBpbXBvcnRzXG5cblxuICAgIGhvb2tzLnZlcnNpb24gPSAnMi4yNC4wJztcblxuICAgIHNldEhvb2tDYWxsYmFjayhjcmVhdGVMb2NhbCk7XG5cbiAgICBob29rcy5mbiAgICAgICAgICAgICAgICAgICAgPSBwcm90bztcbiAgICBob29rcy5taW4gICAgICAgICAgICAgICAgICAgPSBtaW47XG4gICAgaG9va3MubWF4ICAgICAgICAgICAgICAgICAgID0gbWF4O1xuICAgIGhvb2tzLm5vdyAgICAgICAgICAgICAgICAgICA9IG5vdztcbiAgICBob29rcy51dGMgICAgICAgICAgICAgICAgICAgPSBjcmVhdGVVVEM7XG4gICAgaG9va3MudW5peCAgICAgICAgICAgICAgICAgID0gY3JlYXRlVW5peDtcbiAgICBob29rcy5tb250aHMgICAgICAgICAgICAgICAgPSBsaXN0TW9udGhzO1xuICAgIGhvb2tzLmlzRGF0ZSAgICAgICAgICAgICAgICA9IGlzRGF0ZTtcbiAgICBob29rcy5sb2NhbGUgICAgICAgICAgICAgICAgPSBnZXRTZXRHbG9iYWxMb2NhbGU7XG4gICAgaG9va3MuaW52YWxpZCAgICAgICAgICAgICAgID0gY3JlYXRlSW52YWxpZDtcbiAgICBob29rcy5kdXJhdGlvbiAgICAgICAgICAgICAgPSBjcmVhdGVEdXJhdGlvbjtcbiAgICBob29rcy5pc01vbWVudCAgICAgICAgICAgICAgPSBpc01vbWVudDtcbiAgICBob29rcy53ZWVrZGF5cyAgICAgICAgICAgICAgPSBsaXN0V2Vla2RheXM7XG4gICAgaG9va3MucGFyc2Vab25lICAgICAgICAgICAgID0gY3JlYXRlSW5ab25lO1xuICAgIGhvb2tzLmxvY2FsZURhdGEgICAgICAgICAgICA9IGdldExvY2FsZTtcbiAgICBob29rcy5pc0R1cmF0aW9uICAgICAgICAgICAgPSBpc0R1cmF0aW9uO1xuICAgIGhvb2tzLm1vbnRoc1Nob3J0ICAgICAgICAgICA9IGxpc3RNb250aHNTaG9ydDtcbiAgICBob29rcy53ZWVrZGF5c01pbiAgICAgICAgICAgPSBsaXN0V2Vla2RheXNNaW47XG4gICAgaG9va3MuZGVmaW5lTG9jYWxlICAgICAgICAgID0gZGVmaW5lTG9jYWxlO1xuICAgIGhvb2tzLnVwZGF0ZUxvY2FsZSAgICAgICAgICA9IHVwZGF0ZUxvY2FsZTtcbiAgICBob29rcy5sb2NhbGVzICAgICAgICAgICAgICAgPSBsaXN0TG9jYWxlcztcbiAgICBob29rcy53ZWVrZGF5c1Nob3J0ICAgICAgICAgPSBsaXN0V2Vla2RheXNTaG9ydDtcbiAgICBob29rcy5ub3JtYWxpemVVbml0cyAgICAgICAgPSBub3JtYWxpemVVbml0cztcbiAgICBob29rcy5yZWxhdGl2ZVRpbWVSb3VuZGluZyAgPSBnZXRTZXRSZWxhdGl2ZVRpbWVSb3VuZGluZztcbiAgICBob29rcy5yZWxhdGl2ZVRpbWVUaHJlc2hvbGQgPSBnZXRTZXRSZWxhdGl2ZVRpbWVUaHJlc2hvbGQ7XG4gICAgaG9va3MuY2FsZW5kYXJGb3JtYXQgICAgICAgID0gZ2V0Q2FsZW5kYXJGb3JtYXQ7XG4gICAgaG9va3MucHJvdG90eXBlICAgICAgICAgICAgID0gcHJvdG87XG5cbiAgICAvLyBjdXJyZW50bHkgSFRNTDUgaW5wdXQgdHlwZSBvbmx5IHN1cHBvcnRzIDI0LWhvdXIgZm9ybWF0c1xuICAgIGhvb2tzLkhUTUw1X0ZNVCA9IHtcbiAgICAgICAgREFURVRJTUVfTE9DQUw6ICdZWVlZLU1NLUREVEhIOm1tJywgICAgICAgICAgICAgLy8gPGlucHV0IHR5cGU9XCJkYXRldGltZS1sb2NhbFwiIC8+XG4gICAgICAgIERBVEVUSU1FX0xPQ0FMX1NFQ09ORFM6ICdZWVlZLU1NLUREVEhIOm1tOnNzJywgIC8vIDxpbnB1dCB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIiBzdGVwPVwiMVwiIC8+XG4gICAgICAgIERBVEVUSU1FX0xPQ0FMX01TOiAnWVlZWS1NTS1ERFRISDptbTpzcy5TU1MnLCAgIC8vIDxpbnB1dCB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIiBzdGVwPVwiMC4wMDFcIiAvPlxuICAgICAgICBEQVRFOiAnWVlZWS1NTS1ERCcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cImRhdGVcIiAvPlxuICAgICAgICBUSU1FOiAnSEg6bW0nLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cInRpbWVcIiAvPlxuICAgICAgICBUSU1FX1NFQ09ORFM6ICdISDptbTpzcycsICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cInRpbWVcIiBzdGVwPVwiMVwiIC8+XG4gICAgICAgIFRJTUVfTVM6ICdISDptbTpzcy5TU1MnLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwidGltZVwiIHN0ZXA9XCIwLjAwMVwiIC8+XG4gICAgICAgIFdFRUs6ICdHR0dHLVtXXVdXJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwid2Vla1wiIC8+XG4gICAgICAgIE1PTlRIOiAnWVlZWS1NTScgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwibW9udGhcIiAvPlxuICAgIH07XG5cbiAgICByZXR1cm4gaG9va3M7XG5cbn0pKSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///da01\n")}}]);

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.spot-framework"],{"0056":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Group = __webpack_require__(/*! ./group */ \"9083\");\n\nfunction setOrdering (groups, ordering) {\n  if (ordering === 'count') {\n    groups.comparator = function (a, b) {\n      if (a.count === b.count) {\n        return a.value < b.value ? -1 : 1;\n      } else {\n        return b.count - a.count;\n      }\n    };\n  } else if (ordering === 'value') {\n    groups.comparator = 'value';\n  } else {\n    console.error('Ordering not implemented for partition: ', ordering);\n  }\n  groups.sort();\n}\n\nmodule.exports = Collection.extend({\n  indexes: ['value', 'label', 'group', 'groupIndex'],\n  model: Group,\n  comparator: 'label',\n  initialize: function (models, options) {\n    var groups = this;\n    var partition = options.parent;\n\n    // update group index on resort\n    this.on('sort', function () {\n      this.forEach(function (group, i) {\n        group.groupIndex = i;\n      });\n    }, this);\n\n    // this.parent := partition\n    if (partition) {\n      setOrdering(groups, partition.ordering);\n\n      partition.on('change ordering', function () {\n        setOrdering(groups, partition.ordering);\n      });\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDA1Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2dyb3VwLWNvbGxlY3Rpb24uanM/OGM1ZiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgR3JvdXAgPSByZXF1aXJlKCcuL2dyb3VwJyk7XG5cbmZ1bmN0aW9uIHNldE9yZGVyaW5nIChncm91cHMsIG9yZGVyaW5nKSB7XG4gIGlmIChvcmRlcmluZyA9PT0gJ2NvdW50Jykge1xuICAgIGdyb3Vwcy5jb21wYXJhdG9yID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIGlmIChhLmNvdW50ID09PSBiLmNvdW50KSB7XG4gICAgICAgIHJldHVybiBhLnZhbHVlIDwgYi52YWx1ZSA/IC0xIDogMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBiLmNvdW50IC0gYS5jb3VudDtcbiAgICAgIH1cbiAgICB9O1xuICB9IGVsc2UgaWYgKG9yZGVyaW5nID09PSAndmFsdWUnKSB7XG4gICAgZ3JvdXBzLmNvbXBhcmF0b3IgPSAndmFsdWUnO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUuZXJyb3IoJ09yZGVyaW5nIG5vdCBpbXBsZW1lbnRlZCBmb3IgcGFydGl0aW9uOiAnLCBvcmRlcmluZyk7XG4gIH1cbiAgZ3JvdXBzLnNvcnQoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDb2xsZWN0aW9uLmV4dGVuZCh7XG4gIGluZGV4ZXM6IFsndmFsdWUnLCAnbGFiZWwnLCAnZ3JvdXAnLCAnZ3JvdXBJbmRleCddLFxuICBtb2RlbDogR3JvdXAsXG4gIGNvbXBhcmF0b3I6ICdsYWJlbCcsXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uIChtb2RlbHMsIG9wdGlvbnMpIHtcbiAgICB2YXIgZ3JvdXBzID0gdGhpcztcbiAgICB2YXIgcGFydGl0aW9uID0gb3B0aW9ucy5wYXJlbnQ7XG5cbiAgICAvLyB1cGRhdGUgZ3JvdXAgaW5kZXggb24gcmVzb3J0XG4gICAgdGhpcy5vbignc29ydCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZ3JvdXAsIGkpIHtcbiAgICAgICAgZ3JvdXAuZ3JvdXBJbmRleCA9IGk7XG4gICAgICB9KTtcbiAgICB9LCB0aGlzKTtcblxuICAgIC8vIHRoaXMucGFyZW50IDo9IHBhcnRpdGlvblxuICAgIGlmIChwYXJ0aXRpb24pIHtcbiAgICAgIHNldE9yZGVyaW5nKGdyb3VwcywgcGFydGl0aW9uLm9yZGVyaW5nKTtcblxuICAgICAgcGFydGl0aW9uLm9uKCdjaGFuZ2Ugb3JkZXJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNldE9yZGVyaW5nKGdyb3VwcywgcGFydGl0aW9uLm9yZGVyaW5nKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///0056\n")},"0112":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar transports = __webpack_require__(/*! ./transports/index */ \"834b\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:socket');\nvar index = __webpack_require__(/*! indexof */ \"3294\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar parseuri = __webpack_require__(/*! parseuri */ \"64a0\");\nvar parsejson = __webpack_require__(/*! parsejson */ \"185c\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = Socket;\n\n/**\n * Socket constructor.\n *\n * @param {String|Object} uri or options\n * @param {Object} options\n * @api public\n */\n\nfunction Socket (uri, opts) {\n  if (!(this instanceof Socket)) return new Socket(uri, opts);\n\n  opts = opts || {};\n\n  if (uri && 'object' === typeof uri) {\n    opts = uri;\n    uri = null;\n  }\n\n  if (uri) {\n    uri = parseuri(uri);\n    opts.hostname = uri.host;\n    opts.secure = uri.protocol === 'https' || uri.protocol === 'wss';\n    opts.port = uri.port;\n    if (uri.query) opts.query = uri.query;\n  } else if (opts.host) {\n    opts.hostname = parseuri(opts.host).host;\n  }\n\n  this.secure = null != opts.secure ? opts.secure\n    : (global.location && 'https:' === location.protocol);\n\n  if (opts.hostname && !opts.port) {\n    // if no port is specified manually, use the protocol default\n    opts.port = this.secure ? '443' : '80';\n  }\n\n  this.agent = opts.agent || false;\n  this.hostname = opts.hostname ||\n    (global.location ? location.hostname : 'localhost');\n  this.port = opts.port || (global.location && location.port\n      ? location.port\n      : (this.secure ? 443 : 80));\n  this.query = opts.query || {};\n  if ('string' === typeof this.query) this.query = parseqs.decode(this.query);\n  this.upgrade = false !== opts.upgrade;\n  this.path = (opts.path || '/engine.io').replace(/\\/$/, '') + '/';\n  this.forceJSONP = !!opts.forceJSONP;\n  this.jsonp = false !== opts.jsonp;\n  this.forceBase64 = !!opts.forceBase64;\n  this.enablesXDR = !!opts.enablesXDR;\n  this.timestampParam = opts.timestampParam || 't';\n  this.timestampRequests = opts.timestampRequests;\n  this.transports = opts.transports || ['polling', 'websocket'];\n  this.readyState = '';\n  this.writeBuffer = [];\n  this.prevBufferLen = 0;\n  this.policyPort = opts.policyPort || 843;\n  this.rememberUpgrade = opts.rememberUpgrade || false;\n  this.binaryType = null;\n  this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;\n  this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || {}) : false;\n\n  if (true === this.perMessageDeflate) this.perMessageDeflate = {};\n  if (this.perMessageDeflate && null == this.perMessageDeflate.threshold) {\n    this.perMessageDeflate.threshold = 1024;\n  }\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx || null;\n  this.key = opts.key || null;\n  this.passphrase = opts.passphrase || null;\n  this.cert = opts.cert || null;\n  this.ca = opts.ca || null;\n  this.ciphers = opts.ciphers || null;\n  this.rejectUnauthorized = opts.rejectUnauthorized === undefined ? null : opts.rejectUnauthorized;\n  this.forceNode = !!opts.forceNode;\n\n  // other options for Node.js client\n  var freeGlobal = typeof global === 'object' && global;\n  if (freeGlobal.global === freeGlobal) {\n    if (opts.extraHeaders && Object.keys(opts.extraHeaders).length > 0) {\n      this.extraHeaders = opts.extraHeaders;\n    }\n\n    if (opts.localAddress) {\n      this.localAddress = opts.localAddress;\n    }\n  }\n\n  // set on handshake\n  this.id = null;\n  this.upgrades = null;\n  this.pingInterval = null;\n  this.pingTimeout = null;\n\n  // set on heartbeat\n  this.pingIntervalTimer = null;\n  this.pingTimeoutTimer = null;\n\n  this.open();\n}\n\nSocket.priorWebsocketSuccess = false;\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Socket.prototype);\n\n/**\n * Protocol version.\n *\n * @api public\n */\n\nSocket.protocol = parser.protocol; // this is an int\n\n/**\n * Expose deps for legacy compatibility\n * and standalone browser access.\n */\n\nSocket.Socket = Socket;\nSocket.Transport = __webpack_require__(/*! ./transport */ \"0d97\");\nSocket.transports = __webpack_require__(/*! ./transports/index */ \"834b\");\nSocket.parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\n\n/**\n * Creates transport of the given type.\n *\n * @param {String} transport name\n * @return {Transport}\n * @api private\n */\n\nSocket.prototype.createTransport = function (name) {\n  debug('creating transport \"%s\"', name);\n  var query = clone(this.query);\n\n  // append engine.io protocol identifier\n  query.EIO = parser.protocol;\n\n  // transport name\n  query.transport = name;\n\n  // session id if we already have one\n  if (this.id) query.sid = this.id;\n\n  var transport = new transports[name]({\n    agent: this.agent,\n    hostname: this.hostname,\n    port: this.port,\n    secure: this.secure,\n    path: this.path,\n    query: query,\n    forceJSONP: this.forceJSONP,\n    jsonp: this.jsonp,\n    forceBase64: this.forceBase64,\n    enablesXDR: this.enablesXDR,\n    timestampRequests: this.timestampRequests,\n    timestampParam: this.timestampParam,\n    policyPort: this.policyPort,\n    socket: this,\n    pfx: this.pfx,\n    key: this.key,\n    passphrase: this.passphrase,\n    cert: this.cert,\n    ca: this.ca,\n    ciphers: this.ciphers,\n    rejectUnauthorized: this.rejectUnauthorized,\n    perMessageDeflate: this.perMessageDeflate,\n    extraHeaders: this.extraHeaders,\n    forceNode: this.forceNode,\n    localAddress: this.localAddress\n  });\n\n  return transport;\n};\n\nfunction clone (obj) {\n  var o = {};\n  for (var i in obj) {\n    if (obj.hasOwnProperty(i)) {\n      o[i] = obj[i];\n    }\n  }\n  return o;\n}\n\n/**\n * Initializes transport to use and starts probe.\n *\n * @api private\n */\nSocket.prototype.open = function () {\n  var transport;\n  if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') !== -1) {\n    transport = 'websocket';\n  } else if (0 === this.transports.length) {\n    // Emit error on next tick so it can be listened to\n    var self = this;\n    setTimeout(function () {\n      self.emit('error', 'No transports available');\n    }, 0);\n    return;\n  } else {\n    transport = this.transports[0];\n  }\n  this.readyState = 'opening';\n\n  // Retry with the next transport if the transport is disabled (jsonp: false)\n  try {\n    transport = this.createTransport(transport);\n  } catch (e) {\n    this.transports.shift();\n    this.open();\n    return;\n  }\n\n  transport.open();\n  this.setTransport(transport);\n};\n\n/**\n * Sets the current transport. Disables the existing one (if any).\n *\n * @api private\n */\n\nSocket.prototype.setTransport = function (transport) {\n  debug('setting transport %s', transport.name);\n  var self = this;\n\n  if (this.transport) {\n    debug('clearing existing transport %s', this.transport.name);\n    this.transport.removeAllListeners();\n  }\n\n  // set up transport\n  this.transport = transport;\n\n  // set up transport listeners\n  transport\n  .on('drain', function () {\n    self.onDrain();\n  })\n  .on('packet', function (packet) {\n    self.onPacket(packet);\n  })\n  .on('error', function (e) {\n    self.onError(e);\n  })\n  .on('close', function () {\n    self.onClose('transport close');\n  });\n};\n\n/**\n * Probes a transport.\n *\n * @param {String} transport name\n * @api private\n */\n\nSocket.prototype.probe = function (name) {\n  debug('probing transport \"%s\"', name);\n  var transport = this.createTransport(name, { probe: 1 });\n  var failed = false;\n  var self = this;\n\n  Socket.priorWebsocketSuccess = false;\n\n  function onTransportOpen () {\n    if (self.onlyBinaryUpgrades) {\n      var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;\n      failed = failed || upgradeLosesBinary;\n    }\n    if (failed) return;\n\n    debug('probe transport \"%s\" opened', name);\n    transport.send([{ type: 'ping', data: 'probe' }]);\n    transport.once('packet', function (msg) {\n      if (failed) return;\n      if ('pong' === msg.type && 'probe' === msg.data) {\n        debug('probe transport \"%s\" pong', name);\n        self.upgrading = true;\n        self.emit('upgrading', transport);\n        if (!transport) return;\n        Socket.priorWebsocketSuccess = 'websocket' === transport.name;\n\n        debug('pausing current transport \"%s\"', self.transport.name);\n        self.transport.pause(function () {\n          if (failed) return;\n          if ('closed' === self.readyState) return;\n          debug('changing transport and sending upgrade packet');\n\n          cleanup();\n\n          self.setTransport(transport);\n          transport.send([{ type: 'upgrade' }]);\n          self.emit('upgrade', transport);\n          transport = null;\n          self.upgrading = false;\n          self.flush();\n        });\n      } else {\n        debug('probe transport \"%s\" failed', name);\n        var err = new Error('probe error');\n        err.transport = transport.name;\n        self.emit('upgradeError', err);\n      }\n    });\n  }\n\n  function freezeTransport () {\n    if (failed) return;\n\n    // Any callback called by transport should be ignored since now\n    failed = true;\n\n    cleanup();\n\n    transport.close();\n    transport = null;\n  }\n\n  // Handle any error that happens while probing\n  function onerror (err) {\n    var error = new Error('probe error: ' + err);\n    error.transport = transport.name;\n\n    freezeTransport();\n\n    debug('probe transport \"%s\" failed because of error: %s', name, err);\n\n    self.emit('upgradeError', error);\n  }\n\n  function onTransportClose () {\n    onerror('transport closed');\n  }\n\n  // When the socket is closed while we're probing\n  function onclose () {\n    onerror('socket closed');\n  }\n\n  // When the socket is upgraded while we're probing\n  function onupgrade (to) {\n    if (transport && to.name !== transport.name) {\n      debug('\"%s\" works - aborting \"%s\"', to.name, transport.name);\n      freezeTransport();\n    }\n  }\n\n  // Remove all listeners on the transport and on self\n  function cleanup () {\n    transport.removeListener('open', onTransportOpen);\n    transport.removeListener('error', onerror);\n    transport.removeListener('close', onTransportClose);\n    self.removeListener('close', onclose);\n    self.removeListener('upgrading', onupgrade);\n  }\n\n  transport.once('open', onTransportOpen);\n  transport.once('error', onerror);\n  transport.once('close', onTransportClose);\n\n  this.once('close', onclose);\n  this.once('upgrading', onupgrade);\n\n  transport.open();\n};\n\n/**\n * Called when connection is deemed open.\n *\n * @api public\n */\n\nSocket.prototype.onOpen = function () {\n  debug('socket open');\n  this.readyState = 'open';\n  Socket.priorWebsocketSuccess = 'websocket' === this.transport.name;\n  this.emit('open');\n  this.flush();\n\n  // we check for `readyState` in case an `open`\n  // listener already closed the socket\n  if ('open' === this.readyState && this.upgrade && this.transport.pause) {\n    debug('starting upgrade probes');\n    for (var i = 0, l = this.upgrades.length; i < l; i++) {\n      this.probe(this.upgrades[i]);\n    }\n  }\n};\n\n/**\n * Handles a packet.\n *\n * @api private\n */\n\nSocket.prototype.onPacket = function (packet) {\n  if ('opening' === this.readyState || 'open' === this.readyState ||\n      'closing' === this.readyState) {\n    debug('socket receive: type \"%s\", data \"%s\"', packet.type, packet.data);\n\n    this.emit('packet', packet);\n\n    // Socket is live - any packet counts\n    this.emit('heartbeat');\n\n    switch (packet.type) {\n      case 'open':\n        this.onHandshake(parsejson(packet.data));\n        break;\n\n      case 'pong':\n        this.setPing();\n        this.emit('pong');\n        break;\n\n      case 'error':\n        var err = new Error('server error');\n        err.code = packet.data;\n        this.onError(err);\n        break;\n\n      case 'message':\n        this.emit('data', packet.data);\n        this.emit('message', packet.data);\n        break;\n    }\n  } else {\n    debug('packet received with socket readyState \"%s\"', this.readyState);\n  }\n};\n\n/**\n * Called upon handshake completion.\n *\n * @param {Object} handshake obj\n * @api private\n */\n\nSocket.prototype.onHandshake = function (data) {\n  this.emit('handshake', data);\n  this.id = data.sid;\n  this.transport.query.sid = data.sid;\n  this.upgrades = this.filterUpgrades(data.upgrades);\n  this.pingInterval = data.pingInterval;\n  this.pingTimeout = data.pingTimeout;\n  this.onOpen();\n  // In case open handler closes socket\n  if ('closed' === this.readyState) return;\n  this.setPing();\n\n  // Prolong liveness of socket on heartbeat\n  this.removeListener('heartbeat', this.onHeartbeat);\n  this.on('heartbeat', this.onHeartbeat);\n};\n\n/**\n * Resets ping timeout.\n *\n * @api private\n */\n\nSocket.prototype.onHeartbeat = function (timeout) {\n  clearTimeout(this.pingTimeoutTimer);\n  var self = this;\n  self.pingTimeoutTimer = setTimeout(function () {\n    if ('closed' === self.readyState) return;\n    self.onClose('ping timeout');\n  }, timeout || (self.pingInterval + self.pingTimeout));\n};\n\n/**\n * Pings server every `this.pingInterval` and expects response\n * within `this.pingTimeout` or closes connection.\n *\n * @api private\n */\n\nSocket.prototype.setPing = function () {\n  var self = this;\n  clearTimeout(self.pingIntervalTimer);\n  self.pingIntervalTimer = setTimeout(function () {\n    debug('writing ping packet - expecting pong within %sms', self.pingTimeout);\n    self.ping();\n    self.onHeartbeat(self.pingTimeout);\n  }, self.pingInterval);\n};\n\n/**\n* Sends a ping packet.\n*\n* @api private\n*/\n\nSocket.prototype.ping = function () {\n  var self = this;\n  this.sendPacket('ping', function () {\n    self.emit('ping');\n  });\n};\n\n/**\n * Called on `drain` event\n *\n * @api private\n */\n\nSocket.prototype.onDrain = function () {\n  this.writeBuffer.splice(0, this.prevBufferLen);\n\n  // setting prevBufferLen = 0 is very important\n  // for example, when upgrading, upgrade packet is sent over,\n  // and a nonzero prevBufferLen could cause problems on `drain`\n  this.prevBufferLen = 0;\n\n  if (0 === this.writeBuffer.length) {\n    this.emit('drain');\n  } else {\n    this.flush();\n  }\n};\n\n/**\n * Flush write buffers.\n *\n * @api private\n */\n\nSocket.prototype.flush = function () {\n  if ('closed' !== this.readyState && this.transport.writable &&\n    !this.upgrading && this.writeBuffer.length) {\n    debug('flushing %d packets in socket', this.writeBuffer.length);\n    this.transport.send(this.writeBuffer);\n    // keep track of current length of writeBuffer\n    // splice writeBuffer and callbackBuffer on `drain`\n    this.prevBufferLen = this.writeBuffer.length;\n    this.emit('flush');\n  }\n};\n\n/**\n * Sends a message.\n *\n * @param {String} message.\n * @param {Function} callback function.\n * @param {Object} options.\n * @return {Socket} for chaining.\n * @api public\n */\n\nSocket.prototype.write =\nSocket.prototype.send = function (msg, options, fn) {\n  this.sendPacket('message', msg, options, fn);\n  return this;\n};\n\n/**\n * Sends a packet.\n *\n * @param {String} packet type.\n * @param {String} data.\n * @param {Object} options.\n * @param {Function} callback function.\n * @api private\n */\n\nSocket.prototype.sendPacket = function (type, data, options, fn) {\n  if ('function' === typeof data) {\n    fn = data;\n    data = undefined;\n  }\n\n  if ('function' === typeof options) {\n    fn = options;\n    options = null;\n  }\n\n  if ('closing' === this.readyState || 'closed' === this.readyState) {\n    return;\n  }\n\n  options = options || {};\n  options.compress = false !== options.compress;\n\n  var packet = {\n    type: type,\n    data: data,\n    options: options\n  };\n  this.emit('packetCreate', packet);\n  this.writeBuffer.push(packet);\n  if (fn) this.once('flush', fn);\n  this.flush();\n};\n\n/**\n * Closes the connection.\n *\n * @api private\n */\n\nSocket.prototype.close = function () {\n  if ('opening' === this.readyState || 'open' === this.readyState) {\n    this.readyState = 'closing';\n\n    var self = this;\n\n    if (this.writeBuffer.length) {\n      this.once('drain', function () {\n        if (this.upgrading) {\n          waitForUpgrade();\n        } else {\n          close();\n        }\n      });\n    } else if (this.upgrading) {\n      waitForUpgrade();\n    } else {\n      close();\n    }\n  }\n\n  function close () {\n    self.onClose('forced close');\n    debug('socket closing - telling transport to close');\n    self.transport.close();\n  }\n\n  function cleanupAndClose () {\n    self.removeListener('upgrade', cleanupAndClose);\n    self.removeListener('upgradeError', cleanupAndClose);\n    close();\n  }\n\n  function waitForUpgrade () {\n    // wait for upgrade to finish since we can't send packets while pausing a transport\n    self.once('upgrade', cleanupAndClose);\n    self.once('upgradeError', cleanupAndClose);\n  }\n\n  return this;\n};\n\n/**\n * Called upon transport error\n *\n * @api private\n */\n\nSocket.prototype.onError = function (err) {\n  debug('socket error %j', err);\n  Socket.priorWebsocketSuccess = false;\n  this.emit('error', err);\n  this.onClose('transport error', err);\n};\n\n/**\n * Called upon transport close.\n *\n * @api private\n */\n\nSocket.prototype.onClose = function (reason, desc) {\n  if ('opening' === this.readyState || 'open' === this.readyState || 'closing' === this.readyState) {\n    debug('socket close with reason: \"%s\"', reason);\n    var self = this;\n\n    // clear timers\n    clearTimeout(this.pingIntervalTimer);\n    clearTimeout(this.pingTimeoutTimer);\n\n    // stop event from firing again for transport\n    this.transport.removeAllListeners('close');\n\n    // ensure transport won't stay open\n    this.transport.close();\n\n    // ignore further transport communication\n    this.transport.removeAllListeners();\n\n    // set ready state\n    this.readyState = 'closed';\n\n    // clear session id\n    this.id = null;\n\n    // emit close event\n    this.emit('close', reason, desc);\n\n    // clean buffers after, so users can still\n    // grab the buffers on `close` event\n    self.writeBuffer = [];\n    self.prevBufferLen = 0;\n  }\n};\n\n/**\n * Filters upgrades, returning only those matching client transports.\n *\n * @param {Array} server upgrades\n * @api private\n *\n */\n\nSocket.prototype.filterUpgrades = function (upgrades) {\n  var filteredUpgrades = [];\n  for (var i = 0, j = upgrades.length; i < j; i++) {\n    if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);\n  }\n  return filteredUpgrades;\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDExMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvc29ja2V0LmpzPzM1YjUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL2luZGV4Jyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnNvY2tldCcpO1xudmFyIGluZGV4ID0gcmVxdWlyZSgnaW5kZXhvZicpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBwYXJzZXVyaSA9IHJlcXVpcmUoJ3BhcnNldXJpJyk7XG52YXIgcGFyc2Vqc29uID0gcmVxdWlyZSgncGFyc2Vqc29uJyk7XG52YXIgcGFyc2VxcyA9IHJlcXVpcmUoJ3BhcnNlcXMnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNvY2tldDtcblxuLyoqXG4gKiBTb2NrZXQgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSB1cmkgb3Igb3B0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gU29ja2V0ICh1cmksIG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNvY2tldCkpIHJldHVybiBuZXcgU29ja2V0KHVyaSwgb3B0cyk7XG5cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgaWYgKHVyaSAmJiAnb2JqZWN0JyA9PT0gdHlwZW9mIHVyaSkge1xuICAgIG9wdHMgPSB1cmk7XG4gICAgdXJpID0gbnVsbDtcbiAgfVxuXG4gIGlmICh1cmkpIHtcbiAgICB1cmkgPSBwYXJzZXVyaSh1cmkpO1xuICAgIG9wdHMuaG9zdG5hbWUgPSB1cmkuaG9zdDtcbiAgICBvcHRzLnNlY3VyZSA9IHVyaS5wcm90b2NvbCA9PT0gJ2h0dHBzJyB8fCB1cmkucHJvdG9jb2wgPT09ICd3c3MnO1xuICAgIG9wdHMucG9ydCA9IHVyaS5wb3J0O1xuICAgIGlmICh1cmkucXVlcnkpIG9wdHMucXVlcnkgPSB1cmkucXVlcnk7XG4gIH0gZWxzZSBpZiAob3B0cy5ob3N0KSB7XG4gICAgb3B0cy5ob3N0bmFtZSA9IHBhcnNldXJpKG9wdHMuaG9zdCkuaG9zdDtcbiAgfVxuXG4gIHRoaXMuc2VjdXJlID0gbnVsbCAhPSBvcHRzLnNlY3VyZSA/IG9wdHMuc2VjdXJlXG4gICAgOiAoZ2xvYmFsLmxvY2F0aW9uICYmICdodHRwczonID09PSBsb2NhdGlvbi5wcm90b2NvbCk7XG5cbiAgaWYgKG9wdHMuaG9zdG5hbWUgJiYgIW9wdHMucG9ydCkge1xuICAgIC8vIGlmIG5vIHBvcnQgaXMgc3BlY2lmaWVkIG1hbnVhbGx5LCB1c2UgdGhlIHByb3RvY29sIGRlZmF1bHRcbiAgICBvcHRzLnBvcnQgPSB0aGlzLnNlY3VyZSA/ICc0NDMnIDogJzgwJztcbiAgfVxuXG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50IHx8IGZhbHNlO1xuICB0aGlzLmhvc3RuYW1lID0gb3B0cy5ob3N0bmFtZSB8fFxuICAgIChnbG9iYWwubG9jYXRpb24gPyBsb2NhdGlvbi5ob3N0bmFtZSA6ICdsb2NhbGhvc3QnKTtcbiAgdGhpcy5wb3J0ID0gb3B0cy5wb3J0IHx8IChnbG9iYWwubG9jYXRpb24gJiYgbG9jYXRpb24ucG9ydFxuICAgICAgPyBsb2NhdGlvbi5wb3J0XG4gICAgICA6ICh0aGlzLnNlY3VyZSA/IDQ0MyA6IDgwKSk7XG4gIHRoaXMucXVlcnkgPSBvcHRzLnF1ZXJ5IHx8IHt9O1xuICBpZiAoJ3N0cmluZycgPT09IHR5cGVvZiB0aGlzLnF1ZXJ5KSB0aGlzLnF1ZXJ5ID0gcGFyc2Vxcy5kZWNvZGUodGhpcy5xdWVyeSk7XG4gIHRoaXMudXBncmFkZSA9IGZhbHNlICE9PSBvcHRzLnVwZ3JhZGU7XG4gIHRoaXMucGF0aCA9IChvcHRzLnBhdGggfHwgJy9lbmdpbmUuaW8nKS5yZXBsYWNlKC9cXC8kLywgJycpICsgJy8nO1xuICB0aGlzLmZvcmNlSlNPTlAgPSAhIW9wdHMuZm9yY2VKU09OUDtcbiAgdGhpcy5qc29ucCA9IGZhbHNlICE9PSBvcHRzLmpzb25wO1xuICB0aGlzLmZvcmNlQmFzZTY0ID0gISFvcHRzLmZvcmNlQmFzZTY0O1xuICB0aGlzLmVuYWJsZXNYRFIgPSAhIW9wdHMuZW5hYmxlc1hEUjtcbiAgdGhpcy50aW1lc3RhbXBQYXJhbSA9IG9wdHMudGltZXN0YW1wUGFyYW0gfHwgJ3QnO1xuICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgdGhpcy50cmFuc3BvcnRzID0gb3B0cy50cmFuc3BvcnRzIHx8IFsncG9sbGluZycsICd3ZWJzb2NrZXQnXTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gIHRoaXMud3JpdGVCdWZmZXIgPSBbXTtcbiAgdGhpcy5wcmV2QnVmZmVyTGVuID0gMDtcbiAgdGhpcy5wb2xpY3lQb3J0ID0gb3B0cy5wb2xpY3lQb3J0IHx8IDg0MztcbiAgdGhpcy5yZW1lbWJlclVwZ3JhZGUgPSBvcHRzLnJlbWVtYmVyVXBncmFkZSB8fCBmYWxzZTtcbiAgdGhpcy5iaW5hcnlUeXBlID0gbnVsbDtcbiAgdGhpcy5vbmx5QmluYXJ5VXBncmFkZXMgPSBvcHRzLm9ubHlCaW5hcnlVcGdyYWRlcztcbiAgdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZSA9IGZhbHNlICE9PSBvcHRzLnBlck1lc3NhZ2VEZWZsYXRlID8gKG9wdHMucGVyTWVzc2FnZURlZmxhdGUgfHwge30pIDogZmFsc2U7XG5cbiAgaWYgKHRydWUgPT09IHRoaXMucGVyTWVzc2FnZURlZmxhdGUpIHRoaXMucGVyTWVzc2FnZURlZmxhdGUgPSB7fTtcbiAgaWYgKHRoaXMucGVyTWVzc2FnZURlZmxhdGUgJiYgbnVsbCA9PSB0aGlzLnBlck1lc3NhZ2VEZWZsYXRlLnRocmVzaG9sZCkge1xuICAgIHRoaXMucGVyTWVzc2FnZURlZmxhdGUudGhyZXNob2xkID0gMTAyNDtcbiAgfVxuXG4gIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLnBmeCA9IG9wdHMucGZ4IHx8IG51bGw7XG4gIHRoaXMua2V5ID0gb3B0cy5rZXkgfHwgbnVsbDtcbiAgdGhpcy5wYXNzcGhyYXNlID0gb3B0cy5wYXNzcGhyYXNlIHx8IG51bGw7XG4gIHRoaXMuY2VydCA9IG9wdHMuY2VydCB8fCBudWxsO1xuICB0aGlzLmNhID0gb3B0cy5jYSB8fCBudWxsO1xuICB0aGlzLmNpcGhlcnMgPSBvcHRzLmNpcGhlcnMgfHwgbnVsbDtcbiAgdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQgPSBvcHRzLnJlamVjdFVuYXV0aG9yaXplZCA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IG9wdHMucmVqZWN0VW5hdXRob3JpemVkO1xuICB0aGlzLmZvcmNlTm9kZSA9ICEhb3B0cy5mb3JjZU5vZGU7XG5cbiAgLy8gb3RoZXIgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgdmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09PSAnb2JqZWN0JyAmJiBnbG9iYWw7XG4gIGlmIChmcmVlR2xvYmFsLmdsb2JhbCA9PT0gZnJlZUdsb2JhbCkge1xuICAgIGlmIChvcHRzLmV4dHJhSGVhZGVycyAmJiBPYmplY3Qua2V5cyhvcHRzLmV4dHJhSGVhZGVycykubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5leHRyYUhlYWRlcnMgPSBvcHRzLmV4dHJhSGVhZGVycztcbiAgICB9XG5cbiAgICBpZiAob3B0cy5sb2NhbEFkZHJlc3MpIHtcbiAgICAgIHRoaXMubG9jYWxBZGRyZXNzID0gb3B0cy5sb2NhbEFkZHJlc3M7XG4gICAgfVxuICB9XG5cbiAgLy8gc2V0IG9uIGhhbmRzaGFrZVxuICB0aGlzLmlkID0gbnVsbDtcbiAgdGhpcy51cGdyYWRlcyA9IG51bGw7XG4gIHRoaXMucGluZ0ludGVydmFsID0gbnVsbDtcbiAgdGhpcy5waW5nVGltZW91dCA9IG51bGw7XG5cbiAgLy8gc2V0IG9uIGhlYXJ0YmVhdFxuICB0aGlzLnBpbmdJbnRlcnZhbFRpbWVyID0gbnVsbDtcbiAgdGhpcy5waW5nVGltZW91dFRpbWVyID0gbnVsbDtcblxuICB0aGlzLm9wZW4oKTtcbn1cblxuU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuXG4vKipcbiAqIE1peCBpbiBgRW1pdHRlcmAuXG4gKi9cblxuRW1pdHRlcihTb2NrZXQucHJvdG90eXBlKTtcblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sOyAvLyB0aGlzIGlzIGFuIGludFxuXG4vKipcbiAqIEV4cG9zZSBkZXBzIGZvciBsZWdhY3kgY29tcGF0aWJpbGl0eVxuICogYW5kIHN0YW5kYWxvbmUgYnJvd3NlciBhY2Nlc3MuXG4gKi9cblxuU29ja2V0LlNvY2tldCA9IFNvY2tldDtcblNvY2tldC5UcmFuc3BvcnQgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpO1xuU29ja2V0LnRyYW5zcG9ydHMgPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMvaW5kZXgnKTtcblNvY2tldC5wYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyB0cmFuc3BvcnQgb2YgdGhlIGdpdmVuIHR5cGUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHRyYW5zcG9ydCBuYW1lXG4gKiBAcmV0dXJuIHtUcmFuc3BvcnR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNyZWF0ZVRyYW5zcG9ydCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlYnVnKCdjcmVhdGluZyB0cmFuc3BvcnQgXCIlc1wiJywgbmFtZSk7XG4gIHZhciBxdWVyeSA9IGNsb25lKHRoaXMucXVlcnkpO1xuXG4gIC8vIGFwcGVuZCBlbmdpbmUuaW8gcHJvdG9jb2wgaWRlbnRpZmllclxuICBxdWVyeS5FSU8gPSBwYXJzZXIucHJvdG9jb2w7XG5cbiAgLy8gdHJhbnNwb3J0IG5hbWVcbiAgcXVlcnkudHJhbnNwb3J0ID0gbmFtZTtcblxuICAvLyBzZXNzaW9uIGlkIGlmIHdlIGFscmVhZHkgaGF2ZSBvbmVcbiAgaWYgKHRoaXMuaWQpIHF1ZXJ5LnNpZCA9IHRoaXMuaWQ7XG5cbiAgdmFyIHRyYW5zcG9ydCA9IG5ldyB0cmFuc3BvcnRzW25hbWVdKHtcbiAgICBhZ2VudDogdGhpcy5hZ2VudCxcbiAgICBob3N0bmFtZTogdGhpcy5ob3N0bmFtZSxcbiAgICBwb3J0OiB0aGlzLnBvcnQsXG4gICAgc2VjdXJlOiB0aGlzLnNlY3VyZSxcbiAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgcXVlcnk6IHF1ZXJ5LFxuICAgIGZvcmNlSlNPTlA6IHRoaXMuZm9yY2VKU09OUCxcbiAgICBqc29ucDogdGhpcy5qc29ucCxcbiAgICBmb3JjZUJhc2U2NDogdGhpcy5mb3JjZUJhc2U2NCxcbiAgICBlbmFibGVzWERSOiB0aGlzLmVuYWJsZXNYRFIsXG4gICAgdGltZXN0YW1wUmVxdWVzdHM6IHRoaXMudGltZXN0YW1wUmVxdWVzdHMsXG4gICAgdGltZXN0YW1wUGFyYW06IHRoaXMudGltZXN0YW1wUGFyYW0sXG4gICAgcG9saWN5UG9ydDogdGhpcy5wb2xpY3lQb3J0LFxuICAgIHNvY2tldDogdGhpcyxcbiAgICBwZng6IHRoaXMucGZ4LFxuICAgIGtleTogdGhpcy5rZXksXG4gICAgcGFzc3BocmFzZTogdGhpcy5wYXNzcGhyYXNlLFxuICAgIGNlcnQ6IHRoaXMuY2VydCxcbiAgICBjYTogdGhpcy5jYSxcbiAgICBjaXBoZXJzOiB0aGlzLmNpcGhlcnMsXG4gICAgcmVqZWN0VW5hdXRob3JpemVkOiB0aGlzLnJlamVjdFVuYXV0aG9yaXplZCxcbiAgICBwZXJNZXNzYWdlRGVmbGF0ZTogdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZSxcbiAgICBleHRyYUhlYWRlcnM6IHRoaXMuZXh0cmFIZWFkZXJzLFxuICAgIGZvcmNlTm9kZTogdGhpcy5mb3JjZU5vZGUsXG4gICAgbG9jYWxBZGRyZXNzOiB0aGlzLmxvY2FsQWRkcmVzc1xuICB9KTtcblxuICByZXR1cm4gdHJhbnNwb3J0O1xufTtcblxuZnVuY3Rpb24gY2xvbmUgKG9iaikge1xuICB2YXIgbyA9IHt9O1xuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgIG9baV0gPSBvYmpbaV07XG4gICAgfVxuICB9XG4gIHJldHVybiBvO1xufVxuXG4vKipcbiAqIEluaXRpYWxpemVzIHRyYW5zcG9ydCB0byB1c2UgYW5kIHN0YXJ0cyBwcm9iZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuU29ja2V0LnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdHJhbnNwb3J0O1xuICBpZiAodGhpcy5yZW1lbWJlclVwZ3JhZGUgJiYgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyAmJiB0aGlzLnRyYW5zcG9ydHMuaW5kZXhPZignd2Vic29ja2V0JykgIT09IC0xKSB7XG4gICAgdHJhbnNwb3J0ID0gJ3dlYnNvY2tldCc7XG4gIH0gZWxzZSBpZiAoMCA9PT0gdGhpcy50cmFuc3BvcnRzLmxlbmd0aCkge1xuICAgIC8vIEVtaXQgZXJyb3Igb24gbmV4dCB0aWNrIHNvIGl0IGNhbiBiZSBsaXN0ZW5lZCB0b1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCAnTm8gdHJhbnNwb3J0cyBhdmFpbGFibGUnKTtcbiAgICB9LCAwKTtcbiAgICByZXR1cm47XG4gIH0gZWxzZSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy50cmFuc3BvcnRzWzBdO1xuICB9XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcblxuICAvLyBSZXRyeSB3aXRoIHRoZSBuZXh0IHRyYW5zcG9ydCBpZiB0aGUgdHJhbnNwb3J0IGlzIGRpc2FibGVkIChqc29ucDogZmFsc2UpXG4gIHRyeSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy5jcmVhdGVUcmFuc3BvcnQodHJhbnNwb3J0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRoaXMudHJhbnNwb3J0cy5zaGlmdCgpO1xuICAgIHRoaXMub3BlbigpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyYW5zcG9ydC5vcGVuKCk7XG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGN1cnJlbnQgdHJhbnNwb3J0LiBEaXNhYmxlcyB0aGUgZXhpc3Rpbmcgb25lIChpZiBhbnkpLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24gKHRyYW5zcG9ydCkge1xuICBkZWJ1Zygnc2V0dGluZyB0cmFuc3BvcnQgJXMnLCB0cmFuc3BvcnQubmFtZSk7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAodGhpcy50cmFuc3BvcnQpIHtcbiAgICBkZWJ1ZygnY2xlYXJpbmcgZXhpc3RpbmcgdHJhbnNwb3J0ICVzJywgdGhpcy50cmFuc3BvcnQubmFtZSk7XG4gICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gIH1cblxuICAvLyBzZXQgdXAgdHJhbnNwb3J0XG4gIHRoaXMudHJhbnNwb3J0ID0gdHJhbnNwb3J0O1xuXG4gIC8vIHNldCB1cCB0cmFuc3BvcnQgbGlzdGVuZXJzXG4gIHRyYW5zcG9ydFxuICAub24oJ2RyYWluJywgZnVuY3Rpb24gKCkge1xuICAgIHNlbGYub25EcmFpbigpO1xuICB9KVxuICAub24oJ3BhY2tldCcsIGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgICBzZWxmLm9uUGFja2V0KHBhY2tldCk7XG4gIH0pXG4gIC5vbignZXJyb3InLCBmdW5jdGlvbiAoZSkge1xuICAgIHNlbGYub25FcnJvcihlKTtcbiAgfSlcbiAgLm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtcbiAgICBzZWxmLm9uQ2xvc2UoJ3RyYW5zcG9ydCBjbG9zZScpO1xuICB9KTtcbn07XG5cbi8qKlxuICogUHJvYmVzIGEgdHJhbnNwb3J0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0cmFuc3BvcnQgbmFtZVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5wcm9iZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlYnVnKCdwcm9iaW5nIHRyYW5zcG9ydCBcIiVzXCInLCBuYW1lKTtcbiAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuY3JlYXRlVHJhbnNwb3J0KG5hbWUsIHsgcHJvYmU6IDEgfSk7XG4gIHZhciBmYWlsZWQgPSBmYWxzZTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIFNvY2tldC5wcmlvcldlYnNvY2tldFN1Y2Nlc3MgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBvblRyYW5zcG9ydE9wZW4gKCkge1xuICAgIGlmIChzZWxmLm9ubHlCaW5hcnlVcGdyYWRlcykge1xuICAgICAgdmFyIHVwZ3JhZGVMb3Nlc0JpbmFyeSA9ICF0aGlzLnN1cHBvcnRzQmluYXJ5ICYmIHNlbGYudHJhbnNwb3J0LnN1cHBvcnRzQmluYXJ5O1xuICAgICAgZmFpbGVkID0gZmFpbGVkIHx8IHVwZ3JhZGVMb3Nlc0JpbmFyeTtcbiAgICB9XG4gICAgaWYgKGZhaWxlZCkgcmV0dXJuO1xuXG4gICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgb3BlbmVkJywgbmFtZSk7XG4gICAgdHJhbnNwb3J0LnNlbmQoW3sgdHlwZTogJ3BpbmcnLCBkYXRhOiAncHJvYmUnIH1dKTtcbiAgICB0cmFuc3BvcnQub25jZSgncGFja2V0JywgZnVuY3Rpb24gKG1zZykge1xuICAgICAgaWYgKGZhaWxlZCkgcmV0dXJuO1xuICAgICAgaWYgKCdwb25nJyA9PT0gbXNnLnR5cGUgJiYgJ3Byb2JlJyA9PT0gbXNnLmRhdGEpIHtcbiAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgcG9uZycsIG5hbWUpO1xuICAgICAgICBzZWxmLnVwZ3JhZGluZyA9IHRydWU7XG4gICAgICAgIHNlbGYuZW1pdCgndXBncmFkaW5nJywgdHJhbnNwb3J0KTtcbiAgICAgICAgaWYgKCF0cmFuc3BvcnQpIHJldHVybjtcbiAgICAgICAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9ICd3ZWJzb2NrZXQnID09PSB0cmFuc3BvcnQubmFtZTtcblxuICAgICAgICBkZWJ1ZygncGF1c2luZyBjdXJyZW50IHRyYW5zcG9ydCBcIiVzXCInLCBzZWxmLnRyYW5zcG9ydC5uYW1lKTtcbiAgICAgICAgc2VsZi50cmFuc3BvcnQucGF1c2UoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmIChmYWlsZWQpIHJldHVybjtcbiAgICAgICAgICBpZiAoJ2Nsb3NlZCcgPT09IHNlbGYucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICAgIGRlYnVnKCdjaGFuZ2luZyB0cmFuc3BvcnQgYW5kIHNlbmRpbmcgdXBncmFkZSBwYWNrZXQnKTtcblxuICAgICAgICAgIGNsZWFudXAoKTtcblxuICAgICAgICAgIHNlbGYuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG4gICAgICAgICAgdHJhbnNwb3J0LnNlbmQoW3sgdHlwZTogJ3VwZ3JhZGUnIH1dKTtcbiAgICAgICAgICBzZWxmLmVtaXQoJ3VwZ3JhZGUnLCB0cmFuc3BvcnQpO1xuICAgICAgICAgIHRyYW5zcG9ydCA9IG51bGw7XG4gICAgICAgICAgc2VsZi51cGdyYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLmZsdXNoKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgZmFpbGVkJywgbmFtZSk7XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3Byb2JlIGVycm9yJyk7XG4gICAgICAgIGVyci50cmFuc3BvcnQgPSB0cmFuc3BvcnQubmFtZTtcbiAgICAgICAgc2VsZi5lbWl0KCd1cGdyYWRlRXJyb3InLCBlcnIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZnJlZXplVHJhbnNwb3J0ICgpIHtcbiAgICBpZiAoZmFpbGVkKSByZXR1cm47XG5cbiAgICAvLyBBbnkgY2FsbGJhY2sgY2FsbGVkIGJ5IHRyYW5zcG9ydCBzaG91bGQgYmUgaWdub3JlZCBzaW5jZSBub3dcbiAgICBmYWlsZWQgPSB0cnVlO1xuXG4gICAgY2xlYW51cCgpO1xuXG4gICAgdHJhbnNwb3J0LmNsb3NlKCk7XG4gICAgdHJhbnNwb3J0ID0gbnVsbDtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhbnkgZXJyb3IgdGhhdCBoYXBwZW5zIHdoaWxlIHByb2JpbmdcbiAgZnVuY3Rpb24gb25lcnJvciAoZXJyKSB7XG4gICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdwcm9iZSBlcnJvcjogJyArIGVycik7XG4gICAgZXJyb3IudHJhbnNwb3J0ID0gdHJhbnNwb3J0Lm5hbWU7XG5cbiAgICBmcmVlemVUcmFuc3BvcnQoKTtcblxuICAgIGRlYnVnKCdwcm9iZSB0cmFuc3BvcnQgXCIlc1wiIGZhaWxlZCBiZWNhdXNlIG9mIGVycm9yOiAlcycsIG5hbWUsIGVycik7XG5cbiAgICBzZWxmLmVtaXQoJ3VwZ3JhZGVFcnJvcicsIGVycm9yKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVHJhbnNwb3J0Q2xvc2UgKCkge1xuICAgIG9uZXJyb3IoJ3RyYW5zcG9ydCBjbG9zZWQnKTtcbiAgfVxuXG4gIC8vIFdoZW4gdGhlIHNvY2tldCBpcyBjbG9zZWQgd2hpbGUgd2UncmUgcHJvYmluZ1xuICBmdW5jdGlvbiBvbmNsb3NlICgpIHtcbiAgICBvbmVycm9yKCdzb2NrZXQgY2xvc2VkJyk7XG4gIH1cblxuICAvLyBXaGVuIHRoZSBzb2NrZXQgaXMgdXBncmFkZWQgd2hpbGUgd2UncmUgcHJvYmluZ1xuICBmdW5jdGlvbiBvbnVwZ3JhZGUgKHRvKSB7XG4gICAgaWYgKHRyYW5zcG9ydCAmJiB0by5uYW1lICE9PSB0cmFuc3BvcnQubmFtZSkge1xuICAgICAgZGVidWcoJ1wiJXNcIiB3b3JrcyAtIGFib3J0aW5nIFwiJXNcIicsIHRvLm5hbWUsIHRyYW5zcG9ydC5uYW1lKTtcbiAgICAgIGZyZWV6ZVRyYW5zcG9ydCgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIG9uIHRoZSB0cmFuc3BvcnQgYW5kIG9uIHNlbGZcbiAgZnVuY3Rpb24gY2xlYW51cCAoKSB7XG4gICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdvcGVuJywgb25UcmFuc3BvcnRPcGVuKTtcbiAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uVHJhbnNwb3J0Q2xvc2UpO1xuICAgIHNlbGYucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkaW5nJywgb251cGdyYWRlKTtcbiAgfVxuXG4gIHRyYW5zcG9ydC5vbmNlKCdvcGVuJywgb25UcmFuc3BvcnRPcGVuKTtcbiAgdHJhbnNwb3J0Lm9uY2UoJ2Vycm9yJywgb25lcnJvcik7XG4gIHRyYW5zcG9ydC5vbmNlKCdjbG9zZScsIG9uVHJhbnNwb3J0Q2xvc2UpO1xuXG4gIHRoaXMub25jZSgnY2xvc2UnLCBvbmNsb3NlKTtcbiAgdGhpcy5vbmNlKCd1cGdyYWRpbmcnLCBvbnVwZ3JhZGUpO1xuXG4gIHRyYW5zcG9ydC5vcGVuKCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aGVuIGNvbm5lY3Rpb24gaXMgZGVlbWVkIG9wZW4uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgZGVidWcoJ3NvY2tldCBvcGVuJyk7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuJztcbiAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9ICd3ZWJzb2NrZXQnID09PSB0aGlzLnRyYW5zcG9ydC5uYW1lO1xuICB0aGlzLmVtaXQoJ29wZW4nKTtcbiAgdGhpcy5mbHVzaCgpO1xuXG4gIC8vIHdlIGNoZWNrIGZvciBgcmVhZHlTdGF0ZWAgaW4gY2FzZSBhbiBgb3BlbmBcbiAgLy8gbGlzdGVuZXIgYWxyZWFkeSBjbG9zZWQgdGhlIHNvY2tldFxuICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgJiYgdGhpcy51cGdyYWRlICYmIHRoaXMudHJhbnNwb3J0LnBhdXNlKSB7XG4gICAgZGVidWcoJ3N0YXJ0aW5nIHVwZ3JhZGUgcHJvYmVzJyk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLnVwZ3JhZGVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdGhpcy5wcm9iZSh0aGlzLnVwZ3JhZGVzW2ldKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogSGFuZGxlcyBhIHBhY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uUGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICBpZiAoJ29wZW5pbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgfHxcbiAgICAgICdjbG9zaW5nJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgZGVidWcoJ3NvY2tldCByZWNlaXZlOiB0eXBlIFwiJXNcIiwgZGF0YSBcIiVzXCInLCBwYWNrZXQudHlwZSwgcGFja2V0LmRhdGEpO1xuXG4gICAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xuXG4gICAgLy8gU29ja2V0IGlzIGxpdmUgLSBhbnkgcGFja2V0IGNvdW50c1xuICAgIHRoaXMuZW1pdCgnaGVhcnRiZWF0Jyk7XG5cbiAgICBzd2l0Y2ggKHBhY2tldC50eXBlKSB7XG4gICAgICBjYXNlICdvcGVuJzpcbiAgICAgICAgdGhpcy5vbkhhbmRzaGFrZShwYXJzZWpzb24ocGFja2V0LmRhdGEpKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3BvbmcnOlxuICAgICAgICB0aGlzLnNldFBpbmcoKTtcbiAgICAgICAgdGhpcy5lbWl0KCdwb25nJyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3NlcnZlciBlcnJvcicpO1xuICAgICAgICBlcnIuY29kZSA9IHBhY2tldC5kYXRhO1xuICAgICAgICB0aGlzLm9uRXJyb3IoZXJyKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ21lc3NhZ2UnOlxuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBwYWNrZXQuZGF0YSk7XG4gICAgICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIHBhY2tldC5kYXRhKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGRlYnVnKCdwYWNrZXQgcmVjZWl2ZWQgd2l0aCBzb2NrZXQgcmVhZHlTdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGhhbmRzaGFrZSBjb21wbGV0aW9uLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBoYW5kc2hha2Ugb2JqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uSGFuZHNoYWtlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5lbWl0KCdoYW5kc2hha2UnLCBkYXRhKTtcbiAgdGhpcy5pZCA9IGRhdGEuc2lkO1xuICB0aGlzLnRyYW5zcG9ydC5xdWVyeS5zaWQgPSBkYXRhLnNpZDtcbiAgdGhpcy51cGdyYWRlcyA9IHRoaXMuZmlsdGVyVXBncmFkZXMoZGF0YS51cGdyYWRlcyk7XG4gIHRoaXMucGluZ0ludGVydmFsID0gZGF0YS5waW5nSW50ZXJ2YWw7XG4gIHRoaXMucGluZ1RpbWVvdXQgPSBkYXRhLnBpbmdUaW1lb3V0O1xuICB0aGlzLm9uT3BlbigpO1xuICAvLyBJbiBjYXNlIG9wZW4gaGFuZGxlciBjbG9zZXMgc29ja2V0XG4gIGlmICgnY2xvc2VkJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSByZXR1cm47XG4gIHRoaXMuc2V0UGluZygpO1xuXG4gIC8vIFByb2xvbmcgbGl2ZW5lc3Mgb2Ygc29ja2V0IG9uIGhlYXJ0YmVhdFxuICB0aGlzLnJlbW92ZUxpc3RlbmVyKCdoZWFydGJlYXQnLCB0aGlzLm9uSGVhcnRiZWF0KTtcbiAgdGhpcy5vbignaGVhcnRiZWF0JywgdGhpcy5vbkhlYXJ0YmVhdCk7XG59O1xuXG4vKipcbiAqIFJlc2V0cyBwaW5nIHRpbWVvdXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkhlYXJ0YmVhdCA9IGZ1bmN0aW9uICh0aW1lb3V0KSB7XG4gIGNsZWFyVGltZW91dCh0aGlzLnBpbmdUaW1lb3V0VGltZXIpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHNlbGYucGluZ1RpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGlmICgnY2xvc2VkJyA9PT0gc2VsZi5yZWFkeVN0YXRlKSByZXR1cm47XG4gICAgc2VsZi5vbkNsb3NlKCdwaW5nIHRpbWVvdXQnKTtcbiAgfSwgdGltZW91dCB8fCAoc2VsZi5waW5nSW50ZXJ2YWwgKyBzZWxmLnBpbmdUaW1lb3V0KSk7XG59O1xuXG4vKipcbiAqIFBpbmdzIHNlcnZlciBldmVyeSBgdGhpcy5waW5nSW50ZXJ2YWxgIGFuZCBleHBlY3RzIHJlc3BvbnNlXG4gKiB3aXRoaW4gYHRoaXMucGluZ1RpbWVvdXRgIG9yIGNsb3NlcyBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2V0UGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBjbGVhclRpbWVvdXQoc2VsZi5waW5nSW50ZXJ2YWxUaW1lcik7XG4gIHNlbGYucGluZ0ludGVydmFsVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JpdGluZyBwaW5nIHBhY2tldCAtIGV4cGVjdGluZyBwb25nIHdpdGhpbiAlc21zJywgc2VsZi5waW5nVGltZW91dCk7XG4gICAgc2VsZi5waW5nKCk7XG4gICAgc2VsZi5vbkhlYXJ0YmVhdChzZWxmLnBpbmdUaW1lb3V0KTtcbiAgfSwgc2VsZi5waW5nSW50ZXJ2YWwpO1xufTtcblxuLyoqXG4qIFNlbmRzIGEgcGluZyBwYWNrZXQuXG4qXG4qIEBhcGkgcHJpdmF0ZVxuKi9cblxuU29ja2V0LnByb3RvdHlwZS5waW5nID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuc2VuZFBhY2tldCgncGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBzZWxmLmVtaXQoJ3BpbmcnKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIENhbGxlZCBvbiBgZHJhaW5gIGV2ZW50XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkRyYWluID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLndyaXRlQnVmZmVyLnNwbGljZSgwLCB0aGlzLnByZXZCdWZmZXJMZW4pO1xuXG4gIC8vIHNldHRpbmcgcHJldkJ1ZmZlckxlbiA9IDAgaXMgdmVyeSBpbXBvcnRhbnRcbiAgLy8gZm9yIGV4YW1wbGUsIHdoZW4gdXBncmFkaW5nLCB1cGdyYWRlIHBhY2tldCBpcyBzZW50IG92ZXIsXG4gIC8vIGFuZCBhIG5vbnplcm8gcHJldkJ1ZmZlckxlbiBjb3VsZCBjYXVzZSBwcm9ibGVtcyBvbiBgZHJhaW5gXG4gIHRoaXMucHJldkJ1ZmZlckxlbiA9IDA7XG5cbiAgaWYgKDAgPT09IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgdGhpcy5lbWl0KCdkcmFpbicpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuZmx1c2goKTtcbiAgfVxufTtcblxuLyoqXG4gKiBGbHVzaCB3cml0ZSBidWZmZXJzLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnY2xvc2VkJyAhPT0gdGhpcy5yZWFkeVN0YXRlICYmIHRoaXMudHJhbnNwb3J0LndyaXRhYmxlICYmXG4gICAgIXRoaXMudXBncmFkaW5nICYmIHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgZGVidWcoJ2ZsdXNoaW5nICVkIHBhY2tldHMgaW4gc29ja2V0JywgdGhpcy53cml0ZUJ1ZmZlci5sZW5ndGgpO1xuICAgIHRoaXMudHJhbnNwb3J0LnNlbmQodGhpcy53cml0ZUJ1ZmZlcik7XG4gICAgLy8ga2VlcCB0cmFjayBvZiBjdXJyZW50IGxlbmd0aCBvZiB3cml0ZUJ1ZmZlclxuICAgIC8vIHNwbGljZSB3cml0ZUJ1ZmZlciBhbmQgY2FsbGJhY2tCdWZmZXIgb24gYGRyYWluYFxuICAgIHRoaXMucHJldkJ1ZmZlckxlbiA9IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoO1xuICAgIHRoaXMuZW1pdCgnZmx1c2gnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZW5kcyBhIG1lc3NhZ2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQHJldHVybiB7U29ja2V0fSBmb3IgY2hhaW5pbmcuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUud3JpdGUgPVxuU29ja2V0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKG1zZywgb3B0aW9ucywgZm4pIHtcbiAgdGhpcy5zZW5kUGFja2V0KCdtZXNzYWdlJywgbXNnLCBvcHRpb25zLCBmbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZW5kcyBhIHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFja2V0IHR5cGUuXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgZnVuY3Rpb24uXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNlbmRQYWNrZXQgPSBmdW5jdGlvbiAodHlwZSwgZGF0YSwgb3B0aW9ucywgZm4pIHtcbiAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBkYXRhKSB7XG4gICAgZm4gPSBkYXRhO1xuICAgIGRhdGEgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIG9wdGlvbnMpIHtcbiAgICBmbiA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9IG51bGw7XG4gIH1cblxuICBpZiAoJ2Nsb3NpbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ2Nsb3NlZCcgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBvcHRpb25zLmNvbXByZXNzID0gZmFsc2UgIT09IG9wdGlvbnMuY29tcHJlc3M7XG5cbiAgdmFyIHBhY2tldCA9IHtcbiAgICB0eXBlOiB0eXBlLFxuICAgIGRhdGE6IGRhdGEsXG4gICAgb3B0aW9uczogb3B0aW9uc1xuICB9O1xuICB0aGlzLmVtaXQoJ3BhY2tldENyZWF0ZScsIHBhY2tldCk7XG4gIHRoaXMud3JpdGVCdWZmZXIucHVzaChwYWNrZXQpO1xuICBpZiAoZm4pIHRoaXMub25jZSgnZmx1c2gnLCBmbik7XG4gIHRoaXMuZmx1c2goKTtcbn07XG5cbi8qKlxuICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zaW5nJztcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIGlmICh0aGlzLndyaXRlQnVmZmVyLmxlbmd0aCkge1xuICAgICAgdGhpcy5vbmNlKCdkcmFpbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMudXBncmFkaW5nKSB7XG4gICAgICAgICAgd2FpdEZvclVwZ3JhZGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudXBncmFkaW5nKSB7XG4gICAgICB3YWl0Rm9yVXBncmFkZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNsb3NlICgpIHtcbiAgICBzZWxmLm9uQ2xvc2UoJ2ZvcmNlZCBjbG9zZScpO1xuICAgIGRlYnVnKCdzb2NrZXQgY2xvc2luZyAtIHRlbGxpbmcgdHJhbnNwb3J0IHRvIGNsb3NlJyk7XG4gICAgc2VsZi50cmFuc3BvcnQuY2xvc2UoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsZWFudXBBbmRDbG9zZSAoKSB7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkZScsIGNsZWFudXBBbmRDbG9zZSk7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkZUVycm9yJywgY2xlYW51cEFuZENsb3NlKTtcbiAgICBjbG9zZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gd2FpdEZvclVwZ3JhZGUgKCkge1xuICAgIC8vIHdhaXQgZm9yIHVwZ3JhZGUgdG8gZmluaXNoIHNpbmNlIHdlIGNhbid0IHNlbmQgcGFja2V0cyB3aGlsZSBwYXVzaW5nIGEgdHJhbnNwb3J0XG4gICAgc2VsZi5vbmNlKCd1cGdyYWRlJywgY2xlYW51cEFuZENsb3NlKTtcbiAgICBzZWxmLm9uY2UoJ3VwZ3JhZGVFcnJvcicsIGNsZWFudXBBbmRDbG9zZSk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IGVycm9yXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKGVycikge1xuICBkZWJ1Zygnc29ja2V0IGVycm9yICVqJywgZXJyKTtcbiAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5vbkNsb3NlKCd0cmFuc3BvcnQgZXJyb3InLCBlcnIpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiB0cmFuc3BvcnQgY2xvc2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbiwgZGVzYykge1xuICBpZiAoJ29wZW5pbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ2Nsb3NpbmcnID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICBkZWJ1Zygnc29ja2V0IGNsb3NlIHdpdGggcmVhc29uOiBcIiVzXCInLCByZWFzb24pO1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIC8vIGNsZWFyIHRpbWVyc1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnBpbmdJbnRlcnZhbFRpbWVyKTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nVGltZW91dFRpbWVyKTtcblxuICAgIC8vIHN0b3AgZXZlbnQgZnJvbSBmaXJpbmcgYWdhaW4gZm9yIHRyYW5zcG9ydFxuICAgIHRoaXMudHJhbnNwb3J0LnJlbW92ZUFsbExpc3RlbmVycygnY2xvc2UnKTtcblxuICAgIC8vIGVuc3VyZSB0cmFuc3BvcnQgd29uJ3Qgc3RheSBvcGVuXG4gICAgdGhpcy50cmFuc3BvcnQuY2xvc2UoKTtcblxuICAgIC8vIGlnbm9yZSBmdXJ0aGVyIHRyYW5zcG9ydCBjb21tdW5pY2F0aW9uXG4gICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG5cbiAgICAvLyBzZXQgcmVhZHkgc3RhdGVcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcblxuICAgIC8vIGNsZWFyIHNlc3Npb24gaWRcbiAgICB0aGlzLmlkID0gbnVsbDtcblxuICAgIC8vIGVtaXQgY2xvc2UgZXZlbnRcbiAgICB0aGlzLmVtaXQoJ2Nsb3NlJywgcmVhc29uLCBkZXNjKTtcblxuICAgIC8vIGNsZWFuIGJ1ZmZlcnMgYWZ0ZXIsIHNvIHVzZXJzIGNhbiBzdGlsbFxuICAgIC8vIGdyYWIgdGhlIGJ1ZmZlcnMgb24gYGNsb3NlYCBldmVudFxuICAgIHNlbGYud3JpdGVCdWZmZXIgPSBbXTtcbiAgICBzZWxmLnByZXZCdWZmZXJMZW4gPSAwO1xuICB9XG59O1xuXG4vKipcbiAqIEZpbHRlcnMgdXBncmFkZXMsIHJldHVybmluZyBvbmx5IHRob3NlIG1hdGNoaW5nIGNsaWVudCB0cmFuc3BvcnRzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHNlcnZlciB1cGdyYWRlc1xuICogQGFwaSBwcml2YXRlXG4gKlxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZmlsdGVyVXBncmFkZXMgPSBmdW5jdGlvbiAodXBncmFkZXMpIHtcbiAgdmFyIGZpbHRlcmVkVXBncmFkZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGogPSB1cGdyYWRlcy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcbiAgICBpZiAofmluZGV4KHRoaXMudHJhbnNwb3J0cywgdXBncmFkZXNbaV0pKSBmaWx0ZXJlZFVwZ3JhZGVzLnB1c2godXBncmFkZXNbaV0pO1xuICB9XG4gIHJldHVybiBmaWx0ZXJlZFVwZ3JhZGVzO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0112\n")},"0352":function(module,exports,__webpack_require__){eval('// https://crossfilter.github.io/crossfilter/ v1.5.4 Copyright 2020 Mike Bostock\n!function(r,e){ true?module.exports=e():undefined}(this,(function(){"use strict";let r=o,e=o,n=o,t=f,u=i;function o(r){for(var e=new Array(r),n=-1;++n<r;)e[n]=0;return e}function f(r,e){for(var n=r.length;n<e;)r[n++]=0;return r}function i(r,e){if(e>32)throw new Error("invalid array width!");return r}function a(e){this.length=e,this.subarrays=1,this.width=8,this.masks={0:0},this[0]=r(e)}"undefined"!=typeof Uint8Array&&(r=function(r){return new Uint8Array(r)},e=function(r){return new Uint16Array(r)},n=function(r){return new Uint32Array(r)},t=function(r,e){if(r.length>=e)return r;var n=new r.constructor(e);return n.set(r),n},u=function(r,t){var u;switch(t){case 16:u=e(r.length);break;case 32:u=n(r.length);break;default:throw new Error("invalid array width!")}return u.set(r),u}),a.prototype.lengthen=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)this[e]=t(this[e],r);this.length=r},a.prototype.add=function(){var e,n,t,o,f;for(o=0,f=this.subarrays;o<f;++o)if(t=(~(e=this.masks[o])&e+1)>>>0,!((n=this.width-32*o)>=32)||t)return n<32&&t&1<<n&&(this[o]=u(this[o],n<<=1),this.width=32*o+n),this.masks[o]|=t,{offset:o,one:t};return this[this.subarrays]=r(this.length),this.masks[this.subarrays]=1,this.width+=8,{offset:this.subarrays++,one:1}},a.prototype.copy=function(r,e){var n,t;for(n=0,t=this.subarrays;n<t;++n)this[n][r]=this[n][e]},a.prototype.truncate=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)for(var t=this.length-1;t>=r;t--)this[e][t]=0;this.length=r},a.prototype.zero=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)if(this[e][r])return!1;return!0},a.prototype.zeroExcept=function(r,e,n){var t,u;for(t=0,u=this.subarrays;t<u;++t)if(t===e?this[t][r]&n:this[t][r])return!1;return!0},a.prototype.zeroExceptMask=function(r,e){var n,t;for(n=0,t=this.subarrays;n<t;++n)if(this[n][r]&e[n])return!1;return!0},a.prototype.only=function(r,e,n){var t,u;for(t=0,u=this.subarrays;t<u;++t)if(this[t][r]!=(t===e?n:0))return!1;return!0},a.prototype.onlyExcept=function(r,e,n,t,u){var o,f,i;for(f=0,i=this.subarrays;f<i;++f)if(o=this[f][r],f===e&&(o=(o&n)>>>0),o!=(f===t?u:0))return!1;return!0};var l={array8:o,array16:o,array32:o,arrayLengthen:f,arrayWiden:i,bitarray:a};var s={filterExact:(r,e)=>(function(n){var t=n.length;return[r.left(n,e,0,t),r.right(n,e,0,t)]}),filterRange:(r,e)=>{var n=e[0],t=e[1];return function(e){var u=e.length;return[r.left(e,n,0,u),r.left(e,t,0,u)]}},filterAll:r=>[0,r.length]},c=r=>r,h=()=>null,v=()=>0;function p(r){function e(r,e,t){for(var u=t-e,o=1+(u>>>1);--o>0;)n(r,o,u,e);return r}function n(e,n,t,u){for(var o,f=e[--u+n],i=r(f);(o=n<<1)<=t&&(o<t&&r(e[u+o])>r(e[u+o+1])&&o++,!(i<=r(e[u+o])));)e[u+n]=e[u+o],n=o;e[u+n]=f}return e.sort=function(r,e,t){for(var u,o=t-e;--o>0;)u=r[e],r[e]=r[e+o],r[e+o]=u,n(r,1,o,e);return r},e}const d=p(c);function g(r){var e=d.by(r);return function(n,t,u,o){var f,i,a,l=new Array(o=Math.min(u-t,o));for(i=0;i<o;++i)l[i]=n[t++];if(e(l,0,o),t<u){f=r(l[0]);do{r(a=n[t])>f&&(l[0]=a,f=r(e(l,0,o)[0]))}while(++t<u)}return l}}d.by=p;const y=g(c);function x(r){function e(e,n,t,u){for(;t<u;){var o=t+u>>>1;n<r(e[o])?u=o:t=o+1}return t}return e.right=e,e.left=function(e,n,t,u){for(;t<u;){var o=t+u>>>1;r(e[o])<n?t=o+1:u=o}return t},e}y.by=g;const b=x(c);b.by=x;var m=(r,e,n)=>{for(var t=0,u=e.length,o=n?JSON.parse(JSON.stringify(r)):new Array(u);t<u;++t)o[t]=r[e[t]];return o};var E={reduceIncrement:r=>r+1,reduceDecrement:r=>r-1,reduceAdd:r=>(function(e,n){return e+ +r(n)}),reduceSubtract:r=>(function(e,n){return e-r(n)})};const w=(r,e)=>{const n=r[e];return"function"==typeof n?n.call(r):n},A=/\\[([\\w\\d]+)\\]/g;var z=(r,e)=>(function(r,e,n,t,u){for(u in t=(n=n.split(".")).splice(-1,1),n)e=e[n[u]]=e[n[u]]||{};return r(e,t)})(w,r,e.replace(A,".$1")),k=-1;function O(){var r,e={add:a,remove:function(e){for(var o=new Array(t),i=[],a="function"==typeof e,l=0,s=0;l<t;++l)c=l,(a?e(n[c],c):r.zero(c))?(i.push(l),o[l]=k):o[l]=s++;var c;u.forEach((function(r){r(-1,-1,[],i,!0)})),f.forEach((function(r){r(o)}));for(var h=0,v=0;h<t;++h)o[h]!==k&&(h!==v&&(r.copy(v,h),n[v]=n[h]),++v);n.length=t=v,r.truncate(v),g("dataRemoved")},dimension:function(e,i){if("string"==typeof e){var a=e;e=function(r){return z(r,a)}}var p,x,w,A,O,F,N,R,U,D,I,L,W,J,j={filter:function(r){return null==r?er():Array.isArray(r)?rr(r):"function"==typeof r?nr(r):_(r)},filterExact:_,filterRange:rr,filterFunction:nr,filterAll:er,currentFilter:function(){return L},hasCurrentFilter:function(){return W},top:function(e,t){var u,o=[],f=P,a=0;t&&t>0&&(a=t);for(;--f>=K&&e>0;)r.zero(u=F[f])&&(a>0?--a:(o.push(n[u]),--e));if(i)for(f=0;f<$.length&&e>0;f++)r.zero(u=$[f])&&(a>0?--a:(o.push(n[u]),--e));return o},bottom:function(e,t){var u,o,f=[],a=0;t&&t>0&&(a=t);if(i)for(u=0;u<$.length&&e>0;u++)r.zero(o=$[u])&&(a>0?--a:(f.push(n[o]),--e));u=K;for(;u<P&&e>0;)r.zero(o=F[u])&&(a>0?--a:(f.push(n[o]),--e)),u++;return f},group:ur,groupAll:function(){var r=ur(h),e=r.all;return delete r.all,delete r.top,delete r.order,delete r.orderNatural,delete r.size,r.value=function(){return e()[0].value},r},dispose:or,remove:or,accessor:e,id:function(){return A}},$=[],q=function(r){return S(r).sort((function(r,e){var n=N[r],t=N[e];return n<t?-1:n>t?1:r-e}))},B=s.filterAll,G=[],H=[],K=0,P=0,Q=0;o.unshift(V),o.push(X),f.push(Y);var T=r.add();function V(n,u,o){var f,a;if(i){Q=0,G=0,J=[];for(var s=0;s<n.length;s++)for(G=0,J=e(n[s]);G<J.length;G++)Q++;N=[],f=S(n.length),a=M(Q,1);for(var c=S(Q),h=0,v=0;v<n.length;v++)if((J=e(n[v])).length)for(f[v]=J.length,G=0;G<J.length;G++)N.push(J[G]),c[h]=v,h++;else f[v]=0,$.push(v+u);var d=q(Q);N=m(N,d),R=m(c,d)}else N=n.map(e),R=q(o),N=m(N,R);var g,y,x,b=B(N),E=b[0],A=b[1];if(i)if(o=Q,I)for(g=0;g<o;++g)I(N[g],g)||(0==--f[R[g]]&&(r[w][R[g]+u]|=p),a[g]=1);else{for(y=0;y<E;++y)0==--f[R[y]]&&(r[w][R[y]+u]|=p),a[y]=1;for(x=A;x<o;++x)0==--f[R[x]]&&(r[w][R[x]+u]|=p),a[x]=1}else if(I)for(g=0;g<o;++g)I(N[g],g)||(r[w][R[g]+u]|=p);else{for(y=0;y<E;++y)r[w][R[y]+u]|=p;for(x=A;x<o;++x)r[w][R[x]+u]|=p}if(!u)return O=N,F=R,U=f,D=a,K=E,void(P=A);var z,k=O,C=F,L=D,W=0;if(s=0,i&&(z=u,u=k.length,o=Q),O=new Array(i?u+o:t),F=i?new Array(u+o):M(t,t),i&&(D=M(u+o,1)),i){var j=U.length;U=l.arrayLengthen(U,t);for(var G=0;G+j<t;G++)U[G+j]=f[G]}for(var H=0;s<u&&W<o;++H)k[s]<N[W]?(O[H]=k[s],i&&(D[H]=L[s]),F[H]=C[s++]):(O[H]=N[W],i&&(D[H]=a[W]),F[H]=R[W++]+(i?z:u));for(;s<u;++s,++H)O[H]=k[s],i&&(D[H]=L[s]),F[H]=C[s];for(;W<o;++W,++H)O[H]=N[W],i&&(D[H]=a[W]),F[H]=R[W]+(i?z:u);b=B(O),K=b[0],P=b[1]}function X(r,e,n){G.forEach((function(r){r(N,R,e,n)})),N=R=null}function Y(r){if(i){for(var e=0,n=0;e<$.length;e++)r[$[e]]!==k&&($[n]=r[$[e]],n++);for($.length=n,e=0,n=0;e<t;e++)r[e]!==k&&(n!==e&&(U[n]=U[e]),n++);U=U.slice(0,n)}for(var u,o=O.length,f=0,a=0;f<o;++f)r[u=F[f]]!==k&&(f!==a&&(O[a]=O[f]),F[a]=r[u],i&&(D[a]=D[f]),++a);for(O.length=a,i&&(D=D.slice(0,a));a<o;)F[a++]=0;var l=B(O);K=l[0],P=l[1]}function Z(e){var n=e[0],t=e[1];if(I)return I=null,tr((function(r,e){return n<=e&&e<t}),0===e[0]&&e[1]===O.length),K=n,P=t,j;var o,f,a,l=[],c=[],h=[],v=[];if(n<K)for(o=n,f=Math.min(K,t);o<f;++o)l.push(F[o]),h.push(o);else if(n>K)for(o=K,f=Math.min(n,P);o<f;++o)c.push(F[o]),v.push(o);if(t>P)for(o=Math.max(n,P),f=t;o<f;++o)l.push(F[o]),h.push(o);else if(t<P)for(o=Math.max(K,t),f=P;o<f;++o)c.push(F[o]),v.push(o);if(i){var d=[],y=[];for(o=0;o<l.length;o++)U[l[o]]++,D[h[o]]=0,1===U[l[o]]&&(r[w][l[o]]^=p,d.push(l[o]));for(o=0;o<c.length;o++)U[c[o]]--,D[v[o]]=1,0===U[c[o]]&&(r[w][c[o]]^=p,y.push(c[o]));if(l=d,c=y,B===s.filterAll)for(o=0;o<$.length;o++)r[w][a=$[o]]&p&&(r[w][a]^=p,l.push(a));else for(o=0;o<$.length;o++)r[w][a=$[o]]&p||(r[w][a]^=p,c.push(a))}else{for(o=0;o<l.length;o++)r[w][l[o]]^=p;for(o=0;o<c.length;o++)r[w][c[o]]^=p}return K=n,P=t,u.forEach((function(r){r(p,w,l,c)})),g("filtered"),j}function _(r){return L=r,W=!0,Z((B=s.filterExact(b,r))(O))}function rr(r){return L=r,W=!0,Z((B=s.filterRange(b,r))(O))}function er(){return L=void 0,W=!1,Z((B=s.filterAll)(O))}function nr(r){L=r,W=!0,I=r,B=s.filterAll,tr(r,!1);var e=B(O);return K=e[0],P=e[1],j}function tr(e,n){var t,o,f,a=[],l=[],s=[],c=[],h=O.length;if(!i)for(t=0;t<h;++t)!(r[w][o=F[t]]&p)^!!(f=e(O[t],t))&&(f?a.push(o):l.push(o));if(i)for(t=0;t<h;++t)e(O[t],t)?(a.push(F[t]),s.push(t)):(l.push(F[t]),c.push(t));if(i){var v=[],d=[];for(t=0;t<a.length;t++)1===D[s[t]]&&(U[a[t]]++,D[s[t]]=0,1===U[a[t]]&&(r[w][a[t]]^=p,v.push(a[t])));for(t=0;t<l.length;t++)0===D[c[t]]&&(U[l[t]]--,D[c[t]]=1,0===U[l[t]]&&(r[w][l[t]]^=p,d.push(l[t])));if(a=v,l=d,n)for(t=0;t<$.length;t++)r[w][o=$[t]]&p&&(r[w][o]^=p,a.push(o));else for(t=0;t<$.length;t++)r[w][o=$[t]]&p||(r[w][o]^=p,l.push(o))}else{for(t=0;t<a.length;t++)r[w][a[t]]&p&&(r[w][a[t]]&=x);for(t=0;t<l.length;t++)r[w][l[t]]&p||(r[w][l[t]]|=p)}u.forEach((function(r){r(p,w,a,l)})),g("filtered")}function ur(e){var o={top:function(r){var e=g(P(),0,a.length,r);return b.sort(e,0,e.length)},all:P,reduce:Q,reduceCount:T,reduceSum:function(r){return Q(E.reduceAdd(r),E.reduceSubtract(r),v)},order:V,orderNatural:function(){return V(c)},size:function(){return U},dispose:X,remove:X};H.push(o);var a,s,g,b,m,A,z,S,N=8,R=C(N),U=0,D=h,I=h,L=!0,W=e===h;function J(o,f,c,v){i&&(S=c,c=O.length-o.length,v=o.length);var p,d,g,y,b,E,k=a,F=i?[]:M(U,R),J=m,j=A,G=z,H=U,P=0,Q=0;for(L&&(J=G=h),L&&(j=G=h),a=new Array(U),U=0,s=i?H?s:[]:H>1?l.arrayLengthen(s,t):M(t,R),H&&(g=(d=k[0]).key);Q<v&&!((y=e(o[Q]))>=y);)++Q;for(;Q<v;){for(d&&g<=y?(b=d,E=g,F[P]=U,(d=k[++P])&&(g=d.key)):(b={key:y,value:G()},E=y),a[U]=b;y<=E&&(p=f[Q]+(i?S:c),i?s[p]?s[p].push(U):s[p]=[U]:s[p]=U,b.value=J(b.value,n[p],!0),r.zeroExcept(p,w,x)||(b.value=j(b.value,n[p],!1)),!(++Q>=v));)y=e(o[Q]);V()}for(;P<H;)a[F[P]=U]=k[P++],V();if(i)for(var T=0;T<t;T++)s[T]||(s[T]=[]);if(U>P)if(i)for(P=0;P<S;++P)for(T=0;T<s[P].length;T++)s[P][T]=F[s[P][T]];else for(P=0;P<c;++P)s[P]=F[s[P]];function V(){i?U++:++U===R&&(F=l.arrayWiden(F,N<<=1),s=l.arrayWiden(s,N),R=C(N))}p=u.indexOf(D),U>1||i?(D=$,I=B):(!U&&W&&(U=1,a=[{key:null,value:G()}]),1===U?(D=q,I=K):(D=h,I=h),s=null),u[p]=D}function j(r){if(U>1||i){var e,n,o,f=U,l=a,c=M(f,f);if(i){for(e=0,o=0;e<t;++e)if(r[e]!==k){for(s[o]=s[e],n=0;n<s[o].length;n++)c[s[o][n]]=1;++o}s=s.slice(0,o)}else for(e=0,o=0;e<t;++e)r[e]!==k&&(c[s[o]=s[e]]=1,++o);for(a=[],U=0,e=0;e<f;++e)c[e]&&(c[e]=U++,a.push(l[e]));if(U>1||i)if(i)for(e=0;e<o;++e)for(n=0;n<s[e].length;++n)s[e][n]=c[s[e][n]];else for(e=0;e<o;++e)s[e]=c[s[e]];else s=null;u[u.indexOf(D)]=U>1||i?(I=B,D=$):1===U?(I=K,D=q):I=D=h}else if(1===U){if(W)return;for(var v=0;v<t;++v)if(r[v]!==k)return;a=[],U=0,u[u.indexOf(D)]=D=I=h}}function $(e,t,u,o,f){var l,c,h,v,d;if(!(e===p&&t===w||L))if(i){for(l=0,v=u.length;l<v;++l)if(r.zeroExcept(h=u[l],w,x))for(c=0;c<s[h].length;c++)(d=a[s[h][c]]).value=m(d.value,n[h],!1,c);for(l=0,v=o.length;l<v;++l)if(r.onlyExcept(h=o[l],w,x,t,e))for(c=0;c<s[h].length;c++)(d=a[s[h][c]]).value=A(d.value,n[h],f,c)}else{for(l=0,v=u.length;l<v;++l)r.zeroExcept(h=u[l],w,x)&&((d=a[s[h]]).value=m(d.value,n[h],!1));for(l=0,v=o.length;l<v;++l)r.onlyExcept(h=o[l],w,x,t,e)&&((d=a[s[h]]).value=A(d.value,n[h],f))}}function q(e,t,u,o,f){if(!(e===p&&t===w||L)){var i,l,s,c=a[0];for(i=0,s=u.length;i<s;++i)r.zeroExcept(l=u[i],w,x)&&(c.value=m(c.value,n[l],!1));for(i=0,s=o.length;i<s;++i)r.onlyExcept(l=o[i],w,x,t,e)&&(c.value=A(c.value,n[l],f))}}function B(){var e,u,o;for(e=0;e<U;++e)a[e].value=z();if(i){for(e=0;e<t;++e)for(u=0;u<s[e].length;u++)(o=a[s[e][u]]).value=m(o.value,n[e],!0,u);for(e=0;e<t;++e)if(!r.zeroExcept(e,w,x))for(u=0;u<s[e].length;u++)(o=a[s[e][u]]).value=A(o.value,n[e],!1,u)}else{for(e=0;e<t;++e)(o=a[s[e]]).value=m(o.value,n[e],!0);for(e=0;e<t;++e)r.zeroExcept(e,w,x)||((o=a[s[e]]).value=A(o.value,n[e],!1))}}function K(){var e,u=a[0];for(u.value=z(),e=0;e<t;++e)u.value=m(u.value,n[e],!0);for(e=0;e<t;++e)r.zeroExcept(e,w,x)||(u.value=A(u.value,n[e],!1))}function P(){return L&&(I(),L=!1),a}function Q(r,e,n){return m=r,A=e,z=n,L=!0,o}function T(){return Q(E.reduceIncrement,E.reduceDecrement,v)}function V(r){function e(e){return r(e.value)}return g=y.by(e),b=d.by(e),o}function X(){var r=u.indexOf(D);return r>=0&&u.splice(r,1),(r=G.indexOf(J))>=0&&G.splice(r,1),(r=f.indexOf(j))>=0&&f.splice(r,1),(r=H.indexOf(o))>=0&&H.splice(r,1),o}return arguments.length<1&&(e=c),u.push(D),G.push(J),f.push(j),J(O,F,0,t),T().orderNatural()}function or(){H.forEach((function(r){r.dispose()}));var e=o.indexOf(V);return e>=0&&o.splice(e,1),(e=o.indexOf(X))>=0&&o.splice(e,1),(e=f.indexOf(Y))>=0&&f.splice(e,1),r.masks[w]&=x,er()}return w=T.offset,p=T.one,x=~p,A=w<<7|Math.log(p)/Math.log(2),V(n,0,t),X(n,0,t),j},groupAll:function(){var e,f,i,a,l={reduce:p,reduceCount:d,reduceSum:function(r){return p(E.reduceAdd(r),E.reduceSubtract(r),v)},value:function(){s&&(function(){var u;for(e=a(),u=0;u<t;++u)e=f(e,n[u],!0),r.zero(u)||(e=i(e,n[u],!1))}(),s=!1);return e},dispose:g,remove:g},s=!0;function c(u,o){var a;if(!s)for(a=o;a<t;++a)e=f(e,n[a],!0),r.zero(a)||(e=i(e,n[a],!1))}function h(t,u,o,a,l){var c,h,v;if(!s){for(c=0,v=o.length;c<v;++c)r.zero(h=o[c])&&(e=f(e,n[h],l));for(c=0,v=a.length;c<v;++c)r.only(h=a[c],u,t)&&(e=i(e,n[h],l))}}function p(r,e,n){return f=r,i=e,a=n,s=!0,l}function d(){return p(E.reduceIncrement,E.reduceDecrement,v)}function g(){var r=u.indexOf(h);return r>=0&&u.splice(r,1),(r=o.indexOf(c))>=0&&o.splice(r,1),l}return(u.push(h),o.push(c),c(n,0),d())},size:function(){return t},all:function(){return n},allFiltered:function(e){var u=[],o=0,f=p(e||[]);for(o=0;o<t;o++)r.zeroExceptMask(o,f)&&u.push(n[o]);return u},onChange:function(r){if("function"!=typeof r)return void console.warn("onChange callback parameter must be a function!");return i.push(r),function(){i.splice(i.indexOf(r),1)}},isElementFiltered:function(e,n){var t=p(n||[]);return r.zeroExceptMask(e,t)}},n=[],t=0,u=[],o=[],f=[],i=[];function a(u){var f=t,i=u.length;return i&&(n=n.concat(u),r.lengthen(t+=i),o.forEach((function(r){r(u,f,i)})),g("dataAdded")),e}function p(e){var n,t,u,o,f=Array(r.subarrays);for(n=0;n<r.subarrays;n++)f[n]=-1;for(t=0,u=e.length;t<u;t++)f[(o=e[t].id())>>7]&=~(1<<(63&o));return f}function g(r){for(var e=0;e<i.length;e++)i[e](r)}return r=new l.bitarray(0),arguments.length?a(arguments[0]):e}function M(r,e){return(e<257?l.array8:e<65537?l.array16:l.array32)(r)}function S(r){for(var e=M(r,r),n=-1;++n<r;)e[n]=n;return e}function C(r){return 8===r?256:16===r?65536:4294967296}O.heap=d,O.heapselect=y,O.bisect=b,O.permute=m;return O.version="1.5.4",O}));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDM1Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvY3Jvc3NmaWx0ZXIyL2Nyb3NzZmlsdGVyLm1pbi5qcz82ZTBjIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIGh0dHBzOi8vY3Jvc3NmaWx0ZXIuZ2l0aHViLmlvL2Nyb3NzZmlsdGVyLyB2MS41LjQgQ29weXJpZ2h0IDIwMjAgTWlrZSBCb3N0b2NrXG4hZnVuY3Rpb24ocixlKXtcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1lKCk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShlKToocj1yfHxzZWxmKS5jcm9zc2ZpbHRlcj1lKCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7bGV0IHI9byxlPW8sbj1vLHQ9Zix1PWk7ZnVuY3Rpb24gbyhyKXtmb3IodmFyIGU9bmV3IEFycmF5KHIpLG49LTE7KytuPHI7KWVbbl09MDtyZXR1cm4gZX1mdW5jdGlvbiBmKHIsZSl7Zm9yKHZhciBuPXIubGVuZ3RoO248ZTspcltuKytdPTA7cmV0dXJuIHJ9ZnVuY3Rpb24gaShyLGUpe2lmKGU+MzIpdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBhcnJheSB3aWR0aCFcIik7cmV0dXJuIHJ9ZnVuY3Rpb24gYShlKXt0aGlzLmxlbmd0aD1lLHRoaXMuc3ViYXJyYXlzPTEsdGhpcy53aWR0aD04LHRoaXMubWFza3M9ezA6MH0sdGhpc1swXT1yKGUpfVwidW5kZWZpbmVkXCIhPXR5cGVvZiBVaW50OEFycmF5JiYocj1mdW5jdGlvbihyKXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkocil9LGU9ZnVuY3Rpb24ocil7cmV0dXJuIG5ldyBVaW50MTZBcnJheShyKX0sbj1mdW5jdGlvbihyKXtyZXR1cm4gbmV3IFVpbnQzMkFycmF5KHIpfSx0PWZ1bmN0aW9uKHIsZSl7aWYoci5sZW5ndGg+PWUpcmV0dXJuIHI7dmFyIG49bmV3IHIuY29uc3RydWN0b3IoZSk7cmV0dXJuIG4uc2V0KHIpLG59LHU9ZnVuY3Rpb24ocix0KXt2YXIgdTtzd2l0Y2godCl7Y2FzZSAxNjp1PWUoci5sZW5ndGgpO2JyZWFrO2Nhc2UgMzI6dT1uKHIubGVuZ3RoKTticmVhaztkZWZhdWx0OnRocm93IG5ldyBFcnJvcihcImludmFsaWQgYXJyYXkgd2lkdGghXCIpfXJldHVybiB1LnNldChyKSx1fSksYS5wcm90b3R5cGUubGVuZ3RoZW49ZnVuY3Rpb24ocil7dmFyIGUsbjtmb3IoZT0wLG49dGhpcy5zdWJhcnJheXM7ZTxuOysrZSl0aGlzW2VdPXQodGhpc1tlXSxyKTt0aGlzLmxlbmd0aD1yfSxhLnByb3RvdHlwZS5hZGQ9ZnVuY3Rpb24oKXt2YXIgZSxuLHQsbyxmO2ZvcihvPTAsZj10aGlzLnN1YmFycmF5cztvPGY7KytvKWlmKHQ9KH4oZT10aGlzLm1hc2tzW29dKSZlKzEpPj4+MCwhKChuPXRoaXMud2lkdGgtMzIqbyk+PTMyKXx8dClyZXR1cm4gbjwzMiYmdCYxPDxuJiYodGhpc1tvXT11KHRoaXNbb10sbjw8PTEpLHRoaXMud2lkdGg9MzIqbytuKSx0aGlzLm1hc2tzW29dfD10LHtvZmZzZXQ6byxvbmU6dH07cmV0dXJuIHRoaXNbdGhpcy5zdWJhcnJheXNdPXIodGhpcy5sZW5ndGgpLHRoaXMubWFza3NbdGhpcy5zdWJhcnJheXNdPTEsdGhpcy53aWR0aCs9OCx7b2Zmc2V0OnRoaXMuc3ViYXJyYXlzKyssb25lOjF9fSxhLnByb3RvdHlwZS5jb3B5PWZ1bmN0aW9uKHIsZSl7dmFyIG4sdDtmb3Iobj0wLHQ9dGhpcy5zdWJhcnJheXM7bjx0Oysrbil0aGlzW25dW3JdPXRoaXNbbl1bZV19LGEucHJvdG90eXBlLnRydW5jYXRlPWZ1bmN0aW9uKHIpe3ZhciBlLG47Zm9yKGU9MCxuPXRoaXMuc3ViYXJyYXlzO2U8bjsrK2UpZm9yKHZhciB0PXRoaXMubGVuZ3RoLTE7dD49cjt0LS0pdGhpc1tlXVt0XT0wO3RoaXMubGVuZ3RoPXJ9LGEucHJvdG90eXBlLnplcm89ZnVuY3Rpb24ocil7dmFyIGUsbjtmb3IoZT0wLG49dGhpcy5zdWJhcnJheXM7ZTxuOysrZSlpZih0aGlzW2VdW3JdKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS56ZXJvRXhjZXB0PWZ1bmN0aW9uKHIsZSxuKXt2YXIgdCx1O2Zvcih0PTAsdT10aGlzLnN1YmFycmF5czt0PHU7Kyt0KWlmKHQ9PT1lP3RoaXNbdF1bcl0mbjp0aGlzW3RdW3JdKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS56ZXJvRXhjZXB0TWFzaz1mdW5jdGlvbihyLGUpe3ZhciBuLHQ7Zm9yKG49MCx0PXRoaXMuc3ViYXJyYXlzO248dDsrK24paWYodGhpc1tuXVtyXSZlW25dKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS5vbmx5PWZ1bmN0aW9uKHIsZSxuKXt2YXIgdCx1O2Zvcih0PTAsdT10aGlzLnN1YmFycmF5czt0PHU7Kyt0KWlmKHRoaXNbdF1bcl0hPSh0PT09ZT9uOjApKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS5vbmx5RXhjZXB0PWZ1bmN0aW9uKHIsZSxuLHQsdSl7dmFyIG8sZixpO2ZvcihmPTAsaT10aGlzLnN1YmFycmF5cztmPGk7KytmKWlmKG89dGhpc1tmXVtyXSxmPT09ZSYmKG89KG8mbik+Pj4wKSxvIT0oZj09PXQ/dTowKSlyZXR1cm4hMTtyZXR1cm4hMH07dmFyIGw9e2FycmF5ODpvLGFycmF5MTY6byxhcnJheTMyOm8sYXJyYXlMZW5ndGhlbjpmLGFycmF5V2lkZW46aSxiaXRhcnJheTphfTt2YXIgcz17ZmlsdGVyRXhhY3Q6KHIsZSk9PihmdW5jdGlvbihuKXt2YXIgdD1uLmxlbmd0aDtyZXR1cm5bci5sZWZ0KG4sZSwwLHQpLHIucmlnaHQobixlLDAsdCldfSksZmlsdGVyUmFuZ2U6KHIsZSk9Pnt2YXIgbj1lWzBdLHQ9ZVsxXTtyZXR1cm4gZnVuY3Rpb24oZSl7dmFyIHU9ZS5sZW5ndGg7cmV0dXJuW3IubGVmdChlLG4sMCx1KSxyLmxlZnQoZSx0LDAsdSldfX0sZmlsdGVyQWxsOnI9PlswLHIubGVuZ3RoXX0sYz1yPT5yLGg9KCk9Pm51bGwsdj0oKT0+MDtmdW5jdGlvbiBwKHIpe2Z1bmN0aW9uIGUocixlLHQpe2Zvcih2YXIgdT10LWUsbz0xKyh1Pj4+MSk7LS1vPjA7KW4ocixvLHUsZSk7cmV0dXJuIHJ9ZnVuY3Rpb24gbihlLG4sdCx1KXtmb3IodmFyIG8sZj1lWy0tdStuXSxpPXIoZik7KG89bjw8MSk8PXQmJihvPHQmJnIoZVt1K29dKT5yKGVbdStvKzFdKSYmbysrLCEoaTw9cihlW3Urb10pKSk7KWVbdStuXT1lW3Urb10sbj1vO2VbdStuXT1mfXJldHVybiBlLnNvcnQ9ZnVuY3Rpb24ocixlLHQpe2Zvcih2YXIgdSxvPXQtZTstLW8+MDspdT1yW2VdLHJbZV09cltlK29dLHJbZStvXT11LG4ociwxLG8sZSk7cmV0dXJuIHJ9LGV9Y29uc3QgZD1wKGMpO2Z1bmN0aW9uIGcocil7dmFyIGU9ZC5ieShyKTtyZXR1cm4gZnVuY3Rpb24obix0LHUsbyl7dmFyIGYsaSxhLGw9bmV3IEFycmF5KG89TWF0aC5taW4odS10LG8pKTtmb3IoaT0wO2k8bzsrK2kpbFtpXT1uW3QrK107aWYoZShsLDAsbyksdDx1KXtmPXIobFswXSk7ZG97cihhPW5bdF0pPmYmJihsWzBdPWEsZj1yKGUobCwwLG8pWzBdKSl9d2hpbGUoKyt0PHUpfXJldHVybiBsfX1kLmJ5PXA7Y29uc3QgeT1nKGMpO2Z1bmN0aW9uIHgocil7ZnVuY3Rpb24gZShlLG4sdCx1KXtmb3IoO3Q8dTspe3ZhciBvPXQrdT4+PjE7bjxyKGVbb10pP3U9bzp0PW8rMX1yZXR1cm4gdH1yZXR1cm4gZS5yaWdodD1lLGUubGVmdD1mdW5jdGlvbihlLG4sdCx1KXtmb3IoO3Q8dTspe3ZhciBvPXQrdT4+PjE7cihlW29dKTxuP3Q9bysxOnU9b31yZXR1cm4gdH0sZX15LmJ5PWc7Y29uc3QgYj14KGMpO2IuYnk9eDt2YXIgbT0ocixlLG4pPT57Zm9yKHZhciB0PTAsdT1lLmxlbmd0aCxvPW4/SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyKSk6bmV3IEFycmF5KHUpO3Q8dTsrK3Qpb1t0XT1yW2VbdF1dO3JldHVybiBvfTt2YXIgRT17cmVkdWNlSW5jcmVtZW50OnI9PnIrMSxyZWR1Y2VEZWNyZW1lbnQ6cj0+ci0xLHJlZHVjZUFkZDpyPT4oZnVuY3Rpb24oZSxuKXtyZXR1cm4gZSsgK3Iobil9KSxyZWR1Y2VTdWJ0cmFjdDpyPT4oZnVuY3Rpb24oZSxuKXtyZXR1cm4gZS1yKG4pfSl9O2NvbnN0IHc9KHIsZSk9Pntjb25zdCBuPXJbZV07cmV0dXJuXCJmdW5jdGlvblwiPT10eXBlb2Ygbj9uLmNhbGwocik6bn0sQT0vXFxbKFtcXHdcXGRdKylcXF0vZzt2YXIgej0ocixlKT0+KGZ1bmN0aW9uKHIsZSxuLHQsdSl7Zm9yKHUgaW4gdD0obj1uLnNwbGl0KFwiLlwiKSkuc3BsaWNlKC0xLDEpLG4pZT1lW25bdV1dPWVbblt1XV18fHt9O3JldHVybiByKGUsdCl9KSh3LHIsZS5yZXBsYWNlKEEsXCIuJDFcIikpLGs9LTE7ZnVuY3Rpb24gTygpe3ZhciByLGU9e2FkZDphLHJlbW92ZTpmdW5jdGlvbihlKXtmb3IodmFyIG89bmV3IEFycmF5KHQpLGk9W10sYT1cImZ1bmN0aW9uXCI9PXR5cGVvZiBlLGw9MCxzPTA7bDx0OysrbCljPWwsKGE/ZShuW2NdLGMpOnIuemVybyhjKSk/KGkucHVzaChsKSxvW2xdPWspOm9bbF09cysrO3ZhciBjO3UuZm9yRWFjaCgoZnVuY3Rpb24ocil7cigtMSwtMSxbXSxpLCEwKX0pKSxmLmZvckVhY2goKGZ1bmN0aW9uKHIpe3Iobyl9KSk7Zm9yKHZhciBoPTAsdj0wO2g8dDsrK2gpb1toXSE9PWsmJihoIT09diYmKHIuY29weSh2LGgpLG5bdl09bltoXSksKyt2KTtuLmxlbmd0aD10PXYsci50cnVuY2F0ZSh2KSxnKFwiZGF0YVJlbW92ZWRcIil9LGRpbWVuc2lvbjpmdW5jdGlvbihlLGkpe2lmKFwic3RyaW5nXCI9PXR5cGVvZiBlKXt2YXIgYT1lO2U9ZnVuY3Rpb24ocil7cmV0dXJuIHoocixhKX19dmFyIHAseCx3LEEsTyxGLE4sUixVLEQsSSxMLFcsSixqPXtmaWx0ZXI6ZnVuY3Rpb24ocil7cmV0dXJuIG51bGw9PXI/ZXIoKTpBcnJheS5pc0FycmF5KHIpP3JyKHIpOlwiZnVuY3Rpb25cIj09dHlwZW9mIHI/bnIocik6XyhyKX0sZmlsdGVyRXhhY3Q6XyxmaWx0ZXJSYW5nZTpycixmaWx0ZXJGdW5jdGlvbjpucixmaWx0ZXJBbGw6ZXIsY3VycmVudEZpbHRlcjpmdW5jdGlvbigpe3JldHVybiBMfSxoYXNDdXJyZW50RmlsdGVyOmZ1bmN0aW9uKCl7cmV0dXJuIFd9LHRvcDpmdW5jdGlvbihlLHQpe3ZhciB1LG89W10sZj1QLGE9MDt0JiZ0PjAmJihhPXQpO2Zvcig7LS1mPj1LJiZlPjA7KXIuemVybyh1PUZbZl0pJiYoYT4wPy0tYTooby5wdXNoKG5bdV0pLC0tZSkpO2lmKGkpZm9yKGY9MDtmPCQubGVuZ3RoJiZlPjA7ZisrKXIuemVybyh1PSRbZl0pJiYoYT4wPy0tYTooby5wdXNoKG5bdV0pLC0tZSkpO3JldHVybiBvfSxib3R0b206ZnVuY3Rpb24oZSx0KXt2YXIgdSxvLGY9W10sYT0wO3QmJnQ+MCYmKGE9dCk7aWYoaSlmb3IodT0wO3U8JC5sZW5ndGgmJmU+MDt1Kyspci56ZXJvKG89JFt1XSkmJihhPjA/LS1hOihmLnB1c2gobltvXSksLS1lKSk7dT1LO2Zvcig7dTxQJiZlPjA7KXIuemVybyhvPUZbdV0pJiYoYT4wPy0tYTooZi5wdXNoKG5bb10pLC0tZSkpLHUrKztyZXR1cm4gZn0sZ3JvdXA6dXIsZ3JvdXBBbGw6ZnVuY3Rpb24oKXt2YXIgcj11cihoKSxlPXIuYWxsO3JldHVybiBkZWxldGUgci5hbGwsZGVsZXRlIHIudG9wLGRlbGV0ZSByLm9yZGVyLGRlbGV0ZSByLm9yZGVyTmF0dXJhbCxkZWxldGUgci5zaXplLHIudmFsdWU9ZnVuY3Rpb24oKXtyZXR1cm4gZSgpWzBdLnZhbHVlfSxyfSxkaXNwb3NlOm9yLHJlbW92ZTpvcixhY2Nlc3NvcjplLGlkOmZ1bmN0aW9uKCl7cmV0dXJuIEF9fSwkPVtdLHE9ZnVuY3Rpb24ocil7cmV0dXJuIFMocikuc29ydCgoZnVuY3Rpb24ocixlKXt2YXIgbj1OW3JdLHQ9TltlXTtyZXR1cm4gbjx0Py0xOm4+dD8xOnItZX0pKX0sQj1zLmZpbHRlckFsbCxHPVtdLEg9W10sSz0wLFA9MCxRPTA7by51bnNoaWZ0KFYpLG8ucHVzaChYKSxmLnB1c2goWSk7dmFyIFQ9ci5hZGQoKTtmdW5jdGlvbiBWKG4sdSxvKXt2YXIgZixhO2lmKGkpe1E9MCxHPTAsSj1bXTtmb3IodmFyIHM9MDtzPG4ubGVuZ3RoO3MrKylmb3IoRz0wLEo9ZShuW3NdKTtHPEoubGVuZ3RoO0crKylRKys7Tj1bXSxmPVMobi5sZW5ndGgpLGE9TShRLDEpO2Zvcih2YXIgYz1TKFEpLGg9MCx2PTA7djxuLmxlbmd0aDt2KyspaWYoKEo9ZShuW3ZdKSkubGVuZ3RoKWZvcihmW3ZdPUoubGVuZ3RoLEc9MDtHPEoubGVuZ3RoO0crKylOLnB1c2goSltHXSksY1toXT12LGgrKztlbHNlIGZbdl09MCwkLnB1c2godit1KTt2YXIgZD1xKFEpO049bShOLGQpLFI9bShjLGQpfWVsc2UgTj1uLm1hcChlKSxSPXEobyksTj1tKE4sUik7dmFyIGcseSx4LGI9QihOKSxFPWJbMF0sQT1iWzFdO2lmKGkpaWYobz1RLEkpZm9yKGc9MDtnPG87KytnKUkoTltnXSxnKXx8KDA9PS0tZltSW2ddXSYmKHJbd11bUltnXSt1XXw9cCksYVtnXT0xKTtlbHNle2Zvcih5PTA7eTxFOysreSkwPT0tLWZbUlt5XV0mJihyW3ddW1JbeV0rdV18PXApLGFbeV09MTtmb3IoeD1BO3g8bzsrK3gpMD09LS1mW1JbeF1dJiYoclt3XVtSW3hdK3VdfD1wKSxhW3hdPTF9ZWxzZSBpZihJKWZvcihnPTA7ZzxvOysrZylJKE5bZ10sZyl8fChyW3ddW1JbZ10rdV18PXApO2Vsc2V7Zm9yKHk9MDt5PEU7Kyt5KXJbd11bUlt5XSt1XXw9cDtmb3IoeD1BO3g8bzsrK3gpclt3XVtSW3hdK3VdfD1wfWlmKCF1KXJldHVybiBPPU4sRj1SLFU9ZixEPWEsSz1FLHZvaWQoUD1BKTt2YXIgeixrPU8sQz1GLEw9RCxXPTA7aWYocz0wLGkmJih6PXUsdT1rLmxlbmd0aCxvPVEpLE89bmV3IEFycmF5KGk/dStvOnQpLEY9aT9uZXcgQXJyYXkodStvKTpNKHQsdCksaSYmKEQ9TSh1K28sMSkpLGkpe3ZhciBqPVUubGVuZ3RoO1U9bC5hcnJheUxlbmd0aGVuKFUsdCk7Zm9yKHZhciBHPTA7RytqPHQ7RysrKVVbRytqXT1mW0ddfWZvcih2YXIgSD0wO3M8dSYmVzxvOysrSClrW3NdPE5bV10/KE9bSF09a1tzXSxpJiYoRFtIXT1MW3NdKSxGW0hdPUNbcysrXSk6KE9bSF09TltXXSxpJiYoRFtIXT1hW1ddKSxGW0hdPVJbVysrXSsoaT96OnUpKTtmb3IoO3M8dTsrK3MsKytIKU9bSF09a1tzXSxpJiYoRFtIXT1MW3NdKSxGW0hdPUNbc107Zm9yKDtXPG87KytXLCsrSClPW0hdPU5bV10saSYmKERbSF09YVtXXSksRltIXT1SW1ddKyhpP3o6dSk7Yj1CKE8pLEs9YlswXSxQPWJbMV19ZnVuY3Rpb24gWChyLGUsbil7Ry5mb3JFYWNoKChmdW5jdGlvbihyKXtyKE4sUixlLG4pfSkpLE49Uj1udWxsfWZ1bmN0aW9uIFkocil7aWYoaSl7Zm9yKHZhciBlPTAsbj0wO2U8JC5sZW5ndGg7ZSsrKXJbJFtlXV0hPT1rJiYoJFtuXT1yWyRbZV1dLG4rKyk7Zm9yKCQubGVuZ3RoPW4sZT0wLG49MDtlPHQ7ZSsrKXJbZV0hPT1rJiYobiE9PWUmJihVW25dPVVbZV0pLG4rKyk7VT1VLnNsaWNlKDAsbil9Zm9yKHZhciB1LG89Ty5sZW5ndGgsZj0wLGE9MDtmPG87KytmKXJbdT1GW2ZdXSE9PWsmJihmIT09YSYmKE9bYV09T1tmXSksRlthXT1yW3VdLGkmJihEW2FdPURbZl0pLCsrYSk7Zm9yKE8ubGVuZ3RoPWEsaSYmKEQ9RC5zbGljZSgwLGEpKTthPG87KUZbYSsrXT0wO3ZhciBsPUIoTyk7Sz1sWzBdLFA9bFsxXX1mdW5jdGlvbiBaKGUpe3ZhciBuPWVbMF0sdD1lWzFdO2lmKEkpcmV0dXJuIEk9bnVsbCx0cigoZnVuY3Rpb24ocixlKXtyZXR1cm4gbjw9ZSYmZTx0fSksMD09PWVbMF0mJmVbMV09PT1PLmxlbmd0aCksSz1uLFA9dCxqO3ZhciBvLGYsYSxsPVtdLGM9W10saD1bXSx2PVtdO2lmKG48Sylmb3Iobz1uLGY9TWF0aC5taW4oSyx0KTtvPGY7KytvKWwucHVzaChGW29dKSxoLnB1c2gobyk7ZWxzZSBpZihuPkspZm9yKG89SyxmPU1hdGgubWluKG4sUCk7bzxmOysrbyljLnB1c2goRltvXSksdi5wdXNoKG8pO2lmKHQ+UClmb3Iobz1NYXRoLm1heChuLFApLGY9dDtvPGY7KytvKWwucHVzaChGW29dKSxoLnB1c2gobyk7ZWxzZSBpZih0PFApZm9yKG89TWF0aC5tYXgoSyx0KSxmPVA7bzxmOysrbyljLnB1c2goRltvXSksdi5wdXNoKG8pO2lmKGkpe3ZhciBkPVtdLHk9W107Zm9yKG89MDtvPGwubGVuZ3RoO28rKylVW2xbb11dKyssRFtoW29dXT0wLDE9PT1VW2xbb11dJiYoclt3XVtsW29dXV49cCxkLnB1c2gobFtvXSkpO2ZvcihvPTA7bzxjLmxlbmd0aDtvKyspVVtjW29dXS0tLERbdltvXV09MSwwPT09VVtjW29dXSYmKHJbd11bY1tvXV1ePXAseS5wdXNoKGNbb10pKTtpZihsPWQsYz15LEI9PT1zLmZpbHRlckFsbClmb3Iobz0wO288JC5sZW5ndGg7bysrKXJbd11bYT0kW29dXSZwJiYoclt3XVthXV49cCxsLnB1c2goYSkpO2Vsc2UgZm9yKG89MDtvPCQubGVuZ3RoO28rKylyW3ddW2E9JFtvXV0mcHx8KHJbd11bYV1ePXAsYy5wdXNoKGEpKX1lbHNle2ZvcihvPTA7bzxsLmxlbmd0aDtvKyspclt3XVtsW29dXV49cDtmb3Iobz0wO288Yy5sZW5ndGg7bysrKXJbd11bY1tvXV1ePXB9cmV0dXJuIEs9bixQPXQsdS5mb3JFYWNoKChmdW5jdGlvbihyKXtyKHAsdyxsLGMpfSkpLGcoXCJmaWx0ZXJlZFwiKSxqfWZ1bmN0aW9uIF8ocil7cmV0dXJuIEw9cixXPSEwLFooKEI9cy5maWx0ZXJFeGFjdChiLHIpKShPKSl9ZnVuY3Rpb24gcnIocil7cmV0dXJuIEw9cixXPSEwLFooKEI9cy5maWx0ZXJSYW5nZShiLHIpKShPKSl9ZnVuY3Rpb24gZXIoKXtyZXR1cm4gTD12b2lkIDAsVz0hMSxaKChCPXMuZmlsdGVyQWxsKShPKSl9ZnVuY3Rpb24gbnIocil7TD1yLFc9ITAsST1yLEI9cy5maWx0ZXJBbGwsdHIociwhMSk7dmFyIGU9QihPKTtyZXR1cm4gSz1lWzBdLFA9ZVsxXSxqfWZ1bmN0aW9uIHRyKGUsbil7dmFyIHQsbyxmLGE9W10sbD1bXSxzPVtdLGM9W10saD1PLmxlbmd0aDtpZighaSlmb3IodD0wO3Q8aDsrK3QpIShyW3ddW289Rlt0XV0mcCleISEoZj1lKE9bdF0sdCkpJiYoZj9hLnB1c2gobyk6bC5wdXNoKG8pKTtpZihpKWZvcih0PTA7dDxoOysrdCllKE9bdF0sdCk/KGEucHVzaChGW3RdKSxzLnB1c2godCkpOihsLnB1c2goRlt0XSksYy5wdXNoKHQpKTtpZihpKXt2YXIgdj1bXSxkPVtdO2Zvcih0PTA7dDxhLmxlbmd0aDt0KyspMT09PURbc1t0XV0mJihVW2FbdF1dKyssRFtzW3RdXT0wLDE9PT1VW2FbdF1dJiYoclt3XVthW3RdXV49cCx2LnB1c2goYVt0XSkpKTtmb3IodD0wO3Q8bC5sZW5ndGg7dCsrKTA9PT1EW2NbdF1dJiYoVVtsW3RdXS0tLERbY1t0XV09MSwwPT09VVtsW3RdXSYmKHJbd11bbFt0XV1ePXAsZC5wdXNoKGxbdF0pKSk7aWYoYT12LGw9ZCxuKWZvcih0PTA7dDwkLmxlbmd0aDt0Kyspclt3XVtvPSRbdF1dJnAmJihyW3ddW29dXj1wLGEucHVzaChvKSk7ZWxzZSBmb3IodD0wO3Q8JC5sZW5ndGg7dCsrKXJbd11bbz0kW3RdXSZwfHwoclt3XVtvXV49cCxsLnB1c2gobykpfWVsc2V7Zm9yKHQ9MDt0PGEubGVuZ3RoO3QrKylyW3ddW2FbdF1dJnAmJihyW3ddW2FbdF1dJj14KTtmb3IodD0wO3Q8bC5sZW5ndGg7dCsrKXJbd11bbFt0XV0mcHx8KHJbd11bbFt0XV18PXApfXUuZm9yRWFjaCgoZnVuY3Rpb24ocil7cihwLHcsYSxsKX0pKSxnKFwiZmlsdGVyZWRcIil9ZnVuY3Rpb24gdXIoZSl7dmFyIG89e3RvcDpmdW5jdGlvbihyKXt2YXIgZT1nKFAoKSwwLGEubGVuZ3RoLHIpO3JldHVybiBiLnNvcnQoZSwwLGUubGVuZ3RoKX0sYWxsOlAscmVkdWNlOlEscmVkdWNlQ291bnQ6VCxyZWR1Y2VTdW06ZnVuY3Rpb24ocil7cmV0dXJuIFEoRS5yZWR1Y2VBZGQociksRS5yZWR1Y2VTdWJ0cmFjdChyKSx2KX0sb3JkZXI6VixvcmRlck5hdHVyYWw6ZnVuY3Rpb24oKXtyZXR1cm4gVihjKX0sc2l6ZTpmdW5jdGlvbigpe3JldHVybiBVfSxkaXNwb3NlOlgscmVtb3ZlOlh9O0gucHVzaChvKTt2YXIgYSxzLGcsYixtLEEseixTLE49OCxSPUMoTiksVT0wLEQ9aCxJPWgsTD0hMCxXPWU9PT1oO2Z1bmN0aW9uIEoobyxmLGMsdil7aSYmKFM9YyxjPU8ubGVuZ3RoLW8ubGVuZ3RoLHY9by5sZW5ndGgpO3ZhciBwLGQsZyx5LGIsRSxrPWEsRj1pP1tdOk0oVSxSKSxKPW0saj1BLEc9eixIPVUsUD0wLFE9MDtmb3IoTCYmKEo9Rz1oKSxMJiYoaj1HPWgpLGE9bmV3IEFycmF5KFUpLFU9MCxzPWk/SD9zOltdOkg+MT9sLmFycmF5TGVuZ3RoZW4ocyx0KTpNKHQsUiksSCYmKGc9KGQ9a1swXSkua2V5KTtRPHYmJiEoKHk9ZShvW1FdKSk+PXkpOykrK1E7Zm9yKDtRPHY7KXtmb3IoZCYmZzw9eT8oYj1kLEU9ZyxGW1BdPVUsKGQ9a1srK1BdKSYmKGc9ZC5rZXkpKTooYj17a2V5OnksdmFsdWU6RygpfSxFPXkpLGFbVV09Yjt5PD1FJiYocD1mW1FdKyhpP1M6YyksaT9zW3BdP3NbcF0ucHVzaChVKTpzW3BdPVtVXTpzW3BdPVUsYi52YWx1ZT1KKGIudmFsdWUsbltwXSwhMCksci56ZXJvRXhjZXB0KHAsdyx4KXx8KGIudmFsdWU9aihiLnZhbHVlLG5bcF0sITEpKSwhKCsrUT49dikpOyl5PWUob1tRXSk7VigpfWZvcig7UDxIOylhW0ZbUF09VV09a1tQKytdLFYoKTtpZihpKWZvcih2YXIgVD0wO1Q8dDtUKyspc1tUXXx8KHNbVF09W10pO2lmKFU+UClpZihpKWZvcihQPTA7UDxTOysrUClmb3IoVD0wO1Q8c1tQXS5sZW5ndGg7VCsrKXNbUF1bVF09RltzW1BdW1RdXTtlbHNlIGZvcihQPTA7UDxjOysrUClzW1BdPUZbc1tQXV07ZnVuY3Rpb24gVigpe2k/VSsrOisrVT09PVImJihGPWwuYXJyYXlXaWRlbihGLE48PD0xKSxzPWwuYXJyYXlXaWRlbihzLE4pLFI9QyhOKSl9cD11LmluZGV4T2YoRCksVT4xfHxpPyhEPSQsST1CKTooIVUmJlcmJihVPTEsYT1be2tleTpudWxsLHZhbHVlOkcoKX1dKSwxPT09VT8oRD1xLEk9Syk6KEQ9aCxJPWgpLHM9bnVsbCksdVtwXT1EfWZ1bmN0aW9uIGoocil7aWYoVT4xfHxpKXt2YXIgZSxuLG8sZj1VLGw9YSxjPU0oZixmKTtpZihpKXtmb3IoZT0wLG89MDtlPHQ7KytlKWlmKHJbZV0hPT1rKXtmb3Ioc1tvXT1zW2VdLG49MDtuPHNbb10ubGVuZ3RoO24rKyljW3Nbb11bbl1dPTE7KytvfXM9cy5zbGljZSgwLG8pfWVsc2UgZm9yKGU9MCxvPTA7ZTx0OysrZSlyW2VdIT09ayYmKGNbc1tvXT1zW2VdXT0xLCsrbyk7Zm9yKGE9W10sVT0wLGU9MDtlPGY7KytlKWNbZV0mJihjW2VdPVUrKyxhLnB1c2gobFtlXSkpO2lmKFU+MXx8aSlpZihpKWZvcihlPTA7ZTxvOysrZSlmb3Iobj0wO248c1tlXS5sZW5ndGg7KytuKXNbZV1bbl09Y1tzW2VdW25dXTtlbHNlIGZvcihlPTA7ZTxvOysrZSlzW2VdPWNbc1tlXV07ZWxzZSBzPW51bGw7dVt1LmluZGV4T2YoRCldPVU+MXx8aT8oST1CLEQ9JCk6MT09PVU/KEk9SyxEPXEpOkk9RD1ofWVsc2UgaWYoMT09PVUpe2lmKFcpcmV0dXJuO2Zvcih2YXIgdj0wO3Y8dDsrK3YpaWYoclt2XSE9PWspcmV0dXJuO2E9W10sVT0wLHVbdS5pbmRleE9mKEQpXT1EPUk9aH19ZnVuY3Rpb24gJChlLHQsdSxvLGYpe3ZhciBsLGMsaCx2LGQ7aWYoIShlPT09cCYmdD09PXd8fEwpKWlmKGkpe2ZvcihsPTAsdj11Lmxlbmd0aDtsPHY7KytsKWlmKHIuemVyb0V4Y2VwdChoPXVbbF0sdyx4KSlmb3IoYz0wO2M8c1toXS5sZW5ndGg7YysrKShkPWFbc1toXVtjXV0pLnZhbHVlPW0oZC52YWx1ZSxuW2hdLCExLGMpO2ZvcihsPTAsdj1vLmxlbmd0aDtsPHY7KytsKWlmKHIub25seUV4Y2VwdChoPW9bbF0sdyx4LHQsZSkpZm9yKGM9MDtjPHNbaF0ubGVuZ3RoO2MrKykoZD1hW3NbaF1bY11dKS52YWx1ZT1BKGQudmFsdWUsbltoXSxmLGMpfWVsc2V7Zm9yKGw9MCx2PXUubGVuZ3RoO2w8djsrK2wpci56ZXJvRXhjZXB0KGg9dVtsXSx3LHgpJiYoKGQ9YVtzW2hdXSkudmFsdWU9bShkLnZhbHVlLG5baF0sITEpKTtmb3IobD0wLHY9by5sZW5ndGg7bDx2OysrbClyLm9ubHlFeGNlcHQoaD1vW2xdLHcseCx0LGUpJiYoKGQ9YVtzW2hdXSkudmFsdWU9QShkLnZhbHVlLG5baF0sZikpfX1mdW5jdGlvbiBxKGUsdCx1LG8sZil7aWYoIShlPT09cCYmdD09PXd8fEwpKXt2YXIgaSxsLHMsYz1hWzBdO2ZvcihpPTAscz11Lmxlbmd0aDtpPHM7KytpKXIuemVyb0V4Y2VwdChsPXVbaV0sdyx4KSYmKGMudmFsdWU9bShjLnZhbHVlLG5bbF0sITEpKTtmb3IoaT0wLHM9by5sZW5ndGg7aTxzOysraSlyLm9ubHlFeGNlcHQobD1vW2ldLHcseCx0LGUpJiYoYy52YWx1ZT1BKGMudmFsdWUsbltsXSxmKSl9fWZ1bmN0aW9uIEIoKXt2YXIgZSx1LG87Zm9yKGU9MDtlPFU7KytlKWFbZV0udmFsdWU9eigpO2lmKGkpe2ZvcihlPTA7ZTx0OysrZSlmb3IodT0wO3U8c1tlXS5sZW5ndGg7dSsrKShvPWFbc1tlXVt1XV0pLnZhbHVlPW0oby52YWx1ZSxuW2VdLCEwLHUpO2ZvcihlPTA7ZTx0OysrZSlpZighci56ZXJvRXhjZXB0KGUsdyx4KSlmb3IodT0wO3U8c1tlXS5sZW5ndGg7dSsrKShvPWFbc1tlXVt1XV0pLnZhbHVlPUEoby52YWx1ZSxuW2VdLCExLHUpfWVsc2V7Zm9yKGU9MDtlPHQ7KytlKShvPWFbc1tlXV0pLnZhbHVlPW0oby52YWx1ZSxuW2VdLCEwKTtmb3IoZT0wO2U8dDsrK2Upci56ZXJvRXhjZXB0KGUsdyx4KXx8KChvPWFbc1tlXV0pLnZhbHVlPUEoby52YWx1ZSxuW2VdLCExKSl9fWZ1bmN0aW9uIEsoKXt2YXIgZSx1PWFbMF07Zm9yKHUudmFsdWU9eigpLGU9MDtlPHQ7KytlKXUudmFsdWU9bSh1LnZhbHVlLG5bZV0sITApO2ZvcihlPTA7ZTx0OysrZSlyLnplcm9FeGNlcHQoZSx3LHgpfHwodS52YWx1ZT1BKHUudmFsdWUsbltlXSwhMSkpfWZ1bmN0aW9uIFAoKXtyZXR1cm4gTCYmKEkoKSxMPSExKSxhfWZ1bmN0aW9uIFEocixlLG4pe3JldHVybiBtPXIsQT1lLHo9bixMPSEwLG99ZnVuY3Rpb24gVCgpe3JldHVybiBRKEUucmVkdWNlSW5jcmVtZW50LEUucmVkdWNlRGVjcmVtZW50LHYpfWZ1bmN0aW9uIFYocil7ZnVuY3Rpb24gZShlKXtyZXR1cm4gcihlLnZhbHVlKX1yZXR1cm4gZz15LmJ5KGUpLGI9ZC5ieShlKSxvfWZ1bmN0aW9uIFgoKXt2YXIgcj11LmluZGV4T2YoRCk7cmV0dXJuIHI+PTAmJnUuc3BsaWNlKHIsMSksKHI9Ry5pbmRleE9mKEopKT49MCYmRy5zcGxpY2UociwxKSwocj1mLmluZGV4T2YoaikpPj0wJiZmLnNwbGljZShyLDEpLChyPUguaW5kZXhPZihvKSk+PTAmJkguc3BsaWNlKHIsMSksb31yZXR1cm4gYXJndW1lbnRzLmxlbmd0aDwxJiYoZT1jKSx1LnB1c2goRCksRy5wdXNoKEopLGYucHVzaChqKSxKKE8sRiwwLHQpLFQoKS5vcmRlck5hdHVyYWwoKX1mdW5jdGlvbiBvcigpe0guZm9yRWFjaCgoZnVuY3Rpb24ocil7ci5kaXNwb3NlKCl9KSk7dmFyIGU9by5pbmRleE9mKFYpO3JldHVybiBlPj0wJiZvLnNwbGljZShlLDEpLChlPW8uaW5kZXhPZihYKSk+PTAmJm8uc3BsaWNlKGUsMSksKGU9Zi5pbmRleE9mKFkpKT49MCYmZi5zcGxpY2UoZSwxKSxyLm1hc2tzW3ddJj14LGVyKCl9cmV0dXJuIHc9VC5vZmZzZXQscD1ULm9uZSx4PX5wLEE9dzw8N3xNYXRoLmxvZyhwKS9NYXRoLmxvZygyKSxWKG4sMCx0KSxYKG4sMCx0KSxqfSxncm91cEFsbDpmdW5jdGlvbigpe3ZhciBlLGYsaSxhLGw9e3JlZHVjZTpwLHJlZHVjZUNvdW50OmQscmVkdWNlU3VtOmZ1bmN0aW9uKHIpe3JldHVybiBwKEUucmVkdWNlQWRkKHIpLEUucmVkdWNlU3VidHJhY3Qociksdil9LHZhbHVlOmZ1bmN0aW9uKCl7cyYmKGZ1bmN0aW9uKCl7dmFyIHU7Zm9yKGU9YSgpLHU9MDt1PHQ7Kyt1KWU9ZihlLG5bdV0sITApLHIuemVybyh1KXx8KGU9aShlLG5bdV0sITEpKX0oKSxzPSExKTtyZXR1cm4gZX0sZGlzcG9zZTpnLHJlbW92ZTpnfSxzPSEwO2Z1bmN0aW9uIGModSxvKXt2YXIgYTtpZighcylmb3IoYT1vO2E8dDsrK2EpZT1mKGUsblthXSwhMCksci56ZXJvKGEpfHwoZT1pKGUsblthXSwhMSkpfWZ1bmN0aW9uIGgodCx1LG8sYSxsKXt2YXIgYyxoLHY7aWYoIXMpe2ZvcihjPTAsdj1vLmxlbmd0aDtjPHY7KytjKXIuemVybyhoPW9bY10pJiYoZT1mKGUsbltoXSxsKSk7Zm9yKGM9MCx2PWEubGVuZ3RoO2M8djsrK2Mpci5vbmx5KGg9YVtjXSx1LHQpJiYoZT1pKGUsbltoXSxsKSl9fWZ1bmN0aW9uIHAocixlLG4pe3JldHVybiBmPXIsaT1lLGE9bixzPSEwLGx9ZnVuY3Rpb24gZCgpe3JldHVybiBwKEUucmVkdWNlSW5jcmVtZW50LEUucmVkdWNlRGVjcmVtZW50LHYpfWZ1bmN0aW9uIGcoKXt2YXIgcj11LmluZGV4T2YoaCk7cmV0dXJuIHI+PTAmJnUuc3BsaWNlKHIsMSksKHI9by5pbmRleE9mKGMpKT49MCYmby5zcGxpY2UociwxKSxsfXJldHVybih1LnB1c2goaCksby5wdXNoKGMpLGMobiwwKSxkKCkpfSxzaXplOmZ1bmN0aW9uKCl7cmV0dXJuIHR9LGFsbDpmdW5jdGlvbigpe3JldHVybiBufSxhbGxGaWx0ZXJlZDpmdW5jdGlvbihlKXt2YXIgdT1bXSxvPTAsZj1wKGV8fFtdKTtmb3Iobz0wO288dDtvKyspci56ZXJvRXhjZXB0TWFzayhvLGYpJiZ1LnB1c2gobltvXSk7cmV0dXJuIHV9LG9uQ2hhbmdlOmZ1bmN0aW9uKHIpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHIpcmV0dXJuIHZvaWQgY29uc29sZS53YXJuKFwib25DaGFuZ2UgY2FsbGJhY2sgcGFyYW1ldGVyIG11c3QgYmUgYSBmdW5jdGlvbiFcIik7cmV0dXJuIGkucHVzaChyKSxmdW5jdGlvbigpe2kuc3BsaWNlKGkuaW5kZXhPZihyKSwxKX19LGlzRWxlbWVudEZpbHRlcmVkOmZ1bmN0aW9uKGUsbil7dmFyIHQ9cChufHxbXSk7cmV0dXJuIHIuemVyb0V4Y2VwdE1hc2soZSx0KX19LG49W10sdD0wLHU9W10sbz1bXSxmPVtdLGk9W107ZnVuY3Rpb24gYSh1KXt2YXIgZj10LGk9dS5sZW5ndGg7cmV0dXJuIGkmJihuPW4uY29uY2F0KHUpLHIubGVuZ3RoZW4odCs9aSksby5mb3JFYWNoKChmdW5jdGlvbihyKXtyKHUsZixpKX0pKSxnKFwiZGF0YUFkZGVkXCIpKSxlfWZ1bmN0aW9uIHAoZSl7dmFyIG4sdCx1LG8sZj1BcnJheShyLnN1YmFycmF5cyk7Zm9yKG49MDtuPHIuc3ViYXJyYXlzO24rKylmW25dPS0xO2Zvcih0PTAsdT1lLmxlbmd0aDt0PHU7dCsrKWZbKG89ZVt0XS5pZCgpKT4+N10mPX4oMTw8KDYzJm8pKTtyZXR1cm4gZn1mdW5jdGlvbiBnKHIpe2Zvcih2YXIgZT0wO2U8aS5sZW5ndGg7ZSsrKWlbZV0ocil9cmV0dXJuIHI9bmV3IGwuYml0YXJyYXkoMCksYXJndW1lbnRzLmxlbmd0aD9hKGFyZ3VtZW50c1swXSk6ZX1mdW5jdGlvbiBNKHIsZSl7cmV0dXJuKGU8MjU3P2wuYXJyYXk4OmU8NjU1Mzc/bC5hcnJheTE2OmwuYXJyYXkzMikocil9ZnVuY3Rpb24gUyhyKXtmb3IodmFyIGU9TShyLHIpLG49LTE7KytuPHI7KWVbbl09bjtyZXR1cm4gZX1mdW5jdGlvbiBDKHIpe3JldHVybiA4PT09cj8yNTY6MTY9PT1yPzY1NTM2OjQyOTQ5NjcyOTZ9Ty5oZWFwPWQsTy5oZWFwc2VsZWN0PXksTy5iaXNlY3Q9YixPLnBlcm11dGU9bTtyZXR1cm4gTy52ZXJzaW9uPVwiMS41LjRcIixPfSkpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0352\n')},"072d":function(module,exports){eval("/**\n * Server side filtering\n *\n * Implementation of a dataset backed by a server, which in turn uses fi. postgreSQL\n * Fully asynchronous, based on socketIO.\n *\n * Most methods below result in a message with the methodName and a data object, containing:\n *  * `datasets` and `dataview`, or `dataset`\n *  * `filterId` or `facetId`\n *\n * Data can be requested using the dataview.getData() method\n * responds with a `newData` message containing `filterId` and `data`.\n *\n * @module driver/server\n */\n\n/**\n * Autoconfigure a dataset\n *\n * @param {Dataset} dataset\n */\nfunction scan (dataset) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    // spot-server will not respond so no use requesting a scan\n    return;\n  }\n\n  spot.socket.emit('scanData', {\n    dataset: dataset.toJSON()\n  });\n}\n\n/**\n * setMinMax sets the range of a continuous or time facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setMinMax (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    spot.socket.emit('setMinMax', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setMinMax', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * setCategories finds finds all values on an ordinal (categorial) axis\n * Updates the categorialTransform of the facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setCategories (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  facet.categorialTransform.rules.reset();\n  if (spot.isLockedDown) {\n    spot.socket.emit('setCategories', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setCategories', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * Calculate 100 percentiles (ie. 1,2,3,4 etc.), and initialize the `facet.continuousTransform`\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setPercentiles (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    spot.socket.emit('setPercentiles', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setPercentiles', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * Initialize the data filter, and construct the getData callback function on the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction initDataFilter (dataview, filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n * related to the filter.\n * @param {Filter} filter\n */\nfunction releaseDataFilter (filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * Change the filter parameters for an initialized filter\n * @param {Filter} filter\n */\nfunction updateDataFilter (filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * Get data for every filter, and trigger a 'newData' event\n *\n * Returns a Promise that resolves to the dataview when all data and metadata has been updated\n *\n * @param {Dataview} dataview\n * @returns {Promise}\n */\nfunction getData (dataview) {\n  var spot = dataview.parent;\n\n  return new Promise(function (resolve, reject) {\n    if (spot.isLockedDown) {\n      spot.socket.emit('getData', {\n        dataview: dataview.toJSON()\n      });\n    } else {\n      spot.socket.emit('getData', {\n        datasets: spot.cachedDatasets,\n        dataview: dataview.toJSON()\n      });\n    }\n\n    dataview.once('newMetaData', function () {\n      resolve(dataview);\n    });\n  });\n}\n\nmodule.exports = {\n  driverType: 'server',\n  scan: scan,\n  setMinMax: setMinMax,\n  setCategories: setCategories,\n  setPercentiles: setPercentiles,\n  initDataFilter: initDataFilter,\n  releaseDataFilter: releaseDataFilter,\n  updateDataFilter: updateDataFilter,\n  getData: getData\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDcyZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZHJpdmVyL3NlcnZlci5qcz9lMzc3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2VydmVyIHNpZGUgZmlsdGVyaW5nXG4gKlxuICogSW1wbGVtZW50YXRpb24gb2YgYSBkYXRhc2V0IGJhY2tlZCBieSBhIHNlcnZlciwgd2hpY2ggaW4gdHVybiB1c2VzIGZpLiBwb3N0Z3JlU1FMXG4gKiBGdWxseSBhc3luY2hyb25vdXMsIGJhc2VkIG9uIHNvY2tldElPLlxuICpcbiAqIE1vc3QgbWV0aG9kcyBiZWxvdyByZXN1bHQgaW4gYSBtZXNzYWdlIHdpdGggdGhlIG1ldGhvZE5hbWUgYW5kIGEgZGF0YSBvYmplY3QsIGNvbnRhaW5pbmc6XG4gKiAgKiBgZGF0YXNldHNgIGFuZCBgZGF0YXZpZXdgLCBvciBgZGF0YXNldGBcbiAqICAqIGBmaWx0ZXJJZGAgb3IgYGZhY2V0SWRgXG4gKlxuICogRGF0YSBjYW4gYmUgcmVxdWVzdGVkIHVzaW5nIHRoZSBkYXRhdmlldy5nZXREYXRhKCkgbWV0aG9kXG4gKiByZXNwb25kcyB3aXRoIGEgYG5ld0RhdGFgIG1lc3NhZ2UgY29udGFpbmluZyBgZmlsdGVySWRgIGFuZCBgZGF0YWAuXG4gKlxuICogQG1vZHVsZSBkcml2ZXIvc2VydmVyXG4gKi9cblxuLyoqXG4gKiBBdXRvY29uZmlndXJlIGEgZGF0YXNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICovXG5mdW5jdGlvbiBzY2FuIChkYXRhc2V0KSB7XG4gIC8vIERhdGFzZXQgLT4gRGF0YXNldHMgLT4gU3BvdFxuICB2YXIgc3BvdCA9IGRhdGFzZXQuY29sbGVjdGlvbi5wYXJlbnQ7XG5cbiAgaWYgKHNwb3QuaXNMb2NrZWREb3duKSB7XG4gICAgLy8gc3BvdC1zZXJ2ZXIgd2lsbCBub3QgcmVzcG9uZCBzbyBubyB1c2UgcmVxdWVzdGluZyBhIHNjYW5cbiAgICByZXR1cm47XG4gIH1cblxuICBzcG90LnNvY2tldC5lbWl0KCdzY2FuRGF0YScsIHtcbiAgICBkYXRhc2V0OiBkYXRhc2V0LnRvSlNPTigpXG4gIH0pO1xufVxuXG4vKipcbiAqIHNldE1pbk1heCBzZXRzIHRoZSByYW5nZSBvZiBhIGNvbnRpbnVvdXMgb3IgdGltZSBmYWNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqL1xuZnVuY3Rpb24gc2V0TWluTWF4IChkYXRhc2V0LCBmYWNldCkge1xuICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgdmFyIHNwb3QgPSBkYXRhc2V0LmNvbGxlY3Rpb24ucGFyZW50O1xuXG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldE1pbk1heCcsIHtcbiAgICAgIGRhdGFzZXRJZDogZGF0YXNldC5nZXRJZCgpLFxuICAgICAgZmFjZXRJZDogZmFjZXQuZ2V0SWQoKVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldE1pbk1heCcsIHtcbiAgICAgIGRhdGFzZXRJZDogZGF0YXNldC5nZXRJZCgpLFxuICAgICAgZGF0YXNldDogZGF0YXNldC50b0pTT04oKSxcbiAgICAgIGZhY2V0SWQ6IGZhY2V0LmdldElkKClcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIHNldENhdGVnb3JpZXMgZmluZHMgZmluZHMgYWxsIHZhbHVlcyBvbiBhbiBvcmRpbmFsIChjYXRlZ29yaWFsKSBheGlzXG4gKiBVcGRhdGVzIHRoZSBjYXRlZ29yaWFsVHJhbnNmb3JtIG9mIHRoZSBmYWNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqL1xuZnVuY3Rpb24gc2V0Q2F0ZWdvcmllcyAoZGF0YXNldCwgZmFjZXQpIHtcbiAgLy8gRGF0YXNldCAtPiBEYXRhc2V0cyAtPiBTcG90XG4gIHZhciBzcG90ID0gZGF0YXNldC5jb2xsZWN0aW9uLnBhcmVudDtcblxuICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLnJlc2V0KCk7XG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldENhdGVnb3JpZXMnLCB7XG4gICAgICBkYXRhc2V0SWQ6IGRhdGFzZXQuZ2V0SWQoKSxcbiAgICAgIGZhY2V0SWQ6IGZhY2V0LmdldElkKClcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBzcG90LnNvY2tldC5lbWl0KCdzZXRDYXRlZ29yaWVzJywge1xuICAgICAgZGF0YXNldElkOiBkYXRhc2V0LmdldElkKCksXG4gICAgICBkYXRhc2V0OiBkYXRhc2V0LnRvSlNPTigpLFxuICAgICAgZmFjZXRJZDogZmFjZXQuZ2V0SWQoKVxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIDEwMCBwZXJjZW50aWxlcyAoaWUuIDEsMiwzLDQgZXRjLiksIGFuZCBpbml0aWFsaXplIHRoZSBgZmFjZXQuY29udGludW91c1RyYW5zZm9ybWBcbiAqXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXRcbiAqIEBwYXJhbSB7RmFjZXR9IGZhY2V0XG4gKi9cbmZ1bmN0aW9uIHNldFBlcmNlbnRpbGVzIChkYXRhc2V0LCBmYWNldCkge1xuICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgdmFyIHNwb3QgPSBkYXRhc2V0LmNvbGxlY3Rpb24ucGFyZW50O1xuXG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldFBlcmNlbnRpbGVzJywge1xuICAgICAgZGF0YXNldElkOiBkYXRhc2V0LmdldElkKCksXG4gICAgICBmYWNldElkOiBmYWNldC5nZXRJZCgpXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgc3BvdC5zb2NrZXQuZW1pdCgnc2V0UGVyY2VudGlsZXMnLCB7XG4gICAgICBkYXRhc2V0SWQ6IGRhdGFzZXQuZ2V0SWQoKSxcbiAgICAgIGRhdGFzZXQ6IGRhdGFzZXQudG9KU09OKCksXG4gICAgICBmYWNldElkOiBmYWNldC5nZXRJZCgpXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gaW5pdERhdGFGaWx0ZXIgKGRhdGF2aWV3LCBmaWx0ZXIpIHtcbiAgLy8gYXMgdGhlIFNRTCBzZXJ2ZXIgaW1wbGVtZW50YXRpb24gaXMgc3RhdGVsZXNzLCBub3RoaW5nIHRvIGRvIGhlcmVcbn1cblxuLyoqXG4gKiBUaGUgb3Bwb3NpdGUgb3IgaW5pdERhdGFGaWx0ZXIsIGl0IHNob3VsZCByZW1vdmUgdGhlIGZpbHRlciBhbmQgZGVhbGxvY2F0ZSBvdGhlciBjb25maWd1cmF0aW9uXG4gKiByZWxhdGVkIHRvIHRoZSBmaWx0ZXIuXG4gKiBAcGFyYW0ge0ZpbHRlcn0gZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHJlbGVhc2VEYXRhRmlsdGVyIChmaWx0ZXIpIHtcbiAgLy8gYXMgdGhlIFNRTCBzZXJ2ZXIgaW1wbGVtZW50YXRpb24gaXMgc3RhdGVsZXNzLCBub3RoaW5nIHRvIGRvIGhlcmVcbn1cblxuLyoqXG4gKiBDaGFuZ2UgdGhlIGZpbHRlciBwYXJhbWV0ZXJzIGZvciBhbiBpbml0aWFsaXplZCBmaWx0ZXJcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGF0YUZpbHRlciAoZmlsdGVyKSB7XG4gIC8vIGFzIHRoZSBTUUwgc2VydmVyIGltcGxlbWVudGF0aW9uIGlzIHN0YXRlbGVzcywgbm90aGluZyB0byBkbyBoZXJlXG59XG5cbi8qKlxuICogR2V0IGRhdGEgZm9yIGV2ZXJ5IGZpbHRlciwgYW5kIHRyaWdnZXIgYSAnbmV3RGF0YScgZXZlbnRcbiAqXG4gKiBSZXR1cm5zIGEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkYXRhdmlldyB3aGVuIGFsbCBkYXRhIGFuZCBtZXRhZGF0YSBoYXMgYmVlbiB1cGRhdGVkXG4gKlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEByZXR1cm5zIHtQcm9taXNlfVxuICovXG5mdW5jdGlvbiBnZXREYXRhIChkYXRhdmlldykge1xuICB2YXIgc3BvdCA9IGRhdGF2aWV3LnBhcmVudDtcblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgICAgc3BvdC5zb2NrZXQuZW1pdCgnZ2V0RGF0YScsIHtcbiAgICAgICAgZGF0YXZpZXc6IGRhdGF2aWV3LnRvSlNPTigpXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3BvdC5zb2NrZXQuZW1pdCgnZ2V0RGF0YScsIHtcbiAgICAgICAgZGF0YXNldHM6IHNwb3QuY2FjaGVkRGF0YXNldHMsXG4gICAgICAgIGRhdGF2aWV3OiBkYXRhdmlldy50b0pTT04oKVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZGF0YXZpZXcub25jZSgnbmV3TWV0YURhdGEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXNvbHZlKGRhdGF2aWV3KTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBkcml2ZXJUeXBlOiAnc2VydmVyJyxcbiAgc2Nhbjogc2NhbixcbiAgc2V0TWluTWF4OiBzZXRNaW5NYXgsXG4gIHNldENhdGVnb3JpZXM6IHNldENhdGVnb3JpZXMsXG4gIHNldFBlcmNlbnRpbGVzOiBzZXRQZXJjZW50aWxlcyxcbiAgaW5pdERhdGFGaWx0ZXI6IGluaXREYXRhRmlsdGVyLFxuICByZWxlYXNlRGF0YUZpbHRlcjogcmVsZWFzZURhdGFGaWx0ZXIsXG4gIHVwZGF0ZURhdGFGaWx0ZXI6IHVwZGF0ZURhdGFGaWx0ZXIsXG4gIGdldERhdGE6IGdldERhdGFcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///072d\n")},"09c5":function(module,exports,__webpack_require__){eval("/**\n * A single control point for a continuous transform\n *\n * @class ControlPoint\n */\nvar BaseModel = __webpack_require__(/*! ../util/base */ \"3902\");\n\n// Data structure for mapping categorial (and textual) data on groups\nmodule.exports = BaseModel.extend({\n  props: {\n    /**\n     * Value\n     * @type {number}\n     * @memberof! ContinuousRule\n     */\n    x: 'number',\n\n    /**\n     * Transformed value\n     * @type {number}\n     * @memberof! ContinuousRule\n     */\n    fx: 'number'\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDljNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29udHJvbC1wb2ludC5qcz82OTJiIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQSBzaW5nbGUgY29udHJvbCBwb2ludCBmb3IgYSBjb250aW51b3VzIHRyYW5zZm9ybVxuICpcbiAqIEBjbGFzcyBDb250cm9sUG9pbnRcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4uL3V0aWwvYmFzZScpO1xuXG4vLyBEYXRhIHN0cnVjdHVyZSBmb3IgbWFwcGluZyBjYXRlZ29yaWFsIChhbmQgdGV4dHVhbCkgZGF0YSBvbiBncm91cHNcbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVmFsdWVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1J1bGVcbiAgICAgKi9cbiAgICB4OiAnbnVtYmVyJyxcblxuICAgIC8qKlxuICAgICAqIFRyYW5zZm9ybWVkIHZhbHVlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNSdWxlXG4gICAgICovXG4gICAgZng6ICdudW1iZXInXG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///09c5\n")},"0b10":function(module,exports){eval("/**\n * Helpers.\n */\n\nvar s = 1000\nvar m = s * 60\nvar h = m * 60\nvar d = h * 24\nvar y = d * 365.25\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function (val, options) {\n  options = options || {}\n  var type = typeof val\n  if (type === 'string' && val.length > 0) {\n    return parse(val)\n  } else if (type === 'number' && isNaN(val) === false) {\n    return options.long ?\n\t\t\tfmtLong(val) :\n\t\t\tfmtShort(val)\n  }\n  throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val))\n}\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n  str = String(str)\n  if (str.length > 10000) {\n    return\n  }\n  var match = /^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str)\n  if (!match) {\n    return\n  }\n  var n = parseFloat(match[1])\n  var type = (match[2] || 'ms').toLowerCase()\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'yrs':\n    case 'yr':\n    case 'y':\n      return n * y\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d\n    case 'hours':\n    case 'hour':\n    case 'hrs':\n    case 'hr':\n    case 'h':\n      return n * h\n    case 'minutes':\n    case 'minute':\n    case 'mins':\n    case 'min':\n    case 'm':\n      return n * m\n    case 'seconds':\n    case 'second':\n    case 'secs':\n    case 'sec':\n    case 's':\n      return n * s\n    case 'milliseconds':\n    case 'millisecond':\n    case 'msecs':\n    case 'msec':\n    case 'ms':\n      return n\n    default:\n      return undefined\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtShort(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd'\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h'\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm'\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's'\n  }\n  return ms + 'ms'\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtLong(ms) {\n  return plural(ms, d, 'day') ||\n    plural(ms, h, 'hour') ||\n    plural(ms, m, 'minute') ||\n    plural(ms, s, 'second') ||\n    ms + ' ms'\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's'\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMGIxMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvbXMvaW5kZXguanM/YjZlOCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhlbHBlcnMuXG4gKi9cblxudmFyIHMgPSAxMDAwXG52YXIgbSA9IHMgKiA2MFxudmFyIGggPSBtICogNjBcbnZhciBkID0gaCAqIDI0XG52YXIgeSA9IGQgKiAzNjUuMjVcblxuLyoqXG4gKiBQYXJzZSBvciBmb3JtYXQgdGhlIGdpdmVuIGB2YWxgLlxuICpcbiAqIE9wdGlvbnM6XG4gKlxuICogIC0gYGxvbmdgIHZlcmJvc2UgZm9ybWF0dGluZyBbZmFsc2VdXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSB2YWxcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhyb3cgYW4gZXJyb3IgaWYgdmFsIGlzIG5vdCBhIG5vbi1lbXB0eSBzdHJpbmcgb3IgYSBudW1iZXJcbiAqIEByZXR1cm4ge1N0cmluZ3xOdW1iZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHZhbCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWxcbiAgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIHZhbC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHBhcnNlKHZhbClcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBpc05hTih2YWwpID09PSBmYWxzZSkge1xuICAgIHJldHVybiBvcHRpb25zLmxvbmcgP1xuXHRcdFx0Zm10TG9uZyh2YWwpIDpcblx0XHRcdGZtdFNob3J0KHZhbClcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ3ZhbCBpcyBub3QgYSBub24tZW1wdHkgc3RyaW5nIG9yIGEgdmFsaWQgbnVtYmVyLiB2YWw9JyArIEpTT04uc3RyaW5naWZ5KHZhbCkpXG59XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGBzdHJgIGFuZCByZXR1cm4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlKHN0cikge1xuICBzdHIgPSBTdHJpbmcoc3RyKVxuICBpZiAoc3RyLmxlbmd0aCA+IDEwMDAwKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIG1hdGNoID0gL14oKD86XFxkKyk/XFwuP1xcZCspICoobWlsbGlzZWNvbmRzP3xtc2Vjcz98bXN8c2Vjb25kcz98c2Vjcz98c3xtaW51dGVzP3xtaW5zP3xtfGhvdXJzP3xocnM/fGh8ZGF5cz98ZHx5ZWFycz98eXJzP3x5KT8kL2kuZXhlYyhzdHIpXG4gIGlmICghbWF0Y2gpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgbiA9IHBhcnNlRmxvYXQobWF0Y2hbMV0pXG4gIHZhciB0eXBlID0gKG1hdGNoWzJdIHx8ICdtcycpLnRvTG93ZXJDYXNlKClcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAneWVhcnMnOlxuICAgIGNhc2UgJ3llYXInOlxuICAgIGNhc2UgJ3lycyc6XG4gICAgY2FzZSAneXInOlxuICAgIGNhc2UgJ3knOlxuICAgICAgcmV0dXJuIG4gKiB5XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZFxuICAgIGNhc2UgJ2hvdXJzJzpcbiAgICBjYXNlICdob3VyJzpcbiAgICBjYXNlICdocnMnOlxuICAgIGNhc2UgJ2hyJzpcbiAgICBjYXNlICdoJzpcbiAgICAgIHJldHVybiBuICogaFxuICAgIGNhc2UgJ21pbnV0ZXMnOlxuICAgIGNhc2UgJ21pbnV0ZSc6XG4gICAgY2FzZSAnbWlucyc6XG4gICAgY2FzZSAnbWluJzpcbiAgICBjYXNlICdtJzpcbiAgICAgIHJldHVybiBuICogbVxuICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgY2FzZSAnc2Vjcyc6XG4gICAgY2FzZSAnc2VjJzpcbiAgICBjYXNlICdzJzpcbiAgICAgIHJldHVybiBuICogc1xuICAgIGNhc2UgJ21pbGxpc2Vjb25kcyc6XG4gICAgY2FzZSAnbWlsbGlzZWNvbmQnOlxuICAgIGNhc2UgJ21zZWNzJzpcbiAgICBjYXNlICdtc2VjJzpcbiAgICBjYXNlICdtcyc6XG4gICAgICByZXR1cm4gblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuLyoqXG4gKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBmbXRTaG9ydChtcykge1xuICBpZiAobXMgPj0gZCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gZCkgKyAnZCdcbiAgfVxuICBpZiAobXMgPj0gaCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gaCkgKyAnaCdcbiAgfVxuICBpZiAobXMgPj0gbSkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gbSkgKyAnbSdcbiAgfVxuICBpZiAobXMgPj0gcykge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gcykgKyAncydcbiAgfVxuICByZXR1cm4gbXMgKyAnbXMnXG59XG5cbi8qKlxuICogTG9uZyBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBmbXRMb25nKG1zKSB7XG4gIHJldHVybiBwbHVyYWwobXMsIGQsICdkYXknKSB8fFxuICAgIHBsdXJhbChtcywgaCwgJ2hvdXInKSB8fFxuICAgIHBsdXJhbChtcywgbSwgJ21pbnV0ZScpIHx8XG4gICAgcGx1cmFsKG1zLCBzLCAnc2Vjb25kJykgfHxcbiAgICBtcyArICcgbXMnXG59XG5cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi9cblxuZnVuY3Rpb24gcGx1cmFsKG1zLCBuLCBuYW1lKSB7XG4gIGlmIChtcyA8IG4pIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAobXMgPCBuICogMS41KSB7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IobXMgLyBuKSArICcgJyArIG5hbWVcbiAgfVxuICByZXR1cm4gTWF0aC5jZWlsKG1zIC8gbikgKyAnICcgKyBuYW1lICsgJ3MnXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0b10\n")},"0d97":function(module,exports,__webpack_require__){eval("/**\n * Module dependencies.\n */\n\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = Transport;\n\n/**\n * Transport abstract constructor.\n *\n * @param {Object} options.\n * @api private\n */\n\nfunction Transport (opts) {\n  this.path = opts.path;\n  this.hostname = opts.hostname;\n  this.port = opts.port;\n  this.secure = opts.secure;\n  this.query = opts.query;\n  this.timestampParam = opts.timestampParam;\n  this.timestampRequests = opts.timestampRequests;\n  this.readyState = '';\n  this.agent = opts.agent || false;\n  this.socket = opts.socket;\n  this.enablesXDR = opts.enablesXDR;\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx;\n  this.key = opts.key;\n  this.passphrase = opts.passphrase;\n  this.cert = opts.cert;\n  this.ca = opts.ca;\n  this.ciphers = opts.ciphers;\n  this.rejectUnauthorized = opts.rejectUnauthorized;\n  this.forceNode = opts.forceNode;\n\n  // other options for Node.js client\n  this.extraHeaders = opts.extraHeaders;\n  this.localAddress = opts.localAddress;\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Transport.prototype);\n\n/**\n * Emits an error.\n *\n * @param {String} str\n * @return {Transport} for chaining\n * @api public\n */\n\nTransport.prototype.onError = function (msg, desc) {\n  var err = new Error(msg);\n  err.type = 'TransportError';\n  err.description = desc;\n  this.emit('error', err);\n  return this;\n};\n\n/**\n * Opens the transport.\n *\n * @api public\n */\n\nTransport.prototype.open = function () {\n  if ('closed' === this.readyState || '' === this.readyState) {\n    this.readyState = 'opening';\n    this.doOpen();\n  }\n\n  return this;\n};\n\n/**\n * Closes the transport.\n *\n * @api private\n */\n\nTransport.prototype.close = function () {\n  if ('opening' === this.readyState || 'open' === this.readyState) {\n    this.doClose();\n    this.onClose();\n  }\n\n  return this;\n};\n\n/**\n * Sends multiple packets.\n *\n * @param {Array} packets\n * @api private\n */\n\nTransport.prototype.send = function (packets) {\n  if ('open' === this.readyState) {\n    this.write(packets);\n  } else {\n    throw new Error('Transport not open');\n  }\n};\n\n/**\n * Called upon open\n *\n * @api private\n */\n\nTransport.prototype.onOpen = function () {\n  this.readyState = 'open';\n  this.writable = true;\n  this.emit('open');\n};\n\n/**\n * Called with data.\n *\n * @param {String} data\n * @api private\n */\n\nTransport.prototype.onData = function (data) {\n  var packet = parser.decodePacket(data, this.socket.binaryType);\n  this.onPacket(packet);\n};\n\n/**\n * Called with a decoded packet.\n */\n\nTransport.prototype.onPacket = function (packet) {\n  this.emit('packet', packet);\n};\n\n/**\n * Called upon close.\n *\n * @api private\n */\n\nTransport.prototype.onClose = function () {\n  this.readyState = 'closed';\n  this.emit('close');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMGQ5Ny5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0LmpzPzMxMmIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBwYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc3BvcnQ7XG5cbi8qKlxuICogVHJhbnNwb3J0IGFic3RyYWN0IGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gVHJhbnNwb3J0IChvcHRzKSB7XG4gIHRoaXMucGF0aCA9IG9wdHMucGF0aDtcbiAgdGhpcy5ob3N0bmFtZSA9IG9wdHMuaG9zdG5hbWU7XG4gIHRoaXMucG9ydCA9IG9wdHMucG9ydDtcbiAgdGhpcy5zZWN1cmUgPSBvcHRzLnNlY3VyZTtcbiAgdGhpcy5xdWVyeSA9IG9wdHMucXVlcnk7XG4gIHRoaXMudGltZXN0YW1wUGFyYW0gPSBvcHRzLnRpbWVzdGFtcFBhcmFtO1xuICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50IHx8IGZhbHNlO1xuICB0aGlzLnNvY2tldCA9IG9wdHMuc29ja2V0O1xuICB0aGlzLmVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG5cbiAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIHRoaXMucGZ4ID0gb3B0cy5wZng7XG4gIHRoaXMua2V5ID0gb3B0cy5rZXk7XG4gIHRoaXMucGFzc3BocmFzZSA9IG9wdHMucGFzc3BocmFzZTtcbiAgdGhpcy5jZXJ0ID0gb3B0cy5jZXJ0O1xuICB0aGlzLmNhID0gb3B0cy5jYTtcbiAgdGhpcy5jaXBoZXJzID0gb3B0cy5jaXBoZXJzO1xuICB0aGlzLnJlamVjdFVuYXV0aG9yaXplZCA9IG9wdHMucmVqZWN0VW5hdXRob3JpemVkO1xuICB0aGlzLmZvcmNlTm9kZSA9IG9wdHMuZm9yY2VOb2RlO1xuXG4gIC8vIG90aGVyIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIHRoaXMuZXh0cmFIZWFkZXJzID0gb3B0cy5leHRyYUhlYWRlcnM7XG4gIHRoaXMubG9jYWxBZGRyZXNzID0gb3B0cy5sb2NhbEFkZHJlc3M7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFRyYW5zcG9ydC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIEVtaXRzIGFuIGVycm9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge1RyYW5zcG9ydH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uIChtc2csIGRlc2MpIHtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcihtc2cpO1xuICBlcnIudHlwZSA9ICdUcmFuc3BvcnRFcnJvcic7XG4gIGVyci5kZXNjcmlwdGlvbiA9IGRlc2M7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3BlbnMgdGhlIHRyYW5zcG9ydC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCdjbG9zZWQnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJycgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcbiAgICB0aGlzLmRvT3BlbigpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENsb3NlcyB0aGUgdHJhbnNwb3J0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMuZG9DbG9zZSgpO1xuICAgIHRoaXMub25DbG9zZSgpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIG11bHRpcGxlIHBhY2tldHMuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFja2V0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuVHJhbnNwb3J0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKHBhY2tldHMpIHtcbiAgaWYgKCdvcGVuJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgdGhpcy53cml0ZShwYWNrZXRzKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zcG9ydCBub3Qgb3BlbicpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIG9wZW5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW4nO1xuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcbiAgdGhpcy5lbWl0KCdvcGVuJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIGRhdGEuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGFcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdmFyIHBhY2tldCA9IHBhcnNlci5kZWNvZGVQYWNrZXQoZGF0YSwgdGhpcy5zb2NrZXQuYmluYXJ5VHlwZSk7XG4gIHRoaXMub25QYWNrZXQocGFja2V0KTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHdpdGggYSBkZWNvZGVkIHBhY2tldC5cbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uUGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICB0aGlzLmVtaXQoJ3BhY2tldCcsIHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGNsb3NlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0d97\n")},"108d":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module requirements.\n */\n\nvar XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ \"86e3\");\nvar Polling = __webpack_require__(/*! ./polling */ \"181d\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:polling-xhr');\n\n/**\n * Module exports.\n */\n\nmodule.exports = XHR;\nmodule.exports.Request = Request;\n\n/**\n * Empty function\n */\n\nfunction empty () {}\n\n/**\n * XHR Polling constructor.\n *\n * @param {Object} opts\n * @api public\n */\n\nfunction XHR (opts) {\n  Polling.call(this, opts);\n  this.requestTimeout = opts.requestTimeout;\n\n  if (global.location) {\n    var isSSL = 'https:' === location.protocol;\n    var port = location.port;\n\n    // some user agents have empty `location.port`\n    if (!port) {\n      port = isSSL ? 443 : 80;\n    }\n\n    this.xd = opts.hostname !== global.location.hostname ||\n      port !== opts.port;\n    this.xs = opts.secure !== isSSL;\n  } else {\n    this.extraHeaders = opts.extraHeaders;\n  }\n}\n\n/**\n * Inherits from Polling.\n */\n\ninherit(XHR, Polling);\n\n/**\n * XHR supports binary\n */\n\nXHR.prototype.supportsBinary = true;\n\n/**\n * Creates a request.\n *\n * @param {String} method\n * @api private\n */\n\nXHR.prototype.request = function (opts) {\n  opts = opts || {};\n  opts.uri = this.uri();\n  opts.xd = this.xd;\n  opts.xs = this.xs;\n  opts.agent = this.agent || false;\n  opts.supportsBinary = this.supportsBinary;\n  opts.enablesXDR = this.enablesXDR;\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n  opts.requestTimeout = this.requestTimeout;\n\n  // other options for Node.js client\n  opts.extraHeaders = this.extraHeaders;\n\n  return new Request(opts);\n};\n\n/**\n * Sends data.\n *\n * @param {String} data to send.\n * @param {Function} called upon flush.\n * @api private\n */\n\nXHR.prototype.doWrite = function (data, fn) {\n  var isBinary = typeof data !== 'string' && data !== undefined;\n  var req = this.request({ method: 'POST', data: data, isBinary: isBinary });\n  var self = this;\n  req.on('success', fn);\n  req.on('error', function (err) {\n    self.onError('xhr post error', err);\n  });\n  this.sendXhr = req;\n};\n\n/**\n * Starts a poll cycle.\n *\n * @api private\n */\n\nXHR.prototype.doPoll = function () {\n  debug('xhr poll');\n  var req = this.request();\n  var self = this;\n  req.on('data', function (data) {\n    self.onData(data);\n  });\n  req.on('error', function (err) {\n    self.onError('xhr poll error', err);\n  });\n  this.pollXhr = req;\n};\n\n/**\n * Request constructor\n *\n * @param {Object} options\n * @api public\n */\n\nfunction Request (opts) {\n  this.method = opts.method || 'GET';\n  this.uri = opts.uri;\n  this.xd = !!opts.xd;\n  this.xs = !!opts.xs;\n  this.async = false !== opts.async;\n  this.data = undefined !== opts.data ? opts.data : null;\n  this.agent = opts.agent;\n  this.isBinary = opts.isBinary;\n  this.supportsBinary = opts.supportsBinary;\n  this.enablesXDR = opts.enablesXDR;\n  this.requestTimeout = opts.requestTimeout;\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx;\n  this.key = opts.key;\n  this.passphrase = opts.passphrase;\n  this.cert = opts.cert;\n  this.ca = opts.ca;\n  this.ciphers = opts.ciphers;\n  this.rejectUnauthorized = opts.rejectUnauthorized;\n\n  // other options for Node.js client\n  this.extraHeaders = opts.extraHeaders;\n\n  this.create();\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Request.prototype);\n\n/**\n * Creates the XHR object and sends the request.\n *\n * @api private\n */\n\nRequest.prototype.create = function () {\n  var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR };\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n\n  var xhr = this.xhr = new XMLHttpRequest(opts);\n  var self = this;\n\n  try {\n    debug('xhr open %s: %s', this.method, this.uri);\n    xhr.open(this.method, this.uri, this.async);\n    try {\n      if (this.extraHeaders) {\n        xhr.setDisableHeaderCheck(true);\n        for (var i in this.extraHeaders) {\n          if (this.extraHeaders.hasOwnProperty(i)) {\n            xhr.setRequestHeader(i, this.extraHeaders[i]);\n          }\n        }\n      }\n    } catch (e) {}\n    if (this.supportsBinary) {\n      // This has to be done after open because Firefox is stupid\n      // http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension\n      xhr.responseType = 'arraybuffer';\n    }\n\n    if ('POST' === this.method) {\n      try {\n        if (this.isBinary) {\n          xhr.setRequestHeader('Content-type', 'application/octet-stream');\n        } else {\n          xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');\n        }\n      } catch (e) {}\n    }\n\n    try {\n      xhr.setRequestHeader('Accept', '*/*');\n    } catch (e) {}\n\n    // ie6 check\n    if ('withCredentials' in xhr) {\n      xhr.withCredentials = true;\n    }\n\n    if (this.requestTimeout) {\n      xhr.timeout = this.requestTimeout;\n    }\n\n    if (this.hasXDR()) {\n      xhr.onload = function () {\n        self.onLoad();\n      };\n      xhr.onerror = function () {\n        self.onError(xhr.responseText);\n      };\n    } else {\n      xhr.onreadystatechange = function () {\n        if (4 !== xhr.readyState) return;\n        if (200 === xhr.status || 1223 === xhr.status) {\n          self.onLoad();\n        } else {\n          // make sure the `error` event handler that's user-set\n          // does not throw in the same tick and gets caught here\n          setTimeout(function () {\n            self.onError(xhr.status);\n          }, 0);\n        }\n      };\n    }\n\n    debug('xhr data %s', this.data);\n    xhr.send(this.data);\n  } catch (e) {\n    // Need to defer since .create() is called directly fhrom the constructor\n    // and thus the 'error' event can only be only bound *after* this exception\n    // occurs.  Therefore, also, we cannot throw here at all.\n    setTimeout(function () {\n      self.onError(e);\n    }, 0);\n    return;\n  }\n\n  if (global.document) {\n    this.index = Request.requestsCount++;\n    Request.requests[this.index] = this;\n  }\n};\n\n/**\n * Called upon successful response.\n *\n * @api private\n */\n\nRequest.prototype.onSuccess = function () {\n  this.emit('success');\n  this.cleanup();\n};\n\n/**\n * Called if we have data.\n *\n * @api private\n */\n\nRequest.prototype.onData = function (data) {\n  this.emit('data', data);\n  this.onSuccess();\n};\n\n/**\n * Called upon error.\n *\n * @api private\n */\n\nRequest.prototype.onError = function (err) {\n  this.emit('error', err);\n  this.cleanup(true);\n};\n\n/**\n * Cleans up house.\n *\n * @api private\n */\n\nRequest.prototype.cleanup = function (fromError) {\n  if ('undefined' === typeof this.xhr || null === this.xhr) {\n    return;\n  }\n  // xmlhttprequest\n  if (this.hasXDR()) {\n    this.xhr.onload = this.xhr.onerror = empty;\n  } else {\n    this.xhr.onreadystatechange = empty;\n  }\n\n  if (fromError) {\n    try {\n      this.xhr.abort();\n    } catch (e) {}\n  }\n\n  if (global.document) {\n    delete Request.requests[this.index];\n  }\n\n  this.xhr = null;\n};\n\n/**\n * Called upon load.\n *\n * @api private\n */\n\nRequest.prototype.onLoad = function () {\n  var data;\n  try {\n    var contentType;\n    try {\n      contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0];\n    } catch (e) {}\n    if (contentType === 'application/octet-stream') {\n      data = this.xhr.response || this.xhr.responseText;\n    } else {\n      if (!this.supportsBinary) {\n        data = this.xhr.responseText;\n      } else {\n        try {\n          data = String.fromCharCode.apply(null, new Uint8Array(this.xhr.response));\n        } catch (e) {\n          var ui8Arr = new Uint8Array(this.xhr.response);\n          var dataArray = [];\n          for (var idx = 0, length = ui8Arr.length; idx < length; idx++) {\n            dataArray.push(ui8Arr[idx]);\n          }\n\n          data = String.fromCharCode.apply(null, dataArray);\n        }\n      }\n    }\n  } catch (e) {\n    this.onError(e);\n  }\n  if (null != data) {\n    this.onData(data);\n  }\n};\n\n/**\n * Check if it has XDomainRequest.\n *\n * @api private\n */\n\nRequest.prototype.hasXDR = function () {\n  return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR;\n};\n\n/**\n * Aborts the request.\n *\n * @api public\n */\n\nRequest.prototype.abort = function () {\n  this.cleanup();\n};\n\n/**\n * Aborts pending requests when unloading the window. This is needed to prevent\n * memory leaks (e.g. when using IE) and to ensure that no spurious error is\n * emitted.\n */\n\nRequest.requestsCount = 0;\nRequest.requests = {};\n\nif (global.document) {\n  if (global.attachEvent) {\n    global.attachEvent('onunload', unloadHandler);\n  } else if (global.addEventListener) {\n    global.addEventListener('beforeunload', unloadHandler, false);\n  }\n}\n\nfunction unloadHandler () {\n  for (var i in Request.requests) {\n    if (Request.requests.hasOwnProperty(i)) {\n      Request.requests[i].abort();\n    }\n  }\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA4ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLXhoci5qcz9mYmY3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAqL1xuXG52YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdC1zc2wnKTtcbnZhciBQb2xsaW5nID0gcmVxdWlyZSgnLi9wb2xsaW5nJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgaW5oZXJpdCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1pbmhlcml0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnBvbGxpbmcteGhyJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBYSFI7XG5tb2R1bGUuZXhwb3J0cy5SZXF1ZXN0ID0gUmVxdWVzdDtcblxuLyoqXG4gKiBFbXB0eSBmdW5jdGlvblxuICovXG5cbmZ1bmN0aW9uIGVtcHR5ICgpIHt9XG5cbi8qKlxuICogWEhSIFBvbGxpbmcgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gWEhSIChvcHRzKSB7XG4gIFBvbGxpbmcuY2FsbCh0aGlzLCBvcHRzKTtcbiAgdGhpcy5yZXF1ZXN0VGltZW91dCA9IG9wdHMucmVxdWVzdFRpbWVvdXQ7XG5cbiAgaWYgKGdsb2JhbC5sb2NhdGlvbikge1xuICAgIHZhciBpc1NTTCA9ICdodHRwczonID09PSBsb2NhdGlvbi5wcm90b2NvbDtcbiAgICB2YXIgcG9ydCA9IGxvY2F0aW9uLnBvcnQ7XG5cbiAgICAvLyBzb21lIHVzZXIgYWdlbnRzIGhhdmUgZW1wdHkgYGxvY2F0aW9uLnBvcnRgXG4gICAgaWYgKCFwb3J0KSB7XG4gICAgICBwb3J0ID0gaXNTU0wgPyA0NDMgOiA4MDtcbiAgICB9XG5cbiAgICB0aGlzLnhkID0gb3B0cy5ob3N0bmFtZSAhPT0gZ2xvYmFsLmxvY2F0aW9uLmhvc3RuYW1lIHx8XG4gICAgICBwb3J0ICE9PSBvcHRzLnBvcnQ7XG4gICAgdGhpcy54cyA9IG9wdHMuc2VjdXJlICE9PSBpc1NTTDtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuICB9XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBQb2xsaW5nLlxuICovXG5cbmluaGVyaXQoWEhSLCBQb2xsaW5nKTtcblxuLyoqXG4gKiBYSFIgc3VwcG9ydHMgYmluYXJ5XG4gKi9cblxuWEhSLnByb3RvdHlwZS5zdXBwb3J0c0JpbmFyeSA9IHRydWU7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHJlcXVlc3QuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuWEhSLnByb3RvdHlwZS5yZXF1ZXN0ID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgb3B0cyA9IG9wdHMgfHwge307XG4gIG9wdHMudXJpID0gdGhpcy51cmkoKTtcbiAgb3B0cy54ZCA9IHRoaXMueGQ7XG4gIG9wdHMueHMgPSB0aGlzLnhzO1xuICBvcHRzLmFnZW50ID0gdGhpcy5hZ2VudCB8fCBmYWxzZTtcbiAgb3B0cy5zdXBwb3J0c0JpbmFyeSA9IHRoaXMuc3VwcG9ydHNCaW5hcnk7XG4gIG9wdHMuZW5hYmxlc1hEUiA9IHRoaXMuZW5hYmxlc1hEUjtcblxuICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgb3B0cy5wZnggPSB0aGlzLnBmeDtcbiAgb3B0cy5rZXkgPSB0aGlzLmtleTtcbiAgb3B0cy5wYXNzcGhyYXNlID0gdGhpcy5wYXNzcGhyYXNlO1xuICBvcHRzLmNlcnQgPSB0aGlzLmNlcnQ7XG4gIG9wdHMuY2EgPSB0aGlzLmNhO1xuICBvcHRzLmNpcGhlcnMgPSB0aGlzLmNpcGhlcnM7XG4gIG9wdHMucmVqZWN0VW5hdXRob3JpemVkID0gdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQ7XG4gIG9wdHMucmVxdWVzdFRpbWVvdXQgPSB0aGlzLnJlcXVlc3RUaW1lb3V0O1xuXG4gIC8vIG90aGVyIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIG9wdHMuZXh0cmFIZWFkZXJzID0gdGhpcy5leHRyYUhlYWRlcnM7XG5cbiAgcmV0dXJuIG5ldyBSZXF1ZXN0KG9wdHMpO1xufTtcblxuLyoqXG4gKiBTZW5kcyBkYXRhLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIHRvIHNlbmQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblhIUi5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uIChkYXRhLCBmbikge1xuICB2YXIgaXNCaW5hcnkgPSB0eXBlb2YgZGF0YSAhPT0gJ3N0cmluZycgJiYgZGF0YSAhPT0gdW5kZWZpbmVkO1xuICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KHsgbWV0aG9kOiAnUE9TVCcsIGRhdGE6IGRhdGEsIGlzQmluYXJ5OiBpc0JpbmFyeSB9KTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICByZXEub24oJ3N1Y2Nlc3MnLCBmbik7XG4gIHJlcS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgc2VsZi5vbkVycm9yKCd4aHIgcG9zdCBlcnJvcicsIGVycik7XG4gIH0pO1xuICB0aGlzLnNlbmRYaHIgPSByZXE7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuWEhSLnByb3RvdHlwZS5kb1BvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCd4aHIgcG9sbCcpO1xuICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KCk7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgcmVxLm9uKCdkYXRhJywgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBzZWxmLm9uRGF0YShkYXRhKTtcbiAgfSk7XG4gIHJlcS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgc2VsZi5vbkVycm9yKCd4aHIgcG9sbCBlcnJvcicsIGVycik7XG4gIH0pO1xuICB0aGlzLnBvbGxYaHIgPSByZXE7XG59O1xuXG4vKipcbiAqIFJlcXVlc3QgY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0IChvcHRzKSB7XG4gIHRoaXMubWV0aG9kID0gb3B0cy5tZXRob2QgfHwgJ0dFVCc7XG4gIHRoaXMudXJpID0gb3B0cy51cmk7XG4gIHRoaXMueGQgPSAhIW9wdHMueGQ7XG4gIHRoaXMueHMgPSAhIW9wdHMueHM7XG4gIHRoaXMuYXN5bmMgPSBmYWxzZSAhPT0gb3B0cy5hc3luYztcbiAgdGhpcy5kYXRhID0gdW5kZWZpbmVkICE9PSBvcHRzLmRhdGEgPyBvcHRzLmRhdGEgOiBudWxsO1xuICB0aGlzLmFnZW50ID0gb3B0cy5hZ2VudDtcbiAgdGhpcy5pc0JpbmFyeSA9IG9wdHMuaXNCaW5hcnk7XG4gIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSBvcHRzLnN1cHBvcnRzQmluYXJ5O1xuICB0aGlzLmVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG4gIHRoaXMucmVxdWVzdFRpbWVvdXQgPSBvcHRzLnJlcXVlc3RUaW1lb3V0O1xuXG4gIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLnBmeCA9IG9wdHMucGZ4O1xuICB0aGlzLmtleSA9IG9wdHMua2V5O1xuICB0aGlzLnBhc3NwaHJhc2UgPSBvcHRzLnBhc3NwaHJhc2U7XG4gIHRoaXMuY2VydCA9IG9wdHMuY2VydDtcbiAgdGhpcy5jYSA9IG9wdHMuY2E7XG4gIHRoaXMuY2lwaGVycyA9IG9wdHMuY2lwaGVycztcbiAgdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQgPSBvcHRzLnJlamVjdFVuYXV0aG9yaXplZDtcblxuICAvLyBvdGhlciBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuXG4gIHRoaXMuY3JlYXRlKCk7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFJlcXVlc3QucHJvdG90eXBlKTtcblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBYSFIgb2JqZWN0IGFuZCBzZW5kcyB0aGUgcmVxdWVzdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBvcHRzID0geyBhZ2VudDogdGhpcy5hZ2VudCwgeGRvbWFpbjogdGhpcy54ZCwgeHNjaGVtZTogdGhpcy54cywgZW5hYmxlc1hEUjogdGhpcy5lbmFibGVzWERSIH07XG5cbiAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIG9wdHMucGZ4ID0gdGhpcy5wZng7XG4gIG9wdHMua2V5ID0gdGhpcy5rZXk7XG4gIG9wdHMucGFzc3BocmFzZSA9IHRoaXMucGFzc3BocmFzZTtcbiAgb3B0cy5jZXJ0ID0gdGhpcy5jZXJ0O1xuICBvcHRzLmNhID0gdGhpcy5jYTtcbiAgb3B0cy5jaXBoZXJzID0gdGhpcy5jaXBoZXJzO1xuICBvcHRzLnJlamVjdFVuYXV0aG9yaXplZCA9IHRoaXMucmVqZWN0VW5hdXRob3JpemVkO1xuXG4gIHZhciB4aHIgPSB0aGlzLnhociA9IG5ldyBYTUxIdHRwUmVxdWVzdChvcHRzKTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRyeSB7XG4gICAgZGVidWcoJ3hociBvcGVuICVzOiAlcycsIHRoaXMubWV0aG9kLCB0aGlzLnVyaSk7XG4gICAgeGhyLm9wZW4odGhpcy5tZXRob2QsIHRoaXMudXJpLCB0aGlzLmFzeW5jKTtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuZXh0cmFIZWFkZXJzKSB7XG4gICAgICAgIHhoci5zZXREaXNhYmxlSGVhZGVyQ2hlY2sodHJ1ZSk7XG4gICAgICAgIGZvciAodmFyIGkgaW4gdGhpcy5leHRyYUhlYWRlcnMpIHtcbiAgICAgICAgICBpZiAodGhpcy5leHRyYUhlYWRlcnMuaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGksIHRoaXMuZXh0cmFIZWFkZXJzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIGlmICh0aGlzLnN1cHBvcnRzQmluYXJ5KSB7XG4gICAgICAvLyBUaGlzIGhhcyB0byBiZSBkb25lIGFmdGVyIG9wZW4gYmVjYXVzZSBGaXJlZm94IGlzIHN0dXBpZFxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMzIxNjkwMy9nZXQtYmluYXJ5LWRhdGEtd2l0aC14bWxodHRwcmVxdWVzdC1pbi1hLWZpcmVmb3gtZXh0ZW5zaW9uXG4gICAgICB4aHIucmVzcG9uc2VUeXBlID0gJ2FycmF5YnVmZmVyJztcbiAgICB9XG5cbiAgICBpZiAoJ1BPU1QnID09PSB0aGlzLm1ldGhvZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHRoaXMuaXNCaW5hcnkpIHtcbiAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdBY2NlcHQnLCAnKi8qJyk7XG4gICAgfSBjYXRjaCAoZSkge31cblxuICAgIC8vIGllNiBjaGVja1xuICAgIGlmICgnd2l0aENyZWRlbnRpYWxzJyBpbiB4aHIpIHtcbiAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnJlcXVlc3RUaW1lb3V0KSB7XG4gICAgICB4aHIudGltZW91dCA9IHRoaXMucmVxdWVzdFRpbWVvdXQ7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaGFzWERSKCkpIHtcbiAgICAgIHhoci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYub25Mb2FkKCk7XG4gICAgICB9O1xuICAgICAgeGhyLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYub25FcnJvcih4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICg0ICE9PSB4aHIucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICBpZiAoMjAwID09PSB4aHIuc3RhdHVzIHx8IDEyMjMgPT09IHhoci5zdGF0dXMpIHtcbiAgICAgICAgICBzZWxmLm9uTG9hZCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgYGVycm9yYCBldmVudCBoYW5kbGVyIHRoYXQncyB1c2VyLXNldFxuICAgICAgICAgIC8vIGRvZXMgbm90IHRocm93IGluIHRoZSBzYW1lIHRpY2sgYW5kIGdldHMgY2F1Z2h0IGhlcmVcbiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNlbGYub25FcnJvcih4aHIuc3RhdHVzKTtcbiAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBkZWJ1ZygneGhyIGRhdGEgJXMnLCB0aGlzLmRhdGEpO1xuICAgIHhoci5zZW5kKHRoaXMuZGF0YSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBOZWVkIHRvIGRlZmVyIHNpbmNlIC5jcmVhdGUoKSBpcyBjYWxsZWQgZGlyZWN0bHkgZmhyb20gdGhlIGNvbnN0cnVjdG9yXG4gICAgLy8gYW5kIHRodXMgdGhlICdlcnJvcicgZXZlbnQgY2FuIG9ubHkgYmUgb25seSBib3VuZCAqYWZ0ZXIqIHRoaXMgZXhjZXB0aW9uXG4gICAgLy8gb2NjdXJzLiAgVGhlcmVmb3JlLCBhbHNvLCB3ZSBjYW5ub3QgdGhyb3cgaGVyZSBhdCBhbGwuXG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBzZWxmLm9uRXJyb3IoZSk7XG4gICAgfSwgMCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGdsb2JhbC5kb2N1bWVudCkge1xuICAgIHRoaXMuaW5kZXggPSBSZXF1ZXN0LnJlcXVlc3RzQ291bnQrKztcbiAgICBSZXF1ZXN0LnJlcXVlc3RzW3RoaXMuaW5kZXhdID0gdGhpcztcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzdWNjZXNzZnVsIHJlc3BvbnNlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLm9uU3VjY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0KCdzdWNjZXNzJyk7XG4gIHRoaXMuY2xlYW51cCgpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgaWYgd2UgaGF2ZSBkYXRhLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuZW1pdCgnZGF0YScsIGRhdGEpO1xuICB0aGlzLm9uU3VjY2VzcygpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKGVycikge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5jbGVhbnVwKHRydWUpO1xufTtcblxuLyoqXG4gKiBDbGVhbnMgdXAgaG91c2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuY2xlYW51cCA9IGZ1bmN0aW9uIChmcm9tRXJyb3IpIHtcbiAgaWYgKCd1bmRlZmluZWQnID09PSB0eXBlb2YgdGhpcy54aHIgfHwgbnVsbCA9PT0gdGhpcy54aHIpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8geG1saHR0cHJlcXVlc3RcbiAgaWYgKHRoaXMuaGFzWERSKCkpIHtcbiAgICB0aGlzLnhoci5vbmxvYWQgPSB0aGlzLnhoci5vbmVycm9yID0gZW1wdHk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZW1wdHk7XG4gIH1cblxuICBpZiAoZnJvbUVycm9yKSB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMueGhyLmFib3J0KCk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfVxuXG4gIGlmIChnbG9iYWwuZG9jdW1lbnQpIHtcbiAgICBkZWxldGUgUmVxdWVzdC5yZXF1ZXN0c1t0aGlzLmluZGV4XTtcbiAgfVxuXG4gIHRoaXMueGhyID0gbnVsbDtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gbG9hZC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vbkxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBkYXRhO1xuICB0cnkge1xuICAgIHZhciBjb250ZW50VHlwZTtcbiAgICB0cnkge1xuICAgICAgY29udGVudFR5cGUgPSB0aGlzLnhoci5nZXRSZXNwb25zZUhlYWRlcignQ29udGVudC1UeXBlJykuc3BsaXQoJzsnKVswXTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIGlmIChjb250ZW50VHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpIHtcbiAgICAgIGRhdGEgPSB0aGlzLnhoci5yZXNwb25zZSB8fCB0aGlzLnhoci5yZXNwb25zZVRleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy5zdXBwb3J0c0JpbmFyeSkge1xuICAgICAgICBkYXRhID0gdGhpcy54aHIucmVzcG9uc2VUZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDhBcnJheSh0aGlzLnhoci5yZXNwb25zZSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdmFyIHVpOEFyciA9IG5ldyBVaW50OEFycmF5KHRoaXMueGhyLnJlc3BvbnNlKTtcbiAgICAgICAgICB2YXIgZGF0YUFycmF5ID0gW107XG4gICAgICAgICAgZm9yICh2YXIgaWR4ID0gMCwgbGVuZ3RoID0gdWk4QXJyLmxlbmd0aDsgaWR4IDwgbGVuZ3RoOyBpZHgrKykge1xuICAgICAgICAgICAgZGF0YUFycmF5LnB1c2godWk4QXJyW2lkeF0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGRhdGFBcnJheSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aGlzLm9uRXJyb3IoZSk7XG4gIH1cbiAgaWYgKG51bGwgIT0gZGF0YSkge1xuICAgIHRoaXMub25EYXRhKGRhdGEpO1xuICB9XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIGl0IGhhcyBYRG9tYWluUmVxdWVzdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5oYXNYRFIgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGdsb2JhbC5YRG9tYWluUmVxdWVzdCAmJiAhdGhpcy54cyAmJiB0aGlzLmVuYWJsZXNYRFI7XG59O1xuXG4vKipcbiAqIEFib3J0cyB0aGUgcmVxdWVzdC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmFib3J0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmNsZWFudXAoKTtcbn07XG5cbi8qKlxuICogQWJvcnRzIHBlbmRpbmcgcmVxdWVzdHMgd2hlbiB1bmxvYWRpbmcgdGhlIHdpbmRvdy4gVGhpcyBpcyBuZWVkZWQgdG8gcHJldmVudFxuICogbWVtb3J5IGxlYWtzIChlLmcuIHdoZW4gdXNpbmcgSUUpIGFuZCB0byBlbnN1cmUgdGhhdCBubyBzcHVyaW91cyBlcnJvciBpc1xuICogZW1pdHRlZC5cbiAqL1xuXG5SZXF1ZXN0LnJlcXVlc3RzQ291bnQgPSAwO1xuUmVxdWVzdC5yZXF1ZXN0cyA9IHt9O1xuXG5pZiAoZ2xvYmFsLmRvY3VtZW50KSB7XG4gIGlmIChnbG9iYWwuYXR0YWNoRXZlbnQpIHtcbiAgICBnbG9iYWwuYXR0YWNoRXZlbnQoJ29udW5sb2FkJywgdW5sb2FkSGFuZGxlcik7XG4gIH0gZWxzZSBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgdW5sb2FkSGFuZGxlciwgZmFsc2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVubG9hZEhhbmRsZXIgKCkge1xuICBmb3IgKHZhciBpIGluIFJlcXVlc3QucmVxdWVzdHMpIHtcbiAgICBpZiAoUmVxdWVzdC5yZXF1ZXN0cy5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgUmVxdWVzdC5yZXF1ZXN0c1tpXS5hYm9ydCgpO1xuICAgIH1cbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///108d\n")},1278:function(module,exports,__webpack_require__){eval("/**\n * Selection\n * @module client/util-selection\n */\nvar misval = __webpack_require__(/*! ./misval */ \"bff6\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\n/*\n * Set a categorial 1D filter function\n * @param {Partition} partition\n */\nfunction filterFunctionCategorial1D (partition) {\n  var haystack = {};\n\n  if (!partition.selected || !partition.selected.length) {\n    partition.groups.forEach(function (group) {\n      haystack[group.value] = true;\n    });\n  } else {\n    partition.selected.forEach(function (h) {\n      haystack[h] = true;\n    });\n  }\n\n  return function (d) {\n    var needle = d;\n    if (!(needle instanceof Array)) {\n      needle = [d];\n    }\n\n    var selected = false;\n    needle.forEach(function (s) {\n      selected = selected | haystack[s];\n    });\n    return !!selected;\n  };\n}\n\n/*\n * Set a text filter function\n * @param {Partition} partition\n */\nfunction filterFunctionText (partition) {\n  var haystack = {};\n\n  // nothing selected, so all selected\n  if (partition.selected.length === 0) {\n    return function () {\n      return true;\n    };\n  }\n\n  partition.selected.forEach(function (h) {\n    haystack[h] = true;\n  });\n\n  return function (d) {\n    var needle = d;\n    if (!(needle instanceof Array)) {\n      needle = [d];\n    }\n\n    var selected = false;\n    needle.forEach(function (s) {\n      selected = selected | haystack[s];\n    });\n    return !!selected;\n  };\n}\n\n/*\n * Set a continuous 1D filter function\n * @param {Partition} partition\n */\nfunction filterFunctionContinuous1D (partition) {\n  var edge = partition.maxval;\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = partition.minval;\n    max = partition.maxval;\n    return function (d) {\n      return ((d >= min && d <= max) && (d !== misval));\n    };\n  } else {\n    min = partition.selected[0];\n    max = partition.selected[1];\n    return function (d) {\n      return ((d >= min && d < max) || ((d === edge) && (max === edge))) && (d !== misval);\n    };\n  }\n}\n\n/*\n * Set a continuous 1D filter function on a datetime dimension\n * @param {Partition} partition\n */\nfunction filterFunctionDatetime1D (partition) {\n  var edge = moment(partition.maxval);\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = moment(partition.minval);\n    max = moment(partition.maxval);\n\n    return function (d) {\n      var m = moment(d);\n      return (m !== misval) && !m.isBefore(min) && !m.isAfter(max);\n    };\n  } else {\n    min = moment(partition.selected[0]);\n    max = moment(partition.selected[1]);\n    return function (d) {\n      var m = moment(d);\n      return (m !== misval) && !min.isAfter(m) && (m.isBefore(max) || (max.isSame(edge) && max.isSame(m)));\n    };\n  }\n}\n\n/*\n * Set a continuous 1D filter function on a duration dimension\n * @param {Partition} partition\n */\nfunction filterFunctionDuration1D (partition) {\n  var edge = partition.maxval;\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = partition.minval;\n    max = partition.maxval;\n\n    return function (d) {\n      if (d === misval) {\n        return false;\n      }\n      var m = moment.duration(d);\n      return moment.isDuration(m) && m >= min && m <= max;\n    };\n  } else {\n    min = moment.duration(partition.selected[0]);\n    max = moment.duration(partition.selected[1]);\n    return function (d) {\n      if (d === misval) {\n        return false;\n      }\n      var m = moment.duration(d);\n      return moment.isDuration(m) && m >= min && (m < max || (m <= max && max >= edge));\n    };\n  }\n}\n\n/**\n * A filter function based for a single partition\n * @function\n * @returns {boolean} selected True if the datapoint is currently selected\n * @param {Partition} partition\n * @param {Object} datapoint\n * @memberof! Selection\n */\nfunction filterFunction (partition) {\n  if (partition.isCategorial || partition.isConstant) {\n    return filterFunctionCategorial1D(partition);\n  } else if (partition.isContinuous) {\n    return filterFunctionContinuous1D(partition);\n  } else if (partition.isDatetime) {\n    return filterFunctionDatetime1D(partition);\n  } else if (partition.isDuration) {\n    return filterFunctionDuration1D(partition);\n  } else if (partition.isText) {\n    return filterFunctionText(partition);\n  } else {\n    console.error('Cannot make filterfunction for partition', partition);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateCategorial1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // 1. none selected:\n    selected.push(group.value);\n  } else if (selected.length === 1) {\n    if (selected[0] === group.value) {\n      // 2. one selected and the group is the same:\n      selected.splice(0, selected.length);\n      partition.groups.forEach(function (g) {\n        if (g.value !== group.value) {\n          selected.push(g.value);\n        }\n      });\n    } else {\n      // 3. one selected and the group is different:\n      selected.push(group.value);\n    }\n  } else {\n    var i;\n    i = selected.indexOf(group.value);\n    if (i > -1) {\n      // 4. more than one selected and the group is in the selection:\n      selected.splice(i, 1);\n    } else {\n      // 5. more than one selected and the group is not in the selection:\n      selected.push(group.value);\n    }\n  }\n\n  // after add: if filters == groups, reset and dont filter\n  if (selected.length === partition.groups.length) {\n    selected.splice(0, selected.length);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateText (partition, group) {\n  var selected = partition.selected;\n\n  var i;\n  i = selected.indexOf(group.value);\n  if (i > -1) {\n    // 1. in the selection, remove it\n    selected.splice(i, 1);\n  } else {\n    // 2. not in the selection, add it\n    selected.push(group.value);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateContinuous1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min;\n    selected[1] = group.max;\n  } else if (group.min >= selected[1]) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max;\n  } else if (group.max <= selected[0]) {\n    // clicked outside to the left of selection\n    selected[0] = group.min;\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    if (partition.groupLog) {\n      d1 = Math.abs(Math.log(selected[0]) - Math.log(group.min));\n      d2 = Math.abs(Math.log(selected[1]) - Math.log(group.max));\n    } else {\n      d1 = Math.abs(selected[0] - group.min);\n      d2 = Math.abs(selected[1] - group.max);\n    }\n    if (d1 < d2) {\n      selected[0] = group.min;\n    } else {\n      selected[1] = group.max;\n    }\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateDatetime1D (partition, group) {\n  var selected = partition.selected;\n\n  if (!selected || selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min.toISOString();\n    selected[1] = group.max.toISOString();\n    return;\n  }\n\n  var selectionStart = moment(selected[0]);\n  var selectionEnd = moment(selected[1]);\n\n  if (!group.min.isBefore(selectionEnd)) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max.toISOString();\n  } else if (!group.max.isAfter(selectionStart)) {\n    // clicked outside to the left of selection\n    selected[0] = group.min.toISOString();\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    d1 = Math.abs(selectionStart.diff(group.min));\n    d2 = Math.abs(selectionEnd.diff(group.max));\n\n    if (d1 < d2) {\n      selected[0] = group.max.toISOString();\n    } else {\n      selected[1] = group.min.toISOString();\n    }\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateDuration1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min.toISOString();\n    selected[1] = group.max.toISOString();\n    return;\n  }\n\n  var selectionStart = moment.duration(selected[0]);\n  var selectionEnd = moment.duration(selected[1]);\n\n  if (group.min >= selectionEnd) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max.toISOString();\n  } else if (group.max <= selectionStart) {\n    // clicked outside to the left of selection\n    selected[0] = group.min.toISOString();\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    d1 = Math.abs(selectionStart - group.min);\n    d2 = Math.abs(selectionEnd - group.max);\n\n    if (d1 < d2) {\n      selected[0] = group.max.toISOString();\n    } else {\n      selected[1] = group.min.toISOString();\n    }\n  }\n}\n\n/**\n * Update the selection with a given group or interval\n * or, if no group is given, clear the selection.\n *\n * For categorial selections the following rules are used:\n * 1. none selected:\n *    add the group to the selection\n * 2. one selected and the group is the same:\n *    invert the selection\n * 3. one selected and the group is different:\n *    add the group to the selection\n * 4. more than one selected and the group is in the selection:\n *    remove the group from the selection\n * 5. more than one selected and the group is not in the selection:\n *    add the group to the selection\n *\n * For continuous selections the following rules are used:\n * 1. no range selected\n *    set the range equal to that of the group\n * 2. a range selected and the group is outside the selection:\n *    extend the selection to include the group\n * 3. a range selected and the group is inside the selection:\n *    set the endpoint closest to the group to that of the group\n *\n * @function\n * @param {Partition} Partition to update\n * @param {(string|number[])} Group or interval\n */\nfunction updateSelection (partition, group) {\n  if (!group) {\n    // Clear the selection (ie. all points are selected)\n    partition.selected.splice(0, partition.selected.length);\n  } else {\n    // Update the selection\n    if (partition.type === 'categorial' || partition.type === 'constant') {\n      updateCategorial1D(partition, group);\n    } else if (partition.type === 'continuous') {\n      updateContinuous1D(partition, group);\n    } else if (partition.type === 'datetime') {\n      updateDatetime1D(partition, group);\n    } else if (partition.type === 'duration') {\n      updateDuration1D(partition, group);\n    } else if (partition.type === 'text') {\n      updateText(partition, group);\n    } else {\n      console.error('Cannot update selection', partition.type);\n    }\n  }\n}\n\nmodule.exports = {\n  filterFunction: filterFunction,\n  updateSelection: updateSelection\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTI3OC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9zZWxlY3Rpb24uanM/NGY5ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNlbGVjdGlvblxuICogQG1vZHVsZSBjbGllbnQvdXRpbC1zZWxlY3Rpb25cbiAqL1xudmFyIG1pc3ZhbCA9IHJlcXVpcmUoJy4vbWlzdmFsJyk7XG52YXIgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50LXRpbWV6b25lJyk7XG5cbi8qXG4gKiBTZXQgYSBjYXRlZ29yaWFsIDFEIGZpbHRlciBmdW5jdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkNhdGVnb3JpYWwxRCAocGFydGl0aW9uKSB7XG4gIHZhciBoYXlzdGFjayA9IHt9O1xuXG4gIGlmICghcGFydGl0aW9uLnNlbGVjdGVkIHx8ICFwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKSB7XG4gICAgcGFydGl0aW9uLmdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgaGF5c3RhY2tbZ3JvdXAudmFsdWVdID0gdHJ1ZTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBwYXJ0aXRpb24uc2VsZWN0ZWQuZm9yRWFjaChmdW5jdGlvbiAoaCkge1xuICAgICAgaGF5c3RhY2tbaF0gPSB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgdmFyIG5lZWRsZSA9IGQ7XG4gICAgaWYgKCEobmVlZGxlIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICBuZWVkbGUgPSBbZF07XG4gICAgfVxuXG4gICAgdmFyIHNlbGVjdGVkID0gZmFsc2U7XG4gICAgbmVlZGxlLmZvckVhY2goZnVuY3Rpb24gKHMpIHtcbiAgICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQgfCBoYXlzdGFja1tzXTtcbiAgICB9KTtcbiAgICByZXR1cm4gISFzZWxlY3RlZDtcbiAgfTtcbn1cblxuLypcbiAqIFNldCBhIHRleHQgZmlsdGVyIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uVGV4dCAocGFydGl0aW9uKSB7XG4gIHZhciBoYXlzdGFjayA9IHt9O1xuXG4gIC8vIG5vdGhpbmcgc2VsZWN0ZWQsIHNvIGFsbCBzZWxlY3RlZFxuICBpZiAocGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuICB9XG5cbiAgcGFydGl0aW9uLnNlbGVjdGVkLmZvckVhY2goZnVuY3Rpb24gKGgpIHtcbiAgICBoYXlzdGFja1toXSA9IHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIHZhciBuZWVkbGUgPSBkO1xuICAgIGlmICghKG5lZWRsZSBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgbmVlZGxlID0gW2RdO1xuICAgIH1cblxuICAgIHZhciBzZWxlY3RlZCA9IGZhbHNlO1xuICAgIG5lZWRsZS5mb3JFYWNoKGZ1bmN0aW9uIChzKSB7XG4gICAgICBzZWxlY3RlZCA9IHNlbGVjdGVkIHwgaGF5c3RhY2tbc107XG4gICAgfSk7XG4gICAgcmV0dXJuICEhc2VsZWN0ZWQ7XG4gIH07XG59XG5cbi8qXG4gKiBTZXQgYSBjb250aW51b3VzIDFEIGZpbHRlciBmdW5jdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkNvbnRpbnVvdXMxRCAocGFydGl0aW9uKSB7XG4gIHZhciBlZGdlID0gcGFydGl0aW9uLm1heHZhbDtcbiAgdmFyIG1pbjtcbiAgdmFyIG1heDtcblxuICBpZiAoIXBhcnRpdGlvbi5zZWxlY3RlZCB8fCAhcGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCkge1xuICAgIG1pbiA9IHBhcnRpdGlvbi5taW52YWw7XG4gICAgbWF4ID0gcGFydGl0aW9uLm1heHZhbDtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHJldHVybiAoKGQgPj0gbWluICYmIGQgPD0gbWF4KSAmJiAoZCAhPT0gbWlzdmFsKSk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBwYXJ0aXRpb24uc2VsZWN0ZWRbMF07XG4gICAgbWF4ID0gcGFydGl0aW9uLnNlbGVjdGVkWzFdO1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgcmV0dXJuICgoZCA+PSBtaW4gJiYgZCA8IG1heCkgfHwgKChkID09PSBlZGdlKSAmJiAobWF4ID09PSBlZGdlKSkpICYmIChkICE9PSBtaXN2YWwpO1xuICAgIH07XG4gIH1cbn1cblxuLypcbiAqIFNldCBhIGNvbnRpbnVvdXMgMUQgZmlsdGVyIGZ1bmN0aW9uIG9uIGEgZGF0ZXRpbWUgZGltZW5zaW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uRGF0ZXRpbWUxRCAocGFydGl0aW9uKSB7XG4gIHZhciBlZGdlID0gbW9tZW50KHBhcnRpdGlvbi5tYXh2YWwpO1xuICB2YXIgbWluO1xuICB2YXIgbWF4O1xuXG4gIGlmICghcGFydGl0aW9uLnNlbGVjdGVkIHx8ICFwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKSB7XG4gICAgbWluID0gbW9tZW50KHBhcnRpdGlvbi5taW52YWwpO1xuICAgIG1heCA9IG1vbWVudChwYXJ0aXRpb24ubWF4dmFsKTtcblxuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIG0gPSBtb21lbnQoZCk7XG4gICAgICByZXR1cm4gKG0gIT09IG1pc3ZhbCkgJiYgIW0uaXNCZWZvcmUobWluKSAmJiAhbS5pc0FmdGVyKG1heCk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBtb21lbnQocGFydGl0aW9uLnNlbGVjdGVkWzBdKTtcbiAgICBtYXggPSBtb21lbnQocGFydGl0aW9uLnNlbGVjdGVkWzFdKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciBtID0gbW9tZW50KGQpO1xuICAgICAgcmV0dXJuIChtICE9PSBtaXN2YWwpICYmICFtaW4uaXNBZnRlcihtKSAmJiAobS5pc0JlZm9yZShtYXgpIHx8IChtYXguaXNTYW1lKGVkZ2UpICYmIG1heC5pc1NhbWUobSkpKTtcbiAgICB9O1xuICB9XG59XG5cbi8qXG4gKiBTZXQgYSBjb250aW51b3VzIDFEIGZpbHRlciBmdW5jdGlvbiBvbiBhIGR1cmF0aW9uIGRpbWVuc2lvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkR1cmF0aW9uMUQgKHBhcnRpdGlvbikge1xuICB2YXIgZWRnZSA9IHBhcnRpdGlvbi5tYXh2YWw7XG4gIHZhciBtaW47XG4gIHZhciBtYXg7XG5cbiAgaWYgKCFwYXJ0aXRpb24uc2VsZWN0ZWQgfHwgIXBhcnRpdGlvbi5zZWxlY3RlZC5sZW5ndGgpIHtcbiAgICBtaW4gPSBwYXJ0aXRpb24ubWludmFsO1xuICAgIG1heCA9IHBhcnRpdGlvbi5tYXh2YWw7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIG0gPSBtb21lbnQuZHVyYXRpb24oZCk7XG4gICAgICByZXR1cm4gbW9tZW50LmlzRHVyYXRpb24obSkgJiYgbSA+PSBtaW4gJiYgbSA8PSBtYXg7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBtb21lbnQuZHVyYXRpb24ocGFydGl0aW9uLnNlbGVjdGVkWzBdKTtcbiAgICBtYXggPSBtb21lbnQuZHVyYXRpb24ocGFydGl0aW9uLnNlbGVjdGVkWzFdKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIG0gPSBtb21lbnQuZHVyYXRpb24oZCk7XG4gICAgICByZXR1cm4gbW9tZW50LmlzRHVyYXRpb24obSkgJiYgbSA+PSBtaW4gJiYgKG0gPCBtYXggfHwgKG0gPD0gbWF4ICYmIG1heCA+PSBlZGdlKSk7XG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIEEgZmlsdGVyIGZ1bmN0aW9uIGJhc2VkIGZvciBhIHNpbmdsZSBwYXJ0aXRpb25cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge2Jvb2xlYW59IHNlbGVjdGVkIFRydWUgaWYgdGhlIGRhdGFwb2ludCBpcyBjdXJyZW50bHkgc2VsZWN0ZWRcbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhcG9pbnRcbiAqIEBtZW1iZXJvZiEgU2VsZWN0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgaWYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwgfHwgcGFydGl0aW9uLmlzQ29uc3RhbnQpIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25DYXRlZ29yaWFsMUQocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNDb250aW51b3VzKSB7XG4gICAgcmV0dXJuIGZpbHRlckZ1bmN0aW9uQ29udGludW91czFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzRGF0ZXRpbWUpIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25EYXRldGltZTFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzRHVyYXRpb24pIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25EdXJhdGlvbjFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzVGV4dCkge1xuICAgIHJldHVybiBmaWx0ZXJGdW5jdGlvblRleHQocGFydGl0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zb2xlLmVycm9yKCdDYW5ub3QgbWFrZSBmaWx0ZXJmdW5jdGlvbiBmb3IgcGFydGl0aW9uJywgcGFydGl0aW9uKTtcbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlQ2F0ZWdvcmlhbDFEIChwYXJ0aXRpb24sIGdyb3VwKSB7XG4gIHZhciBzZWxlY3RlZCA9IHBhcnRpdGlvbi5zZWxlY3RlZDtcblxuICBpZiAoc2VsZWN0ZWQubGVuZ3RoID09PSAwKSB7XG4gICAgLy8gMS4gbm9uZSBzZWxlY3RlZDpcbiAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgfSBlbHNlIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDEpIHtcbiAgICBpZiAoc2VsZWN0ZWRbMF0gPT09IGdyb3VwLnZhbHVlKSB7XG4gICAgICAvLyAyLiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyB0aGUgc2FtZTpcbiAgICAgIHNlbGVjdGVkLnNwbGljZSgwLCBzZWxlY3RlZC5sZW5ndGgpO1xuICAgICAgcGFydGl0aW9uLmdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChnKSB7XG4gICAgICAgIGlmIChnLnZhbHVlICE9PSBncm91cC52YWx1ZSkge1xuICAgICAgICAgIHNlbGVjdGVkLnB1c2goZy52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyAzLiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyBkaWZmZXJlbnQ6XG4gICAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGk7XG4gICAgaSA9IHNlbGVjdGVkLmluZGV4T2YoZ3JvdXAudmFsdWUpO1xuICAgIGlmIChpID4gLTEpIHtcbiAgICAgIC8vIDQuIG1vcmUgdGhhbiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyBpbiB0aGUgc2VsZWN0aW9uOlxuICAgICAgc2VsZWN0ZWQuc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyA1LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgbm90IGluIHRoZSBzZWxlY3Rpb246XG4gICAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvLyBhZnRlciBhZGQ6IGlmIGZpbHRlcnMgPT0gZ3JvdXBzLCByZXNldCBhbmQgZG9udCBmaWx0ZXJcbiAgaWYgKHNlbGVjdGVkLmxlbmd0aCA9PT0gcGFydGl0aW9uLmdyb3Vwcy5sZW5ndGgpIHtcbiAgICBzZWxlY3RlZC5zcGxpY2UoMCwgc2VsZWN0ZWQubGVuZ3RoKTtcbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlVGV4dCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgdmFyIGk7XG4gIGkgPSBzZWxlY3RlZC5pbmRleE9mKGdyb3VwLnZhbHVlKTtcbiAgaWYgKGkgPiAtMSkge1xuICAgIC8vIDEuIGluIHRoZSBzZWxlY3Rpb24sIHJlbW92ZSBpdFxuICAgIHNlbGVjdGVkLnNwbGljZShpLCAxKTtcbiAgfSBlbHNlIHtcbiAgICAvLyAyLiBub3QgaW4gdGhlIHNlbGVjdGlvbiwgYWRkIGl0XG4gICAgc2VsZWN0ZWQucHVzaChncm91cC52YWx1ZSk7XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7R3JvdXB9IGdyb3VwIC0gVGhlIGdyb3VwIHRvIGFkZCBvciByZW1vdmUgZnJvbSB0aGUgZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZUNvbnRpbnVvdXMxRCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgaWYgKHNlbGVjdGVkLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIG5vdGhpbmcgc2VsZWN0ZWQsIHN0YXJ0IGEgcmFuZ2VcbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbjtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heDtcbiAgfSBlbHNlIGlmIChncm91cC5taW4gPj0gc2VsZWN0ZWRbMV0pIHtcbiAgICAvLyBjbGlja2VkIG91dHNpZGUgdG8gdGhlIHJpZ3RoIG9mIHNlbGVjdGlvblxuICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4O1xuICB9IGVsc2UgaWYgKGdyb3VwLm1heCA8PSBzZWxlY3RlZFswXSkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbjtcbiAgfSBlbHNlIHtcbiAgICAvLyBjbGlja2VkIGluc2lkZSBzZWxlY3Rpb25cbiAgICB2YXIgZDEsIGQyO1xuICAgIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAgIGQxID0gTWF0aC5hYnMoTWF0aC5sb2coc2VsZWN0ZWRbMF0pIC0gTWF0aC5sb2coZ3JvdXAubWluKSk7XG4gICAgICBkMiA9IE1hdGguYWJzKE1hdGgubG9nKHNlbGVjdGVkWzFdKSAtIE1hdGgubG9nKGdyb3VwLm1heCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkMSA9IE1hdGguYWJzKHNlbGVjdGVkWzBdIC0gZ3JvdXAubWluKTtcbiAgICAgIGQyID0gTWF0aC5hYnMoc2VsZWN0ZWRbMV0gLSBncm91cC5tYXgpO1xuICAgIH1cbiAgICBpZiAoZDEgPCBkMikge1xuICAgICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW47XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4O1xuICAgIH1cbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGF0ZXRpbWUxRCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgaWYgKCFzZWxlY3RlZCB8fCBzZWxlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICAvLyBub3RoaW5nIHNlbGVjdGVkLCBzdGFydCBhIHJhbmdlXG4gICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxlY3Rpb25TdGFydCA9IG1vbWVudChzZWxlY3RlZFswXSk7XG4gIHZhciBzZWxlY3Rpb25FbmQgPSBtb21lbnQoc2VsZWN0ZWRbMV0pO1xuXG4gIGlmICghZ3JvdXAubWluLmlzQmVmb3JlKHNlbGVjdGlvbkVuZCkpIHtcbiAgICAvLyBjbGlja2VkIG91dHNpZGUgdG8gdGhlIHJpZ3RoIG9mIHNlbGVjdGlvblxuICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4LnRvSVNPU3RyaW5nKCk7XG4gIH0gZWxzZSBpZiAoIWdyb3VwLm1heC5pc0FmdGVyKHNlbGVjdGlvblN0YXJ0KSkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbi50b0lTT1N0cmluZygpO1xuICB9IGVsc2Uge1xuICAgIC8vIGNsaWNrZWQgaW5zaWRlIHNlbGVjdGlvblxuICAgIHZhciBkMSwgZDI7XG4gICAgZDEgPSBNYXRoLmFicyhzZWxlY3Rpb25TdGFydC5kaWZmKGdyb3VwLm1pbikpO1xuICAgIGQyID0gTWF0aC5hYnMoc2VsZWN0aW9uRW5kLmRpZmYoZ3JvdXAubWF4KSk7XG5cbiAgICBpZiAoZDEgPCBkMikge1xuICAgICAgc2VsZWN0ZWRbMF0gPSBncm91cC5tYXgudG9JU09TdHJpbmcoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZWN0ZWRbMV0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICB9XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7R3JvdXB9IGdyb3VwIC0gVGhlIGdyb3VwIHRvIGFkZCBvciByZW1vdmUgZnJvbSB0aGUgZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZUR1cmF0aW9uMUQgKHBhcnRpdGlvbiwgZ3JvdXApIHtcbiAgdmFyIHNlbGVjdGVkID0gcGFydGl0aW9uLnNlbGVjdGVkO1xuXG4gIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICAvLyBub3RoaW5nIHNlbGVjdGVkLCBzdGFydCBhIHJhbmdlXG4gICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxlY3Rpb25TdGFydCA9IG1vbWVudC5kdXJhdGlvbihzZWxlY3RlZFswXSk7XG4gIHZhciBzZWxlY3Rpb25FbmQgPSBtb21lbnQuZHVyYXRpb24oc2VsZWN0ZWRbMV0pO1xuXG4gIGlmIChncm91cC5taW4gPj0gc2VsZWN0aW9uRW5kKSB7XG4gICAgLy8gY2xpY2tlZCBvdXRzaWRlIHRvIHRoZSByaWd0aCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICB9IGVsc2UgaWYgKGdyb3VwLm1heCA8PSBzZWxlY3Rpb25TdGFydCkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbi50b0lTT1N0cmluZygpO1xuICB9IGVsc2Uge1xuICAgIC8vIGNsaWNrZWQgaW5zaWRlIHNlbGVjdGlvblxuICAgIHZhciBkMSwgZDI7XG4gICAgZDEgPSBNYXRoLmFicyhzZWxlY3Rpb25TdGFydCAtIGdyb3VwLm1pbik7XG4gICAgZDIgPSBNYXRoLmFicyhzZWxlY3Rpb25FbmQgLSBncm91cC5tYXgpO1xuXG4gICAgaWYgKGQxIDwgZDIpIHtcbiAgICAgIHNlbGVjdGVkWzBdID0gZ3JvdXAubWF4LnRvSVNPU3RyaW5nKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWluLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVXBkYXRlIHRoZSBzZWxlY3Rpb24gd2l0aCBhIGdpdmVuIGdyb3VwIG9yIGludGVydmFsXG4gKiBvciwgaWYgbm8gZ3JvdXAgaXMgZ2l2ZW4sIGNsZWFyIHRoZSBzZWxlY3Rpb24uXG4gKlxuICogRm9yIGNhdGVnb3JpYWwgc2VsZWN0aW9ucyB0aGUgZm9sbG93aW5nIHJ1bGVzIGFyZSB1c2VkOlxuICogMS4gbm9uZSBzZWxlY3RlZDpcbiAqICAgIGFkZCB0aGUgZ3JvdXAgdG8gdGhlIHNlbGVjdGlvblxuICogMi4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgdGhlIHNhbWU6XG4gKiAgICBpbnZlcnQgdGhlIHNlbGVjdGlvblxuICogMy4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgZGlmZmVyZW50OlxuICogICAgYWRkIHRoZSBncm91cCB0byB0aGUgc2VsZWN0aW9uXG4gKiA0LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgaW4gdGhlIHNlbGVjdGlvbjpcbiAqICAgIHJlbW92ZSB0aGUgZ3JvdXAgZnJvbSB0aGUgc2VsZWN0aW9uXG4gKiA1LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgbm90IGluIHRoZSBzZWxlY3Rpb246XG4gKiAgICBhZGQgdGhlIGdyb3VwIHRvIHRoZSBzZWxlY3Rpb25cbiAqXG4gKiBGb3IgY29udGludW91cyBzZWxlY3Rpb25zIHRoZSBmb2xsb3dpbmcgcnVsZXMgYXJlIHVzZWQ6XG4gKiAxLiBubyByYW5nZSBzZWxlY3RlZFxuICogICAgc2V0IHRoZSByYW5nZSBlcXVhbCB0byB0aGF0IG9mIHRoZSBncm91cFxuICogMi4gYSByYW5nZSBzZWxlY3RlZCBhbmQgdGhlIGdyb3VwIGlzIG91dHNpZGUgdGhlIHNlbGVjdGlvbjpcbiAqICAgIGV4dGVuZCB0aGUgc2VsZWN0aW9uIHRvIGluY2x1ZGUgdGhlIGdyb3VwXG4gKiAzLiBhIHJhbmdlIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgaW5zaWRlIHRoZSBzZWxlY3Rpb246XG4gKiAgICBzZXQgdGhlIGVuZHBvaW50IGNsb3Nlc3QgdG8gdGhlIGdyb3VwIHRvIHRoYXQgb2YgdGhlIGdyb3VwXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gUGFydGl0aW9uIHRvIHVwZGF0ZVxuICogQHBhcmFtIHsoc3RyaW5nfG51bWJlcltdKX0gR3JvdXAgb3IgaW50ZXJ2YWxcbiAqL1xuZnVuY3Rpb24gdXBkYXRlU2VsZWN0aW9uIChwYXJ0aXRpb24sIGdyb3VwKSB7XG4gIGlmICghZ3JvdXApIHtcbiAgICAvLyBDbGVhciB0aGUgc2VsZWN0aW9uIChpZS4gYWxsIHBvaW50cyBhcmUgc2VsZWN0ZWQpXG4gICAgcGFydGl0aW9uLnNlbGVjdGVkLnNwbGljZSgwLCBwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBVcGRhdGUgdGhlIHNlbGVjdGlvblxuICAgIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2NhdGVnb3JpYWwnIHx8IHBhcnRpdGlvbi50eXBlID09PSAnY29uc3RhbnQnKSB7XG4gICAgICB1cGRhdGVDYXRlZ29yaWFsMUQocGFydGl0aW9uLCBncm91cCk7XG4gICAgfSBlbHNlIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2NvbnRpbnVvdXMnKSB7XG4gICAgICB1cGRhdGVDb250aW51b3VzMUQocGFydGl0aW9uLCBncm91cCk7XG4gICAgfSBlbHNlIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgdXBkYXRlRGF0ZXRpbWUxRChwYXJ0aXRpb24sIGdyb3VwKTtcbiAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi50eXBlID09PSAnZHVyYXRpb24nKSB7XG4gICAgICB1cGRhdGVEdXJhdGlvbjFEKHBhcnRpdGlvbiwgZ3JvdXApO1xuICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLnR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgdXBkYXRlVGV4dChwYXJ0aXRpb24sIGdyb3VwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcignQ2Fubm90IHVwZGF0ZSBzZWxlY3Rpb24nLCBwYXJ0aXRpb24udHlwZSk7XG4gICAgfVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBmaWx0ZXJGdW5jdGlvbjogZmlsdGVyRnVuY3Rpb24sXG4gIHVwZGF0ZVNlbGVjdGlvbjogdXBkYXRlU2VsZWN0aW9uXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1278\n")},"181d":function(module,exports,__webpack_require__){eval("/**\n * Module dependencies.\n */\n\nvar Transport = __webpack_require__(/*! ../transport */ \"0d97\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar yeast = __webpack_require__(/*! yeast */ \"c16d\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:polling');\n\n/**\n * Module exports.\n */\n\nmodule.exports = Polling;\n\n/**\n * Is XHR2 supported?\n */\n\nvar hasXHR2 = (function () {\n  var XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ \"86e3\");\n  var xhr = new XMLHttpRequest({ xdomain: false });\n  return null != xhr.responseType;\n})();\n\n/**\n * Polling interface.\n *\n * @param {Object} opts\n * @api private\n */\n\nfunction Polling (opts) {\n  var forceBase64 = (opts && opts.forceBase64);\n  if (!hasXHR2 || forceBase64) {\n    this.supportsBinary = false;\n  }\n  Transport.call(this, opts);\n}\n\n/**\n * Inherits from Transport.\n */\n\ninherit(Polling, Transport);\n\n/**\n * Transport name.\n */\n\nPolling.prototype.name = 'polling';\n\n/**\n * Opens the socket (triggers polling). We write a PING message to determine\n * when the transport is open.\n *\n * @api private\n */\n\nPolling.prototype.doOpen = function () {\n  this.poll();\n};\n\n/**\n * Pauses polling.\n *\n * @param {Function} callback upon buffers are flushed and transport is paused\n * @api private\n */\n\nPolling.prototype.pause = function (onPause) {\n  var self = this;\n\n  this.readyState = 'pausing';\n\n  function pause () {\n    debug('paused');\n    self.readyState = 'paused';\n    onPause();\n  }\n\n  if (this.polling || !this.writable) {\n    var total = 0;\n\n    if (this.polling) {\n      debug('we are currently polling - waiting to pause');\n      total++;\n      this.once('pollComplete', function () {\n        debug('pre-pause polling complete');\n        --total || pause();\n      });\n    }\n\n    if (!this.writable) {\n      debug('we are currently writing - waiting to pause');\n      total++;\n      this.once('drain', function () {\n        debug('pre-pause writing complete');\n        --total || pause();\n      });\n    }\n  } else {\n    pause();\n  }\n};\n\n/**\n * Starts polling cycle.\n *\n * @api public\n */\n\nPolling.prototype.poll = function () {\n  debug('polling');\n  this.polling = true;\n  this.doPoll();\n  this.emit('poll');\n};\n\n/**\n * Overloads onData to detect payloads.\n *\n * @api private\n */\n\nPolling.prototype.onData = function (data) {\n  var self = this;\n  debug('polling got data %s', data);\n  var callback = function (packet, index, total) {\n    // if its the first message we consider the transport open\n    if ('opening' === self.readyState) {\n      self.onOpen();\n    }\n\n    // if its a close packet, we close the ongoing requests\n    if ('close' === packet.type) {\n      self.onClose();\n      return false;\n    }\n\n    // otherwise bypass onData and handle the message\n    self.onPacket(packet);\n  };\n\n  // decode payload\n  parser.decodePayload(data, this.socket.binaryType, callback);\n\n  // if an event did not trigger closing\n  if ('closed' !== this.readyState) {\n    // if we got data we're not polling\n    this.polling = false;\n    this.emit('pollComplete');\n\n    if ('open' === this.readyState) {\n      this.poll();\n    } else {\n      debug('ignoring poll - transport state \"%s\"', this.readyState);\n    }\n  }\n};\n\n/**\n * For polling, send a close packet.\n *\n * @api private\n */\n\nPolling.prototype.doClose = function () {\n  var self = this;\n\n  function close () {\n    debug('writing close packet');\n    self.write([{ type: 'close' }]);\n  }\n\n  if ('open' === this.readyState) {\n    debug('transport open - closing');\n    close();\n  } else {\n    // in case we're trying to close while\n    // handshaking is in progress (GH-164)\n    debug('transport not open - deferring close');\n    this.once('open', close);\n  }\n};\n\n/**\n * Writes a packets payload.\n *\n * @param {Array} data packets\n * @param {Function} drain callback\n * @api private\n */\n\nPolling.prototype.write = function (packets) {\n  var self = this;\n  this.writable = false;\n  var callbackfn = function () {\n    self.writable = true;\n    self.emit('drain');\n  };\n\n  parser.encodePayload(packets, this.supportsBinary, function (data) {\n    self.doWrite(data, callbackfn);\n  });\n};\n\n/**\n * Generates uri for connection.\n *\n * @api private\n */\n\nPolling.prototype.uri = function () {\n  var query = this.query || {};\n  var schema = this.secure ? 'https' : 'http';\n  var port = '';\n\n  // cache busting is forced\n  if (false !== this.timestampRequests) {\n    query[this.timestampParam] = yeast();\n  }\n\n  if (!this.supportsBinary && !query.sid) {\n    query.b64 = 1;\n  }\n\n  query = parseqs.encode(query);\n\n  // avoid port if default for schema\n  if (this.port && (('https' === schema && Number(this.port) !== 443) ||\n     ('http' === schema && Number(this.port) !== 80))) {\n    port = ':' + this.port;\n  }\n\n  // prepend ? to query\n  if (query.length) {\n    query = '?' + query;\n  }\n\n  var ipv6 = this.hostname.indexOf(':') !== -1;\n  return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTgxZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLmpzP2U1ZjkiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBUcmFuc3BvcnQgPSByZXF1aXJlKCcuLi90cmFuc3BvcnQnKTtcbnZhciBwYXJzZXFzID0gcmVxdWlyZSgncGFyc2VxcycpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcbnZhciB5ZWFzdCA9IHJlcXVpcmUoJ3llYXN0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnBvbGxpbmcnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBvbGxpbmc7XG5cbi8qKlxuICogSXMgWEhSMiBzdXBwb3J0ZWQ/XG4gKi9cblxudmFyIGhhc1hIUjIgPSAoZnVuY3Rpb24gKCkge1xuICB2YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdC1zc2wnKTtcbiAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCh7IHhkb21haW46IGZhbHNlIH0pO1xuICByZXR1cm4gbnVsbCAhPSB4aHIucmVzcG9uc2VUeXBlO1xufSkoKTtcblxuLyoqXG4gKiBQb2xsaW5nIGludGVyZmFjZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gUG9sbGluZyAob3B0cykge1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKCFoYXNYSFIyIHx8IGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIFRyYW5zcG9ydC5jYWxsKHRoaXMsIG9wdHMpO1xufVxuXG4vKipcbiAqIEluaGVyaXRzIGZyb20gVHJhbnNwb3J0LlxuICovXG5cbmluaGVyaXQoUG9sbGluZywgVHJhbnNwb3J0KTtcblxuLyoqXG4gKiBUcmFuc3BvcnQgbmFtZS5cbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5uYW1lID0gJ3BvbGxpbmcnO1xuXG4vKipcbiAqIE9wZW5zIHRoZSBzb2NrZXQgKHRyaWdnZXJzIHBvbGxpbmcpLiBXZSB3cml0ZSBhIFBJTkcgbWVzc2FnZSB0byBkZXRlcm1pbmVcbiAqIHdoZW4gdGhlIHRyYW5zcG9ydCBpcyBvcGVuLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLmRvT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5wb2xsKCk7XG59O1xuXG4vKipcbiAqIFBhdXNlcyBwb2xsaW5nLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHVwb24gYnVmZmVycyBhcmUgZmx1c2hlZCBhbmQgdHJhbnNwb3J0IGlzIHBhdXNlZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAob25QYXVzZSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5yZWFkeVN0YXRlID0gJ3BhdXNpbmcnO1xuXG4gIGZ1bmN0aW9uIHBhdXNlICgpIHtcbiAgICBkZWJ1ZygncGF1c2VkJyk7XG4gICAgc2VsZi5yZWFkeVN0YXRlID0gJ3BhdXNlZCc7XG4gICAgb25QYXVzZSgpO1xuICB9XG5cbiAgaWYgKHRoaXMucG9sbGluZyB8fCAhdGhpcy53cml0YWJsZSkge1xuICAgIHZhciB0b3RhbCA9IDA7XG5cbiAgICBpZiAodGhpcy5wb2xsaW5nKSB7XG4gICAgICBkZWJ1Zygnd2UgYXJlIGN1cnJlbnRseSBwb2xsaW5nIC0gd2FpdGluZyB0byBwYXVzZScpO1xuICAgICAgdG90YWwrKztcbiAgICAgIHRoaXMub25jZSgncG9sbENvbXBsZXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZWJ1ZygncHJlLXBhdXNlIHBvbGxpbmcgY29tcGxldGUnKTtcbiAgICAgICAgLS10b3RhbCB8fCBwYXVzZSgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLndyaXRhYmxlKSB7XG4gICAgICBkZWJ1Zygnd2UgYXJlIGN1cnJlbnRseSB3cml0aW5nIC0gd2FpdGluZyB0byBwYXVzZScpO1xuICAgICAgdG90YWwrKztcbiAgICAgIHRoaXMub25jZSgnZHJhaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlYnVnKCdwcmUtcGF1c2Ugd3JpdGluZyBjb21wbGV0ZScpO1xuICAgICAgICAtLXRvdGFsIHx8IHBhdXNlKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcGF1c2UoKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTdGFydHMgcG9sbGluZyBjeWNsZS5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblBvbGxpbmcucHJvdG90eXBlLnBvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCdwb2xsaW5nJyk7XG4gIHRoaXMucG9sbGluZyA9IHRydWU7XG4gIHRoaXMuZG9Qb2xsKCk7XG4gIHRoaXMuZW1pdCgncG9sbCcpO1xufTtcblxuLyoqXG4gKiBPdmVybG9hZHMgb25EYXRhIHRvIGRldGVjdCBwYXlsb2Fkcy5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5vbkRhdGEgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGRlYnVnKCdwb2xsaW5nIGdvdCBkYXRhICVzJywgZGF0YSk7XG4gIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uIChwYWNrZXQsIGluZGV4LCB0b3RhbCkge1xuICAgIC8vIGlmIGl0cyB0aGUgZmlyc3QgbWVzc2FnZSB3ZSBjb25zaWRlciB0aGUgdHJhbnNwb3J0IG9wZW5cbiAgICBpZiAoJ29wZW5pbmcnID09PSBzZWxmLnJlYWR5U3RhdGUpIHtcbiAgICAgIHNlbGYub25PcGVuKCk7XG4gICAgfVxuXG4gICAgLy8gaWYgaXRzIGEgY2xvc2UgcGFja2V0LCB3ZSBjbG9zZSB0aGUgb25nb2luZyByZXF1ZXN0c1xuICAgIGlmICgnY2xvc2UnID09PSBwYWNrZXQudHlwZSkge1xuICAgICAgc2VsZi5vbkNsb3NlKCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gb3RoZXJ3aXNlIGJ5cGFzcyBvbkRhdGEgYW5kIGhhbmRsZSB0aGUgbWVzc2FnZVxuICAgIHNlbGYub25QYWNrZXQocGFja2V0KTtcbiAgfTtcblxuICAvLyBkZWNvZGUgcGF5bG9hZFxuICBwYXJzZXIuZGVjb2RlUGF5bG9hZChkYXRhLCB0aGlzLnNvY2tldC5iaW5hcnlUeXBlLCBjYWxsYmFjayk7XG5cbiAgLy8gaWYgYW4gZXZlbnQgZGlkIG5vdCB0cmlnZ2VyIGNsb3NpbmdcbiAgaWYgKCdjbG9zZWQnICE9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAvLyBpZiB3ZSBnb3QgZGF0YSB3ZSdyZSBub3QgcG9sbGluZ1xuICAgIHRoaXMucG9sbGluZyA9IGZhbHNlO1xuICAgIHRoaXMuZW1pdCgncG9sbENvbXBsZXRlJyk7XG5cbiAgICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAgIHRoaXMucG9sbCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1ZygnaWdub3JpbmcgcG9sbCAtIHRyYW5zcG9ydCBzdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBGb3IgcG9sbGluZywgc2VuZCBhIGNsb3NlIHBhY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gY2xvc2UgKCkge1xuICAgIGRlYnVnKCd3cml0aW5nIGNsb3NlIHBhY2tldCcpO1xuICAgIHNlbGYud3JpdGUoW3sgdHlwZTogJ2Nsb3NlJyB9XSk7XG4gIH1cblxuICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICBkZWJ1ZygndHJhbnNwb3J0IG9wZW4gLSBjbG9zaW5nJyk7XG4gICAgY2xvc2UoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbiBjYXNlIHdlJ3JlIHRyeWluZyB0byBjbG9zZSB3aGlsZVxuICAgIC8vIGhhbmRzaGFraW5nIGlzIGluIHByb2dyZXNzIChHSC0xNjQpXG4gICAgZGVidWcoJ3RyYW5zcG9ydCBub3Qgb3BlbiAtIGRlZmVycmluZyBjbG9zZScpO1xuICAgIHRoaXMub25jZSgnb3BlbicsIGNsb3NlKTtcbiAgfVxufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBwYWNrZXRzIHBheWxvYWQuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gZGF0YSBwYWNrZXRzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBkcmFpbiBjYWxsYmFja1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAocGFja2V0cykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcbiAgdmFyIGNhbGxiYWNrZm4gPSBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi53cml0YWJsZSA9IHRydWU7XG4gICAgc2VsZi5lbWl0KCdkcmFpbicpO1xuICB9O1xuXG4gIHBhcnNlci5lbmNvZGVQYXlsb2FkKHBhY2tldHMsIHRoaXMuc3VwcG9ydHNCaW5hcnksIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgc2VsZi5kb1dyaXRlKGRhdGEsIGNhbGxiYWNrZm4pO1xuICB9KTtcbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIHVyaSBmb3IgY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS51cmkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBxdWVyeSA9IHRoaXMucXVlcnkgfHwge307XG4gIHZhciBzY2hlbWEgPSB0aGlzLnNlY3VyZSA/ICdodHRwcycgOiAnaHR0cCc7XG4gIHZhciBwb3J0ID0gJyc7XG5cbiAgLy8gY2FjaGUgYnVzdGluZyBpcyBmb3JjZWRcbiAgaWYgKGZhbHNlICE9PSB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzKSB7XG4gICAgcXVlcnlbdGhpcy50aW1lc3RhbXBQYXJhbV0gPSB5ZWFzdCgpO1xuICB9XG5cbiAgaWYgKCF0aGlzLnN1cHBvcnRzQmluYXJ5ICYmICFxdWVyeS5zaWQpIHtcbiAgICBxdWVyeS5iNjQgPSAxO1xuICB9XG5cbiAgcXVlcnkgPSBwYXJzZXFzLmVuY29kZShxdWVyeSk7XG5cbiAgLy8gYXZvaWQgcG9ydCBpZiBkZWZhdWx0IGZvciBzY2hlbWFcbiAgaWYgKHRoaXMucG9ydCAmJiAoKCdodHRwcycgPT09IHNjaGVtYSAmJiBOdW1iZXIodGhpcy5wb3J0KSAhPT0gNDQzKSB8fFxuICAgICAoJ2h0dHAnID09PSBzY2hlbWEgJiYgTnVtYmVyKHRoaXMucG9ydCkgIT09IDgwKSkpIHtcbiAgICBwb3J0ID0gJzonICsgdGhpcy5wb3J0O1xuICB9XG5cbiAgLy8gcHJlcGVuZCA/IHRvIHF1ZXJ5XG4gIGlmIChxdWVyeS5sZW5ndGgpIHtcbiAgICBxdWVyeSA9ICc/JyArIHF1ZXJ5O1xuICB9XG5cbiAgdmFyIGlwdjYgPSB0aGlzLmhvc3RuYW1lLmluZGV4T2YoJzonKSAhPT0gLTE7XG4gIHJldHVybiBzY2hlbWEgKyAnOi8vJyArIChpcHY2ID8gJ1snICsgdGhpcy5ob3N0bmFtZSArICddJyA6IHRoaXMuaG9zdG5hbWUpICsgcG9ydCArIHRoaXMucGF0aCArIHF1ZXJ5O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///181d\n")},"1e1f":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar eio = __webpack_require__(/*! engine.io-client */ \"c59b\");\nvar Socket = __webpack_require__(/*! ./socket */ \"4c13\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar on = __webpack_require__(/*! ./on */ \"faaa\");\nvar bind = __webpack_require__(/*! component-bind */ \"b6f6\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:manager');\nvar indexOf = __webpack_require__(/*! indexof */ \"3294\");\nvar Backoff = __webpack_require__(/*! backo2 */ \"f942\");\n\n/**\n * IE6+ hasOwnProperty\n */\n\nvar has = Object.prototype.hasOwnProperty;\n\n/**\n * Module exports\n */\n\nmodule.exports = Manager;\n\n/**\n * `Manager` constructor.\n *\n * @param {String} engine instance or engine uri/opts\n * @param {Object} options\n * @api public\n */\n\nfunction Manager (uri, opts) {\n  if (!(this instanceof Manager)) return new Manager(uri, opts);\n  if (uri && ('object' === typeof uri)) {\n    opts = uri;\n    uri = undefined;\n  }\n  opts = opts || {};\n\n  opts.path = opts.path || '/socket.io';\n  this.nsps = {};\n  this.subs = [];\n  this.opts = opts;\n  this.reconnection(opts.reconnection !== false);\n  this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);\n  this.reconnectionDelay(opts.reconnectionDelay || 1000);\n  this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);\n  this.randomizationFactor(opts.randomizationFactor || 0.5);\n  this.backoff = new Backoff({\n    min: this.reconnectionDelay(),\n    max: this.reconnectionDelayMax(),\n    jitter: this.randomizationFactor()\n  });\n  this.timeout(null == opts.timeout ? 20000 : opts.timeout);\n  this.readyState = 'closed';\n  this.uri = uri;\n  this.connecting = [];\n  this.lastPing = null;\n  this.encoding = false;\n  this.packetBuffer = [];\n  this.encoder = new parser.Encoder();\n  this.decoder = new parser.Decoder();\n  this.autoConnect = opts.autoConnect !== false;\n  if (this.autoConnect) this.open();\n}\n\n/**\n * Propagate given event to sockets and emit on `this`\n *\n * @api private\n */\n\nManager.prototype.emitAll = function () {\n  this.emit.apply(this, arguments);\n  for (var nsp in this.nsps) {\n    if (has.call(this.nsps, nsp)) {\n      this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);\n    }\n  }\n};\n\n/**\n * Update `socket.id` of all sockets\n *\n * @api private\n */\n\nManager.prototype.updateSocketIds = function () {\n  for (var nsp in this.nsps) {\n    if (has.call(this.nsps, nsp)) {\n      this.nsps[nsp].id = this.engine.id;\n    }\n  }\n};\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Manager.prototype);\n\n/**\n * Sets the `reconnection` config.\n *\n * @param {Boolean} true/false if it should automatically reconnect\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnection = function (v) {\n  if (!arguments.length) return this._reconnection;\n  this._reconnection = !!v;\n  return this;\n};\n\n/**\n * Sets the reconnection attempts config.\n *\n * @param {Number} max reconnection attempts before giving up\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionAttempts = function (v) {\n  if (!arguments.length) return this._reconnectionAttempts;\n  this._reconnectionAttempts = v;\n  return this;\n};\n\n/**\n * Sets the delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionDelay = function (v) {\n  if (!arguments.length) return this._reconnectionDelay;\n  this._reconnectionDelay = v;\n  this.backoff && this.backoff.setMin(v);\n  return this;\n};\n\nManager.prototype.randomizationFactor = function (v) {\n  if (!arguments.length) return this._randomizationFactor;\n  this._randomizationFactor = v;\n  this.backoff && this.backoff.setJitter(v);\n  return this;\n};\n\n/**\n * Sets the maximum delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionDelayMax = function (v) {\n  if (!arguments.length) return this._reconnectionDelayMax;\n  this._reconnectionDelayMax = v;\n  this.backoff && this.backoff.setMax(v);\n  return this;\n};\n\n/**\n * Sets the connection timeout. `false` to disable\n *\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.timeout = function (v) {\n  if (!arguments.length) return this._timeout;\n  this._timeout = v;\n  return this;\n};\n\n/**\n * Starts trying to reconnect if reconnection is enabled and we have not\n * started reconnecting yet\n *\n * @api private\n */\n\nManager.prototype.maybeReconnectOnOpen = function () {\n  // Only try to reconnect if it's the first time we're connecting\n  if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) {\n    // keeps reconnection from firing twice for the same reconnection loop\n    this.reconnect();\n  }\n};\n\n/**\n * Sets the current transport `socket`.\n *\n * @param {Function} optional, callback\n * @return {Manager} self\n * @api public\n */\n\nManager.prototype.open =\nManager.prototype.connect = function (fn, opts) {\n  debug('readyState %s', this.readyState);\n  if (~this.readyState.indexOf('open')) return this;\n\n  debug('opening %s', this.uri);\n  this.engine = eio(this.uri, this.opts);\n  var socket = this.engine;\n  var self = this;\n  this.readyState = 'opening';\n  this.skipReconnect = false;\n\n  // emit `open`\n  var openSub = on(socket, 'open', function () {\n    self.onopen();\n    fn && fn();\n  });\n\n  // emit `connect_error`\n  var errorSub = on(socket, 'error', function (data) {\n    debug('connect_error');\n    self.cleanup();\n    self.readyState = 'closed';\n    self.emitAll('connect_error', data);\n    if (fn) {\n      var err = new Error('Connection error');\n      err.data = data;\n      fn(err);\n    } else {\n      // Only do this if there is no fn to handle the error\n      self.maybeReconnectOnOpen();\n    }\n  });\n\n  // emit `connect_timeout`\n  if (false !== this._timeout) {\n    var timeout = this._timeout;\n    debug('connect attempt will timeout after %d', timeout);\n\n    // set timer\n    var timer = setTimeout(function () {\n      debug('connect attempt timed out after %d', timeout);\n      openSub.destroy();\n      socket.close();\n      socket.emit('error', 'timeout');\n      self.emitAll('connect_timeout', timeout);\n    }, timeout);\n\n    this.subs.push({\n      destroy: function () {\n        clearTimeout(timer);\n      }\n    });\n  }\n\n  this.subs.push(openSub);\n  this.subs.push(errorSub);\n\n  return this;\n};\n\n/**\n * Called upon transport open.\n *\n * @api private\n */\n\nManager.prototype.onopen = function () {\n  debug('open');\n\n  // clear old subs\n  this.cleanup();\n\n  // mark as open\n  this.readyState = 'open';\n  this.emit('open');\n\n  // add new subs\n  var socket = this.engine;\n  this.subs.push(on(socket, 'data', bind(this, 'ondata')));\n  this.subs.push(on(socket, 'ping', bind(this, 'onping')));\n  this.subs.push(on(socket, 'pong', bind(this, 'onpong')));\n  this.subs.push(on(socket, 'error', bind(this, 'onerror')));\n  this.subs.push(on(socket, 'close', bind(this, 'onclose')));\n  this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));\n};\n\n/**\n * Called upon a ping.\n *\n * @api private\n */\n\nManager.prototype.onping = function () {\n  this.lastPing = new Date();\n  this.emitAll('ping');\n};\n\n/**\n * Called upon a packet.\n *\n * @api private\n */\n\nManager.prototype.onpong = function () {\n  this.emitAll('pong', new Date() - this.lastPing);\n};\n\n/**\n * Called with data.\n *\n * @api private\n */\n\nManager.prototype.ondata = function (data) {\n  this.decoder.add(data);\n};\n\n/**\n * Called when parser fully decodes a packet.\n *\n * @api private\n */\n\nManager.prototype.ondecoded = function (packet) {\n  this.emit('packet', packet);\n};\n\n/**\n * Called upon socket error.\n *\n * @api private\n */\n\nManager.prototype.onerror = function (err) {\n  debug('error', err);\n  this.emitAll('error', err);\n};\n\n/**\n * Creates a new socket for the given `nsp`.\n *\n * @return {Socket}\n * @api public\n */\n\nManager.prototype.socket = function (nsp, opts) {\n  var socket = this.nsps[nsp];\n  if (!socket) {\n    socket = new Socket(this, nsp, opts);\n    this.nsps[nsp] = socket;\n    var self = this;\n    socket.on('connecting', onConnecting);\n    socket.on('connect', function () {\n      socket.id = self.engine.id;\n    });\n\n    if (this.autoConnect) {\n      // manually call here since connecting evnet is fired before listening\n      onConnecting();\n    }\n  }\n\n  function onConnecting () {\n    if (!~indexOf(self.connecting, socket)) {\n      self.connecting.push(socket);\n    }\n  }\n\n  return socket;\n};\n\n/**\n * Called upon a socket close.\n *\n * @param {Socket} socket\n */\n\nManager.prototype.destroy = function (socket) {\n  var index = indexOf(this.connecting, socket);\n  if (~index) this.connecting.splice(index, 1);\n  if (this.connecting.length) return;\n\n  this.close();\n};\n\n/**\n * Writes a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nManager.prototype.packet = function (packet) {\n  debug('writing packet %j', packet);\n  var self = this;\n  if (packet.query && packet.type === 0) packet.nsp += '?' + packet.query;\n\n  if (!self.encoding) {\n    // encode, then write to engine with result\n    self.encoding = true;\n    this.encoder.encode(packet, function (encodedPackets) {\n      for (var i = 0; i < encodedPackets.length; i++) {\n        self.engine.write(encodedPackets[i], packet.options);\n      }\n      self.encoding = false;\n      self.processPacketQueue();\n    });\n  } else { // add packet to the queue\n    self.packetBuffer.push(packet);\n  }\n};\n\n/**\n * If packet buffer is non-empty, begins encoding the\n * next packet in line.\n *\n * @api private\n */\n\nManager.prototype.processPacketQueue = function () {\n  if (this.packetBuffer.length > 0 && !this.encoding) {\n    var pack = this.packetBuffer.shift();\n    this.packet(pack);\n  }\n};\n\n/**\n * Clean up transport subscriptions and packet buffer.\n *\n * @api private\n */\n\nManager.prototype.cleanup = function () {\n  debug('cleanup');\n\n  var subsLength = this.subs.length;\n  for (var i = 0; i < subsLength; i++) {\n    var sub = this.subs.shift();\n    sub.destroy();\n  }\n\n  this.packetBuffer = [];\n  this.encoding = false;\n  this.lastPing = null;\n\n  this.decoder.destroy();\n};\n\n/**\n * Close the current socket.\n *\n * @api private\n */\n\nManager.prototype.close =\nManager.prototype.disconnect = function () {\n  debug('disconnect');\n  this.skipReconnect = true;\n  this.reconnecting = false;\n  if ('opening' === this.readyState) {\n    // `onclose` will not fire because\n    // an open event never happened\n    this.cleanup();\n  }\n  this.backoff.reset();\n  this.readyState = 'closed';\n  if (this.engine) this.engine.close();\n};\n\n/**\n * Called upon engine close.\n *\n * @api private\n */\n\nManager.prototype.onclose = function (reason) {\n  debug('onclose');\n\n  this.cleanup();\n  this.backoff.reset();\n  this.readyState = 'closed';\n  this.emit('close', reason);\n\n  if (this._reconnection && !this.skipReconnect) {\n    this.reconnect();\n  }\n};\n\n/**\n * Attempt a reconnection.\n *\n * @api private\n */\n\nManager.prototype.reconnect = function () {\n  if (this.reconnecting || this.skipReconnect) return this;\n\n  var self = this;\n\n  if (this.backoff.attempts >= this._reconnectionAttempts) {\n    debug('reconnect failed');\n    this.backoff.reset();\n    this.emitAll('reconnect_failed');\n    this.reconnecting = false;\n  } else {\n    var delay = this.backoff.duration();\n    debug('will wait %dms before reconnect attempt', delay);\n\n    this.reconnecting = true;\n    var timer = setTimeout(function () {\n      if (self.skipReconnect) return;\n\n      debug('attempting reconnect');\n      self.emitAll('reconnect_attempt', self.backoff.attempts);\n      self.emitAll('reconnecting', self.backoff.attempts);\n\n      // check again for the case socket closed in above events\n      if (self.skipReconnect) return;\n\n      self.open(function (err) {\n        if (err) {\n          debug('reconnect attempt error');\n          self.reconnecting = false;\n          self.reconnect();\n          self.emitAll('reconnect_error', err.data);\n        } else {\n          debug('reconnect success');\n          self.onreconnect();\n        }\n      });\n    }, delay);\n\n    this.subs.push({\n      destroy: function () {\n        clearTimeout(timer);\n      }\n    });\n  }\n};\n\n/**\n * Called upon successful reconnect.\n *\n * @api private\n */\n\nManager.prototype.onreconnect = function () {\n  var attempt = this.backoff.attempts;\n  this.reconnecting = false;\n  this.backoff.reset();\n  this.updateSocketIds();\n  this.emitAll('reconnect', attempt);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMWUxZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvbWFuYWdlci5qcz9mMDk3Il0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBlaW8gPSByZXF1aXJlKCdlbmdpbmUuaW8tY2xpZW50Jyk7XG52YXIgU29ja2V0ID0gcmVxdWlyZSgnLi9zb2NrZXQnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgb24gPSByZXF1aXJlKCcuL29uJyk7XG52YXIgYmluZCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1iaW5kJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdzb2NrZXQuaW8tY2xpZW50Om1hbmFnZXInKTtcbnZhciBpbmRleE9mID0gcmVxdWlyZSgnaW5kZXhvZicpO1xudmFyIEJhY2tvZmYgPSByZXF1aXJlKCdiYWNrbzInKTtcblxuLyoqXG4gKiBJRTYrIGhhc093blByb3BlcnR5XG4gKi9cblxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hbmFnZXI7XG5cbi8qKlxuICogYE1hbmFnZXJgIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBlbmdpbmUgaW5zdGFuY2Ugb3IgZW5naW5lIHVyaS9vcHRzXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBNYW5hZ2VyICh1cmksIG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE1hbmFnZXIpKSByZXR1cm4gbmV3IE1hbmFnZXIodXJpLCBvcHRzKTtcbiAgaWYgKHVyaSAmJiAoJ29iamVjdCcgPT09IHR5cGVvZiB1cmkpKSB7XG4gICAgb3B0cyA9IHVyaTtcbiAgICB1cmkgPSB1bmRlZmluZWQ7XG4gIH1cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgb3B0cy5wYXRoID0gb3B0cy5wYXRoIHx8ICcvc29ja2V0LmlvJztcbiAgdGhpcy5uc3BzID0ge307XG4gIHRoaXMuc3VicyA9IFtdO1xuICB0aGlzLm9wdHMgPSBvcHRzO1xuICB0aGlzLnJlY29ubmVjdGlvbihvcHRzLnJlY29ubmVjdGlvbiAhPT0gZmFsc2UpO1xuICB0aGlzLnJlY29ubmVjdGlvbkF0dGVtcHRzKG9wdHMucmVjb25uZWN0aW9uQXR0ZW1wdHMgfHwgSW5maW5pdHkpO1xuICB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KG9wdHMucmVjb25uZWN0aW9uRGVsYXkgfHwgMTAwMCk7XG4gIHRoaXMucmVjb25uZWN0aW9uRGVsYXlNYXgob3B0cy5yZWNvbm5lY3Rpb25EZWxheU1heCB8fCA1MDAwKTtcbiAgdGhpcy5yYW5kb21pemF0aW9uRmFjdG9yKG9wdHMucmFuZG9taXphdGlvbkZhY3RvciB8fCAwLjUpO1xuICB0aGlzLmJhY2tvZmYgPSBuZXcgQmFja29mZih7XG4gICAgbWluOiB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KCksXG4gICAgbWF4OiB0aGlzLnJlY29ubmVjdGlvbkRlbGF5TWF4KCksXG4gICAgaml0dGVyOiB0aGlzLnJhbmRvbWl6YXRpb25GYWN0b3IoKVxuICB9KTtcbiAgdGhpcy50aW1lb3V0KG51bGwgPT0gb3B0cy50aW1lb3V0ID8gMjAwMDAgOiBvcHRzLnRpbWVvdXQpO1xuICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgdGhpcy51cmkgPSB1cmk7XG4gIHRoaXMuY29ubmVjdGluZyA9IFtdO1xuICB0aGlzLmxhc3RQaW5nID0gbnVsbDtcbiAgdGhpcy5lbmNvZGluZyA9IGZhbHNlO1xuICB0aGlzLnBhY2tldEJ1ZmZlciA9IFtdO1xuICB0aGlzLmVuY29kZXIgPSBuZXcgcGFyc2VyLkVuY29kZXIoKTtcbiAgdGhpcy5kZWNvZGVyID0gbmV3IHBhcnNlci5EZWNvZGVyKCk7XG4gIHRoaXMuYXV0b0Nvbm5lY3QgPSBvcHRzLmF1dG9Db25uZWN0ICE9PSBmYWxzZTtcbiAgaWYgKHRoaXMuYXV0b0Nvbm5lY3QpIHRoaXMub3BlbigpO1xufVxuXG4vKipcbiAqIFByb3BhZ2F0ZSBnaXZlbiBldmVudCB0byBzb2NrZXRzIGFuZCBlbWl0IG9uIGB0aGlzYFxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLmVtaXRBbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICBmb3IgKHZhciBuc3AgaW4gdGhpcy5uc3BzKSB7XG4gICAgaWYgKGhhcy5jYWxsKHRoaXMubnNwcywgbnNwKSkge1xuICAgICAgdGhpcy5uc3BzW25zcF0uZW1pdC5hcHBseSh0aGlzLm5zcHNbbnNwXSwgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogVXBkYXRlIGBzb2NrZXQuaWRgIG9mIGFsbCBzb2NrZXRzXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUudXBkYXRlU29ja2V0SWRzID0gZnVuY3Rpb24gKCkge1xuICBmb3IgKHZhciBuc3AgaW4gdGhpcy5uc3BzKSB7XG4gICAgaWYgKGhhcy5jYWxsKHRoaXMubnNwcywgbnNwKSkge1xuICAgICAgdGhpcy5uc3BzW25zcF0uaWQgPSB0aGlzLmVuZ2luZS5pZDtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKE1hbmFnZXIucHJvdG90eXBlKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBgcmVjb25uZWN0aW9uYCBjb25maWcuXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSB0cnVlL2ZhbHNlIGlmIGl0IHNob3VsZCBhdXRvbWF0aWNhbGx5IHJlY29ubmVjdFxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb24gPSBmdW5jdGlvbiAodikge1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb247XG4gIHRoaXMuX3JlY29ubmVjdGlvbiA9ICEhdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIHJlY29ubmVjdGlvbiBhdHRlbXB0cyBjb25maWcuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1heCByZWNvbm5lY3Rpb24gYXR0ZW1wdHMgYmVmb3JlIGdpdmluZyB1cFxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25BdHRlbXB0cyA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JlY29ubmVjdGlvbkF0dGVtcHRzO1xuICB0aGlzLl9yZWNvbm5lY3Rpb25BdHRlbXB0cyA9IHY7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBkZWxheSBiZXR3ZWVuIHJlY29ubmVjdGlvbnMuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGRlbGF5XG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnJlY29ubmVjdGlvbkRlbGF5ID0gZnVuY3Rpb24gKHYpIHtcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fcmVjb25uZWN0aW9uRGVsYXk7XG4gIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5ID0gdjtcbiAgdGhpcy5iYWNrb2ZmICYmIHRoaXMuYmFja29mZi5zZXRNaW4odik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuTWFuYWdlci5wcm90b3R5cGUucmFuZG9taXphdGlvbkZhY3RvciA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JhbmRvbWl6YXRpb25GYWN0b3I7XG4gIHRoaXMuX3JhbmRvbWl6YXRpb25GYWN0b3IgPSB2O1xuICB0aGlzLmJhY2tvZmYgJiYgdGhpcy5iYWNrb2ZmLnNldEppdHRlcih2KTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIG1heGltdW0gZGVsYXkgYmV0d2VlbiByZWNvbm5lY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBkZWxheVxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25EZWxheU1heCA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5TWF4O1xuICB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheU1heCA9IHY7XG4gIHRoaXMuYmFja29mZiAmJiB0aGlzLmJhY2tvZmYuc2V0TWF4KHYpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgY29ubmVjdGlvbiB0aW1lb3V0LiBgZmFsc2VgIHRvIGRpc2FibGVcbiAqXG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnRpbWVvdXQgPSBmdW5jdGlvbiAodikge1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl90aW1lb3V0O1xuICB0aGlzLl90aW1lb3V0ID0gdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyB0cnlpbmcgdG8gcmVjb25uZWN0IGlmIHJlY29ubmVjdGlvbiBpcyBlbmFibGVkIGFuZCB3ZSBoYXZlIG5vdFxuICogc3RhcnRlZCByZWNvbm5lY3RpbmcgeWV0XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUubWF5YmVSZWNvbm5lY3RPbk9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIC8vIE9ubHkgdHJ5IHRvIHJlY29ubmVjdCBpZiBpdCdzIHRoZSBmaXJzdCB0aW1lIHdlJ3JlIGNvbm5lY3RpbmdcbiAgaWYgKCF0aGlzLnJlY29ubmVjdGluZyAmJiB0aGlzLl9yZWNvbm5lY3Rpb24gJiYgdGhpcy5iYWNrb2ZmLmF0dGVtcHRzID09PSAwKSB7XG4gICAgLy8ga2VlcHMgcmVjb25uZWN0aW9uIGZyb20gZmlyaW5nIHR3aWNlIGZvciB0aGUgc2FtZSByZWNvbm5lY3Rpb24gbG9vcFxuICAgIHRoaXMucmVjb25uZWN0KCk7XG4gIH1cbn07XG5cbi8qKlxuICogU2V0cyB0aGUgY3VycmVudCB0cmFuc3BvcnQgYHNvY2tldGAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gb3B0aW9uYWwsIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9wZW4gPVxuTWFuYWdlci5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uIChmbiwgb3B0cykge1xuICBkZWJ1ZygncmVhZHlTdGF0ZSAlcycsIHRoaXMucmVhZHlTdGF0ZSk7XG4gIGlmICh+dGhpcy5yZWFkeVN0YXRlLmluZGV4T2YoJ29wZW4nKSkgcmV0dXJuIHRoaXM7XG5cbiAgZGVidWcoJ29wZW5pbmcgJXMnLCB0aGlzLnVyaSk7XG4gIHRoaXMuZW5naW5lID0gZWlvKHRoaXMudXJpLCB0aGlzLm9wdHMpO1xuICB2YXIgc29ja2V0ID0gdGhpcy5lbmdpbmU7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW5pbmcnO1xuICB0aGlzLnNraXBSZWNvbm5lY3QgPSBmYWxzZTtcblxuICAvLyBlbWl0IGBvcGVuYFxuICB2YXIgb3BlblN1YiA9IG9uKHNvY2tldCwgJ29wZW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5vbm9wZW4oKTtcbiAgICBmbiAmJiBmbigpO1xuICB9KTtcblxuICAvLyBlbWl0IGBjb25uZWN0X2Vycm9yYFxuICB2YXIgZXJyb3JTdWIgPSBvbihzb2NrZXQsICdlcnJvcicsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgZGVidWcoJ2Nvbm5lY3RfZXJyb3InKTtcbiAgICBzZWxmLmNsZWFudXAoKTtcbiAgICBzZWxmLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgICBzZWxmLmVtaXRBbGwoJ2Nvbm5lY3RfZXJyb3InLCBkYXRhKTtcbiAgICBpZiAoZm4pIHtcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gZXJyb3InKTtcbiAgICAgIGVyci5kYXRhID0gZGF0YTtcbiAgICAgIGZuKGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE9ubHkgZG8gdGhpcyBpZiB0aGVyZSBpcyBubyBmbiB0byBoYW5kbGUgdGhlIGVycm9yXG4gICAgICBzZWxmLm1heWJlUmVjb25uZWN0T25PcGVuKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBlbWl0IGBjb25uZWN0X3RpbWVvdXRgXG4gIGlmIChmYWxzZSAhPT0gdGhpcy5fdGltZW91dCkge1xuICAgIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgICBkZWJ1ZygnY29ubmVjdCBhdHRlbXB0IHdpbGwgdGltZW91dCBhZnRlciAlZCcsIHRpbWVvdXQpO1xuXG4gICAgLy8gc2V0IHRpbWVyXG4gICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBkZWJ1ZygnY29ubmVjdCBhdHRlbXB0IHRpbWVkIG91dCBhZnRlciAlZCcsIHRpbWVvdXQpO1xuICAgICAgb3BlblN1Yi5kZXN0cm95KCk7XG4gICAgICBzb2NrZXQuY2xvc2UoKTtcbiAgICAgIHNvY2tldC5lbWl0KCdlcnJvcicsICd0aW1lb3V0Jyk7XG4gICAgICBzZWxmLmVtaXRBbGwoJ2Nvbm5lY3RfdGltZW91dCcsIHRpbWVvdXQpO1xuICAgIH0sIHRpbWVvdXQpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdGhpcy5zdWJzLnB1c2gob3BlblN1Yik7XG4gIHRoaXMuc3Vicy5wdXNoKGVycm9yU3ViKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IG9wZW4uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1Zygnb3BlbicpO1xuXG4gIC8vIGNsZWFyIG9sZCBzdWJzXG4gIHRoaXMuY2xlYW51cCgpO1xuXG4gIC8vIG1hcmsgYXMgb3BlblxuICB0aGlzLnJlYWR5U3RhdGUgPSAnb3Blbic7XG4gIHRoaXMuZW1pdCgnb3BlbicpO1xuXG4gIC8vIGFkZCBuZXcgc3Vic1xuICB2YXIgc29ja2V0ID0gdGhpcy5lbmdpbmU7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2RhdGEnLCBiaW5kKHRoaXMsICdvbmRhdGEnKSkpO1xuICB0aGlzLnN1YnMucHVzaChvbihzb2NrZXQsICdwaW5nJywgYmluZCh0aGlzLCAnb25waW5nJykpKTtcbiAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAncG9uZycsIGJpbmQodGhpcywgJ29ucG9uZycpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2Vycm9yJywgYmluZCh0aGlzLCAnb25lcnJvcicpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2Nsb3NlJywgYmluZCh0aGlzLCAnb25jbG9zZScpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHRoaXMuZGVjb2RlciwgJ2RlY29kZWQnLCBiaW5kKHRoaXMsICdvbmRlY29kZWQnKSkpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBhIHBpbmcuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25waW5nID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmxhc3RQaW5nID0gbmV3IERhdGUoKTtcbiAgdGhpcy5lbWl0QWxsKCdwaW5nJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgcGFja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9ucG9uZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0QWxsKCdwb25nJywgbmV3IERhdGUoKSAtIHRoaXMubGFzdFBpbmcpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgd2l0aCBkYXRhLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uZGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuZGVjb2Rlci5hZGQoZGF0YSk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aGVuIHBhcnNlciBmdWxseSBkZWNvZGVzIGEgcGFja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uZGVjb2RlZCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzb2NrZXQgZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25lcnJvciA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgZGVidWcoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5lbWl0QWxsKCdlcnJvcicsIGVycik7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc29ja2V0IGZvciB0aGUgZ2l2ZW4gYG5zcGAuXG4gKlxuICogQHJldHVybiB7U29ja2V0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5zb2NrZXQgPSBmdW5jdGlvbiAobnNwLCBvcHRzKSB7XG4gIHZhciBzb2NrZXQgPSB0aGlzLm5zcHNbbnNwXTtcbiAgaWYgKCFzb2NrZXQpIHtcbiAgICBzb2NrZXQgPSBuZXcgU29ja2V0KHRoaXMsIG5zcCwgb3B0cyk7XG4gICAgdGhpcy5uc3BzW25zcF0gPSBzb2NrZXQ7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHNvY2tldC5vbignY29ubmVjdGluZycsIG9uQ29ubmVjdGluZyk7XG4gICAgc29ja2V0Lm9uKCdjb25uZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgc29ja2V0LmlkID0gc2VsZi5lbmdpbmUuaWQ7XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5hdXRvQ29ubmVjdCkge1xuICAgICAgLy8gbWFudWFsbHkgY2FsbCBoZXJlIHNpbmNlIGNvbm5lY3RpbmcgZXZuZXQgaXMgZmlyZWQgYmVmb3JlIGxpc3RlbmluZ1xuICAgICAgb25Db25uZWN0aW5nKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25Db25uZWN0aW5nICgpIHtcbiAgICBpZiAoIX5pbmRleE9mKHNlbGYuY29ubmVjdGluZywgc29ja2V0KSkge1xuICAgICAgc2VsZi5jb25uZWN0aW5nLnB1c2goc29ja2V0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc29ja2V0O1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBhIHNvY2tldCBjbG9zZS5cbiAqXG4gKiBAcGFyYW0ge1NvY2tldH0gc29ja2V0XG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uIChzb2NrZXQpIHtcbiAgdmFyIGluZGV4ID0gaW5kZXhPZih0aGlzLmNvbm5lY3RpbmcsIHNvY2tldCk7XG4gIGlmICh+aW5kZXgpIHRoaXMuY29ubmVjdGluZy5zcGxpY2UoaW5kZXgsIDEpO1xuICBpZiAodGhpcy5jb25uZWN0aW5nLmxlbmd0aCkgcmV0dXJuO1xuXG4gIHRoaXMuY2xvc2UoKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgcGFja2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgZGVidWcoJ3dyaXRpbmcgcGFja2V0ICVqJywgcGFja2V0KTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAocGFja2V0LnF1ZXJ5ICYmIHBhY2tldC50eXBlID09PSAwKSBwYWNrZXQubnNwICs9ICc/JyArIHBhY2tldC5xdWVyeTtcblxuICBpZiAoIXNlbGYuZW5jb2RpbmcpIHtcbiAgICAvLyBlbmNvZGUsIHRoZW4gd3JpdGUgdG8gZW5naW5lIHdpdGggcmVzdWx0XG4gICAgc2VsZi5lbmNvZGluZyA9IHRydWU7XG4gICAgdGhpcy5lbmNvZGVyLmVuY29kZShwYWNrZXQsIGZ1bmN0aW9uIChlbmNvZGVkUGFja2V0cykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbmNvZGVkUGFja2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBzZWxmLmVuZ2luZS53cml0ZShlbmNvZGVkUGFja2V0c1tpXSwgcGFja2V0Lm9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgc2VsZi5lbmNvZGluZyA9IGZhbHNlO1xuICAgICAgc2VsZi5wcm9jZXNzUGFja2V0UXVldWUoKTtcbiAgICB9KTtcbiAgfSBlbHNlIHsgLy8gYWRkIHBhY2tldCB0byB0aGUgcXVldWVcbiAgICBzZWxmLnBhY2tldEJ1ZmZlci5wdXNoKHBhY2tldCk7XG4gIH1cbn07XG5cbi8qKlxuICogSWYgcGFja2V0IGJ1ZmZlciBpcyBub24tZW1wdHksIGJlZ2lucyBlbmNvZGluZyB0aGVcbiAqIG5leHQgcGFja2V0IGluIGxpbmUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUucHJvY2Vzc1BhY2tldFF1ZXVlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5wYWNrZXRCdWZmZXIubGVuZ3RoID4gMCAmJiAhdGhpcy5lbmNvZGluZykge1xuICAgIHZhciBwYWNrID0gdGhpcy5wYWNrZXRCdWZmZXIuc2hpZnQoKTtcbiAgICB0aGlzLnBhY2tldChwYWNrKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDbGVhbiB1cCB0cmFuc3BvcnQgc3Vic2NyaXB0aW9ucyBhbmQgcGFja2V0IGJ1ZmZlci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5jbGVhbnVwID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2xlYW51cCcpO1xuXG4gIHZhciBzdWJzTGVuZ3RoID0gdGhpcy5zdWJzLmxlbmd0aDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdWJzTGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc3ViID0gdGhpcy5zdWJzLnNoaWZ0KCk7XG4gICAgc3ViLmRlc3Ryb3koKTtcbiAgfVxuXG4gIHRoaXMucGFja2V0QnVmZmVyID0gW107XG4gIHRoaXMuZW5jb2RpbmcgPSBmYWxzZTtcbiAgdGhpcy5sYXN0UGluZyA9IG51bGw7XG5cbiAgdGhpcy5kZWNvZGVyLmRlc3Ryb3koKTtcbn07XG5cbi8qKlxuICogQ2xvc2UgdGhlIGN1cnJlbnQgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLmNsb3NlID1cbk1hbmFnZXIucHJvdG90eXBlLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCdkaXNjb25uZWN0Jyk7XG4gIHRoaXMuc2tpcFJlY29ubmVjdCA9IHRydWU7XG4gIHRoaXMucmVjb25uZWN0aW5nID0gZmFsc2U7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIC8vIGBvbmNsb3NlYCB3aWxsIG5vdCBmaXJlIGJlY2F1c2VcbiAgICAvLyBhbiBvcGVuIGV2ZW50IG5ldmVyIGhhcHBlbmVkXG4gICAgdGhpcy5jbGVhbnVwKCk7XG4gIH1cbiAgdGhpcy5iYWNrb2ZmLnJlc2V0KCk7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuICBpZiAodGhpcy5lbmdpbmUpIHRoaXMuZW5naW5lLmNsb3NlKCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGVuZ2luZSBjbG9zZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vbmNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICBkZWJ1Zygnb25jbG9zZScpO1xuXG4gIHRoaXMuY2xlYW51cCgpO1xuICB0aGlzLmJhY2tvZmYucmVzZXQoKTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnLCByZWFzb24pO1xuXG4gIGlmICh0aGlzLl9yZWNvbm5lY3Rpb24gJiYgIXRoaXMuc2tpcFJlY29ubmVjdCkge1xuICAgIHRoaXMucmVjb25uZWN0KCk7XG4gIH1cbn07XG5cbi8qKlxuICogQXR0ZW1wdCBhIHJlY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnJlY29ubmVjdGluZyB8fCB0aGlzLnNraXBSZWNvbm5lY3QpIHJldHVybiB0aGlzO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAodGhpcy5iYWNrb2ZmLmF0dGVtcHRzID49IHRoaXMuX3JlY29ubmVjdGlvbkF0dGVtcHRzKSB7XG4gICAgZGVidWcoJ3JlY29ubmVjdCBmYWlsZWQnKTtcbiAgICB0aGlzLmJhY2tvZmYucmVzZXQoKTtcbiAgICB0aGlzLmVtaXRBbGwoJ3JlY29ubmVjdF9mYWlsZWQnKTtcbiAgICB0aGlzLnJlY29ubmVjdGluZyA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHZhciBkZWxheSA9IHRoaXMuYmFja29mZi5kdXJhdGlvbigpO1xuICAgIGRlYnVnKCd3aWxsIHdhaXQgJWRtcyBiZWZvcmUgcmVjb25uZWN0IGF0dGVtcHQnLCBkZWxheSk7XG5cbiAgICB0aGlzLnJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoc2VsZi5za2lwUmVjb25uZWN0KSByZXR1cm47XG5cbiAgICAgIGRlYnVnKCdhdHRlbXB0aW5nIHJlY29ubmVjdCcpO1xuICAgICAgc2VsZi5lbWl0QWxsKCdyZWNvbm5lY3RfYXR0ZW1wdCcsIHNlbGYuYmFja29mZi5hdHRlbXB0cyk7XG4gICAgICBzZWxmLmVtaXRBbGwoJ3JlY29ubmVjdGluZycsIHNlbGYuYmFja29mZi5hdHRlbXB0cyk7XG5cbiAgICAgIC8vIGNoZWNrIGFnYWluIGZvciB0aGUgY2FzZSBzb2NrZXQgY2xvc2VkIGluIGFib3ZlIGV2ZW50c1xuICAgICAgaWYgKHNlbGYuc2tpcFJlY29ubmVjdCkgcmV0dXJuO1xuXG4gICAgICBzZWxmLm9wZW4oZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgZGVidWcoJ3JlY29ubmVjdCBhdHRlbXB0IGVycm9yJyk7XG4gICAgICAgICAgc2VsZi5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLnJlY29ubmVjdCgpO1xuICAgICAgICAgIHNlbGYuZW1pdEFsbCgncmVjb25uZWN0X2Vycm9yJywgZXJyLmRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlYnVnKCdyZWNvbm5lY3Qgc3VjY2VzcycpO1xuICAgICAgICAgIHNlbGYub25yZWNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSwgZGVsYXkpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHN1Y2Nlc3NmdWwgcmVjb25uZWN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9ucmVjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXR0ZW1wdCA9IHRoaXMuYmFja29mZi5hdHRlbXB0cztcbiAgdGhpcy5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgdGhpcy5iYWNrb2ZmLnJlc2V0KCk7XG4gIHRoaXMudXBkYXRlU29ja2V0SWRzKCk7XG4gIHRoaXMuZW1pdEFsbCgncmVjb25uZWN0JywgYXR0ZW1wdCk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1e1f\n")},"1ed2":function(module,exports){eval("/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function(val, options){\n  options = options || {};\n  if ('string' == typeof val) return parse(val);\n  return options.long\n    ? long(val)\n    : short(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n  str = '' + str;\n  if (str.length > 10000) return;\n  var match = /^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);\n  if (!match) return;\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'yrs':\n    case 'yr':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'hrs':\n    case 'hr':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'mins':\n    case 'min':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 'secs':\n    case 'sec':\n    case 's':\n      return n * s;\n    case 'milliseconds':\n    case 'millisecond':\n    case 'msecs':\n    case 'msec':\n    case 'ms':\n      return n;\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction short(ms) {\n  if (ms >= d) return Math.round(ms / d) + 'd';\n  if (ms >= h) return Math.round(ms / h) + 'h';\n  if (ms >= m) return Math.round(ms / m) + 'm';\n  if (ms >= s) return Math.round(ms / s) + 's';\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction long(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, n, name) {\n  if (ms < n) return;\n  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMWVkMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvbXMvaW5kZXguanM/NDg1MiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhlbHBlcnMuXG4gKi9cblxudmFyIHMgPSAxMDAwO1xudmFyIG0gPSBzICogNjA7XG52YXIgaCA9IG0gKiA2MDtcbnZhciBkID0gaCAqIDI0O1xudmFyIHkgPSBkICogMzY1LjI1O1xuXG4vKipcbiAqIFBhcnNlIG9yIGZvcm1hdCB0aGUgZ2l2ZW4gYHZhbGAuXG4gKlxuICogT3B0aW9uczpcbiAqXG4gKiAgLSBgbG9uZ2AgdmVyYm9zZSBmb3JtYXR0aW5nIFtmYWxzZV1cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xOdW1iZXJ9IHZhbFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ3xOdW1iZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24odmFsLCBvcHRpb25zKXtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGlmICgnc3RyaW5nJyA9PSB0eXBlb2YgdmFsKSByZXR1cm4gcGFyc2UodmFsKTtcbiAgcmV0dXJuIG9wdGlvbnMubG9uZ1xuICAgID8gbG9uZyh2YWwpXG4gICAgOiBzaG9ydCh2YWwpO1xufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gYHN0cmAgYW5kIHJldHVybiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7TnVtYmVyfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcGFyc2Uoc3RyKSB7XG4gIHN0ciA9ICcnICsgc3RyO1xuICBpZiAoc3RyLmxlbmd0aCA+IDEwMDAwKSByZXR1cm47XG4gIHZhciBtYXRjaCA9IC9eKCg/OlxcZCspP1xcLj9cXGQrKSAqKG1pbGxpc2Vjb25kcz98bXNlY3M/fG1zfHNlY29uZHM/fHNlY3M/fHN8bWludXRlcz98bWlucz98bXxob3Vycz98aHJzP3xofGRheXM/fGR8eWVhcnM/fHlycz98eSk/JC9pLmV4ZWMoc3RyKTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuO1xuICB2YXIgbiA9IHBhcnNlRmxvYXQobWF0Y2hbMV0pO1xuICB2YXIgdHlwZSA9IChtYXRjaFsyXSB8fCAnbXMnKS50b0xvd2VyQ2FzZSgpO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICd5ZWFycyc6XG4gICAgY2FzZSAneWVhcic6XG4gICAgY2FzZSAneXJzJzpcbiAgICBjYXNlICd5cic6XG4gICAgY2FzZSAneSc6XG4gICAgICByZXR1cm4gbiAqIHk7XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZDtcbiAgICBjYXNlICdob3Vycyc6XG4gICAgY2FzZSAnaG91cic6XG4gICAgY2FzZSAnaHJzJzpcbiAgICBjYXNlICdocic6XG4gICAgY2FzZSAnaCc6XG4gICAgICByZXR1cm4gbiAqIGg7XG4gICAgY2FzZSAnbWludXRlcyc6XG4gICAgY2FzZSAnbWludXRlJzpcbiAgICBjYXNlICdtaW5zJzpcbiAgICBjYXNlICdtaW4nOlxuICAgIGNhc2UgJ20nOlxuICAgICAgcmV0dXJuIG4gKiBtO1xuICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgY2FzZSAnc2Vjcyc6XG4gICAgY2FzZSAnc2VjJzpcbiAgICBjYXNlICdzJzpcbiAgICAgIHJldHVybiBuICogcztcbiAgICBjYXNlICdtaWxsaXNlY29uZHMnOlxuICAgIGNhc2UgJ21pbGxpc2Vjb25kJzpcbiAgICBjYXNlICdtc2Vjcyc6XG4gICAgY2FzZSAnbXNlYyc6XG4gICAgY2FzZSAnbXMnOlxuICAgICAgcmV0dXJuIG47XG4gIH1cbn1cblxuLyoqXG4gKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzaG9ydChtcykge1xuICBpZiAobXMgPj0gZCkgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArICdkJztcbiAgaWYgKG1zID49IGgpIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gaCkgKyAnaCc7XG4gIGlmIChtcyA+PSBtKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIG0pICsgJ20nO1xuICBpZiAobXMgPj0gcykgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArICdzJztcbiAgcmV0dXJuIG1zICsgJ21zJztcbn1cblxuLyoqXG4gKiBMb25nIGZvcm1hdCBmb3IgYG1zYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbXNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvbmcobXMpIHtcbiAgcmV0dXJuIHBsdXJhbChtcywgZCwgJ2RheScpXG4gICAgfHwgcGx1cmFsKG1zLCBoLCAnaG91cicpXG4gICAgfHwgcGx1cmFsKG1zLCBtLCAnbWludXRlJylcbiAgICB8fCBwbHVyYWwobXMsIHMsICdzZWNvbmQnKVxuICAgIHx8IG1zICsgJyBtcyc7XG59XG5cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi9cblxuZnVuY3Rpb24gcGx1cmFsKG1zLCBuLCBuYW1lKSB7XG4gIGlmIChtcyA8IG4pIHJldHVybjtcbiAgaWYgKG1zIDwgbiAqIDEuNSkgcmV0dXJuIE1hdGguZmxvb3IobXMgLyBuKSArICcgJyArIG5hbWU7XG4gIHJldHVybiBNYXRoLmNlaWwobXMgLyBuKSArICcgJyArIG5hbWUgKyAncyc7XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1ed2\n")},"23b1":function(module,exports,__webpack_require__){eval("\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = debug.debug = debug;\nexports.coerce = coerce;\nexports.disable = disable;\nexports.enable = enable;\nexports.enabled = enabled;\nexports.humanize = __webpack_require__(/*! ms */ \"0b10\");\n\n/**\n * The currently active debug mode names, and names to skip.\n */\n\nexports.names = [];\nexports.skips = [];\n\n/**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lowercased letter, i.e. \"n\".\n */\n\nexports.formatters = {};\n\n/**\n * Previously assigned color.\n */\n\nvar prevColor = 0;\n\n/**\n * Previous log timestamp.\n */\n\nvar prevTime;\n\n/**\n * Select a color.\n *\n * @return {Number}\n * @api private\n */\n\nfunction selectColor() {\n  return exports.colors[prevColor++ % exports.colors.length];\n}\n\n/**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\nfunction debug(namespace) {\n\n  // define the `disabled` version\n  function disabled() {\n  }\n  disabled.enabled = false;\n\n  // define the `enabled` version\n  function enabled() {\n\n    var self = enabled;\n\n    // set `diff` timestamp\n    var curr = +new Date();\n    var ms = curr - (prevTime || curr);\n    self.diff = ms;\n    self.prev = prevTime;\n    self.curr = curr;\n    prevTime = curr;\n\n    // add the `color` if not set\n    if (null == self.useColors) self.useColors = exports.useColors();\n    if (null == self.color && self.useColors) self.color = selectColor();\n\n    var args = new Array(arguments.length);\n    for (var i = 0; i < args.length; i++) {\n      args[i] = arguments[i];\n    }\n\n    args[0] = exports.coerce(args[0]);\n\n    if ('string' !== typeof args[0]) {\n      // anything else let's inspect with %o\n      args = ['%o'].concat(args);\n    }\n\n    // apply any `formatters` transformations\n    var index = 0;\n    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {\n      // if we encounter an escaped % then don't increase the array index\n      if (match === '%%') return match;\n      index++;\n      var formatter = exports.formatters[format];\n      if ('function' === typeof formatter) {\n        var val = args[index];\n        match = formatter.call(self, val);\n\n        // now we need to remove `args[index]` since it's inlined in the `format`\n        args.splice(index, 1);\n        index--;\n      }\n      return match;\n    });\n\n    // apply env-specific formatting\n    args = exports.formatArgs.apply(self, args);\n\n    var logFn = enabled.log || exports.log || console.log.bind(console);\n    logFn.apply(self, args);\n  }\n  enabled.enabled = true;\n\n  var fn = exports.enabled(namespace) ? enabled : disabled;\n\n  fn.namespace = namespace;\n\n  return fn;\n}\n\n/**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\nfunction enable(namespaces) {\n  exports.save(namespaces);\n\n  var split = (namespaces || '').split(/[\\s,]+/);\n  var len = split.length;\n\n  for (var i = 0; i < len; i++) {\n    if (!split[i]) continue; // ignore empty strings\n    namespaces = split[i].replace(/[\\\\^$+?.()|[\\]{}]/g, '\\\\$&').replace(/\\*/g, '.*?');\n    if (namespaces[0] === '-') {\n      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n    } else {\n      exports.names.push(new RegExp('^' + namespaces + '$'));\n    }\n  }\n}\n\n/**\n * Disable debug output.\n *\n * @api public\n */\n\nfunction disable() {\n  exports.enable('');\n}\n\n/**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\nfunction enabled(name) {\n  var i, len;\n  for (i = 0, len = exports.skips.length; i < len; i++) {\n    if (exports.skips[i].test(name)) {\n      return false;\n    }\n  }\n  for (i = 0, len = exports.names.length; i < len; i++) {\n    if (exports.names[i].test(name)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\nfunction coerce(val) {\n  if (val instanceof Error) return val.stack || val.message;\n  return val;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjNiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZGVidWcvZGVidWcuanM/NjMxMiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogVGhpcyBpcyB0aGUgY29tbW9uIGxvZ2ljIGZvciBib3RoIHRoZSBOb2RlLmpzIGFuZCB3ZWIgYnJvd3NlclxuICogaW1wbGVtZW50YXRpb25zIG9mIGBkZWJ1ZygpYC5cbiAqXG4gKiBFeHBvc2UgYGRlYnVnKClgIGFzIHRoZSBtb2R1bGUuXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZGVidWcuZGVidWcgPSBkZWJ1ZztcbmV4cG9ydHMuY29lcmNlID0gY29lcmNlO1xuZXhwb3J0cy5kaXNhYmxlID0gZGlzYWJsZTtcbmV4cG9ydHMuZW5hYmxlID0gZW5hYmxlO1xuZXhwb3J0cy5lbmFibGVkID0gZW5hYmxlZDtcbmV4cG9ydHMuaHVtYW5pemUgPSByZXF1aXJlKCdtcycpO1xuXG4vKipcbiAqIFRoZSBjdXJyZW50bHkgYWN0aXZlIGRlYnVnIG1vZGUgbmFtZXMsIGFuZCBuYW1lcyB0byBza2lwLlxuICovXG5cbmV4cG9ydHMubmFtZXMgPSBbXTtcbmV4cG9ydHMuc2tpcHMgPSBbXTtcblxuLyoqXG4gKiBNYXAgb2Ygc3BlY2lhbCBcIiVuXCIgaGFuZGxpbmcgZnVuY3Rpb25zLCBmb3IgdGhlIGRlYnVnIFwiZm9ybWF0XCIgYXJndW1lbnQuXG4gKlxuICogVmFsaWQga2V5IG5hbWVzIGFyZSBhIHNpbmdsZSwgbG93ZXJjYXNlZCBsZXR0ZXIsIGkuZS4gXCJuXCIuXG4gKi9cblxuZXhwb3J0cy5mb3JtYXR0ZXJzID0ge307XG5cbi8qKlxuICogUHJldmlvdXNseSBhc3NpZ25lZCBjb2xvci5cbiAqL1xuXG52YXIgcHJldkNvbG9yID0gMDtcblxuLyoqXG4gKiBQcmV2aW91cyBsb2cgdGltZXN0YW1wLlxuICovXG5cbnZhciBwcmV2VGltZTtcblxuLyoqXG4gKiBTZWxlY3QgYSBjb2xvci5cbiAqXG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzZWxlY3RDb2xvcigpIHtcbiAgcmV0dXJuIGV4cG9ydHMuY29sb3JzW3ByZXZDb2xvcisrICUgZXhwb3J0cy5jb2xvcnMubGVuZ3RoXTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBkZWJ1Z2dlciB3aXRoIHRoZSBnaXZlbiBgbmFtZXNwYWNlYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZGVidWcobmFtZXNwYWNlKSB7XG5cbiAgLy8gZGVmaW5lIHRoZSBgZGlzYWJsZWRgIHZlcnNpb25cbiAgZnVuY3Rpb24gZGlzYWJsZWQoKSB7XG4gIH1cbiAgZGlzYWJsZWQuZW5hYmxlZCA9IGZhbHNlO1xuXG4gIC8vIGRlZmluZSB0aGUgYGVuYWJsZWRgIHZlcnNpb25cbiAgZnVuY3Rpb24gZW5hYmxlZCgpIHtcblxuICAgIHZhciBzZWxmID0gZW5hYmxlZDtcblxuICAgIC8vIHNldCBgZGlmZmAgdGltZXN0YW1wXG4gICAgdmFyIGN1cnIgPSArbmV3IERhdGUoKTtcbiAgICB2YXIgbXMgPSBjdXJyIC0gKHByZXZUaW1lIHx8IGN1cnIpO1xuICAgIHNlbGYuZGlmZiA9IG1zO1xuICAgIHNlbGYucHJldiA9IHByZXZUaW1lO1xuICAgIHNlbGYuY3VyciA9IGN1cnI7XG4gICAgcHJldlRpbWUgPSBjdXJyO1xuXG4gICAgLy8gYWRkIHRoZSBgY29sb3JgIGlmIG5vdCBzZXRcbiAgICBpZiAobnVsbCA9PSBzZWxmLnVzZUNvbG9ycykgc2VsZi51c2VDb2xvcnMgPSBleHBvcnRzLnVzZUNvbG9ycygpO1xuICAgIGlmIChudWxsID09IHNlbGYuY29sb3IgJiYgc2VsZi51c2VDb2xvcnMpIHNlbGYuY29sb3IgPSBzZWxlY3RDb2xvcigpO1xuXG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgIH1cblxuICAgIGFyZ3NbMF0gPSBleHBvcnRzLmNvZXJjZShhcmdzWzBdKTtcblxuICAgIGlmICgnc3RyaW5nJyAhPT0gdHlwZW9mIGFyZ3NbMF0pIHtcbiAgICAgIC8vIGFueXRoaW5nIGVsc2UgbGV0J3MgaW5zcGVjdCB3aXRoICVvXG4gICAgICBhcmdzID0gWyclbyddLmNvbmNhdChhcmdzKTtcbiAgICB9XG5cbiAgICAvLyBhcHBseSBhbnkgYGZvcm1hdHRlcnNgIHRyYW5zZm9ybWF0aW9uc1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgYXJnc1swXSA9IGFyZ3NbMF0ucmVwbGFjZSgvJShbYS16JV0pL2csIGZ1bmN0aW9uKG1hdGNoLCBmb3JtYXQpIHtcbiAgICAgIC8vIGlmIHdlIGVuY291bnRlciBhbiBlc2NhcGVkICUgdGhlbiBkb24ndCBpbmNyZWFzZSB0aGUgYXJyYXkgaW5kZXhcbiAgICAgIGlmIChtYXRjaCA9PT0gJyUlJykgcmV0dXJuIG1hdGNoO1xuICAgICAgaW5kZXgrKztcbiAgICAgIHZhciBmb3JtYXR0ZXIgPSBleHBvcnRzLmZvcm1hdHRlcnNbZm9ybWF0XTtcbiAgICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgZm9ybWF0dGVyKSB7XG4gICAgICAgIHZhciB2YWwgPSBhcmdzW2luZGV4XTtcbiAgICAgICAgbWF0Y2ggPSBmb3JtYXR0ZXIuY2FsbChzZWxmLCB2YWwpO1xuXG4gICAgICAgIC8vIG5vdyB3ZSBuZWVkIHRvIHJlbW92ZSBgYXJnc1tpbmRleF1gIHNpbmNlIGl0J3MgaW5saW5lZCBpbiB0aGUgYGZvcm1hdGBcbiAgICAgICAgYXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBpbmRleC0tO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH0pO1xuXG4gICAgLy8gYXBwbHkgZW52LXNwZWNpZmljIGZvcm1hdHRpbmdcbiAgICBhcmdzID0gZXhwb3J0cy5mb3JtYXRBcmdzLmFwcGx5KHNlbGYsIGFyZ3MpO1xuXG4gICAgdmFyIGxvZ0ZuID0gZW5hYmxlZC5sb2cgfHwgZXhwb3J0cy5sb2cgfHwgY29uc29sZS5sb2cuYmluZChjb25zb2xlKTtcbiAgICBsb2dGbi5hcHBseShzZWxmLCBhcmdzKTtcbiAgfVxuICBlbmFibGVkLmVuYWJsZWQgPSB0cnVlO1xuXG4gIHZhciBmbiA9IGV4cG9ydHMuZW5hYmxlZChuYW1lc3BhY2UpID8gZW5hYmxlZCA6IGRpc2FibGVkO1xuXG4gIGZuLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTtcblxuICByZXR1cm4gZm47XG59XG5cbi8qKlxuICogRW5hYmxlcyBhIGRlYnVnIG1vZGUgYnkgbmFtZXNwYWNlcy4gVGhpcyBjYW4gaW5jbHVkZSBtb2Rlc1xuICogc2VwYXJhdGVkIGJ5IGEgY29sb24gYW5kIHdpbGRjYXJkcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGUobmFtZXNwYWNlcykge1xuICBleHBvcnRzLnNhdmUobmFtZXNwYWNlcyk7XG5cbiAgdmFyIHNwbGl0ID0gKG5hbWVzcGFjZXMgfHwgJycpLnNwbGl0KC9bXFxzLF0rLyk7XG4gIHZhciBsZW4gPSBzcGxpdC5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGlmICghc3BsaXRbaV0pIGNvbnRpbnVlOyAvLyBpZ25vcmUgZW1wdHkgc3RyaW5nc1xuICAgIG5hbWVzcGFjZXMgPSBzcGxpdFtpXS5yZXBsYWNlKC9bXFxcXF4kKz8uKCl8W1xcXXt9XS9nLCAnXFxcXCQmJykucmVwbGFjZSgvXFwqL2csICcuKj8nKTtcbiAgICBpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG4gICAgICBleHBvcnRzLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzLnN1YnN0cigxKSArICckJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzICsgJyQnKSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGlzYWJsZSBkZWJ1ZyBvdXRwdXQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkaXNhYmxlKCkge1xuICBleHBvcnRzLmVuYWJsZSgnJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RlIG5hbWUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGVkKG5hbWUpIHtcbiAgdmFyIGksIGxlbjtcbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLnNraXBzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5uYW1lcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLm5hbWVzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29lcmNlIGB2YWxgLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjb2VyY2UodmFsKSB7XG4gIGlmICh2YWwgaW5zdGFuY2VvZiBFcnJvcikgcmV0dXJuIHZhbC5zdGFjayB8fCB2YWwubWVzc2FnZTtcbiAgcmV0dXJuIHZhbDtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///23b1\n")},"2dce":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {\n/**\n * Module requirements.\n */\n\nvar Polling = __webpack_require__(/*! ./polling */ \"181d\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = JSONPPolling;\n\n/**\n * Cached regular expressions.\n */\n\nvar rNewline = /\\n/g;\nvar rEscapedNewline = /\\\\n/g;\n\n/**\n * Global JSONP callbacks.\n */\n\nvar callbacks;\n\n/**\n * Noop.\n */\n\nfunction empty () { }\n\n/**\n * JSONP Polling constructor.\n *\n * @param {Object} opts.\n * @api public\n */\n\nfunction JSONPPolling (opts) {\n  Polling.call(this, opts);\n\n  this.query = this.query || {};\n\n  // define global callbacks array if not present\n  // we do this here (lazily) to avoid unneeded global pollution\n  if (!callbacks) {\n    // we need to consider multiple engines in the same page\n    if (!global.___eio) global.___eio = [];\n    callbacks = global.___eio;\n  }\n\n  // callback identifier\n  this.index = callbacks.length;\n\n  // add callback to jsonp global\n  var self = this;\n  callbacks.push(function (msg) {\n    self.onData(msg);\n  });\n\n  // append to query string\n  this.query.j = this.index;\n\n  // prevent spurious errors from being emitted when the window is unloaded\n  if (global.document && global.addEventListener) {\n    global.addEventListener('beforeunload', function () {\n      if (self.script) self.script.onerror = empty;\n    }, false);\n  }\n}\n\n/**\n * Inherits from Polling.\n */\n\ninherit(JSONPPolling, Polling);\n\n/*\n * JSONP only supports binary as base64 encoded strings\n */\n\nJSONPPolling.prototype.supportsBinary = false;\n\n/**\n * Closes the socket.\n *\n * @api private\n */\n\nJSONPPolling.prototype.doClose = function () {\n  if (this.script) {\n    this.script.parentNode.removeChild(this.script);\n    this.script = null;\n  }\n\n  if (this.form) {\n    this.form.parentNode.removeChild(this.form);\n    this.form = null;\n    this.iframe = null;\n  }\n\n  Polling.prototype.doClose.call(this);\n};\n\n/**\n * Starts a poll cycle.\n *\n * @api private\n */\n\nJSONPPolling.prototype.doPoll = function () {\n  var self = this;\n  var script = document.createElement('script');\n\n  if (this.script) {\n    this.script.parentNode.removeChild(this.script);\n    this.script = null;\n  }\n\n  script.async = true;\n  script.src = this.uri();\n  script.onerror = function (e) {\n    self.onError('jsonp poll error', e);\n  };\n\n  var insertAt = document.getElementsByTagName('script')[0];\n  if (insertAt) {\n    insertAt.parentNode.insertBefore(script, insertAt);\n  } else {\n    (document.head || document.body).appendChild(script);\n  }\n  this.script = script;\n\n  var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent);\n\n  if (isUAgecko) {\n    setTimeout(function () {\n      var iframe = document.createElement('iframe');\n      document.body.appendChild(iframe);\n      document.body.removeChild(iframe);\n    }, 100);\n  }\n};\n\n/**\n * Writes with a hidden iframe.\n *\n * @param {String} data to send\n * @param {Function} called upon flush.\n * @api private\n */\n\nJSONPPolling.prototype.doWrite = function (data, fn) {\n  var self = this;\n\n  if (!this.form) {\n    var form = document.createElement('form');\n    var area = document.createElement('textarea');\n    var id = this.iframeId = 'eio_iframe_' + this.index;\n    var iframe;\n\n    form.className = 'socketio';\n    form.style.position = 'absolute';\n    form.style.top = '-1000px';\n    form.style.left = '-1000px';\n    form.target = id;\n    form.method = 'POST';\n    form.setAttribute('accept-charset', 'utf-8');\n    area.name = 'd';\n    form.appendChild(area);\n    document.body.appendChild(form);\n\n    this.form = form;\n    this.area = area;\n  }\n\n  this.form.action = this.uri();\n\n  function complete () {\n    initIframe();\n    fn();\n  }\n\n  function initIframe () {\n    if (self.iframe) {\n      try {\n        self.form.removeChild(self.iframe);\n      } catch (e) {\n        self.onError('jsonp polling iframe removal error', e);\n      }\n    }\n\n    try {\n      // ie6 dynamic iframes with target=\"\" support (thanks Chris Lambacher)\n      var html = '<iframe src=\"javascript:0\" name=\"' + self.iframeId + '\">';\n      iframe = document.createElement(html);\n    } catch (e) {\n      iframe = document.createElement('iframe');\n      iframe.name = self.iframeId;\n      iframe.src = 'javascript:0';\n    }\n\n    iframe.id = self.iframeId;\n\n    self.form.appendChild(iframe);\n    self.iframe = iframe;\n  }\n\n  initIframe();\n\n  // escape \\n to prevent it from being converted into \\r\\n by some UAs\n  // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side\n  data = data.replace(rEscapedNewline, '\\\\\\n');\n  this.area.value = data.replace(rNewline, '\\\\n');\n\n  try {\n    this.form.submit();\n  } catch (e) {}\n\n  if (this.iframe.attachEvent) {\n    this.iframe.onreadystatechange = function () {\n      if (self.iframe.readyState === 'complete') {\n        complete();\n      }\n    };\n  } else {\n    this.iframe.onload = complete;\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMmRjZS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLWpzb25wLmpzP2RmZDYiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSByZXF1aXJlbWVudHMuXG4gKi9cblxudmFyIFBvbGxpbmcgPSByZXF1aXJlKCcuL3BvbGxpbmcnKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEpTT05QUG9sbGluZztcblxuLyoqXG4gKiBDYWNoZWQgcmVndWxhciBleHByZXNzaW9ucy5cbiAqL1xuXG52YXIgck5ld2xpbmUgPSAvXFxuL2c7XG52YXIgckVzY2FwZWROZXdsaW5lID0gL1xcXFxuL2c7XG5cbi8qKlxuICogR2xvYmFsIEpTT05QIGNhbGxiYWNrcy5cbiAqL1xuXG52YXIgY2FsbGJhY2tzO1xuXG4vKipcbiAqIE5vb3AuXG4gKi9cblxuZnVuY3Rpb24gZW1wdHkgKCkgeyB9XG5cbi8qKlxuICogSlNPTlAgUG9sbGluZyBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cy5cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gSlNPTlBQb2xsaW5nIChvcHRzKSB7XG4gIFBvbGxpbmcuY2FsbCh0aGlzLCBvcHRzKTtcblxuICB0aGlzLnF1ZXJ5ID0gdGhpcy5xdWVyeSB8fCB7fTtcblxuICAvLyBkZWZpbmUgZ2xvYmFsIGNhbGxiYWNrcyBhcnJheSBpZiBub3QgcHJlc2VudFxuICAvLyB3ZSBkbyB0aGlzIGhlcmUgKGxhemlseSkgdG8gYXZvaWQgdW5uZWVkZWQgZ2xvYmFsIHBvbGx1dGlvblxuICBpZiAoIWNhbGxiYWNrcykge1xuICAgIC8vIHdlIG5lZWQgdG8gY29uc2lkZXIgbXVsdGlwbGUgZW5naW5lcyBpbiB0aGUgc2FtZSBwYWdlXG4gICAgaWYgKCFnbG9iYWwuX19fZWlvKSBnbG9iYWwuX19fZWlvID0gW107XG4gICAgY2FsbGJhY2tzID0gZ2xvYmFsLl9fX2VpbztcbiAgfVxuXG4gIC8vIGNhbGxiYWNrIGlkZW50aWZpZXJcbiAgdGhpcy5pbmRleCA9IGNhbGxiYWNrcy5sZW5ndGg7XG5cbiAgLy8gYWRkIGNhbGxiYWNrIHRvIGpzb25wIGdsb2JhbFxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGNhbGxiYWNrcy5wdXNoKGZ1bmN0aW9uIChtc2cpIHtcbiAgICBzZWxmLm9uRGF0YShtc2cpO1xuICB9KTtcblxuICAvLyBhcHBlbmQgdG8gcXVlcnkgc3RyaW5nXG4gIHRoaXMucXVlcnkuaiA9IHRoaXMuaW5kZXg7XG5cbiAgLy8gcHJldmVudCBzcHVyaW91cyBlcnJvcnMgZnJvbSBiZWluZyBlbWl0dGVkIHdoZW4gdGhlIHdpbmRvdyBpcyB1bmxvYWRlZFxuICBpZiAoZ2xvYmFsLmRvY3VtZW50ICYmIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2JlZm9yZXVubG9hZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLnNjcmlwdCkgc2VsZi5zY3JpcHQub25lcnJvciA9IGVtcHR5O1xuICAgIH0sIGZhbHNlKTtcbiAgfVxufVxuXG4vKipcbiAqIEluaGVyaXRzIGZyb20gUG9sbGluZy5cbiAqL1xuXG5pbmhlcml0KEpTT05QUG9sbGluZywgUG9sbGluZyk7XG5cbi8qXG4gKiBKU09OUCBvbmx5IHN1cHBvcnRzIGJpbmFyeSBhcyBiYXNlNjQgZW5jb2RlZCBzdHJpbmdzXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuXG4vKipcbiAqIENsb3NlcyB0aGUgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkpTT05QUG9sbGluZy5wcm90b3R5cGUuZG9DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuc2NyaXB0KSB7XG4gICAgdGhpcy5zY3JpcHQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnNjcmlwdCk7XG4gICAgdGhpcy5zY3JpcHQgPSBudWxsO1xuICB9XG5cbiAgaWYgKHRoaXMuZm9ybSkge1xuICAgIHRoaXMuZm9ybS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuZm9ybSk7XG4gICAgdGhpcy5mb3JtID0gbnVsbDtcbiAgICB0aGlzLmlmcmFtZSA9IG51bGw7XG4gIH1cblxuICBQb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlLmNhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5kb1BvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gIGlmICh0aGlzLnNjcmlwdCkge1xuICAgIHRoaXMuc2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5zY3JpcHQpO1xuICAgIHRoaXMuc2NyaXB0ID0gbnVsbDtcbiAgfVxuXG4gIHNjcmlwdC5hc3luYyA9IHRydWU7XG4gIHNjcmlwdC5zcmMgPSB0aGlzLnVyaSgpO1xuICBzY3JpcHQub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsIGVycm9yJywgZSk7XG4gIH07XG5cbiAgdmFyIGluc2VydEF0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NjcmlwdCcpWzBdO1xuICBpZiAoaW5zZXJ0QXQpIHtcbiAgICBpbnNlcnRBdC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHQsIGluc2VydEF0KTtcbiAgfSBlbHNlIHtcbiAgICAoZG9jdW1lbnQuaGVhZCB8fCBkb2N1bWVudC5ib2R5KS5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICB9XG4gIHRoaXMuc2NyaXB0ID0gc2NyaXB0O1xuXG4gIHZhciBpc1VBZ2Vja28gPSAndW5kZWZpbmVkJyAhPT0gdHlwZW9mIG5hdmlnYXRvciAmJiAvZ2Vja28vaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG4gIGlmIChpc1VBZ2Vja28pIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgICB9LCAxMDApO1xuICB9XG59O1xuXG4vKipcbiAqIFdyaXRlcyB3aXRoIGEgaGlkZGVuIGlmcmFtZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSB0byBzZW5kXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkpTT05QUG9sbGluZy5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uIChkYXRhLCBmbikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKCF0aGlzLmZvcm0pIHtcbiAgICB2YXIgZm9ybSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2Zvcm0nKTtcbiAgICB2YXIgYXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgdmFyIGlkID0gdGhpcy5pZnJhbWVJZCA9ICdlaW9faWZyYW1lXycgKyB0aGlzLmluZGV4O1xuICAgIHZhciBpZnJhbWU7XG5cbiAgICBmb3JtLmNsYXNzTmFtZSA9ICdzb2NrZXRpbyc7XG4gICAgZm9ybS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgZm9ybS5zdHlsZS50b3AgPSAnLTEwMDBweCc7XG4gICAgZm9ybS5zdHlsZS5sZWZ0ID0gJy0xMDAwcHgnO1xuICAgIGZvcm0udGFyZ2V0ID0gaWQ7XG4gICAgZm9ybS5tZXRob2QgPSAnUE9TVCc7XG4gICAgZm9ybS5zZXRBdHRyaWJ1dGUoJ2FjY2VwdC1jaGFyc2V0JywgJ3V0Zi04Jyk7XG4gICAgYXJlYS5uYW1lID0gJ2QnO1xuICAgIGZvcm0uYXBwZW5kQ2hpbGQoYXJlYSk7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmb3JtKTtcblxuICAgIHRoaXMuZm9ybSA9IGZvcm07XG4gICAgdGhpcy5hcmVhID0gYXJlYTtcbiAgfVxuXG4gIHRoaXMuZm9ybS5hY3Rpb24gPSB0aGlzLnVyaSgpO1xuXG4gIGZ1bmN0aW9uIGNvbXBsZXRlICgpIHtcbiAgICBpbml0SWZyYW1lKCk7XG4gICAgZm4oKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRJZnJhbWUgKCkge1xuICAgIGlmIChzZWxmLmlmcmFtZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2VsZi5mb3JtLnJlbW92ZUNoaWxkKHNlbGYuaWZyYW1lKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsaW5nIGlmcmFtZSByZW1vdmFsIGVycm9yJywgZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIGllNiBkeW5hbWljIGlmcmFtZXMgd2l0aCB0YXJnZXQ9XCJcIiBzdXBwb3J0ICh0aGFua3MgQ2hyaXMgTGFtYmFjaGVyKVxuICAgICAgdmFyIGh0bWwgPSAnPGlmcmFtZSBzcmM9XCJqYXZhc2NyaXB0OjBcIiBuYW1lPVwiJyArIHNlbGYuaWZyYW1lSWQgKyAnXCI+JztcbiAgICAgIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaHRtbCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgICBpZnJhbWUubmFtZSA9IHNlbGYuaWZyYW1lSWQ7XG4gICAgICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6MCc7XG4gICAgfVxuXG4gICAgaWZyYW1lLmlkID0gc2VsZi5pZnJhbWVJZDtcblxuICAgIHNlbGYuZm9ybS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICAgIHNlbGYuaWZyYW1lID0gaWZyYW1lO1xuICB9XG5cbiAgaW5pdElmcmFtZSgpO1xuXG4gIC8vIGVzY2FwZSBcXG4gdG8gcHJldmVudCBpdCBmcm9tIGJlaW5nIGNvbnZlcnRlZCBpbnRvIFxcclxcbiBieSBzb21lIFVBc1xuICAvLyBkb3VibGUgZXNjYXBpbmcgaXMgcmVxdWlyZWQgZm9yIGVzY2FwZWQgbmV3IGxpbmVzIGJlY2F1c2UgdW5lc2NhcGluZyBvZiBuZXcgbGluZXMgY2FuIGJlIGRvbmUgc2FmZWx5IG9uIHNlcnZlci1zaWRlXG4gIGRhdGEgPSBkYXRhLnJlcGxhY2UockVzY2FwZWROZXdsaW5lLCAnXFxcXFxcbicpO1xuICB0aGlzLmFyZWEudmFsdWUgPSBkYXRhLnJlcGxhY2Uock5ld2xpbmUsICdcXFxcbicpO1xuXG4gIHRyeSB7XG4gICAgdGhpcy5mb3JtLnN1Ym1pdCgpO1xuICB9IGNhdGNoIChlKSB7fVxuXG4gIGlmICh0aGlzLmlmcmFtZS5hdHRhY2hFdmVudCkge1xuICAgIHRoaXMuaWZyYW1lLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLmlmcmFtZS5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnKSB7XG4gICAgICAgIGNvbXBsZXRlKCk7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmlmcmFtZS5vbmxvYWQgPSBjb21wbGV0ZTtcbiAgfVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2dce\n")},3902:function(module,exports,__webpack_require__){eval("/**\n * Base class\n *\n * Implements unique ID per instance. It is set once, and can not be updated.\n * An ID is generated during initialization; however it is included in the (de-)serializing of the object.\n * @class Base\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\n// see discussion here: https://gist.github.com/gordonbrander/2230317\nfunction uniqueID () {\n  function chr4 () {\n    return Math.random().toString(16).slice(-4);\n  }\n  return chr4() + chr4() +\n    '-' + chr4() +\n    '-' + chr4() +\n    '-' + chr4() +\n    '-' + chr4() + chr4() + chr4();\n}\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Unique ID for this class\n     * @memberof! Base\n     * @readonly\n     * @type {ID}\n     */\n    id: {\n      type: 'string',\n      default: function () {\n        return uniqueID();\n      },\n      setonce: true\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkwMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9iYXNlLmpzP2NlYTgiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCYXNlIGNsYXNzXG4gKlxuICogSW1wbGVtZW50cyB1bmlxdWUgSUQgcGVyIGluc3RhbmNlLiBJdCBpcyBzZXQgb25jZSwgYW5kIGNhbiBub3QgYmUgdXBkYXRlZC5cbiAqIEFuIElEIGlzIGdlbmVyYXRlZCBkdXJpbmcgaW5pdGlhbGl6YXRpb247IGhvd2V2ZXIgaXQgaXMgaW5jbHVkZWQgaW4gdGhlIChkZS0pc2VyaWFsaXppbmcgb2YgdGhlIG9iamVjdC5cbiAqIEBjbGFzcyBCYXNlXG4gKi9cbnZhciBBbXBlcnNhbmRNb2RlbCA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1tb2RlbCcpO1xuXG4vLyBzZWUgZGlzY3Vzc2lvbiBoZXJlOiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9nb3Jkb25icmFuZGVyLzIyMzAzMTdcbmZ1bmN0aW9uIHVuaXF1ZUlEICgpIHtcbiAgZnVuY3Rpb24gY2hyNCAoKSB7XG4gICAgcmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMTYpLnNsaWNlKC00KTtcbiAgfVxuICByZXR1cm4gY2hyNCgpICsgY2hyNCgpICtcbiAgICAnLScgKyBjaHI0KCkgK1xuICAgICctJyArIGNocjQoKSArXG4gICAgJy0nICsgY2hyNCgpICtcbiAgICAnLScgKyBjaHI0KCkgKyBjaHI0KCkgKyBjaHI0KCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBVbmlxdWUgSUQgZm9yIHRoaXMgY2xhc3NcbiAgICAgKiBAbWVtYmVyb2YhIEJhc2VcbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKiBAdHlwZSB7SUR9XG4gICAgICovXG4gICAgaWQ6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdW5pcXVlSUQoKTtcbiAgICAgIH0sXG4gICAgICBzZXRvbmNlOiB0cnVlXG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3902\n")},"3b07":function(module,exports,__webpack_require__){eval("/**\n * Main spot object.\n *\n * @class Spot\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\nvar Datasets = __webpack_require__(/*! ./dataset/collection */ \"544d\");\nvar driverClient = __webpack_require__(/*! ./driver/client */ \"720c\");\nvar driverServer = __webpack_require__(/*! ./driver/server */ \"072d\");\nvar utildx = __webpack_require__(/*! ./util/crossfilter */ \"adfa\");\nvar timeUtil = __webpack_require__(/*! ./util/time */ \"d45b\");\nvar io = __webpack_require__(/*! socket.io-client */ \"b452\");\n\n/**\n * Connect to the spot-server using a websocket and setup callbacks\n *\n * @function\n * @param {address} Optional. IP address and port number to connect to. fi.  'http://localhost:3000'\n *\n * @memberof! Spot\n */\nfunction connectToServer (address) {\n  var me = this;\n  var socket;\n\n  if (address) {\n    // connect to specified address\n    // necessary for when window.location is not availble (node.js)\n    socket = io.connect(address);\n  } else {\n    // Use socket.io fallback to autodetect address\n    // ie. when a website wants to connect, use the window.location\n    socket = io.connect();\n  }\n\n  socket.on('connect', function () {\n    me.isConnected = true;\n    console.log('Connected to server');\n  });\n\n  socket.on('disconnect', function () {\n    me.isConnected = false;\n  });\n\n  socket.on('syncDatasets', function (req) {\n    // do an incremental update, as we typically start without datasets\n    me.datasets.add(req.data, { merge: true });\n  });\n\n  socket.on('syncDataview', function (req) {\n    me.dataview.reset(req.data);\n  });\n\n  socket.on('syncFacets', function (req) {\n    // do an incremental update, as we typically update only a few properties of a facet\n    // Also, a full reset will orphan the view.model objects in spot-app (ie. crashes)\n    var dataset = me.datasets.get(req.datasetId);\n    dataset.facets.add(req.data, { merge: true });\n\n    me.resetDataview(); // NOTE: the cached (serialized) datasets need to be updated, too\n\n    dataset.trigger('syncFacets');\n  });\n\n  socket.on('newData', function (req) {\n    var filter = me.dataview.filters.get(req.filterId);\n    if (req.data) {\n      filter.data = req.data;\n\n      // for text filters, rebuild partition and count\n      filter.partitions.forEach(function (partition, p) {\n        var columnToName = {1: 'a', 2: 'b', 3: 'c', 4: 'd'};\n\n        if (partition.isText) {\n          partition.groups.reset(null, {silent: true});\n          filter.data.forEach(function (d) {\n            var count = (parseFloat(d.aa) || parseInt(d.count)) || 0;\n\n            if (count) {\n              partition.groups.add({\n                min: 0,\n                max: 100,\n                count: count,\n                label: d[columnToName[(p + 1)]],\n                value: d[columnToName[(p + 1)]]\n              }, {silent: true});\n            }\n          });\n          partition.groups.sort();\n        }\n      });\n      filter.trigger('newData');\n    }\n  });\n\n  socket.on('newMetaData', function (req) {\n    me.dataview.dataTotal = parseInt(req.dataTotal);\n    me.dataview.dataSelected = parseInt(req.dataSelected);\n    console.timeEnd('Get data');\n    me.dataview.trigger('newMetaData');\n  });\n\n  socket.connect();\n  me.socket = socket;\n}\n\n/**\n * Disconnect from the spot-server\n *\n * @function\n * @memberof! Spot\n */\nfunction disconnectFromServer () {\n  this.socket.disconnect();\n}\n\n/**\n * Request a list of available datasets from the server\n *\n * Depending on the driver, this can be an asyncrhonous function.\n * It returns a Promise that resolves to the dataset collection\n *\n * @function\n * @returns {Promise}\n *\n * @memberof! Spot\n */\nfunction getDatasets () {\n  var me = this;\n\n  return new Promise(function (resolve, reject) {\n    me.socket.emit('getDatasets');\n\n    me.datasets.once('reset', function () {\n      resolve(me.datasets);\n    });\n  });\n}\n\n/**\n * Reset min, max, and categories for all facets in the dataview\n *\n * @param {Spot} me Main spot instance\n *\n * @memberof! Spot\n */\nfunction resetDataview () {\n  var toSerialize = [];\n\n  // Update list of active datasets, and serialize the datasets parts we need to send on getData requests\n  this.dataview.datasetIds = [];\n  this.datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      // BUGFIX: the list of datasetIds can get out of sync when using spot-server. Just recreate it always.\n      this.dataview.datasetIds.push(dataset.getId());\n      toSerialize.push(dataset.toJSON()); // TODO: only serialize used facets?\n    }\n  }, this);\n  this.cachedDatasets = JSON.stringify(toSerialize);\n\n  // rescan min/max values and categories for the newly added facets\n  this.dataview.facets.forEach(function (facet) {\n    var newFacet = this.dataview.facets.get(facet.name, 'name');\n\n    if (newFacet.isContinuous || newFacet.isDatetime || newFacet.isDuration) {\n      this.setFacetMinMax(facet);\n    } else if (newFacet.isCategorial) {\n      this.setFacetCategories(facet);\n    }\n  }, this);\n}\n\n/*\n * Add or remove facets from a dataset to the global (merged) dataset\n *\n * @memberof! Spot\n * @param {Spot} me Main spot instance\n * @param {Dataset} dataset Dataset set add or remove\n */\nfunction toggleDatasetFacets (me, dataset) {\n  if (dataset.isActive) {\n    // remove active facets in dataset from the global dataset...\n    dataset.facets.forEach(function (facet) {\n      if (!facet.isActive) {\n        return;\n      }\n\n      // ...but only when no other active dataset contains it\n      var facetIsUnique = true;\n      me.datasets.forEach(function (otherDataset) {\n        if (!otherDataset.isActive || otherDataset === dataset) {\n          return;\n        }\n        if (otherDataset.facets.get(facet.name, 'name')) {\n          facetIsUnique = false;\n        }\n      });\n      if (facetIsUnique) {\n        var toRemove = me.dataview.facets.get(facet.name, 'name');\n        me.dataview.facets.remove(toRemove);\n      }\n    });\n  } else if (!dataset.isActive) {\n    // copy facets\n    dataset.facets.forEach(function (facet) {\n      // do nothing if facet is not active\n      if (!facet.isActive) {\n        return;\n      }\n\n      // default options for all facet types\n      var options = {\n        name: facet.name,\n        accessor: facet.name,\n        description: facet.description,\n        type: facet.transform.transformedType,\n        units: facet.units, // TODO: transformed units?\n        isActive: true\n      };\n\n      // do not add if a similar facet already exists\n      if (!me.dataview.facets.get(facet.name, 'name')) {\n        me.dataview.facets.add(options);\n      }\n    });\n  }\n}\n\n/*\n * Add or remove data from a dataset to the global (merged) dataset\n *\n * @memberof! Spot\n * @param {Spot} me Main spot instance\n * @param {Dataset} dataset Dataset set add or remove\n */\nfunction toggleDatasetData (me, dataset) {\n  if (dataset.isActive) {\n    // if dataset is active, remove it:\n    // ...clear all crossfilter filters\n    me.dataview.filters.forEach(function (filter) {\n      // BUGFIX: when loading sessions, the dataset is not initialized properly\n      // so check for it to be sure\n      if (filter.dimension) {\n        filter.dimension.filterAll();\n      }\n    });\n\n    // ...filter all data, originating from the dataset from the dataset\n    var dimension = me.dataview.crossfilter.dimension(function (d) {\n      return d._OriginalDatasetId;\n    });\n    dimension.filter(dataset.getId());\n\n    // ...remove matching data\n    me.dataview.crossfilter.remove();\n\n    // ...restore original filters\n    dimension.filterAll();\n    dimension.dispose();\n    me.dataview.filters.forEach(function (filter) {\n      filter.updateDataFilter();\n    });\n  } else if (!dataset.isActive) {\n    // if dataset is not active, add it\n    // ...find facets to copy\n    var dataTransforms = [];\n    dataset.facets.forEach(function (facet) {\n      // do nothing if facet is not active\n      if (!facet.isActive) {\n        return;\n      }\n      dataTransforms.push({\n        key: facet.name,\n        fn: utildx.valueFn(facet)\n      });\n    });\n\n    // ...transform data\n    var data = dataset.data;\n    var transformedData = [];\n\n    data.forEach(function (datum) {\n      var transformedDatum = {};\n      dataTransforms.forEach(function (transform) {\n        transformedDatum[transform.key] = transform.fn(datum);\n      });\n      transformedDatum._OriginalDatasetId = dataset.getId();\n      transformedData.push(transformedDatum);\n    });\n\n    // ...add to merged dataset\n    me.dataview.crossfilter.add(transformedData);\n  }\n\n  // update counts\n  me.dataview.dataTotal = me.dataview.crossfilter.size();\n  me.dataview.dataSelected = me.dataview.countGroup.value();\n}\n\n/**\n * Add or remove a dataset from the dataview\n * @param {Dataset} dataset Dataset set add or remove\n *\n * @function\n * @memberof! Spot\n */\nfunction toggleDataset (dataset) {\n  if (this.sessionType === 'server') {\n    toggleDatasetFacets(this, dataset);\n  } else if (this.sessionType === 'client') {\n    // release all filters\n    this.dataview.filters.forEach(function (filter) {\n      filter.releaseDataFilter();\n    });\n\n    // manually merge the datasets\n    toggleDatasetFacets(this, dataset);\n    toggleDatasetData(this, dataset);\n  }\n\n  dataset.isActive = !dataset.isActive;\n\n  this.resetDataview();\n}\n\nfunction setFacetMinMax (facet) {\n  // This should work for all kinds of facets:\n  // numbers, durations, and datatimes all implement the relevant operations\n  var datasets = this.datasets;\n\n  var first = true;\n  datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      var subFacet = dataset.facets.get(facet.name, 'name');\n      if (first) {\n        facet.minvalAsText = subFacet.transform.transformedMinAsText;\n        facet.maxvalAsText = subFacet.transform.transformedMaxAsText;\n        first = false;\n      } else {\n        if (subFacet.minval < facet.minval) {\n          facet.minvalAsText = subFacet.transform.transformedMinAsText;\n        }\n        if (subFacet.maxval > facet.maxval) {\n          facet.maxvalAsText = subFacet.transform.transformedMaxAsText;\n        }\n      }\n    }\n  });\n}\n\nfunction setFacetCategories (facet) {\n  var datasets = this.datasets;\n\n  facet.categorialTransform.reset();\n\n  // get categories by combining the sets for the separate datasets\n  datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      var subFacet = dataset.facets.get(facet.name, 'name');\n\n      if (subFacet.isCategorial) {\n        // merge rules from subFacet into those of Facet\n        subFacet.categorialTransform.rules.forEach(function (rule) {\n          var newRule = facet.categorialTransform.rules.get(rule.expression, 'expression');\n          if (newRule) {\n            newRule.count += rule.count;\n          } else {\n            facet.categorialTransform.rules.add(rule.toJSON());\n          }\n        });\n      } else if (subFacet.isDatetime) {\n        var expressions = timeUtil.timeParts.get(subFacet.datetimeTransform.transformedFormat, 'description').groups;\n        expressions.forEach(function (expression) {\n          var newRule = facet.categorialTransform.rules.get(expression, 'expression');\n          if (newRule) {\n            // no-op: category exist and we don't have a proper count\n          } else {\n            facet.categorialTransform.rules.add({\n              expression: expression,\n              count: 0,\n              group: expression\n            });\n          }\n        });\n      }\n    }\n  });\n}\n\nmodule.exports = BaseModel.extend({\n  type: 'user',\n  props: {\n    /**\n     * Is there a connection with a spot sever?\n     * @memberof! Spot\n     * @type {boolean}\n     */\n    isConnected: ['boolean', true, false],\n    /**\n     * When the app in locked down, facets and datasets cannot be edited\n     * @memberof! Spot\n     * @type {boolean}\n     */\n    isLockedDown: ['boolean', true, false],\n    /**\n     * Type of spot session. Must be 'client' or 'server'\n     * @memberof! Spot\n     * @type {string}\n     */\n    sessionType: {\n      type: 'string',\n      required: true,\n      default: 'client',\n      values: ['client', 'server'],\n      setOnce: true\n    }\n  },\n  children: {\n    /**\n     * A union of all active datasets\n     * @memberof! Spot\n     * @type {Dataview}\n     */\n    dataview: Dataview\n  },\n  collections: {\n    /**\n     * Collection of all datasets\n     * @memberof! Spot\n     * @type {Dataset[]}\n     */\n    datasets: Datasets\n  },\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    // default to client side (crossfilter) sessions\n    this.driver = driverClient;\n\n    // assign backend driver\n    if (arguments && arguments[0] && arguments[0].sessionType) {\n      if (arguments[0].sessionType === 'client') {\n        this.driver = driverClient;\n      } else if (arguments[0].sessionType === 'server') {\n        this.driver = driverServer;\n      } else {\n        console.error('No driver for type', arguments[0].sessionType);\n      }\n    }\n  },\n  resetDataview: resetDataview,\n  connectToServer: connectToServer,\n  disconnectFromServer: disconnectFromServer,\n  getDatasets: getDatasets,\n  setFacetMinMax: setFacetMinMax,\n  setFacetCategories: setFacetCategories,\n  toggleDataset: toggleDataset\n});\n\nmodule.exports.util = {\n  dx: utildx,\n  misval: __webpack_require__(/*! ./util/misval */ \"bff6\"),\n  time: timeUtil\n};\n\nmodule.exports.transforms = {\n  categorial: __webpack_require__(/*! ./facet/categorial-transform */ \"9b75\"),\n  continuous: __webpack_require__(/*! ./facet/continuous-transform */ \"5a80\"),\n  datetime: __webpack_require__(/*! ./facet/datetime-transform */ \"a0ca\"),\n  duration: __webpack_require__(/*! ./facet/duration-transform */ \"b123\")\n};\n\nmodule.exports.constructors = {\n  Dataview: Dataview,\n  Dataset: __webpack_require__(/*! ./dataset */ \"545a\"),\n  Datasets: Datasets\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiM2IwNy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvbWUuanM/Y2NmYSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1haW4gc3BvdCBvYmplY3QuXG4gKlxuICogQGNsYXNzIFNwb3RcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG52YXIgRGF0YXZpZXcgPSByZXF1aXJlKCcuL2RhdGF2aWV3Jyk7XG52YXIgRGF0YXNldHMgPSByZXF1aXJlKCcuL2RhdGFzZXQvY29sbGVjdGlvbicpO1xudmFyIGRyaXZlckNsaWVudCA9IHJlcXVpcmUoJy4vZHJpdmVyL2NsaWVudCcpO1xudmFyIGRyaXZlclNlcnZlciA9IHJlcXVpcmUoJy4vZHJpdmVyL3NlcnZlcicpO1xudmFyIHV0aWxkeCA9IHJlcXVpcmUoJy4vdXRpbC9jcm9zc2ZpbHRlcicpO1xudmFyIHRpbWVVdGlsID0gcmVxdWlyZSgnLi91dGlsL3RpbWUnKTtcbnZhciBpbyA9IHJlcXVpcmUoJ3NvY2tldC5pby1jbGllbnQnKTtcblxuLyoqXG4gKiBDb25uZWN0IHRvIHRoZSBzcG90LXNlcnZlciB1c2luZyBhIHdlYnNvY2tldCBhbmQgc2V0dXAgY2FsbGJhY2tzXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge2FkZHJlc3N9IE9wdGlvbmFsLiBJUCBhZGRyZXNzIGFuZCBwb3J0IG51bWJlciB0byBjb25uZWN0IHRvLiBmaS4gICdodHRwOi8vbG9jYWxob3N0OjMwMDAnXG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIGNvbm5lY3RUb1NlcnZlciAoYWRkcmVzcykge1xuICB2YXIgbWUgPSB0aGlzO1xuICB2YXIgc29ja2V0O1xuXG4gIGlmIChhZGRyZXNzKSB7XG4gICAgLy8gY29ubmVjdCB0byBzcGVjaWZpZWQgYWRkcmVzc1xuICAgIC8vIG5lY2Vzc2FyeSBmb3Igd2hlbiB3aW5kb3cubG9jYXRpb24gaXMgbm90IGF2YWlsYmxlIChub2RlLmpzKVxuICAgIHNvY2tldCA9IGlvLmNvbm5lY3QoYWRkcmVzcyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gVXNlIHNvY2tldC5pbyBmYWxsYmFjayB0byBhdXRvZGV0ZWN0IGFkZHJlc3NcbiAgICAvLyBpZS4gd2hlbiBhIHdlYnNpdGUgd2FudHMgdG8gY29ubmVjdCwgdXNlIHRoZSB3aW5kb3cubG9jYXRpb25cbiAgICBzb2NrZXQgPSBpby5jb25uZWN0KCk7XG4gIH1cblxuICBzb2NrZXQub24oJ2Nvbm5lY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgbWUuaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgIGNvbnNvbGUubG9nKCdDb25uZWN0ZWQgdG8gc2VydmVyJyk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignZGlzY29ubmVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBtZS5pc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICB9KTtcblxuICBzb2NrZXQub24oJ3N5bmNEYXRhc2V0cycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAvLyBkbyBhbiBpbmNyZW1lbnRhbCB1cGRhdGUsIGFzIHdlIHR5cGljYWxseSBzdGFydCB3aXRob3V0IGRhdGFzZXRzXG4gICAgbWUuZGF0YXNldHMuYWRkKHJlcS5kYXRhLCB7IG1lcmdlOiB0cnVlIH0pO1xuICB9KTtcblxuICBzb2NrZXQub24oJ3N5bmNEYXRhdmlldycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICBtZS5kYXRhdmlldy5yZXNldChyZXEuZGF0YSk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignc3luY0ZhY2V0cycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAvLyBkbyBhbiBpbmNyZW1lbnRhbCB1cGRhdGUsIGFzIHdlIHR5cGljYWxseSB1cGRhdGUgb25seSBhIGZldyBwcm9wZXJ0aWVzIG9mIGEgZmFjZXRcbiAgICAvLyBBbHNvLCBhIGZ1bGwgcmVzZXQgd2lsbCBvcnBoYW4gdGhlIHZpZXcubW9kZWwgb2JqZWN0cyBpbiBzcG90LWFwcCAoaWUuIGNyYXNoZXMpXG4gICAgdmFyIGRhdGFzZXQgPSBtZS5kYXRhc2V0cy5nZXQocmVxLmRhdGFzZXRJZCk7XG4gICAgZGF0YXNldC5mYWNldHMuYWRkKHJlcS5kYXRhLCB7IG1lcmdlOiB0cnVlIH0pO1xuXG4gICAgbWUucmVzZXREYXRhdmlldygpOyAvLyBOT1RFOiB0aGUgY2FjaGVkIChzZXJpYWxpemVkKSBkYXRhc2V0cyBuZWVkIHRvIGJlIHVwZGF0ZWQsIHRvb1xuXG4gICAgZGF0YXNldC50cmlnZ2VyKCdzeW5jRmFjZXRzJyk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignbmV3RGF0YScsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICB2YXIgZmlsdGVyID0gbWUuZGF0YXZpZXcuZmlsdGVycy5nZXQocmVxLmZpbHRlcklkKTtcbiAgICBpZiAocmVxLmRhdGEpIHtcbiAgICAgIGZpbHRlci5kYXRhID0gcmVxLmRhdGE7XG5cbiAgICAgIC8vIGZvciB0ZXh0IGZpbHRlcnMsIHJlYnVpbGQgcGFydGl0aW9uIGFuZCBjb3VudFxuICAgICAgZmlsdGVyLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uLCBwKSB7XG4gICAgICAgIHZhciBjb2x1bW5Ub05hbWUgPSB7MTogJ2EnLCAyOiAnYicsIDM6ICdjJywgNDogJ2QnfTtcblxuICAgICAgICBpZiAocGFydGl0aW9uLmlzVGV4dCkge1xuICAgICAgICAgIHBhcnRpdGlvbi5ncm91cHMucmVzZXQobnVsbCwge3NpbGVudDogdHJ1ZX0pO1xuICAgICAgICAgIGZpbHRlci5kYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHZhciBjb3VudCA9IChwYXJzZUZsb2F0KGQuYWEpIHx8IHBhcnNlSW50KGQuY291bnQpKSB8fCAwO1xuXG4gICAgICAgICAgICBpZiAoY291bnQpIHtcbiAgICAgICAgICAgICAgcGFydGl0aW9uLmdyb3Vwcy5hZGQoe1xuICAgICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgICBtYXg6IDEwMCxcbiAgICAgICAgICAgICAgICBjb3VudDogY291bnQsXG4gICAgICAgICAgICAgICAgbGFiZWw6IGRbY29sdW1uVG9OYW1lWyhwICsgMSldXSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogZFtjb2x1bW5Ub05hbWVbKHAgKyAxKV1dXG4gICAgICAgICAgICAgIH0sIHtzaWxlbnQ6IHRydWV9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwYXJ0aXRpb24uZ3JvdXBzLnNvcnQoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBmaWx0ZXIudHJpZ2dlcignbmV3RGF0YScpO1xuICAgIH1cbiAgfSk7XG5cbiAgc29ja2V0Lm9uKCduZXdNZXRhRGF0YScsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICBtZS5kYXRhdmlldy5kYXRhVG90YWwgPSBwYXJzZUludChyZXEuZGF0YVRvdGFsKTtcbiAgICBtZS5kYXRhdmlldy5kYXRhU2VsZWN0ZWQgPSBwYXJzZUludChyZXEuZGF0YVNlbGVjdGVkKTtcbiAgICBjb25zb2xlLnRpbWVFbmQoJ0dldCBkYXRhJyk7XG4gICAgbWUuZGF0YXZpZXcudHJpZ2dlcignbmV3TWV0YURhdGEnKTtcbiAgfSk7XG5cbiAgc29ja2V0LmNvbm5lY3QoKTtcbiAgbWUuc29ja2V0ID0gc29ja2V0O1xufVxuXG4vKipcbiAqIERpc2Nvbm5lY3QgZnJvbSB0aGUgc3BvdC1zZXJ2ZXJcbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiEgU3BvdFxuICovXG5mdW5jdGlvbiBkaXNjb25uZWN0RnJvbVNlcnZlciAoKSB7XG4gIHRoaXMuc29ja2V0LmRpc2Nvbm5lY3QoKTtcbn1cblxuLyoqXG4gKiBSZXF1ZXN0IGEgbGlzdCBvZiBhdmFpbGFibGUgZGF0YXNldHMgZnJvbSB0aGUgc2VydmVyXG4gKlxuICogRGVwZW5kaW5nIG9uIHRoZSBkcml2ZXIsIHRoaXMgY2FuIGJlIGFuIGFzeW5jcmhvbm91cyBmdW5jdGlvbi5cbiAqIEl0IHJldHVybnMgYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGRhdGFzZXQgY29sbGVjdGlvblxuICpcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2V9XG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIGdldERhdGFzZXRzICgpIHtcbiAgdmFyIG1lID0gdGhpcztcblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIG1lLnNvY2tldC5lbWl0KCdnZXREYXRhc2V0cycpO1xuXG4gICAgbWUuZGF0YXNldHMub25jZSgncmVzZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXNvbHZlKG1lLmRhdGFzZXRzKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmVzZXQgbWluLCBtYXgsIGFuZCBjYXRlZ29yaWVzIGZvciBhbGwgZmFjZXRzIGluIHRoZSBkYXRhdmlld1xuICpcbiAqIEBwYXJhbSB7U3BvdH0gbWUgTWFpbiBzcG90IGluc3RhbmNlXG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIHJlc2V0RGF0YXZpZXcgKCkge1xuICB2YXIgdG9TZXJpYWxpemUgPSBbXTtcblxuICAvLyBVcGRhdGUgbGlzdCBvZiBhY3RpdmUgZGF0YXNldHMsIGFuZCBzZXJpYWxpemUgdGhlIGRhdGFzZXRzIHBhcnRzIHdlIG5lZWQgdG8gc2VuZCBvbiBnZXREYXRhIHJlcXVlc3RzXG4gIHRoaXMuZGF0YXZpZXcuZGF0YXNldElkcyA9IFtdO1xuICB0aGlzLmRhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24gKGRhdGFzZXQpIHtcbiAgICBpZiAoZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgICAgLy8gQlVHRklYOiB0aGUgbGlzdCBvZiBkYXRhc2V0SWRzIGNhbiBnZXQgb3V0IG9mIHN5bmMgd2hlbiB1c2luZyBzcG90LXNlcnZlci4gSnVzdCByZWNyZWF0ZSBpdCBhbHdheXMuXG4gICAgICB0aGlzLmRhdGF2aWV3LmRhdGFzZXRJZHMucHVzaChkYXRhc2V0LmdldElkKCkpO1xuICAgICAgdG9TZXJpYWxpemUucHVzaChkYXRhc2V0LnRvSlNPTigpKTsgLy8gVE9ETzogb25seSBzZXJpYWxpemUgdXNlZCBmYWNldHM/XG4gICAgfVxuICB9LCB0aGlzKTtcbiAgdGhpcy5jYWNoZWREYXRhc2V0cyA9IEpTT04uc3RyaW5naWZ5KHRvU2VyaWFsaXplKTtcblxuICAvLyByZXNjYW4gbWluL21heCB2YWx1ZXMgYW5kIGNhdGVnb3JpZXMgZm9yIHRoZSBuZXdseSBhZGRlZCBmYWNldHNcbiAgdGhpcy5kYXRhdmlldy5mYWNldHMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICB2YXIgbmV3RmFjZXQgPSB0aGlzLmRhdGF2aWV3LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcblxuICAgIGlmIChuZXdGYWNldC5pc0NvbnRpbnVvdXMgfHwgbmV3RmFjZXQuaXNEYXRldGltZSB8fCBuZXdGYWNldC5pc0R1cmF0aW9uKSB7XG4gICAgICB0aGlzLnNldEZhY2V0TWluTWF4KGZhY2V0KTtcbiAgICB9IGVsc2UgaWYgKG5ld0ZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgdGhpcy5zZXRGYWNldENhdGVnb3JpZXMoZmFjZXQpO1xuICAgIH1cbiAgfSwgdGhpcyk7XG59XG5cbi8qXG4gKiBBZGQgb3IgcmVtb3ZlIGZhY2V0cyBmcm9tIGEgZGF0YXNldCB0byB0aGUgZ2xvYmFsIChtZXJnZWQpIGRhdGFzZXRcbiAqXG4gKiBAbWVtYmVyb2YhIFNwb3RcbiAqIEBwYXJhbSB7U3BvdH0gbWUgTWFpbiBzcG90IGluc3RhbmNlXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXQgRGF0YXNldCBzZXQgYWRkIG9yIHJlbW92ZVxuICovXG5mdW5jdGlvbiB0b2dnbGVEYXRhc2V0RmFjZXRzIChtZSwgZGF0YXNldCkge1xuICBpZiAoZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIHJlbW92ZSBhY3RpdmUgZmFjZXRzIGluIGRhdGFzZXQgZnJvbSB0aGUgZ2xvYmFsIGRhdGFzZXQuLi5cbiAgICBkYXRhc2V0LmZhY2V0cy5mb3JFYWNoKGZ1bmN0aW9uIChmYWNldCkge1xuICAgICAgaWYgKCFmYWNldC5pc0FjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIC4uLmJ1dCBvbmx5IHdoZW4gbm8gb3RoZXIgYWN0aXZlIGRhdGFzZXQgY29udGFpbnMgaXRcbiAgICAgIHZhciBmYWNldElzVW5pcXVlID0gdHJ1ZTtcbiAgICAgIG1lLmRhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24gKG90aGVyRGF0YXNldCkge1xuICAgICAgICBpZiAoIW90aGVyRGF0YXNldC5pc0FjdGl2ZSB8fCBvdGhlckRhdGFzZXQgPT09IGRhdGFzZXQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG90aGVyRGF0YXNldC5mYWNldHMuZ2V0KGZhY2V0Lm5hbWUsICduYW1lJykpIHtcbiAgICAgICAgICBmYWNldElzVW5pcXVlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKGZhY2V0SXNVbmlxdWUpIHtcbiAgICAgICAgdmFyIHRvUmVtb3ZlID0gbWUuZGF0YXZpZXcuZmFjZXRzLmdldChmYWNldC5uYW1lLCAnbmFtZScpO1xuICAgICAgICBtZS5kYXRhdmlldy5mYWNldHMucmVtb3ZlKHRvUmVtb3ZlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIGlmICghZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIGNvcHkgZmFjZXRzXG4gICAgZGF0YXNldC5mYWNldHMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICAgIC8vIGRvIG5vdGhpbmcgaWYgZmFjZXQgaXMgbm90IGFjdGl2ZVxuICAgICAgaWYgKCFmYWNldC5pc0FjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGRlZmF1bHQgb3B0aW9ucyBmb3IgYWxsIGZhY2V0IHR5cGVzXG4gICAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgbmFtZTogZmFjZXQubmFtZSxcbiAgICAgICAgYWNjZXNzb3I6IGZhY2V0Lm5hbWUsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBmYWNldC5kZXNjcmlwdGlvbixcbiAgICAgICAgdHlwZTogZmFjZXQudHJhbnNmb3JtLnRyYW5zZm9ybWVkVHlwZSxcbiAgICAgICAgdW5pdHM6IGZhY2V0LnVuaXRzLCAvLyBUT0RPOiB0cmFuc2Zvcm1lZCB1bml0cz9cbiAgICAgICAgaXNBY3RpdmU6IHRydWVcbiAgICAgIH07XG5cbiAgICAgIC8vIGRvIG5vdCBhZGQgaWYgYSBzaW1pbGFyIGZhY2V0IGFscmVhZHkgZXhpc3RzXG4gICAgICBpZiAoIW1lLmRhdGF2aWV3LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKSkge1xuICAgICAgICBtZS5kYXRhdmlldy5mYWNldHMuYWRkKG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbi8qXG4gKiBBZGQgb3IgcmVtb3ZlIGRhdGEgZnJvbSBhIGRhdGFzZXQgdG8gdGhlIGdsb2JhbCAobWVyZ2VkKSBkYXRhc2V0XG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKiBAcGFyYW0ge1Nwb3R9IG1lIE1haW4gc3BvdCBpbnN0YW5jZVxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0IERhdGFzZXQgc2V0IGFkZCBvciByZW1vdmVcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlRGF0YXNldERhdGEgKG1lLCBkYXRhc2V0KSB7XG4gIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgLy8gaWYgZGF0YXNldCBpcyBhY3RpdmUsIHJlbW92ZSBpdDpcbiAgICAvLyAuLi5jbGVhciBhbGwgY3Jvc3NmaWx0ZXIgZmlsdGVyc1xuICAgIG1lLmRhdGF2aWV3LmZpbHRlcnMuZm9yRWFjaChmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgICAvLyBCVUdGSVg6IHdoZW4gbG9hZGluZyBzZXNzaW9ucywgdGhlIGRhdGFzZXQgaXMgbm90IGluaXRpYWxpemVkIHByb3Blcmx5XG4gICAgICAvLyBzbyBjaGVjayBmb3IgaXQgdG8gYmUgc3VyZVxuICAgICAgaWYgKGZpbHRlci5kaW1lbnNpb24pIHtcbiAgICAgICAgZmlsdGVyLmRpbWVuc2lvbi5maWx0ZXJBbGwoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIC4uLmZpbHRlciBhbGwgZGF0YSwgb3JpZ2luYXRpbmcgZnJvbSB0aGUgZGF0YXNldCBmcm9tIHRoZSBkYXRhc2V0XG4gICAgdmFyIGRpbWVuc2lvbiA9IG1lLmRhdGF2aWV3LmNyb3NzZmlsdGVyLmRpbWVuc2lvbihmdW5jdGlvbiAoZCkge1xuICAgICAgcmV0dXJuIGQuX09yaWdpbmFsRGF0YXNldElkO1xuICAgIH0pO1xuICAgIGRpbWVuc2lvbi5maWx0ZXIoZGF0YXNldC5nZXRJZCgpKTtcblxuICAgIC8vIC4uLnJlbW92ZSBtYXRjaGluZyBkYXRhXG4gICAgbWUuZGF0YXZpZXcuY3Jvc3NmaWx0ZXIucmVtb3ZlKCk7XG5cbiAgICAvLyAuLi5yZXN0b3JlIG9yaWdpbmFsIGZpbHRlcnNcbiAgICBkaW1lbnNpb24uZmlsdGVyQWxsKCk7XG4gICAgZGltZW5zaW9uLmRpc3Bvc2UoKTtcbiAgICBtZS5kYXRhdmlldy5maWx0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpbHRlcikge1xuICAgICAgZmlsdGVyLnVwZGF0ZURhdGFGaWx0ZXIoKTtcbiAgICB9KTtcbiAgfSBlbHNlIGlmICghZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIGlmIGRhdGFzZXQgaXMgbm90IGFjdGl2ZSwgYWRkIGl0XG4gICAgLy8gLi4uZmluZCBmYWNldHMgdG8gY29weVxuICAgIHZhciBkYXRhVHJhbnNmb3JtcyA9IFtdO1xuICAgIGRhdGFzZXQuZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgICAvLyBkbyBub3RoaW5nIGlmIGZhY2V0IGlzIG5vdCBhY3RpdmVcbiAgICAgIGlmICghZmFjZXQuaXNBY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZGF0YVRyYW5zZm9ybXMucHVzaCh7XG4gICAgICAgIGtleTogZmFjZXQubmFtZSxcbiAgICAgICAgZm46IHV0aWxkeC52YWx1ZUZuKGZhY2V0KVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyAuLi50cmFuc2Zvcm0gZGF0YVxuICAgIHZhciBkYXRhID0gZGF0YXNldC5kYXRhO1xuICAgIHZhciB0cmFuc2Zvcm1lZERhdGEgPSBbXTtcblxuICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZGF0dW0pIHtcbiAgICAgIHZhciB0cmFuc2Zvcm1lZERhdHVtID0ge307XG4gICAgICBkYXRhVHJhbnNmb3Jtcy5mb3JFYWNoKGZ1bmN0aW9uICh0cmFuc2Zvcm0pIHtcbiAgICAgICAgdHJhbnNmb3JtZWREYXR1bVt0cmFuc2Zvcm0ua2V5XSA9IHRyYW5zZm9ybS5mbihkYXR1bSk7XG4gICAgICB9KTtcbiAgICAgIHRyYW5zZm9ybWVkRGF0dW0uX09yaWdpbmFsRGF0YXNldElkID0gZGF0YXNldC5nZXRJZCgpO1xuICAgICAgdHJhbnNmb3JtZWREYXRhLnB1c2godHJhbnNmb3JtZWREYXR1bSk7XG4gICAgfSk7XG5cbiAgICAvLyAuLi5hZGQgdG8gbWVyZ2VkIGRhdGFzZXRcbiAgICBtZS5kYXRhdmlldy5jcm9zc2ZpbHRlci5hZGQodHJhbnNmb3JtZWREYXRhKTtcbiAgfVxuXG4gIC8vIHVwZGF0ZSBjb3VudHNcbiAgbWUuZGF0YXZpZXcuZGF0YVRvdGFsID0gbWUuZGF0YXZpZXcuY3Jvc3NmaWx0ZXIuc2l6ZSgpO1xuICBtZS5kYXRhdmlldy5kYXRhU2VsZWN0ZWQgPSBtZS5kYXRhdmlldy5jb3VudEdyb3VwLnZhbHVlKCk7XG59XG5cbi8qKlxuICogQWRkIG9yIHJlbW92ZSBhIGRhdGFzZXQgZnJvbSB0aGUgZGF0YXZpZXdcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldCBEYXRhc2V0IHNldCBhZGQgb3IgcmVtb3ZlXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2YhIFNwb3RcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlRGF0YXNldCAoZGF0YXNldCkge1xuICBpZiAodGhpcy5zZXNzaW9uVHlwZSA9PT0gJ3NlcnZlcicpIHtcbiAgICB0b2dnbGVEYXRhc2V0RmFjZXRzKHRoaXMsIGRhdGFzZXQpO1xuICB9IGVsc2UgaWYgKHRoaXMuc2Vzc2lvblR5cGUgPT09ICdjbGllbnQnKSB7XG4gICAgLy8gcmVsZWFzZSBhbGwgZmlsdGVyc1xuICAgIHRoaXMuZGF0YXZpZXcuZmlsdGVycy5mb3JFYWNoKGZ1bmN0aW9uIChmaWx0ZXIpIHtcbiAgICAgIGZpbHRlci5yZWxlYXNlRGF0YUZpbHRlcigpO1xuICAgIH0pO1xuXG4gICAgLy8gbWFudWFsbHkgbWVyZ2UgdGhlIGRhdGFzZXRzXG4gICAgdG9nZ2xlRGF0YXNldEZhY2V0cyh0aGlzLCBkYXRhc2V0KTtcbiAgICB0b2dnbGVEYXRhc2V0RGF0YSh0aGlzLCBkYXRhc2V0KTtcbiAgfVxuXG4gIGRhdGFzZXQuaXNBY3RpdmUgPSAhZGF0YXNldC5pc0FjdGl2ZTtcblxuICB0aGlzLnJlc2V0RGF0YXZpZXcoKTtcbn1cblxuZnVuY3Rpb24gc2V0RmFjZXRNaW5NYXggKGZhY2V0KSB7XG4gIC8vIFRoaXMgc2hvdWxkIHdvcmsgZm9yIGFsbCBraW5kcyBvZiBmYWNldHM6XG4gIC8vIG51bWJlcnMsIGR1cmF0aW9ucywgYW5kIGRhdGF0aW1lcyBhbGwgaW1wbGVtZW50IHRoZSByZWxldmFudCBvcGVyYXRpb25zXG4gIHZhciBkYXRhc2V0cyA9IHRoaXMuZGF0YXNldHM7XG5cbiAgdmFyIGZpcnN0ID0gdHJ1ZTtcbiAgZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZGF0YXNldCkge1xuICAgIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgICB2YXIgc3ViRmFjZXQgPSBkYXRhc2V0LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcbiAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICBmYWNldC5taW52YWxBc1RleHQgPSBzdWJGYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW5Bc1RleHQ7XG4gICAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IHN1YkZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZE1heEFzVGV4dDtcbiAgICAgICAgZmlyc3QgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChzdWJGYWNldC5taW52YWwgPCBmYWNldC5taW52YWwpIHtcbiAgICAgICAgICBmYWNldC5taW52YWxBc1RleHQgPSBzdWJGYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW5Bc1RleHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN1YkZhY2V0Lm1heHZhbCA+IGZhY2V0Lm1heHZhbCkge1xuICAgICAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IHN1YkZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZE1heEFzVGV4dDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHNldEZhY2V0Q2F0ZWdvcmllcyAoZmFjZXQpIHtcbiAgdmFyIGRhdGFzZXRzID0gdGhpcy5kYXRhc2V0cztcblxuICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJlc2V0KCk7XG5cbiAgLy8gZ2V0IGNhdGVnb3JpZXMgYnkgY29tYmluaW5nIHRoZSBzZXRzIGZvciB0aGUgc2VwYXJhdGUgZGF0YXNldHNcbiAgZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZGF0YXNldCkge1xuICAgIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgICB2YXIgc3ViRmFjZXQgPSBkYXRhc2V0LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcblxuICAgICAgaWYgKHN1YkZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgICAvLyBtZXJnZSBydWxlcyBmcm9tIHN1YkZhY2V0IGludG8gdGhvc2Ugb2YgRmFjZXRcbiAgICAgICAgc3ViRmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChydWxlKSB7XG4gICAgICAgICAgdmFyIG5ld1J1bGUgPSBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLmdldChydWxlLmV4cHJlc3Npb24sICdleHByZXNzaW9uJyk7XG4gICAgICAgICAgaWYgKG5ld1J1bGUpIHtcbiAgICAgICAgICAgIG5ld1J1bGUuY291bnQgKz0gcnVsZS5jb3VudDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5hZGQocnVsZS50b0pTT04oKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoc3ViRmFjZXQuaXNEYXRldGltZSkge1xuICAgICAgICB2YXIgZXhwcmVzc2lvbnMgPSB0aW1lVXRpbC50aW1lUGFydHMuZ2V0KHN1YkZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKS5ncm91cHM7XG4gICAgICAgIGV4cHJlc3Npb25zLmZvckVhY2goZnVuY3Rpb24gKGV4cHJlc3Npb24pIHtcbiAgICAgICAgICB2YXIgbmV3UnVsZSA9IGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuZ2V0KGV4cHJlc3Npb24sICdleHByZXNzaW9uJyk7XG4gICAgICAgICAgaWYgKG5ld1J1bGUpIHtcbiAgICAgICAgICAgIC8vIG5vLW9wOiBjYXRlZ29yeSBleGlzdCBhbmQgd2UgZG9uJ3QgaGF2ZSBhIHByb3BlciBjb3VudFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLmFkZCh7XG4gICAgICAgICAgICAgIGV4cHJlc3Npb246IGV4cHJlc3Npb24sXG4gICAgICAgICAgICAgIGNvdW50OiAwLFxuICAgICAgICAgICAgICBncm91cDogZXhwcmVzc2lvblxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VNb2RlbC5leHRlbmQoe1xuICB0eXBlOiAndXNlcicsXG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogSXMgdGhlcmUgYSBjb25uZWN0aW9uIHdpdGggYSBzcG90IHNldmVyP1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIGlzQ29ubmVjdGVkOiBbJ2Jvb2xlYW4nLCB0cnVlLCBmYWxzZV0sXG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgYXBwIGluIGxvY2tlZCBkb3duLCBmYWNldHMgYW5kIGRhdGFzZXRzIGNhbm5vdCBiZSBlZGl0ZWRcbiAgICAgKiBAbWVtYmVyb2YhIFNwb3RcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0xvY2tlZERvd246IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXSxcbiAgICAvKipcbiAgICAgKiBUeXBlIG9mIHNwb3Qgc2Vzc2lvbi4gTXVzdCBiZSAnY2xpZW50JyBvciAnc2VydmVyJ1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgc2Vzc2lvblR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnY2xpZW50JyxcbiAgICAgIHZhbHVlczogWydjbGllbnQnLCAnc2VydmVyJ10sXG4gICAgICBzZXRPbmNlOiB0cnVlXG4gICAgfVxuICB9LFxuICBjaGlsZHJlbjoge1xuICAgIC8qKlxuICAgICAqIEEgdW5pb24gb2YgYWxsIGFjdGl2ZSBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtEYXRhdmlld31cbiAgICAgKi9cbiAgICBkYXRhdmlldzogRGF0YXZpZXdcbiAgfSxcbiAgY29sbGVjdGlvbnM6IHtcbiAgICAvKipcbiAgICAgKiBDb2xsZWN0aW9uIG9mIGFsbCBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtEYXRhc2V0W119XG4gICAgICovXG4gICAgZGF0YXNldHM6IERhdGFzZXRzXG4gIH0sXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBmaXJzdCBkbyBwYXJlbnQgY2xhc3MgaW5pdGlhbGl6YXRpb25cbiAgICBCYXNlTW9kZWwucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIC8vIGRlZmF1bHQgdG8gY2xpZW50IHNpZGUgKGNyb3NzZmlsdGVyKSBzZXNzaW9uc1xuICAgIHRoaXMuZHJpdmVyID0gZHJpdmVyQ2xpZW50O1xuXG4gICAgLy8gYXNzaWduIGJhY2tlbmQgZHJpdmVyXG4gICAgaWYgKGFyZ3VtZW50cyAmJiBhcmd1bWVudHNbMF0gJiYgYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlKSB7XG4gICAgICBpZiAoYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlID09PSAnY2xpZW50Jykge1xuICAgICAgICB0aGlzLmRyaXZlciA9IGRyaXZlckNsaWVudDtcbiAgICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlID09PSAnc2VydmVyJykge1xuICAgICAgICB0aGlzLmRyaXZlciA9IGRyaXZlclNlcnZlcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ05vIGRyaXZlciBmb3IgdHlwZScsIGFyZ3VtZW50c1swXS5zZXNzaW9uVHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICByZXNldERhdGF2aWV3OiByZXNldERhdGF2aWV3LFxuICBjb25uZWN0VG9TZXJ2ZXI6IGNvbm5lY3RUb1NlcnZlcixcbiAgZGlzY29ubmVjdEZyb21TZXJ2ZXI6IGRpc2Nvbm5lY3RGcm9tU2VydmVyLFxuICBnZXREYXRhc2V0czogZ2V0RGF0YXNldHMsXG4gIHNldEZhY2V0TWluTWF4OiBzZXRGYWNldE1pbk1heCxcbiAgc2V0RmFjZXRDYXRlZ29yaWVzOiBzZXRGYWNldENhdGVnb3JpZXMsXG4gIHRvZ2dsZURhdGFzZXQ6IHRvZ2dsZURhdGFzZXRcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cy51dGlsID0ge1xuICBkeDogdXRpbGR4LFxuICBtaXN2YWw6IHJlcXVpcmUoJy4vdXRpbC9taXN2YWwnKSxcbiAgdGltZTogdGltZVV0aWxcbn07XG5cbm1vZHVsZS5leHBvcnRzLnRyYW5zZm9ybXMgPSB7XG4gIGNhdGVnb3JpYWw6IHJlcXVpcmUoJy4vZmFjZXQvY2F0ZWdvcmlhbC10cmFuc2Zvcm0nKSxcbiAgY29udGludW91czogcmVxdWlyZSgnLi9mYWNldC9jb250aW51b3VzLXRyYW5zZm9ybScpLFxuICBkYXRldGltZTogcmVxdWlyZSgnLi9mYWNldC9kYXRldGltZS10cmFuc2Zvcm0nKSxcbiAgZHVyYXRpb246IHJlcXVpcmUoJy4vZmFjZXQvZHVyYXRpb24tdHJhbnNmb3JtJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNvbnN0cnVjdG9ycyA9IHtcbiAgRGF0YXZpZXc6IERhdGF2aWV3LFxuICBEYXRhc2V0OiByZXF1aXJlKCcuL2RhdGFzZXQnKSxcbiAgRGF0YXNldHM6IERhdGFzZXRzXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3b07\n")},"419b":function(module,exports,__webpack_require__){eval('/* WEBPACK VAR INJECTION */(function(global) {\nmodule.exports = isBuf;\n\n/**\n * Returns true if obj is a buffer or an arraybuffer.\n *\n * @api private\n */\n\nfunction isBuf(obj) {\n  return (global.Buffer && global.Buffer.isBuffer(obj)) ||\n         (global.ArrayBuffer && obj instanceof ArrayBuffer);\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ "698d")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE5Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9pcy1idWZmZXIuanM/MGJlNiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbm1vZHVsZS5leHBvcnRzID0gaXNCdWY7XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIG9iaiBpcyBhIGJ1ZmZlciBvciBhbiBhcnJheWJ1ZmZlci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0J1ZihvYmopIHtcbiAgcmV0dXJuIChnbG9iYWwuQnVmZmVyICYmIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIob2JqKSkgfHxcbiAgICAgICAgIChnbG9iYWwuQXJyYXlCdWZmZXIgJiYgb2JqIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpO1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///419b\n')},"433b":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(process) {\n/**\n * This is the web browser implementation of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = __webpack_require__(/*! ./debug */ \"23b1\");\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = 'undefined' != typeof chrome\n               && 'undefined' != typeof chrome.storage\n                  ? chrome.storage.local\n                  : localstorage();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n  'lightseagreen',\n  'forestgreen',\n  'goldenrod',\n  'dodgerblue',\n  'darkorchid',\n  'crimson'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\nfunction useColors() {\n  // is webkit? http://stackoverflow.com/a/16459606/376773\n  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n  return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) ||\n    // is firebug? http://stackoverflow.com/a/398120/376773\n    (window.console && (console.firebug || (console.exception && console.table))) ||\n    // is firefox >= v31?\n    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n    (navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31);\n}\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nexports.formatters.j = function(v) {\n  try {\n    return JSON.stringify(v);\n  } catch (err) {\n    return '[UnexpectedJSONParseError]: ' + err.message;\n  }\n};\n\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs() {\n  var args = arguments;\n  var useColors = this.useColors;\n\n  args[0] = (useColors ? '%c' : '')\n    + this.namespace\n    + (useColors ? ' %c' : ' ')\n    + args[0]\n    + (useColors ? '%c ' : ' ')\n    + '+' + exports.humanize(this.diff);\n\n  if (!useColors) return args;\n\n  var c = 'color: ' + this.color;\n  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));\n\n  // the final \"%c\" is somewhat tricky, because there could be other\n  // arguments passed either before or after the %c, so we need to\n  // figure out the correct index to insert the CSS into\n  var index = 0;\n  var lastC = 0;\n  args[0].replace(/%[a-z%]/g, function(match) {\n    if ('%%' === match) return;\n    index++;\n    if ('%c' === match) {\n      // we only are interested in the *last* %c\n      // (the user may have provided their own)\n      lastC = index;\n    }\n  });\n\n  args.splice(lastC, 0, c);\n  return args;\n}\n\n/**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\nfunction log() {\n  // this hackery is required for IE8/9, where\n  // the `console.log` function doesn't have 'apply'\n  return 'object' === typeof console\n    && console.log\n    && Function.prototype.apply.call(console.log, console, arguments);\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\nfunction save(namespaces) {\n  try {\n    if (null == namespaces) {\n      exports.storage.removeItem('debug');\n    } else {\n      exports.storage.debug = namespaces;\n    }\n  } catch(e) {}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n  var r;\n  try {\n    return exports.storage.debug;\n  } catch(e) {}\n\n  // If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n  if (typeof process !== 'undefined' && 'env' in process) {\n    return process.env.DEBUG;\n  }\n}\n\n/**\n * Enable namespaces listed in `localStorage.debug` initially.\n */\n\nexports.enable(load());\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage(){\n  try {\n    return window.localStorage;\n  } catch (e) {}\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../process/browser.js */ \"26d5\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMzYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZGVidWcvYnJvd3Nlci5qcz82NDdhIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSB3ZWIgYnJvd3NlciBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gKlxuICogRXhwb3NlIGBkZWJ1ZygpYCBhcyB0aGUgbW9kdWxlLlxuICovXG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZGVidWcnKTtcbmV4cG9ydHMubG9nID0gbG9nO1xuZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbmV4cG9ydHMuc2F2ZSA9IHNhdmU7XG5leHBvcnRzLmxvYWQgPSBsb2FkO1xuZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG5leHBvcnRzLnN0b3JhZ2UgPSAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lXG4gICAgICAgICAgICAgICAmJiAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lLnN0b3JhZ2VcbiAgICAgICAgICAgICAgICAgID8gY2hyb21lLnN0b3JhZ2UubG9jYWxcbiAgICAgICAgICAgICAgICAgIDogbG9jYWxzdG9yYWdlKCk7XG5cbi8qKlxuICogQ29sb3JzLlxuICovXG5cbmV4cG9ydHMuY29sb3JzID0gW1xuICAnbGlnaHRzZWFncmVlbicsXG4gICdmb3Jlc3RncmVlbicsXG4gICdnb2xkZW5yb2QnLFxuICAnZG9kZ2VyYmx1ZScsXG4gICdkYXJrb3JjaGlkJyxcbiAgJ2NyaW1zb24nXG5dO1xuXG4vKipcbiAqIEN1cnJlbnRseSBvbmx5IFdlYktpdC1iYXNlZCBXZWIgSW5zcGVjdG9ycywgRmlyZWZveCA+PSB2MzEsXG4gKiBhbmQgdGhlIEZpcmVidWcgZXh0ZW5zaW9uIChhbnkgRmlyZWZveCB2ZXJzaW9uKSBhcmUga25vd25cbiAqIHRvIHN1cHBvcnQgXCIlY1wiIENTUyBjdXN0b21pemF0aW9ucy5cbiAqXG4gKiBUT0RPOiBhZGQgYSBgbG9jYWxTdG9yYWdlYCB2YXJpYWJsZSB0byBleHBsaWNpdGx5IGVuYWJsZS9kaXNhYmxlIGNvbG9yc1xuICovXG5cbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcbiAgLy8gaXMgd2Via2l0PyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNjQ1OTYwNi8zNzY3NzNcbiAgLy8gZG9jdW1lbnQgaXMgdW5kZWZpbmVkIGluIHJlYWN0LW5hdGl2ZTogaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0LW5hdGl2ZS9wdWxsLzE2MzJcbiAgcmV0dXJuICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmICdXZWJraXRBcHBlYXJhbmNlJyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUpIHx8XG4gICAgLy8gaXMgZmlyZWJ1Zz8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzk4MTIwLzM3Njc3M1xuICAgICh3aW5kb3cuY29uc29sZSAmJiAoY29uc29sZS5maXJlYnVnIHx8IChjb25zb2xlLmV4Y2VwdGlvbiAmJiBjb25zb2xlLnRhYmxlKSkpIHx8XG4gICAgLy8gaXMgZmlyZWZveCA+PSB2MzE/XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9Ub29scy9XZWJfQ29uc29sZSNTdHlsaW5nX21lc3NhZ2VzXG4gICAgKG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5tYXRjaCgvZmlyZWZveFxcLyhcXGQrKS8pICYmIHBhcnNlSW50KFJlZ0V4cC4kMSwgMTApID49IDMxKTtcbn1cblxuLyoqXG4gKiBNYXAgJWogdG8gYEpTT04uc3RyaW5naWZ5KClgLCBzaW5jZSBubyBXZWIgSW5zcGVjdG9ycyBkbyB0aGF0IGJ5IGRlZmF1bHQuXG4gKi9cblxuZXhwb3J0cy5mb3JtYXR0ZXJzLmogPSBmdW5jdGlvbih2KSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHYpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gJ1tVbmV4cGVjdGVkSlNPTlBhcnNlRXJyb3JdOiAnICsgZXJyLm1lc3NhZ2U7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBDb2xvcml6ZSBsb2cgYXJndW1lbnRzIGlmIGVuYWJsZWQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBmb3JtYXRBcmdzKCkge1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIHVzZUNvbG9ycyA9IHRoaXMudXNlQ29sb3JzO1xuXG4gIGFyZ3NbMF0gPSAodXNlQ29sb3JzID8gJyVjJyA6ICcnKVxuICAgICsgdGhpcy5uYW1lc3BhY2VcbiAgICArICh1c2VDb2xvcnMgPyAnICVjJyA6ICcgJylcbiAgICArIGFyZ3NbMF1cbiAgICArICh1c2VDb2xvcnMgPyAnJWMgJyA6ICcgJylcbiAgICArICcrJyArIGV4cG9ydHMuaHVtYW5pemUodGhpcy5kaWZmKTtcblxuICBpZiAoIXVzZUNvbG9ycykgcmV0dXJuIGFyZ3M7XG5cbiAgdmFyIGMgPSAnY29sb3I6ICcgKyB0aGlzLmNvbG9yO1xuICBhcmdzID0gW2FyZ3NbMF0sIGMsICdjb2xvcjogaW5oZXJpdCddLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmdzLCAxKSk7XG5cbiAgLy8gdGhlIGZpbmFsIFwiJWNcIiBpcyBzb21ld2hhdCB0cmlja3ksIGJlY2F1c2UgdGhlcmUgY291bGQgYmUgb3RoZXJcbiAgLy8gYXJndW1lbnRzIHBhc3NlZCBlaXRoZXIgYmVmb3JlIG9yIGFmdGVyIHRoZSAlYywgc28gd2UgbmVlZCB0b1xuICAvLyBmaWd1cmUgb3V0IHRoZSBjb3JyZWN0IGluZGV4IHRvIGluc2VydCB0aGUgQ1NTIGludG9cbiAgdmFyIGluZGV4ID0gMDtcbiAgdmFyIGxhc3RDID0gMDtcbiAgYXJnc1swXS5yZXBsYWNlKC8lW2EteiVdL2csIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgaWYgKCclJScgPT09IG1hdGNoKSByZXR1cm47XG4gICAgaW5kZXgrKztcbiAgICBpZiAoJyVjJyA9PT0gbWF0Y2gpIHtcbiAgICAgIC8vIHdlIG9ubHkgYXJlIGludGVyZXN0ZWQgaW4gdGhlICpsYXN0KiAlY1xuICAgICAgLy8gKHRoZSB1c2VyIG1heSBoYXZlIHByb3ZpZGVkIHRoZWlyIG93bilcbiAgICAgIGxhc3RDID0gaW5kZXg7XG4gICAgfVxuICB9KTtcblxuICBhcmdzLnNwbGljZShsYXN0QywgMCwgYyk7XG4gIHJldHVybiBhcmdzO1xufVxuXG4vKipcbiAqIEludm9rZXMgYGNvbnNvbGUubG9nKClgIHdoZW4gYXZhaWxhYmxlLlxuICogTm8tb3Agd2hlbiBgY29uc29sZS5sb2dgIGlzIG5vdCBhIFwiZnVuY3Rpb25cIi5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGxvZygpIHtcbiAgLy8gdGhpcyBoYWNrZXJ5IGlzIHJlcXVpcmVkIGZvciBJRTgvOSwgd2hlcmVcbiAgLy8gdGhlIGBjb25zb2xlLmxvZ2AgZnVuY3Rpb24gZG9lc24ndCBoYXZlICdhcHBseSdcbiAgcmV0dXJuICdvYmplY3QnID09PSB0eXBlb2YgY29uc29sZVxuICAgICYmIGNvbnNvbGUubG9nXG4gICAgJiYgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoY29uc29sZS5sb2csIGNvbnNvbGUsIGFyZ3VtZW50cyk7XG59XG5cbi8qKlxuICogU2F2ZSBgbmFtZXNwYWNlc2AuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNhdmUobmFtZXNwYWNlcykge1xuICB0cnkge1xuICAgIGlmIChudWxsID09IG5hbWVzcGFjZXMpIHtcbiAgICAgIGV4cG9ydHMuc3RvcmFnZS5yZW1vdmVJdGVtKCdkZWJ1ZycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLnN0b3JhZ2UuZGVidWcgPSBuYW1lc3BhY2VzO1xuICAgIH1cbiAgfSBjYXRjaChlKSB7fVxufVxuXG4vKipcbiAqIExvYWQgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gcmV0dXJucyB0aGUgcHJldmlvdXNseSBwZXJzaXN0ZWQgZGVidWcgbW9kZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvYWQoKSB7XG4gIHZhciByO1xuICB0cnkge1xuICAgIHJldHVybiBleHBvcnRzLnN0b3JhZ2UuZGVidWc7XG4gIH0gY2F0Y2goZSkge31cblxuICAvLyBJZiBkZWJ1ZyBpc24ndCBzZXQgaW4gTFMsIGFuZCB3ZSdyZSBpbiBFbGVjdHJvbiwgdHJ5IHRvIGxvYWQgJERFQlVHXG4gIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ2VudicgaW4gcHJvY2Vzcykge1xuICAgIHJldHVybiBwcm9jZXNzLmVudi5ERUJVRztcbiAgfVxufVxuXG4vKipcbiAqIEVuYWJsZSBuYW1lc3BhY2VzIGxpc3RlZCBpbiBgbG9jYWxTdG9yYWdlLmRlYnVnYCBpbml0aWFsbHkuXG4gKi9cblxuZXhwb3J0cy5lbmFibGUobG9hZCgpKTtcblxuLyoqXG4gKiBMb2NhbHN0b3JhZ2UgYXR0ZW1wdHMgdG8gcmV0dXJuIHRoZSBsb2NhbHN0b3JhZ2UuXG4gKlxuICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBzYWZhcmkgdGhyb3dzXG4gKiB3aGVuIGEgdXNlciBkaXNhYmxlcyBjb29raWVzL2xvY2Fsc3RvcmFnZVxuICogYW5kIHlvdSBhdHRlbXB0IHRvIGFjY2VzcyBpdC5cbiAqXG4gKiBAcmV0dXJuIHtMb2NhbFN0b3JhZ2V9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2NhbHN0b3JhZ2UoKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZTtcbiAgfSBjYXRjaCAoZSkge31cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///433b\n")},"4c13":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar toArray = __webpack_require__(/*! to-array */ \"7de3\");\nvar on = __webpack_require__(/*! ./on */ \"faaa\");\nvar bind = __webpack_require__(/*! component-bind */ \"b6f6\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:socket');\nvar hasBin = __webpack_require__(/*! has-binary */ \"d304\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = exports = Socket;\n\n/**\n * Internal events (blacklisted).\n * These events can't be emitted by the user.\n *\n * @api private\n */\n\nvar events = {\n  connect: 1,\n  connect_error: 1,\n  connect_timeout: 1,\n  connecting: 1,\n  disconnect: 1,\n  error: 1,\n  reconnect: 1,\n  reconnect_attempt: 1,\n  reconnect_failed: 1,\n  reconnect_error: 1,\n  reconnecting: 1,\n  ping: 1,\n  pong: 1\n};\n\n/**\n * Shortcut to `Emitter#emit`.\n */\n\nvar emit = Emitter.prototype.emit;\n\n/**\n * `Socket` constructor.\n *\n * @api public\n */\n\nfunction Socket (io, nsp, opts) {\n  this.io = io;\n  this.nsp = nsp;\n  this.json = this; // compat\n  this.ids = 0;\n  this.acks = {};\n  this.receiveBuffer = [];\n  this.sendBuffer = [];\n  this.connected = false;\n  this.disconnected = true;\n  if (opts && opts.query) {\n    this.query = opts.query;\n  }\n  if (this.io.autoConnect) this.open();\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Socket.prototype);\n\n/**\n * Subscribe to open, close and packet events\n *\n * @api private\n */\n\nSocket.prototype.subEvents = function () {\n  if (this.subs) return;\n\n  var io = this.io;\n  this.subs = [\n    on(io, 'open', bind(this, 'onopen')),\n    on(io, 'packet', bind(this, 'onpacket')),\n    on(io, 'close', bind(this, 'onclose'))\n  ];\n};\n\n/**\n * \"Opens\" the socket.\n *\n * @api public\n */\n\nSocket.prototype.open =\nSocket.prototype.connect = function () {\n  if (this.connected) return this;\n\n  this.subEvents();\n  this.io.open(); // ensure open\n  if ('open' === this.io.readyState) this.onopen();\n  this.emit('connecting');\n  return this;\n};\n\n/**\n * Sends a `message` event.\n *\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.send = function () {\n  var args = toArray(arguments);\n  args.unshift('message');\n  this.emit.apply(this, args);\n  return this;\n};\n\n/**\n * Override `emit`.\n * If the event is in `events`, it's emitted normally.\n *\n * @param {String} event name\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.emit = function (ev) {\n  if (events.hasOwnProperty(ev)) {\n    emit.apply(this, arguments);\n    return this;\n  }\n\n  var args = toArray(arguments);\n  var parserType = parser.EVENT; // default\n  if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary\n  var packet = { type: parserType, data: args };\n\n  packet.options = {};\n  packet.options.compress = !this.flags || false !== this.flags.compress;\n\n  // event ack callback\n  if ('function' === typeof args[args.length - 1]) {\n    debug('emitting packet with ack id %d', this.ids);\n    this.acks[this.ids] = args.pop();\n    packet.id = this.ids++;\n  }\n\n  if (this.connected) {\n    this.packet(packet);\n  } else {\n    this.sendBuffer.push(packet);\n  }\n\n  delete this.flags;\n\n  return this;\n};\n\n/**\n * Sends a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.packet = function (packet) {\n  packet.nsp = this.nsp;\n  this.io.packet(packet);\n};\n\n/**\n * Called upon engine `open`.\n *\n * @api private\n */\n\nSocket.prototype.onopen = function () {\n  debug('transport is open - connecting');\n\n  // write connect packet if necessary\n  if ('/' !== this.nsp) {\n    if (this.query) {\n      this.packet({type: parser.CONNECT, query: this.query});\n    } else {\n      this.packet({type: parser.CONNECT});\n    }\n  }\n};\n\n/**\n * Called upon engine `close`.\n *\n * @param {String} reason\n * @api private\n */\n\nSocket.prototype.onclose = function (reason) {\n  debug('close (%s)', reason);\n  this.connected = false;\n  this.disconnected = true;\n  delete this.id;\n  this.emit('disconnect', reason);\n};\n\n/**\n * Called with socket packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onpacket = function (packet) {\n  if (packet.nsp !== this.nsp) return;\n\n  switch (packet.type) {\n    case parser.CONNECT:\n      this.onconnect();\n      break;\n\n    case parser.EVENT:\n      this.onevent(packet);\n      break;\n\n    case parser.BINARY_EVENT:\n      this.onevent(packet);\n      break;\n\n    case parser.ACK:\n      this.onack(packet);\n      break;\n\n    case parser.BINARY_ACK:\n      this.onack(packet);\n      break;\n\n    case parser.DISCONNECT:\n      this.ondisconnect();\n      break;\n\n    case parser.ERROR:\n      this.emit('error', packet.data);\n      break;\n  }\n};\n\n/**\n * Called upon a server event.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onevent = function (packet) {\n  var args = packet.data || [];\n  debug('emitting event %j', args);\n\n  if (null != packet.id) {\n    debug('attaching ack callback to event');\n    args.push(this.ack(packet.id));\n  }\n\n  if (this.connected) {\n    emit.apply(this, args);\n  } else {\n    this.receiveBuffer.push(args);\n  }\n};\n\n/**\n * Produces an ack callback to emit with an event.\n *\n * @api private\n */\n\nSocket.prototype.ack = function (id) {\n  var self = this;\n  var sent = false;\n  return function () {\n    // prevent double callbacks\n    if (sent) return;\n    sent = true;\n    var args = toArray(arguments);\n    debug('sending ack %j', args);\n\n    var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;\n    self.packet({\n      type: type,\n      id: id,\n      data: args\n    });\n  };\n};\n\n/**\n * Called upon a server acknowlegement.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onack = function (packet) {\n  var ack = this.acks[packet.id];\n  if ('function' === typeof ack) {\n    debug('calling ack %s with %j', packet.id, packet.data);\n    ack.apply(this, packet.data);\n    delete this.acks[packet.id];\n  } else {\n    debug('bad ack %s', packet.id);\n  }\n};\n\n/**\n * Called upon server connect.\n *\n * @api private\n */\n\nSocket.prototype.onconnect = function () {\n  this.connected = true;\n  this.disconnected = false;\n  this.emit('connect');\n  this.emitBuffered();\n};\n\n/**\n * Emit buffered events (received and emitted).\n *\n * @api private\n */\n\nSocket.prototype.emitBuffered = function () {\n  var i;\n  for (i = 0; i < this.receiveBuffer.length; i++) {\n    emit.apply(this, this.receiveBuffer[i]);\n  }\n  this.receiveBuffer = [];\n\n  for (i = 0; i < this.sendBuffer.length; i++) {\n    this.packet(this.sendBuffer[i]);\n  }\n  this.sendBuffer = [];\n};\n\n/**\n * Called upon server disconnect.\n *\n * @api private\n */\n\nSocket.prototype.ondisconnect = function () {\n  debug('server disconnect (%s)', this.nsp);\n  this.destroy();\n  this.onclose('io server disconnect');\n};\n\n/**\n * Called upon forced client/server side disconnections,\n * this method ensures the manager stops tracking us and\n * that reconnections don't get triggered for this.\n *\n * @api private.\n */\n\nSocket.prototype.destroy = function () {\n  if (this.subs) {\n    // clean subscriptions to avoid reconnections\n    for (var i = 0; i < this.subs.length; i++) {\n      this.subs[i].destroy();\n    }\n    this.subs = null;\n  }\n\n  this.io.destroy(this);\n};\n\n/**\n * Disconnects the socket manually.\n *\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.close =\nSocket.prototype.disconnect = function () {\n  if (this.connected) {\n    debug('performing disconnect (%s)', this.nsp);\n    this.packet({ type: parser.DISCONNECT });\n  }\n\n  // remove socket from pool\n  this.destroy();\n\n  if (this.connected) {\n    // fire events\n    this.onclose('io client disconnect');\n  }\n  return this;\n};\n\n/**\n * Sets the compress flag.\n *\n * @param {Boolean} if `true`, compresses the sending data\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.compress = function (compress) {\n  this.flags = this.flags || {};\n  this.flags.compress = compress;\n  return this;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNGMxMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvc29ja2V0LmpzPzg3ZDEiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNlciA9IHJlcXVpcmUoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciB0b0FycmF5ID0gcmVxdWlyZSgndG8tYXJyYXknKTtcbnZhciBvbiA9IHJlcXVpcmUoJy4vb24nKTtcbnZhciBiaW5kID0gcmVxdWlyZSgnY29tcG9uZW50LWJpbmQnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6c29ja2V0Jyk7XG52YXIgaGFzQmluID0gcmVxdWlyZSgnaGFzLWJpbmFyeScpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IFNvY2tldDtcblxuLyoqXG4gKiBJbnRlcm5hbCBldmVudHMgKGJsYWNrbGlzdGVkKS5cbiAqIFRoZXNlIGV2ZW50cyBjYW4ndCBiZSBlbWl0dGVkIGJ5IHRoZSB1c2VyLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbnZhciBldmVudHMgPSB7XG4gIGNvbm5lY3Q6IDEsXG4gIGNvbm5lY3RfZXJyb3I6IDEsXG4gIGNvbm5lY3RfdGltZW91dDogMSxcbiAgY29ubmVjdGluZzogMSxcbiAgZGlzY29ubmVjdDogMSxcbiAgZXJyb3I6IDEsXG4gIHJlY29ubmVjdDogMSxcbiAgcmVjb25uZWN0X2F0dGVtcHQ6IDEsXG4gIHJlY29ubmVjdF9mYWlsZWQ6IDEsXG4gIHJlY29ubmVjdF9lcnJvcjogMSxcbiAgcmVjb25uZWN0aW5nOiAxLFxuICBwaW5nOiAxLFxuICBwb25nOiAxXG59O1xuXG4vKipcbiAqIFNob3J0Y3V0IHRvIGBFbWl0dGVyI2VtaXRgLlxuICovXG5cbnZhciBlbWl0ID0gRW1pdHRlci5wcm90b3R5cGUuZW1pdDtcblxuLyoqXG4gKiBgU29ja2V0YCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFNvY2tldCAoaW8sIG5zcCwgb3B0cykge1xuICB0aGlzLmlvID0gaW87XG4gIHRoaXMubnNwID0gbnNwO1xuICB0aGlzLmpzb24gPSB0aGlzOyAvLyBjb21wYXRcbiAgdGhpcy5pZHMgPSAwO1xuICB0aGlzLmFja3MgPSB7fTtcbiAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG4gIHRoaXMuc2VuZEJ1ZmZlciA9IFtdO1xuICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICB0aGlzLmRpc2Nvbm5lY3RlZCA9IHRydWU7XG4gIGlmIChvcHRzICYmIG9wdHMucXVlcnkpIHtcbiAgICB0aGlzLnF1ZXJ5ID0gb3B0cy5xdWVyeTtcbiAgfVxuICBpZiAodGhpcy5pby5hdXRvQ29ubmVjdCkgdGhpcy5vcGVuKCk7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFNvY2tldC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIFN1YnNjcmliZSB0byBvcGVuLCBjbG9zZSBhbmQgcGFja2V0IGV2ZW50c1xuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc3ViRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zdWJzKSByZXR1cm47XG5cbiAgdmFyIGlvID0gdGhpcy5pbztcbiAgdGhpcy5zdWJzID0gW1xuICAgIG9uKGlvLCAnb3BlbicsIGJpbmQodGhpcywgJ29ub3BlbicpKSxcbiAgICBvbihpbywgJ3BhY2tldCcsIGJpbmQodGhpcywgJ29ucGFja2V0JykpLFxuICAgIG9uKGlvLCAnY2xvc2UnLCBiaW5kKHRoaXMsICdvbmNsb3NlJykpXG4gIF07XG59O1xuXG4vKipcbiAqIFwiT3BlbnNcIiB0aGUgc29ja2V0LlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vcGVuID1cblNvY2tldC5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY29ubmVjdGVkKSByZXR1cm4gdGhpcztcblxuICB0aGlzLnN1YkV2ZW50cygpO1xuICB0aGlzLmlvLm9wZW4oKTsgLy8gZW5zdXJlIG9wZW5cbiAgaWYgKCdvcGVuJyA9PT0gdGhpcy5pby5yZWFkeVN0YXRlKSB0aGlzLm9ub3BlbigpO1xuICB0aGlzLmVtaXQoJ2Nvbm5lY3RpbmcnKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIGEgYG1lc3NhZ2VgIGV2ZW50LlxuICpcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMpO1xuICBhcmdzLnVuc2hpZnQoJ21lc3NhZ2UnKTtcbiAgdGhpcy5lbWl0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgYGVtaXRgLlxuICogSWYgdGhlIGV2ZW50IGlzIGluIGBldmVudHNgLCBpdCdzIGVtaXR0ZWQgbm9ybWFsbHkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IG5hbWVcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShldikpIHtcbiAgICBlbWl0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgdmFyIHBhcnNlclR5cGUgPSBwYXJzZXIuRVZFTlQ7IC8vIGRlZmF1bHRcbiAgaWYgKGhhc0JpbihhcmdzKSkgeyBwYXJzZXJUeXBlID0gcGFyc2VyLkJJTkFSWV9FVkVOVDsgfSAvLyBiaW5hcnlcbiAgdmFyIHBhY2tldCA9IHsgdHlwZTogcGFyc2VyVHlwZSwgZGF0YTogYXJncyB9O1xuXG4gIHBhY2tldC5vcHRpb25zID0ge307XG4gIHBhY2tldC5vcHRpb25zLmNvbXByZXNzID0gIXRoaXMuZmxhZ3MgfHwgZmFsc2UgIT09IHRoaXMuZmxhZ3MuY29tcHJlc3M7XG5cbiAgLy8gZXZlbnQgYWNrIGNhbGxiYWNrXG4gIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgYXJnc1thcmdzLmxlbmd0aCAtIDFdKSB7XG4gICAgZGVidWcoJ2VtaXR0aW5nIHBhY2tldCB3aXRoIGFjayBpZCAlZCcsIHRoaXMuaWRzKTtcbiAgICB0aGlzLmFja3NbdGhpcy5pZHNdID0gYXJncy5wb3AoKTtcbiAgICBwYWNrZXQuaWQgPSB0aGlzLmlkcysrO1xuICB9XG5cbiAgaWYgKHRoaXMuY29ubmVjdGVkKSB7XG4gICAgdGhpcy5wYWNrZXQocGFja2V0KTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnNlbmRCdWZmZXIucHVzaChwYWNrZXQpO1xuICB9XG5cbiAgZGVsZXRlIHRoaXMuZmxhZ3M7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIGEgcGFja2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUucGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICBwYWNrZXQubnNwID0gdGhpcy5uc3A7XG4gIHRoaXMuaW8ucGFja2V0KHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGVuZ2luZSBgb3BlbmAuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCd0cmFuc3BvcnQgaXMgb3BlbiAtIGNvbm5lY3RpbmcnKTtcblxuICAvLyB3cml0ZSBjb25uZWN0IHBhY2tldCBpZiBuZWNlc3NhcnlcbiAgaWYgKCcvJyAhPT0gdGhpcy5uc3ApIHtcbiAgICBpZiAodGhpcy5xdWVyeSkge1xuICAgICAgdGhpcy5wYWNrZXQoe3R5cGU6IHBhcnNlci5DT05ORUNULCBxdWVyeTogdGhpcy5xdWVyeX0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBhY2tldCh7dHlwZTogcGFyc2VyLkNPTk5FQ1R9KTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZW5naW5lIGBjbG9zZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJlYXNvblxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICBkZWJ1ZygnY2xvc2UgKCVzKScsIHJlYXNvbik7XG4gIHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG4gIHRoaXMuZGlzY29ubmVjdGVkID0gdHJ1ZTtcbiAgZGVsZXRlIHRoaXMuaWQ7XG4gIHRoaXMuZW1pdCgnZGlzY29ubmVjdCcsIHJlYXNvbik7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIHNvY2tldCBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbnBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgaWYgKHBhY2tldC5uc3AgIT09IHRoaXMubnNwKSByZXR1cm47XG5cbiAgc3dpdGNoIChwYWNrZXQudHlwZSkge1xuICAgIGNhc2UgcGFyc2VyLkNPTk5FQ1Q6XG4gICAgICB0aGlzLm9uY29ubmVjdCgpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5FVkVOVDpcbiAgICAgIHRoaXMub25ldmVudChwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfRVZFTlQ6XG4gICAgICB0aGlzLm9uZXZlbnQocGFja2V0KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5ESVNDT05ORUNUOlxuICAgICAgdGhpcy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuRVJST1I6XG4gICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgcGFja2V0LmRhdGEpO1xuICAgICAgYnJlYWs7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gYSBzZXJ2ZXIgZXZlbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmV2ZW50ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICB2YXIgYXJncyA9IHBhY2tldC5kYXRhIHx8IFtdO1xuICBkZWJ1ZygnZW1pdHRpbmcgZXZlbnQgJWonLCBhcmdzKTtcblxuICBpZiAobnVsbCAhPSBwYWNrZXQuaWQpIHtcbiAgICBkZWJ1ZygnYXR0YWNoaW5nIGFjayBjYWxsYmFjayB0byBldmVudCcpO1xuICAgIGFyZ3MucHVzaCh0aGlzLmFjayhwYWNrZXQuaWQpKTtcbiAgfVxuXG4gIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgIGVtaXQuYXBwbHkodGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yZWNlaXZlQnVmZmVyLnB1c2goYXJncyk7XG4gIH1cbn07XG5cbi8qKlxuICogUHJvZHVjZXMgYW4gYWNrIGNhbGxiYWNrIHRvIGVtaXQgd2l0aCBhbiBldmVudC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmFjayA9IGZ1bmN0aW9uIChpZCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBzZW50ID0gZmFsc2U7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gcHJldmVudCBkb3VibGUgY2FsbGJhY2tzXG4gICAgaWYgKHNlbnQpIHJldHVybjtcbiAgICBzZW50ID0gdHJ1ZTtcbiAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICBkZWJ1Zygnc2VuZGluZyBhY2sgJWonLCBhcmdzKTtcblxuICAgIHZhciB0eXBlID0gaGFzQmluKGFyZ3MpID8gcGFyc2VyLkJJTkFSWV9BQ0sgOiBwYXJzZXIuQUNLO1xuICAgIHNlbGYucGFja2V0KHtcbiAgICAgIHR5cGU6IHR5cGUsXG4gICAgICBpZDogaWQsXG4gICAgICBkYXRhOiBhcmdzXG4gICAgfSk7XG4gIH07XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgc2VydmVyIGFja25vd2xlZ2VtZW50LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25hY2sgPSBmdW5jdGlvbiAocGFja2V0KSB7XG4gIHZhciBhY2sgPSB0aGlzLmFja3NbcGFja2V0LmlkXTtcbiAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBhY2spIHtcbiAgICBkZWJ1ZygnY2FsbGluZyBhY2sgJXMgd2l0aCAlaicsIHBhY2tldC5pZCwgcGFja2V0LmRhdGEpO1xuICAgIGFjay5hcHBseSh0aGlzLCBwYWNrZXQuZGF0YSk7XG4gICAgZGVsZXRlIHRoaXMuYWNrc1twYWNrZXQuaWRdO1xuICB9IGVsc2Uge1xuICAgIGRlYnVnKCdiYWQgYWNrICVzJywgcGFja2V0LmlkKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzZXJ2ZXIgY29ubmVjdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuICB0aGlzLmRpc2Nvbm5lY3RlZCA9IGZhbHNlO1xuICB0aGlzLmVtaXQoJ2Nvbm5lY3QnKTtcbiAgdGhpcy5lbWl0QnVmZmVyZWQoKTtcbn07XG5cbi8qKlxuICogRW1pdCBidWZmZXJlZCBldmVudHMgKHJlY2VpdmVkIGFuZCBlbWl0dGVkKS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmVtaXRCdWZmZXJlZCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnJlY2VpdmVCdWZmZXIubGVuZ3RoOyBpKyspIHtcbiAgICBlbWl0LmFwcGx5KHRoaXMsIHRoaXMucmVjZWl2ZUJ1ZmZlcltpXSk7XG4gIH1cbiAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMuc2VuZEJ1ZmZlci5sZW5ndGg7IGkrKykge1xuICAgIHRoaXMucGFja2V0KHRoaXMuc2VuZEJ1ZmZlcltpXSk7XG4gIH1cbiAgdGhpcy5zZW5kQnVmZmVyID0gW107XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHNlcnZlciBkaXNjb25uZWN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25kaXNjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1Zygnc2VydmVyIGRpc2Nvbm5lY3QgKCVzKScsIHRoaXMubnNwKTtcbiAgdGhpcy5kZXN0cm95KCk7XG4gIHRoaXMub25jbG9zZSgnaW8gc2VydmVyIGRpc2Nvbm5lY3QnKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZm9yY2VkIGNsaWVudC9zZXJ2ZXIgc2lkZSBkaXNjb25uZWN0aW9ucyxcbiAqIHRoaXMgbWV0aG9kIGVuc3VyZXMgdGhlIG1hbmFnZXIgc3RvcHMgdHJhY2tpbmcgdXMgYW5kXG4gKiB0aGF0IHJlY29ubmVjdGlvbnMgZG9uJ3QgZ2V0IHRyaWdnZXJlZCBmb3IgdGhpcy5cbiAqXG4gKiBAYXBpIHByaXZhdGUuXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zdWJzKSB7XG4gICAgLy8gY2xlYW4gc3Vic2NyaXB0aW9ucyB0byBhdm9pZCByZWNvbm5lY3Rpb25zXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuc3Vic1tpXS5kZXN0cm95KCk7XG4gICAgfVxuICAgIHRoaXMuc3VicyA9IG51bGw7XG4gIH1cblxuICB0aGlzLmlvLmRlc3Ryb3kodGhpcyk7XG59O1xuXG4vKipcbiAqIERpc2Nvbm5lY3RzIHRoZSBzb2NrZXQgbWFudWFsbHkuXG4gKlxuICogQHJldHVybiB7U29ja2V0fSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPVxuU29ja2V0LnByb3RvdHlwZS5kaXNjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jb25uZWN0ZWQpIHtcbiAgICBkZWJ1ZygncGVyZm9ybWluZyBkaXNjb25uZWN0ICglcyknLCB0aGlzLm5zcCk7XG4gICAgdGhpcy5wYWNrZXQoeyB0eXBlOiBwYXJzZXIuRElTQ09OTkVDVCB9KTtcbiAgfVxuXG4gIC8vIHJlbW92ZSBzb2NrZXQgZnJvbSBwb29sXG4gIHRoaXMuZGVzdHJveSgpO1xuXG4gIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgIC8vIGZpcmUgZXZlbnRzXG4gICAgdGhpcy5vbmNsb3NlKCdpbyBjbGllbnQgZGlzY29ubmVjdCcpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBjb21wcmVzcyBmbGFnLlxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaWYgYHRydWVgLCBjb21wcmVzc2VzIHRoZSBzZW5kaW5nIGRhdGFcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNvbXByZXNzID0gZnVuY3Rpb24gKGNvbXByZXNzKSB7XG4gIHRoaXMuZmxhZ3MgPSB0aGlzLmZsYWdzIHx8IHt9O1xuICB0aGlzLmZsYWdzLmNvbXByZXNzID0gY29tcHJlc3M7XG4gIHJldHVybiB0aGlzO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4c13\n")},"4d50":function(module,exports,__webpack_require__){eval("/**\n * Facets are the main abstraction over the data.\n *\n * A `Dataset` is a collection of (similar) items, with each item having a certain set of properties, ie. `Facet`s.\n * The `Facet` class defines the property: It can be a continuous value, a set of labels or tags,\n * or it can be result of some transformation or equation.\n *\n * @class Facet\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar CategorialTransform = __webpack_require__(/*! ./facet/categorial-transform */ \"9b75\");\nvar ContinuousTransform = __webpack_require__(/*! ./facet/continuous-transform */ \"5a80\");\nvar datetimeTransform = __webpack_require__(/*! ./facet/datetime-transform */ \"a0ca\");\nvar durationTransform = __webpack_require__(/*! ./facet/duration-transform */ \"b123\");\nvar textTransform = __webpack_require__(/*! ./facet/text-transform */ \"e810\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    this.on('change:type', function (facet, newval) {\n      // reset transformations on type change\n      this.continuousTransform.reset();\n      this.categorialTransform.reset();\n      this.datetimeTransform.reset();\n      this.durationTransform.reset();\n    });\n  },\n  props: {\n    /**\n     * Show in facet lists (used for interactive searching on Facets page)\n     * @memberof! Facet\n     * @type {boolean}\n     */\n    show: ['boolean', false, true],\n\n    /**\n     * Show facet bar (on Analyze page)\n     * @memberof! Facet\n     * @type {boolean}\n     */\n    isActive: ['boolean', false, false],\n\n    // general facet properties\n    /**\n     * Description of this facet, for displaying purposes\n     * @memberof! Facet\n     * @type {string}\n     */\n    description: ['string', true, ''],\n\n    /**\n     * For continuous facets, its units for displaying purposes\n     * @memberof! Facet\n     * @type {string}\n     */\n    units: ['string', true, ''],\n\n    /**\n     * Short name (human readable) for this facet, must be unique.\n     * @memberof! Facet\n     * @type {string}\n     */\n    name: ['string', true, ''],\n\n    /**\n     * Type of this facet:\n     *  * `constant`        A constant value of \"1\" for all data items\n     *  * `continuous`      The facet takes on real numbers\n     *  * `categorial`      The facet is a string, or an array of strings (for a well defined set of labels and tags)\n     *  * `datetime`        The facet is a datetime (using momentjs.tz)\n     *  * `duration`        The facet is a duration (using momentjs.duration)\n     *  * `text`            Freeform text.\n     * Check for facet type using isConstant, isContinuous, isCategorial, isDatetime, isDuration, or isText  properties.\n     * @memberof! Facet\n     * @type {string}\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['constant', 'continuous', 'categorial', 'datetime', 'duration', 'text']\n    },\n\n    /**\n     * The accessor for this facet.\n     * For nested properties use dot notation: For a dataset `[ {name: {first: \"Santa\", last: \"Claus\"}}, ...]`\n     * you can use `name.first` and `name.last` to get Santa and Claus, respectively.\n     *\n     * @memberof! Facet\n     * @type {string}\n     */\n    accessor: ['string', false, null],\n\n    /**\n     * Missing or invalid data indicator; for multiple values, use a comma separated, quoted list\n     * Numbers, strings, booleans, and the special value null are allowed.\n     * Use single or double quotes for strings \"missing\".\n     * The parsed values are available in the misval property.\n     *\n     * @memberof! Facet\n     * @type {string}\n     */\n    misvalAsText: 'string',\n\n    /**\n     * For continuous or datetime Facets, the minimum value as text.\n     * Parsed value available in the `minval` property\n     * @memberof! Facet\n     * @type {string}\n     */\n    minvalAsText: 'string',\n\n    /**\n     * For continuous or datetime Facets, the maximum value as text.\n     * Parsed value available in the `maxval` property\n     * @memberof! Facet\n     * @type {string}\n     */\n    maxvalAsText: 'string'\n  },\n  children: {\n    /**\n     * A categorial transformation to apply to the data\n     * @memberof! Facet\n     * @type {CategorialTransform}\n     */\n    categorialTransform: CategorialTransform,\n    /**\n     * A datetime transformation to apply to the data\n     * @memberof! Facet\n     * @type {dateimeTransform}\n     */\n    datetimeTransform: datetimeTransform,\n    /**\n     * A duration transformation to apply to the data\n     * @memberof! Facet\n     * @type {dateimeTransform}\n     */\n    durationTransform: durationTransform,\n    /**\n     * A continuous transformation to apply to the data\n     * @memberof! Facet\n     * @type {ContinuousTransform}\n     */\n    continuousTransform: ContinuousTransform,\n    /**\n     * A text transform\n     * @memberof! Facet\n     * @type {TextTransform}\n     */\n    textTransform: textTransform\n  },\n\n  derived: {\n    // properties for: type\n    isConstant: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'constant';\n      }\n    },\n    isContinuous: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'continuous';\n      }\n    },\n    isCategorial: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'categorial';\n      }\n    },\n    isDatetime: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'datetime';\n      }\n    },\n    isDuration: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'duration';\n      }\n    },\n    isText: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'text';\n      }\n    },\n\n    /**\n     * Array of missing data indicators\n     * @memberof! Facet\n     * @type {Object[]}\n     * @readonly\n     */\n    misval: {\n      deps: ['misvalAsText'],\n      fn: function () {\n        // Parse the text content as a JSON array:\n        //  - strings should be quoted\n        //  - numbers unquoated\n        //  - special numbers not allowed: NaN, Infinity\n        try {\n          if (this.misvalAsText !== null) {\n            return JSON.parse('[' + this.misvalAsText + ']');\n          } else {\n            return [];\n          }\n        } catch (e) {\n          return [];\n        }\n      },\n      cache: false\n    },\n\n    /**\n     * For continuous or datetime Facets, the minimum value.\n     * @memberof! Facet\n     * @type {number|datetime}\n     * @readonly\n     */\n    minval: {\n      deps: ['minvalAsText', 'type'],\n      fn: function () {\n        var min;\n        if (this.isContinuous) {\n          min = parseFloat(this.minvalAsText);\n          if (isNaN(min)) {\n            min = 0;\n          }\n        } else if (this.isDatetime) {\n          min = moment(this.minvalAsText, moment.ISO_8601);\n          if (!min.isValid()) {\n            min = moment('2010-01-01 00:00', moment.ISO_8601);\n          }\n        } else if (this.isDuration) {\n          min = moment.duration(this.minvalAsText);\n          if (!moment.isDuration(min)) {\n            min = moment.duration(1, 'seconds');\n          }\n        }\n        return min;\n      },\n      cache: false\n    },\n    /**\n     * For continuous or datetime Facets, the maximum value.\n     * @memberof! Facet\n     * @type {number|datetime}\n     * @readonly\n     */\n    maxval: {\n      deps: ['maxvalAsText', 'type'],\n      fn: function () {\n        var max;\n        if (this.isContinuous) {\n          max = parseFloat(this.maxvalAsText);\n          if (isNaN(max)) {\n            max = 100;\n          }\n        } else if (this.isDatetime) {\n          max = moment(this.maxvalAsText, moment.ISO_8601);\n          if (!max.isValid()) {\n            max = moment('2020-01-01 00:00', moment.ISO_8601);\n          }\n        } else if (this.isDuration) {\n          max = moment.duration(this.maxvalAsText);\n          if (!moment.isDuration(max)) {\n            max = moment.duration(100, 'seconds');\n          }\n        }\n        return max;\n      },\n      cache: false\n    },\n    transform: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isContinuous) {\n          return this.continuousTransform;\n        } else if (this.isCategorial) {\n          return this.categorialTransform;\n        } else if (this.isDatetime) {\n          return this.datetimeTransform;\n        } else if (this.isDuration) {\n          return this.durationTransform;\n        } else if (this.isText) {\n          return this.textTransform;\n        }\n        console.error('Invalid facet');\n      },\n      cache: false\n    }\n  },\n  /**\n   * setMinMax sets the range of a continuous or time facet\n   * For facets in a dataview, the minimum is just the minimum of the facet over all active datasets,\n   * and the same for the maximum.\n   * For facets in a datset, the actual implementation is in the dataset driver.\n   *\n   * @memberof! Facet\n   */\n  setMinMax: function () {\n    var Dataset = __webpack_require__(/*! ./dataset */ \"545a\");\n    var Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\n\n    var ancestor = this.collection.parent;\n    var spot;\n\n    if (ancestor instanceof Dataview) {\n      // Facet -> Facets -> Dataview -> Spot\n      spot = this.collection.parent.parent;\n      spot.setFacetMinMax(this);\n    } else if (ancestor instanceof Dataset) {\n      // Dataset -> Datasets -> Spot\n      spot = ancestor.collection.parent;\n      spot.driver.setMinMax(ancestor, this);\n    }\n  },\n  /**\n   * setCategories finds finds all values on an ordinal (categorial) axis\n   * Updates the categorialTransform of the facet\n   * For facets in a dataview, this is the union of the categories of facet over all active datasets.\n   * For facets in a dataset, the actual implementation is in the dataset driver.\n   *\n   * @memberof! Facet\n   */\n  setCategories: function () {\n    var Dataset = __webpack_require__(/*! ./dataset */ \"545a\");\n    var Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\n\n    var ancestor = this.collection.parent;\n    var spot;\n\n    if (ancestor instanceof Dataview) {\n      // Facet -> Facets -> Dataview -> Spot\n      spot = this.collection.parent.parent;\n      spot.setFacetCategories(this);\n    } else if (ancestor instanceof Dataset) {\n      // Facet -> Facets -> Dataset -> Datasets -> Spot\n      spot = ancestor.collection.parent;\n      spot.driver.setCategories(ancestor, this);\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNGQ1MC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQuanM/ZDdlYiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEZhY2V0cyBhcmUgdGhlIG1haW4gYWJzdHJhY3Rpb24gb3ZlciB0aGUgZGF0YS5cbiAqXG4gKiBBIGBEYXRhc2V0YCBpcyBhIGNvbGxlY3Rpb24gb2YgKHNpbWlsYXIpIGl0ZW1zLCB3aXRoIGVhY2ggaXRlbSBoYXZpbmcgYSBjZXJ0YWluIHNldCBvZiBwcm9wZXJ0aWVzLCBpZS4gYEZhY2V0YHMuXG4gKiBUaGUgYEZhY2V0YCBjbGFzcyBkZWZpbmVzIHRoZSBwcm9wZXJ0eTogSXQgY2FuIGJlIGEgY29udGludW91cyB2YWx1ZSwgYSBzZXQgb2YgbGFiZWxzIG9yIHRhZ3MsXG4gKiBvciBpdCBjYW4gYmUgcmVzdWx0IG9mIHNvbWUgdHJhbnNmb3JtYXRpb24gb3IgZXF1YXRpb24uXG4gKlxuICogQGNsYXNzIEZhY2V0XG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBCYXNlTW9kZWwgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIENhdGVnb3JpYWxUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L2NhdGVnb3JpYWwtdHJhbnNmb3JtJyk7XG52YXIgQ29udGludW91c1RyYW5zZm9ybSA9IHJlcXVpcmUoJy4vZmFjZXQvY29udGludW91cy10cmFuc2Zvcm0nKTtcbnZhciBkYXRldGltZVRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vZmFjZXQvZGF0ZXRpbWUtdHJhbnNmb3JtJyk7XG52YXIgZHVyYXRpb25UcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L2R1cmF0aW9uLXRyYW5zZm9ybScpO1xudmFyIHRleHRUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L3RleHQtdHJhbnNmb3JtJyk7XG52YXIgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50LXRpbWV6b25lJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLm9uKCdjaGFuZ2U6dHlwZScsIGZ1bmN0aW9uIChmYWNldCwgbmV3dmFsKSB7XG4gICAgICAvLyByZXNldCB0cmFuc2Zvcm1hdGlvbnMgb24gdHlwZSBjaGFuZ2VcbiAgICAgIHRoaXMuY29udGludW91c1RyYW5zZm9ybS5yZXNldCgpO1xuICAgICAgdGhpcy5jYXRlZ29yaWFsVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgICB0aGlzLmRhdGV0aW1lVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgICB0aGlzLmR1cmF0aW9uVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgfSk7XG4gIH0sXG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogU2hvdyBpbiBmYWNldCBsaXN0cyAodXNlZCBmb3IgaW50ZXJhY3RpdmUgc2VhcmNoaW5nIG9uIEZhY2V0cyBwYWdlKVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBzaG93OiBbJ2Jvb2xlYW4nLCBmYWxzZSwgdHJ1ZV0sXG5cbiAgICAvKipcbiAgICAgKiBTaG93IGZhY2V0IGJhciAob24gQW5hbHl6ZSBwYWdlKVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0FjdGl2ZTogWydib29sZWFuJywgZmFsc2UsIGZhbHNlXSxcblxuICAgIC8vIGdlbmVyYWwgZmFjZXQgcHJvcGVydGllc1xuICAgIC8qKlxuICAgICAqIERlc2NyaXB0aW9uIG9mIHRoaXMgZmFjZXQsIGZvciBkaXNwbGF5aW5nIHB1cnBvc2VzXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgZGVzY3JpcHRpb246IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgZmFjZXRzLCBpdHMgdW5pdHMgZm9yIGRpc3BsYXlpbmcgcHVycG9zZXNcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB1bml0czogWydzdHJpbmcnLCB0cnVlLCAnJ10sXG5cbiAgICAvKipcbiAgICAgKiBTaG9ydCBuYW1lIChodW1hbiByZWFkYWJsZSkgZm9yIHRoaXMgZmFjZXQsIG11c3QgYmUgdW5pcXVlLlxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG5hbWU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiB0aGlzIGZhY2V0OlxuICAgICAqICAqIGBjb25zdGFudGAgICAgICAgIEEgY29uc3RhbnQgdmFsdWUgb2YgXCIxXCIgZm9yIGFsbCBkYXRhIGl0ZW1zXG4gICAgICogICogYGNvbnRpbnVvdXNgICAgICAgVGhlIGZhY2V0IHRha2VzIG9uIHJlYWwgbnVtYmVyc1xuICAgICAqICAqIGBjYXRlZ29yaWFsYCAgICAgIFRoZSBmYWNldCBpcyBhIHN0cmluZywgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncyAoZm9yIGEgd2VsbCBkZWZpbmVkIHNldCBvZiBsYWJlbHMgYW5kIHRhZ3MpXG4gICAgICogICogYGRhdGV0aW1lYCAgICAgICAgVGhlIGZhY2V0IGlzIGEgZGF0ZXRpbWUgKHVzaW5nIG1vbWVudGpzLnR6KVxuICAgICAqICAqIGBkdXJhdGlvbmAgICAgICAgIFRoZSBmYWNldCBpcyBhIGR1cmF0aW9uICh1c2luZyBtb21lbnRqcy5kdXJhdGlvbilcbiAgICAgKiAgKiBgdGV4dGAgICAgICAgICAgICBGcmVlZm9ybSB0ZXh0LlxuICAgICAqIENoZWNrIGZvciBmYWNldCB0eXBlIHVzaW5nIGlzQ29uc3RhbnQsIGlzQ29udGludW91cywgaXNDYXRlZ29yaWFsLCBpc0RhdGV0aW1lLCBpc0R1cmF0aW9uLCBvciBpc1RleHQgIHByb3BlcnRpZXMuXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHlwZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICdjYXRlZ29yaWFsJyxcbiAgICAgIHZhbHVlczogWydjb25zdGFudCcsICdjb250aW51b3VzJywgJ2NhdGVnb3JpYWwnLCAnZGF0ZXRpbWUnLCAnZHVyYXRpb24nLCAndGV4dCddXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBhY2Nlc3NvciBmb3IgdGhpcyBmYWNldC5cbiAgICAgKiBGb3IgbmVzdGVkIHByb3BlcnRpZXMgdXNlIGRvdCBub3RhdGlvbjogRm9yIGEgZGF0YXNldCBgWyB7bmFtZToge2ZpcnN0OiBcIlNhbnRhXCIsIGxhc3Q6IFwiQ2xhdXNcIn19LCAuLi5dYFxuICAgICAqIHlvdSBjYW4gdXNlIGBuYW1lLmZpcnN0YCBhbmQgYG5hbWUubGFzdGAgdG8gZ2V0IFNhbnRhIGFuZCBDbGF1cywgcmVzcGVjdGl2ZWx5LlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgYWNjZXNzb3I6IFsnc3RyaW5nJywgZmFsc2UsIG51bGxdLFxuXG4gICAgLyoqXG4gICAgICogTWlzc2luZyBvciBpbnZhbGlkIGRhdGEgaW5kaWNhdG9yOyBmb3IgbXVsdGlwbGUgdmFsdWVzLCB1c2UgYSBjb21tYSBzZXBhcmF0ZWQsIHF1b3RlZCBsaXN0XG4gICAgICogTnVtYmVycywgc3RyaW5ncywgYm9vbGVhbnMsIGFuZCB0aGUgc3BlY2lhbCB2YWx1ZSBudWxsIGFyZSBhbGxvd2VkLlxuICAgICAqIFVzZSBzaW5nbGUgb3IgZG91YmxlIHF1b3RlcyBmb3Igc3RyaW5ncyBcIm1pc3NpbmdcIi5cbiAgICAgKiBUaGUgcGFyc2VkIHZhbHVlcyBhcmUgYXZhaWxhYmxlIGluIHRoZSBtaXN2YWwgcHJvcGVydHkuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBtaXN2YWxBc1RleHQ6ICdzdHJpbmcnLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgb3IgZGF0ZXRpbWUgRmFjZXRzLCB0aGUgbWluaW11bSB2YWx1ZSBhcyB0ZXh0LlxuICAgICAqIFBhcnNlZCB2YWx1ZSBhdmFpbGFibGUgaW4gdGhlIGBtaW52YWxgIHByb3BlcnR5XG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgbWludmFsQXNUZXh0OiAnc3RyaW5nJyxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1heGltdW0gdmFsdWUgYXMgdGV4dC5cbiAgICAgKiBQYXJzZWQgdmFsdWUgYXZhaWxhYmxlIGluIHRoZSBgbWF4dmFsYCBwcm9wZXJ0eVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG1heHZhbEFzVGV4dDogJ3N0cmluZydcbiAgfSxcbiAgY2hpbGRyZW46IHtcbiAgICAvKipcbiAgICAgKiBBIGNhdGVnb3JpYWwgdHJhbnNmb3JtYXRpb24gdG8gYXBwbHkgdG8gdGhlIGRhdGFcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge0NhdGVnb3JpYWxUcmFuc2Zvcm19XG4gICAgICovXG4gICAgY2F0ZWdvcmlhbFRyYW5zZm9ybTogQ2F0ZWdvcmlhbFRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGRhdGV0aW1lIHRyYW5zZm9ybWF0aW9uIHRvIGFwcGx5IHRvIHRoZSBkYXRhXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtkYXRlaW1lVHJhbnNmb3JtfVxuICAgICAqL1xuICAgIGRhdGV0aW1lVHJhbnNmb3JtOiBkYXRldGltZVRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGR1cmF0aW9uIHRyYW5zZm9ybWF0aW9uIHRvIGFwcGx5IHRvIHRoZSBkYXRhXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtkYXRlaW1lVHJhbnNmb3JtfVxuICAgICAqL1xuICAgIGR1cmF0aW9uVHJhbnNmb3JtOiBkdXJhdGlvblRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGNvbnRpbnVvdXMgdHJhbnNmb3JtYXRpb24gdG8gYXBwbHkgdG8gdGhlIGRhdGFcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge0NvbnRpbnVvdXNUcmFuc2Zvcm19XG4gICAgICovXG4gICAgY29udGludW91c1RyYW5zZm9ybTogQ29udGludW91c1RyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIHRleHQgdHJhbnNmb3JtXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtUZXh0VHJhbnNmb3JtfVxuICAgICAqL1xuICAgIHRleHRUcmFuc2Zvcm06IHRleHRUcmFuc2Zvcm1cbiAgfSxcblxuICBkZXJpdmVkOiB7XG4gICAgLy8gcHJvcGVydGllcyBmb3I6IHR5cGVcbiAgICBpc0NvbnN0YW50OiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjb25zdGFudCc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0NvbnRpbnVvdXM6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2NvbnRpbnVvdXMnO1xuICAgICAgfVxuICAgIH0sXG4gICAgaXNDYXRlZ29yaWFsOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjYXRlZ29yaWFsJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzRGF0ZXRpbWU6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2RhdGV0aW1lJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzRHVyYXRpb246IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2R1cmF0aW9uJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzVGV4dDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAndGV4dCc7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEFycmF5IG9mIG1pc3NpbmcgZGF0YSBpbmRpY2F0b3JzXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtPYmplY3RbXX1cbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKi9cbiAgICBtaXN2YWw6IHtcbiAgICAgIGRlcHM6IFsnbWlzdmFsQXNUZXh0J10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBQYXJzZSB0aGUgdGV4dCBjb250ZW50IGFzIGEgSlNPTiBhcnJheTpcbiAgICAgICAgLy8gIC0gc3RyaW5ncyBzaG91bGQgYmUgcXVvdGVkXG4gICAgICAgIC8vICAtIG51bWJlcnMgdW5xdW9hdGVkXG4gICAgICAgIC8vICAtIHNwZWNpYWwgbnVtYmVycyBub3QgYWxsb3dlZDogTmFOLCBJbmZpbml0eVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICh0aGlzLm1pc3ZhbEFzVGV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoJ1snICsgdGhpcy5taXN2YWxBc1RleHQgKyAnXScpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1pbmltdW0gdmFsdWUuXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtudW1iZXJ8ZGF0ZXRpbWV9XG4gICAgICogQHJlYWRvbmx5XG4gICAgICovXG4gICAgbWludmFsOiB7XG4gICAgICBkZXBzOiBbJ21pbnZhbEFzVGV4dCcsICd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWluO1xuICAgICAgICBpZiAodGhpcy5pc0NvbnRpbnVvdXMpIHtcbiAgICAgICAgICBtaW4gPSBwYXJzZUZsb2F0KHRoaXMubWludmFsQXNUZXh0KTtcbiAgICAgICAgICBpZiAoaXNOYU4obWluKSkge1xuICAgICAgICAgICAgbWluID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0RhdGV0aW1lKSB7XG4gICAgICAgICAgbWluID0gbW9tZW50KHRoaXMubWludmFsQXNUZXh0LCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICAgIGlmICghbWluLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgbWluID0gbW9tZW50KCcyMDEwLTAxLTAxIDAwOjAwJywgbW9tZW50LklTT184NjAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0R1cmF0aW9uKSB7XG4gICAgICAgICAgbWluID0gbW9tZW50LmR1cmF0aW9uKHRoaXMubWludmFsQXNUZXh0KTtcbiAgICAgICAgICBpZiAoIW1vbWVudC5pc0R1cmF0aW9uKG1pbikpIHtcbiAgICAgICAgICAgIG1pbiA9IG1vbWVudC5kdXJhdGlvbigxLCAnc2Vjb25kcycpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWluO1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgb3IgZGF0ZXRpbWUgRmFjZXRzLCB0aGUgbWF4aW11bSB2YWx1ZS5cbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge251bWJlcnxkYXRldGltZX1cbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKi9cbiAgICBtYXh2YWw6IHtcbiAgICAgIGRlcHM6IFsnbWF4dmFsQXNUZXh0JywgJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXg7XG4gICAgICAgIGlmICh0aGlzLmlzQ29udGludW91cykge1xuICAgICAgICAgIG1heCA9IHBhcnNlRmxvYXQodGhpcy5tYXh2YWxBc1RleHQpO1xuICAgICAgICAgIGlmIChpc05hTihtYXgpKSB7XG4gICAgICAgICAgICBtYXggPSAxMDA7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEYXRldGltZSkge1xuICAgICAgICAgIG1heCA9IG1vbWVudCh0aGlzLm1heHZhbEFzVGV4dCwgbW9tZW50LklTT184NjAxKTtcbiAgICAgICAgICBpZiAoIW1heC5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIG1heCA9IG1vbWVudCgnMjAyMC0wMS0wMSAwMDowMCcsIG1vbWVudC5JU09fODYwMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEdXJhdGlvbikge1xuICAgICAgICAgIG1heCA9IG1vbWVudC5kdXJhdGlvbih0aGlzLm1heHZhbEFzVGV4dCk7XG4gICAgICAgICAgaWYgKCFtb21lbnQuaXNEdXJhdGlvbihtYXgpKSB7XG4gICAgICAgICAgICBtYXggPSBtb21lbnQuZHVyYXRpb24oMTAwLCAnc2Vjb25kcycpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWF4O1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgdHJhbnNmb3JtOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzQ29udGludW91cykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRpbnVvdXNUcmFuc2Zvcm07XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0NhdGVnb3JpYWwpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jYXRlZ29yaWFsVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEYXRldGltZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmRhdGV0aW1lVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEdXJhdGlvbikge1xuICAgICAgICAgIHJldHVybiB0aGlzLmR1cmF0aW9uVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNUZXh0KSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudGV4dFRyYW5zZm9ybTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmVycm9yKCdJbnZhbGlkIGZhY2V0Jyk7XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfVxuICB9LFxuICAvKipcbiAgICogc2V0TWluTWF4IHNldHMgdGhlIHJhbmdlIG9mIGEgY29udGludW91cyBvciB0aW1lIGZhY2V0XG4gICAqIEZvciBmYWNldHMgaW4gYSBkYXRhdmlldywgdGhlIG1pbmltdW0gaXMganVzdCB0aGUgbWluaW11bSBvZiB0aGUgZmFjZXQgb3ZlciBhbGwgYWN0aXZlIGRhdGFzZXRzLFxuICAgKiBhbmQgdGhlIHNhbWUgZm9yIHRoZSBtYXhpbXVtLlxuICAgKiBGb3IgZmFjZXRzIGluIGEgZGF0c2V0LCB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIGlzIGluIHRoZSBkYXRhc2V0IGRyaXZlci5cbiAgICpcbiAgICogQG1lbWJlcm9mISBGYWNldFxuICAgKi9cbiAgc2V0TWluTWF4OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIERhdGFzZXQgPSByZXF1aXJlKCcuL2RhdGFzZXQnKTtcbiAgICB2YXIgRGF0YXZpZXcgPSByZXF1aXJlKCcuL2RhdGF2aWV3Jyk7XG5cbiAgICB2YXIgYW5jZXN0b3IgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90O1xuXG4gICAgaWYgKGFuY2VzdG9yIGluc3RhbmNlb2YgRGF0YXZpZXcpIHtcbiAgICAgIC8vIEZhY2V0IC0+IEZhY2V0cyAtPiBEYXRhdmlldyAtPiBTcG90XG4gICAgICBzcG90ID0gdGhpcy5jb2xsZWN0aW9uLnBhcmVudC5wYXJlbnQ7XG4gICAgICBzcG90LnNldEZhY2V0TWluTWF4KHRoaXMpO1xuICAgIH0gZWxzZSBpZiAoYW5jZXN0b3IgaW5zdGFuY2VvZiBEYXRhc2V0KSB7XG4gICAgICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgICAgIHNwb3QgPSBhbmNlc3Rvci5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICAgIHNwb3QuZHJpdmVyLnNldE1pbk1heChhbmNlc3RvciwgdGhpcyk7XG4gICAgfVxuICB9LFxuICAvKipcbiAgICogc2V0Q2F0ZWdvcmllcyBmaW5kcyBmaW5kcyBhbGwgdmFsdWVzIG9uIGFuIG9yZGluYWwgKGNhdGVnb3JpYWwpIGF4aXNcbiAgICogVXBkYXRlcyB0aGUgY2F0ZWdvcmlhbFRyYW5zZm9ybSBvZiB0aGUgZmFjZXRcbiAgICogRm9yIGZhY2V0cyBpbiBhIGRhdGF2aWV3LCB0aGlzIGlzIHRoZSB1bmlvbiBvZiB0aGUgY2F0ZWdvcmllcyBvZiBmYWNldCBvdmVyIGFsbCBhY3RpdmUgZGF0YXNldHMuXG4gICAqIEZvciBmYWNldHMgaW4gYSBkYXRhc2V0LCB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIGlzIGluIHRoZSBkYXRhc2V0IGRyaXZlci5cbiAgICpcbiAgICogQG1lbWJlcm9mISBGYWNldFxuICAgKi9cbiAgc2V0Q2F0ZWdvcmllczogZnVuY3Rpb24gKCkge1xuICAgIHZhciBEYXRhc2V0ID0gcmVxdWlyZSgnLi9kYXRhc2V0Jyk7XG4gICAgdmFyIERhdGF2aWV3ID0gcmVxdWlyZSgnLi9kYXRhdmlldycpO1xuXG4gICAgdmFyIGFuY2VzdG9yID0gdGhpcy5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICB2YXIgc3BvdDtcblxuICAgIGlmIChhbmNlc3RvciBpbnN0YW5jZW9mIERhdGF2aWV3KSB7XG4gICAgICAvLyBGYWNldCAtPiBGYWNldHMgLT4gRGF0YXZpZXcgLT4gU3BvdFxuICAgICAgc3BvdCA9IHRoaXMuY29sbGVjdGlvbi5wYXJlbnQucGFyZW50O1xuICAgICAgc3BvdC5zZXRGYWNldENhdGVnb3JpZXModGhpcyk7XG4gICAgfSBlbHNlIGlmIChhbmNlc3RvciBpbnN0YW5jZW9mIERhdGFzZXQpIHtcbiAgICAgIC8vIEZhY2V0IC0+IEZhY2V0cyAtPiBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgICAgIHNwb3QgPSBhbmNlc3Rvci5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICAgIHNwb3QuZHJpdmVyLnNldENhdGVnb3JpZXMoYW5jZXN0b3IsIHRoaXMpO1xuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4d50\n")},5066:function(module,exports,__webpack_require__){eval("/**\n * A Dataview is a join of Datasets\n *\n * @class Dataview\n * @extends Base\n */\nvar Crossfilter = __webpack_require__(/*! crossfilter2 */ \"0352\"); // TODO: only for client side datasets\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Filters = __webpack_require__(/*! ./filter/collection */ \"7fa4\");\nvar Facets = __webpack_require__(/*! ./facet/collection */ \"51fb\");\n\nfunction getData () {\n  if (this.isPaused) {\n    return;\n  }\n  console.time('Get data');\n\n  var spot = this.parent;\n\n  return spot.driver.getData(this);\n}\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    /**\n     * Crossfilter instance, see [here](http://square.github.io/crossfilter/)\n     * used for client side data handling.\n     *\n     * @memberof! Dataset\n     */\n    this.crossfilter = new Crossfilter([]);\n    this.countGroup = this.crossfilter.groupAll().reduceCount();\n  },\n  props: {\n    /**\n     * Total number of datapoints in the current dataview\n     *\n     * @memberof! Dataview\n     * @readonly\n     * @type {number}\n     */\n    dataTotal: ['number', true, 0],\n    /**\n     * Number of datapoints that are currently selected\n     *\n     * @memberof! Dataview\n     * @readonly\n     * @type {number}\n     */\n    dataSelected: ['number', true, 0],\n    /**\n     * DatasetId's of active datasets\n     *\n     * @memberof! Dataview\n     * @type {String[]}\n     */\n    datasetIds: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    }\n  },\n  session: {\n    /**\n     * isPaused when true, calls to getAllData are ignored.\n     * This is useful to suppres calls to getData\n     * when adding and removing a number of filters at once.\n     * @memberof! Dataview\n     * @type {boolean}\n     */\n    isPaused: ['boolean', true, false]\n  },\n  collections: {\n    /**\n     * A Facet collection holding pre defined facets\n     *\n     * @memberof! Dataview\n     * @type {Facet[]}\n     */\n    facets: Facets,\n    /**\n     * A Filter collection holding all active filters on the dataview\n     *\n     * @memberof! Dataview\n     * @type {Filter[]}\n     */\n    filters: Filters\n  },\n  /**\n   * Pause the dataview. This means calls to getData are blocked.\n   * Useful when updating a lot of filters and you are not interested in the intermediate state.\n   *\n   * @memberof! Dataview\n   */\n  pause: function () {\n    this.isPaused = true;\n  },\n  /**\n   * Unpause the dataview.\n   *\n   * @memberof! Dataview\n   */\n  play: function () {\n    this.isPaused = false;\n  },\n\n  /**\n   * Get data for all filters linked to this dataview.\n   * When data has become available for a filter, a `newData` event is triggered on that filter.\n   *\n   * @memberof! Dataview\n   * @function\n   */\n  getData: getData\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTA2Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXZpZXcuanM/NGQ0YSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEEgRGF0YXZpZXcgaXMgYSBqb2luIG9mIERhdGFzZXRzXG4gKlxuICogQGNsYXNzIERhdGF2aWV3XG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBDcm9zc2ZpbHRlciA9IHJlcXVpcmUoJ2Nyb3NzZmlsdGVyMicpOyAvLyBUT0RPOiBvbmx5IGZvciBjbGllbnQgc2lkZSBkYXRhc2V0c1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG52YXIgRmlsdGVycyA9IHJlcXVpcmUoJy4vZmlsdGVyL2NvbGxlY3Rpb24nKTtcbnZhciBGYWNldHMgPSByZXF1aXJlKCcuL2ZhY2V0L2NvbGxlY3Rpb24nKTtcblxuZnVuY3Rpb24gZ2V0RGF0YSAoKSB7XG4gIGlmICh0aGlzLmlzUGF1c2VkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnNvbGUudGltZSgnR2V0IGRhdGEnKTtcblxuICB2YXIgc3BvdCA9IHRoaXMucGFyZW50O1xuXG4gIHJldHVybiBzcG90LmRyaXZlci5nZXREYXRhKHRoaXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VNb2RlbC5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gZmlyc3QgZG8gcGFyZW50IGNsYXNzIGluaXRpYWxpemF0aW9uXG4gICAgQmFzZU1vZGVsLnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICAvKipcbiAgICAgKiBDcm9zc2ZpbHRlciBpbnN0YW5jZSwgc2VlIFtoZXJlXShodHRwOi8vc3F1YXJlLmdpdGh1Yi5pby9jcm9zc2ZpbHRlci8pXG4gICAgICogdXNlZCBmb3IgY2xpZW50IHNpZGUgZGF0YSBoYW5kbGluZy5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqL1xuICAgIHRoaXMuY3Jvc3NmaWx0ZXIgPSBuZXcgQ3Jvc3NmaWx0ZXIoW10pO1xuICAgIHRoaXMuY291bnRHcm91cCA9IHRoaXMuY3Jvc3NmaWx0ZXIuZ3JvdXBBbGwoKS5yZWR1Y2VDb3VudCgpO1xuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRvdGFsIG51bWJlciBvZiBkYXRhcG9pbnRzIGluIHRoZSBjdXJyZW50IGRhdGF2aWV3XG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHJlYWRvbmx5XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBkYXRhVG90YWw6IFsnbnVtYmVyJywgdHJ1ZSwgMF0sXG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIGRhdGFwb2ludHMgdGhhdCBhcmUgY3VycmVudGx5IHNlbGVjdGVkXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHJlYWRvbmx5XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBkYXRhU2VsZWN0ZWQ6IFsnbnVtYmVyJywgdHJ1ZSwgMF0sXG4gICAgLyoqXG4gICAgICogRGF0YXNldElkJ3Mgb2YgYWN0aXZlIGRhdGFzZXRzXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge1N0cmluZ1tdfVxuICAgICAqL1xuICAgIGRhdGFzZXRJZHM6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBkZWZhdWx0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHNlc3Npb246IHtcbiAgICAvKipcbiAgICAgKiBpc1BhdXNlZCB3aGVuIHRydWUsIGNhbGxzIHRvIGdldEFsbERhdGEgYXJlIGlnbm9yZWQuXG4gICAgICogVGhpcyBpcyB1c2VmdWwgdG8gc3VwcHJlcyBjYWxscyB0byBnZXREYXRhXG4gICAgICogd2hlbiBhZGRpbmcgYW5kIHJlbW92aW5nIGEgbnVtYmVyIG9mIGZpbHRlcnMgYXQgb25jZS5cbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNQYXVzZWQ6IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXVxuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEEgRmFjZXQgY29sbGVjdGlvbiBob2xkaW5nIHByZSBkZWZpbmVkIGZhY2V0c1xuICAgICAqXG4gICAgICogQG1lbWJlcm9mISBEYXRhdmlld1xuICAgICAqIEB0eXBlIHtGYWNldFtdfVxuICAgICAqL1xuICAgIGZhY2V0czogRmFjZXRzLFxuICAgIC8qKlxuICAgICAqIEEgRmlsdGVyIGNvbGxlY3Rpb24gaG9sZGluZyBhbGwgYWN0aXZlIGZpbHRlcnMgb24gdGhlIGRhdGF2aWV3XG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge0ZpbHRlcltdfVxuICAgICAqL1xuICAgIGZpbHRlcnM6IEZpbHRlcnNcbiAgfSxcbiAgLyoqXG4gICAqIFBhdXNlIHRoZSBkYXRhdmlldy4gVGhpcyBtZWFucyBjYWxscyB0byBnZXREYXRhIGFyZSBibG9ja2VkLlxuICAgKiBVc2VmdWwgd2hlbiB1cGRhdGluZyBhIGxvdCBvZiBmaWx0ZXJzIGFuZCB5b3UgYXJlIG5vdCBpbnRlcmVzdGVkIGluIHRoZSBpbnRlcm1lZGlhdGUgc3RhdGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiEgRGF0YXZpZXdcbiAgICovXG4gIHBhdXNlOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5pc1BhdXNlZCA9IHRydWU7XG4gIH0sXG4gIC8qKlxuICAgKiBVbnBhdXNlIHRoZSBkYXRhdmlldy5cbiAgICpcbiAgICogQG1lbWJlcm9mISBEYXRhdmlld1xuICAgKi9cbiAgcGxheTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuaXNQYXVzZWQgPSBmYWxzZTtcbiAgfSxcblxuICAvKipcbiAgICogR2V0IGRhdGEgZm9yIGFsbCBmaWx0ZXJzIGxpbmtlZCB0byB0aGlzIGRhdGF2aWV3LlxuICAgKiBXaGVuIGRhdGEgaGFzIGJlY29tZSBhdmFpbGFibGUgZm9yIGEgZmlsdGVyLCBhIGBuZXdEYXRhYCBldmVudCBpcyB0cmlnZ2VyZWQgb24gdGhhdCBmaWx0ZXIuXG4gICAqXG4gICAqIEBtZW1iZXJvZiEgRGF0YXZpZXdcbiAgICogQGZ1bmN0aW9uXG4gICAqL1xuICBnZXREYXRhOiBnZXREYXRhXG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5066\n")},"51fb":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Facet = __webpack_require__(/*! ../facet */ \"4d50\");\n\nmodule.exports = Collection.extend({\n  model: Facet,\n  mainIndex: 'id',\n  indexes: ['name'],\n  session: {\n    needle: ['string', true, ''], // search string used on the Facet page\n    showSearch: ['boolean', true, false] // show/hide the search bar on the Facet page\n  },\n  comparator: function (left, right) {\n    return left.name.localeCompare(right.name);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTFmYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29sbGVjdGlvbi5qcz84ZWU5Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBDb2xsZWN0aW9uID0gcmVxdWlyZSgnYW1wZXJzYW5kLWNvbGxlY3Rpb24nKTtcbnZhciBGYWNldCA9IHJlcXVpcmUoJy4uL2ZhY2V0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogRmFjZXQsXG4gIG1haW5JbmRleDogJ2lkJyxcbiAgaW5kZXhlczogWyduYW1lJ10sXG4gIHNlc3Npb246IHtcbiAgICBuZWVkbGU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLCAvLyBzZWFyY2ggc3RyaW5nIHVzZWQgb24gdGhlIEZhY2V0IHBhZ2VcbiAgICBzaG93U2VhcmNoOiBbJ2Jvb2xlYW4nLCB0cnVlLCBmYWxzZV0gLy8gc2hvdy9oaWRlIHRoZSBzZWFyY2ggYmFyIG9uIHRoZSBGYWNldCBwYWdlXG4gIH0sXG4gIGNvbXBhcmF0b3I6IGZ1bmN0aW9uIChsZWZ0LCByaWdodCkge1xuICAgIHJldHVybiBsZWZ0Lm5hbWUubG9jYWxlQ29tcGFyZShyaWdodC5uYW1lKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///51fb\n")},"544d":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Dataset = __webpack_require__(/*! ../dataset */ \"545a\");\n\nmodule.exports = Collection.extend({\n  mainIndex: 'id',\n  indexes: ['name'],\n  model: Dataset\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQ0ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXNldC9jb2xsZWN0aW9uLmpzPzkxZDkiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIENvbGxlY3Rpb24gPSByZXF1aXJlKCdhbXBlcnNhbmQtY29sbGVjdGlvbicpO1xudmFyIERhdGFzZXQgPSByZXF1aXJlKCcuLi9kYXRhc2V0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtYWluSW5kZXg6ICdpZCcsXG4gIGluZGV4ZXM6IFsnbmFtZSddLFxuICBtb2RlbDogRGF0YXNldFxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///544d\n")},"545a":function(module,exports,__webpack_require__){eval("/**\n * @class Dataset\n * @extends Base\n */\nvar Crossfilter = __webpack_require__(/*! crossfilter2 */ \"0352\"); // TODO: only for client side datasets\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Facets = __webpack_require__(/*! ./facet/collection */ \"51fb\");\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    /**\n     * Crossfilter instance, see [here](http://square.github.io/crossfilter/)\n     * used for client side data handling.\n     *\n     * @memberof! Dataset\n     */\n    this.crossfilter = new Crossfilter([]);\n    this.countGroup = this.crossfilter.groupAll().reduceCount();\n  },\n  props: {\n    /**\n     * Name of the dataset\n     * @memberof! Dataset\n     * @type {string}\n     */\n    name: {\n      type: 'string',\n      required: true,\n      default: 'Name'\n    },\n    /**\n     * URL, fi. to paper, dataset owner, etc.\n     * @memberof! Dataset\n     * @type {string}\n     */\n    URL: {\n      type: 'string',\n      required: true,\n      default: 'URL'\n    },\n    /**\n     * Database table name for server datasets\n     * @memberof! Dataset\n     * @type {string}\n     */\n    databaseTable: {\n      type: 'string',\n      default: ''\n    },\n    /**\n     * Short description of the dataset\n     * @memberof! Dataset\n     * @type {string}\n     */\n    description: {\n      type: 'string',\n      required: true,\n      default: 'Description'\n    },\n    /**\n     * If dataset is part of the current session\n     * @memberof! Dataset\n     * @type {boolean}\n     */\n    isActive: {\n      type: 'boolean',\n      required: true,\n      default: false\n    }\n  },\n  session: {\n    /**\n     * For searching through datasets URL and description.\n     * True if this dataset matches the search paramters.\n     */\n    show: {\n      type: 'boolean',\n      required: true,\n      default: true\n    },\n    data: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    }\n  },\n  collections: {\n    /**\n     * A Facet collection holding pre defined facets\n     * @memberof! Dataset\n     * @type {Facet[]}\n     */\n    facets: Facets\n  },\n  scan: function () {\n    // Dataset -> Datasets -> spot\n    var spot = this.collection.parent;\n\n    // clear all existing facets\n    this.facets.reset();\n\n    spot.driver.scan(this);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQ1YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXNldC5qcz9lYTcwIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGNsYXNzIERhdGFzZXRcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xudmFyIENyb3NzZmlsdGVyID0gcmVxdWlyZSgnY3Jvc3NmaWx0ZXIyJyk7IC8vIFRPRE86IG9ubHkgZm9yIGNsaWVudCBzaWRlIGRhdGFzZXRzXG52YXIgQmFzZU1vZGVsID0gcmVxdWlyZSgnLi91dGlsL2Jhc2UnKTtcbnZhciBGYWNldHMgPSByZXF1aXJlKCcuL2ZhY2V0L2NvbGxlY3Rpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlTW9kZWwuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIC8vIGZpcnN0IGRvIHBhcmVudCBjbGFzcyBpbml0aWFsaXphdGlvblxuICAgIEJhc2VNb2RlbC5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgLyoqXG4gICAgICogQ3Jvc3NmaWx0ZXIgaW5zdGFuY2UsIHNlZSBbaGVyZV0oaHR0cDovL3NxdWFyZS5naXRodWIuaW8vY3Jvc3NmaWx0ZXIvKVxuICAgICAqIHVzZWQgZm9yIGNsaWVudCBzaWRlIGRhdGEgaGFuZGxpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKi9cbiAgICB0aGlzLmNyb3NzZmlsdGVyID0gbmV3IENyb3NzZmlsdGVyKFtdKTtcbiAgICB0aGlzLmNvdW50R3JvdXAgPSB0aGlzLmNyb3NzZmlsdGVyLmdyb3VwQWxsKCkucmVkdWNlQ291bnQoKTtcbiAgfSxcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBOYW1lIG9mIHRoZSBkYXRhc2V0XG4gICAgICogQG1lbWJlcm9mISBEYXRhc2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBuYW1lOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ05hbWUnXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBVUkwsIGZpLiB0byBwYXBlciwgZGF0YXNldCBvd25lciwgZXRjLlxuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgVVJMOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ1VSTCdcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIERhdGFiYXNlIHRhYmxlIG5hbWUgZm9yIHNlcnZlciBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgZGF0YWJhc2VUYWJsZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZWZhdWx0OiAnJ1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogU2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIGRhdGFzZXRcbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRlc2NyaXB0aW9uOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ0Rlc2NyaXB0aW9uJ1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogSWYgZGF0YXNldCBpcyBwYXJ0IG9mIHRoZSBjdXJyZW50IHNlc3Npb25cbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0FjdGl2ZToge1xuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiBmYWxzZVxuICAgIH1cbiAgfSxcbiAgc2Vzc2lvbjoge1xuICAgIC8qKlxuICAgICAqIEZvciBzZWFyY2hpbmcgdGhyb3VnaCBkYXRhc2V0cyBVUkwgYW5kIGRlc2NyaXB0aW9uLlxuICAgICAqIFRydWUgaWYgdGhpcyBkYXRhc2V0IG1hdGNoZXMgdGhlIHNlYXJjaCBwYXJhbXRlcnMuXG4gICAgICovXG4gICAgc2hvdzoge1xuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiB0cnVlXG4gICAgfSxcbiAgICBkYXRhOiB7XG4gICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEEgRmFjZXQgY29sbGVjdGlvbiBob2xkaW5nIHByZSBkZWZpbmVkIGZhY2V0c1xuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtGYWNldFtdfVxuICAgICAqL1xuICAgIGZhY2V0czogRmFjZXRzXG4gIH0sXG4gIHNjYW46IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IHNwb3RcbiAgICB2YXIgc3BvdCA9IHRoaXMuY29sbGVjdGlvbi5wYXJlbnQ7XG5cbiAgICAvLyBjbGVhciBhbGwgZXhpc3RpbmcgZmFjZXRzXG4gICAgdGhpcy5mYWNldHMucmVzZXQoKTtcblxuICAgIHNwb3QuZHJpdmVyLnNjYW4odGhpcyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///545a\n")},"58ab":function(module,exports,__webpack_require__){eval('\nmodule.exports = __webpack_require__(/*! ./socket */ "0112");\n\n/**\n * Exports parser\n *\n * @api public\n *\n */\nmodule.exports.parser = __webpack_require__(/*! engine.io-parser */ "aa6c");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNThhYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvaW5kZXguanM/ZWViYiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9zb2NrZXQnKTtcblxuLyoqXG4gKiBFeHBvcnRzIHBhcnNlclxuICpcbiAqIEBhcGkgcHVibGljXG4gKlxuICovXG5tb2R1bGUuZXhwb3J0cy5wYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///58ab\n')},"5a80":function(module,exports,__webpack_require__){eval("/**\n * ContinuousTransfrom defines a transformation on continuous (nummerical) data.\n * Currently linear interpolation between a set of control points is implemented.\n *\n * @class ContinuousTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nvar ControlPoint = __webpack_require__(/*! ./control-point */ \"09c5\");\nvar ControlPoints = Collection.extend({\n  model: ControlPoint\n});\n\n/**\n * Apply piecewise linear transformation\n * The function is constant outside the range spanned by the control points;\n * there it is set to value of the first, or the last, control points.\n *\n * @function\n * @memberof! ContinuousTransform\n * @param {number} x\n * @returns {number} fx\n */\nfunction transform (cps, x) {\n  if (x === misval) {\n    return misval;\n  }\n\n  var ncps = cps.models.length;\n  if (x <= cps.models[0].x) {\n    // outside range on left side\n    return cps.models[0].fx;\n  } else if (x >= cps.models[ncps - 1].x) {\n    // outside range on right side\n    return cps.models[ncps - 1].fx;\n  } else {\n    // inside range\n    var i = 0;\n    while (x > cps.models[i].x) {\n      i = i + 1;\n    }\n\n    // linear interpolate between fx_i and fx_(i+1)\n    var xm = cps.models[i].x;\n    var xp = cps.models[i + 1].x;\n    var fxm = cps.models[i].fx;\n    var fxp = cps.models[i + 1].fx;\n    if (xp === xm) {\n      return 0.5 * (fxm + fxp);\n    } else {\n      return fxm + (x - xm) * (fxp - fxm) / (xp - xm);\n    }\n  }\n}\n\n/**\n * The inverse of the transform\n *\n * @function\n * @memberof! ContinuousTransform\n * @param {number} fx\n * @returns {number} x\n */\nfunction inverse (cps, fx) {\n  if (fx === misval) {\n    return misval;\n  }\n\n  var ncps = cps.models.length;\n  if (fx <= cps.models[0].fx) {\n    // outside range on left side\n    return cps.models[0].x;\n  } else if (fx >= cps.models[ncps - 1].fx) {\n    // outside range on right side\n    return cps.models[ncps - 1].x;\n  } else {\n    // inside range\n    var i = 0;\n    while (fx > cps.models[i].fx) {\n      i = i + 1;\n    }\n\n    // linear interpolate between fx_i and fx_(i+1)\n    var xm = cps.models[i].x;\n    var xp = cps.models[i + 1].x;\n    var fxm = cps.models[i].fx;\n    var fxp = cps.models[i + 1].fx;\n    if (fxp === fxm) {\n      return 0.5 * (xm + xp);\n    } else {\n      return xm + (fx - fxm) * (xp - xm) / (fxp - fxm);\n    }\n  }\n}\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * The type of continuous transform, can be none, or percentiles\n     * Use isNone, or isPercentiles, check for transform type\n     * @memberof! ContinuousTransform\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'none',\n      values: ['none', 'percentiles']\n    },\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'continuous',\n      values: ['continuous']\n    }\n  },\n  derived: {\n    isNone: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'none';\n      }\n    },\n    isPercentiles: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'percentiles';\n      }\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! ContinuousTransform\n     */\n    transformedMin: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isPercentiles) {\n          return 0;\n        } else if (this.isNone) {\n          return this.parent.minval;\n        } else {\n          console.error('Invalid continuous transform');\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! ContinuousTransform\n     */\n    transformedMax: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isPercentiles) {\n          return 100;\n        } else if (this.isNone) {\n          return this.parent.maxval;\n        } else {\n          console.error('Invalid continuous transform');\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! ContinuousTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! ContinuousTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n  collections: {\n    cps: ControlPoints\n  },\n  transform: function (x) {\n    return transform(this.cps, x);\n  },\n  inverse: function (fx) {\n    return inverse(this.cps, fx);\n  },\n  reset: function () {\n    this.type = 'none';\n    this.cps.reset();\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNWE4MC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29udGludW91cy10cmFuc2Zvcm0uanM/YzgwOSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbnRpbnVvdXNUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNvbnRpbnVvdXMgKG51bW1lcmljYWwpIGRhdGEuXG4gKiBDdXJyZW50bHkgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiBhIHNldCBvZiBjb250cm9sIHBvaW50cyBpcyBpbXBsZW1lbnRlZC5cbiAqXG4gKiBAY2xhc3MgQ29udGludW91c1RyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBDb2xsZWN0aW9uID0gcmVxdWlyZSgnYW1wZXJzYW5kLWNvbGxlY3Rpb24nKTtcbnZhciBtaXN2YWwgPSByZXF1aXJlKCcuLi91dGlsL21pc3ZhbCcpO1xuXG52YXIgQ29udHJvbFBvaW50ID0gcmVxdWlyZSgnLi9jb250cm9sLXBvaW50Jyk7XG52YXIgQ29udHJvbFBvaW50cyA9IENvbGxlY3Rpb24uZXh0ZW5kKHtcbiAgbW9kZWw6IENvbnRyb2xQb2ludFxufSk7XG5cbi8qKlxuICogQXBwbHkgcGllY2V3aXNlIGxpbmVhciB0cmFuc2Zvcm1hdGlvblxuICogVGhlIGZ1bmN0aW9uIGlzIGNvbnN0YW50IG91dHNpZGUgdGhlIHJhbmdlIHNwYW5uZWQgYnkgdGhlIGNvbnRyb2wgcG9pbnRzO1xuICogdGhlcmUgaXQgaXMgc2V0IHRvIHZhbHVlIG9mIHRoZSBmaXJzdCwgb3IgdGhlIGxhc3QsIGNvbnRyb2wgcG9pbnRzLlxuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mISBDb250aW51b3VzVHJhbnNmb3JtXG4gKiBAcGFyYW0ge251bWJlcn0geFxuICogQHJldHVybnMge251bWJlcn0gZnhcbiAqL1xuZnVuY3Rpb24gdHJhbnNmb3JtIChjcHMsIHgpIHtcbiAgaWYgKHggPT09IG1pc3ZhbCkge1xuICAgIHJldHVybiBtaXN2YWw7XG4gIH1cblxuICB2YXIgbmNwcyA9IGNwcy5tb2RlbHMubGVuZ3RoO1xuICBpZiAoeCA8PSBjcHMubW9kZWxzWzBdLngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIGxlZnQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzWzBdLmZ4O1xuICB9IGVsc2UgaWYgKHggPj0gY3BzLm1vZGVsc1tuY3BzIC0gMV0ueCkge1xuICAgIC8vIG91dHNpZGUgcmFuZ2Ugb24gcmlnaHQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzW25jcHMgLSAxXS5meDtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbnNpZGUgcmFuZ2VcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKHggPiBjcHMubW9kZWxzW2ldLngpIHtcbiAgICAgIGkgPSBpICsgMTtcbiAgICB9XG5cbiAgICAvLyBsaW5lYXIgaW50ZXJwb2xhdGUgYmV0d2VlbiBmeF9pIGFuZCBmeF8oaSsxKVxuICAgIHZhciB4bSA9IGNwcy5tb2RlbHNbaV0ueDtcbiAgICB2YXIgeHAgPSBjcHMubW9kZWxzW2kgKyAxXS54O1xuICAgIHZhciBmeG0gPSBjcHMubW9kZWxzW2ldLmZ4O1xuICAgIHZhciBmeHAgPSBjcHMubW9kZWxzW2kgKyAxXS5meDtcbiAgICBpZiAoeHAgPT09IHhtKSB7XG4gICAgICByZXR1cm4gMC41ICogKGZ4bSArIGZ4cCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmeG0gKyAoeCAtIHhtKSAqIChmeHAgLSBmeG0pIC8gKHhwIC0geG0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoZSBpbnZlcnNlIG9mIHRoZSB0cmFuc2Zvcm1cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICogQHBhcmFtIHtudW1iZXJ9IGZ4XG4gKiBAcmV0dXJucyB7bnVtYmVyfSB4XG4gKi9cbmZ1bmN0aW9uIGludmVyc2UgKGNwcywgZngpIHtcbiAgaWYgKGZ4ID09PSBtaXN2YWwpIHtcbiAgICByZXR1cm4gbWlzdmFsO1xuICB9XG5cbiAgdmFyIG5jcHMgPSBjcHMubW9kZWxzLmxlbmd0aDtcbiAgaWYgKGZ4IDw9IGNwcy5tb2RlbHNbMF0uZngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIGxlZnQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzWzBdLng7XG4gIH0gZWxzZSBpZiAoZnggPj0gY3BzLm1vZGVsc1tuY3BzIC0gMV0uZngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIHJpZ2h0IHNpZGVcbiAgICByZXR1cm4gY3BzLm1vZGVsc1tuY3BzIC0gMV0ueDtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbnNpZGUgcmFuZ2VcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKGZ4ID4gY3BzLm1vZGVsc1tpXS5meCkge1xuICAgICAgaSA9IGkgKyAxO1xuICAgIH1cblxuICAgIC8vIGxpbmVhciBpbnRlcnBvbGF0ZSBiZXR3ZWVuIGZ4X2kgYW5kIGZ4XyhpKzEpXG4gICAgdmFyIHhtID0gY3BzLm1vZGVsc1tpXS54O1xuICAgIHZhciB4cCA9IGNwcy5tb2RlbHNbaSArIDFdLng7XG4gICAgdmFyIGZ4bSA9IGNwcy5tb2RlbHNbaV0uZng7XG4gICAgdmFyIGZ4cCA9IGNwcy5tb2RlbHNbaSArIDFdLmZ4O1xuICAgIGlmIChmeHAgPT09IGZ4bSkge1xuICAgICAgcmV0dXJuIDAuNSAqICh4bSArIHhwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHhtICsgKGZ4IC0gZnhtKSAqICh4cCAtIHhtKSAvIChmeHAgLSBmeG0pO1xuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEFtcGVyc2FuZE1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgY29udGludW91cyB0cmFuc2Zvcm0sIGNhbiBiZSBub25lLCBvciBwZXJjZW50aWxlc1xuICAgICAqIFVzZSBpc05vbmUsIG9yIGlzUGVyY2VudGlsZXMsIGNoZWNrIGZvciB0cmFuc2Zvcm0gdHlwZVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnbm9uZScsXG4gICAgICB2YWx1ZXM6IFsnbm9uZScsICdwZXJjZW50aWxlcyddXG4gICAgfSxcbiAgICB0cmFuc2Zvcm1lZFR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnY29udGludW91cycsXG4gICAgICB2YWx1ZXM6IFsnY29udGludW91cyddXG4gICAgfVxuICB9LFxuICBkZXJpdmVkOiB7XG4gICAgaXNOb25lOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdub25lJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzUGVyY2VudGlsZXM6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ3BlcmNlbnRpbGVzJztcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1pbjoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5pc1BlcmNlbnRpbGVzKSB7XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc05vbmUpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQubWludmFsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgY29udGludW91cyB0cmFuc2Zvcm0nKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWF4OiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUGVyY2VudGlsZXMpIHtcbiAgICAgICAgICByZXR1cm4gMTAwO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNOb25lKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50Lm1heHZhbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdJbnZhbGlkIGNvbnRpbnVvdXMgdHJhbnNmb3JtJyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkTWluJywgJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1pbnZhbCA9IHRoaXMudHJhbnNmb3JtZWRNaW47XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiBtaW52YWwuZm9ybWF0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1heEFzVGV4dDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZE1heCcsICd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXh2YWwgPSB0aGlzLnRyYW5zZm9ybWVkTWF4O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLmZvcm1hdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH1cbiAgfSxcbiAgY29sbGVjdGlvbnM6IHtcbiAgICBjcHM6IENvbnRyb2xQb2ludHNcbiAgfSxcbiAgdHJhbnNmb3JtOiBmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiB0cmFuc2Zvcm0odGhpcy5jcHMsIHgpO1xuICB9LFxuICBpbnZlcnNlOiBmdW5jdGlvbiAoZngpIHtcbiAgICByZXR1cm4gaW52ZXJzZSh0aGlzLmNwcywgZngpO1xuICB9LFxuICByZXNldDogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMudHlwZSA9ICdub25lJztcbiAgICB0aGlzLmNwcy5yZXNldCgpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5a80\n")},6176:function(module,exports){eval("module.exports = Array.isArray || function (arr) {\n  return Object.prototype.toString.call(arr) == '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjE3Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcz8xYjA4Il0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6176\n")},"636d":function(module,exports){eval("\n/**\n * Expose `Emitter`.\n */\n\nmodule.exports = Emitter;\n\n/**\n * Initialize a new `Emitter`.\n *\n * @api public\n */\n\nfunction Emitter(obj) {\n  if (obj) return mixin(obj);\n};\n\n/**\n * Mixin the emitter properties.\n *\n * @param {Object} obj\n * @return {Object}\n * @api private\n */\n\nfunction mixin(obj) {\n  for (var key in Emitter.prototype) {\n    obj[key] = Emitter.prototype[key];\n  }\n  return obj;\n}\n\n/**\n * Listen on the given `event` with `fn`.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.on =\nEmitter.prototype.addEventListener = function(event, fn){\n  this._callbacks = this._callbacks || {};\n  (this._callbacks[event] = this._callbacks[event] || [])\n    .push(fn);\n  return this;\n};\n\n/**\n * Adds an `event` listener that will be invoked a single\n * time then automatically removed.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.once = function(event, fn){\n  var self = this;\n  this._callbacks = this._callbacks || {};\n\n  function on() {\n    self.off(event, on);\n    fn.apply(this, arguments);\n  }\n\n  on.fn = fn;\n  this.on(event, on);\n  return this;\n};\n\n/**\n * Remove the given callback for `event` or all\n * registered callbacks.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.off =\nEmitter.prototype.removeListener =\nEmitter.prototype.removeAllListeners =\nEmitter.prototype.removeEventListener = function(event, fn){\n  this._callbacks = this._callbacks || {};\n\n  // all\n  if (0 == arguments.length) {\n    this._callbacks = {};\n    return this;\n  }\n\n  // specific event\n  var callbacks = this._callbacks[event];\n  if (!callbacks) return this;\n\n  // remove all handlers\n  if (1 == arguments.length) {\n    delete this._callbacks[event];\n    return this;\n  }\n\n  // remove specific handler\n  var cb;\n  for (var i = 0; i < callbacks.length; i++) {\n    cb = callbacks[i];\n    if (cb === fn || cb.fn === fn) {\n      callbacks.splice(i, 1);\n      break;\n    }\n  }\n  return this;\n};\n\n/**\n * Emit `event` with the given args.\n *\n * @param {String} event\n * @param {Mixed} ...\n * @return {Emitter}\n */\n\nEmitter.prototype.emit = function(event){\n  this._callbacks = this._callbacks || {};\n  var args = [].slice.call(arguments, 1)\n    , callbacks = this._callbacks[event];\n\n  if (callbacks) {\n    callbacks = callbacks.slice(0);\n    for (var i = 0, len = callbacks.length; i < len; ++i) {\n      callbacks[i].apply(this, args);\n    }\n  }\n\n  return this;\n};\n\n/**\n * Return array of callbacks for `event`.\n *\n * @param {String} event\n * @return {Array}\n * @api public\n */\n\nEmitter.prototype.listeners = function(event){\n  this._callbacks = this._callbacks || {};\n  return this._callbacks[event] || [];\n};\n\n/**\n * Check if this emitter has `event` handlers.\n *\n * @param {String} event\n * @return {Boolean}\n * @api public\n */\n\nEmitter.prototype.hasListeners = function(event){\n  return !! this.listeners(event).length;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjM2ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanM/ZWVlMiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogRXhwb3NlIGBFbWl0dGVyYC5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVtaXR0ZXI7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgRW1pdHRlcmAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBFbWl0dGVyKG9iaikge1xuICBpZiAob2JqKSByZXR1cm4gbWl4aW4ob2JqKTtcbn07XG5cbi8qKlxuICogTWl4aW4gdGhlIGVtaXR0ZXIgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBtaXhpbihvYmopIHtcbiAgZm9yICh2YXIga2V5IGluIEVtaXR0ZXIucHJvdG90eXBlKSB7XG4gICAgb2JqW2tleV0gPSBFbWl0dGVyLnByb3RvdHlwZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbiA9XG5FbWl0dGVyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICAodGhpcy5fY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuX2NhbGxiYWNrc1tldmVudF0gfHwgW10pXG4gICAgLnB1c2goZm4pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXG4gKiB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICBmdW5jdGlvbiBvbigpIHtcbiAgICBzZWxmLm9mZihldmVudCwgb24pO1xuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBvbi5mbiA9IGZuO1xuICB0aGlzLm9uKGV2ZW50LCBvbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICogcmVnaXN0ZXJlZCBjYWxsYmFja3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub2ZmID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuXG4gIC8vIGFsbFxuICBpZiAoMCA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgdGhpcy5fY2FsbGJhY2tzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzcGVjaWZpYyBldmVudFxuICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcbiAgaWYgKCFjYWxsYmFja3MpIHJldHVybiB0aGlzO1xuXG4gIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcbiAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcbiAgdmFyIGNiO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgIGNiID0gY2FsbGJhY2tzW2ldO1xuICAgIGlmIChjYiA9PT0gZm4gfHwgY2IuZm4gPT09IGZuKSB7XG4gICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7TWl4ZWR9IC4uLlxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oZXZlbnQpe1xuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG4gIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpXG4gICAgLCBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuXG4gIGlmIChjYWxsYmFja3MpIHtcbiAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgY2FsbGJhY2tzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYXJyYXkgb2YgY2FsbGJhY2tzIGZvciBgZXZlbnRgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7QXJyYXl9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XSB8fCBbXTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhpcyBlbWl0dGVyIGhhcyBgZXZlbnRgIGhhbmRsZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuaGFzTGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xuICByZXR1cm4gISEgdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///636d\n")},"6b20":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar Transport = __webpack_require__(/*! ../transport */ \"0d97\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar yeast = __webpack_require__(/*! yeast */ \"c16d\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:websocket');\nvar BrowserWebSocket = global.WebSocket || global.MozWebSocket;\nvar NodeWebSocket;\nif (typeof window === 'undefined') {\n  try {\n    NodeWebSocket = __webpack_require__(/*! ws */ 1);\n  } catch (e) { }\n}\n\n/**\n * Get either the `WebSocket` or `MozWebSocket` globals\n * in the browser or try to resolve WebSocket-compatible\n * interface exposed by `ws` for Node-like environment.\n */\n\nvar WebSocket = BrowserWebSocket;\nif (!WebSocket && typeof window === 'undefined') {\n  WebSocket = NodeWebSocket;\n}\n\n/**\n * Module exports.\n */\n\nmodule.exports = WS;\n\n/**\n * WebSocket transport constructor.\n *\n * @api {Object} connection options\n * @api public\n */\n\nfunction WS (opts) {\n  var forceBase64 = (opts && opts.forceBase64);\n  if (forceBase64) {\n    this.supportsBinary = false;\n  }\n  this.perMessageDeflate = opts.perMessageDeflate;\n  this.usingBrowserWebSocket = BrowserWebSocket && !opts.forceNode;\n  if (!this.usingBrowserWebSocket) {\n    WebSocket = NodeWebSocket;\n  }\n  Transport.call(this, opts);\n}\n\n/**\n * Inherits from Transport.\n */\n\ninherit(WS, Transport);\n\n/**\n * Transport name.\n *\n * @api public\n */\n\nWS.prototype.name = 'websocket';\n\n/*\n * WebSockets support binary\n */\n\nWS.prototype.supportsBinary = true;\n\n/**\n * Opens socket.\n *\n * @api private\n */\n\nWS.prototype.doOpen = function () {\n  if (!this.check()) {\n    // let probe timeout\n    return;\n  }\n\n  var uri = this.uri();\n  var protocols = void (0);\n  var opts = {\n    agent: this.agent,\n    perMessageDeflate: this.perMessageDeflate\n  };\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n  if (this.extraHeaders) {\n    opts.headers = this.extraHeaders;\n  }\n  if (this.localAddress) {\n    opts.localAddress = this.localAddress;\n  }\n\n  try {\n    this.ws = this.usingBrowserWebSocket ? new WebSocket(uri) : new WebSocket(uri, protocols, opts);\n  } catch (err) {\n    return this.emit('error', err);\n  }\n\n  if (this.ws.binaryType === undefined) {\n    this.supportsBinary = false;\n  }\n\n  if (this.ws.supports && this.ws.supports.binary) {\n    this.supportsBinary = true;\n    this.ws.binaryType = 'nodebuffer';\n  } else {\n    this.ws.binaryType = 'arraybuffer';\n  }\n\n  this.addEventListeners();\n};\n\n/**\n * Adds event listeners to the socket\n *\n * @api private\n */\n\nWS.prototype.addEventListeners = function () {\n  var self = this;\n\n  this.ws.onopen = function () {\n    self.onOpen();\n  };\n  this.ws.onclose = function () {\n    self.onClose();\n  };\n  this.ws.onmessage = function (ev) {\n    self.onData(ev.data);\n  };\n  this.ws.onerror = function (e) {\n    self.onError('websocket error', e);\n  };\n};\n\n/**\n * Writes data to socket.\n *\n * @param {Array} array of packets.\n * @api private\n */\n\nWS.prototype.write = function (packets) {\n  var self = this;\n  this.writable = false;\n\n  // encodePacket efficient as it uses WS framing\n  // no need for encodePayload\n  var total = packets.length;\n  for (var i = 0, l = total; i < l; i++) {\n    (function (packet) {\n      parser.encodePacket(packet, self.supportsBinary, function (data) {\n        if (!self.usingBrowserWebSocket) {\n          // always create a new object (GH-437)\n          var opts = {};\n          if (packet.options) {\n            opts.compress = packet.options.compress;\n          }\n\n          if (self.perMessageDeflate) {\n            var len = 'string' === typeof data ? global.Buffer.byteLength(data) : data.length;\n            if (len < self.perMessageDeflate.threshold) {\n              opts.compress = false;\n            }\n          }\n        }\n\n        // Sometimes the websocket has already been closed but the browser didn't\n        // have a chance of informing us about it yet, in that case send will\n        // throw an error\n        try {\n          if (self.usingBrowserWebSocket) {\n            // TypeError is thrown when passing the second argument on Safari\n            self.ws.send(data);\n          } else {\n            self.ws.send(data, opts);\n          }\n        } catch (e) {\n          debug('websocket closed before onclose event');\n        }\n\n        --total || done();\n      });\n    })(packets[i]);\n  }\n\n  function done () {\n    self.emit('flush');\n\n    // fake drain\n    // defer to next tick to allow Socket to clear writeBuffer\n    setTimeout(function () {\n      self.writable = true;\n      self.emit('drain');\n    }, 0);\n  }\n};\n\n/**\n * Called upon close\n *\n * @api private\n */\n\nWS.prototype.onClose = function () {\n  Transport.prototype.onClose.call(this);\n};\n\n/**\n * Closes socket.\n *\n * @api private\n */\n\nWS.prototype.doClose = function () {\n  if (typeof this.ws !== 'undefined') {\n    this.ws.close();\n  }\n};\n\n/**\n * Generates uri for connection.\n *\n * @api private\n */\n\nWS.prototype.uri = function () {\n  var query = this.query || {};\n  var schema = this.secure ? 'wss' : 'ws';\n  var port = '';\n\n  // avoid port if default for schema\n  if (this.port && (('wss' === schema && Number(this.port) !== 443) ||\n    ('ws' === schema && Number(this.port) !== 80))) {\n    port = ':' + this.port;\n  }\n\n  // append timestamp to URI\n  if (this.timestampRequests) {\n    query[this.timestampParam] = yeast();\n  }\n\n  // communicate binary support capabilities\n  if (!this.supportsBinary) {\n    query.b64 = 1;\n  }\n\n  query = parseqs.encode(query);\n\n  // prepend ? to query\n  if (query.length) {\n    query = '?' + query;\n  }\n\n  var ipv6 = this.hostname.indexOf(':') !== -1;\n  return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;\n};\n\n/**\n * Feature detection for WebSocket.\n *\n * @return {Boolean} whether this transport is available.\n * @api public\n */\n\nWS.prototype.check = function () {\n  return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNmIyMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy93ZWJzb2NrZXQuanM/ZGI4MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIFRyYW5zcG9ydCA9IHJlcXVpcmUoJy4uL3RyYW5zcG9ydCcpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBwYXJzZXFzID0gcmVxdWlyZSgncGFyc2VxcycpO1xudmFyIGluaGVyaXQgPSByZXF1aXJlKCdjb21wb25lbnQtaW5oZXJpdCcpO1xudmFyIHllYXN0ID0gcmVxdWlyZSgneWVhc3QnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ2VuZ2luZS5pby1jbGllbnQ6d2Vic29ja2V0Jyk7XG52YXIgQnJvd3NlcldlYlNvY2tldCA9IGdsb2JhbC5XZWJTb2NrZXQgfHwgZ2xvYmFsLk1veldlYlNvY2tldDtcbnZhciBOb2RlV2ViU29ja2V0O1xuaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gIHRyeSB7XG4gICAgTm9kZVdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG4gIH0gY2F0Y2ggKGUpIHsgfVxufVxuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxudmFyIFdlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQ7XG5pZiAoIVdlYlNvY2tldCAmJiB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICBXZWJTb2NrZXQgPSBOb2RlV2ViU29ja2V0O1xufVxuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gV1M7XG5cbi8qKlxuICogV2ViU29ja2V0IHRyYW5zcG9ydCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHtPYmplY3R9IGNvbm5lY3Rpb24gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBXUyAob3B0cykge1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIHRoaXMucGVyTWVzc2FnZURlZmxhdGUgPSBvcHRzLnBlck1lc3NhZ2VEZWZsYXRlO1xuICB0aGlzLnVzaW5nQnJvd3NlcldlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQgJiYgIW9wdHMuZm9yY2VOb2RlO1xuICBpZiAoIXRoaXMudXNpbmdCcm93c2VyV2ViU29ja2V0KSB7XG4gICAgV2ViU29ja2V0ID0gTm9kZVdlYlNvY2tldDtcbiAgfVxuICBUcmFuc3BvcnQuY2FsbCh0aGlzLCBvcHRzKTtcbn1cblxuLyoqXG4gKiBJbmhlcml0cyBmcm9tIFRyYW5zcG9ydC5cbiAqL1xuXG5pbmhlcml0KFdTLCBUcmFuc3BvcnQpO1xuXG4vKipcbiAqIFRyYW5zcG9ydCBuYW1lLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuV1MucHJvdG90eXBlLm5hbWUgPSAnd2Vic29ja2V0JztcblxuLypcbiAqIFdlYlNvY2tldHMgc3VwcG9ydCBiaW5hcnlcbiAqL1xuXG5XUy5wcm90b3R5cGUuc3VwcG9ydHNCaW5hcnkgPSB0cnVlO1xuXG4vKipcbiAqIE9wZW5zIHNvY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5XUy5wcm90b3R5cGUuZG9PcGVuID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuY2hlY2soKSkge1xuICAgIC8vIGxldCBwcm9iZSB0aW1lb3V0XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHVyaSA9IHRoaXMudXJpKCk7XG4gIHZhciBwcm90b2NvbHMgPSB2b2lkICgwKTtcbiAgdmFyIG9wdHMgPSB7XG4gICAgYWdlbnQ6IHRoaXMuYWdlbnQsXG4gICAgcGVyTWVzc2FnZURlZmxhdGU6IHRoaXMucGVyTWVzc2FnZURlZmxhdGVcbiAgfTtcblxuICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgb3B0cy5wZnggPSB0aGlzLnBmeDtcbiAgb3B0cy5rZXkgPSB0aGlzLmtleTtcbiAgb3B0cy5wYXNzcGhyYXNlID0gdGhpcy5wYXNzcGhyYXNlO1xuICBvcHRzLmNlcnQgPSB0aGlzLmNlcnQ7XG4gIG9wdHMuY2EgPSB0aGlzLmNhO1xuICBvcHRzLmNpcGhlcnMgPSB0aGlzLmNpcGhlcnM7XG4gIG9wdHMucmVqZWN0VW5hdXRob3JpemVkID0gdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQ7XG4gIGlmICh0aGlzLmV4dHJhSGVhZGVycykge1xuICAgIG9wdHMuaGVhZGVycyA9IHRoaXMuZXh0cmFIZWFkZXJzO1xuICB9XG4gIGlmICh0aGlzLmxvY2FsQWRkcmVzcykge1xuICAgIG9wdHMubG9jYWxBZGRyZXNzID0gdGhpcy5sb2NhbEFkZHJlc3M7XG4gIH1cblxuICB0cnkge1xuICAgIHRoaXMud3MgPSB0aGlzLnVzaW5nQnJvd3NlcldlYlNvY2tldCA/IG5ldyBXZWJTb2NrZXQodXJpKSA6IG5ldyBXZWJTb2NrZXQodXJpLCBwcm90b2NvbHMsIG9wdHMpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gIH1cblxuICBpZiAodGhpcy53cy5iaW5hcnlUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG4gIH1cblxuICBpZiAodGhpcy53cy5zdXBwb3J0cyAmJiB0aGlzLndzLnN1cHBvcnRzLmJpbmFyeSkge1xuICAgIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSB0cnVlO1xuICAgIHRoaXMud3MuYmluYXJ5VHlwZSA9ICdub2RlYnVmZmVyJztcbiAgfSBlbHNlIHtcbiAgICB0aGlzLndzLmJpbmFyeVR5cGUgPSAnYXJyYXlidWZmZXInO1xuICB9XG5cbiAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xufTtcblxuLyoqXG4gKiBBZGRzIGV2ZW50IGxpc3RlbmVycyB0byB0aGUgc29ja2V0XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXJzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy53cy5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5vbk9wZW4oKTtcbiAgfTtcbiAgdGhpcy53cy5vbmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgIHNlbGYub25DbG9zZSgpO1xuICB9O1xuICB0aGlzLndzLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChldikge1xuICAgIHNlbGYub25EYXRhKGV2LmRhdGEpO1xuICB9O1xuICB0aGlzLndzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZSkge1xuICAgIHNlbGYub25FcnJvcignd2Vic29ja2V0IGVycm9yJywgZSk7XG4gIH07XG59O1xuXG4vKipcbiAqIFdyaXRlcyBkYXRhIHRvIHNvY2tldC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBvZiBwYWNrZXRzLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKHBhY2tldHMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG5cbiAgLy8gZW5jb2RlUGFja2V0IGVmZmljaWVudCBhcyBpdCB1c2VzIFdTIGZyYW1pbmdcbiAgLy8gbm8gbmVlZCBmb3IgZW5jb2RlUGF5bG9hZFxuICB2YXIgdG90YWwgPSBwYWNrZXRzLmxlbmd0aDtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB0b3RhbDsgaSA8IGw7IGkrKykge1xuICAgIChmdW5jdGlvbiAocGFja2V0KSB7XG4gICAgICBwYXJzZXIuZW5jb2RlUGFja2V0KHBhY2tldCwgc2VsZi5zdXBwb3J0c0JpbmFyeSwgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgaWYgKCFzZWxmLnVzaW5nQnJvd3NlcldlYlNvY2tldCkge1xuICAgICAgICAgIC8vIGFsd2F5cyBjcmVhdGUgYSBuZXcgb2JqZWN0IChHSC00MzcpXG4gICAgICAgICAgdmFyIG9wdHMgPSB7fTtcbiAgICAgICAgICBpZiAocGFja2V0Lm9wdGlvbnMpIHtcbiAgICAgICAgICAgIG9wdHMuY29tcHJlc3MgPSBwYWNrZXQub3B0aW9ucy5jb21wcmVzcztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc2VsZi5wZXJNZXNzYWdlRGVmbGF0ZSkge1xuICAgICAgICAgICAgdmFyIGxlbiA9ICdzdHJpbmcnID09PSB0eXBlb2YgZGF0YSA/IGdsb2JhbC5CdWZmZXIuYnl0ZUxlbmd0aChkYXRhKSA6IGRhdGEubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKGxlbiA8IHNlbGYucGVyTWVzc2FnZURlZmxhdGUudGhyZXNob2xkKSB7XG4gICAgICAgICAgICAgIG9wdHMuY29tcHJlc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTb21ldGltZXMgdGhlIHdlYnNvY2tldCBoYXMgYWxyZWFkeSBiZWVuIGNsb3NlZCBidXQgdGhlIGJyb3dzZXIgZGlkbid0XG4gICAgICAgIC8vIGhhdmUgYSBjaGFuY2Ugb2YgaW5mb3JtaW5nIHVzIGFib3V0IGl0IHlldCwgaW4gdGhhdCBjYXNlIHNlbmQgd2lsbFxuICAgICAgICAvLyB0aHJvdyBhbiBlcnJvclxuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChzZWxmLnVzaW5nQnJvd3NlcldlYlNvY2tldCkge1xuICAgICAgICAgICAgLy8gVHlwZUVycm9yIGlzIHRocm93biB3aGVuIHBhc3NpbmcgdGhlIHNlY29uZCBhcmd1bWVudCBvbiBTYWZhcmlcbiAgICAgICAgICAgIHNlbGYud3Muc2VuZChkYXRhKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi53cy5zZW5kKGRhdGEsIG9wdHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGRlYnVnKCd3ZWJzb2NrZXQgY2xvc2VkIGJlZm9yZSBvbmNsb3NlIGV2ZW50Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAtLXRvdGFsIHx8IGRvbmUoKTtcbiAgICAgIH0pO1xuICAgIH0pKHBhY2tldHNbaV0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZG9uZSAoKSB7XG4gICAgc2VsZi5lbWl0KCdmbHVzaCcpO1xuXG4gICAgLy8gZmFrZSBkcmFpblxuICAgIC8vIGRlZmVyIHRvIG5leHQgdGljayB0byBhbGxvdyBTb2NrZXQgdG8gY2xlYXIgd3JpdGVCdWZmZXJcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYud3JpdGFibGUgPSB0cnVlO1xuICAgICAgc2VsZi5lbWl0KCdkcmFpbicpO1xuICAgIH0sIDApO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGNsb3NlXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLm9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIFRyYW5zcG9ydC5wcm90b3R5cGUub25DbG9zZS5jYWxsKHRoaXMpO1xufTtcblxuLyoqXG4gKiBDbG9zZXMgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbldTLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIHRoaXMud3MgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhpcy53cy5jbG9zZSgpO1xuICB9XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyB1cmkgZm9yIGNvbm5lY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLnVyaSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHF1ZXJ5ID0gdGhpcy5xdWVyeSB8fCB7fTtcbiAgdmFyIHNjaGVtYSA9IHRoaXMuc2VjdXJlID8gJ3dzcycgOiAnd3MnO1xuICB2YXIgcG9ydCA9ICcnO1xuXG4gIC8vIGF2b2lkIHBvcnQgaWYgZGVmYXVsdCBmb3Igc2NoZW1hXG4gIGlmICh0aGlzLnBvcnQgJiYgKCgnd3NzJyA9PT0gc2NoZW1hICYmIE51bWJlcih0aGlzLnBvcnQpICE9PSA0NDMpIHx8XG4gICAgKCd3cycgPT09IHNjaGVtYSAmJiBOdW1iZXIodGhpcy5wb3J0KSAhPT0gODApKSkge1xuICAgIHBvcnQgPSAnOicgKyB0aGlzLnBvcnQ7XG4gIH1cblxuICAvLyBhcHBlbmQgdGltZXN0YW1wIHRvIFVSSVxuICBpZiAodGhpcy50aW1lc3RhbXBSZXF1ZXN0cykge1xuICAgIHF1ZXJ5W3RoaXMudGltZXN0YW1wUGFyYW1dID0geWVhc3QoKTtcbiAgfVxuXG4gIC8vIGNvbW11bmljYXRlIGJpbmFyeSBzdXBwb3J0IGNhcGFiaWxpdGllc1xuICBpZiAoIXRoaXMuc3VwcG9ydHNCaW5hcnkpIHtcbiAgICBxdWVyeS5iNjQgPSAxO1xuICB9XG5cbiAgcXVlcnkgPSBwYXJzZXFzLmVuY29kZShxdWVyeSk7XG5cbiAgLy8gcHJlcGVuZCA/IHRvIHF1ZXJ5XG4gIGlmIChxdWVyeS5sZW5ndGgpIHtcbiAgICBxdWVyeSA9ICc/JyArIHF1ZXJ5O1xuICB9XG5cbiAgdmFyIGlwdjYgPSB0aGlzLmhvc3RuYW1lLmluZGV4T2YoJzonKSAhPT0gLTE7XG4gIHJldHVybiBzY2hlbWEgKyAnOi8vJyArIChpcHY2ID8gJ1snICsgdGhpcy5ob3N0bmFtZSArICddJyA6IHRoaXMuaG9zdG5hbWUpICsgcG9ydCArIHRoaXMucGF0aCArIHF1ZXJ5O1xufTtcblxuLyoqXG4gKiBGZWF0dXJlIGRldGVjdGlvbiBmb3IgV2ViU29ja2V0LlxuICpcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHdoZXRoZXIgdGhpcyB0cmFuc3BvcnQgaXMgYXZhaWxhYmxlLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5XUy5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhIVdlYlNvY2tldCAmJiAhKCdfX2luaXRpYWxpemUnIGluIFdlYlNvY2tldCAmJiB0aGlzLm5hbWUgPT09IFdTLnByb3RvdHlwZS5uYW1lKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6b20\n")},"6fba":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar debug = __webpack_require__(/*! debug */ \"8233\")('socket.io-parser');\nvar json = __webpack_require__(/*! json3 */ \"3b17\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"636d\");\nvar binary = __webpack_require__(/*! ./binary */ \"ea82\");\nvar isBuf = __webpack_require__(/*! ./is-buffer */ \"419b\");\n\n/**\n * Protocol version.\n *\n * @api public\n */\n\nexports.protocol = 4;\n\n/**\n * Packet types.\n *\n * @api public\n */\n\nexports.types = [\n  'CONNECT',\n  'DISCONNECT',\n  'EVENT',\n  'ACK',\n  'ERROR',\n  'BINARY_EVENT',\n  'BINARY_ACK'\n];\n\n/**\n * Packet type `connect`.\n *\n * @api public\n */\n\nexports.CONNECT = 0;\n\n/**\n * Packet type `disconnect`.\n *\n * @api public\n */\n\nexports.DISCONNECT = 1;\n\n/**\n * Packet type `event`.\n *\n * @api public\n */\n\nexports.EVENT = 2;\n\n/**\n * Packet type `ack`.\n *\n * @api public\n */\n\nexports.ACK = 3;\n\n/**\n * Packet type `error`.\n *\n * @api public\n */\n\nexports.ERROR = 4;\n\n/**\n * Packet type 'binary event'\n *\n * @api public\n */\n\nexports.BINARY_EVENT = 5;\n\n/**\n * Packet type `binary ack`. For acks with binary arguments.\n *\n * @api public\n */\n\nexports.BINARY_ACK = 6;\n\n/**\n * Encoder constructor.\n *\n * @api public\n */\n\nexports.Encoder = Encoder;\n\n/**\n * Decoder constructor.\n *\n * @api public\n */\n\nexports.Decoder = Decoder;\n\n/**\n * A socket.io Encoder instance\n *\n * @api public\n */\n\nfunction Encoder() {}\n\n/**\n * Encode a packet as a single string if non-binary, or as a\n * buffer sequence, depending on packet type.\n *\n * @param {Object} obj - packet object\n * @param {Function} callback - function to handle encodings (likely engine.write)\n * @return Calls callback with Array of encodings\n * @api public\n */\n\nEncoder.prototype.encode = function(obj, callback){\n  debug('encoding packet %j', obj);\n\n  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n    encodeAsBinary(obj, callback);\n  }\n  else {\n    var encoding = encodeAsString(obj);\n    callback([encoding]);\n  }\n};\n\n/**\n * Encode packet as string.\n *\n * @param {Object} packet\n * @return {String} encoded\n * @api private\n */\n\nfunction encodeAsString(obj) {\n  var str = '';\n  var nsp = false;\n\n  // first is type\n  str += obj.type;\n\n  // attachments if we have them\n  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n    str += obj.attachments;\n    str += '-';\n  }\n\n  // if we have a namespace other than `/`\n  // we append it followed by a comma `,`\n  if (obj.nsp && '/' != obj.nsp) {\n    nsp = true;\n    str += obj.nsp;\n  }\n\n  // immediately followed by the id\n  if (null != obj.id) {\n    if (nsp) {\n      str += ',';\n      nsp = false;\n    }\n    str += obj.id;\n  }\n\n  // json data\n  if (null != obj.data) {\n    if (nsp) str += ',';\n    str += json.stringify(obj.data);\n  }\n\n  debug('encoded %j as %s', obj, str);\n  return str;\n}\n\n/**\n * Encode packet as 'buffer sequence' by removing blobs, and\n * deconstructing packet into object with placeholders and\n * a list of buffers.\n *\n * @param {Object} packet\n * @return {Buffer} encoded\n * @api private\n */\n\nfunction encodeAsBinary(obj, callback) {\n\n  function writeEncoding(bloblessData) {\n    var deconstruction = binary.deconstructPacket(bloblessData);\n    var pack = encodeAsString(deconstruction.packet);\n    var buffers = deconstruction.buffers;\n\n    buffers.unshift(pack); // add packet info to beginning of data list\n    callback(buffers); // write all the buffers\n  }\n\n  binary.removeBlobs(obj, writeEncoding);\n}\n\n/**\n * A socket.io Decoder instance\n *\n * @return {Object} decoder\n * @api public\n */\n\nfunction Decoder() {\n  this.reconstructor = null;\n}\n\n/**\n * Mix in `Emitter` with Decoder.\n */\n\nEmitter(Decoder.prototype);\n\n/**\n * Decodes an ecoded packet string into packet JSON.\n *\n * @param {String} obj - encoded packet\n * @return {Object} packet\n * @api public\n */\n\nDecoder.prototype.add = function(obj) {\n  var packet;\n  if ('string' == typeof obj) {\n    packet = decodeString(obj);\n    if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) { // binary packet's json\n      this.reconstructor = new BinaryReconstructor(packet);\n\n      // no attachments, labeled binary but no binary data to follow\n      if (this.reconstructor.reconPack.attachments === 0) {\n        this.emit('decoded', packet);\n      }\n    } else { // non-binary full packet\n      this.emit('decoded', packet);\n    }\n  }\n  else if (isBuf(obj) || obj.base64) { // raw binary data\n    if (!this.reconstructor) {\n      throw new Error('got binary data when not reconstructing a packet');\n    } else {\n      packet = this.reconstructor.takeBinaryData(obj);\n      if (packet) { // received final buffer\n        this.reconstructor = null;\n        this.emit('decoded', packet);\n      }\n    }\n  }\n  else {\n    throw new Error('Unknown type: ' + obj);\n  }\n};\n\n/**\n * Decode a packet String (JSON data)\n *\n * @param {String} str\n * @return {Object} packet\n * @api private\n */\n\nfunction decodeString(str) {\n  var p = {};\n  var i = 0;\n\n  // look up type\n  p.type = Number(str.charAt(0));\n  if (null == exports.types[p.type]) return error();\n\n  // look up attachments if type binary\n  if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) {\n    var buf = '';\n    while (str.charAt(++i) != '-') {\n      buf += str.charAt(i);\n      if (i == str.length) break;\n    }\n    if (buf != Number(buf) || str.charAt(i) != '-') {\n      throw new Error('Illegal attachments');\n    }\n    p.attachments = Number(buf);\n  }\n\n  // look up namespace (if any)\n  if ('/' == str.charAt(i + 1)) {\n    p.nsp = '';\n    while (++i) {\n      var c = str.charAt(i);\n      if (',' == c) break;\n      p.nsp += c;\n      if (i == str.length) break;\n    }\n  } else {\n    p.nsp = '/';\n  }\n\n  // look up id\n  var next = str.charAt(i + 1);\n  if ('' !== next && Number(next) == next) {\n    p.id = '';\n    while (++i) {\n      var c = str.charAt(i);\n      if (null == c || Number(c) != c) {\n        --i;\n        break;\n      }\n      p.id += str.charAt(i);\n      if (i == str.length) break;\n    }\n    p.id = Number(p.id);\n  }\n\n  // look up json data\n  if (str.charAt(++i)) {\n    p = tryParse(p, str.substr(i));\n  }\n\n  debug('decoded %s as %j', str, p);\n  return p;\n}\n\nfunction tryParse(p, str) {\n  try {\n    p.data = json.parse(str);\n  } catch(e){\n    return error();\n  }\n  return p; \n};\n\n/**\n * Deallocates a parser's resources\n *\n * @api public\n */\n\nDecoder.prototype.destroy = function() {\n  if (this.reconstructor) {\n    this.reconstructor.finishedReconstruction();\n  }\n};\n\n/**\n * A manager of a binary event's 'buffer sequence'. Should\n * be constructed whenever a packet of type BINARY_EVENT is\n * decoded.\n *\n * @param {Object} packet\n * @return {BinaryReconstructor} initialized reconstructor\n * @api private\n */\n\nfunction BinaryReconstructor(packet) {\n  this.reconPack = packet;\n  this.buffers = [];\n}\n\n/**\n * Method to be called when binary data received from connection\n * after a BINARY_EVENT packet.\n *\n * @param {Buffer | ArrayBuffer} binData - the raw binary data received\n * @return {null | Object} returns null if more binary data is expected or\n *   a reconstructed packet object if all buffers have been received.\n * @api private\n */\n\nBinaryReconstructor.prototype.takeBinaryData = function(binData) {\n  this.buffers.push(binData);\n  if (this.buffers.length == this.reconPack.attachments) { // done with buffer list\n    var packet = binary.reconstructPacket(this.reconPack, this.buffers);\n    this.finishedReconstruction();\n    return packet;\n  }\n  return null;\n};\n\n/**\n * Cleans up binary packet reconstruction variables.\n *\n * @api private\n */\n\nBinaryReconstructor.prototype.finishedReconstruction = function() {\n  this.reconPack = null;\n  this.buffers = [];\n};\n\nfunction error(data){\n  return {\n    type: exports.ERROR,\n    data: 'parser error'\n  };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNmZiYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9pbmRleC5qcz84ZjQzIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBqc29uID0gcmVxdWlyZSgnanNvbjMnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciBiaW5hcnkgPSByZXF1aXJlKCcuL2JpbmFyeScpO1xudmFyIGlzQnVmID0gcmVxdWlyZSgnLi9pcy1idWZmZXInKTtcblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5wcm90b2NvbCA9IDQ7XG5cbi8qKlxuICogUGFja2V0IHR5cGVzLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy50eXBlcyA9IFtcbiAgJ0NPTk5FQ1QnLFxuICAnRElTQ09OTkVDVCcsXG4gICdFVkVOVCcsXG4gICdBQ0snLFxuICAnRVJST1InLFxuICAnQklOQVJZX0VWRU5UJyxcbiAgJ0JJTkFSWV9BQ0snXG5dO1xuXG4vKipcbiAqIFBhY2tldCB0eXBlIGBjb25uZWN0YC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuQ09OTkVDVCA9IDA7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGRpc2Nvbm5lY3RgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5ESVNDT05ORUNUID0gMTtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgZXZlbnRgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5FVkVOVCA9IDI7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGFja2AuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkFDSyA9IDM7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGVycm9yYC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuRVJST1IgPSA0O1xuXG4vKipcbiAqIFBhY2tldCB0eXBlICdiaW5hcnkgZXZlbnQnXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkJJTkFSWV9FVkVOVCA9IDU7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGJpbmFyeSBhY2tgLiBGb3IgYWNrcyB3aXRoIGJpbmFyeSBhcmd1bWVudHMuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkJJTkFSWV9BQ0sgPSA2O1xuXG4vKipcbiAqIEVuY29kZXIgY29uc3RydWN0b3IuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkVuY29kZXIgPSBFbmNvZGVyO1xuXG4vKipcbiAqIERlY29kZXIgY29uc3RydWN0b3IuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkRlY29kZXIgPSBEZWNvZGVyO1xuXG4vKipcbiAqIEEgc29ja2V0LmlvIEVuY29kZXIgaW5zdGFuY2VcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIEVuY29kZXIoKSB7fVxuXG4vKipcbiAqIEVuY29kZSBhIHBhY2tldCBhcyBhIHNpbmdsZSBzdHJpbmcgaWYgbm9uLWJpbmFyeSwgb3IgYXMgYVxuICogYnVmZmVyIHNlcXVlbmNlLCBkZXBlbmRpbmcgb24gcGFja2V0IHR5cGUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiAtIHBhY2tldCBvYmplY3RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIC0gZnVuY3Rpb24gdG8gaGFuZGxlIGVuY29kaW5ncyAobGlrZWx5IGVuZ2luZS53cml0ZSlcbiAqIEByZXR1cm4gQ2FsbHMgY2FsbGJhY2sgd2l0aCBBcnJheSBvZiBlbmNvZGluZ3NcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW5jb2Rlci5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24ob2JqLCBjYWxsYmFjayl7XG4gIGRlYnVnKCdlbmNvZGluZyBwYWNrZXQgJWonLCBvYmopO1xuXG4gIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBvYmoudHlwZSB8fCBleHBvcnRzLkJJTkFSWV9BQ0sgPT0gb2JqLnR5cGUpIHtcbiAgICBlbmNvZGVBc0JpbmFyeShvYmosIGNhbGxiYWNrKTtcbiAgfVxuICBlbHNlIHtcbiAgICB2YXIgZW5jb2RpbmcgPSBlbmNvZGVBc1N0cmluZyhvYmopO1xuICAgIGNhbGxiYWNrKFtlbmNvZGluZ10pO1xuICB9XG59O1xuXG4vKipcbiAqIEVuY29kZSBwYWNrZXQgYXMgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEByZXR1cm4ge1N0cmluZ30gZW5jb2RlZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gZW5jb2RlQXNTdHJpbmcob2JqKSB7XG4gIHZhciBzdHIgPSAnJztcbiAgdmFyIG5zcCA9IGZhbHNlO1xuXG4gIC8vIGZpcnN0IGlzIHR5cGVcbiAgc3RyICs9IG9iai50eXBlO1xuXG4gIC8vIGF0dGFjaG1lbnRzIGlmIHdlIGhhdmUgdGhlbVxuICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gb2JqLnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IG9iai50eXBlKSB7XG4gICAgc3RyICs9IG9iai5hdHRhY2htZW50cztcbiAgICBzdHIgKz0gJy0nO1xuICB9XG5cbiAgLy8gaWYgd2UgaGF2ZSBhIG5hbWVzcGFjZSBvdGhlciB0aGFuIGAvYFxuICAvLyB3ZSBhcHBlbmQgaXQgZm9sbG93ZWQgYnkgYSBjb21tYSBgLGBcbiAgaWYgKG9iai5uc3AgJiYgJy8nICE9IG9iai5uc3ApIHtcbiAgICBuc3AgPSB0cnVlO1xuICAgIHN0ciArPSBvYmoubnNwO1xuICB9XG5cbiAgLy8gaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgdGhlIGlkXG4gIGlmIChudWxsICE9IG9iai5pZCkge1xuICAgIGlmIChuc3ApIHtcbiAgICAgIHN0ciArPSAnLCc7XG4gICAgICBuc3AgPSBmYWxzZTtcbiAgICB9XG4gICAgc3RyICs9IG9iai5pZDtcbiAgfVxuXG4gIC8vIGpzb24gZGF0YVxuICBpZiAobnVsbCAhPSBvYmouZGF0YSkge1xuICAgIGlmIChuc3ApIHN0ciArPSAnLCc7XG4gICAgc3RyICs9IGpzb24uc3RyaW5naWZ5KG9iai5kYXRhKTtcbiAgfVxuXG4gIGRlYnVnKCdlbmNvZGVkICVqIGFzICVzJywgb2JqLCBzdHIpO1xuICByZXR1cm4gc3RyO1xufVxuXG4vKipcbiAqIEVuY29kZSBwYWNrZXQgYXMgJ2J1ZmZlciBzZXF1ZW5jZScgYnkgcmVtb3ZpbmcgYmxvYnMsIGFuZFxuICogZGVjb25zdHJ1Y3RpbmcgcGFja2V0IGludG8gb2JqZWN0IHdpdGggcGxhY2Vob2xkZXJzIGFuZFxuICogYSBsaXN0IG9mIGJ1ZmZlcnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQHJldHVybiB7QnVmZmVyfSBlbmNvZGVkXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBlbmNvZGVBc0JpbmFyeShvYmosIGNhbGxiYWNrKSB7XG5cbiAgZnVuY3Rpb24gd3JpdGVFbmNvZGluZyhibG9ibGVzc0RhdGEpIHtcbiAgICB2YXIgZGVjb25zdHJ1Y3Rpb24gPSBiaW5hcnkuZGVjb25zdHJ1Y3RQYWNrZXQoYmxvYmxlc3NEYXRhKTtcbiAgICB2YXIgcGFjayA9IGVuY29kZUFzU3RyaW5nKGRlY29uc3RydWN0aW9uLnBhY2tldCk7XG4gICAgdmFyIGJ1ZmZlcnMgPSBkZWNvbnN0cnVjdGlvbi5idWZmZXJzO1xuXG4gICAgYnVmZmVycy51bnNoaWZ0KHBhY2spOyAvLyBhZGQgcGFja2V0IGluZm8gdG8gYmVnaW5uaW5nIG9mIGRhdGEgbGlzdFxuICAgIGNhbGxiYWNrKGJ1ZmZlcnMpOyAvLyB3cml0ZSBhbGwgdGhlIGJ1ZmZlcnNcbiAgfVxuXG4gIGJpbmFyeS5yZW1vdmVCbG9icyhvYmosIHdyaXRlRW5jb2RpbmcpO1xufVxuXG4vKipcbiAqIEEgc29ja2V0LmlvIERlY29kZXIgaW5zdGFuY2VcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGRlY29kZXJcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRGVjb2RlcigpIHtcbiAgdGhpcy5yZWNvbnN0cnVjdG9yID0gbnVsbDtcbn1cblxuLyoqXG4gKiBNaXggaW4gYEVtaXR0ZXJgIHdpdGggRGVjb2Rlci5cbiAqL1xuXG5FbWl0dGVyKERlY29kZXIucHJvdG90eXBlKTtcblxuLyoqXG4gKiBEZWNvZGVzIGFuIGVjb2RlZCBwYWNrZXQgc3RyaW5nIGludG8gcGFja2V0IEpTT04uXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG9iaiAtIGVuY29kZWQgcGFja2V0XG4gKiBAcmV0dXJuIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5EZWNvZGVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbihvYmopIHtcbiAgdmFyIHBhY2tldDtcbiAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBvYmopIHtcbiAgICBwYWNrZXQgPSBkZWNvZGVTdHJpbmcob2JqKTtcbiAgICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gcGFja2V0LnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IHBhY2tldC50eXBlKSB7IC8vIGJpbmFyeSBwYWNrZXQncyBqc29uXG4gICAgICB0aGlzLnJlY29uc3RydWN0b3IgPSBuZXcgQmluYXJ5UmVjb25zdHJ1Y3RvcihwYWNrZXQpO1xuXG4gICAgICAvLyBubyBhdHRhY2htZW50cywgbGFiZWxlZCBiaW5hcnkgYnV0IG5vIGJpbmFyeSBkYXRhIHRvIGZvbGxvd1xuICAgICAgaWYgKHRoaXMucmVjb25zdHJ1Y3Rvci5yZWNvblBhY2suYXR0YWNobWVudHMgPT09IDApIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkZWNvZGVkJywgcGFja2V0KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgeyAvLyBub24tYmluYXJ5IGZ1bGwgcGFja2V0XG4gICAgICB0aGlzLmVtaXQoJ2RlY29kZWQnLCBwYWNrZXQpO1xuICAgIH1cbiAgfVxuICBlbHNlIGlmIChpc0J1ZihvYmopIHx8IG9iai5iYXNlNjQpIHsgLy8gcmF3IGJpbmFyeSBkYXRhXG4gICAgaWYgKCF0aGlzLnJlY29uc3RydWN0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ290IGJpbmFyeSBkYXRhIHdoZW4gbm90IHJlY29uc3RydWN0aW5nIGEgcGFja2V0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhY2tldCA9IHRoaXMucmVjb25zdHJ1Y3Rvci50YWtlQmluYXJ5RGF0YShvYmopO1xuICAgICAgaWYgKHBhY2tldCkgeyAvLyByZWNlaXZlZCBmaW5hbCBidWZmZXJcbiAgICAgICAgdGhpcy5yZWNvbnN0cnVjdG9yID0gbnVsbDtcbiAgICAgICAgdGhpcy5lbWl0KCdkZWNvZGVkJywgcGFja2V0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHR5cGU6ICcgKyBvYmopO1xuICB9XG59O1xuXG4vKipcbiAqIERlY29kZSBhIHBhY2tldCBTdHJpbmcgKEpTT04gZGF0YSlcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gZGVjb2RlU3RyaW5nKHN0cikge1xuICB2YXIgcCA9IHt9O1xuICB2YXIgaSA9IDA7XG5cbiAgLy8gbG9vayB1cCB0eXBlXG4gIHAudHlwZSA9IE51bWJlcihzdHIuY2hhckF0KDApKTtcbiAgaWYgKG51bGwgPT0gZXhwb3J0cy50eXBlc1twLnR5cGVdKSByZXR1cm4gZXJyb3IoKTtcblxuICAvLyBsb29rIHVwIGF0dGFjaG1lbnRzIGlmIHR5cGUgYmluYXJ5XG4gIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBwLnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IHAudHlwZSkge1xuICAgIHZhciBidWYgPSAnJztcbiAgICB3aGlsZSAoc3RyLmNoYXJBdCgrK2kpICE9ICctJykge1xuICAgICAgYnVmICs9IHN0ci5jaGFyQXQoaSk7XG4gICAgICBpZiAoaSA9PSBzdHIubGVuZ3RoKSBicmVhaztcbiAgICB9XG4gICAgaWYgKGJ1ZiAhPSBOdW1iZXIoYnVmKSB8fCBzdHIuY2hhckF0KGkpICE9ICctJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbGxlZ2FsIGF0dGFjaG1lbnRzJyk7XG4gICAgfVxuICAgIHAuYXR0YWNobWVudHMgPSBOdW1iZXIoYnVmKTtcbiAgfVxuXG4gIC8vIGxvb2sgdXAgbmFtZXNwYWNlIChpZiBhbnkpXG4gIGlmICgnLycgPT0gc3RyLmNoYXJBdChpICsgMSkpIHtcbiAgICBwLm5zcCA9ICcnO1xuICAgIHdoaWxlICgrK2kpIHtcbiAgICAgIHZhciBjID0gc3RyLmNoYXJBdChpKTtcbiAgICAgIGlmICgnLCcgPT0gYykgYnJlYWs7XG4gICAgICBwLm5zcCArPSBjO1xuICAgICAgaWYgKGkgPT0gc3RyLmxlbmd0aCkgYnJlYWs7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHAubnNwID0gJy8nO1xuICB9XG5cbiAgLy8gbG9vayB1cCBpZFxuICB2YXIgbmV4dCA9IHN0ci5jaGFyQXQoaSArIDEpO1xuICBpZiAoJycgIT09IG5leHQgJiYgTnVtYmVyKG5leHQpID09IG5leHQpIHtcbiAgICBwLmlkID0gJyc7XG4gICAgd2hpbGUgKCsraSkge1xuICAgICAgdmFyIGMgPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKG51bGwgPT0gYyB8fCBOdW1iZXIoYykgIT0gYykge1xuICAgICAgICAtLWk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgcC5pZCArPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKGkgPT0gc3RyLmxlbmd0aCkgYnJlYWs7XG4gICAgfVxuICAgIHAuaWQgPSBOdW1iZXIocC5pZCk7XG4gIH1cblxuICAvLyBsb29rIHVwIGpzb24gZGF0YVxuICBpZiAoc3RyLmNoYXJBdCgrK2kpKSB7XG4gICAgcCA9IHRyeVBhcnNlKHAsIHN0ci5zdWJzdHIoaSkpO1xuICB9XG5cbiAgZGVidWcoJ2RlY29kZWQgJXMgYXMgJWonLCBzdHIsIHApO1xuICByZXR1cm4gcDtcbn1cblxuZnVuY3Rpb24gdHJ5UGFyc2UocCwgc3RyKSB7XG4gIHRyeSB7XG4gICAgcC5kYXRhID0ganNvbi5wYXJzZShzdHIpO1xuICB9IGNhdGNoKGUpe1xuICAgIHJldHVybiBlcnJvcigpO1xuICB9XG4gIHJldHVybiBwOyBcbn07XG5cbi8qKlxuICogRGVhbGxvY2F0ZXMgYSBwYXJzZXIncyByZXNvdXJjZXNcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkRlY29kZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMucmVjb25zdHJ1Y3Rvcikge1xuICAgIHRoaXMucmVjb25zdHJ1Y3Rvci5maW5pc2hlZFJlY29uc3RydWN0aW9uKCk7XG4gIH1cbn07XG5cbi8qKlxuICogQSBtYW5hZ2VyIG9mIGEgYmluYXJ5IGV2ZW50J3MgJ2J1ZmZlciBzZXF1ZW5jZScuIFNob3VsZFxuICogYmUgY29uc3RydWN0ZWQgd2hlbmV2ZXIgYSBwYWNrZXQgb2YgdHlwZSBCSU5BUllfRVZFTlQgaXNcbiAqIGRlY29kZWQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQHJldHVybiB7QmluYXJ5UmVjb25zdHJ1Y3Rvcn0gaW5pdGlhbGl6ZWQgcmVjb25zdHJ1Y3RvclxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gQmluYXJ5UmVjb25zdHJ1Y3RvcihwYWNrZXQpIHtcbiAgdGhpcy5yZWNvblBhY2sgPSBwYWNrZXQ7XG4gIHRoaXMuYnVmZmVycyA9IFtdO1xufVxuXG4vKipcbiAqIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBiaW5hcnkgZGF0YSByZWNlaXZlZCBmcm9tIGNvbm5lY3Rpb25cbiAqIGFmdGVyIGEgQklOQVJZX0VWRU5UIHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge0J1ZmZlciB8IEFycmF5QnVmZmVyfSBiaW5EYXRhIC0gdGhlIHJhdyBiaW5hcnkgZGF0YSByZWNlaXZlZFxuICogQHJldHVybiB7bnVsbCB8IE9iamVjdH0gcmV0dXJucyBudWxsIGlmIG1vcmUgYmluYXJ5IGRhdGEgaXMgZXhwZWN0ZWQgb3JcbiAqICAgYSByZWNvbnN0cnVjdGVkIHBhY2tldCBvYmplY3QgaWYgYWxsIGJ1ZmZlcnMgaGF2ZSBiZWVuIHJlY2VpdmVkLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuQmluYXJ5UmVjb25zdHJ1Y3Rvci5wcm90b3R5cGUudGFrZUJpbmFyeURhdGEgPSBmdW5jdGlvbihiaW5EYXRhKSB7XG4gIHRoaXMuYnVmZmVycy5wdXNoKGJpbkRhdGEpO1xuICBpZiAodGhpcy5idWZmZXJzLmxlbmd0aCA9PSB0aGlzLnJlY29uUGFjay5hdHRhY2htZW50cykgeyAvLyBkb25lIHdpdGggYnVmZmVyIGxpc3RcbiAgICB2YXIgcGFja2V0ID0gYmluYXJ5LnJlY29uc3RydWN0UGFja2V0KHRoaXMucmVjb25QYWNrLCB0aGlzLmJ1ZmZlcnMpO1xuICAgIHRoaXMuZmluaXNoZWRSZWNvbnN0cnVjdGlvbigpO1xuICAgIHJldHVybiBwYWNrZXQ7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIENsZWFucyB1cCBiaW5hcnkgcGFja2V0IHJlY29uc3RydWN0aW9uIHZhcmlhYmxlcy5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5CaW5hcnlSZWNvbnN0cnVjdG9yLnByb3RvdHlwZS5maW5pc2hlZFJlY29uc3RydWN0aW9uID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMucmVjb25QYWNrID0gbnVsbDtcbiAgdGhpcy5idWZmZXJzID0gW107XG59O1xuXG5mdW5jdGlvbiBlcnJvcihkYXRhKXtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBleHBvcnRzLkVSUk9SLFxuICAgIGRhdGE6ICdwYXJzZXIgZXJyb3InXG4gIH07XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6fba\n")},"720c":function(module,exports,__webpack_require__){eval("/**\n * Client side filtering using crossfilter\n * Due to limitation of crossfilter with array (or data that has no natrual ordering), this will not work as expected:\n * * dimension: `function (d) {return [d.x, d.y, d.z]}`\n * * group: `function (d) {return [d.x / 10 , d.y / 10, d.z / 10]}`\n *\n * Therefore, we preform grouping already in the dimension itself, and join the array to a string.\n * Strings have a natural ordering and thus can be used as dimension value.\n * * dimension: `function (d) -> \"d.x/10|d.y/10|d.z/10\"`\n * * group: `function (d) {return d;}`\n *\n * @module driver/client\n */\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nvar utildx = __webpack_require__(/*! ../util/crossfilter */ \"adfa\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nvar grpIdxToName = {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'};\nvar aggRankToName = {1: 'aa', 2: 'bb', 3: 'cc', 4: 'dd', 5: 'ee'};\n\n/**\n * setMinMax sets the range of a continuous or time facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setMinMax (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var valFn = utildx.baseValueFn(facet);\n\n  // to be able to mark the value as missing we need it unprocessed, so rawValueFn\n  var rawValFn = utildx.rawValueFn(facet);\n\n  var lessFn;\n  var moreFn;\n  if (facet.isDatetime) {\n    lessFn = function (a, b) { return (b === misval || a.isBefore(b)); };\n    moreFn = function (a, b) { return (b === misval || b.isBefore(a)); };\n  } else {\n    lessFn = function (a, b) { return (b === misval || a < b); };\n    moreFn = function (a, b) { return (b === misval || a > b); };\n  }\n\n  var minval = misval;\n  var rawMin = misval;\n\n  var maxval = misval;\n  var rawMax = misval;\n\n  dataset.data.forEach(function (d) {\n    var rawV = rawValFn(d);\n    var v = valFn(d);\n\n    if (v !== misval) {\n      if (lessFn(v, minval)) {\n        minval = v;\n        rawMin = rawV;\n      }\n      if (moreFn(v, maxval)) {\n        maxval = v;\n        rawMax = rawV;\n      }\n    }\n  });\n\n  if (minval !== misval) {\n    if (facet.isContinuous) {\n      facet.minvalAsText = minval.toString();\n    } else if (facet.isDatetime) {\n      facet.minvalAsText = minval.toISOString();\n    } else if (facet.isDuration) {\n      facet.minvalAsText = minval.toISOString();\n    }\n    facet.rawMinval = rawMin;\n  } else {\n    facet.minvalAsText = '';\n    facet.rawMinval = misval;\n  }\n\n  if (maxval !== misval) {\n    if (facet.isContinuous) {\n      facet.maxvalAsText = maxval.toString();\n    } else if (facet.isDatetime) {\n      facet.maxvalAsText = maxval.toISOString();\n    } else if (facet.isDuration) {\n      facet.maxvalAsText = maxval.toISOString();\n    }\n    facet.rawMaxval = rawMax;\n  } else {\n    facet.maxvalAsText = '';\n    facet.rawMaxval = misval;\n  }\n}\n\n/**\n * setCategories finds finds all values on an ordinal (categorial) axis\n * Updates the categorialTransform of the facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setCategories (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var valFn = utildx.baseValueFn(facet);\n\n  var p = {};\n  var Plength = 0;\n  dataset.data.forEach(function (d, i) {\n    var vals = valFn(d);\n    if (vals instanceof Array) {\n      vals.forEach(function (val) {\n        if (p.hasOwnProperty(val)) {\n          p[val]++;\n        } else {\n          if (Plength < 75) { // NOTE: limit to maximally 75 categories\n            p[val] = 1;\n            Plength++;\n          }\n        }\n      });\n    } else {\n      if (p.hasOwnProperty(vals)) {\n        p[vals]++;\n      } else {\n        if (Plength < 75) { // NOTE: limit to maximally 75 categories\n          p[vals] = 1;\n          Plength++;\n        }\n      }\n    }\n  });\n\n  facet.categorialTransform.reset();\n\n  Object.keys(p).forEach(function (key) {\n    // TODO: missing data should be mapped to a misval from misvalAsText\n    var keyAsString = key.toString();\n    var groupAsString = keyAsString;\n\n    facet.categorialTransform.rules.add({expression: keyAsString, count: p[key], group: groupAsString});\n  });\n}\n\n/**\n * Calculate 100 percentiles (ie. 1,2,3,4 etc.), and initialize the `facet.continuousTransform`\n * to an approximate percentile mapping.\n * Use the recommended method from [NIST](http://www.itl.nist.gov/div898/handbook/prc/section2/prc262.htm)\n * See also the discussion on [Wikipedia](https://en.wikipedia.org/wiki/Percentile)\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setPercentiles (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var basevalueFn = utildx.baseValueFn(facet);\n  var data = dataset.data;\n\n  data.sort(function (a, b) {\n    var valA = basevalueFn(a);\n    var valB = basevalueFn(b);\n\n    if (valA === valB) {\n      return 0;\n    }\n    if (valA === misval) {\n      return -1;\n    }\n    if (valB === misval) {\n      return 1;\n    }\n\n    if (valA < valB) {\n      return -1;\n    } else {\n      return 1;\n    }\n  });\n\n  var tf = facet.continuousTransform;\n  var x, i;\n\n  // drop missing values, which should be sorted at the start of the array\n  i = 0;\n  while (basevalueFn(data[i]) === misval && i < data.length) {\n    i++;\n  }\n  data.splice(0, i);\n\n  // start clean\n  tf.reset();\n\n  // add minimum value as control points p0 and p1\n  tf.cps.add({x: basevalueFn(data[0]), fx: 0});\n  tf.cps.add({x: basevalueFn(data[0]), fx: 0});\n\n  var p, value;\n  for (p = 1; p < 100; p++) {\n    x = (p * 0.01) * (data.length + 1) - 1; // indexing starts at zero, not at one\n    i = Math.trunc(x);\n    value = (1 - x + i) * basevalueFn(data[i]) + (x - i) * basevalueFn(data[i + 1]);\n    tf.cps.add({x: value, fx: p});\n  }\n\n  // add maximum value as p101 and p102\n  tf.cps.add({x: basevalueFn(data[data.length - 1]), fx: 100});\n  tf.cps.add({x: basevalueFn(data[data.length - 1]), fx: 100});\n\n  tf.type = 'percentiles';\n}\n\n/**\n * Autoconfigure a dataset:\n * 1. pick 10 random elements\n * 2. create facets for their properties\n * 3. add facets' values over the sample to the facet.description\n * 4. set range or categories\n *\n * @param {Dataset} dataset\n */\nfunction scan (dataset) {\n  function facetExists (facets, path) {\n    var exists = false;\n    facets.forEach(function (f) {\n      if (f.accessor === path || f.accessor === path + '[]') {\n        exists = true;\n      }\n    });\n    return exists;\n  }\n\n  function addValue (values, v, missing) {\n    if (v === misval) {\n      v = missing;\n    }\n    if (values.indexOf(v) === -1) {\n      values.push(v);\n    }\n  }\n\n  function guessType (values) {\n    var mytype = {\n      continuous: 0,\n      text: 0,\n      datetime: 0,\n      duration: 0,\n      categorial: 0\n    };\n    values.forEach(function (value) {\n      if (moment(value, moment.ISO_8601).isValid()) {\n        // \"2016-08-17 17:25:00+01\"\n        mytype.datetime++;\n      } else if (\n          (moment.duration(value).asMilliseconds() !== 0) &&\n          (typeof value === 'string') &&\n          (value[0].toLowerCase() === 'p')) {\n        // \"P10Y\"\n        mytype.duration++;\n      } else if (value == +value) {  // eslint-disable-line eqeqeq\n        // \"10\" or 10\n        mytype.continuous++;\n      } else {\n        // \"hello world\"\n        mytype.categorial++;\n      }\n    });\n\n    // get facetType with highest count\n    var max = -1;\n    var facetType;\n    Object.keys(mytype).forEach(function (key) {\n      if (mytype[key] > max) {\n        facetType = key;\n        max = mytype[key];\n      }\n    });\n\n    return facetType;\n  }\n\n  function tryFacet (facets, data, path, value) {\n    // Check for existence\n    if (facetExists(facets, path)) {\n      return;\n    }\n\n    // Create a new facet\n    var facet = facets.add({\n      name: path,\n      accessor: path,\n      type: 'text'\n    });\n\n    // Sample values\n    var baseValueFn = utildx.baseValueFn(facet);\n    var values = [];\n    var isArray = false;\n\n    data.forEach(function (d) {\n      var value = baseValueFn(d);\n      if (value instanceof Array) {\n        isArray = true;\n        value.forEach(function (v) {\n          addValue(values, v, facet.misval[0]);\n        });\n      } else {\n        addValue(values, value, facet.misval[0]);\n      }\n    });\n\n    // Reconfigure facet\n    facet.accessor = isArray ? facet.accessor + '[]' : facet.accessor;\n    facet.type = guessType(values);\n    facet.description = values.join(', ').match('^.{0,40}') + '...';\n    facet.isActive = true;\n  }\n\n  function recurse (facets, data, path, tree) {\n    var props = Object.getOwnPropertyNames(tree);\n    props.forEach(function (name) {\n      var subpath;\n      if (path) {\n        subpath = path + '##' + name;\n      } else {\n        subpath = name;\n      }\n\n      if (tree[name] instanceof Array) {\n        // add an array as a itself as a facet, ie. labelset, to prevent adding each element as separate facet\n        // also add the array length as facet\n        tryFacet(facets, data, subpath, tree[name]);\n        tryFacet(facets, data, subpath + '.length', tree[name].length);\n      } else if (tree[name] instanceof Object) {\n        // recurse into objects\n        recurse(facets, data, subpath, tree[name]);\n      } else {\n        // add strings and numbers as facets\n        tryFacet(facets, data, subpath, tree[name]);\n      }\n    });\n  }\n\n  // Add facets\n  var data = dataset.data.slice(0, 10);\n  data.forEach(function (d) {\n    recurse(dataset.facets, data, '', d);\n  });\n\n  dataset.facets.forEach(function (facet) {\n    if (facet.isCategorial) {\n      setCategories(dataset, facet);\n    } else if (facet.isContinuous || facet.isDatetime) {\n      setMinMax(dataset, facet);\n    }\n  });\n  dataset.trigger('syncFacets');\n}\n\n/**\n * Initialize the data filter, and construct the getData callback function on the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction initDataFilter (dataview, filter) {\n  var facet;\n\n  // use the partitions as groups:\n  var groupFns = [];\n  filter.partitions.forEach(function (partition) {\n    facet = dataview.facets.get(partition.facetName, 'name');\n    var valueFn = utildx.valueFn(facet);\n    var groupFn = utildx.groupFn(partition);\n\n    var rank = partition.rank;\n    groupFns[rank - 1] = function (d) {\n      return groupFn(valueFn(d));\n    };\n  });\n\n  // and then create keys from the group values\n  var groupsKeys = function (d) {\n    var keys = [];\n\n    groupFns.forEach(function (groupFn) {\n      var result = groupFn(d);\n      var newKeys = [];\n      if (keys.length === 0) {\n        if (result instanceof Array) {\n          newKeys = result;\n        } else {\n          newKeys = [result];\n        }\n      } else {\n        if (result instanceof Array) {\n          keys.forEach(function (oldKey) {\n            result.forEach(function (key) {\n              newKeys.push(oldKey + '|' + key);\n            });\n          });\n        } else {\n          keys.forEach(function (oldKey) {\n            newKeys.push(oldKey + '|' + result);\n          });\n        }\n      }\n      keys = newKeys;\n    });\n    return keys;\n  };\n\n  // set up the facet valueFns to aggregate over\n  // and the reduction functions for them\n  var aggregateFns = [];\n  var aggregateRanks = [];\n  var reduceFns = [];\n  filter.aggregates.forEach(function (aggregate) {\n    facet = dataview.facets.get(aggregate.facetName, 'name');\n    aggregateRanks.push(aggregate.rank);\n    aggregateFns.push(utildx.valueFn(facet));\n    reduceFns.push(utildx.reduceFn(aggregate));\n  });\n\n  // setup the crossfilter dimensions and groups\n  filter.dimension = dataview.crossfilter.dimension(function (d) {\n    return groupsKeys(d);\n  }, true);\n  var crossfilterGroup = filter.dimension.group(function (d) { return d; });\n\n  crossfilterGroup.reduce(\n    // add\n    function (p, d) {\n      if (aggregateFns.length === 0) {\n        p[0] = p[0] ? p[0] : {count: 0};\n        p[0].count += 1;\n      }\n\n      aggregateFns.forEach(function (aggregateFn, i) {\n        var val = aggregateFn(d);\n        if (val !== misval) {\n          val = parseFloat(val);\n          p[i] = p[i] || {count: 0, sum: 0, sumsquares: 0};\n          p[i].count += 1;\n          p[i].sum += val;\n          p[i].sumsquares += val * val;\n        }\n      });\n      return p;\n    },\n    // subtract\n    function (p, d) {\n      if (aggregateFns.length === 0) {\n        p[0] = p[0] ? p[0] : {count: 0};\n        p[0].count -= 1;\n      }\n\n      aggregateFns.forEach(function (aggregateFn, i) {\n        var val = aggregateFn(d);\n        if (val !== misval) {\n          val = parseFloat(val);\n          p[i] = p[i] || {count: 0, sum: 0, sumsquares: 0};\n          p[i].count -= 1;\n          p[i].sum -= val;\n          p[i].sumsquares -= val * val;\n        }\n      });\n      return p;\n    },\n    // initialize\n    function () {\n      return [];\n    }\n  );\n\n  filter.getData = function () {\n    filter.data = [];\n\n    // Get data from crossfilter\n    var groups = crossfilterGroup.all();\n\n    // { key: \"group1|group2|...\",\n    //   value: [ {count: agg1, sum: agg1}\n    //            {count: agg2, sum: agg2}\n    //            {count: agg3, sum: agg3}\n    //                    ...             ]}\n    groups.forEach(function (group) {\n      var item = {};\n\n      // turn the string back into individual group values\n      var groupsKeys;\n      if (typeof group.key === 'string') {\n        groupsKeys = group.key.split('|');\n      } else {\n        // shortcut for numeric non-partitioned case\n        groupsKeys = [group.key];\n      }\n\n      // add paritioning data to the item\n      groupsKeys.forEach(function (subkey, i) {\n        item[grpIdxToName[i]] = subkey;\n      });\n\n      // add aggregated data to the item\n      reduceFns.forEach(function (reduceFn, i) {\n        var name = aggRankToName[aggregateRanks[i]];\n        item[name] = reduceFn(group.value[i]);\n      });\n\n      // add an overall count\n      // becuase the filtering removes missing data points, this is the same as\n      // the count for any one of the aggregates\n      item.count = group.value[0] ? group.value[0].count : 0;\n\n      filter.data.push(item);\n    });\n  };\n}\n\n/**\n * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n * related to the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction releaseDataFilter (dataview, filter) {\n  if (filter.dimension) {\n    filter.dimension.filterAll();\n    filter.dimension.dispose();\n    delete filter.dimension;\n    delete filter.getData;\n  }\n}\n\n/**\n * Change the filter parameters for an initialized filter\n * @param {Filter} filter\n */\nfunction updateDataFilter (filter) {\n  if (filter.dimension) {\n    filter.dimension.filterFunction(filter.filterFunction());\n  }\n}\n\n/**\n * Get data for every filter, and trigger a 'newData' event\n *\n * Returns a Promise that resolves to the dataview when all data and metadata has been updated\n *\n * @param {Dataview} dataview\n * @returns {Promise}\n */\nfunction getData (dataview) {\n  dataview.filters.forEach(function (filter) {\n    if (filter.isInitialized) {\n      filter.getData();\n      filter.trigger('newData');\n    }\n  });\n\n  // update counts\n  dataview.dataTotal = dataview.crossfilter.size();\n  dataview.dataSelected = dataview.countGroup.value();\n  dataview.trigger('newMetaData');\n\n  return Promise.resolve(dataview);\n}\n\nmodule.exports = {\n  driverType: 'client',\n  scan: scan,\n  setMinMax: setMinMax,\n  setCategories: setCategories,\n  setPercentiles: setPercentiles,\n  initDataFilter: initDataFilter,\n  releaseDataFilter: releaseDataFilter,\n  updateDataFilter: updateDataFilter,\n  getData: getData\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwYy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZHJpdmVyL2NsaWVudC5qcz9kZjc3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2xpZW50IHNpZGUgZmlsdGVyaW5nIHVzaW5nIGNyb3NzZmlsdGVyXG4gKiBEdWUgdG8gbGltaXRhdGlvbiBvZiBjcm9zc2ZpbHRlciB3aXRoIGFycmF5IChvciBkYXRhIHRoYXQgaGFzIG5vIG5hdHJ1YWwgb3JkZXJpbmcpLCB0aGlzIHdpbGwgbm90IHdvcmsgYXMgZXhwZWN0ZWQ6XG4gKiAqIGRpbWVuc2lvbjogYGZ1bmN0aW9uIChkKSB7cmV0dXJuIFtkLngsIGQueSwgZC56XX1gXG4gKiAqIGdyb3VwOiBgZnVuY3Rpb24gKGQpIHtyZXR1cm4gW2QueCAvIDEwICwgZC55IC8gMTAsIGQueiAvIDEwXX1gXG4gKlxuICogVGhlcmVmb3JlLCB3ZSBwcmVmb3JtIGdyb3VwaW5nIGFscmVhZHkgaW4gdGhlIGRpbWVuc2lvbiBpdHNlbGYsIGFuZCBqb2luIHRoZSBhcnJheSB0byBhIHN0cmluZy5cbiAqIFN0cmluZ3MgaGF2ZSBhIG5hdHVyYWwgb3JkZXJpbmcgYW5kIHRodXMgY2FuIGJlIHVzZWQgYXMgZGltZW5zaW9uIHZhbHVlLlxuICogKiBkaW1lbnNpb246IGBmdW5jdGlvbiAoZCkgLT4gXCJkLngvMTB8ZC55LzEwfGQuei8xMFwiYFxuICogKiBncm91cDogYGZ1bmN0aW9uIChkKSB7cmV0dXJuIGQ7fWBcbiAqXG4gKiBAbW9kdWxlIGRyaXZlci9jbGllbnRcbiAqL1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xuXG52YXIgdXRpbGR4ID0gcmVxdWlyZSgnLi4vdXRpbC9jcm9zc2ZpbHRlcicpO1xudmFyIG1pc3ZhbCA9IHJlcXVpcmUoJy4uL3V0aWwvbWlzdmFsJyk7XG5cbnZhciBncnBJZHhUb05hbWUgPSB7MDogJ2EnLCAxOiAnYicsIDI6ICdjJywgMzogJ2QnLCA0OiAnZSd9O1xudmFyIGFnZ1JhbmtUb05hbWUgPSB7MTogJ2FhJywgMjogJ2JiJywgMzogJ2NjJywgNDogJ2RkJywgNTogJ2VlJ307XG5cbi8qKlxuICogc2V0TWluTWF4IHNldHMgdGhlIHJhbmdlIG9mIGEgY29udGludW91cyBvciB0aW1lIGZhY2V0XG4gKlxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0XG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICovXG5mdW5jdGlvbiBzZXRNaW5NYXggKGRhdGFzZXQsIGZhY2V0KSB7XG4gIC8vIHdlIG5lZWQgdGhlIHZhbHVlIGp1c3QgYmVmb3JlIGEgdHJhbnNmb3JtYXRpb24sIHNvIGJhc2VWYWx1ZUZuXG4gIHZhciB2YWxGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG5cbiAgLy8gdG8gYmUgYWJsZSB0byBtYXJrIHRoZSB2YWx1ZSBhcyBtaXNzaW5nIHdlIG5lZWQgaXQgdW5wcm9jZXNzZWQsIHNvIHJhd1ZhbHVlRm5cbiAgdmFyIHJhd1ZhbEZuID0gdXRpbGR4LnJhd1ZhbHVlRm4oZmFjZXQpO1xuXG4gIHZhciBsZXNzRm47XG4gIHZhciBtb3JlRm47XG4gIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgbGVzc0ZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYS5pc0JlZm9yZShiKSk7IH07XG4gICAgbW9yZUZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYi5pc0JlZm9yZShhKSk7IH07XG4gIH0gZWxzZSB7XG4gICAgbGVzc0ZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYSA8IGIpOyB9O1xuICAgIG1vcmVGbiA9IGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiAoYiA9PT0gbWlzdmFsIHx8IGEgPiBiKTsgfTtcbiAgfVxuXG4gIHZhciBtaW52YWwgPSBtaXN2YWw7XG4gIHZhciByYXdNaW4gPSBtaXN2YWw7XG5cbiAgdmFyIG1heHZhbCA9IG1pc3ZhbDtcbiAgdmFyIHJhd01heCA9IG1pc3ZhbDtcblxuICBkYXRhc2V0LmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgIHZhciByYXdWID0gcmF3VmFsRm4oZCk7XG4gICAgdmFyIHYgPSB2YWxGbihkKTtcblxuICAgIGlmICh2ICE9PSBtaXN2YWwpIHtcbiAgICAgIGlmIChsZXNzRm4odiwgbWludmFsKSkge1xuICAgICAgICBtaW52YWwgPSB2O1xuICAgICAgICByYXdNaW4gPSByYXdWO1xuICAgICAgfVxuICAgICAgaWYgKG1vcmVGbih2LCBtYXh2YWwpKSB7XG4gICAgICAgIG1heHZhbCA9IHY7XG4gICAgICAgIHJhd01heCA9IHJhd1Y7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBpZiAobWludmFsICE9PSBtaXN2YWwpIHtcbiAgICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgICBmYWNldC5taW52YWxBc1RleHQgPSBtaW52YWwudG9TdHJpbmcoKTtcbiAgICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICAgIGZhY2V0Lm1pbnZhbEFzVGV4dCA9IG1pbnZhbC50b0lTT1N0cmluZygpO1xuICAgIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgICAgZmFjZXQubWludmFsQXNUZXh0ID0gbWludmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGZhY2V0LnJhd01pbnZhbCA9IHJhd01pbjtcbiAgfSBlbHNlIHtcbiAgICBmYWNldC5taW52YWxBc1RleHQgPSAnJztcbiAgICBmYWNldC5yYXdNaW52YWwgPSBtaXN2YWw7XG4gIH1cblxuICBpZiAobWF4dmFsICE9PSBtaXN2YWwpIHtcbiAgICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgICBmYWNldC5tYXh2YWxBc1RleHQgPSBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IG1heHZhbC50b0lTT1N0cmluZygpO1xuICAgIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgICAgZmFjZXQubWF4dmFsQXNUZXh0ID0gbWF4dmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGZhY2V0LnJhd01heHZhbCA9IHJhd01heDtcbiAgfSBlbHNlIHtcbiAgICBmYWNldC5tYXh2YWxBc1RleHQgPSAnJztcbiAgICBmYWNldC5yYXdNYXh2YWwgPSBtaXN2YWw7XG4gIH1cbn1cblxuLyoqXG4gKiBzZXRDYXRlZ29yaWVzIGZpbmRzIGZpbmRzIGFsbCB2YWx1ZXMgb24gYW4gb3JkaW5hbCAoY2F0ZWdvcmlhbCkgYXhpc1xuICogVXBkYXRlcyB0aGUgY2F0ZWdvcmlhbFRyYW5zZm9ybSBvZiB0aGUgZmFjZXRcbiAqXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXRcbiAqIEBwYXJhbSB7RmFjZXR9IGZhY2V0XG4gKi9cbmZ1bmN0aW9uIHNldENhdGVnb3JpZXMgKGRhdGFzZXQsIGZhY2V0KSB7XG4gIC8vIHdlIG5lZWQgdGhlIHZhbHVlIGp1c3QgYmVmb3JlIGEgdHJhbnNmb3JtYXRpb24sIHNvIGJhc2VWYWx1ZUZuXG4gIHZhciB2YWxGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG5cbiAgdmFyIHAgPSB7fTtcbiAgdmFyIFBsZW5ndGggPSAwO1xuICBkYXRhc2V0LmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZCwgaSkge1xuICAgIHZhciB2YWxzID0gdmFsRm4oZCk7XG4gICAgaWYgKHZhbHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgdmFscy5mb3JFYWNoKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgaWYgKHAuaGFzT3duUHJvcGVydHkodmFsKSkge1xuICAgICAgICAgIHBbdmFsXSsrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChQbGVuZ3RoIDwgNzUpIHsgLy8gTk9URTogbGltaXQgdG8gbWF4aW1hbGx5IDc1IGNhdGVnb3JpZXNcbiAgICAgICAgICAgIHBbdmFsXSA9IDE7XG4gICAgICAgICAgICBQbGVuZ3RoKys7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHAuaGFzT3duUHJvcGVydHkodmFscykpIHtcbiAgICAgICAgcFt2YWxzXSsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKFBsZW5ndGggPCA3NSkgeyAvLyBOT1RFOiBsaW1pdCB0byBtYXhpbWFsbHkgNzUgY2F0ZWdvcmllc1xuICAgICAgICAgIHBbdmFsc10gPSAxO1xuICAgICAgICAgIFBsZW5ndGgrKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5yZXNldCgpO1xuXG4gIE9iamVjdC5rZXlzKHApLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIC8vIFRPRE86IG1pc3NpbmcgZGF0YSBzaG91bGQgYmUgbWFwcGVkIHRvIGEgbWlzdmFsIGZyb20gbWlzdmFsQXNUZXh0XG4gICAgdmFyIGtleUFzU3RyaW5nID0ga2V5LnRvU3RyaW5nKCk7XG4gICAgdmFyIGdyb3VwQXNTdHJpbmcgPSBrZXlBc1N0cmluZztcblxuICAgIGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuYWRkKHtleHByZXNzaW9uOiBrZXlBc1N0cmluZywgY291bnQ6IHBba2V5XSwgZ3JvdXA6IGdyb3VwQXNTdHJpbmd9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIDEwMCBwZXJjZW50aWxlcyAoaWUuIDEsMiwzLDQgZXRjLiksIGFuZCBpbml0aWFsaXplIHRoZSBgZmFjZXQuY29udGludW91c1RyYW5zZm9ybWBcbiAqIHRvIGFuIGFwcHJveGltYXRlIHBlcmNlbnRpbGUgbWFwcGluZy5cbiAqIFVzZSB0aGUgcmVjb21tZW5kZWQgbWV0aG9kIGZyb20gW05JU1RdKGh0dHA6Ly93d3cuaXRsLm5pc3QuZ292L2Rpdjg5OC9oYW5kYm9vay9wcmMvc2VjdGlvbjIvcHJjMjYyLmh0bSlcbiAqIFNlZSBhbHNvIHRoZSBkaXNjdXNzaW9uIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1BlcmNlbnRpbGUpXG4gKlxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0XG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICovXG5mdW5jdGlvbiBzZXRQZXJjZW50aWxlcyAoZGF0YXNldCwgZmFjZXQpIHtcbiAgLy8gd2UgbmVlZCB0aGUgdmFsdWUganVzdCBiZWZvcmUgYSB0cmFuc2Zvcm1hdGlvbiwgc28gYmFzZVZhbHVlRm5cbiAgdmFyIGJhc2V2YWx1ZUZuID0gdXRpbGR4LmJhc2VWYWx1ZUZuKGZhY2V0KTtcbiAgdmFyIGRhdGEgPSBkYXRhc2V0LmRhdGE7XG5cbiAgZGF0YS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgdmFyIHZhbEEgPSBiYXNldmFsdWVGbihhKTtcbiAgICB2YXIgdmFsQiA9IGJhc2V2YWx1ZUZuKGIpO1xuXG4gICAgaWYgKHZhbEEgPT09IHZhbEIpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpZiAodmFsQSA9PT0gbWlzdmFsKSB7XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIGlmICh2YWxCID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIGlmICh2YWxBIDwgdmFsQikge1xuICAgICAgcmV0dXJuIC0xO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH0pO1xuXG4gIHZhciB0ZiA9IGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm07XG4gIHZhciB4LCBpO1xuXG4gIC8vIGRyb3AgbWlzc2luZyB2YWx1ZXMsIHdoaWNoIHNob3VsZCBiZSBzb3J0ZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZSBhcnJheVxuICBpID0gMDtcbiAgd2hpbGUgKGJhc2V2YWx1ZUZuKGRhdGFbaV0pID09PSBtaXN2YWwgJiYgaSA8IGRhdGEubGVuZ3RoKSB7XG4gICAgaSsrO1xuICB9XG4gIGRhdGEuc3BsaWNlKDAsIGkpO1xuXG4gIC8vIHN0YXJ0IGNsZWFuXG4gIHRmLnJlc2V0KCk7XG5cbiAgLy8gYWRkIG1pbmltdW0gdmFsdWUgYXMgY29udHJvbCBwb2ludHMgcDAgYW5kIHAxXG4gIHRmLmNwcy5hZGQoe3g6IGJhc2V2YWx1ZUZuKGRhdGFbMF0pLCBmeDogMH0pO1xuICB0Zi5jcHMuYWRkKHt4OiBiYXNldmFsdWVGbihkYXRhWzBdKSwgZng6IDB9KTtcblxuICB2YXIgcCwgdmFsdWU7XG4gIGZvciAocCA9IDE7IHAgPCAxMDA7IHArKykge1xuICAgIHggPSAocCAqIDAuMDEpICogKGRhdGEubGVuZ3RoICsgMSkgLSAxOyAvLyBpbmRleGluZyBzdGFydHMgYXQgemVybywgbm90IGF0IG9uZVxuICAgIGkgPSBNYXRoLnRydW5jKHgpO1xuICAgIHZhbHVlID0gKDEgLSB4ICsgaSkgKiBiYXNldmFsdWVGbihkYXRhW2ldKSArICh4IC0gaSkgKiBiYXNldmFsdWVGbihkYXRhW2kgKyAxXSk7XG4gICAgdGYuY3BzLmFkZCh7eDogdmFsdWUsIGZ4OiBwfSk7XG4gIH1cblxuICAvLyBhZGQgbWF4aW11bSB2YWx1ZSBhcyBwMTAxIGFuZCBwMTAyXG4gIHRmLmNwcy5hZGQoe3g6IGJhc2V2YWx1ZUZuKGRhdGFbZGF0YS5sZW5ndGggLSAxXSksIGZ4OiAxMDB9KTtcbiAgdGYuY3BzLmFkZCh7eDogYmFzZXZhbHVlRm4oZGF0YVtkYXRhLmxlbmd0aCAtIDFdKSwgZng6IDEwMH0pO1xuXG4gIHRmLnR5cGUgPSAncGVyY2VudGlsZXMnO1xufVxuXG4vKipcbiAqIEF1dG9jb25maWd1cmUgYSBkYXRhc2V0OlxuICogMS4gcGljayAxMCByYW5kb20gZWxlbWVudHNcbiAqIDIuIGNyZWF0ZSBmYWNldHMgZm9yIHRoZWlyIHByb3BlcnRpZXNcbiAqIDMuIGFkZCBmYWNldHMnIHZhbHVlcyBvdmVyIHRoZSBzYW1wbGUgdG8gdGhlIGZhY2V0LmRlc2NyaXB0aW9uXG4gKiA0LiBzZXQgcmFuZ2Ugb3IgY2F0ZWdvcmllc1xuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICovXG5mdW5jdGlvbiBzY2FuIChkYXRhc2V0KSB7XG4gIGZ1bmN0aW9uIGZhY2V0RXhpc3RzIChmYWNldHMsIHBhdGgpIHtcbiAgICB2YXIgZXhpc3RzID0gZmFsc2U7XG4gICAgZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgIGlmIChmLmFjY2Vzc29yID09PSBwYXRoIHx8IGYuYWNjZXNzb3IgPT09IHBhdGggKyAnW10nKSB7XG4gICAgICAgIGV4aXN0cyA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGV4aXN0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFZhbHVlICh2YWx1ZXMsIHYsIG1pc3NpbmcpIHtcbiAgICBpZiAodiA9PT0gbWlzdmFsKSB7XG4gICAgICB2ID0gbWlzc2luZztcbiAgICB9XG4gICAgaWYgKHZhbHVlcy5pbmRleE9mKHYpID09PSAtMSkge1xuICAgICAgdmFsdWVzLnB1c2godik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZ3Vlc3NUeXBlICh2YWx1ZXMpIHtcbiAgICB2YXIgbXl0eXBlID0ge1xuICAgICAgY29udGludW91czogMCxcbiAgICAgIHRleHQ6IDAsXG4gICAgICBkYXRldGltZTogMCxcbiAgICAgIGR1cmF0aW9uOiAwLFxuICAgICAgY2F0ZWdvcmlhbDogMFxuICAgIH07XG4gICAgdmFsdWVzLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBpZiAobW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpLmlzVmFsaWQoKSkge1xuICAgICAgICAvLyBcIjIwMTYtMDgtMTcgMTc6MjU6MDArMDFcIlxuICAgICAgICBteXR5cGUuZGF0ZXRpbWUrKztcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgKG1vbWVudC5kdXJhdGlvbih2YWx1ZSkuYXNNaWxsaXNlY29uZHMoKSAhPT0gMCkgJiZcbiAgICAgICAgICAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgJiZcbiAgICAgICAgICAodmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSkge1xuICAgICAgICAvLyBcIlAxMFlcIlxuICAgICAgICBteXR5cGUuZHVyYXRpb24rKztcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gK3ZhbHVlKSB7ICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgICAgICAvLyBcIjEwXCIgb3IgMTBcbiAgICAgICAgbXl0eXBlLmNvbnRpbnVvdXMrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFwiaGVsbG8gd29ybGRcIlxuICAgICAgICBteXR5cGUuY2F0ZWdvcmlhbCsrO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gZ2V0IGZhY2V0VHlwZSB3aXRoIGhpZ2hlc3QgY291bnRcbiAgICB2YXIgbWF4ID0gLTE7XG4gICAgdmFyIGZhY2V0VHlwZTtcbiAgICBPYmplY3Qua2V5cyhteXR5cGUpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgaWYgKG15dHlwZVtrZXldID4gbWF4KSB7XG4gICAgICAgIGZhY2V0VHlwZSA9IGtleTtcbiAgICAgICAgbWF4ID0gbXl0eXBlW2tleV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZmFjZXRUeXBlO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJ5RmFjZXQgKGZhY2V0cywgZGF0YSwgcGF0aCwgdmFsdWUpIHtcbiAgICAvLyBDaGVjayBmb3IgZXhpc3RlbmNlXG4gICAgaWYgKGZhY2V0RXhpc3RzKGZhY2V0cywgcGF0aCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYSBuZXcgZmFjZXRcbiAgICB2YXIgZmFjZXQgPSBmYWNldHMuYWRkKHtcbiAgICAgIG5hbWU6IHBhdGgsXG4gICAgICBhY2Nlc3NvcjogcGF0aCxcbiAgICAgIHR5cGU6ICd0ZXh0J1xuICAgIH0pO1xuXG4gICAgLy8gU2FtcGxlIHZhbHVlc1xuICAgIHZhciBiYXNlVmFsdWVGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIHZhciBpc0FycmF5ID0gZmFsc2U7XG5cbiAgICBkYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGJhc2VWYWx1ZUZuKGQpO1xuICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgaXNBcnJheSA9IHRydWU7XG4gICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICBhZGRWYWx1ZSh2YWx1ZXMsIHYsIGZhY2V0Lm1pc3ZhbFswXSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWRkVmFsdWUodmFsdWVzLCB2YWx1ZSwgZmFjZXQubWlzdmFsWzBdKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFJlY29uZmlndXJlIGZhY2V0XG4gICAgZmFjZXQuYWNjZXNzb3IgPSBpc0FycmF5ID8gZmFjZXQuYWNjZXNzb3IgKyAnW10nIDogZmFjZXQuYWNjZXNzb3I7XG4gICAgZmFjZXQudHlwZSA9IGd1ZXNzVHlwZSh2YWx1ZXMpO1xuICAgIGZhY2V0LmRlc2NyaXB0aW9uID0gdmFsdWVzLmpvaW4oJywgJykubWF0Y2goJ14uezAsNDB9JykgKyAnLi4uJztcbiAgICBmYWNldC5pc0FjdGl2ZSA9IHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiByZWN1cnNlIChmYWNldHMsIGRhdGEsIHBhdGgsIHRyZWUpIHtcbiAgICB2YXIgcHJvcHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0cmVlKTtcbiAgICBwcm9wcy5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICB2YXIgc3VicGF0aDtcbiAgICAgIGlmIChwYXRoKSB7XG4gICAgICAgIHN1YnBhdGggPSBwYXRoICsgJyMjJyArIG5hbWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdWJwYXRoID0gbmFtZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRyZWVbbmFtZV0gaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAvLyBhZGQgYW4gYXJyYXkgYXMgYSBpdHNlbGYgYXMgYSBmYWNldCwgaWUuIGxhYmVsc2V0LCB0byBwcmV2ZW50IGFkZGluZyBlYWNoIGVsZW1lbnQgYXMgc2VwYXJhdGUgZmFjZXRcbiAgICAgICAgLy8gYWxzbyBhZGQgdGhlIGFycmF5IGxlbmd0aCBhcyBmYWNldFxuICAgICAgICB0cnlGYWNldChmYWNldHMsIGRhdGEsIHN1YnBhdGgsIHRyZWVbbmFtZV0pO1xuICAgICAgICB0cnlGYWNldChmYWNldHMsIGRhdGEsIHN1YnBhdGggKyAnLmxlbmd0aCcsIHRyZWVbbmFtZV0ubGVuZ3RoKTtcbiAgICAgIH0gZWxzZSBpZiAodHJlZVtuYW1lXSBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgICAgICAvLyByZWN1cnNlIGludG8gb2JqZWN0c1xuICAgICAgICByZWN1cnNlKGZhY2V0cywgZGF0YSwgc3VicGF0aCwgdHJlZVtuYW1lXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBhZGQgc3RyaW5ncyBhbmQgbnVtYmVycyBhcyBmYWNldHNcbiAgICAgICAgdHJ5RmFjZXQoZmFjZXRzLCBkYXRhLCBzdWJwYXRoLCB0cmVlW25hbWVdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIEFkZCBmYWNldHNcbiAgdmFyIGRhdGEgPSBkYXRhc2V0LmRhdGEuc2xpY2UoMCwgMTApO1xuICBkYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICByZWN1cnNlKGRhdGFzZXQuZmFjZXRzLCBkYXRhLCAnJywgZCk7XG4gIH0pO1xuXG4gIGRhdGFzZXQuZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgaWYgKGZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgc2V0Q2F0ZWdvcmllcyhkYXRhc2V0LCBmYWNldCk7XG4gICAgfSBlbHNlIGlmIChmYWNldC5pc0NvbnRpbnVvdXMgfHwgZmFjZXQuaXNEYXRldGltZSkge1xuICAgICAgc2V0TWluTWF4KGRhdGFzZXQsIGZhY2V0KTtcbiAgICB9XG4gIH0pO1xuICBkYXRhc2V0LnRyaWdnZXIoJ3N5bmNGYWNldHMnKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gaW5pdERhdGFGaWx0ZXIgKGRhdGF2aWV3LCBmaWx0ZXIpIHtcbiAgdmFyIGZhY2V0O1xuXG4gIC8vIHVzZSB0aGUgcGFydGl0aW9ucyBhcyBncm91cHM6XG4gIHZhciBncm91cEZucyA9IFtdO1xuICBmaWx0ZXIucGFydGl0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgICBmYWNldCA9IGRhdGF2aWV3LmZhY2V0cy5nZXQocGFydGl0aW9uLmZhY2V0TmFtZSwgJ25hbWUnKTtcbiAgICB2YXIgdmFsdWVGbiA9IHV0aWxkeC52YWx1ZUZuKGZhY2V0KTtcbiAgICB2YXIgZ3JvdXBGbiA9IHV0aWxkeC5ncm91cEZuKHBhcnRpdGlvbik7XG5cbiAgICB2YXIgcmFuayA9IHBhcnRpdGlvbi5yYW5rO1xuICAgIGdyb3VwRm5zW3JhbmsgLSAxXSA9IGZ1bmN0aW9uIChkKSB7XG4gICAgICByZXR1cm4gZ3JvdXBGbih2YWx1ZUZuKGQpKTtcbiAgICB9O1xuICB9KTtcblxuICAvLyBhbmQgdGhlbiBjcmVhdGUga2V5cyBmcm9tIHRoZSBncm91cCB2YWx1ZXNcbiAgdmFyIGdyb3Vwc0tleXMgPSBmdW5jdGlvbiAoZCkge1xuICAgIHZhciBrZXlzID0gW107XG5cbiAgICBncm91cEZucy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cEZuKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gZ3JvdXBGbihkKTtcbiAgICAgIHZhciBuZXdLZXlzID0gW107XG4gICAgICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgbmV3S2V5cyA9IHJlc3VsdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdLZXlzID0gW3Jlc3VsdF07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAob2xkS2V5KSB7XG4gICAgICAgICAgICByZXN1bHQuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgIG5ld0tleXMucHVzaChvbGRLZXkgKyAnfCcgKyBrZXkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChvbGRLZXkpIHtcbiAgICAgICAgICAgIG5ld0tleXMucHVzaChvbGRLZXkgKyAnfCcgKyByZXN1bHQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBrZXlzID0gbmV3S2V5cztcbiAgICB9KTtcbiAgICByZXR1cm4ga2V5cztcbiAgfTtcblxuICAvLyBzZXQgdXAgdGhlIGZhY2V0IHZhbHVlRm5zIHRvIGFnZ3JlZ2F0ZSBvdmVyXG4gIC8vIGFuZCB0aGUgcmVkdWN0aW9uIGZ1bmN0aW9ucyBmb3IgdGhlbVxuICB2YXIgYWdncmVnYXRlRm5zID0gW107XG4gIHZhciBhZ2dyZWdhdGVSYW5rcyA9IFtdO1xuICB2YXIgcmVkdWNlRm5zID0gW107XG4gIGZpbHRlci5hZ2dyZWdhdGVzLmZvckVhY2goZnVuY3Rpb24gKGFnZ3JlZ2F0ZSkge1xuICAgIGZhY2V0ID0gZGF0YXZpZXcuZmFjZXRzLmdldChhZ2dyZWdhdGUuZmFjZXROYW1lLCAnbmFtZScpO1xuICAgIGFnZ3JlZ2F0ZVJhbmtzLnB1c2goYWdncmVnYXRlLnJhbmspO1xuICAgIGFnZ3JlZ2F0ZUZucy5wdXNoKHV0aWxkeC52YWx1ZUZuKGZhY2V0KSk7XG4gICAgcmVkdWNlRm5zLnB1c2godXRpbGR4LnJlZHVjZUZuKGFnZ3JlZ2F0ZSkpO1xuICB9KTtcblxuICAvLyBzZXR1cCB0aGUgY3Jvc3NmaWx0ZXIgZGltZW5zaW9ucyBhbmQgZ3JvdXBzXG4gIGZpbHRlci5kaW1lbnNpb24gPSBkYXRhdmlldy5jcm9zc2ZpbHRlci5kaW1lbnNpb24oZnVuY3Rpb24gKGQpIHtcbiAgICByZXR1cm4gZ3JvdXBzS2V5cyhkKTtcbiAgfSwgdHJ1ZSk7XG4gIHZhciBjcm9zc2ZpbHRlckdyb3VwID0gZmlsdGVyLmRpbWVuc2lvbi5ncm91cChmdW5jdGlvbiAoZCkgeyByZXR1cm4gZDsgfSk7XG5cbiAgY3Jvc3NmaWx0ZXJHcm91cC5yZWR1Y2UoXG4gICAgLy8gYWRkXG4gICAgZnVuY3Rpb24gKHAsIGQpIHtcbiAgICAgIGlmIChhZ2dyZWdhdGVGbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHBbMF0gPSBwWzBdID8gcFswXSA6IHtjb3VudDogMH07XG4gICAgICAgIHBbMF0uY291bnQgKz0gMTtcbiAgICAgIH1cblxuICAgICAgYWdncmVnYXRlRm5zLmZvckVhY2goZnVuY3Rpb24gKGFnZ3JlZ2F0ZUZuLCBpKSB7XG4gICAgICAgIHZhciB2YWwgPSBhZ2dyZWdhdGVGbihkKTtcbiAgICAgICAgaWYgKHZhbCAhPT0gbWlzdmFsKSB7XG4gICAgICAgICAgdmFsID0gcGFyc2VGbG9hdCh2YWwpO1xuICAgICAgICAgIHBbaV0gPSBwW2ldIHx8IHtjb3VudDogMCwgc3VtOiAwLCBzdW1zcXVhcmVzOiAwfTtcbiAgICAgICAgICBwW2ldLmNvdW50ICs9IDE7XG4gICAgICAgICAgcFtpXS5zdW0gKz0gdmFsO1xuICAgICAgICAgIHBbaV0uc3Vtc3F1YXJlcyArPSB2YWwgKiB2YWw7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHA7XG4gICAgfSxcbiAgICAvLyBzdWJ0cmFjdFxuICAgIGZ1bmN0aW9uIChwLCBkKSB7XG4gICAgICBpZiAoYWdncmVnYXRlRm5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBwWzBdID0gcFswXSA/IHBbMF0gOiB7Y291bnQ6IDB9O1xuICAgICAgICBwWzBdLmNvdW50IC09IDE7XG4gICAgICB9XG5cbiAgICAgIGFnZ3JlZ2F0ZUZucy5mb3JFYWNoKGZ1bmN0aW9uIChhZ2dyZWdhdGVGbiwgaSkge1xuICAgICAgICB2YXIgdmFsID0gYWdncmVnYXRlRm4oZCk7XG4gICAgICAgIGlmICh2YWwgIT09IG1pc3ZhbCkge1xuICAgICAgICAgIHZhbCA9IHBhcnNlRmxvYXQodmFsKTtcbiAgICAgICAgICBwW2ldID0gcFtpXSB8fCB7Y291bnQ6IDAsIHN1bTogMCwgc3Vtc3F1YXJlczogMH07XG4gICAgICAgICAgcFtpXS5jb3VudCAtPSAxO1xuICAgICAgICAgIHBbaV0uc3VtIC09IHZhbDtcbiAgICAgICAgICBwW2ldLnN1bXNxdWFyZXMgLT0gdmFsICogdmFsO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBwO1xuICAgIH0sXG4gICAgLy8gaW5pdGlhbGl6ZVxuICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICk7XG5cbiAgZmlsdGVyLmdldERhdGEgPSBmdW5jdGlvbiAoKSB7XG4gICAgZmlsdGVyLmRhdGEgPSBbXTtcblxuICAgIC8vIEdldCBkYXRhIGZyb20gY3Jvc3NmaWx0ZXJcbiAgICB2YXIgZ3JvdXBzID0gY3Jvc3NmaWx0ZXJHcm91cC5hbGwoKTtcblxuICAgIC8vIHsga2V5OiBcImdyb3VwMXxncm91cDJ8Li4uXCIsXG4gICAgLy8gICB2YWx1ZTogWyB7Y291bnQ6IGFnZzEsIHN1bTogYWdnMX1cbiAgICAvLyAgICAgICAgICAgIHtjb3VudDogYWdnMiwgc3VtOiBhZ2cyfVxuICAgIC8vICAgICAgICAgICAge2NvdW50OiBhZ2czLCBzdW06IGFnZzN9XG4gICAgLy8gICAgICAgICAgICAgICAgICAgIC4uLiAgICAgICAgICAgICBdfVxuICAgIGdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgdmFyIGl0ZW0gPSB7fTtcblxuICAgICAgLy8gdHVybiB0aGUgc3RyaW5nIGJhY2sgaW50byBpbmRpdmlkdWFsIGdyb3VwIHZhbHVlc1xuICAgICAgdmFyIGdyb3Vwc0tleXM7XG4gICAgICBpZiAodHlwZW9mIGdyb3VwLmtleSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZ3JvdXBzS2V5cyA9IGdyb3VwLmtleS5zcGxpdCgnfCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gc2hvcnRjdXQgZm9yIG51bWVyaWMgbm9uLXBhcnRpdGlvbmVkIGNhc2VcbiAgICAgICAgZ3JvdXBzS2V5cyA9IFtncm91cC5rZXldO1xuICAgICAgfVxuXG4gICAgICAvLyBhZGQgcGFyaXRpb25pbmcgZGF0YSB0byB0aGUgaXRlbVxuICAgICAgZ3JvdXBzS2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChzdWJrZXksIGkpIHtcbiAgICAgICAgaXRlbVtncnBJZHhUb05hbWVbaV1dID0gc3Via2V5O1xuICAgICAgfSk7XG5cbiAgICAgIC8vIGFkZCBhZ2dyZWdhdGVkIGRhdGEgdG8gdGhlIGl0ZW1cbiAgICAgIHJlZHVjZUZucy5mb3JFYWNoKGZ1bmN0aW9uIChyZWR1Y2VGbiwgaSkge1xuICAgICAgICB2YXIgbmFtZSA9IGFnZ1JhbmtUb05hbWVbYWdncmVnYXRlUmFua3NbaV1dO1xuICAgICAgICBpdGVtW25hbWVdID0gcmVkdWNlRm4oZ3JvdXAudmFsdWVbaV0pO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIGFkZCBhbiBvdmVyYWxsIGNvdW50XG4gICAgICAvLyBiZWN1YXNlIHRoZSBmaWx0ZXJpbmcgcmVtb3ZlcyBtaXNzaW5nIGRhdGEgcG9pbnRzLCB0aGlzIGlzIHRoZSBzYW1lIGFzXG4gICAgICAvLyB0aGUgY291bnQgZm9yIGFueSBvbmUgb2YgdGhlIGFnZ3JlZ2F0ZXNcbiAgICAgIGl0ZW0uY291bnQgPSBncm91cC52YWx1ZVswXSA/IGdyb3VwLnZhbHVlWzBdLmNvdW50IDogMDtcblxuICAgICAgZmlsdGVyLmRhdGEucHVzaChpdGVtKTtcbiAgICB9KTtcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGUgb3Bwb3NpdGUgb3IgaW5pdERhdGFGaWx0ZXIsIGl0IHNob3VsZCByZW1vdmUgdGhlIGZpbHRlciBhbmQgZGVhbGxvY2F0ZSBvdGhlciBjb25maWd1cmF0aW9uXG4gKiByZWxhdGVkIHRvIHRoZSBmaWx0ZXIuXG4gKiBAcGFyYW0ge0RhdGF2aWV3fSBkYXRhdmlld1xuICogQHBhcmFtIHtGaWx0ZXJ9IGZpbHRlclxuICovXG5mdW5jdGlvbiByZWxlYXNlRGF0YUZpbHRlciAoZGF0YXZpZXcsIGZpbHRlcikge1xuICBpZiAoZmlsdGVyLmRpbWVuc2lvbikge1xuICAgIGZpbHRlci5kaW1lbnNpb24uZmlsdGVyQWxsKCk7XG4gICAgZmlsdGVyLmRpbWVuc2lvbi5kaXNwb3NlKCk7XG4gICAgZGVsZXRlIGZpbHRlci5kaW1lbnNpb247XG4gICAgZGVsZXRlIGZpbHRlci5nZXREYXRhO1xuICB9XG59XG5cbi8qKlxuICogQ2hhbmdlIHRoZSBmaWx0ZXIgcGFyYW1ldGVycyBmb3IgYW4gaW5pdGlhbGl6ZWQgZmlsdGVyXG4gKiBAcGFyYW0ge0ZpbHRlcn0gZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZURhdGFGaWx0ZXIgKGZpbHRlcikge1xuICBpZiAoZmlsdGVyLmRpbWVuc2lvbikge1xuICAgIGZpbHRlci5kaW1lbnNpb24uZmlsdGVyRnVuY3Rpb24oZmlsdGVyLmZpbHRlckZ1bmN0aW9uKCkpO1xuICB9XG59XG5cbi8qKlxuICogR2V0IGRhdGEgZm9yIGV2ZXJ5IGZpbHRlciwgYW5kIHRyaWdnZXIgYSAnbmV3RGF0YScgZXZlbnRcbiAqXG4gKiBSZXR1cm5zIGEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkYXRhdmlldyB3aGVuIGFsbCBkYXRhIGFuZCBtZXRhZGF0YSBoYXMgYmVlbiB1cGRhdGVkXG4gKlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEByZXR1cm5zIHtQcm9taXNlfVxuICovXG5mdW5jdGlvbiBnZXREYXRhIChkYXRhdmlldykge1xuICBkYXRhdmlldy5maWx0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpbHRlcikge1xuICAgIGlmIChmaWx0ZXIuaXNJbml0aWFsaXplZCkge1xuICAgICAgZmlsdGVyLmdldERhdGEoKTtcbiAgICAgIGZpbHRlci50cmlnZ2VyKCduZXdEYXRhJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyB1cGRhdGUgY291bnRzXG4gIGRhdGF2aWV3LmRhdGFUb3RhbCA9IGRhdGF2aWV3LmNyb3NzZmlsdGVyLnNpemUoKTtcbiAgZGF0YXZpZXcuZGF0YVNlbGVjdGVkID0gZGF0YXZpZXcuY291bnRHcm91cC52YWx1ZSgpO1xuICBkYXRhdmlldy50cmlnZ2VyKCduZXdNZXRhRGF0YScpO1xuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoZGF0YXZpZXcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZHJpdmVyVHlwZTogJ2NsaWVudCcsXG4gIHNjYW46IHNjYW4sXG4gIHNldE1pbk1heDogc2V0TWluTWF4LFxuICBzZXRDYXRlZ29yaWVzOiBzZXRDYXRlZ29yaWVzLFxuICBzZXRQZXJjZW50aWxlczogc2V0UGVyY2VudGlsZXMsXG4gIGluaXREYXRhRmlsdGVyOiBpbml0RGF0YUZpbHRlcixcbiAgcmVsZWFzZURhdGFGaWx0ZXI6IHJlbGVhc2VEYXRhRmlsdGVyLFxuICB1cGRhdGVEYXRhRmlsdGVyOiB1cGRhdGVEYXRhRmlsdGVyLFxuICBnZXREYXRhOiBnZXREYXRhXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///720c\n")},"780f":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {\n/**\n * Module dependencies.\n */\n\nvar parseuri = __webpack_require__(/*! parseuri */ \"64a0\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:url');\n\n/**\n * Module exports.\n */\n\nmodule.exports = url;\n\n/**\n * URL parser.\n *\n * @param {String} url\n * @param {Object} An object meant to mimic window.location.\n *                 Defaults to window.location.\n * @api public\n */\n\nfunction url (uri, loc) {\n  var obj = uri;\n\n  // default to window.location\n  loc = loc || global.location;\n  if (null == uri) uri = loc.protocol + '//' + loc.host;\n\n  // relative path support\n  if ('string' === typeof uri) {\n    if ('/' === uri.charAt(0)) {\n      if ('/' === uri.charAt(1)) {\n        uri = loc.protocol + uri;\n      } else {\n        uri = loc.host + uri;\n      }\n    }\n\n    if (!/^(https?|wss?):\\/\\//.test(uri)) {\n      debug('protocol-less url %s', uri);\n      if ('undefined' !== typeof loc) {\n        uri = loc.protocol + '//' + uri;\n      } else {\n        uri = 'https://' + uri;\n      }\n    }\n\n    // parse\n    debug('parse %s', uri);\n    obj = parseuri(uri);\n  }\n\n  // make sure we treat `localhost:80` and `localhost` equally\n  if (!obj.port) {\n    if (/^(http|ws)$/.test(obj.protocol)) {\n      obj.port = '80';\n    } else if (/^(http|ws)s$/.test(obj.protocol)) {\n      obj.port = '443';\n    }\n  }\n\n  obj.path = obj.path || '/';\n\n  var ipv6 = obj.host.indexOf(':') !== -1;\n  var host = ipv6 ? '[' + obj.host + ']' : obj.host;\n\n  // define unique id\n  obj.id = obj.protocol + '://' + host + ':' + obj.port;\n  // define href\n  obj.href = obj.protocol + '://' + host + (loc && loc.port === obj.port ? '' : (':' + obj.port));\n\n  return obj;\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzgwZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvdXJsLmpzPzAwMGMiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNldXJpID0gcmVxdWlyZSgncGFyc2V1cmknKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6dXJsJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSB1cmw7XG5cbi8qKlxuICogVVJMIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge09iamVjdH0gQW4gb2JqZWN0IG1lYW50IHRvIG1pbWljIHdpbmRvdy5sb2NhdGlvbi5cbiAqICAgICAgICAgICAgICAgICBEZWZhdWx0cyB0byB3aW5kb3cubG9jYXRpb24uXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIHVybCAodXJpLCBsb2MpIHtcbiAgdmFyIG9iaiA9IHVyaTtcblxuICAvLyBkZWZhdWx0IHRvIHdpbmRvdy5sb2NhdGlvblxuICBsb2MgPSBsb2MgfHwgZ2xvYmFsLmxvY2F0aW9uO1xuICBpZiAobnVsbCA9PSB1cmkpIHVyaSA9IGxvYy5wcm90b2NvbCArICcvLycgKyBsb2MuaG9zdDtcblxuICAvLyByZWxhdGl2ZSBwYXRoIHN1cHBvcnRcbiAgaWYgKCdzdHJpbmcnID09PSB0eXBlb2YgdXJpKSB7XG4gICAgaWYgKCcvJyA9PT0gdXJpLmNoYXJBdCgwKSkge1xuICAgICAgaWYgKCcvJyA9PT0gdXJpLmNoYXJBdCgxKSkge1xuICAgICAgICB1cmkgPSBsb2MucHJvdG9jb2wgKyB1cmk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cmkgPSBsb2MuaG9zdCArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIS9eKGh0dHBzP3x3c3M/KTpcXC9cXC8vLnRlc3QodXJpKSkge1xuICAgICAgZGVidWcoJ3Byb3RvY29sLWxlc3MgdXJsICVzJywgdXJpKTtcbiAgICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGxvYykge1xuICAgICAgICB1cmkgPSBsb2MucHJvdG9jb2wgKyAnLy8nICsgdXJpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdXJpID0gJ2h0dHBzOi8vJyArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBwYXJzZVxuICAgIGRlYnVnKCdwYXJzZSAlcycsIHVyaSk7XG4gICAgb2JqID0gcGFyc2V1cmkodXJpKTtcbiAgfVxuXG4gIC8vIG1ha2Ugc3VyZSB3ZSB0cmVhdCBgbG9jYWxob3N0OjgwYCBhbmQgYGxvY2FsaG9zdGAgZXF1YWxseVxuICBpZiAoIW9iai5wb3J0KSB7XG4gICAgaWYgKC9eKGh0dHB8d3MpJC8udGVzdChvYmoucHJvdG9jb2wpKSB7XG4gICAgICBvYmoucG9ydCA9ICc4MCc7XG4gICAgfSBlbHNlIGlmICgvXihodHRwfHdzKXMkLy50ZXN0KG9iai5wcm90b2NvbCkpIHtcbiAgICAgIG9iai5wb3J0ID0gJzQ0Myc7XG4gICAgfVxuICB9XG5cbiAgb2JqLnBhdGggPSBvYmoucGF0aCB8fCAnLyc7XG5cbiAgdmFyIGlwdjYgPSBvYmouaG9zdC5pbmRleE9mKCc6JykgIT09IC0xO1xuICB2YXIgaG9zdCA9IGlwdjYgPyAnWycgKyBvYmouaG9zdCArICddJyA6IG9iai5ob3N0O1xuXG4gIC8vIGRlZmluZSB1bmlxdWUgaWRcbiAgb2JqLmlkID0gb2JqLnByb3RvY29sICsgJzovLycgKyBob3N0ICsgJzonICsgb2JqLnBvcnQ7XG4gIC8vIGRlZmluZSBocmVmXG4gIG9iai5ocmVmID0gb2JqLnByb3RvY29sICsgJzovLycgKyBob3N0ICsgKGxvYyAmJiBsb2MucG9ydCA9PT0gb2JqLnBvcnQgPyAnJyA6ICgnOicgKyBvYmoucG9ydCkpO1xuXG4gIHJldHVybiBvYmo7XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///780f\n")},"7d91":function(module,exports){eval("\n/**\n * Gets the keys for an object.\n *\n * @return {Array} keys\n * @api private\n */\n\nmodule.exports = Object.keys || function keys (obj){\n  var arr = [];\n  var has = Object.prototype.hasOwnProperty;\n\n  for (var i in obj) {\n    if (has.call(obj, i)) {\n      arr.push(i);\n    }\n  }\n  return arr;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2Q5MS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIva2V5cy5qcz83NTljIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBHZXRzIHRoZSBrZXlzIGZvciBhbiBvYmplY3QuXG4gKlxuICogQHJldHVybiB7QXJyYXl9IGtleXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ga2V5cyAob2JqKXtcbiAgdmFyIGFyciA9IFtdO1xuICB2YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGkpKSB7XG4gICAgICBhcnIucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycjtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7d91\n")},"7fa4":function(module,exports,__webpack_require__){eval('var Collection = __webpack_require__(/*! ampersand-collection */ "7bd3");\nvar Filter = __webpack_require__(/*! ../filter */ "9476");\n\nmodule.exports = Collection.extend({\n  mainIndex: \'id\',\n  model: Filter,\n  comparator: function (a, b) {\n    if (a.row > b.row || a.row === b.row && a.col > b.col) {\n      return 1;\n    }\n    if (a.col === b.col) {\n      return 0;\n    }\n    return -1;\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2ZhNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmlsdGVyL2NvbGxlY3Rpb24uanM/ODgyYyJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgRmlsdGVyID0gcmVxdWlyZSgnLi4vZmlsdGVyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtYWluSW5kZXg6ICdpZCcsXG4gIG1vZGVsOiBGaWx0ZXIsXG4gIGNvbXBhcmF0b3I6IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgaWYgKGEucm93ID4gYi5yb3cgfHwgYS5yb3cgPT09IGIucm93ICYmIGEuY29sID4gYi5jb2wpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICBpZiAoYS5jb2wgPT09IGIuY29sKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7fa4\n')},8191:function(module,exports,__webpack_require__){eval("/**\n * Partition\n *\n * Describes a partitioning of the data, based on the values a Facet can take.\n *\n * @class Partition\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Groups = __webpack_require__(/*! ./partition/group-collection */ \"0056\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar selection = __webpack_require__(/*! ./util/selection */ \"1278\");\nvar util = __webpack_require__(/*! ./util/time */ \"d45b\");\n\n/*\n * @param {Partition} partition\n * @param {Group[]} groups\n * @memberof! Partition\n */\nfunction setDatetimeGroups (partition, groups) {\n  var timeStart = partition.minval;\n  var timeEnd = partition.maxval;\n  var timeRes = util.getDatetimeResolution(timeStart, timeEnd);\n  var timeZone = partition.zone;\n\n  var current = moment(timeStart);\n  while ((!current.isAfter(timeEnd)) && groups.length < 500) {\n    groups.add({\n      min: moment(current).tz(timeZone).startOf(timeRes),\n      max: moment(current).tz(timeZone).endOf(timeRes),\n      value: moment(current).tz(timeZone).startOf(timeRes).format(),\n      label: moment(current).tz(timeZone).startOf(timeRes).format()\n    });\n    current.add(1, timeRes);\n  }\n}\n\n/*\n * @param {Partition} partition\n * @param {Group[]} groups\n * @memberof! Partition\n */\nfunction setDurationGroups (partition, groups) {\n  var dStart = partition.minval;\n  var dEnd = partition.maxval;\n  var dRes = util.getDurationResolution(dStart, dEnd);\n\n  var current = Math.floor(parseFloat(dStart.as(dRes)));\n  var last = Math.floor(parseFloat(dEnd.as(dRes)));\n\n  while (current < last) {\n    groups.add({\n      min: moment.duration(current, dRes),\n      max: moment.duration(current + 1, dRes),\n      value: moment.duration(current, dRes).toISOString(),\n      label: moment.duration(current, dRes).toISOString()\n    });\n\n    current = current + 1;\n  }\n}\n\n/*\n * Setup a grouping based on the `partition.groupingContinuous`, `partition.minval`,\n * `partition.maxval`, and the `partition.groupingParam`.\n * @memberof! Partition\n * @param {Partition} partition\n * @param {Group[]} groups\n */\nfunction setContinuousGroups (partition, groups) {\n  var param = partition.groupingParam;\n  var x0, x1, size, nbins;\n\n  if (partition.groupFixedN) {\n    // A fixed number of equally sized bins\n    nbins = param;\n    x0 = partition.minval;\n    x1 = partition.maxval;\n    size = (x1 - x0) / nbins;\n  } else if (partition.groupFixedS) {\n    // A fixed bin size\n    size = param;\n    x0 = Math.floor(partition.minval / size) * size;\n    x1 = Math.ceil(partition.maxval / size) * size;\n    nbins = (x1 - x0) / size;\n  } else if (partition.groupFixedSC) {\n    // A fixed bin size, centered on 0\n    size = param;\n    x0 = (Math.floor(partition.minval / size) - 0.5) * size;\n    x1 = (Math.ceil(partition.maxval / size) + 0.5) * size;\n    nbins = (x1 - x0) / size;\n  } else if (partition.groupLog) {\n    // Fixed number of logarithmically (base 10) sized bins\n    nbins = param;\n    x0 = Math.log(partition.minval) / Math.log(10.0);\n    x1 = Math.log(partition.maxval) / Math.log(10.0);\n    size = (x1 - x0) / nbins;\n  }\n\n  function unlog (x) {\n    return Math.exp(x * Math.log(10));\n  }\n\n  var i;\n  for (i = 0; i < nbins; i++) {\n    var start = x0 + i * size;\n    var end = x0 + (i + 1) * size;\n    var mid = 0.5 * (start + end);\n\n    if (partition.groupLog) {\n      groups.add({\n        min: unlog(start),\n        max: unlog(end),\n        value: unlog(start),\n        label: unlog(end).toPrecision(5)\n      });\n    } else {\n      groups.add({\n        min: start,\n        max: end,\n        value: mid,\n        label: mid.toPrecision(5)\n      });\n    }\n  }\n}\n\n/*\n * Setup a grouping based on the `partition.categorialTransform`\n * @memberof! Partition\n * @param {Partition} partition\n * @param {Group[]} groups\n */\nfunction setCategorialGroups (partition, groups) {\n  // dataview -> filters -> filter -> partitions -> partition\n  //          -> facets\n\n  var dataview;\n  var facet;\n  try {\n    dataview = partition.collection.parent.collection.parent;\n    facet = dataview.facets.get(partition.facetName, 'name');\n  } catch (e) {\n    console.error('setCategorialGroups: cannot locate facet for this partition');\n    return;\n  }\n\n  if (facet.isCategorial) {\n    // default: a categorial facet, with a categorial parittion\n    facet.categorialTransform.rules.forEach(function (rule, i) {\n      groups.add({\n        value: rule.group,\n        label: rule.group,\n        count: rule.count\n      });\n    });\n  } else if (facet.isDatetime) {\n    var format = facet.datetimeTransform.transformedFormat;\n    var timePart = util.timeParts.get(format, 'description');\n\n    timePart.groups.forEach(function (g, i) {\n      groups.add({\n        value: g,\n        label: g,\n        count: 0\n      });\n    });\n  } else {\n    console.warn('Not implemented');\n  }\n}\n\n/**\n * Reset type, minimum and maximum values\n * @params {Partition} partition\n * @params {Object} Options - silent do not trigger change events\n * @memberof! Partition\n */\nfunction reset (options) {\n  var partition = this;\n  // partition -> partitions -> filter -> filters -> dataview\n  var filter = partition.collection.parent;\n  var dataview = filter.collection.parent;\n  var facet = dataview.facets.get(partition.facetName, 'name');\n  options = options || {};\n\n  partition.set({\n    type: facet.transform.transformedType,\n    minval: facet.transform.transformedMin,\n    maxval: facet.transform.transformedMax\n  }, options);\n}\n\nmodule.exports = BaseModel.extend({\n  dataTypes: {\n    'numberDatetimeOrDuration': {\n      set: function (value) {\n        var newValue;\n\n        // check for momentjs objects\n        if (moment.isDuration(value)) {\n          return {\n            val: moment.duration(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (moment.isMoment(value)) {\n          return {\n            val: value.clone(),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to create momentjs objects\n        newValue = moment(value, moment.ISO_8601);\n        if (newValue.isValid()) {\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          newValue = moment.duration(value);\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to set a number\n        if (value === +value) {\n          return {\n            val: +value,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // failed..\n        return {\n          val: value,\n          type: typeof value\n        };\n      },\n      compare: function (currentVal, newVal) {\n        if (currentVal instanceof moment) {\n          return currentVal.isSame(newVal);\n        } else {\n          return +currentVal === +newVal;\n        }\n      }\n    }\n  },\n  props: {\n    /**\n     * Label for displaying on plots\n     * @memberof! Partition\n     * @type {string}\n     */\n    label: {\n      type: 'string',\n      required: true,\n      default: ''\n    },\n    /**\n     * Show a legend for this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    showLegend: {\n      type: 'boolean',\n      required: false,\n      default: true\n    },\n    /**\n     * Show an axis label for this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    showLabel: {\n      type: 'boolean',\n      required: false,\n      default: true\n    },\n\n    /**\n     * Timezone for partitioning\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    zone: {\n      type: 'string',\n      required: 'true',\n      default: function () {\n        return moment.tz.guess();\n      }\n    },\n\n    /**\n     * Type of this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['constant', 'continuous', 'categorial', 'datetime', 'duration', 'text']\n    },\n\n    /**\n     * The name of the facet to partition over\n     * @memberof! Partition\n     * @type {string}\n     */\n    facetName: 'string',\n\n    /**\n     * When part of a partitioning, this deterimines the ordering\n     * @memberof! Partition\n     * @type {number}\n     */\n    rank: {\n      type: 'number',\n      required: true\n    },\n\n    /**\n     * For categorial and text Facets, the ordering can be alfabetical or by count\n     * @memberof! Partition\n     */\n    ordering: {\n      type: 'string',\n      values: ['count', 'value'],\n      required: true,\n      default: 'value'\n    },\n\n    /**\n     * For continuous or datetime Facets, the minimum value. Values lower than this are grouped to 'missing'\n     * @memberof! Partition\n     * @type {number|moment}\n     */\n    minval: 'numberDatetimeOrDuration',\n\n    /**\n     * For continuous or datetime Facets, the maximum value. Values higher than this are grouped to 'missing'\n     * @memberof! Partition\n     * @type {number|moment}\n     */\n    maxval: 'numberDatetimeOrDuration',\n\n    /**\n     * Extra parameter used in the grouping strategy: either the number of bins, or the bin size.\n     * @memberof! Partition\n     * @type {number}\n     */\n    groupingParam: ['number', true, 20],\n\n    /**\n     * Grouping strategy:\n     *  * `fixedn`  fixed number of bins in the interval [minval, maxval]\n     *  * `fixedsc` a fixed binsize, centered on zero\n     *  * `fixeds`  a fixed binsize, starting at zero\n     *  * `log`     fixed number of bins but on a logarithmic scale\n     * Don't use directly but check grouping via the groupFixedN, groupFixedSC,\n     * groupFixedS, and groupLog properties\n     * @memberof! Partition\n     * @type {number}\n     */\n    groupingContinuous: {\n      type: 'string',\n      required: true,\n      default: 'fixedn',\n      values: ['fixedn', 'fixedsc', 'fixeds', 'log']\n    },\n\n    /**\n     * Depending on the type of partition, this can be an array of the selected groups,\n     * or a numberic interval [start, end]\n     * @memberof! Partition\n     * @type {array}\n     */\n    // NOTE: for categorial facets, contains rule.group\n    selected: {\n      type: 'array',\n      required: true,\n      default: function () {\n        return [];\n      }\n    }\n  },\n  derived: {\n    // properties for: type\n    isConstant: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'constant';\n      }\n    },\n    isContinuous: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'continuous';\n      }\n    },\n    isCategorial: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'categorial';\n      }\n    },\n    isDatetime: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'datetime';\n      }\n    },\n    isDuration: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'duration';\n      }\n    },\n    isText: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'text';\n      }\n    },\n    // properties for grouping-continuous\n    groupFixedN: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixedn';\n      }\n    },\n    groupFixedSC: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixedsc';\n      }\n    },\n    groupFixedS: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixeds';\n      }\n    },\n    groupLog: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'log';\n      }\n    },\n    /**\n     * The (ordered) set of groups this Partition can take, making up this partition.\n     * The list is recalculated when any of the partition's properties change:\n     * 'groupingContinuous', 'groupingParam', 'minval', 'maxval', 'type', 'zone' change\n     * The list keeps itself sorted according to the partition.ordering\n     *\n     * Can be used for plotting etc.\n     * @memberof! Partition\n     * @type {Group[]}\n     */\n    groups: {\n      deps: ['groupingContinuous', 'groupingParam', 'minval', 'maxval', 'type', 'zone'],\n      fn: function () {\n        var partition = this;\n        var groups = new Groups([], {\n          parent: partition\n        });\n\n        if (partition.isCategorial) {\n          setCategorialGroups(partition, groups);\n        } else if (partition.isContinuous) {\n          setContinuousGroups(partition, groups);\n        } else if (partition.isDatetime) {\n          setDatetimeGroups(partition, groups);\n        } else if (partition.isDuration) {\n          setDurationGroups(partition, groups);\n        } else if (partition.isText) {\n          // no-op\n        } else {\n          console.error('Cannot set groups for partition', partition.getId());\n        }\n\n        return groups;\n      }\n    }\n  },\n  updateSelection: function (group) {\n    selection.updateSelection(this, group);\n  },\n  filterFunction: function () {\n    return selection.filterFunction(this);\n  },\n  reset: reset\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODE5MS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uLmpzPzUzODciXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQYXJ0aXRpb25cbiAqXG4gKiBEZXNjcmliZXMgYSBwYXJ0aXRpb25pbmcgb2YgdGhlIGRhdGEsIGJhc2VkIG9uIHRoZSB2YWx1ZXMgYSBGYWNldCBjYW4gdGFrZS5cbiAqXG4gKiBAY2xhc3MgUGFydGl0aW9uXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBCYXNlTW9kZWwgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIEdyb3VwcyA9IHJlcXVpcmUoJy4vcGFydGl0aW9uL2dyb3VwLWNvbGxlY3Rpb24nKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciBzZWxlY3Rpb24gPSByZXF1aXJlKCcuL3V0aWwvc2VsZWN0aW9uJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbC90aW1lJyk7XG5cbi8qXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKiBAcGFyYW0ge0dyb3VwW119IGdyb3Vwc1xuICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAqL1xuZnVuY3Rpb24gc2V0RGF0ZXRpbWVHcm91cHMgKHBhcnRpdGlvbiwgZ3JvdXBzKSB7XG4gIHZhciB0aW1lU3RhcnQgPSBwYXJ0aXRpb24ubWludmFsO1xuICB2YXIgdGltZUVuZCA9IHBhcnRpdGlvbi5tYXh2YWw7XG4gIHZhciB0aW1lUmVzID0gdXRpbC5nZXREYXRldGltZVJlc29sdXRpb24odGltZVN0YXJ0LCB0aW1lRW5kKTtcbiAgdmFyIHRpbWVab25lID0gcGFydGl0aW9uLnpvbmU7XG5cbiAgdmFyIGN1cnJlbnQgPSBtb21lbnQodGltZVN0YXJ0KTtcbiAgd2hpbGUgKCghY3VycmVudC5pc0FmdGVyKHRpbWVFbmQpKSAmJiBncm91cHMubGVuZ3RoIDwgNTAwKSB7XG4gICAgZ3JvdXBzLmFkZCh7XG4gICAgICBtaW46IG1vbWVudChjdXJyZW50KS50eih0aW1lWm9uZSkuc3RhcnRPZih0aW1lUmVzKSxcbiAgICAgIG1heDogbW9tZW50KGN1cnJlbnQpLnR6KHRpbWVab25lKS5lbmRPZih0aW1lUmVzKSxcbiAgICAgIHZhbHVlOiBtb21lbnQoY3VycmVudCkudHoodGltZVpvbmUpLnN0YXJ0T2YodGltZVJlcykuZm9ybWF0KCksXG4gICAgICBsYWJlbDogbW9tZW50KGN1cnJlbnQpLnR6KHRpbWVab25lKS5zdGFydE9mKHRpbWVSZXMpLmZvcm1hdCgpXG4gICAgfSk7XG4gICAgY3VycmVudC5hZGQoMSwgdGltZVJlcyk7XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7R3JvdXBbXX0gZ3JvdXBzXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBzZXREdXJhdGlvbkdyb3VwcyAocGFydGl0aW9uLCBncm91cHMpIHtcbiAgdmFyIGRTdGFydCA9IHBhcnRpdGlvbi5taW52YWw7XG4gIHZhciBkRW5kID0gcGFydGl0aW9uLm1heHZhbDtcbiAgdmFyIGRSZXMgPSB1dGlsLmdldER1cmF0aW9uUmVzb2x1dGlvbihkU3RhcnQsIGRFbmQpO1xuXG4gIHZhciBjdXJyZW50ID0gTWF0aC5mbG9vcihwYXJzZUZsb2F0KGRTdGFydC5hcyhkUmVzKSkpO1xuICB2YXIgbGFzdCA9IE1hdGguZmxvb3IocGFyc2VGbG9hdChkRW5kLmFzKGRSZXMpKSk7XG5cbiAgd2hpbGUgKGN1cnJlbnQgPCBsYXN0KSB7XG4gICAgZ3JvdXBzLmFkZCh7XG4gICAgICBtaW46IG1vbWVudC5kdXJhdGlvbihjdXJyZW50LCBkUmVzKSxcbiAgICAgIG1heDogbW9tZW50LmR1cmF0aW9uKGN1cnJlbnQgKyAxLCBkUmVzKSxcbiAgICAgIHZhbHVlOiBtb21lbnQuZHVyYXRpb24oY3VycmVudCwgZFJlcykudG9JU09TdHJpbmcoKSxcbiAgICAgIGxhYmVsOiBtb21lbnQuZHVyYXRpb24oY3VycmVudCwgZFJlcykudG9JU09TdHJpbmcoKVxuICAgIH0pO1xuXG4gICAgY3VycmVudCA9IGN1cnJlbnQgKyAxO1xuICB9XG59XG5cbi8qXG4gKiBTZXR1cCBhIGdyb3VwaW5nIGJhc2VkIG9uIHRoZSBgcGFydGl0aW9uLmdyb3VwaW5nQ29udGludW91c2AsIGBwYXJ0aXRpb24ubWludmFsYCxcbiAqIGBwYXJ0aXRpb24ubWF4dmFsYCwgYW5kIHRoZSBgcGFydGl0aW9uLmdyb3VwaW5nUGFyYW1gLlxuICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7R3JvdXBbXX0gZ3JvdXBzXG4gKi9cbmZ1bmN0aW9uIHNldENvbnRpbnVvdXNHcm91cHMgKHBhcnRpdGlvbiwgZ3JvdXBzKSB7XG4gIHZhciBwYXJhbSA9IHBhcnRpdGlvbi5ncm91cGluZ1BhcmFtO1xuICB2YXIgeDAsIHgxLCBzaXplLCBuYmlucztcblxuICBpZiAocGFydGl0aW9uLmdyb3VwRml4ZWROKSB7XG4gICAgLy8gQSBmaXhlZCBudW1iZXIgb2YgZXF1YWxseSBzaXplZCBiaW5zXG4gICAgbmJpbnMgPSBwYXJhbTtcbiAgICB4MCA9IHBhcnRpdGlvbi5taW52YWw7XG4gICAgeDEgPSBwYXJ0aXRpb24ubWF4dmFsO1xuICAgIHNpemUgPSAoeDEgLSB4MCkgLyBuYmlucztcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uZ3JvdXBGaXhlZFMpIHtcbiAgICAvLyBBIGZpeGVkIGJpbiBzaXplXG4gICAgc2l6ZSA9IHBhcmFtO1xuICAgIHgwID0gTWF0aC5mbG9vcihwYXJ0aXRpb24ubWludmFsIC8gc2l6ZSkgKiBzaXplO1xuICAgIHgxID0gTWF0aC5jZWlsKHBhcnRpdGlvbi5tYXh2YWwgLyBzaXplKSAqIHNpemU7XG4gICAgbmJpbnMgPSAoeDEgLSB4MCkgLyBzaXplO1xuICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5ncm91cEZpeGVkU0MpIHtcbiAgICAvLyBBIGZpeGVkIGJpbiBzaXplLCBjZW50ZXJlZCBvbiAwXG4gICAgc2l6ZSA9IHBhcmFtO1xuICAgIHgwID0gKE1hdGguZmxvb3IocGFydGl0aW9uLm1pbnZhbCAvIHNpemUpIC0gMC41KSAqIHNpemU7XG4gICAgeDEgPSAoTWF0aC5jZWlsKHBhcnRpdGlvbi5tYXh2YWwgLyBzaXplKSArIDAuNSkgKiBzaXplO1xuICAgIG5iaW5zID0gKHgxIC0geDApIC8gc2l6ZTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAvLyBGaXhlZCBudW1iZXIgb2YgbG9nYXJpdGhtaWNhbGx5IChiYXNlIDEwKSBzaXplZCBiaW5zXG4gICAgbmJpbnMgPSBwYXJhbTtcbiAgICB4MCA9IE1hdGgubG9nKHBhcnRpdGlvbi5taW52YWwpIC8gTWF0aC5sb2coMTAuMCk7XG4gICAgeDEgPSBNYXRoLmxvZyhwYXJ0aXRpb24ubWF4dmFsKSAvIE1hdGgubG9nKDEwLjApO1xuICAgIHNpemUgPSAoeDEgLSB4MCkgLyBuYmlucztcbiAgfVxuXG4gIGZ1bmN0aW9uIHVubG9nICh4KSB7XG4gICAgcmV0dXJuIE1hdGguZXhwKHggKiBNYXRoLmxvZygxMCkpO1xuICB9XG5cbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBuYmluczsgaSsrKSB7XG4gICAgdmFyIHN0YXJ0ID0geDAgKyBpICogc2l6ZTtcbiAgICB2YXIgZW5kID0geDAgKyAoaSArIDEpICogc2l6ZTtcbiAgICB2YXIgbWlkID0gMC41ICogKHN0YXJ0ICsgZW5kKTtcblxuICAgIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAgIGdyb3Vwcy5hZGQoe1xuICAgICAgICBtaW46IHVubG9nKHN0YXJ0KSxcbiAgICAgICAgbWF4OiB1bmxvZyhlbmQpLFxuICAgICAgICB2YWx1ZTogdW5sb2coc3RhcnQpLFxuICAgICAgICBsYWJlbDogdW5sb2coZW5kKS50b1ByZWNpc2lvbig1KVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdyb3Vwcy5hZGQoe1xuICAgICAgICBtaW46IHN0YXJ0LFxuICAgICAgICBtYXg6IGVuZCxcbiAgICAgICAgdmFsdWU6IG1pZCxcbiAgICAgICAgbGFiZWw6IG1pZC50b1ByZWNpc2lvbig1KVxuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qXG4gKiBTZXR1cCBhIGdyb3VwaW5nIGJhc2VkIG9uIHRoZSBgcGFydGl0aW9uLmNhdGVnb3JpYWxUcmFuc2Zvcm1gXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICogQHBhcmFtIHtHcm91cFtdfSBncm91cHNcbiAqL1xuZnVuY3Rpb24gc2V0Q2F0ZWdvcmlhbEdyb3VwcyAocGFydGl0aW9uLCBncm91cHMpIHtcbiAgLy8gZGF0YXZpZXcgLT4gZmlsdGVycyAtPiBmaWx0ZXIgLT4gcGFydGl0aW9ucyAtPiBwYXJ0aXRpb25cbiAgLy8gICAgICAgICAgLT4gZmFjZXRzXG5cbiAgdmFyIGRhdGF2aWV3O1xuICB2YXIgZmFjZXQ7XG4gIHRyeSB7XG4gICAgZGF0YXZpZXcgPSBwYXJ0aXRpb24uY29sbGVjdGlvbi5wYXJlbnQuY29sbGVjdGlvbi5wYXJlbnQ7XG4gICAgZmFjZXQgPSBkYXRhdmlldy5mYWNldHMuZ2V0KHBhcnRpdGlvbi5mYWNldE5hbWUsICduYW1lJyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKCdzZXRDYXRlZ29yaWFsR3JvdXBzOiBjYW5ub3QgbG9jYXRlIGZhY2V0IGZvciB0aGlzIHBhcnRpdGlvbicpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmYWNldC5pc0NhdGVnb3JpYWwpIHtcbiAgICAvLyBkZWZhdWx0OiBhIGNhdGVnb3JpYWwgZmFjZXQsIHdpdGggYSBjYXRlZ29yaWFsIHBhcml0dGlvblxuICAgIGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuZm9yRWFjaChmdW5jdGlvbiAocnVsZSwgaSkge1xuICAgICAgZ3JvdXBzLmFkZCh7XG4gICAgICAgIHZhbHVlOiBydWxlLmdyb3VwLFxuICAgICAgICBsYWJlbDogcnVsZS5ncm91cCxcbiAgICAgICAgY291bnQ6IHJ1bGUuY291bnRcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICB2YXIgZm9ybWF0ID0gZmFjZXQuZGF0ZXRpbWVUcmFuc2Zvcm0udHJhbnNmb3JtZWRGb3JtYXQ7XG4gICAgdmFyIHRpbWVQYXJ0ID0gdXRpbC50aW1lUGFydHMuZ2V0KGZvcm1hdCwgJ2Rlc2NyaXB0aW9uJyk7XG5cbiAgICB0aW1lUGFydC5ncm91cHMuZm9yRWFjaChmdW5jdGlvbiAoZywgaSkge1xuICAgICAgZ3JvdXBzLmFkZCh7XG4gICAgICAgIHZhbHVlOiBnLFxuICAgICAgICBsYWJlbDogZyxcbiAgICAgICAgY291bnQ6IDBcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUud2FybignTm90IGltcGxlbWVudGVkJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNldCB0eXBlLCBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlc1xuICogQHBhcmFtcyB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbXMge09iamVjdH0gT3B0aW9ucyAtIHNpbGVudCBkbyBub3QgdHJpZ2dlciBjaGFuZ2UgZXZlbnRzXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICovXG5mdW5jdGlvbiByZXNldCAob3B0aW9ucykge1xuICB2YXIgcGFydGl0aW9uID0gdGhpcztcbiAgLy8gcGFydGl0aW9uIC0+IHBhcnRpdGlvbnMgLT4gZmlsdGVyIC0+IGZpbHRlcnMgLT4gZGF0YXZpZXdcbiAgdmFyIGZpbHRlciA9IHBhcnRpdGlvbi5jb2xsZWN0aW9uLnBhcmVudDtcbiAgdmFyIGRhdGF2aWV3ID0gZmlsdGVyLmNvbGxlY3Rpb24ucGFyZW50O1xuICB2YXIgZmFjZXQgPSBkYXRhdmlldy5mYWNldHMuZ2V0KHBhcnRpdGlvbi5mYWNldE5hbWUsICduYW1lJyk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHBhcnRpdGlvbi5zZXQoe1xuICAgIHR5cGU6IGZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZFR5cGUsXG4gICAgbWludmFsOiBmYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW4sXG4gICAgbWF4dmFsOiBmYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNYXhcbiAgfSwgb3B0aW9ucyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIGRhdGFUeXBlczoge1xuICAgICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nOiB7XG4gICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIG1vbWVudGpzIG9iamVjdHNcbiAgICAgICAgaWYgKG1vbWVudC5pc0R1cmF0aW9uKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG1vbWVudC5kdXJhdGlvbih2YWx1ZSksXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vbWVudC5pc01vbWVudCh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsOiB2YWx1ZS5jbG9uZSgpLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIGNyZWF0ZSBtb21lbnRqcyBvYmplY3RzXG4gICAgICAgIG5ld1ZhbHVlID0gbW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICBpZiAobmV3VmFsdWUuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbDogbmV3VmFsdWUsXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSB7XG4gICAgICAgICAgbmV3VmFsdWUgPSBtb21lbnQuZHVyYXRpb24odmFsdWUpO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG5ld1ZhbHVlLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIHNldCBhIG51bWJlclxuICAgICAgICBpZiAodmFsdWUgPT09ICt2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6ICt2YWx1ZSxcbiAgICAgICAgICAgIHR5cGU6ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZhaWxlZC4uXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsOiB2YWx1ZSxcbiAgICAgICAgICB0eXBlOiB0eXBlb2YgdmFsdWVcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBjb21wYXJlOiBmdW5jdGlvbiAoY3VycmVudFZhbCwgbmV3VmFsKSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsIGluc3RhbmNlb2YgbW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuIGN1cnJlbnRWYWwuaXNTYW1lKG5ld1ZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICtjdXJyZW50VmFsID09PSArbmV3VmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIExhYmVsIGZvciBkaXNwbGF5aW5nIG9uIHBsb3RzXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGxhYmVsOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJydcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFNob3cgYSBsZWdlbmQgZm9yIHRoaXMgcGFydGl0aW9uXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHNob3dMZWdlbmQ6IHtcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgIGRlZmF1bHQ6IHRydWVcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFNob3cgYW4gYXhpcyBsYWJlbCBmb3IgdGhpcyBwYXJ0aXRpb25cbiAgICAgKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgc2hvd0xhYmVsOiB7XG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICBkZWZhdWx0OiB0cnVlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRpbWV6b25lIGZvciBwYXJ0aXRpb25pbmdcbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB6b25lOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiAndHJ1ZScsXG4gICAgICBkZWZhdWx0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiB0aGlzIHBhcnRpdGlvblxuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0eXBlOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ2NhdGVnb3JpYWwnLFxuICAgICAgdmFsdWVzOiBbJ2NvbnN0YW50JywgJ2NvbnRpbnVvdXMnLCAnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICd0ZXh0J11cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGZhY2V0IHRvIHBhcnRpdGlvbiBvdmVyXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZhY2V0TmFtZTogJ3N0cmluZycsXG5cbiAgICAvKipcbiAgICAgKiBXaGVuIHBhcnQgb2YgYSBwYXJ0aXRpb25pbmcsIHRoaXMgZGV0ZXJpbWluZXMgdGhlIG9yZGVyaW5nXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHJhbms6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNhdGVnb3JpYWwgYW5kIHRleHQgRmFjZXRzLCB0aGUgb3JkZXJpbmcgY2FuIGJlIGFsZmFiZXRpY2FsIG9yIGJ5IGNvdW50XG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKi9cbiAgICBvcmRlcmluZzoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICB2YWx1ZXM6IFsnY291bnQnLCAndmFsdWUnXSxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ3ZhbHVlJ1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBGb3IgY29udGludW91cyBvciBkYXRldGltZSBGYWNldHMsIHRoZSBtaW5pbXVtIHZhbHVlLiBWYWx1ZXMgbG93ZXIgdGhhbiB0aGlzIGFyZSBncm91cGVkIHRvICdtaXNzaW5nJ1xuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICovXG4gICAgbWludmFsOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJyxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1heGltdW0gdmFsdWUuIFZhbHVlcyBoaWdoZXIgdGhhbiB0aGlzIGFyZSBncm91cGVkIHRvICdtaXNzaW5nJ1xuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICovXG4gICAgbWF4dmFsOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJyxcblxuICAgIC8qKlxuICAgICAqIEV4dHJhIHBhcmFtZXRlciB1c2VkIGluIHRoZSBncm91cGluZyBzdHJhdGVneTogZWl0aGVyIHRoZSBudW1iZXIgb2YgYmlucywgb3IgdGhlIGJpbiBzaXplLlxuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBncm91cGluZ1BhcmFtOiBbJ251bWJlcicsIHRydWUsIDIwXSxcblxuICAgIC8qKlxuICAgICAqIEdyb3VwaW5nIHN0cmF0ZWd5OlxuICAgICAqICAqIGBmaXhlZG5gICBmaXhlZCBudW1iZXIgb2YgYmlucyBpbiB0aGUgaW50ZXJ2YWwgW21pbnZhbCwgbWF4dmFsXVxuICAgICAqICAqIGBmaXhlZHNjYCBhIGZpeGVkIGJpbnNpemUsIGNlbnRlcmVkIG9uIHplcm9cbiAgICAgKiAgKiBgZml4ZWRzYCAgYSBmaXhlZCBiaW5zaXplLCBzdGFydGluZyBhdCB6ZXJvXG4gICAgICogICogYGxvZ2AgICAgIGZpeGVkIG51bWJlciBvZiBiaW5zIGJ1dCBvbiBhIGxvZ2FyaXRobWljIHNjYWxlXG4gICAgICogRG9uJ3QgdXNlIGRpcmVjdGx5IGJ1dCBjaGVjayBncm91cGluZyB2aWEgdGhlIGdyb3VwRml4ZWROLCBncm91cEZpeGVkU0MsXG4gICAgICogZ3JvdXBGaXhlZFMsIGFuZCBncm91cExvZyBwcm9wZXJ0aWVzXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdyb3VwaW5nQ29udGludW91czoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICdmaXhlZG4nLFxuICAgICAgdmFsdWVzOiBbJ2ZpeGVkbicsICdmaXhlZHNjJywgJ2ZpeGVkcycsICdsb2cnXVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBEZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgcGFydGl0aW9uLCB0aGlzIGNhbiBiZSBhbiBhcnJheSBvZiB0aGUgc2VsZWN0ZWQgZ3JvdXBzLFxuICAgICAqIG9yIGEgbnVtYmVyaWMgaW50ZXJ2YWwgW3N0YXJ0LCBlbmRdXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7YXJyYXl9XG4gICAgICovXG4gICAgLy8gTk9URTogZm9yIGNhdGVnb3JpYWwgZmFjZXRzLCBjb250YWlucyBydWxlLmdyb3VwXG4gICAgc2VsZWN0ZWQ6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgZGVyaXZlZDoge1xuICAgIC8vIHByb3BlcnRpZXMgZm9yOiB0eXBlXG4gICAgaXNDb25zdGFudDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAnY29uc3RhbnQnO1xuICAgICAgfVxuICAgIH0sXG4gICAgaXNDb250aW51b3VzOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjb250aW51b3VzJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzQ2F0ZWdvcmlhbDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAnY2F0ZWdvcmlhbCc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0RhdGV0aW1lOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdkYXRldGltZSc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0R1cmF0aW9uOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdkdXJhdGlvbic7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ3RleHQnO1xuICAgICAgfVxuICAgIH0sXG4gICAgLy8gcHJvcGVydGllcyBmb3IgZ3JvdXBpbmctY29udGludW91c1xuICAgIGdyb3VwRml4ZWROOiB7XG4gICAgICBkZXBzOiBbJ2dyb3VwaW5nQ29udGludW91cyddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JvdXBpbmdDb250aW51b3VzID09PSAnZml4ZWRuJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGdyb3VwRml4ZWRTQzoge1xuICAgICAgZGVwczogWydncm91cGluZ0NvbnRpbnVvdXMnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyb3VwaW5nQ29udGludW91cyA9PT0gJ2ZpeGVkc2MnO1xuICAgICAgfVxuICAgIH0sXG4gICAgZ3JvdXBGaXhlZFM6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cGluZ0NvbnRpbnVvdXMgPT09ICdmaXhlZHMnO1xuICAgICAgfVxuICAgIH0sXG4gICAgZ3JvdXBMb2c6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cGluZ0NvbnRpbnVvdXMgPT09ICdsb2cnO1xuICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIChvcmRlcmVkKSBzZXQgb2YgZ3JvdXBzIHRoaXMgUGFydGl0aW9uIGNhbiB0YWtlLCBtYWtpbmcgdXAgdGhpcyBwYXJ0aXRpb24uXG4gICAgICogVGhlIGxpc3QgaXMgcmVjYWxjdWxhdGVkIHdoZW4gYW55IG9mIHRoZSBwYXJ0aXRpb24ncyBwcm9wZXJ0aWVzIGNoYW5nZTpcbiAgICAgKiAnZ3JvdXBpbmdDb250aW51b3VzJywgJ2dyb3VwaW5nUGFyYW0nLCAnbWludmFsJywgJ21heHZhbCcsICd0eXBlJywgJ3pvbmUnIGNoYW5nZVxuICAgICAqIFRoZSBsaXN0IGtlZXBzIGl0c2VsZiBzb3J0ZWQgYWNjb3JkaW5nIHRvIHRoZSBwYXJ0aXRpb24ub3JkZXJpbmdcbiAgICAgKlxuICAgICAqIENhbiBiZSB1c2VkIGZvciBwbG90dGluZyBldGMuXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7R3JvdXBbXX1cbiAgICAgKi9cbiAgICBncm91cHM6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJywgJ2dyb3VwaW5nUGFyYW0nLCAnbWludmFsJywgJ21heHZhbCcsICd0eXBlJywgJ3pvbmUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwYXJ0aXRpb24gPSB0aGlzO1xuICAgICAgICB2YXIgZ3JvdXBzID0gbmV3IEdyb3VwcyhbXSwge1xuICAgICAgICAgIHBhcmVudDogcGFydGl0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChwYXJ0aXRpb24uaXNDYXRlZ29yaWFsKSB7XG4gICAgICAgICAgc2V0Q2F0ZWdvcmlhbEdyb3VwcyhwYXJ0aXRpb24sIGdyb3Vwcyk7XG4gICAgICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzQ29udGludW91cykge1xuICAgICAgICAgIHNldENvbnRpbnVvdXNHcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0RhdGV0aW1lKSB7XG4gICAgICAgICAgc2V0RGF0ZXRpbWVHcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0R1cmF0aW9uKSB7XG4gICAgICAgICAgc2V0RHVyYXRpb25Hcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc1RleHQpIHtcbiAgICAgICAgICAvLyBuby1vcFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Nhbm5vdCBzZXQgZ3JvdXBzIGZvciBwYXJ0aXRpb24nLCBwYXJ0aXRpb24uZ2V0SWQoKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ3JvdXBzO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgdXBkYXRlU2VsZWN0aW9uOiBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICBzZWxlY3Rpb24udXBkYXRlU2VsZWN0aW9uKHRoaXMsIGdyb3VwKTtcbiAgfSxcbiAgZmlsdGVyRnVuY3Rpb246IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gc2VsZWN0aW9uLmZpbHRlckZ1bmN0aW9uKHRoaXMpO1xuICB9LFxuICByZXNldDogcmVzZXRcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8191\n")},8233:function(module,exports,__webpack_require__){eval("\n/**\n * This is the web browser implementation of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = __webpack_require__(/*! ./debug */ \"bb16\");\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = 'undefined' != typeof chrome\n               && 'undefined' != typeof chrome.storage\n                  ? chrome.storage.local\n                  : localstorage();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n  'lightseagreen',\n  'forestgreen',\n  'goldenrod',\n  'dodgerblue',\n  'darkorchid',\n  'crimson'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\nfunction useColors() {\n  // is webkit? http://stackoverflow.com/a/16459606/376773\n  return ('WebkitAppearance' in document.documentElement.style) ||\n    // is firebug? http://stackoverflow.com/a/398120/376773\n    (window.console && (console.firebug || (console.exception && console.table))) ||\n    // is firefox >= v31?\n    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n    (navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31);\n}\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nexports.formatters.j = function(v) {\n  return JSON.stringify(v);\n};\n\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs() {\n  var args = arguments;\n  var useColors = this.useColors;\n\n  args[0] = (useColors ? '%c' : '')\n    + this.namespace\n    + (useColors ? ' %c' : ' ')\n    + args[0]\n    + (useColors ? '%c ' : ' ')\n    + '+' + exports.humanize(this.diff);\n\n  if (!useColors) return args;\n\n  var c = 'color: ' + this.color;\n  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));\n\n  // the final \"%c\" is somewhat tricky, because there could be other\n  // arguments passed either before or after the %c, so we need to\n  // figure out the correct index to insert the CSS into\n  var index = 0;\n  var lastC = 0;\n  args[0].replace(/%[a-z%]/g, function(match) {\n    if ('%%' === match) return;\n    index++;\n    if ('%c' === match) {\n      // we only are interested in the *last* %c\n      // (the user may have provided their own)\n      lastC = index;\n    }\n  });\n\n  args.splice(lastC, 0, c);\n  return args;\n}\n\n/**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\nfunction log() {\n  // this hackery is required for IE8/9, where\n  // the `console.log` function doesn't have 'apply'\n  return 'object' === typeof console\n    && console.log\n    && Function.prototype.apply.call(console.log, console, arguments);\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\nfunction save(namespaces) {\n  try {\n    if (null == namespaces) {\n      exports.storage.removeItem('debug');\n    } else {\n      exports.storage.debug = namespaces;\n    }\n  } catch(e) {}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n  var r;\n  try {\n    r = exports.storage.debug;\n  } catch(e) {}\n  return r;\n}\n\n/**\n * Enable namespaces listed in `localStorage.debug` initially.\n */\n\nexports.enable(load());\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage(){\n  try {\n    return window.localStorage;\n  } catch (e) {}\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvZGVidWcvYnJvd3Nlci5qcz80ZDVhIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSB3ZWIgYnJvd3NlciBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gKlxuICogRXhwb3NlIGBkZWJ1ZygpYCBhcyB0aGUgbW9kdWxlLlxuICovXG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZGVidWcnKTtcbmV4cG9ydHMubG9nID0gbG9nO1xuZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbmV4cG9ydHMuc2F2ZSA9IHNhdmU7XG5leHBvcnRzLmxvYWQgPSBsb2FkO1xuZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG5leHBvcnRzLnN0b3JhZ2UgPSAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lXG4gICAgICAgICAgICAgICAmJiAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lLnN0b3JhZ2VcbiAgICAgICAgICAgICAgICAgID8gY2hyb21lLnN0b3JhZ2UubG9jYWxcbiAgICAgICAgICAgICAgICAgIDogbG9jYWxzdG9yYWdlKCk7XG5cbi8qKlxuICogQ29sb3JzLlxuICovXG5cbmV4cG9ydHMuY29sb3JzID0gW1xuICAnbGlnaHRzZWFncmVlbicsXG4gICdmb3Jlc3RncmVlbicsXG4gICdnb2xkZW5yb2QnLFxuICAnZG9kZ2VyYmx1ZScsXG4gICdkYXJrb3JjaGlkJyxcbiAgJ2NyaW1zb24nXG5dO1xuXG4vKipcbiAqIEN1cnJlbnRseSBvbmx5IFdlYktpdC1iYXNlZCBXZWIgSW5zcGVjdG9ycywgRmlyZWZveCA+PSB2MzEsXG4gKiBhbmQgdGhlIEZpcmVidWcgZXh0ZW5zaW9uIChhbnkgRmlyZWZveCB2ZXJzaW9uKSBhcmUga25vd25cbiAqIHRvIHN1cHBvcnQgXCIlY1wiIENTUyBjdXN0b21pemF0aW9ucy5cbiAqXG4gKiBUT0RPOiBhZGQgYSBgbG9jYWxTdG9yYWdlYCB2YXJpYWJsZSB0byBleHBsaWNpdGx5IGVuYWJsZS9kaXNhYmxlIGNvbG9yc1xuICovXG5cbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcbiAgLy8gaXMgd2Via2l0PyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNjQ1OTYwNi8zNzY3NzNcbiAgcmV0dXJuICgnV2Via2l0QXBwZWFyYW5jZScgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlKSB8fFxuICAgIC8vIGlzIGZpcmVidWc/IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM5ODEyMC8zNzY3NzNcbiAgICAod2luZG93LmNvbnNvbGUgJiYgKGNvbnNvbGUuZmlyZWJ1ZyB8fCAoY29uc29sZS5leGNlcHRpb24gJiYgY29uc29sZS50YWJsZSkpKSB8fFxuICAgIC8vIGlzIGZpcmVmb3ggPj0gdjMxP1xuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvVG9vbHMvV2ViX0NvbnNvbGUjU3R5bGluZ19tZXNzYWdlc1xuICAgIChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkubWF0Y2goL2ZpcmVmb3hcXC8oXFxkKykvKSAmJiBwYXJzZUludChSZWdFeHAuJDEsIDEwKSA+PSAzMSk7XG59XG5cbi8qKlxuICogTWFwICVqIHRvIGBKU09OLnN0cmluZ2lmeSgpYCwgc2luY2Ugbm8gV2ViIEluc3BlY3RvcnMgZG8gdGhhdCBieSBkZWZhdWx0LlxuICovXG5cbmV4cG9ydHMuZm9ybWF0dGVycy5qID0gZnVuY3Rpb24odikge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodik7XG59O1xuXG5cbi8qKlxuICogQ29sb3JpemUgbG9nIGFyZ3VtZW50cyBpZiBlbmFibGVkLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZm9ybWF0QXJncygpIHtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciB1c2VDb2xvcnMgPSB0aGlzLnVzZUNvbG9ycztcblxuICBhcmdzWzBdID0gKHVzZUNvbG9ycyA/ICclYycgOiAnJylcbiAgICArIHRoaXMubmFtZXNwYWNlXG4gICAgKyAodXNlQ29sb3JzID8gJyAlYycgOiAnICcpXG4gICAgKyBhcmdzWzBdXG4gICAgKyAodXNlQ29sb3JzID8gJyVjICcgOiAnICcpXG4gICAgKyAnKycgKyBleHBvcnRzLmh1bWFuaXplKHRoaXMuZGlmZik7XG5cbiAgaWYgKCF1c2VDb2xvcnMpIHJldHVybiBhcmdzO1xuXG4gIHZhciBjID0gJ2NvbG9yOiAnICsgdGhpcy5jb2xvcjtcbiAgYXJncyA9IFthcmdzWzBdLCBjLCAnY29sb3I6IGluaGVyaXQnXS5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncywgMSkpO1xuXG4gIC8vIHRoZSBmaW5hbCBcIiVjXCIgaXMgc29tZXdoYXQgdHJpY2t5LCBiZWNhdXNlIHRoZXJlIGNvdWxkIGJlIG90aGVyXG4gIC8vIGFyZ3VtZW50cyBwYXNzZWQgZWl0aGVyIGJlZm9yZSBvciBhZnRlciB0aGUgJWMsIHNvIHdlIG5lZWQgdG9cbiAgLy8gZmlndXJlIG91dCB0aGUgY29ycmVjdCBpbmRleCB0byBpbnNlcnQgdGhlIENTUyBpbnRvXG4gIHZhciBpbmRleCA9IDA7XG4gIHZhciBsYXN0QyA9IDA7XG4gIGFyZ3NbMF0ucmVwbGFjZSgvJVthLXolXS9nLCBmdW5jdGlvbihtYXRjaCkge1xuICAgIGlmICgnJSUnID09PSBtYXRjaCkgcmV0dXJuO1xuICAgIGluZGV4Kys7XG4gICAgaWYgKCclYycgPT09IG1hdGNoKSB7XG4gICAgICAvLyB3ZSBvbmx5IGFyZSBpbnRlcmVzdGVkIGluIHRoZSAqbGFzdCogJWNcbiAgICAgIC8vICh0aGUgdXNlciBtYXkgaGF2ZSBwcm92aWRlZCB0aGVpciBvd24pXG4gICAgICBsYXN0QyA9IGluZGV4O1xuICAgIH1cbiAgfSk7XG5cbiAgYXJncy5zcGxpY2UobGFzdEMsIDAsIGMpO1xuICByZXR1cm4gYXJncztcbn1cblxuLyoqXG4gKiBJbnZva2VzIGBjb25zb2xlLmxvZygpYCB3aGVuIGF2YWlsYWJsZS5cbiAqIE5vLW9wIHdoZW4gYGNvbnNvbGUubG9nYCBpcyBub3QgYSBcImZ1bmN0aW9uXCIuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBsb2coKSB7XG4gIC8vIHRoaXMgaGFja2VyeSBpcyByZXF1aXJlZCBmb3IgSUU4LzksIHdoZXJlXG4gIC8vIHRoZSBgY29uc29sZS5sb2dgIGZ1bmN0aW9uIGRvZXNuJ3QgaGF2ZSAnYXBwbHknXG4gIHJldHVybiAnb2JqZWN0JyA9PT0gdHlwZW9mIGNvbnNvbGVcbiAgICAmJiBjb25zb2xlLmxvZ1xuICAgICYmIEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKGNvbnNvbGUubG9nLCBjb25zb2xlLCBhcmd1bWVudHMpO1xufVxuXG4vKipcbiAqIFNhdmUgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lc3BhY2VzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzYXZlKG5hbWVzcGFjZXMpIHtcbiAgdHJ5IHtcbiAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2VzKSB7XG4gICAgICBleHBvcnRzLnN0b3JhZ2UucmVtb3ZlSXRlbSgnZGVidWcnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhwb3J0cy5zdG9yYWdlLmRlYnVnID0gbmFtZXNwYWNlcztcbiAgICB9XG4gIH0gY2F0Y2goZSkge31cbn1cblxuLyoqXG4gKiBMb2FkIGBuYW1lc3BhY2VzYC5cbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHJldHVybnMgdGhlIHByZXZpb3VzbHkgcGVyc2lzdGVkIGRlYnVnIG1vZGVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2FkKCkge1xuICB2YXIgcjtcbiAgdHJ5IHtcbiAgICByID0gZXhwb3J0cy5zdG9yYWdlLmRlYnVnO1xuICB9IGNhdGNoKGUpIHt9XG4gIHJldHVybiByO1xufVxuXG4vKipcbiAqIEVuYWJsZSBuYW1lc3BhY2VzIGxpc3RlZCBpbiBgbG9jYWxTdG9yYWdlLmRlYnVnYCBpbml0aWFsbHkuXG4gKi9cblxuZXhwb3J0cy5lbmFibGUobG9hZCgpKTtcblxuLyoqXG4gKiBMb2NhbHN0b3JhZ2UgYXR0ZW1wdHMgdG8gcmV0dXJuIHRoZSBsb2NhbHN0b3JhZ2UuXG4gKlxuICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBzYWZhcmkgdGhyb3dzXG4gKiB3aGVuIGEgdXNlciBkaXNhYmxlcyBjb29raWVzL2xvY2Fsc3RvcmFnZVxuICogYW5kIHlvdSBhdHRlbXB0IHRvIGFjY2VzcyBpdC5cbiAqXG4gKiBAcmV0dXJuIHtMb2NhbFN0b3JhZ2V9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2NhbHN0b3JhZ2UoKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZTtcbiAgfSBjYXRjaCAoZSkge31cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8233\n")},"834b":function(module,exports,__webpack_require__){eval('/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies\n */\n\nvar XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ "86e3");\nvar XHR = __webpack_require__(/*! ./polling-xhr */ "108d");\nvar JSONP = __webpack_require__(/*! ./polling-jsonp */ "2dce");\nvar websocket = __webpack_require__(/*! ./websocket */ "6b20");\n\n/**\n * Export transports.\n */\n\nexports.polling = polling;\nexports.websocket = websocket;\n\n/**\n * Polling transport polymorphic constructor.\n * Decides on xhr vs jsonp based on feature detection.\n *\n * @api private\n */\n\nfunction polling (opts) {\n  var xhr;\n  var xd = false;\n  var xs = false;\n  var jsonp = false !== opts.jsonp;\n\n  if (global.location) {\n    var isSSL = \'https:\' === location.protocol;\n    var port = location.port;\n\n    // some user agents have empty `location.port`\n    if (!port) {\n      port = isSSL ? 443 : 80;\n    }\n\n    xd = opts.hostname !== location.hostname || port !== opts.port;\n    xs = opts.secure !== isSSL;\n  }\n\n  opts.xdomain = xd;\n  opts.xscheme = xs;\n  xhr = new XMLHttpRequest(opts);\n\n  if (\'open\' in xhr && !opts.forceJSONP) {\n    return new XHR(opts);\n  } else {\n    if (!jsonp) throw new Error(\'JSONP disabled\');\n    return new JSONP(opts);\n  }\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ "698d")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODM0Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9pbmRleC5qcz84OTk2Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llc1xuICovXG5cbnZhciBYTUxIdHRwUmVxdWVzdCA9IHJlcXVpcmUoJ3htbGh0dHByZXF1ZXN0LXNzbCcpO1xudmFyIFhIUiA9IHJlcXVpcmUoJy4vcG9sbGluZy14aHInKTtcbnZhciBKU09OUCA9IHJlcXVpcmUoJy4vcG9sbGluZy1qc29ucCcpO1xudmFyIHdlYnNvY2tldCA9IHJlcXVpcmUoJy4vd2Vic29ja2V0Jyk7XG5cbi8qKlxuICogRXhwb3J0IHRyYW5zcG9ydHMuXG4gKi9cblxuZXhwb3J0cy5wb2xsaW5nID0gcG9sbGluZztcbmV4cG9ydHMud2Vic29ja2V0ID0gd2Vic29ja2V0O1xuXG4vKipcbiAqIFBvbGxpbmcgdHJhbnNwb3J0IHBvbHltb3JwaGljIGNvbnN0cnVjdG9yLlxuICogRGVjaWRlcyBvbiB4aHIgdnMganNvbnAgYmFzZWQgb24gZmVhdHVyZSBkZXRlY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcG9sbGluZyAob3B0cykge1xuICB2YXIgeGhyO1xuICB2YXIgeGQgPSBmYWxzZTtcbiAgdmFyIHhzID0gZmFsc2U7XG4gIHZhciBqc29ucCA9IGZhbHNlICE9PSBvcHRzLmpzb25wO1xuXG4gIGlmIChnbG9iYWwubG9jYXRpb24pIHtcbiAgICB2YXIgaXNTU0wgPSAnaHR0cHM6JyA9PT0gbG9jYXRpb24ucHJvdG9jb2w7XG4gICAgdmFyIHBvcnQgPSBsb2NhdGlvbi5wb3J0O1xuXG4gICAgLy8gc29tZSB1c2VyIGFnZW50cyBoYXZlIGVtcHR5IGBsb2NhdGlvbi5wb3J0YFxuICAgIGlmICghcG9ydCkge1xuICAgICAgcG9ydCA9IGlzU1NMID8gNDQzIDogODA7XG4gICAgfVxuXG4gICAgeGQgPSBvcHRzLmhvc3RuYW1lICE9PSBsb2NhdGlvbi5ob3N0bmFtZSB8fCBwb3J0ICE9PSBvcHRzLnBvcnQ7XG4gICAgeHMgPSBvcHRzLnNlY3VyZSAhPT0gaXNTU0w7XG4gIH1cblxuICBvcHRzLnhkb21haW4gPSB4ZDtcbiAgb3B0cy54c2NoZW1lID0geHM7XG4gIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdChvcHRzKTtcblxuICBpZiAoJ29wZW4nIGluIHhociAmJiAhb3B0cy5mb3JjZUpTT05QKSB7XG4gICAgcmV0dXJuIG5ldyBYSFIob3B0cyk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFqc29ucCkgdGhyb3cgbmV3IEVycm9yKCdKU09OUCBkaXNhYmxlZCcpO1xuICAgIHJldHVybiBuZXcgSlNPTlAob3B0cyk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///834b\n')},"86e3":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {// browser shim for xmlhttprequest module\n\nvar hasCORS = __webpack_require__(/*! has-cors */ \"0392\");\n\nmodule.exports = function (opts) {\n  var xdomain = opts.xdomain;\n\n  // scheme must be same when usign XDomainRequest\n  // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx\n  var xscheme = opts.xscheme;\n\n  // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.\n  // https://github.com/Automattic/engine.io-client/pull/217\n  var enablesXDR = opts.enablesXDR;\n\n  // XMLHttpRequest can be disabled on IE\n  try {\n    if ('undefined' !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {\n      return new XMLHttpRequest();\n    }\n  } catch (e) { }\n\n  // Use XDomainRequest for IE8 if enablesXDR is true\n  // because loading bar keeps flashing when using jsonp-polling\n  // https://github.com/yujiosaka/socke.io-ie8-loading-example\n  try {\n    if ('undefined' !== typeof XDomainRequest && !xscheme && enablesXDR) {\n      return new XDomainRequest();\n    }\n  } catch (e) { }\n\n  if (!xdomain) {\n    try {\n      return new global[['Active'].concat('Object').join('X')]('Microsoft.XMLHTTP');\n    } catch (e) { }\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODZlMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIveG1saHR0cHJlcXVlc3QuanM/NzY2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBicm93c2VyIHNoaW0gZm9yIHhtbGh0dHByZXF1ZXN0IG1vZHVsZVxuXG52YXIgaGFzQ09SUyA9IHJlcXVpcmUoJ2hhcy1jb3JzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgdmFyIHhkb21haW4gPSBvcHRzLnhkb21haW47XG5cbiAgLy8gc2NoZW1lIG11c3QgYmUgc2FtZSB3aGVuIHVzaWduIFhEb21haW5SZXF1ZXN0XG4gIC8vIGh0dHA6Ly9ibG9ncy5tc2RuLmNvbS9iL2llaW50ZXJuYWxzL2FyY2hpdmUvMjAxMC8wNS8xMy94ZG9tYWlucmVxdWVzdC1yZXN0cmljdGlvbnMtbGltaXRhdGlvbnMtYW5kLXdvcmthcm91bmRzLmFzcHhcbiAgdmFyIHhzY2hlbWUgPSBvcHRzLnhzY2hlbWU7XG5cbiAgLy8gWERvbWFpblJlcXVlc3QgaGFzIGEgZmxvdyBvZiBub3Qgc2VuZGluZyBjb29raWUsIHRoZXJlZm9yZSBpdCBzaG91bGQgYmUgZGlzYWJsZWQgYXMgYSBkZWZhdWx0LlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vQXV0b21hdHRpYy9lbmdpbmUuaW8tY2xpZW50L3B1bGwvMjE3XG4gIHZhciBlbmFibGVzWERSID0gb3B0cy5lbmFibGVzWERSO1xuXG4gIC8vIFhNTEh0dHBSZXF1ZXN0IGNhbiBiZSBkaXNhYmxlZCBvbiBJRVxuICB0cnkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIFhNTEh0dHBSZXF1ZXN0ICYmICgheGRvbWFpbiB8fCBoYXNDT1JTKSkge1xuICAgICAgcmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkgeyB9XG5cbiAgLy8gVXNlIFhEb21haW5SZXF1ZXN0IGZvciBJRTggaWYgZW5hYmxlc1hEUiBpcyB0cnVlXG4gIC8vIGJlY2F1c2UgbG9hZGluZyBiYXIga2VlcHMgZmxhc2hpbmcgd2hlbiB1c2luZyBqc29ucC1wb2xsaW5nXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS95dWppb3Nha2Evc29ja2UuaW8taWU4LWxvYWRpbmctZXhhbXBsZVxuICB0cnkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIFhEb21haW5SZXF1ZXN0ICYmICF4c2NoZW1lICYmIGVuYWJsZXNYRFIpIHtcbiAgICAgIHJldHVybiBuZXcgWERvbWFpblJlcXVlc3QoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHsgfVxuXG4gIGlmICgheGRvbWFpbikge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbmV3IGdsb2JhbFtbJ0FjdGl2ZSddLmNvbmNhdCgnT2JqZWN0Jykuam9pbignWCcpXSgnTWljcm9zb2Z0LlhNTEhUVFAnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbiAgfVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///86e3\n")},9083:function(module,exports,__webpack_require__){eval("/**\n * A `Group` represents a value a `Facet` can take using a partitioning.\n * For continuous or time facets, it represents an interval.\n * For categorial facets, it is a single label.\n *\n * The `Facet.groups` collection is used for plotting, to deterime the postion along the axis.\n * Selections can be updated using a `Group`.\n *\n * @extends Base\n * @class Group\n */\nvar Base = __webpack_require__(/*! ../util/base */ \"3902\");\nvar moment = __webpack_require__(/*! moment */ \"da01\");\n\nmodule.exports = Base.extend({\n  dataTypes: {\n    'numberDatetimeOrDuration': {\n      set: function (value) {\n        var newValue;\n\n        // check for momentjs objects\n        if (moment.isDuration(value)) {\n          return {\n            val: moment.duration(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (moment.isMoment(value)) {\n          return {\n            val: moment(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to create momentjs objects\n        newValue = moment(value, moment.ISO_8601);\n        if (newValue.isValid()) {\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          newValue = moment.duration(value);\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to set a number\n        if (value === +value) {\n          return {\n            val: +value,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // failed..\n        return {\n          val: value,\n          type: typeof value\n        };\n      },\n      compare: function (currentVal, newVal) {\n        if (currentVal instanceof moment) {\n          return currentVal.isSame(newVal);\n        } else {\n          return +currentVal === +newVal;\n        }\n      }\n    }\n  },\n  props: {\n    /**\n     * For continuous, datetime, or duration facets. Lower limit of interval\n     * @type {number|moment}\n     * @memberof! Group\n     */\n    min: 'numberDatetimeOrDuration',\n\n    /**\n     * For continuous, datetime, or duration facets. Upper limit of interval\n     * @type {number|moment}\n     * @memberof! Group\n     */\n    max: 'numberDatetimeOrDuration',\n\n    /**\n     * Number of times this transform is used\n     * @type {number}\n     * @memberof! Group\n     */\n    count: ['number', true, 0],\n\n    /**\n     * Label for display\n     * @type {string}\n     * @memberof! Group\n     */\n    label: ['string', true, 'label'],\n\n    /**\n     * A value guaranteed to be in this group, used to check if this group is currently selected.\n     * moments and durations should be stored as moment.format() and duration.toISOString()\n     * @type {string|number}\n     * @memberof! Group\n     */\n    value: 'any',\n\n    /**\n     * Index, cached version of groups.models.indexOf(group)\n     * @type {number}\n     * @memberof! Group\n     */\n    groupIndex: 'number'\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2dyb3VwLmpzPzEwNGMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBIGBHcm91cGAgcmVwcmVzZW50cyBhIHZhbHVlIGEgYEZhY2V0YCBjYW4gdGFrZSB1c2luZyBhIHBhcnRpdGlvbmluZy5cbiAqIEZvciBjb250aW51b3VzIG9yIHRpbWUgZmFjZXRzLCBpdCByZXByZXNlbnRzIGFuIGludGVydmFsLlxuICogRm9yIGNhdGVnb3JpYWwgZmFjZXRzLCBpdCBpcyBhIHNpbmdsZSBsYWJlbC5cbiAqXG4gKiBUaGUgYEZhY2V0Lmdyb3Vwc2AgY29sbGVjdGlvbiBpcyB1c2VkIGZvciBwbG90dGluZywgdG8gZGV0ZXJpbWUgdGhlIHBvc3Rpb24gYWxvbmcgdGhlIGF4aXMuXG4gKiBTZWxlY3Rpb25zIGNhbiBiZSB1cGRhdGVkIHVzaW5nIGEgYEdyb3VwYC5cbiAqXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKiBAY2xhc3MgR3JvdXBcbiAqL1xudmFyIEJhc2UgPSByZXF1aXJlKCcuLi91dGlsL2Jhc2UnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlLmV4dGVuZCh7XG4gIGRhdGFUeXBlczoge1xuICAgICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nOiB7XG4gICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIG1vbWVudGpzIG9iamVjdHNcbiAgICAgICAgaWYgKG1vbWVudC5pc0R1cmF0aW9uKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG1vbWVudC5kdXJhdGlvbih2YWx1ZSksXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vbWVudC5pc01vbWVudCh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsOiBtb21lbnQodmFsdWUpLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIGNyZWF0ZSBtb21lbnRqcyBvYmplY3RzXG4gICAgICAgIG5ld1ZhbHVlID0gbW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICBpZiAobmV3VmFsdWUuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbDogbmV3VmFsdWUsXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSB7XG4gICAgICAgICAgbmV3VmFsdWUgPSBtb21lbnQuZHVyYXRpb24odmFsdWUpO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG5ld1ZhbHVlLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIHNldCBhIG51bWJlclxuICAgICAgICBpZiAodmFsdWUgPT09ICt2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6ICt2YWx1ZSxcbiAgICAgICAgICAgIHR5cGU6ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZhaWxlZC4uXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsOiB2YWx1ZSxcbiAgICAgICAgICB0eXBlOiB0eXBlb2YgdmFsdWVcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBjb21wYXJlOiBmdW5jdGlvbiAoY3VycmVudFZhbCwgbmV3VmFsKSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsIGluc3RhbmNlb2YgbW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuIGN1cnJlbnRWYWwuaXNTYW1lKG5ld1ZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICtjdXJyZW50VmFsID09PSArbmV3VmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzLCBkYXRldGltZSwgb3IgZHVyYXRpb24gZmFjZXRzLiBMb3dlciBsaW1pdCBvZiBpbnRlcnZhbFxuICAgICAqIEB0eXBlIHtudW1iZXJ8bW9tZW50fVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICBtaW46ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMsIGRhdGV0aW1lLCBvciBkdXJhdGlvbiBmYWNldHMuIFVwcGVyIGxpbWl0IG9mIGludGVydmFsXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIG1heDogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbicsXG5cbiAgICAvKipcbiAgICAgKiBOdW1iZXIgb2YgdGltZXMgdGhpcyB0cmFuc2Zvcm0gaXMgdXNlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIGNvdW50OiBbJ251bWJlcicsIHRydWUsIDBdLFxuXG4gICAgLyoqXG4gICAgICogTGFiZWwgZm9yIGRpc3BsYXlcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICBsYWJlbDogWydzdHJpbmcnLCB0cnVlLCAnbGFiZWwnXSxcblxuICAgIC8qKlxuICAgICAqIEEgdmFsdWUgZ3VhcmFudGVlZCB0byBiZSBpbiB0aGlzIGdyb3VwLCB1c2VkIHRvIGNoZWNrIGlmIHRoaXMgZ3JvdXAgaXMgY3VycmVudGx5IHNlbGVjdGVkLlxuICAgICAqIG1vbWVudHMgYW5kIGR1cmF0aW9ucyBzaG91bGQgYmUgc3RvcmVkIGFzIG1vbWVudC5mb3JtYXQoKSBhbmQgZHVyYXRpb24udG9JU09TdHJpbmcoKVxuICAgICAqIEB0eXBlIHtzdHJpbmd8bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICB2YWx1ZTogJ2FueScsXG5cbiAgICAvKipcbiAgICAgKiBJbmRleCwgY2FjaGVkIHZlcnNpb24gb2YgZ3JvdXBzLm1vZGVscy5pbmRleE9mKGdyb3VwKVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIGdyb3VwSW5kZXg6ICdudW1iZXInXG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9083\n")},"939f":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Create a blob builder even when vendor prefixes exist\n */\n\nvar BlobBuilder = global.BlobBuilder\n  || global.WebKitBlobBuilder\n  || global.MSBlobBuilder\n  || global.MozBlobBuilder;\n\n/**\n * Check if Blob constructor is supported\n */\n\nvar blobSupported = (function() {\n  try {\n    var a = new Blob(['hi']);\n    return a.size === 2;\n  } catch(e) {\n    return false;\n  }\n})();\n\n/**\n * Check if Blob constructor supports ArrayBufferViews\n * Fails in Safari 6, so we need to map to ArrayBuffers there.\n */\n\nvar blobSupportsArrayBufferView = blobSupported && (function() {\n  try {\n    var b = new Blob([new Uint8Array([1,2])]);\n    return b.size === 2;\n  } catch(e) {\n    return false;\n  }\n})();\n\n/**\n * Check if BlobBuilder is supported\n */\n\nvar blobBuilderSupported = BlobBuilder\n  && BlobBuilder.prototype.append\n  && BlobBuilder.prototype.getBlob;\n\n/**\n * Helper function that maps ArrayBufferViews to ArrayBuffers\n * Used by BlobBuilder constructor and old browsers that didn't\n * support it in the Blob constructor.\n */\n\nfunction mapArrayBufferViews(ary) {\n  for (var i = 0; i < ary.length; i++) {\n    var chunk = ary[i];\n    if (chunk.buffer instanceof ArrayBuffer) {\n      var buf = chunk.buffer;\n\n      // if this is a subarray, make a copy so we only\n      // include the subarray region from the underlying buffer\n      if (chunk.byteLength !== buf.byteLength) {\n        var copy = new Uint8Array(chunk.byteLength);\n        copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength));\n        buf = copy.buffer;\n      }\n\n      ary[i] = buf;\n    }\n  }\n}\n\nfunction BlobBuilderConstructor(ary, options) {\n  options = options || {};\n\n  var bb = new BlobBuilder();\n  mapArrayBufferViews(ary);\n\n  for (var i = 0; i < ary.length; i++) {\n    bb.append(ary[i]);\n  }\n\n  return (options.type) ? bb.getBlob(options.type) : bb.getBlob();\n};\n\nfunction BlobConstructor(ary, options) {\n  mapArrayBufferViews(ary);\n  return new Blob(ary, options || {});\n};\n\nmodule.exports = (function() {\n  if (blobSupported) {\n    return blobSupportsArrayBufferView ? global.Blob : BlobConstructor;\n  } else if (blobBuilderSupported) {\n    return BlobBuilderConstructor;\n  } else {\n    return undefined;\n  }\n})();\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM5Zi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvYmxvYi9pbmRleC5qcz8yMTA3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ3JlYXRlIGEgYmxvYiBidWlsZGVyIGV2ZW4gd2hlbiB2ZW5kb3IgcHJlZml4ZXMgZXhpc3RcbiAqL1xuXG52YXIgQmxvYkJ1aWxkZXIgPSBnbG9iYWwuQmxvYkJ1aWxkZXJcbiAgfHwgZ2xvYmFsLldlYktpdEJsb2JCdWlsZGVyXG4gIHx8IGdsb2JhbC5NU0Jsb2JCdWlsZGVyXG4gIHx8IGdsb2JhbC5Nb3pCbG9iQnVpbGRlcjtcblxuLyoqXG4gKiBDaGVjayBpZiBCbG9iIGNvbnN0cnVjdG9yIGlzIHN1cHBvcnRlZFxuICovXG5cbnZhciBibG9iU3VwcG9ydGVkID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIHZhciBhID0gbmV3IEJsb2IoWydoaSddKTtcbiAgICByZXR1cm4gYS5zaXplID09PSAyO1xuICB9IGNhdGNoKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8qKlxuICogQ2hlY2sgaWYgQmxvYiBjb25zdHJ1Y3RvciBzdXBwb3J0cyBBcnJheUJ1ZmZlclZpZXdzXG4gKiBGYWlscyBpbiBTYWZhcmkgNiwgc28gd2UgbmVlZCB0byBtYXAgdG8gQXJyYXlCdWZmZXJzIHRoZXJlLlxuICovXG5cbnZhciBibG9iU3VwcG9ydHNBcnJheUJ1ZmZlclZpZXcgPSBibG9iU3VwcG9ydGVkICYmIChmdW5jdGlvbigpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYiA9IG5ldyBCbG9iKFtuZXcgVWludDhBcnJheShbMSwyXSldKTtcbiAgICByZXR1cm4gYi5zaXplID09PSAyO1xuICB9IGNhdGNoKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8qKlxuICogQ2hlY2sgaWYgQmxvYkJ1aWxkZXIgaXMgc3VwcG9ydGVkXG4gKi9cblxudmFyIGJsb2JCdWlsZGVyU3VwcG9ydGVkID0gQmxvYkJ1aWxkZXJcbiAgJiYgQmxvYkJ1aWxkZXIucHJvdG90eXBlLmFwcGVuZFxuICAmJiBCbG9iQnVpbGRlci5wcm90b3R5cGUuZ2V0QmxvYjtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBtYXBzIEFycmF5QnVmZmVyVmlld3MgdG8gQXJyYXlCdWZmZXJzXG4gKiBVc2VkIGJ5IEJsb2JCdWlsZGVyIGNvbnN0cnVjdG9yIGFuZCBvbGQgYnJvd3NlcnMgdGhhdCBkaWRuJ3RcbiAqIHN1cHBvcnQgaXQgaW4gdGhlIEJsb2IgY29uc3RydWN0b3IuXG4gKi9cblxuZnVuY3Rpb24gbWFwQXJyYXlCdWZmZXJWaWV3cyhhcnkpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnkubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgY2h1bmsgPSBhcnlbaV07XG4gICAgaWYgKGNodW5rLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICB2YXIgYnVmID0gY2h1bmsuYnVmZmVyO1xuXG4gICAgICAvLyBpZiB0aGlzIGlzIGEgc3ViYXJyYXksIG1ha2UgYSBjb3B5IHNvIHdlIG9ubHlcbiAgICAgIC8vIGluY2x1ZGUgdGhlIHN1YmFycmF5IHJlZ2lvbiBmcm9tIHRoZSB1bmRlcmx5aW5nIGJ1ZmZlclxuICAgICAgaWYgKGNodW5rLmJ5dGVMZW5ndGggIT09IGJ1Zi5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHZhciBjb3B5ID0gbmV3IFVpbnQ4QXJyYXkoY2h1bmsuYnl0ZUxlbmd0aCk7XG4gICAgICAgIGNvcHkuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZiwgY2h1bmsuYnl0ZU9mZnNldCwgY2h1bmsuYnl0ZUxlbmd0aCkpO1xuICAgICAgICBidWYgPSBjb3B5LmJ1ZmZlcjtcbiAgICAgIH1cblxuICAgICAgYXJ5W2ldID0gYnVmO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBCbG9iQnVpbGRlckNvbnN0cnVjdG9yKGFyeSwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgYmIgPSBuZXcgQmxvYkJ1aWxkZXIoKTtcbiAgbWFwQXJyYXlCdWZmZXJWaWV3cyhhcnkpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgYmIuYXBwZW5kKGFyeVtpXSk7XG4gIH1cblxuICByZXR1cm4gKG9wdGlvbnMudHlwZSkgPyBiYi5nZXRCbG9iKG9wdGlvbnMudHlwZSkgOiBiYi5nZXRCbG9iKCk7XG59O1xuXG5mdW5jdGlvbiBCbG9iQ29uc3RydWN0b3IoYXJ5LCBvcHRpb25zKSB7XG4gIG1hcEFycmF5QnVmZmVyVmlld3MoYXJ5KTtcbiAgcmV0dXJuIG5ldyBCbG9iKGFyeSwgb3B0aW9ucyB8fCB7fSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IChmdW5jdGlvbigpIHtcbiAgaWYgKGJsb2JTdXBwb3J0ZWQpIHtcbiAgICByZXR1cm4gYmxvYlN1cHBvcnRzQXJyYXlCdWZmZXJWaWV3ID8gZ2xvYmFsLkJsb2IgOiBCbG9iQ29uc3RydWN0b3I7XG4gIH0gZWxzZSBpZiAoYmxvYkJ1aWxkZXJTdXBwb3J0ZWQpIHtcbiAgICByZXR1cm4gQmxvYkJ1aWxkZXJDb25zdHJ1Y3RvcjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59KSgpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///939f\n")},9476:function(module,exports,__webpack_require__){eval("/**\n * A filter provides a chart with an interface to the data.\n * The filter contains a number of `Partition`s and `Aggregate`s.\n * It takes care of calling the relevant functions provided by a `Dataset`.\n *\n * @class Filter\n * @extends Base\n */\n\n/**\n * @typedef {Object} DataRecord - Object holding the plot data, partitions are labelled with a single small letter, aggregates with a double small letter\n * @property {string} DataRecord.a Value of first partition\n * @property {string} DataRecord.b Value of second partition\n * @property {string} DataRecord.c Value of third partition, etc.\n * @property {string} DataRecord.aa Value of first aggregate\n * @property {string} DataRecord.bb Value of second aggregate, etc.\n */\n\n/**\n * @typedef {DataRecord[]} Data - Array of DataRecords\n */\n\nvar Base = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Aggregates = __webpack_require__(/*! ./aggregate/collection */ \"fbef\");\nvar Partitions = __webpack_require__(/*! ./partition/collection */ \"e59a\");\n\nmodule.exports = Base.extend({\n  props: {\n    /**\n     * Hint for the client (website) how to visualize this filter\n     * @memberof! Filter\n     * @type {string}\n     */\n    chartType: {\n      type: 'string',\n      required: true,\n      default: 'barchart',\n      values: ['piechart', 'horizontalbarchart', 'barchart', 'linechart', 'radarchart', 'polarareachart', 'bubbleplot', 'scatterchart', 'networkchart']\n    },\n    /**\n     * Title for displaying purposes\n     * @memberof! Filter\n     * @type {string}\n     */\n    title: ['string', true, ''],\n    /**\n     * Hint for the client (website) how to position the chart for this filter\n     * position (col, row) and size (size_x, size_y) of chart\n     */\n    col: 'number',\n    row: 'number',\n    size_x: 'number',\n    size_y: 'number'\n  },\n  collections: {\n    /**\n     * @memberof! Filter\n     * @type {Partitions[]}\n     */\n    partitions: Partitions,\n    /**\n     * @memberof! Filter\n     * @type {Aggregate[]}\n     */\n    aggregates: Aggregates\n  },\n  // Session properties are not typically persisted to the server,\n  // and are not returned by calls to toJSON() or serialize().\n  session: {\n    /**\n     * Array containing the data to plot\n     * @memberof! Filter\n     * @type {Data}\n     */\n    data: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    },\n    /*\n     * Call this function to request new data.\n     * The dataset backing the facet will copy the data to Filter.data.\n     * A newData event is fired when the data is ready to be plotted.\n     *\n     * @function\n     * @virtual\n     * @private\n     * @memberof! Filter\n     * @emits newData\n     */\n    getData: {\n      type: 'any'\n    },\n    /**\n     * A history of the current drill-down (ie. partitions.toJSON())\n     */\n    zoomHistory: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    },\n    /**\n     * Boolean indicating if the filter is initialized\n     */\n    isInitialized: {\n      type: 'boolean',\n      required: true,\n      default: false\n    }\n  },\n  initialize: function () {\n    // set up callback to free internal state on remove\n    this.on('remove', function () {\n      this.releaseDataFilter();\n    });\n  },\n  zoomIn: function () {\n    this.releaseDataFilter();\n\n    // save current state\n    this.zoomHistory.push(JSON.stringify(this.partitions.toJSON()));\n\n    this.partitions.forEach(function (partition) {\n      if ((partition.selected.length === 2) && (partition.isDatetime || partition.isContinuous)) {\n        if (partition.groupFixedS || partition.groupFixedSC) {\n          // scale down binsize\n          var newSize = partition.selected[1] - partition.selected[0];\n          var oldSize = partition.maxval - partition.minval;\n          partition.groupingParam = partition.groupingParam * newSize / oldSize;\n        }\n        // zoom to selected range, if possible\n        partition.set({\n          minval: partition.selected[0],\n          maxval: partition.selected[1]\n        });\n      } else if (partition.selected.length > 0 && (partition.isCategorial)) {\n        // zoom to selected categories, if possible\n        partition.groups.reset();\n        partition.selected.forEach(function (value) {\n          partition.groups.add({\n            value: value,\n            label: value,\n            count: 0,\n            isSelected: true\n          });\n        });\n      }\n      // select all\n      partition.updateSelection();\n    });\n    this.initDataFilter();\n    this.updateDataFilter(); // also triggers a getAllData()\n  },\n  zoomOut: function () {\n    var doReset = true;\n\n    // clear current selection\n    this.partitions.forEach(function (partition) {\n      if (partition.selected.length > 0) {\n        partition.updateSelection();\n        doReset = false;\n      }\n    });\n\n    if (doReset) {\n      this.releaseDataFilter();\n      if (this.zoomHistory.length > 0) {\n        // nothing was selected and we have drilled down: go up\n        var state = JSON.parse(this.zoomHistory.pop());\n        this.partitions.reset(state);\n      } else {\n        // nothing was selected and no drill down: reset partitioning\n        this.partitions.forEach(function (partition) {\n          if (partition.isDatetime || partition.isContinuous) {\n            partition.reset();\n          }\n        });\n      }\n      this.initDataFilter();\n    }\n    this.updateDataFilter(); // also triggers a getAllData()\n  },\n  // Apply the separate filterFunctions from each partition in a single function\n  filterFunction: function () {\n    var fs = [];\n    this.partitions.forEach(function (partition) {\n      fs.push(partition.filterFunction());\n    });\n    return function (d) {\n      if (typeof d === 'string') {\n        var groups = d.split('|');\n        return fs.every(function (f, i) { return f(groups[i]); });\n      } else {\n        // shortcut for non-partitioned numeric data\n        return fs[0](d);\n      }\n    };\n  },\n  /**\n   * Initialize the data filter, and construct the getData callback function on the filter.\n   *\n   * @memberof! Filter\n   */\n  initDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.releaseDataFilter(dataview, this);\n    spot.driver.initDataFilter(dataview, this);\n    spot.driver.updateDataFilter(this);\n\n    this.isInitialized = true;\n  },\n  /**\n   * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n   * related to the filter.\n   *\n   * @memberof! Filter\n   */\n  releaseDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.releaseDataFilter(dataview, this);\n\n    this.isInitialized = false;\n  },\n  /**\n   * Apply changes to the filter (like selecting groups)\n   *\n   * @memberof! Filter\n   */\n  updateDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.updateDataFilter(this);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ3Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmlsdGVyLmpzPzM4ZmYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBIGZpbHRlciBwcm92aWRlcyBhIGNoYXJ0IHdpdGggYW4gaW50ZXJmYWNlIHRvIHRoZSBkYXRhLlxuICogVGhlIGZpbHRlciBjb250YWlucyBhIG51bWJlciBvZiBgUGFydGl0aW9uYHMgYW5kIGBBZ2dyZWdhdGVgcy5cbiAqIEl0IHRha2VzIGNhcmUgb2YgY2FsbGluZyB0aGUgcmVsZXZhbnQgZnVuY3Rpb25zIHByb3ZpZGVkIGJ5IGEgYERhdGFzZXRgLlxuICpcbiAqIEBjbGFzcyBGaWx0ZXJcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IERhdGFSZWNvcmQgLSBPYmplY3QgaG9sZGluZyB0aGUgcGxvdCBkYXRhLCBwYXJ0aXRpb25zIGFyZSBsYWJlbGxlZCB3aXRoIGEgc2luZ2xlIHNtYWxsIGxldHRlciwgYWdncmVnYXRlcyB3aXRoIGEgZG91YmxlIHNtYWxsIGxldHRlclxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYSBWYWx1ZSBvZiBmaXJzdCBwYXJ0aXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEYXRhUmVjb3JkLmIgVmFsdWUgb2Ygc2Vjb25kIHBhcnRpdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYyBWYWx1ZSBvZiB0aGlyZCBwYXJ0aXRpb24sIGV0Yy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEYXRhUmVjb3JkLmFhIFZhbHVlIG9mIGZpcnN0IGFnZ3JlZ2F0ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYmIgVmFsdWUgb2Ygc2Vjb25kIGFnZ3JlZ2F0ZSwgZXRjLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge0RhdGFSZWNvcmRbXX0gRGF0YSAtIEFycmF5IG9mIERhdGFSZWNvcmRzXG4gKi9cblxudmFyIEJhc2UgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIEFnZ3JlZ2F0ZXMgPSByZXF1aXJlKCcuL2FnZ3JlZ2F0ZS9jb2xsZWN0aW9uJyk7XG52YXIgUGFydGl0aW9ucyA9IHJlcXVpcmUoJy4vcGFydGl0aW9uL2NvbGxlY3Rpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogSGludCBmb3IgdGhlIGNsaWVudCAod2Vic2l0ZSkgaG93IHRvIHZpc3VhbGl6ZSB0aGlzIGZpbHRlclxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBjaGFydFR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnYmFyY2hhcnQnLFxuICAgICAgdmFsdWVzOiBbJ3BpZWNoYXJ0JywgJ2hvcml6b250YWxiYXJjaGFydCcsICdiYXJjaGFydCcsICdsaW5lY2hhcnQnLCAncmFkYXJjaGFydCcsICdwb2xhcmFyZWFjaGFydCcsICdidWJibGVwbG90JywgJ3NjYXR0ZXJjaGFydCcsICduZXR3b3JrY2hhcnQnXVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGl0bGUgZm9yIGRpc3BsYXlpbmcgcHVycG9zZXNcbiAgICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGl0bGU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuICAgIC8qKlxuICAgICAqIEhpbnQgZm9yIHRoZSBjbGllbnQgKHdlYnNpdGUpIGhvdyB0byBwb3NpdGlvbiB0aGUgY2hhcnQgZm9yIHRoaXMgZmlsdGVyXG4gICAgICogcG9zaXRpb24gKGNvbCwgcm93KSBhbmQgc2l6ZSAoc2l6ZV94LCBzaXplX3kpIG9mIGNoYXJ0XG4gICAgICovXG4gICAgY29sOiAnbnVtYmVyJyxcbiAgICByb3c6ICdudW1iZXInLFxuICAgIHNpemVfeDogJ251bWJlcicsXG4gICAgc2l6ZV95OiAnbnVtYmVyJ1xuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge1BhcnRpdGlvbnNbXX1cbiAgICAgKi9cbiAgICBwYXJ0aXRpb25zOiBQYXJ0aXRpb25zLFxuICAgIC8qKlxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge0FnZ3JlZ2F0ZVtdfVxuICAgICAqL1xuICAgIGFnZ3JlZ2F0ZXM6IEFnZ3JlZ2F0ZXNcbiAgfSxcbiAgLy8gU2Vzc2lvbiBwcm9wZXJ0aWVzIGFyZSBub3QgdHlwaWNhbGx5IHBlcnNpc3RlZCB0byB0aGUgc2VydmVyLFxuICAvLyBhbmQgYXJlIG5vdCByZXR1cm5lZCBieSBjYWxscyB0byB0b0pTT04oKSBvciBzZXJpYWxpemUoKS5cbiAgc2Vzc2lvbjoge1xuICAgIC8qKlxuICAgICAqIEFycmF5IGNvbnRhaW5pbmcgdGhlIGRhdGEgdG8gcGxvdFxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge0RhdGF9XG4gICAgICovXG4gICAgZGF0YToge1xuICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0sXG4gICAgLypcbiAgICAgKiBDYWxsIHRoaXMgZnVuY3Rpb24gdG8gcmVxdWVzdCBuZXcgZGF0YS5cbiAgICAgKiBUaGUgZGF0YXNldCBiYWNraW5nIHRoZSBmYWNldCB3aWxsIGNvcHkgdGhlIGRhdGEgdG8gRmlsdGVyLmRhdGEuXG4gICAgICogQSBuZXdEYXRhIGV2ZW50IGlzIGZpcmVkIHdoZW4gdGhlIGRhdGEgaXMgcmVhZHkgdG8gYmUgcGxvdHRlZC5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEB2aXJ0dWFsXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgICAqIEBlbWl0cyBuZXdEYXRhXG4gICAgICovXG4gICAgZ2V0RGF0YToge1xuICAgICAgdHlwZTogJ2FueSdcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIEEgaGlzdG9yeSBvZiB0aGUgY3VycmVudCBkcmlsbC1kb3duIChpZS4gcGFydGl0aW9ucy50b0pTT04oKSlcbiAgICAgKi9cbiAgICB6b29tSGlzdG9yeToge1xuICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogQm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSBmaWx0ZXIgaXMgaW5pdGlhbGl6ZWRcbiAgICAgKi9cbiAgICBpc0luaXRpYWxpemVkOiB7XG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IGZhbHNlXG4gICAgfVxuICB9LFxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gc2V0IHVwIGNhbGxiYWNrIHRvIGZyZWUgaW50ZXJuYWwgc3RhdGUgb24gcmVtb3ZlXG4gICAgdGhpcy5vbigncmVtb3ZlJywgZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5yZWxlYXNlRGF0YUZpbHRlcigpO1xuICAgIH0pO1xuICB9LFxuICB6b29tSW46IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlbGVhc2VEYXRhRmlsdGVyKCk7XG5cbiAgICAvLyBzYXZlIGN1cnJlbnQgc3RhdGVcbiAgICB0aGlzLnpvb21IaXN0b3J5LnB1c2goSlNPTi5zdHJpbmdpZnkodGhpcy5wYXJ0aXRpb25zLnRvSlNPTigpKSk7XG5cbiAgICB0aGlzLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uKSB7XG4gICAgICBpZiAoKHBhcnRpdGlvbi5zZWxlY3RlZC5sZW5ndGggPT09IDIpICYmIChwYXJ0aXRpb24uaXNEYXRldGltZSB8fCBwYXJ0aXRpb24uaXNDb250aW51b3VzKSkge1xuICAgICAgICBpZiAocGFydGl0aW9uLmdyb3VwRml4ZWRTIHx8IHBhcnRpdGlvbi5ncm91cEZpeGVkU0MpIHtcbiAgICAgICAgICAvLyBzY2FsZSBkb3duIGJpbnNpemVcbiAgICAgICAgICB2YXIgbmV3U2l6ZSA9IHBhcnRpdGlvbi5zZWxlY3RlZFsxXSAtIHBhcnRpdGlvbi5zZWxlY3RlZFswXTtcbiAgICAgICAgICB2YXIgb2xkU2l6ZSA9IHBhcnRpdGlvbi5tYXh2YWwgLSBwYXJ0aXRpb24ubWludmFsO1xuICAgICAgICAgIHBhcnRpdGlvbi5ncm91cGluZ1BhcmFtID0gcGFydGl0aW9uLmdyb3VwaW5nUGFyYW0gKiBuZXdTaXplIC8gb2xkU2l6ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyB6b29tIHRvIHNlbGVjdGVkIHJhbmdlLCBpZiBwb3NzaWJsZVxuICAgICAgICBwYXJ0aXRpb24uc2V0KHtcbiAgICAgICAgICBtaW52YWw6IHBhcnRpdGlvbi5zZWxlY3RlZFswXSxcbiAgICAgICAgICBtYXh2YWw6IHBhcnRpdGlvbi5zZWxlY3RlZFsxXVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCA+IDAgJiYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwpKSB7XG4gICAgICAgIC8vIHpvb20gdG8gc2VsZWN0ZWQgY2F0ZWdvcmllcywgaWYgcG9zc2libGVcbiAgICAgICAgcGFydGl0aW9uLmdyb3Vwcy5yZXNldCgpO1xuICAgICAgICBwYXJ0aXRpb24uc2VsZWN0ZWQuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICBwYXJ0aXRpb24uZ3JvdXBzLmFkZCh7XG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICBsYWJlbDogdmFsdWUsXG4gICAgICAgICAgICBjb3VudDogMCxcbiAgICAgICAgICAgIGlzU2VsZWN0ZWQ6IHRydWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyBzZWxlY3QgYWxsXG4gICAgICBwYXJ0aXRpb24udXBkYXRlU2VsZWN0aW9uKCk7XG4gICAgfSk7XG4gICAgdGhpcy5pbml0RGF0YUZpbHRlcigpO1xuICAgIHRoaXMudXBkYXRlRGF0YUZpbHRlcigpOyAvLyBhbHNvIHRyaWdnZXJzIGEgZ2V0QWxsRGF0YSgpXG4gIH0sXG4gIHpvb21PdXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZG9SZXNldCA9IHRydWU7XG5cbiAgICAvLyBjbGVhciBjdXJyZW50IHNlbGVjdGlvblxuICAgIHRoaXMucGFydGl0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgICAgIGlmIChwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoID4gMCkge1xuICAgICAgICBwYXJ0aXRpb24udXBkYXRlU2VsZWN0aW9uKCk7XG4gICAgICAgIGRvUmVzZXQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChkb1Jlc2V0KSB7XG4gICAgICB0aGlzLnJlbGVhc2VEYXRhRmlsdGVyKCk7XG4gICAgICBpZiAodGhpcy56b29tSGlzdG9yeS5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIG5vdGhpbmcgd2FzIHNlbGVjdGVkIGFuZCB3ZSBoYXZlIGRyaWxsZWQgZG93bjogZ28gdXBcbiAgICAgICAgdmFyIHN0YXRlID0gSlNPTi5wYXJzZSh0aGlzLnpvb21IaXN0b3J5LnBvcCgpKTtcbiAgICAgICAgdGhpcy5wYXJ0aXRpb25zLnJlc2V0KHN0YXRlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG5vdGhpbmcgd2FzIHNlbGVjdGVkIGFuZCBubyBkcmlsbCBkb3duOiByZXNldCBwYXJ0aXRpb25pbmdcbiAgICAgICAgdGhpcy5wYXJ0aXRpb25zLmZvckVhY2goZnVuY3Rpb24gKHBhcnRpdGlvbikge1xuICAgICAgICAgIGlmIChwYXJ0aXRpb24uaXNEYXRldGltZSB8fCBwYXJ0aXRpb24uaXNDb250aW51b3VzKSB7XG4gICAgICAgICAgICBwYXJ0aXRpb24ucmVzZXQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgdGhpcy5pbml0RGF0YUZpbHRlcigpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZURhdGFGaWx0ZXIoKTsgLy8gYWxzbyB0cmlnZ2VycyBhIGdldEFsbERhdGEoKVxuICB9LFxuICAvLyBBcHBseSB0aGUgc2VwYXJhdGUgZmlsdGVyRnVuY3Rpb25zIGZyb20gZWFjaCBwYXJ0aXRpb24gaW4gYSBzaW5nbGUgZnVuY3Rpb25cbiAgZmlsdGVyRnVuY3Rpb246IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZnMgPSBbXTtcbiAgICB0aGlzLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uKSB7XG4gICAgICBmcy5wdXNoKHBhcnRpdGlvbi5maWx0ZXJGdW5jdGlvbigpKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmICh0eXBlb2YgZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdmFyIGdyb3VwcyA9IGQuc3BsaXQoJ3wnKTtcbiAgICAgICAgcmV0dXJuIGZzLmV2ZXJ5KGZ1bmN0aW9uIChmLCBpKSB7IHJldHVybiBmKGdyb3Vwc1tpXSk7IH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gc2hvcnRjdXQgZm9yIG5vbi1wYXJ0aXRpb25lZCBudW1lcmljIGRhdGFcbiAgICAgICAgcmV0dXJuIGZzWzBdKGQpO1xuICAgICAgfVxuICAgIH07XG4gIH0sXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICAgKlxuICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgKi9cbiAgaW5pdERhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIucmVsZWFzZURhdGFGaWx0ZXIoZGF0YXZpZXcsIHRoaXMpO1xuICAgIHNwb3QuZHJpdmVyLmluaXREYXRhRmlsdGVyKGRhdGF2aWV3LCB0aGlzKTtcbiAgICBzcG90LmRyaXZlci51cGRhdGVEYXRhRmlsdGVyKHRoaXMpO1xuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgfSxcbiAgLyoqXG4gICAqIFRoZSBvcHBvc2l0ZSBvciBpbml0RGF0YUZpbHRlciwgaXQgc2hvdWxkIHJlbW92ZSB0aGUgZmlsdGVyIGFuZCBkZWFsbG9jYXRlIG90aGVyIGNvbmZpZ3VyYXRpb25cbiAgICogcmVsYXRlZCB0byB0aGUgZmlsdGVyLlxuICAgKlxuICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgKi9cbiAgcmVsZWFzZURhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIucmVsZWFzZURhdGFGaWx0ZXIoZGF0YXZpZXcsIHRoaXMpO1xuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gZmFsc2U7XG4gIH0sXG4gIC8qKlxuICAgKiBBcHBseSBjaGFuZ2VzIHRvIHRoZSBmaWx0ZXIgKGxpa2Ugc2VsZWN0aW5nIGdyb3VwcylcbiAgICpcbiAgICogQG1lbWJlcm9mISBGaWx0ZXJcbiAgICovXG4gIHVwZGF0ZURhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIudXBkYXRlRGF0YUZpbHRlcih0aGlzKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9476\n")},"9b75":function(module,exports,__webpack_require__){eval("/**\n * CategorialTransfrom defines a transformation on categorial and textual data,\n * and is implemented as a collection of rules.\n *\n * @class CategorialTransform\n */\nvar Model = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\n\nvar Rule = __webpack_require__(/*! ./categorial-rule */ \"ba23\");\nvar Rules = Collection.extend({\n  indexes: ['expression'],\n  model: Rule\n});\n\n/**\n * Apply the first applicable transformation rule.\n * When no matching rule is found, return 'Other'\n *\n * @function\n * @memberof! CategorialTransform\n * @param {string} text\n * @returns {string} text The transformed text\n */\nfunction transform (rules, text) {\n  var i;\n  for (i = 0; i < rules.length; i++) {\n    var group = rules.models[i].match(text);\n    if (group) {\n      return group;\n    }\n  }\n  return 'Other';\n}\n\nmodule.exports = Model.extend({\n  props: {\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['categorial']\n    },\n    transformedMin: {\n      type: 'number',\n      required: true,\n      default: 0\n    },\n    transformedMax: {\n      type: 'number',\n      required: true,\n      default: 100\n    },\n    transformedMinAsText: {\n      type: 'string',\n      required: true,\n      default: '0'\n    },\n    transformedMaxAsText: {\n      type: 'string',\n      required: true,\n      default: '100'\n    }\n  },\n  collections: {\n    rules: Rules\n  },\n  transform: function (labels) {\n    if (!this.rules) {\n      return labels;\n    }\n    if (labels instanceof Array) {\n      labels.forEach(function (label, i) {\n        labels[i] = transform(this.rules, label);\n      }, this);\n    } else {\n      labels = transform(this.rules, labels);\n    }\n    return labels;\n  },\n  reset: function () {\n    this.rules.reset();\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWI3NS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY2F0ZWdvcmlhbC10cmFuc2Zvcm0uanM/MzBlYiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENhdGVnb3JpYWxUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNhdGVnb3JpYWwgYW5kIHRleHR1YWwgZGF0YSxcbiAqIGFuZCBpcyBpbXBsZW1lbnRlZCBhcyBhIGNvbGxlY3Rpb24gb2YgcnVsZXMuXG4gKlxuICogQGNsYXNzIENhdGVnb3JpYWxUcmFuc2Zvcm1cbiAqL1xudmFyIE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG52YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG5cbnZhciBSdWxlID0gcmVxdWlyZSgnLi9jYXRlZ29yaWFsLXJ1bGUnKTtcbnZhciBSdWxlcyA9IENvbGxlY3Rpb24uZXh0ZW5kKHtcbiAgaW5kZXhlczogWydleHByZXNzaW9uJ10sXG4gIG1vZGVsOiBSdWxlXG59KTtcblxuLyoqXG4gKiBBcHBseSB0aGUgZmlyc3QgYXBwbGljYWJsZSB0cmFuc2Zvcm1hdGlvbiBydWxlLlxuICogV2hlbiBubyBtYXRjaGluZyBydWxlIGlzIGZvdW5kLCByZXR1cm4gJ090aGVyJ1xuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mISBDYXRlZ29yaWFsVHJhbnNmb3JtXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICogQHJldHVybnMge3N0cmluZ30gdGV4dCBUaGUgdHJhbnNmb3JtZWQgdGV4dFxuICovXG5mdW5jdGlvbiB0cmFuc2Zvcm0gKHJ1bGVzLCB0ZXh0KSB7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgcnVsZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZ3JvdXAgPSBydWxlcy5tb2RlbHNbaV0ubWF0Y2godGV4dCk7XG4gICAgaWYgKGdyb3VwKSB7XG4gICAgICByZXR1cm4gZ3JvdXA7XG4gICAgfVxuICB9XG4gIHJldHVybiAnT3RoZXInO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IE1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgdHJhbnNmb3JtZWRUeXBlOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ2NhdGVnb3JpYWwnLFxuICAgICAgdmFsdWVzOiBbJ2NhdGVnb3JpYWwnXVxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNaW46IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAwXG4gICAgfSxcbiAgICB0cmFuc2Zvcm1lZE1heDoge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IDEwMFxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNaW5Bc1RleHQ6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnMCdcbiAgICB9LFxuICAgIHRyYW5zZm9ybWVkTWF4QXNUZXh0OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJzEwMCdcbiAgICB9XG4gIH0sXG4gIGNvbGxlY3Rpb25zOiB7XG4gICAgcnVsZXM6IFJ1bGVzXG4gIH0sXG4gIHRyYW5zZm9ybTogZnVuY3Rpb24gKGxhYmVscykge1xuICAgIGlmICghdGhpcy5ydWxlcykge1xuICAgICAgcmV0dXJuIGxhYmVscztcbiAgICB9XG4gICAgaWYgKGxhYmVscyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBsYWJlbHMuZm9yRWFjaChmdW5jdGlvbiAobGFiZWwsIGkpIHtcbiAgICAgICAgbGFiZWxzW2ldID0gdHJhbnNmb3JtKHRoaXMucnVsZXMsIGxhYmVsKTtcbiAgICAgIH0sIHRoaXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYWJlbHMgPSB0cmFuc2Zvcm0odGhpcy5ydWxlcywgbGFiZWxzKTtcbiAgICB9XG4gICAgcmV0dXJuIGxhYmVscztcbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJ1bGVzLnJlc2V0KCk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9b75\n")},"9d63":function(module,exports,__webpack_require__){eval("/**\n * The Aggregate class describes how to aggregate data, as described by a `Facet` into a single value.\n * For example, you can sum or average over numbers, or count the number of different labels.\n *\n * @class Aggregate\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\n\nmodule.exports = BaseModel.extend({\n  props: {\n    /**\n     * The name of the facet to aggregate over\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    facetName: 'string',\n\n    /**\n     * Label for displaying on plots\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    label: {\n      type: 'string',\n      required: true,\n      default: ''\n    },\n\n    /**\n     * When part of a aggregates, this deterimines the ordering\n     * @memberof! Aggregate\n     * @type {number}\n     */\n    rank: {\n      type: 'number',\n      required: true\n    },\n\n    /**\n     * Operation:\n     *  * `count`  count the number of elements in the group\n     *  * `sum`    sum the elements in the group\n     *  * `avg`    take the average of the elements in the group\n     *  * `stddev`  take the sample\n     *  * `min`    minum value of the elements in the group\n     *  * `max`    maximum value of the elements in the group\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    operation: {\n      type: 'string',\n      required: true,\n      default: 'avg',\n      values: ['count', 'avg', 'sum', 'stddev', 'min', 'max']\n    },\n    // NOTE: properties for reduction, should be a valid SQL aggregation function\n\n    /**\n     * Normalization: TODO\n     *  * `none`      data in same units as the original data\n     *  * `relative`  data is in percentages of the total; for subgroups in percentage of the parent group\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    normalization: {\n      type: 'string',\n      required: true,\n      default: 'none',\n      values: ['none', 'percentage']\n    }\n  },\n  derived: {\n    // operation values\n    doSum: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'sum';\n      }\n    },\n    doCount: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'count';\n      }\n    },\n    doAverage: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'avg';\n      }\n    },\n    doStddev: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'stddev';\n      }\n    },\n    doMin: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'min';\n      }\n    },\n    doMax: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'max';\n      }\n    },\n\n    // normalization values\n    normalizeNone: {\n      deps: ['normalization'],\n      fn: function () {\n        return this.normalization === 'absolute';\n      }\n    },\n    normalizePercentage: {\n      deps: ['normalization'],\n      fn: function () {\n        return this.normalization === 'percentage';\n      }\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWQ2My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvYWdncmVnYXRlLmpzP2JkNmEiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgQWdncmVnYXRlIGNsYXNzIGRlc2NyaWJlcyBob3cgdG8gYWdncmVnYXRlIGRhdGEsIGFzIGRlc2NyaWJlZCBieSBhIGBGYWNldGAgaW50byBhIHNpbmdsZSB2YWx1ZS5cbiAqIEZvciBleGFtcGxlLCB5b3UgY2FuIHN1bSBvciBhdmVyYWdlIG92ZXIgbnVtYmVycywgb3IgY291bnQgdGhlIG51bWJlciBvZiBkaWZmZXJlbnQgbGFiZWxzLlxuICpcbiAqIEBjbGFzcyBBZ2dyZWdhdGVcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGZhY2V0IHRvIGFnZ3JlZ2F0ZSBvdmVyXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZhY2V0TmFtZTogJ3N0cmluZycsXG5cbiAgICAvKipcbiAgICAgKiBMYWJlbCBmb3IgZGlzcGxheWluZyBvbiBwbG90c1xuICAgICAqIEBtZW1iZXJvZiEgQWdncmVnYXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBsYWJlbDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICcnXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFdoZW4gcGFydCBvZiBhIGFnZ3JlZ2F0ZXMsIHRoaXMgZGV0ZXJpbWluZXMgdGhlIG9yZGVyaW5nXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHJhbms6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogT3BlcmF0aW9uOlxuICAgICAqICAqIGBjb3VudGAgIGNvdW50IHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGdyb3VwXG4gICAgICogICogYHN1bWAgICAgc3VtIHRoZSBlbGVtZW50cyBpbiB0aGUgZ3JvdXBcbiAgICAgKiAgKiBgYXZnYCAgICB0YWtlIHRoZSBhdmVyYWdlIG9mIHRoZSBlbGVtZW50cyBpbiB0aGUgZ3JvdXBcbiAgICAgKiAgKiBgc3RkZGV2YCAgdGFrZSB0aGUgc2FtcGxlXG4gICAgICogICogYG1pbmAgICAgbWludW0gdmFsdWUgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBncm91cFxuICAgICAqICAqIGBtYXhgICAgIG1heGltdW0gdmFsdWUgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBncm91cFxuICAgICAqIEBtZW1iZXJvZiEgQWdncmVnYXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBvcGVyYXRpb246IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnYXZnJyxcbiAgICAgIHZhbHVlczogWydjb3VudCcsICdhdmcnLCAnc3VtJywgJ3N0ZGRldicsICdtaW4nLCAnbWF4J11cbiAgICB9LFxuICAgIC8vIE5PVEU6IHByb3BlcnRpZXMgZm9yIHJlZHVjdGlvbiwgc2hvdWxkIGJlIGEgdmFsaWQgU1FMIGFnZ3JlZ2F0aW9uIGZ1bmN0aW9uXG5cbiAgICAvKipcbiAgICAgKiBOb3JtYWxpemF0aW9uOiBUT0RPXG4gICAgICogICogYG5vbmVgICAgICAgZGF0YSBpbiBzYW1lIHVuaXRzIGFzIHRoZSBvcmlnaW5hbCBkYXRhXG4gICAgICogICogYHJlbGF0aXZlYCAgZGF0YSBpcyBpbiBwZXJjZW50YWdlcyBvZiB0aGUgdG90YWw7IGZvciBzdWJncm91cHMgaW4gcGVyY2VudGFnZSBvZiB0aGUgcGFyZW50IGdyb3VwXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG5vcm1hbGl6YXRpb246IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnbm9uZScsXG4gICAgICB2YWx1ZXM6IFsnbm9uZScsICdwZXJjZW50YWdlJ11cbiAgICB9XG4gIH0sXG4gIGRlcml2ZWQ6IHtcbiAgICAvLyBvcGVyYXRpb24gdmFsdWVzXG4gICAgZG9TdW06IHtcbiAgICAgIGRlcHM6IFsnb3BlcmF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vcGVyYXRpb24gPT09ICdzdW0nO1xuICAgICAgfVxuICAgIH0sXG4gICAgZG9Db3VudDoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ2NvdW50JztcbiAgICAgIH1cbiAgICB9LFxuICAgIGRvQXZlcmFnZToge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ2F2Zyc7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb1N0ZGRldjoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ3N0ZGRldic7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb01pbjoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ21pbic7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb01heDoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ21heCc7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8vIG5vcm1hbGl6YXRpb24gdmFsdWVzXG4gICAgbm9ybWFsaXplTm9uZToge1xuICAgICAgZGVwczogWydub3JtYWxpemF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxpemF0aW9uID09PSAnYWJzb2x1dGUnO1xuICAgICAgfVxuICAgIH0sXG4gICAgbm9ybWFsaXplUGVyY2VudGFnZToge1xuICAgICAgZGVwczogWydub3JtYWxpemF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxpemF0aW9uID09PSAncGVyY2VudGFnZSc7XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9d63\n")},a0ca:function(module,exports,__webpack_require__){eval("/**\n * DatetimeTransform defines a transformation on time or dates with timezones\n *\n * @class DatetimeTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Timezone to use when parsing, for when timezone information is absent or incorrect.\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    zone: ['string', true, 'ISO8601'],\n\n    /**\n     * Format indentifier to use when parsing, when not in ISO8601 format\n     * Mappings are defined in util/time.js => timeParts.description\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    format: ['string', true, 'ISO8601'],\n\n    /**\n     * Reformats to a string using the momentjs or postgreSQL format specifiers.\n     * This allows a transformation to day of the year, or day of week etc.\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedFormat: ['string', true, 'ISO8601'],\n\n    /**\n     * Controls conversion to duration by subtracting this date\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedReference: 'string',\n\n    /**\n     * Reference timezone for conversion from datetime to duration\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedZone: ['string', true, 'ISO8601']\n\n  },\n  derived: {\n    // reference momentjs for duration <-> datetime conversion\n    referenceMoment: {\n      deps: ['transformedReference', 'transformedZone'],\n      fn: function () {\n        var tz;\n        if (this.transformedZone === 'ISO8601') {\n          tz = moment.tz.guess();\n        } else {\n          var timeZone = util.timeZones.get(this.transformedZone, 'description');\n          if (timeZone && timeZone.format) {\n            tz = timeZone.format;\n          } else {\n            tz = moment.tz.guess();\n          }\n        }\n        if (this.transformedReference) {\n          return moment.tz(this.transformedReference, tz);\n        }\n        return null;\n      }\n    },\n    /**\n     * The type of the facet after the transformation has been applied\n     * @memberof! DatetimeTransform\n     */\n    transformedType: {\n      deps: ['transformedFormat', 'transformedReference'],\n      fn: function () {\n        if (this.transformedReference) {\n          // datetime -> duration\n          return 'duration';\n        } else if (this.transformedFormat === 'ISO8601') {\n          // datetime -> datetime\n          return 'datetime';\n        } else {\n          // datetime -> time part\n          var timePart = util.timeParts.get(this.transformedFormat, 'description');\n          if (timePart && timePart.type) {\n            return timePart.type;\n          }\n        }\n        return 'datetime';\n      },\n      cache: false\n    },\n    /**\n     * The minium value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! DatetimeTransform\n     */\n    transformedMin: {\n      deps: ['transformedType'],\n      fn: function () {\n        var timePart;\n        if (this.transformedType === 'datetime' || this.transformedType === 'duration') {\n          return this.transform(this.parent.minval);\n        }\n        timePart = util.timeParts.get(this.transformedFormat, 'description');\n        if (timePart.calcualte) {\n          return this.transform(this.parent.minval);\n        } else {\n          return timePart.min;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! DatetimeTransform\n     */\n    transformedMax: {\n      deps: ['transformedType'],\n      fn: function () {\n        var timePart;\n        if (this.transformedType === 'datetime' || this.transformedType === 'duration') {\n          return this.transform(this.parent.maxval);\n        }\n        timePart = util.timeParts.get(this.transformedFormat, 'description');\n        if (timePart.calcualte) {\n          return this.transform(this.parent.maxval);\n        } else {\n          return timePart.max;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DatetimeTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DatetimeTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n\n  /**\n   * @function\n   * @memberof! DatetimeTransform\n   * @param {Object} momentjs\n   * @returns {Object} momentjs\n   */\n  transform: function transform (inval) {\n    if (typeof inval === 'undefined') {\n      return misval;\n    }\n\n    var d = inval.clone();\n    var timePart;\n\n    if (this.referenceMoment) {\n      // datetime -> duration\n      return moment.duration(d.diff(this.referenceMoment, 'milliseconds', true), 'milliseconds');\n    } else if (this.transformedFormat !== 'ISO8601') {\n      timePart = util.timeParts.get(this.transformedFormat, 'description');\n      if (timePart && timePart.momentFormat) {\n        return d.format(timePart.momentFormat);\n      }\n      return d;\n    } else {\n      return d;\n    }\n  },\n  reset: function () {\n    this.unset(['zone', 'transformedFormat', 'transformedZone', 'transformedReference']);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYTBjYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvZGF0ZXRpbWUtdHJhbnNmb3JtLmpzPzM1YTIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEYXRldGltZVRyYW5zZm9ybSBkZWZpbmVzIGEgdHJhbnNmb3JtYXRpb24gb24gdGltZSBvciBkYXRlcyB3aXRoIHRpbWV6b25lc1xuICpcbiAqIEBjbGFzcyBEYXRldGltZVRyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC90aW1lJyk7XG52YXIgbWlzdmFsID0gcmVxdWlyZSgnLi4vdXRpbC9taXN2YWwnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRpbWV6b25lIHRvIHVzZSB3aGVuIHBhcnNpbmcsIGZvciB3aGVuIHRpbWV6b25lIGluZm9ybWF0aW9uIGlzIGFic2VudCBvciBpbmNvcnJlY3QuXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgem9uZTogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogRm9ybWF0IGluZGVudGlmaWVyIHRvIHVzZSB3aGVuIHBhcnNpbmcsIHdoZW4gbm90IGluIElTTzg2MDEgZm9ybWF0XG4gICAgICogTWFwcGluZ3MgYXJlIGRlZmluZWQgaW4gdXRpbC90aW1lLmpzID0+IHRpbWVQYXJ0cy5kZXNjcmlwdGlvblxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZvcm1hdDogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogUmVmb3JtYXRzIHRvIGEgc3RyaW5nIHVzaW5nIHRoZSBtb21lbnRqcyBvciBwb3N0Z3JlU1FMIGZvcm1hdCBzcGVjaWZpZXJzLlxuICAgICAqIFRoaXMgYWxsb3dzIGEgdHJhbnNmb3JtYXRpb24gdG8gZGF5IG9mIHRoZSB5ZWFyLCBvciBkYXkgb2Ygd2VlayBldGMuXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRGb3JtYXQ6IFsnc3RyaW5nJywgdHJ1ZSwgJ0lTTzg2MDEnXSxcblxuICAgIC8qKlxuICAgICAqIENvbnRyb2xzIGNvbnZlcnNpb24gdG8gZHVyYXRpb24gYnkgc3VidHJhY3RpbmcgdGhpcyBkYXRlXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRSZWZlcmVuY2U6ICdzdHJpbmcnLFxuXG4gICAgLyoqXG4gICAgICogUmVmZXJlbmNlIHRpbWV6b25lIGZvciBjb252ZXJzaW9uIGZyb20gZGF0ZXRpbWUgdG8gZHVyYXRpb25cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFpvbmU6IFsnc3RyaW5nJywgdHJ1ZSwgJ0lTTzg2MDEnXVxuXG4gIH0sXG4gIGRlcml2ZWQ6IHtcbiAgICAvLyByZWZlcmVuY2UgbW9tZW50anMgZm9yIGR1cmF0aW9uIDwtPiBkYXRldGltZSBjb252ZXJzaW9uXG4gICAgcmVmZXJlbmNlTW9tZW50OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkUmVmZXJlbmNlJywgJ3RyYW5zZm9ybWVkWm9uZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHR6O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFpvbmUgPT09ICdJU084NjAxJykge1xuICAgICAgICAgIHR6ID0gbW9tZW50LnR6Lmd1ZXNzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHRpbWVab25lID0gdXRpbC50aW1lWm9uZXMuZ2V0KHRoaXMudHJhbnNmb3JtZWRab25lLCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgICBpZiAodGltZVpvbmUgJiYgdGltZVpvbmUuZm9ybWF0KSB7XG4gICAgICAgICAgICB0eiA9IHRpbWVab25lLmZvcm1hdDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHogPSBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXR1cm4gbW9tZW50LnR6KHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UsIHR6KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBmYWNldCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFR5cGU6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRGb3JtYXQnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkUmVmZXJlbmNlKSB7XG4gICAgICAgICAgLy8gZGF0ZXRpbWUgLT4gZHVyYXRpb25cbiAgICAgICAgICByZXR1cm4gJ2R1cmF0aW9uJztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0ID09PSAnSVNPODYwMScpIHtcbiAgICAgICAgICAvLyBkYXRldGltZSAtPiBkYXRldGltZVxuICAgICAgICAgIHJldHVybiAnZGF0ZXRpbWUnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGRhdGV0aW1lIC0+IHRpbWUgcGFydFxuICAgICAgICAgIHZhciB0aW1lUGFydCA9IHV0aWwudGltZVBhcnRzLmdldCh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgICBpZiAodGltZVBhcnQgJiYgdGltZVBhcnQudHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRpbWVQYXJ0LnR5cGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnZGF0ZXRpbWUnO1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1pbml1bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluOiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRpbWVQYXJ0O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScgfHwgdGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkdXJhdGlvbicpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0odGhpcy5wYXJlbnQubWludmFsKTtcbiAgICAgICAgfVxuICAgICAgICB0aW1lUGFydCA9IHV0aWwudGltZVBhcnRzLmdldCh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgaWYgKHRpbWVQYXJ0LmNhbGN1YWx0ZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybSh0aGlzLnBhcmVudC5taW52YWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aW1lUGFydC5taW47XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNYXg6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGltZVBhcnQ7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJyB8fCB0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2R1cmF0aW9uJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybSh0aGlzLnBhcmVudC5tYXh2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHRpbWVQYXJ0ID0gdXRpbC50aW1lUGFydHMuZ2V0KHRoaXMudHJhbnNmb3JtZWRGb3JtYXQsICdkZXNjcmlwdGlvbicpO1xuICAgICAgICBpZiAodGltZVBhcnQuY2FsY3VhbHRlKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKHRoaXMucGFyZW50Lm1heHZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRpbWVQYXJ0Lm1heDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKlxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkTWluJywgJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1pbnZhbCA9IHRoaXMudHJhbnNmb3JtZWRNaW47XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiBtaW52YWwuZm9ybWF0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNYXhBc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRNYXgnLCAndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWF4dmFsID0gdGhpcy50cmFuc2Zvcm1lZE1heDtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnZGF0ZXRpbWUnKSB7XG4gICAgICAgICAgcmV0dXJuIG1heHZhbC5mb3JtYXQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIEBmdW5jdGlvblxuICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtb21lbnRqc1xuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBtb21lbnRqc1xuICAgKi9cbiAgdHJhbnNmb3JtOiBmdW5jdGlvbiB0cmFuc2Zvcm0gKGludmFsKSB7XG4gICAgaWYgKHR5cGVvZiBpbnZhbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfVxuXG4gICAgdmFyIGQgPSBpbnZhbC5jbG9uZSgpO1xuICAgIHZhciB0aW1lUGFydDtcblxuICAgIGlmICh0aGlzLnJlZmVyZW5jZU1vbWVudCkge1xuICAgICAgLy8gZGF0ZXRpbWUgLT4gZHVyYXRpb25cbiAgICAgIHJldHVybiBtb21lbnQuZHVyYXRpb24oZC5kaWZmKHRoaXMucmVmZXJlbmNlTW9tZW50LCAnbWlsbGlzZWNvbmRzJywgdHJ1ZSksICdtaWxsaXNlY29uZHMnKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudHJhbnNmb3JtZWRGb3JtYXQgIT09ICdJU084NjAxJykge1xuICAgICAgdGltZVBhcnQgPSB1dGlsLnRpbWVQYXJ0cy5nZXQodGhpcy50cmFuc2Zvcm1lZEZvcm1hdCwgJ2Rlc2NyaXB0aW9uJyk7XG4gICAgICBpZiAodGltZVBhcnQgJiYgdGltZVBhcnQubW9tZW50Rm9ybWF0KSB7XG4gICAgICAgIHJldHVybiBkLmZvcm1hdCh0aW1lUGFydC5tb21lbnRGb3JtYXQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBkO1xuICAgIH1cbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVuc2V0KFsnem9uZScsICd0cmFuc2Zvcm1lZEZvcm1hdCcsICd0cmFuc2Zvcm1lZFpvbmUnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///a0ca\n")},aa6c:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar keys = __webpack_require__(/*! ./keys */ \"7d91\");\nvar hasBinary = __webpack_require__(/*! has-binary */ \"d304\");\nvar sliceBuffer = __webpack_require__(/*! arraybuffer.slice */ \"ef13\");\nvar after = __webpack_require__(/*! after */ \"4aa5\");\nvar utf8 = __webpack_require__(/*! wtf-8 */ \"943e\");\n\nvar base64encoder;\nif (global && global.ArrayBuffer) {\n  base64encoder = __webpack_require__(/*! base64-arraybuffer */ \"21de\");\n}\n\n/**\n * Check if we are running an android browser. That requires us to use\n * ArrayBuffer with polling transports...\n *\n * http://ghinda.net/jpeg-blob-ajax-android/\n */\n\nvar isAndroid = typeof navigator !== 'undefined' && /Android/i.test(navigator.userAgent);\n\n/**\n * Check if we are running in PhantomJS.\n * Uploading a Blob with PhantomJS does not work correctly, as reported here:\n * https://github.com/ariya/phantomjs/issues/11395\n * @type boolean\n */\nvar isPhantomJS = typeof navigator !== 'undefined' && /PhantomJS/i.test(navigator.userAgent);\n\n/**\n * When true, avoids using Blobs to encode payloads.\n * @type boolean\n */\nvar dontSendBlobs = isAndroid || isPhantomJS;\n\n/**\n * Current protocol version.\n */\n\nexports.protocol = 3;\n\n/**\n * Packet types.\n */\n\nvar packets = exports.packets = {\n    open:     0    // non-ws\n  , close:    1    // non-ws\n  , ping:     2\n  , pong:     3\n  , message:  4\n  , upgrade:  5\n  , noop:     6\n};\n\nvar packetslist = keys(packets);\n\n/**\n * Premade error packet.\n */\n\nvar err = { type: 'error', data: 'parser error' };\n\n/**\n * Create a blob api even for blob builder when vendor prefixes exist\n */\n\nvar Blob = __webpack_require__(/*! blob */ \"939f\");\n\n/**\n * Encodes a packet.\n *\n *     <packet type id> [ <data> ]\n *\n * Example:\n *\n *     5hello world\n *     3\n *     4\n *\n * Binary is encoded in an identical principle\n *\n * @api private\n */\n\nexports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {\n  if ('function' == typeof supportsBinary) {\n    callback = supportsBinary;\n    supportsBinary = false;\n  }\n\n  if ('function' == typeof utf8encode) {\n    callback = utf8encode;\n    utf8encode = null;\n  }\n\n  var data = (packet.data === undefined)\n    ? undefined\n    : packet.data.buffer || packet.data;\n\n  if (global.ArrayBuffer && data instanceof ArrayBuffer) {\n    return encodeArrayBuffer(packet, supportsBinary, callback);\n  } else if (Blob && data instanceof global.Blob) {\n    return encodeBlob(packet, supportsBinary, callback);\n  }\n\n  // might be an object with { base64: true, data: dataAsBase64String }\n  if (data && data.base64) {\n    return encodeBase64Object(packet, callback);\n  }\n\n  // Sending data as a utf-8 string\n  var encoded = packets[packet.type];\n\n  // data fragment is optional\n  if (undefined !== packet.data) {\n    encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data);\n  }\n\n  return callback('' + encoded);\n\n};\n\nfunction encodeBase64Object(packet, callback) {\n  // packet data is an object { base64: true, data: dataAsBase64String }\n  var message = 'b' + exports.packets[packet.type] + packet.data.data;\n  return callback(message);\n}\n\n/**\n * Encode packet helpers for binary types\n */\n\nfunction encodeArrayBuffer(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  var data = packet.data;\n  var contentArray = new Uint8Array(data);\n  var resultBuffer = new Uint8Array(1 + data.byteLength);\n\n  resultBuffer[0] = packets[packet.type];\n  for (var i = 0; i < contentArray.length; i++) {\n    resultBuffer[i+1] = contentArray[i];\n  }\n\n  return callback(resultBuffer.buffer);\n}\n\nfunction encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  var fr = new FileReader();\n  fr.onload = function() {\n    packet.data = fr.result;\n    exports.encodePacket(packet, supportsBinary, true, callback);\n  };\n  return fr.readAsArrayBuffer(packet.data);\n}\n\nfunction encodeBlob(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  if (dontSendBlobs) {\n    return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);\n  }\n\n  var length = new Uint8Array(1);\n  length[0] = packets[packet.type];\n  var blob = new Blob([length.buffer, packet.data]);\n\n  return callback(blob);\n}\n\n/**\n * Encodes a packet with binary data in a base64 string\n *\n * @param {Object} packet, has `type` and `data`\n * @return {String} base64 encoded message\n */\n\nexports.encodeBase64Packet = function(packet, callback) {\n  var message = 'b' + exports.packets[packet.type];\n  if (Blob && packet.data instanceof global.Blob) {\n    var fr = new FileReader();\n    fr.onload = function() {\n      var b64 = fr.result.split(',')[1];\n      callback(message + b64);\n    };\n    return fr.readAsDataURL(packet.data);\n  }\n\n  var b64data;\n  try {\n    b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));\n  } catch (e) {\n    // iPhone Safari doesn't let you apply with typed arrays\n    var typed = new Uint8Array(packet.data);\n    var basic = new Array(typed.length);\n    for (var i = 0; i < typed.length; i++) {\n      basic[i] = typed[i];\n    }\n    b64data = String.fromCharCode.apply(null, basic);\n  }\n  message += global.btoa(b64data);\n  return callback(message);\n};\n\n/**\n * Decodes a packet. Changes format to Blob if requested.\n *\n * @return {Object} with `type` and `data` (if any)\n * @api private\n */\n\nexports.decodePacket = function (data, binaryType, utf8decode) {\n  if (data === undefined) {\n    return err;\n  }\n  // String data\n  if (typeof data == 'string') {\n    if (data.charAt(0) == 'b') {\n      return exports.decodeBase64Packet(data.substr(1), binaryType);\n    }\n\n    if (utf8decode) {\n      data = tryDecode(data);\n      if (data === false) {\n        return err;\n      }\n    }\n    var type = data.charAt(0);\n\n    if (Number(type) != type || !packetslist[type]) {\n      return err;\n    }\n\n    if (data.length > 1) {\n      return { type: packetslist[type], data: data.substring(1) };\n    } else {\n      return { type: packetslist[type] };\n    }\n  }\n\n  var asArray = new Uint8Array(data);\n  var type = asArray[0];\n  var rest = sliceBuffer(data, 1);\n  if (Blob && binaryType === 'blob') {\n    rest = new Blob([rest]);\n  }\n  return { type: packetslist[type], data: rest };\n};\n\nfunction tryDecode(data) {\n  try {\n    data = utf8.decode(data);\n  } catch (e) {\n    return false;\n  }\n  return data;\n}\n\n/**\n * Decodes a packet encoded in a base64 string\n *\n * @param {String} base64 encoded message\n * @return {Object} with `type` and `data` (if any)\n */\n\nexports.decodeBase64Packet = function(msg, binaryType) {\n  var type = packetslist[msg.charAt(0)];\n  if (!base64encoder) {\n    return { type: type, data: { base64: true, data: msg.substr(1) } };\n  }\n\n  var data = base64encoder.decode(msg.substr(1));\n\n  if (binaryType === 'blob' && Blob) {\n    data = new Blob([data]);\n  }\n\n  return { type: type, data: data };\n};\n\n/**\n * Encodes multiple messages (payload).\n *\n *     <length>:data\n *\n * Example:\n *\n *     11:hello world2:hi\n *\n * If any contents are binary, they will be encoded as base64 strings. Base64\n * encoded strings are marked with a b before the length specifier\n *\n * @param {Array} packets\n * @api private\n */\n\nexports.encodePayload = function (packets, supportsBinary, callback) {\n  if (typeof supportsBinary == 'function') {\n    callback = supportsBinary;\n    supportsBinary = null;\n  }\n\n  var isBinary = hasBinary(packets);\n\n  if (supportsBinary && isBinary) {\n    if (Blob && !dontSendBlobs) {\n      return exports.encodePayloadAsBlob(packets, callback);\n    }\n\n    return exports.encodePayloadAsArrayBuffer(packets, callback);\n  }\n\n  if (!packets.length) {\n    return callback('0:');\n  }\n\n  function setLengthHeader(message) {\n    return message.length + ':' + message;\n  }\n\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function(message) {\n      doneCallback(null, setLengthHeader(message));\n    });\n  }\n\n  map(packets, encodeOne, function(err, results) {\n    return callback(results.join(''));\n  });\n};\n\n/**\n * Async array map using after\n */\n\nfunction map(ary, each, done) {\n  var result = new Array(ary.length);\n  var next = after(ary.length, done);\n\n  var eachWithIndex = function(i, el, cb) {\n    each(el, function(error, msg) {\n      result[i] = msg;\n      cb(error, result);\n    });\n  };\n\n  for (var i = 0; i < ary.length; i++) {\n    eachWithIndex(i, ary[i], next);\n  }\n}\n\n/*\n * Decodes data when a payload is maybe expected. Possible binary contents are\n * decoded from their base64 representation\n *\n * @param {String} data, callback method\n * @api public\n */\n\nexports.decodePayload = function (data, binaryType, callback) {\n  if (typeof data != 'string') {\n    return exports.decodePayloadAsBinary(data, binaryType, callback);\n  }\n\n  if (typeof binaryType === 'function') {\n    callback = binaryType;\n    binaryType = null;\n  }\n\n  var packet;\n  if (data == '') {\n    // parser error - ignoring payload\n    return callback(err, 0, 1);\n  }\n\n  var length = ''\n    , n, msg;\n\n  for (var i = 0, l = data.length; i < l; i++) {\n    var chr = data.charAt(i);\n\n    if (':' != chr) {\n      length += chr;\n    } else {\n      if ('' == length || (length != (n = Number(length)))) {\n        // parser error - ignoring payload\n        return callback(err, 0, 1);\n      }\n\n      msg = data.substr(i + 1, n);\n\n      if (length != msg.length) {\n        // parser error - ignoring payload\n        return callback(err, 0, 1);\n      }\n\n      if (msg.length) {\n        packet = exports.decodePacket(msg, binaryType, true);\n\n        if (err.type == packet.type && err.data == packet.data) {\n          // parser error in individual packet - ignoring payload\n          return callback(err, 0, 1);\n        }\n\n        var ret = callback(packet, i + n, l);\n        if (false === ret) return;\n      }\n\n      // advance cursor\n      i += n;\n      length = '';\n    }\n  }\n\n  if (length != '') {\n    // parser error - ignoring payload\n    return callback(err, 0, 1);\n  }\n\n};\n\n/**\n * Encodes multiple messages (payload) as binary.\n *\n * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number\n * 255><data>\n *\n * Example:\n * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers\n *\n * @param {Array} packets\n * @return {ArrayBuffer} encoded payload\n * @api private\n */\n\nexports.encodePayloadAsArrayBuffer = function(packets, callback) {\n  if (!packets.length) {\n    return callback(new ArrayBuffer(0));\n  }\n\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, true, true, function(data) {\n      return doneCallback(null, data);\n    });\n  }\n\n  map(packets, encodeOne, function(err, encodedPackets) {\n    var totalLength = encodedPackets.reduce(function(acc, p) {\n      var len;\n      if (typeof p === 'string'){\n        len = p.length;\n      } else {\n        len = p.byteLength;\n      }\n      return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2\n    }, 0);\n\n    var resultArray = new Uint8Array(totalLength);\n\n    var bufferIndex = 0;\n    encodedPackets.forEach(function(p) {\n      var isString = typeof p === 'string';\n      var ab = p;\n      if (isString) {\n        var view = new Uint8Array(p.length);\n        for (var i = 0; i < p.length; i++) {\n          view[i] = p.charCodeAt(i);\n        }\n        ab = view.buffer;\n      }\n\n      if (isString) { // not true binary\n        resultArray[bufferIndex++] = 0;\n      } else { // true binary\n        resultArray[bufferIndex++] = 1;\n      }\n\n      var lenStr = ab.byteLength.toString();\n      for (var i = 0; i < lenStr.length; i++) {\n        resultArray[bufferIndex++] = parseInt(lenStr[i]);\n      }\n      resultArray[bufferIndex++] = 255;\n\n      var view = new Uint8Array(ab);\n      for (var i = 0; i < view.length; i++) {\n        resultArray[bufferIndex++] = view[i];\n      }\n    });\n\n    return callback(resultArray.buffer);\n  });\n};\n\n/**\n * Encode as Blob\n */\n\nexports.encodePayloadAsBlob = function(packets, callback) {\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, true, true, function(encoded) {\n      var binaryIdentifier = new Uint8Array(1);\n      binaryIdentifier[0] = 1;\n      if (typeof encoded === 'string') {\n        var view = new Uint8Array(encoded.length);\n        for (var i = 0; i < encoded.length; i++) {\n          view[i] = encoded.charCodeAt(i);\n        }\n        encoded = view.buffer;\n        binaryIdentifier[0] = 0;\n      }\n\n      var len = (encoded instanceof ArrayBuffer)\n        ? encoded.byteLength\n        : encoded.size;\n\n      var lenStr = len.toString();\n      var lengthAry = new Uint8Array(lenStr.length + 1);\n      for (var i = 0; i < lenStr.length; i++) {\n        lengthAry[i] = parseInt(lenStr[i]);\n      }\n      lengthAry[lenStr.length] = 255;\n\n      if (Blob) {\n        var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);\n        doneCallback(null, blob);\n      }\n    });\n  }\n\n  map(packets, encodeOne, function(err, results) {\n    return callback(new Blob(results));\n  });\n};\n\n/*\n * Decodes data when a payload is maybe expected. Strings are decoded by\n * interpreting each byte as a key code for entries marked to start with 0. See\n * description of encodePayloadAsBinary\n *\n * @param {ArrayBuffer} data, callback method\n * @api public\n */\n\nexports.decodePayloadAsBinary = function (data, binaryType, callback) {\n  if (typeof binaryType === 'function') {\n    callback = binaryType;\n    binaryType = null;\n  }\n\n  var bufferTail = data;\n  var buffers = [];\n\n  var numberTooLong = false;\n  while (bufferTail.byteLength > 0) {\n    var tailArray = new Uint8Array(bufferTail);\n    var isString = tailArray[0] === 0;\n    var msgLength = '';\n\n    for (var i = 1; ; i++) {\n      if (tailArray[i] == 255) break;\n\n      if (msgLength.length > 310) {\n        numberTooLong = true;\n        break;\n      }\n\n      msgLength += tailArray[i];\n    }\n\n    if(numberTooLong) return callback(err, 0, 1);\n\n    bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);\n    msgLength = parseInt(msgLength);\n\n    var msg = sliceBuffer(bufferTail, 0, msgLength);\n    if (isString) {\n      try {\n        msg = String.fromCharCode.apply(null, new Uint8Array(msg));\n      } catch (e) {\n        // iPhone Safari doesn't let you apply to typed arrays\n        var typed = new Uint8Array(msg);\n        msg = '';\n        for (var i = 0; i < typed.length; i++) {\n          msg += String.fromCharCode(typed[i]);\n        }\n      }\n    }\n\n    buffers.push(msg);\n    bufferTail = sliceBuffer(bufferTail, msgLength);\n  }\n\n  var total = buffers.length;\n  buffers.forEach(function(buffer, i) {\n    callback(exports.decodePacket(buffer, binaryType, true), i, total);\n  });\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWE2Yy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIvYnJvd3Nlci5qcz9hZjAyIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIga2V5cyA9IHJlcXVpcmUoJy4va2V5cycpO1xudmFyIGhhc0JpbmFyeSA9IHJlcXVpcmUoJ2hhcy1iaW5hcnknKTtcbnZhciBzbGljZUJ1ZmZlciA9IHJlcXVpcmUoJ2FycmF5YnVmZmVyLnNsaWNlJyk7XG52YXIgYWZ0ZXIgPSByZXF1aXJlKCdhZnRlcicpO1xudmFyIHV0ZjggPSByZXF1aXJlKCd3dGYtOCcpO1xuXG52YXIgYmFzZTY0ZW5jb2RlcjtcbmlmIChnbG9iYWwgJiYgZ2xvYmFsLkFycmF5QnVmZmVyKSB7XG4gIGJhc2U2NGVuY29kZXIgPSByZXF1aXJlKCdiYXNlNjQtYXJyYXlidWZmZXInKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgcnVubmluZyBhbiBhbmRyb2lkIGJyb3dzZXIuIFRoYXQgcmVxdWlyZXMgdXMgdG8gdXNlXG4gKiBBcnJheUJ1ZmZlciB3aXRoIHBvbGxpbmcgdHJhbnNwb3J0cy4uLlxuICpcbiAqIGh0dHA6Ly9naGluZGEubmV0L2pwZWctYmxvYi1hamF4LWFuZHJvaWQvXG4gKi9cblxudmFyIGlzQW5kcm9pZCA9IHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmIC9BbmRyb2lkL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgcnVubmluZyBpbiBQaGFudG9tSlMuXG4gKiBVcGxvYWRpbmcgYSBCbG9iIHdpdGggUGhhbnRvbUpTIGRvZXMgbm90IHdvcmsgY29ycmVjdGx5LCBhcyByZXBvcnRlZCBoZXJlOlxuICogaHR0cHM6Ly9naXRodWIuY29tL2FyaXlhL3BoYW50b21qcy9pc3N1ZXMvMTEzOTVcbiAqIEB0eXBlIGJvb2xlYW5cbiAqL1xudmFyIGlzUGhhbnRvbUpTID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgL1BoYW50b21KUy9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG5cbi8qKlxuICogV2hlbiB0cnVlLCBhdm9pZHMgdXNpbmcgQmxvYnMgdG8gZW5jb2RlIHBheWxvYWRzLlxuICogQHR5cGUgYm9vbGVhblxuICovXG52YXIgZG9udFNlbmRCbG9icyA9IGlzQW5kcm9pZCB8fCBpc1BoYW50b21KUztcblxuLyoqXG4gKiBDdXJyZW50IHByb3RvY29sIHZlcnNpb24uXG4gKi9cblxuZXhwb3J0cy5wcm90b2NvbCA9IDM7XG5cbi8qKlxuICogUGFja2V0IHR5cGVzLlxuICovXG5cbnZhciBwYWNrZXRzID0gZXhwb3J0cy5wYWNrZXRzID0ge1xuICAgIG9wZW46ICAgICAwICAgIC8vIG5vbi13c1xuICAsIGNsb3NlOiAgICAxICAgIC8vIG5vbi13c1xuICAsIHBpbmc6ICAgICAyXG4gICwgcG9uZzogICAgIDNcbiAgLCBtZXNzYWdlOiAgNFxuICAsIHVwZ3JhZGU6ICA1XG4gICwgbm9vcDogICAgIDZcbn07XG5cbnZhciBwYWNrZXRzbGlzdCA9IGtleXMocGFja2V0cyk7XG5cbi8qKlxuICogUHJlbWFkZSBlcnJvciBwYWNrZXQuXG4gKi9cblxudmFyIGVyciA9IHsgdHlwZTogJ2Vycm9yJywgZGF0YTogJ3BhcnNlciBlcnJvcicgfTtcblxuLyoqXG4gKiBDcmVhdGUgYSBibG9iIGFwaSBldmVuIGZvciBibG9iIGJ1aWxkZXIgd2hlbiB2ZW5kb3IgcHJlZml4ZXMgZXhpc3RcbiAqL1xuXG52YXIgQmxvYiA9IHJlcXVpcmUoJ2Jsb2InKTtcblxuLyoqXG4gKiBFbmNvZGVzIGEgcGFja2V0LlxuICpcbiAqICAgICA8cGFja2V0IHR5cGUgaWQ+IFsgPGRhdGE+IF1cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICA1aGVsbG8gd29ybGRcbiAqICAgICAzXG4gKiAgICAgNFxuICpcbiAqIEJpbmFyeSBpcyBlbmNvZGVkIGluIGFuIGlkZW50aWNhbCBwcmluY2lwbGVcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLmVuY29kZVBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCB1dGY4ZW5jb2RlLCBjYWxsYmFjaykge1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2Ygc3VwcG9ydHNCaW5hcnkpIHtcbiAgICBjYWxsYmFjayA9IHN1cHBvcnRzQmluYXJ5O1xuICAgIHN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG4gIH1cblxuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgdXRmOGVuY29kZSkge1xuICAgIGNhbGxiYWNrID0gdXRmOGVuY29kZTtcbiAgICB1dGY4ZW5jb2RlID0gbnVsbDtcbiAgfVxuXG4gIHZhciBkYXRhID0gKHBhY2tldC5kYXRhID09PSB1bmRlZmluZWQpXG4gICAgPyB1bmRlZmluZWRcbiAgICA6IHBhY2tldC5kYXRhLmJ1ZmZlciB8fCBwYWNrZXQuZGF0YTtcblxuICBpZiAoZ2xvYmFsLkFycmF5QnVmZmVyICYmIGRhdGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiBlbmNvZGVBcnJheUJ1ZmZlcihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjayk7XG4gIH0gZWxzZSBpZiAoQmxvYiAmJiBkYXRhIGluc3RhbmNlb2YgZ2xvYmFsLkJsb2IpIHtcbiAgICByZXR1cm4gZW5jb2RlQmxvYihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjayk7XG4gIH1cblxuICAvLyBtaWdodCBiZSBhbiBvYmplY3Qgd2l0aCB7IGJhc2U2NDogdHJ1ZSwgZGF0YTogZGF0YUFzQmFzZTY0U3RyaW5nIH1cbiAgaWYgKGRhdGEgJiYgZGF0YS5iYXNlNjQpIHtcbiAgICByZXR1cm4gZW5jb2RlQmFzZTY0T2JqZWN0KHBhY2tldCwgY2FsbGJhY2spO1xuICB9XG5cbiAgLy8gU2VuZGluZyBkYXRhIGFzIGEgdXRmLTggc3RyaW5nXG4gIHZhciBlbmNvZGVkID0gcGFja2V0c1twYWNrZXQudHlwZV07XG5cbiAgLy8gZGF0YSBmcmFnbWVudCBpcyBvcHRpb25hbFxuICBpZiAodW5kZWZpbmVkICE9PSBwYWNrZXQuZGF0YSkge1xuICAgIGVuY29kZWQgKz0gdXRmOGVuY29kZSA/IHV0ZjguZW5jb2RlKFN0cmluZyhwYWNrZXQuZGF0YSkpIDogU3RyaW5nKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHJldHVybiBjYWxsYmFjaygnJyArIGVuY29kZWQpO1xuXG59O1xuXG5mdW5jdGlvbiBlbmNvZGVCYXNlNjRPYmplY3QocGFja2V0LCBjYWxsYmFjaykge1xuICAvLyBwYWNrZXQgZGF0YSBpcyBhbiBvYmplY3QgeyBiYXNlNjQ6IHRydWUsIGRhdGE6IGRhdGFBc0Jhc2U2NFN0cmluZyB9XG4gIHZhciBtZXNzYWdlID0gJ2InICsgZXhwb3J0cy5wYWNrZXRzW3BhY2tldC50eXBlXSArIHBhY2tldC5kYXRhLmRhdGE7XG4gIHJldHVybiBjYWxsYmFjayhtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBFbmNvZGUgcGFja2V0IGhlbHBlcnMgZm9yIGJpbmFyeSB0eXBlc1xuICovXG5cbmZ1bmN0aW9uIGVuY29kZUFycmF5QnVmZmVyKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKSB7XG4gIGlmICghc3VwcG9ydHNCaW5hcnkpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQocGFja2V0LCBjYWxsYmFjayk7XG4gIH1cblxuICB2YXIgZGF0YSA9IHBhY2tldC5kYXRhO1xuICB2YXIgY29udGVudEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gIHZhciByZXN1bHRCdWZmZXIgPSBuZXcgVWludDhBcnJheSgxICsgZGF0YS5ieXRlTGVuZ3RoKTtcblxuICByZXN1bHRCdWZmZXJbMF0gPSBwYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb250ZW50QXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICByZXN1bHRCdWZmZXJbaSsxXSA9IGNvbnRlbnRBcnJheVtpXTtcbiAgfVxuXG4gIHJldHVybiBjYWxsYmFjayhyZXN1bHRCdWZmZXIuYnVmZmVyKTtcbn1cblxuZnVuY3Rpb24gZW5jb2RlQmxvYkFzQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgaWYgKCFzdXBwb3J0c0JpbmFyeSkge1xuICAgIHJldHVybiBleHBvcnRzLmVuY29kZUJhc2U2NFBhY2tldChwYWNrZXQsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHZhciBmciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gIGZyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgIHBhY2tldC5kYXRhID0gZnIucmVzdWx0O1xuICAgIGV4cG9ydHMuZW5jb2RlUGFja2V0KHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIHRydWUsIGNhbGxiYWNrKTtcbiAgfTtcbiAgcmV0dXJuIGZyLnJlYWRBc0FycmF5QnVmZmVyKHBhY2tldC5kYXRhKTtcbn1cblxuZnVuY3Rpb24gZW5jb2RlQmxvYihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjaykge1xuICBpZiAoIXN1cHBvcnRzQmluYXJ5KSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuZW5jb2RlQmFzZTY0UGFja2V0KHBhY2tldCwgY2FsbGJhY2spO1xuICB9XG5cbiAgaWYgKGRvbnRTZW5kQmxvYnMpIHtcbiAgICByZXR1cm4gZW5jb2RlQmxvYkFzQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spO1xuICB9XG5cbiAgdmFyIGxlbmd0aCA9IG5ldyBVaW50OEFycmF5KDEpO1xuICBsZW5ndGhbMF0gPSBwYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgdmFyIGJsb2IgPSBuZXcgQmxvYihbbGVuZ3RoLmJ1ZmZlciwgcGFja2V0LmRhdGFdKTtcblxuICByZXR1cm4gY2FsbGJhY2soYmxvYik7XG59XG5cbi8qKlxuICogRW5jb2RlcyBhIHBhY2tldCB3aXRoIGJpbmFyeSBkYXRhIGluIGEgYmFzZTY0IHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQsIGhhcyBgdHlwZWAgYW5kIGBkYXRhYFxuICogQHJldHVybiB7U3RyaW5nfSBiYXNlNjQgZW5jb2RlZCBtZXNzYWdlXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQsIGNhbGxiYWNrKSB7XG4gIHZhciBtZXNzYWdlID0gJ2InICsgZXhwb3J0cy5wYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgaWYgKEJsb2IgJiYgcGFja2V0LmRhdGEgaW5zdGFuY2VvZiBnbG9iYWwuQmxvYikge1xuICAgIHZhciBmciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgZnIub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYjY0ID0gZnIucmVzdWx0LnNwbGl0KCcsJylbMV07XG4gICAgICBjYWxsYmFjayhtZXNzYWdlICsgYjY0KTtcbiAgICB9O1xuICAgIHJldHVybiBmci5yZWFkQXNEYXRhVVJMKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHZhciBiNjRkYXRhO1xuICB0cnkge1xuICAgIGI2NGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBpUGhvbmUgU2FmYXJpIGRvZXNuJ3QgbGV0IHlvdSBhcHBseSB3aXRoIHR5cGVkIGFycmF5c1xuICAgIHZhciB0eXBlZCA9IG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKTtcbiAgICB2YXIgYmFzaWMgPSBuZXcgQXJyYXkodHlwZWQubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICBiYXNpY1tpXSA9IHR5cGVkW2ldO1xuICAgIH1cbiAgICBiNjRkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBiYXNpYyk7XG4gIH1cbiAgbWVzc2FnZSArPSBnbG9iYWwuYnRvYShiNjRkYXRhKTtcbiAgcmV0dXJuIGNhbGxiYWNrKG1lc3NhZ2UpO1xufTtcblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0LiBDaGFuZ2VzIGZvcm1hdCB0byBCbG9iIGlmIHJlcXVlc3RlZC5cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHdpdGggYHR5cGVgIGFuZCBgZGF0YWAgKGlmIGFueSlcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZGVjb2RlUGFja2V0ID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIHV0ZjhkZWNvZGUpIHtcbiAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBlcnI7XG4gIH1cbiAgLy8gU3RyaW5nIGRhdGFcbiAgaWYgKHR5cGVvZiBkYXRhID09ICdzdHJpbmcnKSB7XG4gICAgaWYgKGRhdGEuY2hhckF0KDApID09ICdiJykge1xuICAgICAgcmV0dXJuIGV4cG9ydHMuZGVjb2RlQmFzZTY0UGFja2V0KGRhdGEuc3Vic3RyKDEpLCBiaW5hcnlUeXBlKTtcbiAgICB9XG5cbiAgICBpZiAodXRmOGRlY29kZSkge1xuICAgICAgZGF0YSA9IHRyeURlY29kZShkYXRhKTtcbiAgICAgIGlmIChkYXRhID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gZXJyO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgdHlwZSA9IGRhdGEuY2hhckF0KDApO1xuXG4gICAgaWYgKE51bWJlcih0eXBlKSAhPSB0eXBlIHx8ICFwYWNrZXRzbGlzdFt0eXBlXSkge1xuICAgICAgcmV0dXJuIGVycjtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS5sZW5ndGggPiAxKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBwYWNrZXRzbGlzdFt0eXBlXSwgZGF0YTogZGF0YS5zdWJzdHJpbmcoMSkgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHsgdHlwZTogcGFja2V0c2xpc3RbdHlwZV0gfTtcbiAgICB9XG4gIH1cblxuICB2YXIgYXNBcnJheSA9IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICB2YXIgdHlwZSA9IGFzQXJyYXlbMF07XG4gIHZhciByZXN0ID0gc2xpY2VCdWZmZXIoZGF0YSwgMSk7XG4gIGlmIChCbG9iICYmIGJpbmFyeVR5cGUgPT09ICdibG9iJykge1xuICAgIHJlc3QgPSBuZXcgQmxvYihbcmVzdF0pO1xuICB9XG4gIHJldHVybiB7IHR5cGU6IHBhY2tldHNsaXN0W3R5cGVdLCBkYXRhOiByZXN0IH07XG59O1xuXG5mdW5jdGlvbiB0cnlEZWNvZGUoZGF0YSkge1xuICB0cnkge1xuICAgIGRhdGEgPSB1dGY4LmRlY29kZShkYXRhKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gZGF0YTtcbn1cblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0IGVuY29kZWQgaW4gYSBiYXNlNjQgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGJhc2U2NCBlbmNvZGVkIG1lc3NhZ2VcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBgdHlwZWAgYW5kIGBkYXRhYCAoaWYgYW55KVxuICovXG5cbmV4cG9ydHMuZGVjb2RlQmFzZTY0UGFja2V0ID0gZnVuY3Rpb24obXNnLCBiaW5hcnlUeXBlKSB7XG4gIHZhciB0eXBlID0gcGFja2V0c2xpc3RbbXNnLmNoYXJBdCgwKV07XG4gIGlmICghYmFzZTY0ZW5jb2Rlcikge1xuICAgIHJldHVybiB7IHR5cGU6IHR5cGUsIGRhdGE6IHsgYmFzZTY0OiB0cnVlLCBkYXRhOiBtc2cuc3Vic3RyKDEpIH0gfTtcbiAgfVxuXG4gIHZhciBkYXRhID0gYmFzZTY0ZW5jb2Rlci5kZWNvZGUobXNnLnN1YnN0cigxKSk7XG5cbiAgaWYgKGJpbmFyeVR5cGUgPT09ICdibG9iJyAmJiBCbG9iKSB7XG4gICAgZGF0YSA9IG5ldyBCbG9iKFtkYXRhXSk7XG4gIH1cblxuICByZXR1cm4geyB0eXBlOiB0eXBlLCBkYXRhOiBkYXRhIH07XG59O1xuXG4vKipcbiAqIEVuY29kZXMgbXVsdGlwbGUgbWVzc2FnZXMgKHBheWxvYWQpLlxuICpcbiAqICAgICA8bGVuZ3RoPjpkYXRhXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgMTE6aGVsbG8gd29ybGQyOmhpXG4gKlxuICogSWYgYW55IGNvbnRlbnRzIGFyZSBiaW5hcnksIHRoZXkgd2lsbCBiZSBlbmNvZGVkIGFzIGJhc2U2NCBzdHJpbmdzLiBCYXNlNjRcbiAqIGVuY29kZWQgc3RyaW5ncyBhcmUgbWFya2VkIHdpdGggYSBiIGJlZm9yZSB0aGUgbGVuZ3RoIHNwZWNpZmllclxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHBhY2tldHNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGF5bG9hZCA9IGZ1bmN0aW9uIChwYWNrZXRzLCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBzdXBwb3J0c0JpbmFyeSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBzdXBwb3J0c0JpbmFyeTtcbiAgICBzdXBwb3J0c0JpbmFyeSA9IG51bGw7XG4gIH1cblxuICB2YXIgaXNCaW5hcnkgPSBoYXNCaW5hcnkocGFja2V0cyk7XG5cbiAgaWYgKHN1cHBvcnRzQmluYXJ5ICYmIGlzQmluYXJ5KSB7XG4gICAgaWYgKEJsb2IgJiYgIWRvbnRTZW5kQmxvYnMpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0Jsb2IocGFja2V0cywgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0FycmF5QnVmZmVyKHBhY2tldHMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIGlmICghcGFja2V0cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gY2FsbGJhY2soJzA6Jyk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkge1xuICAgIHJldHVybiBtZXNzYWdlLmxlbmd0aCArICc6JyArIG1lc3NhZ2U7XG4gIH1cblxuICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICBleHBvcnRzLmVuY29kZVBhY2tldChwYWNrZXQsICFpc0JpbmFyeSA/IGZhbHNlIDogc3VwcG9ydHNCaW5hcnksIHRydWUsIGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgIGRvbmVDYWxsYmFjayhudWxsLCBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkpO1xuICAgIH0pO1xuICB9XG5cbiAgbWFwKHBhY2tldHMsIGVuY29kZU9uZSwgZnVuY3Rpb24oZXJyLCByZXN1bHRzKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdHMuam9pbignJykpO1xuICB9KTtcbn07XG5cbi8qKlxuICogQXN5bmMgYXJyYXkgbWFwIHVzaW5nIGFmdGVyXG4gKi9cblxuZnVuY3Rpb24gbWFwKGFyeSwgZWFjaCwgZG9uZSkge1xuICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KGFyeS5sZW5ndGgpO1xuICB2YXIgbmV4dCA9IGFmdGVyKGFyeS5sZW5ndGgsIGRvbmUpO1xuXG4gIHZhciBlYWNoV2l0aEluZGV4ID0gZnVuY3Rpb24oaSwgZWwsIGNiKSB7XG4gICAgZWFjaChlbCwgZnVuY3Rpb24oZXJyb3IsIG1zZykge1xuICAgICAgcmVzdWx0W2ldID0gbXNnO1xuICAgICAgY2IoZXJyb3IsIHJlc3VsdCk7XG4gICAgfSk7XG4gIH07XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnkubGVuZ3RoOyBpKyspIHtcbiAgICBlYWNoV2l0aEluZGV4KGksIGFyeVtpXSwgbmV4dCk7XG4gIH1cbn1cblxuLypcbiAqIERlY29kZXMgZGF0YSB3aGVuIGEgcGF5bG9hZCBpcyBtYXliZSBleHBlY3RlZC4gUG9zc2libGUgYmluYXJ5IGNvbnRlbnRzIGFyZVxuICogZGVjb2RlZCBmcm9tIHRoZWlyIGJhc2U2NCByZXByZXNlbnRhdGlvblxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhLCBjYWxsYmFjayBtZXRob2RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5kZWNvZGVQYXlsb2FkID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgZGF0YSAhPSAnc3RyaW5nJykge1xuICAgIHJldHVybiBleHBvcnRzLmRlY29kZVBheWxvYWRBc0JpbmFyeShkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjayk7XG4gIH1cblxuICBpZiAodHlwZW9mIGJpbmFyeVR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IGJpbmFyeVR5cGU7XG4gICAgYmluYXJ5VHlwZSA9IG51bGw7XG4gIH1cblxuICB2YXIgcGFja2V0O1xuICBpZiAoZGF0YSA9PSAnJykge1xuICAgIC8vIHBhcnNlciBlcnJvciAtIGlnbm9yaW5nIHBheWxvYWRcbiAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgfVxuXG4gIHZhciBsZW5ndGggPSAnJ1xuICAgICwgbiwgbXNnO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gZGF0YS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIgY2hyID0gZGF0YS5jaGFyQXQoaSk7XG5cbiAgICBpZiAoJzonICE9IGNocikge1xuICAgICAgbGVuZ3RoICs9IGNocjtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCcnID09IGxlbmd0aCB8fCAobGVuZ3RoICE9IChuID0gTnVtYmVyKGxlbmd0aCkpKSkge1xuICAgICAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICAgICAgfVxuXG4gICAgICBtc2cgPSBkYXRhLnN1YnN0cihpICsgMSwgbik7XG5cbiAgICAgIGlmIChsZW5ndGggIT0gbXNnLmxlbmd0aCkge1xuICAgICAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICAgICAgfVxuXG4gICAgICBpZiAobXNnLmxlbmd0aCkge1xuICAgICAgICBwYWNrZXQgPSBleHBvcnRzLmRlY29kZVBhY2tldChtc2csIGJpbmFyeVR5cGUsIHRydWUpO1xuXG4gICAgICAgIGlmIChlcnIudHlwZSA9PSBwYWNrZXQudHlwZSAmJiBlcnIuZGF0YSA9PSBwYWNrZXQuZGF0YSkge1xuICAgICAgICAgIC8vIHBhcnNlciBlcnJvciBpbiBpbmRpdmlkdWFsIHBhY2tldCAtIGlnbm9yaW5nIHBheWxvYWRcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXQgPSBjYWxsYmFjayhwYWNrZXQsIGkgKyBuLCBsKTtcbiAgICAgICAgaWYgKGZhbHNlID09PSByZXQpIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gYWR2YW5jZSBjdXJzb3JcbiAgICAgIGkgKz0gbjtcbiAgICAgIGxlbmd0aCA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIGlmIChsZW5ndGggIT0gJycpIHtcbiAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG4gIH1cblxufTtcblxuLyoqXG4gKiBFbmNvZGVzIG11bHRpcGxlIG1lc3NhZ2VzIChwYXlsb2FkKSBhcyBiaW5hcnkuXG4gKlxuICogPDEgPSBiaW5hcnksIDAgPSBzdHJpbmc+PG51bWJlciBmcm9tIDAtOT48bnVtYmVyIGZyb20gMC05PlsuLi5dPG51bWJlclxuICogMjU1PjxkYXRhPlxuICpcbiAqIEV4YW1wbGU6XG4gKiAxIDMgMjU1IDEgMiAzLCBpZiB0aGUgYmluYXJ5IGNvbnRlbnRzIGFyZSBpbnRlcnByZXRlZCBhcyA4IGJpdCBpbnRlZ2Vyc1xuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHBhY2tldHNcbiAqIEByZXR1cm4ge0FycmF5QnVmZmVyfSBlbmNvZGVkIHBheWxvYWRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGF5bG9hZEFzQXJyYXlCdWZmZXIgPSBmdW5jdGlvbihwYWNrZXRzLCBjYWxsYmFjaykge1xuICBpZiAoIXBhY2tldHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBBcnJheUJ1ZmZlcigwKSk7XG4gIH1cblxuICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICBleHBvcnRzLmVuY29kZVBhY2tldChwYWNrZXQsIHRydWUsIHRydWUsIGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHJldHVybiBkb25lQ2FsbGJhY2sobnVsbCwgZGF0YSk7XG4gICAgfSk7XG4gIH1cblxuICBtYXAocGFja2V0cywgZW5jb2RlT25lLCBmdW5jdGlvbihlcnIsIGVuY29kZWRQYWNrZXRzKSB7XG4gICAgdmFyIHRvdGFsTGVuZ3RoID0gZW5jb2RlZFBhY2tldHMucmVkdWNlKGZ1bmN0aW9uKGFjYywgcCkge1xuICAgICAgdmFyIGxlbjtcbiAgICAgIGlmICh0eXBlb2YgcCA9PT0gJ3N0cmluZycpe1xuICAgICAgICBsZW4gPSBwLmxlbmd0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxlbiA9IHAuYnl0ZUxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2MgKyBsZW4udG9TdHJpbmcoKS5sZW5ndGggKyBsZW4gKyAyOyAvLyBzdHJpbmcvYmluYXJ5IGlkZW50aWZpZXIgKyBzZXBhcmF0b3IgPSAyXG4gICAgfSwgMCk7XG5cbiAgICB2YXIgcmVzdWx0QXJyYXkgPSBuZXcgVWludDhBcnJheSh0b3RhbExlbmd0aCk7XG5cbiAgICB2YXIgYnVmZmVySW5kZXggPSAwO1xuICAgIGVuY29kZWRQYWNrZXRzLmZvckVhY2goZnVuY3Rpb24ocCkge1xuICAgICAgdmFyIGlzU3RyaW5nID0gdHlwZW9mIHAgPT09ICdzdHJpbmcnO1xuICAgICAgdmFyIGFiID0gcDtcbiAgICAgIGlmIChpc1N0cmluZykge1xuICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KHAubGVuZ3RoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmlld1tpXSA9IHAuY2hhckNvZGVBdChpKTtcbiAgICAgICAgfVxuICAgICAgICBhYiA9IHZpZXcuYnVmZmVyO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNTdHJpbmcpIHsgLy8gbm90IHRydWUgYmluYXJ5XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMDtcbiAgICAgIH0gZWxzZSB7IC8vIHRydWUgYmluYXJ5XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMTtcbiAgICAgIH1cblxuICAgICAgdmFyIGxlblN0ciA9IGFiLmJ5dGVMZW5ndGgudG9TdHJpbmcoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuU3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gcGFyc2VJbnQobGVuU3RyW2ldKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMjU1O1xuXG4gICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGFiKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IHZpZXdbaV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY2FsbGJhY2socmVzdWx0QXJyYXkuYnVmZmVyKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEVuY29kZSBhcyBCbG9iXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVQYXlsb2FkQXNCbG9iID0gZnVuY3Rpb24ocGFja2V0cywgY2FsbGJhY2spIHtcbiAgZnVuY3Rpb24gZW5jb2RlT25lKHBhY2tldCwgZG9uZUNhbGxiYWNrKSB7XG4gICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCB0cnVlLCB0cnVlLCBmdW5jdGlvbihlbmNvZGVkKSB7XG4gICAgICB2YXIgYmluYXJ5SWRlbnRpZmllciA9IG5ldyBVaW50OEFycmF5KDEpO1xuICAgICAgYmluYXJ5SWRlbnRpZmllclswXSA9IDE7XG4gICAgICBpZiAodHlwZW9mIGVuY29kZWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoZW5jb2RlZC5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVuY29kZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2aWV3W2ldID0gZW5jb2RlZC5jaGFyQ29kZUF0KGkpO1xuICAgICAgICB9XG4gICAgICAgIGVuY29kZWQgPSB2aWV3LmJ1ZmZlcjtcbiAgICAgICAgYmluYXJ5SWRlbnRpZmllclswXSA9IDA7XG4gICAgICB9XG5cbiAgICAgIHZhciBsZW4gPSAoZW5jb2RlZCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKVxuICAgICAgICA/IGVuY29kZWQuYnl0ZUxlbmd0aFxuICAgICAgICA6IGVuY29kZWQuc2l6ZTtcblxuICAgICAgdmFyIGxlblN0ciA9IGxlbi50b1N0cmluZygpO1xuICAgICAgdmFyIGxlbmd0aEFyeSA9IG5ldyBVaW50OEFycmF5KGxlblN0ci5sZW5ndGggKyAxKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuU3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxlbmd0aEFyeVtpXSA9IHBhcnNlSW50KGxlblN0cltpXSk7XG4gICAgICB9XG4gICAgICBsZW5ndGhBcnlbbGVuU3RyLmxlbmd0aF0gPSAyNTU7XG5cbiAgICAgIGlmIChCbG9iKSB7XG4gICAgICAgIHZhciBibG9iID0gbmV3IEJsb2IoW2JpbmFyeUlkZW50aWZpZXIuYnVmZmVyLCBsZW5ndGhBcnkuYnVmZmVyLCBlbmNvZGVkXSk7XG4gICAgICAgIGRvbmVDYWxsYmFjayhudWxsLCBibG9iKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG1hcChwYWNrZXRzLCBlbmNvZGVPbmUsIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICAgIHJldHVybiBjYWxsYmFjayhuZXcgQmxvYihyZXN1bHRzKSk7XG4gIH0pO1xufTtcblxuLypcbiAqIERlY29kZXMgZGF0YSB3aGVuIGEgcGF5bG9hZCBpcyBtYXliZSBleHBlY3RlZC4gU3RyaW5ncyBhcmUgZGVjb2RlZCBieVxuICogaW50ZXJwcmV0aW5nIGVhY2ggYnl0ZSBhcyBhIGtleSBjb2RlIGZvciBlbnRyaWVzIG1hcmtlZCB0byBzdGFydCB3aXRoIDAuIFNlZVxuICogZGVzY3JpcHRpb24gb2YgZW5jb2RlUGF5bG9hZEFzQmluYXJ5XG4gKlxuICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gZGF0YSwgY2FsbGJhY2sgbWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb2RlUGF5bG9hZEFzQmluYXJ5ID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgYmluYXJ5VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gYmluYXJ5VHlwZTtcbiAgICBiaW5hcnlUeXBlID0gbnVsbDtcbiAgfVxuXG4gIHZhciBidWZmZXJUYWlsID0gZGF0YTtcbiAgdmFyIGJ1ZmZlcnMgPSBbXTtcblxuICB2YXIgbnVtYmVyVG9vTG9uZyA9IGZhbHNlO1xuICB3aGlsZSAoYnVmZmVyVGFpbC5ieXRlTGVuZ3RoID4gMCkge1xuICAgIHZhciB0YWlsQXJyYXkgPSBuZXcgVWludDhBcnJheShidWZmZXJUYWlsKTtcbiAgICB2YXIgaXNTdHJpbmcgPSB0YWlsQXJyYXlbMF0gPT09IDA7XG4gICAgdmFyIG1zZ0xlbmd0aCA9ICcnO1xuXG4gICAgZm9yICh2YXIgaSA9IDE7IDsgaSsrKSB7XG4gICAgICBpZiAodGFpbEFycmF5W2ldID09IDI1NSkgYnJlYWs7XG5cbiAgICAgIGlmIChtc2dMZW5ndGgubGVuZ3RoID4gMzEwKSB7XG4gICAgICAgIG51bWJlclRvb0xvbmcgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgbXNnTGVuZ3RoICs9IHRhaWxBcnJheVtpXTtcbiAgICB9XG5cbiAgICBpZihudW1iZXJUb29Mb25nKSByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcblxuICAgIGJ1ZmZlclRhaWwgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCAyICsgbXNnTGVuZ3RoLmxlbmd0aCk7XG4gICAgbXNnTGVuZ3RoID0gcGFyc2VJbnQobXNnTGVuZ3RoKTtcblxuICAgIHZhciBtc2cgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCAwLCBtc2dMZW5ndGgpO1xuICAgIGlmIChpc1N0cmluZykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbXNnID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDhBcnJheShtc2cpKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gaVBob25lIFNhZmFyaSBkb2Vzbid0IGxldCB5b3UgYXBwbHkgdG8gdHlwZWQgYXJyYXlzXG4gICAgICAgIHZhciB0eXBlZCA9IG5ldyBVaW50OEFycmF5KG1zZyk7XG4gICAgICAgIG1zZyA9ICcnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgbXNnICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodHlwZWRbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgYnVmZmVycy5wdXNoKG1zZyk7XG4gICAgYnVmZmVyVGFpbCA9IHNsaWNlQnVmZmVyKGJ1ZmZlclRhaWwsIG1zZ0xlbmd0aCk7XG4gIH1cblxuICB2YXIgdG90YWwgPSBidWZmZXJzLmxlbmd0aDtcbiAgYnVmZmVycy5mb3JFYWNoKGZ1bmN0aW9uKGJ1ZmZlciwgaSkge1xuICAgIGNhbGxiYWNrKGV4cG9ydHMuZGVjb2RlUGFja2V0KGJ1ZmZlciwgYmluYXJ5VHlwZSwgdHJ1ZSksIGksIHRvdGFsKTtcbiAgfSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///aa6c\n")},adfa:function(module,exports,__webpack_require__){eval("/**\n * Utility functions for crossfilter datasets\n * We roughly follow the crossfilter design of dimensions and groups, but we\n * add extra steps to allow transformations on the data.\n * 1. a datum is turned into a raw value, ie. string or number etc. by rawValueFn\n * 2. it is then cast to the correct type value using baseValFn\n * 3. a further transfrom can be applied with valueFn\n * 4. a value is grouped using groupFn; this value must be either a number or a string.\n *\n * @module client/util-crossfilter\n * @see rawValueFn, baseValueFn, valueFn, groupFn\n */\nvar misval = __webpack_require__(/*! ./misval */ \"bff6\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\n\n/**\n * @typedef {Object} SubgroupValue\n * @property {number} count The count of the number of elements in this subgroup\n * @property {number} sum The sum of all elements in this subgroup\n */\n\n/**\n * Reduce a SubgroupValue to a single number\n *\n * @callback reduceCB\n * @param {SubgroupValue} d SubgroupValue\n * @returns {number} Reduced value\n */\n/**\n\n/**\n * Returns a function for further reducing the crossfilter group\n * to a single value, depending on sum/count/average settings of\n * the Aggregate class.\n * @param {Aggregate} facet - The Aggregate class for which to create the reduction function\n * @returns {cb} The required reduction function\n */\nfunction reduceFn (aggregate) {\n  if (aggregate.doSum) {\n    /**\n     * @callback subgroupSum\n     * @param {SubgroupValue} d\n     * @returns {number} sum\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n      if (d.count > 0) {\n        return d.sum;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doCount) {\n    /**\n     * @callback subgroupCount\n     * @param {SubgroupValue} d\n     * @returns {number} count\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n      if (d.count > 0) {\n        return d.count;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doAverage) {\n    /**\n     * @callback subgroupAverage\n     * @param {SubgroupValue} d\n     * @returns {number} d.sum/d.count\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n\n      if (d.count > 0) {\n        return d.sum / d.count;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doStddev) {\n    /**\n     * @callback subgroupStddev\n     * @param {SubgroupValue} d\n     * @returns {number} stddev(d)\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n\n      // \\sum_i (x_i - \\bar x)^2 =\n      //   \\sum_i (x_i^2 - 2x_i\\bar x + (\\bar x)^2) =\n      //   \\sum_i (x_i^2) - 2 N (\\bar x)^2 + N(\\bar x)^2 =\n      //   \\sum_i (x_i^2) - N (\\bar x)^2\n      if (d.count > 1) {\n        return Math.sqrt((d.sumsquares - (d.sum * d.sum / d.count)) / (d.count - 1));\n      } else {\n        return misval;\n      }\n    };\n  }\n\n  console.error('Operation not implemented for this Aggregate', aggregate);\n  return function (d) {\n    if (d === misval || d == null) {\n      return misval;\n    }\n    if (d.count > 0) {\n      return d.count;\n    } else {\n      return misval;\n    }\n  };\n}\n\n// ********************************************************\n// Facet transform utility function\n// ********************************************************\n\n/**\n * Returns the base value for a datum\n *\n * @callback baseValueCB\n * @param {Object} d Raw data record\n * @returns {Object} base value\n */\n\n/**\n * Raw value for given facet\n * @param {Facet} facet\n * @returns {rawValueCB} Raw value function for this facet\n */\nfunction rawValueFn (facet) {\n  var accessor;\n\n  // Array dimensions have a [] appended to the accessor,\n  // remove it to get to the actual accessor\n  var path = facet.accessor;\n  if (path.match(/\\[]$/)) {\n    path = path.substring(0, path.length - 2);\n  }\n\n  var misvals = {};\n  facet.misval.forEach(function (val) {\n    misvals[val] = true;\n  });\n\n  // Access nested properties via a double hash sign, this to prevent collision with regular keys; fi. 'person.name'\n  path = path.split('##');\n\n  if (path.length === 1) {\n    // Use a simple direct accessor, as it is probably faster than the more general case\n    // and it was implemented already\n    if (facet.misval.length > 0) {\n      accessor = function (d) {\n        var value = d[path[0]];\n        if (value === undefined || value === null || value in misvals) {\n          return misval;\n        }\n        return value;\n      };\n    } else {\n      accessor = function (d) {\n        var value = d[path[0]];\n        if (value === undefined || value === null) {\n          return misval;\n        }\n        return value;\n      };\n    }\n  } else {\n    // Recursively follow the crumbs to the desired property\n    accessor = function (d) {\n      var i = 0;\n      var value = d;\n\n      for (i = 0; i < path.length; i++) {\n        if (value && value[path[i]] !== undefined) {\n          value = value[path[i]];\n        } else {\n          return misval;\n        }\n      }\n\n      if (value === null || value in misvals) {\n        value = misval;\n      }\n      return value;\n    };\n  }\n\n  return accessor;\n}\n\n/**\n * Base value for given facet, ie. cast to correct type or object.\n * @param {Facet} facet\n * @returns {vaseValueCB} Base value function for this facet\n */\nfunction baseValueFn (facet) {\n  var rawValFn = rawValueFn(facet);\n\n  if (facet.isContinuous) {\n    /*\n     * Continuous facets:\n     * Parse numeric value from base value\n     */\n    return function (d) {\n      var val = parseFloat(rawValFn(d));\n      if (isNaN(val) || val === Infinity || val === -Infinity) {\n        return misval;\n      }\n      return val;\n    };\n  } else if (facet.isCategorial) {\n    return function (d) {\n      var vals = rawValFn(d);\n      if (vals !== misval) {\n        if (vals instanceof Array) {\n          vals.forEach(function (val, i) {\n            vals[i] = val.toString();\n          });\n        } else {\n          vals = vals.toString();\n        }\n        return vals;\n      }\n      return misval;\n    };\n  } else if (facet.isDatetime) {\n    /*\n     * Time parsing:\n     * 1. moment parses the string using the given format, but defaults to\n     *    the [ISO 8601 standard](https://en.wikipedia.org/wiki/ISO_8601)\n     * 2. Note that if the string contains timezone information, that is parsed too.\n     * 3. The time is transformed to requested timezone, defaulting the locale default\n     *    when no zone is set\n    */\n    var timeFormat = facet.datetimeTransform.format;\n    if (timeFormat === 'ISO8601') {\n      // use default ISO formatting\n      timeFormat = moment.ISO_8601;\n    }\n\n    var timeZone = facet.datetimeTransform.zone;\n    if (timeZone === 'ISO8601') {\n      // use default locale timezone, get overridden if a string contains a timezone\n      timeZone = moment.tz.guess();\n    } else {\n      timeZone = util.timeZones.get(timeZone, 'description').format;\n    }\n\n    return function (d) {\n      var value = rawValFn(d);\n      if (value !== misval) {\n        var m = moment.tz(value, timeFormat, timeZone);\n        if (m.isValid()) {\n          return m;\n        }\n      }\n      return misval;\n    };\n  } else if (facet.isDuration) {\n    /*\n     * Duration parsing:\n     * 1. If no format is given, the string parsed using\n     *    the [ISO 8601 standard](https://en.wikipedia.org/wiki/ISO_8601)\n     * 2. If a format is given, the string is parsed as float and interpreted in the given units\n     */\n    var units = facet.durationTransform.units;\n    if (units === 'ISO8601') {\n      return function (d) {\n        var value = rawValFn(d);\n\n        // parse string if necessary\n        if (value !== misval && typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          value = moment.duration(value);\n        }\n\n        // check for valid duration\n        if (moment.isDuration(value)) {\n          return value;\n        }\n\n        return misval;\n      };\n    } else {\n      units = util.durationUnits.get(units, 'description').momentFormat;\n      return function (d) {\n        var value = rawValFn(d);\n\n        // parse string if necessary\n        if (value !== misval && !isNaN(value)) {\n          // NOTE: isNaN('0') is false, if that gives problems, we could use:\n          // value == +value) { // eslint-disable-line eqeqeq\n          value = moment.duration(parseFloat(value), units);\n        }\n\n        // check for valid duration\n        if (moment.isDuration(value)) {\n          return value;\n        }\n\n        return misval;\n      };\n    }\n  }\n\n  // isCategorial, isText\n  // no casting or constructing necessary, return the raw value\n  return rawValFn;\n}\n\n/**\n * Returns the transformed value from a base value\n *\n * @callback valueCB\n * @param {Object} d Base value\n * @returns {Object} Transformed value\n */\n\n/**\n * Create a function that returns the transformed value for this facet\n * @param {Facet} facet\n * @returns {valueCB} Value function for this facet\n */\nfunction valueFn (facet) {\n  // get base value function\n  var baseValFn = baseValueFn(facet);\n\n  if (facet.isConstant) {\n    return function () { return '1'; };\n  } else if (facet.isContinuous) {\n    // do we have a continuous transform?\n    if (facet.continuousTransform && facet.continuousTransform.type !== 'none') {\n      // yes, use it\n      return function (d) {\n        var val = facet.continuousTransform.transform(parseFloat(baseValFn(d)));\n        if (isNaN(val) || val === Infinity || val === -Infinity) {\n          return misval;\n        }\n        return val;\n      };\n    }\n  } else if (facet.isCategorial) {\n    // do we have a categorial transform?\n    if (facet.categorialTransform && facet.categorialTransform.rules.length > 0) {\n      // yes, use it\n      return function (d) {\n        var val = baseValFn(d);\n        return val === misval ? misval : facet.categorialTransform.transform(baseValFn(d));\n      };\n    }\n  } else if (facet.isDatetime) {\n    // always use the transform, so we do not have to repeat the yes/no transfrom logic here\n    return function (d) {\n      var val = baseValFn(d);\n      return val === misval ? misval : facet.datetimeTransform.transform(val);\n    };\n  } else if (facet.isDuration) {\n    // always use the transform, so we do not have to repeat the yes/no transfrom logic here\n    return function (d) {\n      var val = baseValFn(d);\n      return val === misval ? misval : facet.durationTransform.transform(val);\n    };\n  }\n\n  // no transfrom, return base value\n  return baseValFn;\n}\n\nfunction continuousGroupFn (partition) {\n  return function (d) {\n    if (d === misval) {\n      return d;\n    }\n\n    var ngroups = partition.groups.length;\n    if (d < partition.minval || d > partition.maxval) {\n      return misval;\n    }\n\n    // bins include their lower bound, but not their upper bound\n    var i = 0;\n    while (i < ngroups && d >= partition.groups.models[i].max) {\n      i++;\n    }\n    // special case last bin includes also upperbound d === partition.maxval\n    if (i === ngroups) {\n      return partition.groups.models[i - 1].value;\n    }\n    return partition.groups.models[i].value;\n  };\n}\n\n/*\n * Round the datetime to the specified resolution\n * see:\n * http://momentjs.com/docs/#/manipulating/start-of/\n * http://momentjs.com/docs/#/displaying/as-javascript-date/\n */\nfunction datetimeGroupFn (partition) {\n  var timeStep = util.getDatetimeResolution(partition.minval, partition.maxval);\n  return function (d) {\n    if (d === misval) {\n      return misval;\n    }\n    if (d.isBefore(partition.minval) || d.isAfter(partition.maxval)) {\n      return misval;\n    }\n    var grouped = moment(d).startOf(timeStep).format();\n    return grouped;\n  };\n}\n\n/*\n * Round the duration to the specified resolution\n */\nfunction durationGroupFn (partition) {\n  var timeStep = util.getDurationResolution(partition.minval, partition.maxval);\n  return function (d) {\n    if (d === misval) {\n      return misval;\n    }\n    if (d < partition.minval || d > partition.maxval) {\n      return misval;\n    }\n    var rounded = Math.floor(parseFloat(d.as(timeStep)));\n    return moment.duration(rounded, timeStep).toISOString();\n  };\n}\n\n/*\n * Don't do any grouping; that is done in the step from base value to value.\n * Matching of facet value and group could lead to a different ordering,\n * which is not allowed by crossfilter\n */\nfunction categorialGroupFn (partition) {\n  return function (d) { return d; };\n}\n\n/**\n * Returns the grouped value for a transformed value\n *\n * @callback groupCB\n * @param {Object} d Transformed value\n * @returns {Object} Group\n */\n\n/**\n * Create a function that returns the group value for a partition\n * @param {Partition} partition\n * @returns {cb} Group function for this partition, taking a `Data`\n */\nfunction groupFn (partition) {\n  if (partition.isConstant) {\n    return function () { return '1'; };\n  } else if (partition.isContinuous) {\n    return continuousGroupFn(partition);\n  } else if (partition.isCategorial) {\n    return categorialGroupFn(partition);\n  } else if (partition.isDatetime) {\n    return datetimeGroupFn(partition);\n  } else if (partition.isDuration) {\n    return durationGroupFn(partition);\n  } else if (partition.isText) {\n    return function (d) { return d.toString(); };\n  } else {\n    console.error('Group function not implemented for partition', partition);\n  }\n}\n\nmodule.exports = {\n  rawValueFn: rawValueFn,\n  baseValueFn: baseValueFn,\n  valueFn: valueFn,\n  groupFn: groupFn,\n\n  reduceFn: reduceFn\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRmYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9jcm9zc2ZpbHRlci5qcz8xZjdhIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIGNyb3NzZmlsdGVyIGRhdGFzZXRzXG4gKiBXZSByb3VnaGx5IGZvbGxvdyB0aGUgY3Jvc3NmaWx0ZXIgZGVzaWduIG9mIGRpbWVuc2lvbnMgYW5kIGdyb3VwcywgYnV0IHdlXG4gKiBhZGQgZXh0cmEgc3RlcHMgdG8gYWxsb3cgdHJhbnNmb3JtYXRpb25zIG9uIHRoZSBkYXRhLlxuICogMS4gYSBkYXR1bSBpcyB0dXJuZWQgaW50byBhIHJhdyB2YWx1ZSwgaWUuIHN0cmluZyBvciBudW1iZXIgZXRjLiBieSByYXdWYWx1ZUZuXG4gKiAyLiBpdCBpcyB0aGVuIGNhc3QgdG8gdGhlIGNvcnJlY3QgdHlwZSB2YWx1ZSB1c2luZyBiYXNlVmFsRm5cbiAqIDMuIGEgZnVydGhlciB0cmFuc2Zyb20gY2FuIGJlIGFwcGxpZWQgd2l0aCB2YWx1ZUZuXG4gKiA0LiBhIHZhbHVlIGlzIGdyb3VwZWQgdXNpbmcgZ3JvdXBGbjsgdGhpcyB2YWx1ZSBtdXN0IGJlIGVpdGhlciBhIG51bWJlciBvciBhIHN0cmluZy5cbiAqXG4gKiBAbW9kdWxlIGNsaWVudC91dGlsLWNyb3NzZmlsdGVyXG4gKiBAc2VlIHJhd1ZhbHVlRm4sIGJhc2VWYWx1ZUZuLCB2YWx1ZUZuLCBncm91cEZuXG4gKi9cbnZhciBtaXN2YWwgPSByZXF1aXJlKCcuL21pc3ZhbCcpO1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsL3RpbWUnKTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTdWJncm91cFZhbHVlXG4gKiBAcHJvcGVydHkge251bWJlcn0gY291bnQgVGhlIGNvdW50IG9mIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBzdWJncm91cFxuICogQHByb3BlcnR5IHtudW1iZXJ9IHN1bSBUaGUgc3VtIG9mIGFsbCBlbGVtZW50cyBpbiB0aGlzIHN1Ymdyb3VwXG4gKi9cblxuLyoqXG4gKiBSZWR1Y2UgYSBTdWJncm91cFZhbHVlIHRvIGEgc2luZ2xlIG51bWJlclxuICpcbiAqIEBjYWxsYmFjayByZWR1Y2VDQlxuICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkIFN1Ymdyb3VwVmFsdWVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJlZHVjZWQgdmFsdWVcbiAqL1xuLyoqXG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIGZvciBmdXJ0aGVyIHJlZHVjaW5nIHRoZSBjcm9zc2ZpbHRlciBncm91cFxuICogdG8gYSBzaW5nbGUgdmFsdWUsIGRlcGVuZGluZyBvbiBzdW0vY291bnQvYXZlcmFnZSBzZXR0aW5ncyBvZlxuICogdGhlIEFnZ3JlZ2F0ZSBjbGFzcy5cbiAqIEBwYXJhbSB7QWdncmVnYXRlfSBmYWNldCAtIFRoZSBBZ2dyZWdhdGUgY2xhc3MgZm9yIHdoaWNoIHRvIGNyZWF0ZSB0aGUgcmVkdWN0aW9uIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7Y2J9IFRoZSByZXF1aXJlZCByZWR1Y3Rpb24gZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gcmVkdWNlRm4gKGFnZ3JlZ2F0ZSkge1xuICBpZiAoYWdncmVnYXRlLmRvU3VtKSB7XG4gICAgLyoqXG4gICAgICogQGNhbGxiYWNrIHN1Ymdyb3VwU3VtXG4gICAgICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkXG4gICAgICogQHJldHVybnMge251bWJlcn0gc3VtXG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICBpZiAoZCA9PT0gbWlzdmFsIHx8IGQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgICAgaWYgKGQuY291bnQgPiAwKSB7XG4gICAgICAgIHJldHVybiBkLnN1bTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIGlmIChhZ2dyZWdhdGUuZG9Db3VudCkge1xuICAgIC8qKlxuICAgICAqIEBjYWxsYmFjayBzdWJncm91cENvdW50XG4gICAgICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkXG4gICAgICogQHJldHVybnMge251bWJlcn0gY291bnRcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGQuY291bnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgIH07XG4gIH0gZWxzZSBpZiAoYWdncmVnYXRlLmRvQXZlcmFnZSkge1xuICAgIC8qKlxuICAgICAqIEBjYWxsYmFjayBzdWJncm91cEF2ZXJhZ2VcbiAgICAgKiBAcGFyYW0ge1N1Ymdyb3VwVmFsdWV9IGRcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBkLnN1bS9kLmNvdW50XG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICBpZiAoZCA9PT0gbWlzdmFsIHx8IGQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuXG4gICAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGQuc3VtIC8gZC5jb3VudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIGlmIChhZ2dyZWdhdGUuZG9TdGRkZXYpIHtcbiAgICAvKipcbiAgICAgKiBAY2FsbGJhY2sgc3ViZ3JvdXBTdGRkZXZcbiAgICAgKiBAcGFyYW0ge1N1Ymdyb3VwVmFsdWV9IGRcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBzdGRkZXYoZClcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG5cbiAgICAgIC8vIFxcc3VtX2kgKHhfaSAtIFxcYmFyIHgpXjIgPVxuICAgICAgLy8gICBcXHN1bV9pICh4X2leMiAtIDJ4X2lcXGJhciB4ICsgKFxcYmFyIHgpXjIpID1cbiAgICAgIC8vICAgXFxzdW1faSAoeF9pXjIpIC0gMiBOIChcXGJhciB4KV4yICsgTihcXGJhciB4KV4yID1cbiAgICAgIC8vICAgXFxzdW1faSAoeF9pXjIpIC0gTiAoXFxiYXIgeCleMlxuICAgICAgaWYgKGQuY291bnQgPiAxKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnNxcnQoKGQuc3Vtc3F1YXJlcyAtIChkLnN1bSAqIGQuc3VtIC8gZC5jb3VudCkpIC8gKGQuY291bnQgLSAxKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBjb25zb2xlLmVycm9yKCdPcGVyYXRpb24gbm90IGltcGxlbWVudGVkIGZvciB0aGlzIEFnZ3JlZ2F0ZScsIGFnZ3JlZ2F0ZSk7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgIHJldHVybiBkLmNvdW50O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgfTtcbn1cblxuLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbi8vIEZhY2V0IHRyYW5zZm9ybSB1dGlsaXR5IGZ1bmN0aW9uXG4vLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG4vKipcbiAqIFJldHVybnMgdGhlIGJhc2UgdmFsdWUgZm9yIGEgZGF0dW1cbiAqXG4gKiBAY2FsbGJhY2sgYmFzZVZhbHVlQ0JcbiAqIEBwYXJhbSB7T2JqZWN0fSBkIFJhdyBkYXRhIHJlY29yZFxuICogQHJldHVybnMge09iamVjdH0gYmFzZSB2YWx1ZVxuICovXG5cbi8qKlxuICogUmF3IHZhbHVlIGZvciBnaXZlbiBmYWNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqIEByZXR1cm5zIHtyYXdWYWx1ZUNCfSBSYXcgdmFsdWUgZnVuY3Rpb24gZm9yIHRoaXMgZmFjZXRcbiAqL1xuZnVuY3Rpb24gcmF3VmFsdWVGbiAoZmFjZXQpIHtcbiAgdmFyIGFjY2Vzc29yO1xuXG4gIC8vIEFycmF5IGRpbWVuc2lvbnMgaGF2ZSBhIFtdIGFwcGVuZGVkIHRvIHRoZSBhY2Nlc3NvcixcbiAgLy8gcmVtb3ZlIGl0IHRvIGdldCB0byB0aGUgYWN0dWFsIGFjY2Vzc29yXG4gIHZhciBwYXRoID0gZmFjZXQuYWNjZXNzb3I7XG4gIGlmIChwYXRoLm1hdGNoKC9cXFtdJC8pKSB7XG4gICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoIC0gMik7XG4gIH1cblxuICB2YXIgbWlzdmFscyA9IHt9O1xuICBmYWNldC5taXN2YWwuZm9yRWFjaChmdW5jdGlvbiAodmFsKSB7XG4gICAgbWlzdmFsc1t2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgLy8gQWNjZXNzIG5lc3RlZCBwcm9wZXJ0aWVzIHZpYSBhIGRvdWJsZSBoYXNoIHNpZ24sIHRoaXMgdG8gcHJldmVudCBjb2xsaXNpb24gd2l0aCByZWd1bGFyIGtleXM7IGZpLiAncGVyc29uLm5hbWUnXG4gIHBhdGggPSBwYXRoLnNwbGl0KCcjIycpO1xuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMSkge1xuICAgIC8vIFVzZSBhIHNpbXBsZSBkaXJlY3QgYWNjZXNzb3IsIGFzIGl0IGlzIHByb2JhYmx5IGZhc3RlciB0aGFuIHRoZSBtb3JlIGdlbmVyYWwgY2FzZVxuICAgIC8vIGFuZCBpdCB3YXMgaW1wbGVtZW50ZWQgYWxyZWFkeVxuICAgIGlmIChmYWNldC5taXN2YWwubGVuZ3RoID4gMCkge1xuICAgICAgYWNjZXNzb3IgPSBmdW5jdGlvbiAoZCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBkW3BhdGhbMF1dO1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSBpbiBtaXN2YWxzKSB7XG4gICAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBhY2Nlc3NvciA9IGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGRbcGF0aFswXV07XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBSZWN1cnNpdmVseSBmb2xsb3cgdGhlIGNydW1icyB0byB0aGUgZGVzaXJlZCBwcm9wZXJ0eVxuICAgIGFjY2Vzc29yID0gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciBpID0gMDtcbiAgICAgIHZhciB2YWx1ZSA9IGQ7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh2YWx1ZSAmJiB2YWx1ZVtwYXRoW2ldXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZVtwYXRoW2ldXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSBpbiBtaXN2YWxzKSB7XG4gICAgICAgIHZhbHVlID0gbWlzdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gYWNjZXNzb3I7XG59XG5cbi8qKlxuICogQmFzZSB2YWx1ZSBmb3IgZ2l2ZW4gZmFjZXQsIGllLiBjYXN0IHRvIGNvcnJlY3QgdHlwZSBvciBvYmplY3QuXG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICogQHJldHVybnMge3Zhc2VWYWx1ZUNCfSBCYXNlIHZhbHVlIGZ1bmN0aW9uIGZvciB0aGlzIGZhY2V0XG4gKi9cbmZ1bmN0aW9uIGJhc2VWYWx1ZUZuIChmYWNldCkge1xuICB2YXIgcmF3VmFsRm4gPSByYXdWYWx1ZUZuKGZhY2V0KTtcblxuICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgLypcbiAgICAgKiBDb250aW51b3VzIGZhY2V0czpcbiAgICAgKiBQYXJzZSBudW1lcmljIHZhbHVlIGZyb20gYmFzZSB2YWx1ZVxuICAgICAqL1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbCA9IHBhcnNlRmxvYXQocmF3VmFsRm4oZCkpO1xuICAgICAgaWYgKGlzTmFOKHZhbCkgfHwgdmFsID09PSBJbmZpbml0eSB8fCB2YWwgPT09IC1JbmZpbml0eSkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbDtcbiAgICB9O1xuICB9IGVsc2UgaWYgKGZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbHMgPSByYXdWYWxGbihkKTtcbiAgICAgIGlmICh2YWxzICE9PSBtaXN2YWwpIHtcbiAgICAgICAgaWYgKHZhbHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgIHZhbHMuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBpKSB7XG4gICAgICAgICAgICB2YWxzW2ldID0gdmFsLnRvU3RyaW5nKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFscyA9IHZhbHMudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFscztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgLypcbiAgICAgKiBUaW1lIHBhcnNpbmc6XG4gICAgICogMS4gbW9tZW50IHBhcnNlcyB0aGUgc3RyaW5nIHVzaW5nIHRoZSBnaXZlbiBmb3JtYXQsIGJ1dCBkZWZhdWx0cyB0b1xuICAgICAqICAgIHRoZSBbSVNPIDg2MDEgc3RhbmRhcmRdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT184NjAxKVxuICAgICAqIDIuIE5vdGUgdGhhdCBpZiB0aGUgc3RyaW5nIGNvbnRhaW5zIHRpbWV6b25lIGluZm9ybWF0aW9uLCB0aGF0IGlzIHBhcnNlZCB0b28uXG4gICAgICogMy4gVGhlIHRpbWUgaXMgdHJhbnNmb3JtZWQgdG8gcmVxdWVzdGVkIHRpbWV6b25lLCBkZWZhdWx0aW5nIHRoZSBsb2NhbGUgZGVmYXVsdFxuICAgICAqICAgIHdoZW4gbm8gem9uZSBpcyBzZXRcbiAgICAqL1xuICAgIHZhciB0aW1lRm9ybWF0ID0gZmFjZXQuZGF0ZXRpbWVUcmFuc2Zvcm0uZm9ybWF0O1xuICAgIGlmICh0aW1lRm9ybWF0ID09PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIHVzZSBkZWZhdWx0IElTTyBmb3JtYXR0aW5nXG4gICAgICB0aW1lRm9ybWF0ID0gbW9tZW50LklTT184NjAxO1xuICAgIH1cblxuICAgIHZhciB0aW1lWm9uZSA9IGZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnpvbmU7XG4gICAgaWYgKHRpbWVab25lID09PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIHVzZSBkZWZhdWx0IGxvY2FsZSB0aW1lem9uZSwgZ2V0IG92ZXJyaWRkZW4gaWYgYSBzdHJpbmcgY29udGFpbnMgYSB0aW1lem9uZVxuICAgICAgdGltZVpvbmUgPSBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGltZVpvbmUgPSB1dGlsLnRpbWVab25lcy5nZXQodGltZVpvbmUsICdkZXNjcmlwdGlvbicpLmZvcm1hdDtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWx1ZSA9IHJhd1ZhbEZuKGQpO1xuICAgICAgaWYgKHZhbHVlICE9PSBtaXN2YWwpIHtcbiAgICAgICAgdmFyIG0gPSBtb21lbnQudHoodmFsdWUsIHRpbWVGb3JtYXQsIHRpbWVab25lKTtcbiAgICAgICAgaWYgKG0uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIG07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0R1cmF0aW9uKSB7XG4gICAgLypcbiAgICAgKiBEdXJhdGlvbiBwYXJzaW5nOlxuICAgICAqIDEuIElmIG5vIGZvcm1hdCBpcyBnaXZlbiwgdGhlIHN0cmluZyBwYXJzZWQgdXNpbmdcbiAgICAgKiAgICB0aGUgW0lTTyA4NjAxIHN0YW5kYXJkXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSlcbiAgICAgKiAyLiBJZiBhIGZvcm1hdCBpcyBnaXZlbiwgdGhlIHN0cmluZyBpcyBwYXJzZWQgYXMgZmxvYXQgYW5kIGludGVycHJldGVkIGluIHRoZSBnaXZlbiB1bml0c1xuICAgICAqL1xuICAgIHZhciB1bml0cyA9IGZhY2V0LmR1cmF0aW9uVHJhbnNmb3JtLnVuaXRzO1xuICAgIGlmICh1bml0cyA9PT0gJ0lTTzg2MDEnKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gcmF3VmFsRm4oZCk7XG5cbiAgICAgICAgLy8gcGFyc2Ugc3RyaW5nIGlmIG5lY2Vzc2FyeVxuICAgICAgICBpZiAodmFsdWUgIT09IG1pc3ZhbCAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlWzBdLnRvTG93ZXJDYXNlKCkgPT09ICdwJykge1xuICAgICAgICAgIHZhbHVlID0gbW9tZW50LmR1cmF0aW9uKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGZvciB2YWxpZCBkdXJhdGlvblxuICAgICAgICBpZiAobW9tZW50LmlzRHVyYXRpb24odmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuaXRzID0gdXRpbC5kdXJhdGlvblVuaXRzLmdldCh1bml0cywgJ2Rlc2NyaXB0aW9uJykubW9tZW50Rm9ybWF0O1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJhd1ZhbEZuKGQpO1xuXG4gICAgICAgIC8vIHBhcnNlIHN0cmluZyBpZiBuZWNlc3NhcnlcbiAgICAgICAgaWYgKHZhbHVlICE9PSBtaXN2YWwgJiYgIWlzTmFOKHZhbHVlKSkge1xuICAgICAgICAgIC8vIE5PVEU6IGlzTmFOKCcwJykgaXMgZmFsc2UsIGlmIHRoYXQgZ2l2ZXMgcHJvYmxlbXMsIHdlIGNvdWxkIHVzZTpcbiAgICAgICAgICAvLyB2YWx1ZSA9PSArdmFsdWUpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICAgICAgICB2YWx1ZSA9IG1vbWVudC5kdXJhdGlvbihwYXJzZUZsb2F0KHZhbHVlKSwgdW5pdHMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIHZhbGlkIGR1cmF0aW9uXG4gICAgICAgIGlmIChtb21lbnQuaXNEdXJhdGlvbih2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvLyBpc0NhdGVnb3JpYWwsIGlzVGV4dFxuICAvLyBubyBjYXN0aW5nIG9yIGNvbnN0cnVjdGluZyBuZWNlc3NhcnksIHJldHVybiB0aGUgcmF3IHZhbHVlXG4gIHJldHVybiByYXdWYWxGbjtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB0cmFuc2Zvcm1lZCB2YWx1ZSBmcm9tIGEgYmFzZSB2YWx1ZVxuICpcbiAqIEBjYWxsYmFjayB2YWx1ZUNCXG4gKiBAcGFyYW0ge09iamVjdH0gZCBCYXNlIHZhbHVlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBUcmFuc2Zvcm1lZCB2YWx1ZVxuICovXG5cbi8qKlxuICogQ3JlYXRlIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB0cmFuc2Zvcm1lZCB2YWx1ZSBmb3IgdGhpcyBmYWNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqIEByZXR1cm5zIHt2YWx1ZUNCfSBWYWx1ZSBmdW5jdGlvbiBmb3IgdGhpcyBmYWNldFxuICovXG5mdW5jdGlvbiB2YWx1ZUZuIChmYWNldCkge1xuICAvLyBnZXQgYmFzZSB2YWx1ZSBmdW5jdGlvblxuICB2YXIgYmFzZVZhbEZuID0gYmFzZVZhbHVlRm4oZmFjZXQpO1xuXG4gIGlmIChmYWNldC5pc0NvbnN0YW50KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsgcmV0dXJuICcxJzsgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0NvbnRpbnVvdXMpIHtcbiAgICAvLyBkbyB3ZSBoYXZlIGEgY29udGludW91cyB0cmFuc2Zvcm0/XG4gICAgaWYgKGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm0gJiYgZmFjZXQuY29udGludW91c1RyYW5zZm9ybS50eXBlICE9PSAnbm9uZScpIHtcbiAgICAgIC8vIHllcywgdXNlIGl0XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgdmFyIHZhbCA9IGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm0udHJhbnNmb3JtKHBhcnNlRmxvYXQoYmFzZVZhbEZuKGQpKSk7XG4gICAgICAgIGlmIChpc05hTih2YWwpIHx8IHZhbCA9PT0gSW5maW5pdHkgfHwgdmFsID09PSAtSW5maW5pdHkpIHtcbiAgICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIGlmIChmYWNldC5pc0NhdGVnb3JpYWwpIHtcbiAgICAvLyBkbyB3ZSBoYXZlIGEgY2F0ZWdvcmlhbCB0cmFuc2Zvcm0/XG4gICAgaWYgKGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0gJiYgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyB5ZXMsIHVzZSBpdFxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWwgPSBiYXNlVmFsRm4oZCk7XG4gICAgICAgIHJldHVybiB2YWwgPT09IG1pc3ZhbCA/IG1pc3ZhbCA6IGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0udHJhbnNmb3JtKGJhc2VWYWxGbihkKSk7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgLy8gYWx3YXlzIHVzZSB0aGUgdHJhbnNmb3JtLCBzbyB3ZSBkbyBub3QgaGF2ZSB0byByZXBlYXQgdGhlIHllcy9ubyB0cmFuc2Zyb20gbG9naWMgaGVyZVxuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbCA9IGJhc2VWYWxGbihkKTtcbiAgICAgIHJldHVybiB2YWwgPT09IG1pc3ZhbCA/IG1pc3ZhbCA6IGZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnRyYW5zZm9ybSh2YWwpO1xuICAgIH07XG4gIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgIC8vIGFsd2F5cyB1c2UgdGhlIHRyYW5zZm9ybSwgc28gd2UgZG8gbm90IGhhdmUgdG8gcmVwZWF0IHRoZSB5ZXMvbm8gdHJhbnNmcm9tIGxvZ2ljIGhlcmVcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWwgPSBiYXNlVmFsRm4oZCk7XG4gICAgICByZXR1cm4gdmFsID09PSBtaXN2YWwgPyBtaXN2YWwgOiBmYWNldC5kdXJhdGlvblRyYW5zZm9ybS50cmFuc2Zvcm0odmFsKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gbm8gdHJhbnNmcm9tLCByZXR1cm4gYmFzZSB2YWx1ZVxuICByZXR1cm4gYmFzZVZhbEZuO1xufVxuXG5mdW5jdGlvbiBjb250aW51b3VzR3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiBkO1xuICAgIH1cblxuICAgIHZhciBuZ3JvdXBzID0gcGFydGl0aW9uLmdyb3Vwcy5sZW5ndGg7XG4gICAgaWYgKGQgPCBwYXJ0aXRpb24ubWludmFsIHx8IGQgPiBwYXJ0aXRpb24ubWF4dmFsKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cblxuICAgIC8vIGJpbnMgaW5jbHVkZSB0aGVpciBsb3dlciBib3VuZCwgYnV0IG5vdCB0aGVpciB1cHBlciBib3VuZFxuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoaSA8IG5ncm91cHMgJiYgZCA+PSBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpXS5tYXgpIHtcbiAgICAgIGkrKztcbiAgICB9XG4gICAgLy8gc3BlY2lhbCBjYXNlIGxhc3QgYmluIGluY2x1ZGVzIGFsc28gdXBwZXJib3VuZCBkID09PSBwYXJ0aXRpb24ubWF4dmFsXG4gICAgaWYgKGkgPT09IG5ncm91cHMpIHtcbiAgICAgIHJldHVybiBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpIC0gMV0udmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpXS52YWx1ZTtcbiAgfTtcbn1cblxuLypcbiAqIFJvdW5kIHRoZSBkYXRldGltZSB0byB0aGUgc3BlY2lmaWVkIHJlc29sdXRpb25cbiAqIHNlZTpcbiAqIGh0dHA6Ly9tb21lbnRqcy5jb20vZG9jcy8jL21hbmlwdWxhdGluZy9zdGFydC1vZi9cbiAqIGh0dHA6Ly9tb21lbnRqcy5jb20vZG9jcy8jL2Rpc3BsYXlpbmcvYXMtamF2YXNjcmlwdC1kYXRlL1xuICovXG5mdW5jdGlvbiBkYXRldGltZUdyb3VwRm4gKHBhcnRpdGlvbikge1xuICB2YXIgdGltZVN0ZXAgPSB1dGlsLmdldERhdGV0aW1lUmVzb2x1dGlvbihwYXJ0aXRpb24ubWludmFsLCBwYXJ0aXRpb24ubWF4dmFsKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgaWYgKGQgPT09IG1pc3ZhbCkge1xuICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICB9XG4gICAgaWYgKGQuaXNCZWZvcmUocGFydGl0aW9uLm1pbnZhbCkgfHwgZC5pc0FmdGVyKHBhcnRpdGlvbi5tYXh2YWwpKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgICB2YXIgZ3JvdXBlZCA9IG1vbWVudChkKS5zdGFydE9mKHRpbWVTdGVwKS5mb3JtYXQoKTtcbiAgICByZXR1cm4gZ3JvdXBlZDtcbiAgfTtcbn1cblxuLypcbiAqIFJvdW5kIHRoZSBkdXJhdGlvbiB0byB0aGUgc3BlY2lmaWVkIHJlc29sdXRpb25cbiAqL1xuZnVuY3Rpb24gZHVyYXRpb25Hcm91cEZuIChwYXJ0aXRpb24pIHtcbiAgdmFyIHRpbWVTdGVwID0gdXRpbC5nZXREdXJhdGlvblJlc29sdXRpb24ocGFydGl0aW9uLm1pbnZhbCwgcGFydGl0aW9uLm1heHZhbCk7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfVxuICAgIGlmIChkIDwgcGFydGl0aW9uLm1pbnZhbCB8fCBkID4gcGFydGl0aW9uLm1heHZhbCkge1xuICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICB9XG4gICAgdmFyIHJvdW5kZWQgPSBNYXRoLmZsb29yKHBhcnNlRmxvYXQoZC5hcyh0aW1lU3RlcCkpKTtcbiAgICByZXR1cm4gbW9tZW50LmR1cmF0aW9uKHJvdW5kZWQsIHRpbWVTdGVwKS50b0lTT1N0cmluZygpO1xuICB9O1xufVxuXG4vKlxuICogRG9uJ3QgZG8gYW55IGdyb3VwaW5nOyB0aGF0IGlzIGRvbmUgaW4gdGhlIHN0ZXAgZnJvbSBiYXNlIHZhbHVlIHRvIHZhbHVlLlxuICogTWF0Y2hpbmcgb2YgZmFjZXQgdmFsdWUgYW5kIGdyb3VwIGNvdWxkIGxlYWQgdG8gYSBkaWZmZXJlbnQgb3JkZXJpbmcsXG4gKiB3aGljaCBpcyBub3QgYWxsb3dlZCBieSBjcm9zc2ZpbHRlclxuICovXG5mdW5jdGlvbiBjYXRlZ29yaWFsR3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkgeyByZXR1cm4gZDsgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBncm91cGVkIHZhbHVlIGZvciBhIHRyYW5zZm9ybWVkIHZhbHVlXG4gKlxuICogQGNhbGxiYWNrIGdyb3VwQ0JcbiAqIEBwYXJhbSB7T2JqZWN0fSBkIFRyYW5zZm9ybWVkIHZhbHVlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBHcm91cFxuICovXG5cbi8qKlxuICogQ3JlYXRlIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBncm91cCB2YWx1ZSBmb3IgYSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEByZXR1cm5zIHtjYn0gR3JvdXAgZnVuY3Rpb24gZm9yIHRoaXMgcGFydGl0aW9uLCB0YWtpbmcgYSBgRGF0YWBcbiAqL1xuZnVuY3Rpb24gZ3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIGlmIChwYXJ0aXRpb24uaXNDb25zdGFudCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7IHJldHVybiAnMSc7IH07XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzQ29udGludW91cykge1xuICAgIHJldHVybiBjb250aW51b3VzR3JvdXBGbihwYXJ0aXRpb24pO1xuICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwpIHtcbiAgICByZXR1cm4gY2F0ZWdvcmlhbEdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNEYXRldGltZSkge1xuICAgIHJldHVybiBkYXRldGltZUdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNEdXJhdGlvbikge1xuICAgIHJldHVybiBkdXJhdGlvbkdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNUZXh0KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7IHJldHVybiBkLnRvU3RyaW5nKCk7IH07XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS5lcnJvcignR3JvdXAgZnVuY3Rpb24gbm90IGltcGxlbWVudGVkIGZvciBwYXJ0aXRpb24nLCBwYXJ0aXRpb24pO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICByYXdWYWx1ZUZuOiByYXdWYWx1ZUZuLFxuICBiYXNlVmFsdWVGbjogYmFzZVZhbHVlRm4sXG4gIHZhbHVlRm46IHZhbHVlRm4sXG4gIGdyb3VwRm46IGdyb3VwRm4sXG5cbiAgcmVkdWNlRm46IHJlZHVjZUZuXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///adfa\n")},b123:function(module,exports,__webpack_require__){eval("/**\n * DurationTransfrom defines a transformation on duration data\n *\n * @class DurationTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Units of the duration\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    units: ['string', true, 'ISO8601'],\n\n    /**\n     * For durations, transforms duration to these units\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    transformedUnits: ['string', true, 'ISO8601'],\n\n    /**\n     * Transform the date to this timezone.\n     *\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedZone: ['string', true, 'ISO8601'],\n\n    /**\n     * Controls conversion to datetime by adding this date\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    transformedReference: 'string'\n  },\n  derived: {\n    /**\n     * Reference momentjs for duration <-> datetime conversion\n     *\n     * @type {moment}\n     * @memberof! DurationTransform\n     */\n    referenceMoment: {\n      deps: ['transformedReference', 'transformedZone'],\n      fn: function () {\n        var tz;\n        if (this.transformedZone === 'ISO8601') {\n          tz = moment.tz.guess();\n        } else {\n          var timeZone = util.timeZones.get(this.transformedZone, 'description');\n          if (timeZone && timeZone.format) {\n            tz = timeZone.format;\n          } else {\n            tz = moment.tz.guess();\n          }\n        }\n\n        if (this.transformedReference) {\n          return moment.tz(this.transformedReference, tz);\n        }\n        return null;\n      }\n    },\n    /**\n     * The type of the facet after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DurationTransform\n     */\n    transformedType: {\n      deps: ['transformedFormat', 'transformedReference', 'transformedZone'],\n      fn: function () {\n        if (this.referenceMoment) {\n          return 'datetime';\n        } else if (this.transformedUnits !== 'ISO8601') {\n          return 'continuous';\n        } else {\n          return 'duration';\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minium value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMin: {\n      deps: ['transformedType'],\n      fn: function () {\n        var facet = this.parent;\n        if (this.transformedType === 'datetime') {\n          return this.transform(facet.minval);\n        } else if (this.transformedType === 'continuous') {\n          return this.transform(facet.minval);\n        } else {\n          return facet.minval;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMax: {\n      deps: ['transformedType'],\n      fn: function () {\n        var facet = this.parent;\n        if (this.transformedType === 'datetime') {\n          return this.transform(facet.maxval);\n        } else if (this.transformedType === 'continuous') {\n          return this.transform(facet.maxval);\n        } else {\n          return facet.maxval;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n\n  /**\n   * Apply the configured transformation to this Facet's value\n   *\n   * @function\n   * @memberof! DurationTransform\n   * @param {Object} inval momentjs duration\n   * @returns {Object} outval momentjs duration or datetime\n   */\n  transform: function transform (inval) {\n    var units;\n    if (this.referenceMoment) {\n      // duration -> datetime\n      return this.referenceMoment.clone().add(inval);\n    } else if (this.transformedUnits !== 'ISO8601') {\n      // duration -> continuous\n      units = util.durationUnits.get(this.transformedUnits, 'description').momentFormat;\n      return inval.as(units);\n    } else {\n      // no change\n      return inval;\n    }\n  },\n  reset: function () {\n    this.unset(['zone', 'transformedFormat', 'transformedZone', 'transformedReference']);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjEyMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvZHVyYXRpb24tdHJhbnNmb3JtLmpzPzJkZjUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEdXJhdGlvblRyYW5zZnJvbSBkZWZpbmVzIGEgdHJhbnNmb3JtYXRpb24gb24gZHVyYXRpb24gZGF0YVxuICpcbiAqIEBjbGFzcyBEdXJhdGlvblRyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC90aW1lJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBVbml0cyBvZiB0aGUgZHVyYXRpb25cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHVuaXRzOiBbJ3N0cmluZycsIHRydWUsICdJU084NjAxJ10sXG5cbiAgICAvKipcbiAgICAgKiBGb3IgZHVyYXRpb25zLCB0cmFuc2Zvcm1zIGR1cmF0aW9uIHRvIHRoZXNlIHVuaXRzXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFVuaXRzOiBbJ3N0cmluZycsIHRydWUsICdJU084NjAxJ10sXG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm0gdGhlIGRhdGUgdG8gdGhpcyB0aW1lem9uZS5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkWm9uZTogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogQ29udHJvbHMgY29udmVyc2lvbiB0byBkYXRldGltZSBieSBhZGRpbmcgdGhpcyBkYXRlXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFJlZmVyZW5jZTogJ3N0cmluZydcbiAgfSxcbiAgZGVyaXZlZDoge1xuICAgIC8qKlxuICAgICAqIFJlZmVyZW5jZSBtb21lbnRqcyBmb3IgZHVyYXRpb24gPC0+IGRhdGV0aW1lIGNvbnZlcnNpb25cbiAgICAgKlxuICAgICAqIEB0eXBlIHttb21lbnR9XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblRyYW5zZm9ybVxuICAgICAqL1xuICAgIHJlZmVyZW5jZU1vbWVudDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZFJlZmVyZW5jZScsICd0cmFuc2Zvcm1lZFpvbmUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0ejtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRab25lID09PSAnSVNPODYwMScpIHtcbiAgICAgICAgICB0eiA9IG1vbWVudC50ei5ndWVzcygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciB0aW1lWm9uZSA9IHV0aWwudGltZVpvbmVzLmdldCh0aGlzLnRyYW5zZm9ybWVkWm9uZSwgJ2Rlc2NyaXB0aW9uJyk7XG4gICAgICAgICAgaWYgKHRpbWVab25lICYmIHRpbWVab25lLmZvcm1hdCkge1xuICAgICAgICAgICAgdHogPSB0aW1lWm9uZS5mb3JtYXQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHR6ID0gbW9tZW50LnR6Lmd1ZXNzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXR1cm4gbW9tZW50LnR6KHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UsIHR6KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBmYWNldCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRUeXBlOiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkRm9ybWF0JywgJ3RyYW5zZm9ybWVkUmVmZXJlbmNlJywgJ3RyYW5zZm9ybWVkWm9uZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMucmVmZXJlbmNlTW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuICdkYXRldGltZSc7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy50cmFuc2Zvcm1lZFVuaXRzICE9PSAnSVNPODYwMScpIHtcbiAgICAgICAgICByZXR1cm4gJ2NvbnRpbnVvdXMnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiAnZHVyYXRpb24nO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWluaXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1pbjoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmYWNldCA9IHRoaXMucGFyZW50O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0oZmFjZXQubWludmFsKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2NvbnRpbnVvdXMnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKGZhY2V0Lm1pbnZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGZhY2V0Lm1pbnZhbDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWF4OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZhY2V0ID0gdGhpcy5wYXJlbnQ7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybShmYWNldC5tYXh2YWwpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnY29udGludW91cycpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0oZmFjZXQubWF4dmFsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZmFjZXQubWF4dmFsO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWluaW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNaW5Bc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRNaW4nLCAndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWludmFsID0gdGhpcy50cmFuc2Zvcm1lZE1pbjtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnZGF0ZXRpbWUnKSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC5mb3JtYXQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWludmFsLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1heEFzVGV4dDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZE1heCcsICd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXh2YWwgPSB0aGlzLnRyYW5zZm9ybWVkTWF4O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLmZvcm1hdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogQXBwbHkgdGhlIGNvbmZpZ3VyZWQgdHJhbnNmb3JtYXRpb24gdG8gdGhpcyBGYWNldCdzIHZhbHVlXG4gICAqXG4gICAqIEBmdW5jdGlvblxuICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBpbnZhbCBtb21lbnRqcyBkdXJhdGlvblxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBvdXR2YWwgbW9tZW50anMgZHVyYXRpb24gb3IgZGF0ZXRpbWVcbiAgICovXG4gIHRyYW5zZm9ybTogZnVuY3Rpb24gdHJhbnNmb3JtIChpbnZhbCkge1xuICAgIHZhciB1bml0cztcbiAgICBpZiAodGhpcy5yZWZlcmVuY2VNb21lbnQpIHtcbiAgICAgIC8vIGR1cmF0aW9uIC0+IGRhdGV0aW1lXG4gICAgICByZXR1cm4gdGhpcy5yZWZlcmVuY2VNb21lbnQuY2xvbmUoKS5hZGQoaW52YWwpO1xuICAgIH0gZWxzZSBpZiAodGhpcy50cmFuc2Zvcm1lZFVuaXRzICE9PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIGR1cmF0aW9uIC0+IGNvbnRpbnVvdXNcbiAgICAgIHVuaXRzID0gdXRpbC5kdXJhdGlvblVuaXRzLmdldCh0aGlzLnRyYW5zZm9ybWVkVW5pdHMsICdkZXNjcmlwdGlvbicpLm1vbWVudEZvcm1hdDtcbiAgICAgIHJldHVybiBpbnZhbC5hcyh1bml0cyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG5vIGNoYW5nZVxuICAgICAgcmV0dXJuIGludmFsO1xuICAgIH1cbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVuc2V0KFsnem9uZScsICd0cmFuc2Zvcm1lZEZvcm1hdCcsICd0cmFuc2Zvcm1lZFpvbmUnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///b123\n")},b452:function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar url = __webpack_require__(/*! ./url */ \"780f\");\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar Manager = __webpack_require__(/*! ./manager */ \"1e1f\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client');\n\n/**\n * Module exports.\n */\n\nmodule.exports = exports = lookup;\n\n/**\n * Managers cache.\n */\n\nvar cache = exports.managers = {};\n\n/**\n * Looks up an existing `Manager` for multiplexing.\n * If the user summons:\n *\n *   `io('http://localhost/a');`\n *   `io('http://localhost/b');`\n *\n * We reuse the existing instance based on same scheme/port/host,\n * and we initialize sockets for each namespace.\n *\n * @api public\n */\n\nfunction lookup (uri, opts) {\n  if (typeof uri === 'object') {\n    opts = uri;\n    uri = undefined;\n  }\n\n  opts = opts || {};\n\n  var parsed = url(uri);\n  var source = parsed.source;\n  var id = parsed.id;\n  var path = parsed.path;\n  var sameNamespace = cache[id] && path in cache[id].nsps;\n  var newConnection = opts.forceNew || opts['force new connection'] ||\n                      false === opts.multiplex || sameNamespace;\n\n  var io;\n\n  if (newConnection) {\n    debug('ignoring socket cache for %s', source);\n    io = Manager(source, opts);\n  } else {\n    if (!cache[id]) {\n      debug('new io instance for %s', source);\n      cache[id] = Manager(source, opts);\n    }\n    io = cache[id];\n  }\n  if (parsed.query && !opts.query) {\n    opts.query = parsed.query;\n  } else if (opts && 'object' === typeof opts.query) {\n    opts.query = encodeQueryString(opts.query);\n  }\n  return io.socket(parsed.path, opts);\n}\n/**\n *  Helper method to parse query objects to string.\n * @param {object} query\n * @returns {string}\n */\nfunction encodeQueryString (obj) {\n  var str = [];\n  for (var p in obj) {\n    if (obj.hasOwnProperty(p)) {\n      str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));\n    }\n  }\n  return str.join('&');\n}\n/**\n * Protocol version.\n *\n * @api public\n */\n\nexports.protocol = parser.protocol;\n\n/**\n * `connect`.\n *\n * @param {String} uri\n * @api public\n */\n\nexports.connect = lookup;\n\n/**\n * Expose constructors for standalone build.\n *\n * @api public\n */\n\nexports.Manager = __webpack_require__(/*! ./manager */ \"1e1f\");\nexports.Socket = __webpack_require__(/*! ./socket */ \"4c13\");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjQ1Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvaW5kZXguanM/ZjQyZiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgdXJsID0gcmVxdWlyZSgnLi91cmwnKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgTWFuYWdlciA9IHJlcXVpcmUoJy4vbWFuYWdlcicpO1xudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnc29ja2V0LmlvLWNsaWVudCcpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGxvb2t1cDtcblxuLyoqXG4gKiBNYW5hZ2VycyBjYWNoZS5cbiAqL1xuXG52YXIgY2FjaGUgPSBleHBvcnRzLm1hbmFnZXJzID0ge307XG5cbi8qKlxuICogTG9va3MgdXAgYW4gZXhpc3RpbmcgYE1hbmFnZXJgIGZvciBtdWx0aXBsZXhpbmcuXG4gKiBJZiB0aGUgdXNlciBzdW1tb25zOlxuICpcbiAqICAgYGlvKCdodHRwOi8vbG9jYWxob3N0L2EnKTtgXG4gKiAgIGBpbygnaHR0cDovL2xvY2FsaG9zdC9iJyk7YFxuICpcbiAqIFdlIHJldXNlIHRoZSBleGlzdGluZyBpbnN0YW5jZSBiYXNlZCBvbiBzYW1lIHNjaGVtZS9wb3J0L2hvc3QsXG4gKiBhbmQgd2UgaW5pdGlhbGl6ZSBzb2NrZXRzIGZvciBlYWNoIG5hbWVzcGFjZS5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGxvb2t1cCAodXJpLCBvcHRzKSB7XG4gIGlmICh0eXBlb2YgdXJpID09PSAnb2JqZWN0Jykge1xuICAgIG9wdHMgPSB1cmk7XG4gICAgdXJpID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgdmFyIHBhcnNlZCA9IHVybCh1cmkpO1xuICB2YXIgc291cmNlID0gcGFyc2VkLnNvdXJjZTtcbiAgdmFyIGlkID0gcGFyc2VkLmlkO1xuICB2YXIgcGF0aCA9IHBhcnNlZC5wYXRoO1xuICB2YXIgc2FtZU5hbWVzcGFjZSA9IGNhY2hlW2lkXSAmJiBwYXRoIGluIGNhY2hlW2lkXS5uc3BzO1xuICB2YXIgbmV3Q29ubmVjdGlvbiA9IG9wdHMuZm9yY2VOZXcgfHwgb3B0c1snZm9yY2UgbmV3IGNvbm5lY3Rpb24nXSB8fFxuICAgICAgICAgICAgICAgICAgICAgIGZhbHNlID09PSBvcHRzLm11bHRpcGxleCB8fCBzYW1lTmFtZXNwYWNlO1xuXG4gIHZhciBpbztcblxuICBpZiAobmV3Q29ubmVjdGlvbikge1xuICAgIGRlYnVnKCdpZ25vcmluZyBzb2NrZXQgY2FjaGUgZm9yICVzJywgc291cmNlKTtcbiAgICBpbyA9IE1hbmFnZXIoc291cmNlLCBvcHRzKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoIWNhY2hlW2lkXSkge1xuICAgICAgZGVidWcoJ25ldyBpbyBpbnN0YW5jZSBmb3IgJXMnLCBzb3VyY2UpO1xuICAgICAgY2FjaGVbaWRdID0gTWFuYWdlcihzb3VyY2UsIG9wdHMpO1xuICAgIH1cbiAgICBpbyA9IGNhY2hlW2lkXTtcbiAgfVxuICBpZiAocGFyc2VkLnF1ZXJ5ICYmICFvcHRzLnF1ZXJ5KSB7XG4gICAgb3B0cy5xdWVyeSA9IHBhcnNlZC5xdWVyeTtcbiAgfSBlbHNlIGlmIChvcHRzICYmICdvYmplY3QnID09PSB0eXBlb2Ygb3B0cy5xdWVyeSkge1xuICAgIG9wdHMucXVlcnkgPSBlbmNvZGVRdWVyeVN0cmluZyhvcHRzLnF1ZXJ5KTtcbiAgfVxuICByZXR1cm4gaW8uc29ja2V0KHBhcnNlZC5wYXRoLCBvcHRzKTtcbn1cbi8qKlxuICogIEhlbHBlciBtZXRob2QgdG8gcGFyc2UgcXVlcnkgb2JqZWN0cyB0byBzdHJpbmcuXG4gKiBAcGFyYW0ge29iamVjdH0gcXVlcnlcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGVuY29kZVF1ZXJ5U3RyaW5nIChvYmopIHtcbiAgdmFyIHN0ciA9IFtdO1xuICBmb3IgKHZhciBwIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkocCkpIHtcbiAgICAgIHN0ci5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChwKSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChvYmpbcF0pKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0ci5qb2luKCcmJyk7XG59XG4vKipcbiAqIFByb3RvY29sIHZlcnNpb24uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sO1xuXG4vKipcbiAqIGBjb25uZWN0YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJpXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuY29ubmVjdCA9IGxvb2t1cDtcblxuLyoqXG4gKiBFeHBvc2UgY29uc3RydWN0b3JzIGZvciBzdGFuZGFsb25lIGJ1aWxkLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5NYW5hZ2VyID0gcmVxdWlyZSgnLi9tYW5hZ2VyJyk7XG5leHBvcnRzLlNvY2tldCA9IHJlcXVpcmUoJy4vc29ja2V0Jyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///b452\n")},ba23:function(module,exports,__webpack_require__){eval("/**\n * Categorial Rule abstracts a single matching rule\n *\n * @class CategorialRule\n */\nvar Base = __webpack_require__(/*! ../util/base */ \"3902\");\n\n// Data structure for mapping categorial (and textual) data on groups\nmodule.exports = Base.extend({\n  props: {\n    /**\n     * string or string format of regexp to match data against.\n     * To use a regular expression, start and end the string with a slash, '/'.\n     * Options can be appedended, notably 'i' for case insensitive matching.\n     * The first captured group can be used in the group, see below.\n     * Examples\n     * 1. 'hello' matches 'hello', not 'hello world'\n     * 2. '/hello/' matches 'hello world', but not 'Hello world'\n     * 3. '/hello/i' matches 'I say Hello'\n     * @type {string}\n     * @memberof! CategorialRule\n     */\n    expression: ['string', true, 'Missing'],\n\n    /**\n     * Number of items this transform is used\n     * @type {number}\n     * @memberof! CategorialRule\n     */\n    count: ['number', true, 0],\n\n    /**\n     * Name of the group this is mapped to. The special substring $1 is replaced by the first captured group,\n     * in example 4 above, with group set to 'He says $1', the match results in 'He says goodbye'\n     * @type {string}\n     * @memberof! CategorialRule\n     */\n    group: ['string', true, 'Missing']\n  },\n  derived: {\n\n    /**\n     * Match function\n     * @memberof! CategorialRule\n     * @function\n     * @param {string} text The text to match\n     * @returns {string|false} group The group label if matching, else false\n     */\n    match: {\n      deps: ['expression', 'group'],\n      fn: function () {\n        var that = this;\n\n        var reFormat = new RegExp(/^\\/(.*)\\/([gimuy]*)$/);\n        var match = reFormat.exec(that.expression);\n\n        if (match) {\n          // if the expression is in the form of /<text>/<flags>, it is a regular expression, compile it\n          var exp = RegExp(match[1], match[2]);\n          return function (text) {\n            var m = exp.exec(text);\n            if (m) {\n              return that.group;\n              // return that.group.replace('$1', m[1]);\n            } else {\n              return false;\n            }\n          };\n        } else {\n          // otherwise do matching using '==='\n          return function (text) {\n            if (text === that.expression) {\n              return that.group;\n            } else {\n              return false;\n            }\n          };\n        }\n      }\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmEyMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY2F0ZWdvcmlhbC1ydWxlLmpzP2UxNzMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDYXRlZ29yaWFsIFJ1bGUgYWJzdHJhY3RzIGEgc2luZ2xlIG1hdGNoaW5nIHJ1bGVcbiAqXG4gKiBAY2xhc3MgQ2F0ZWdvcmlhbFJ1bGVcbiAqL1xudmFyIEJhc2UgPSByZXF1aXJlKCcuLi91dGlsL2Jhc2UnKTtcblxuLy8gRGF0YSBzdHJ1Y3R1cmUgZm9yIG1hcHBpbmcgY2F0ZWdvcmlhbCAoYW5kIHRleHR1YWwpIGRhdGEgb24gZ3JvdXBzXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2UuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBzdHJpbmcgb3Igc3RyaW5nIGZvcm1hdCBvZiByZWdleHAgdG8gbWF0Y2ggZGF0YSBhZ2FpbnN0LlxuICAgICAqIFRvIHVzZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbiwgc3RhcnQgYW5kIGVuZCB0aGUgc3RyaW5nIHdpdGggYSBzbGFzaCwgJy8nLlxuICAgICAqIE9wdGlvbnMgY2FuIGJlIGFwcGVkZW5kZWQsIG5vdGFibHkgJ2knIGZvciBjYXNlIGluc2Vuc2l0aXZlIG1hdGNoaW5nLlxuICAgICAqIFRoZSBmaXJzdCBjYXB0dXJlZCBncm91cCBjYW4gYmUgdXNlZCBpbiB0aGUgZ3JvdXAsIHNlZSBiZWxvdy5cbiAgICAgKiBFeGFtcGxlc1xuICAgICAqIDEuICdoZWxsbycgbWF0Y2hlcyAnaGVsbG8nLCBub3QgJ2hlbGxvIHdvcmxkJ1xuICAgICAqIDIuICcvaGVsbG8vJyBtYXRjaGVzICdoZWxsbyB3b3JsZCcsIGJ1dCBub3QgJ0hlbGxvIHdvcmxkJ1xuICAgICAqIDMuICcvaGVsbG8vaScgbWF0Y2hlcyAnSSBzYXkgSGVsbG8nXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIENhdGVnb3JpYWxSdWxlXG4gICAgICovXG4gICAgZXhwcmVzc2lvbjogWydzdHJpbmcnLCB0cnVlLCAnTWlzc2luZyddLFxuXG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIGl0ZW1zIHRoaXMgdHJhbnNmb3JtIGlzIHVzZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ2F0ZWdvcmlhbFJ1bGVcbiAgICAgKi9cbiAgICBjb3VudDogWydudW1iZXInLCB0cnVlLCAwXSxcblxuICAgIC8qKlxuICAgICAqIE5hbWUgb2YgdGhlIGdyb3VwIHRoaXMgaXMgbWFwcGVkIHRvLiBUaGUgc3BlY2lhbCBzdWJzdHJpbmcgJDEgaXMgcmVwbGFjZWQgYnkgdGhlIGZpcnN0IGNhcHR1cmVkIGdyb3VwLFxuICAgICAqIGluIGV4YW1wbGUgNCBhYm92ZSwgd2l0aCBncm91cCBzZXQgdG8gJ0hlIHNheXMgJDEnLCB0aGUgbWF0Y2ggcmVzdWx0cyBpbiAnSGUgc2F5cyBnb29kYnllJ1xuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQG1lbWJlcm9mISBDYXRlZ29yaWFsUnVsZVxuICAgICAqL1xuICAgIGdyb3VwOiBbJ3N0cmluZycsIHRydWUsICdNaXNzaW5nJ11cbiAgfSxcbiAgZGVyaXZlZDoge1xuXG4gICAgLyoqXG4gICAgICogTWF0Y2ggZnVuY3Rpb25cbiAgICAgKiBAbWVtYmVyb2YhIENhdGVnb3JpYWxSdWxlXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgVGhlIHRleHQgdG8gbWF0Y2hcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfGZhbHNlfSBncm91cCBUaGUgZ3JvdXAgbGFiZWwgaWYgbWF0Y2hpbmcsIGVsc2UgZmFsc2VcbiAgICAgKi9cbiAgICBtYXRjaDoge1xuICAgICAgZGVwczogWydleHByZXNzaW9uJywgJ2dyb3VwJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHJlRm9ybWF0ID0gbmV3IFJlZ0V4cCgvXlxcLyguKilcXC8oW2dpbXV5XSopJC8pO1xuICAgICAgICB2YXIgbWF0Y2ggPSByZUZvcm1hdC5leGVjKHRoYXQuZXhwcmVzc2lvbik7XG5cbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgLy8gaWYgdGhlIGV4cHJlc3Npb24gaXMgaW4gdGhlIGZvcm0gb2YgLzx0ZXh0Pi88ZmxhZ3M+LCBpdCBpcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiwgY29tcGlsZSBpdFxuICAgICAgICAgIHZhciBleHAgPSBSZWdFeHAobWF0Y2hbMV0sIG1hdGNoWzJdKTtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHRleHQpIHtcbiAgICAgICAgICAgIHZhciBtID0gZXhwLmV4ZWModGV4dCk7XG4gICAgICAgICAgICBpZiAobSkge1xuICAgICAgICAgICAgICByZXR1cm4gdGhhdC5ncm91cDtcbiAgICAgICAgICAgICAgLy8gcmV0dXJuIHRoYXQuZ3JvdXAucmVwbGFjZSgnJDEnLCBtWzFdKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG90aGVyd2lzZSBkbyBtYXRjaGluZyB1c2luZyAnPT09J1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICAgICAgaWYgKHRleHQgPT09IHRoYXQuZXhwcmVzc2lvbikge1xuICAgICAgICAgICAgICByZXR1cm4gdGhhdC5ncm91cDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///ba23\n")},bb16:function(module,exports,__webpack_require__){eval("\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = debug;\nexports.coerce = coerce;\nexports.disable = disable;\nexports.enable = enable;\nexports.enabled = enabled;\nexports.humanize = __webpack_require__(/*! ms */ \"1ed2\");\n\n/**\n * The currently active debug mode names, and names to skip.\n */\n\nexports.names = [];\nexports.skips = [];\n\n/**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lowercased letter, i.e. \"n\".\n */\n\nexports.formatters = {};\n\n/**\n * Previously assigned color.\n */\n\nvar prevColor = 0;\n\n/**\n * Previous log timestamp.\n */\n\nvar prevTime;\n\n/**\n * Select a color.\n *\n * @return {Number}\n * @api private\n */\n\nfunction selectColor() {\n  return exports.colors[prevColor++ % exports.colors.length];\n}\n\n/**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\nfunction debug(namespace) {\n\n  // define the `disabled` version\n  function disabled() {\n  }\n  disabled.enabled = false;\n\n  // define the `enabled` version\n  function enabled() {\n\n    var self = enabled;\n\n    // set `diff` timestamp\n    var curr = +new Date();\n    var ms = curr - (prevTime || curr);\n    self.diff = ms;\n    self.prev = prevTime;\n    self.curr = curr;\n    prevTime = curr;\n\n    // add the `color` if not set\n    if (null == self.useColors) self.useColors = exports.useColors();\n    if (null == self.color && self.useColors) self.color = selectColor();\n\n    var args = Array.prototype.slice.call(arguments);\n\n    args[0] = exports.coerce(args[0]);\n\n    if ('string' !== typeof args[0]) {\n      // anything else let's inspect with %o\n      args = ['%o'].concat(args);\n    }\n\n    // apply any `formatters` transformations\n    var index = 0;\n    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {\n      // if we encounter an escaped % then don't increase the array index\n      if (match === '%%') return match;\n      index++;\n      var formatter = exports.formatters[format];\n      if ('function' === typeof formatter) {\n        var val = args[index];\n        match = formatter.call(self, val);\n\n        // now we need to remove `args[index]` since it's inlined in the `format`\n        args.splice(index, 1);\n        index--;\n      }\n      return match;\n    });\n\n    if ('function' === typeof exports.formatArgs) {\n      args = exports.formatArgs.apply(self, args);\n    }\n    var logFn = enabled.log || exports.log || console.log.bind(console);\n    logFn.apply(self, args);\n  }\n  enabled.enabled = true;\n\n  var fn = exports.enabled(namespace) ? enabled : disabled;\n\n  fn.namespace = namespace;\n\n  return fn;\n}\n\n/**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\nfunction enable(namespaces) {\n  exports.save(namespaces);\n\n  var split = (namespaces || '').split(/[\\s,]+/);\n  var len = split.length;\n\n  for (var i = 0; i < len; i++) {\n    if (!split[i]) continue; // ignore empty strings\n    namespaces = split[i].replace(/\\*/g, '.*?');\n    if (namespaces[0] === '-') {\n      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n    } else {\n      exports.names.push(new RegExp('^' + namespaces + '$'));\n    }\n  }\n}\n\n/**\n * Disable debug output.\n *\n * @api public\n */\n\nfunction disable() {\n  exports.enable('');\n}\n\n/**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\nfunction enabled(name) {\n  var i, len;\n  for (i = 0, len = exports.skips.length; i < len; i++) {\n    if (exports.skips[i].test(name)) {\n      return false;\n    }\n  }\n  for (i = 0, len = exports.names.length; i < len; i++) {\n    if (exports.names[i].test(name)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\nfunction coerce(val) {\n  if (val instanceof Error) return val.stack || val.message;\n  return val;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmIxNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvZGVidWcvZGVidWcuanM/NTJhNyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogVGhpcyBpcyB0aGUgY29tbW9uIGxvZ2ljIGZvciBib3RoIHRoZSBOb2RlLmpzIGFuZCB3ZWIgYnJvd3NlclxuICogaW1wbGVtZW50YXRpb25zIG9mIGBkZWJ1ZygpYC5cbiAqXG4gKiBFeHBvc2UgYGRlYnVnKClgIGFzIHRoZSBtb2R1bGUuXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZGVidWc7XG5leHBvcnRzLmNvZXJjZSA9IGNvZXJjZTtcbmV4cG9ydHMuZGlzYWJsZSA9IGRpc2FibGU7XG5leHBvcnRzLmVuYWJsZSA9IGVuYWJsZTtcbmV4cG9ydHMuZW5hYmxlZCA9IGVuYWJsZWQ7XG5leHBvcnRzLmh1bWFuaXplID0gcmVxdWlyZSgnbXMnKTtcblxuLyoqXG4gKiBUaGUgY3VycmVudGx5IGFjdGl2ZSBkZWJ1ZyBtb2RlIG5hbWVzLCBhbmQgbmFtZXMgdG8gc2tpcC5cbiAqL1xuXG5leHBvcnRzLm5hbWVzID0gW107XG5leHBvcnRzLnNraXBzID0gW107XG5cbi8qKlxuICogTWFwIG9mIHNwZWNpYWwgXCIlblwiIGhhbmRsaW5nIGZ1bmN0aW9ucywgZm9yIHRoZSBkZWJ1ZyBcImZvcm1hdFwiIGFyZ3VtZW50LlxuICpcbiAqIFZhbGlkIGtleSBuYW1lcyBhcmUgYSBzaW5nbGUsIGxvd2VyY2FzZWQgbGV0dGVyLCBpLmUuIFwiblwiLlxuICovXG5cbmV4cG9ydHMuZm9ybWF0dGVycyA9IHt9O1xuXG4vKipcbiAqIFByZXZpb3VzbHkgYXNzaWduZWQgY29sb3IuXG4gKi9cblxudmFyIHByZXZDb2xvciA9IDA7XG5cbi8qKlxuICogUHJldmlvdXMgbG9nIHRpbWVzdGFtcC5cbiAqL1xuXG52YXIgcHJldlRpbWU7XG5cbi8qKlxuICogU2VsZWN0IGEgY29sb3IuXG4gKlxuICogQHJldHVybiB7TnVtYmVyfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2VsZWN0Q29sb3IoKSB7XG4gIHJldHVybiBleHBvcnRzLmNvbG9yc1twcmV2Q29sb3IrKyAlIGV4cG9ydHMuY29sb3JzLmxlbmd0aF07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgZGVidWdnZXIgd2l0aCB0aGUgZ2l2ZW4gYG5hbWVzcGFjZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlYnVnKG5hbWVzcGFjZSkge1xuXG4gIC8vIGRlZmluZSB0aGUgYGRpc2FibGVkYCB2ZXJzaW9uXG4gIGZ1bmN0aW9uIGRpc2FibGVkKCkge1xuICB9XG4gIGRpc2FibGVkLmVuYWJsZWQgPSBmYWxzZTtcblxuICAvLyBkZWZpbmUgdGhlIGBlbmFibGVkYCB2ZXJzaW9uXG4gIGZ1bmN0aW9uIGVuYWJsZWQoKSB7XG5cbiAgICB2YXIgc2VsZiA9IGVuYWJsZWQ7XG5cbiAgICAvLyBzZXQgYGRpZmZgIHRpbWVzdGFtcFxuICAgIHZhciBjdXJyID0gK25ldyBEYXRlKCk7XG4gICAgdmFyIG1zID0gY3VyciAtIChwcmV2VGltZSB8fCBjdXJyKTtcbiAgICBzZWxmLmRpZmYgPSBtcztcbiAgICBzZWxmLnByZXYgPSBwcmV2VGltZTtcbiAgICBzZWxmLmN1cnIgPSBjdXJyO1xuICAgIHByZXZUaW1lID0gY3VycjtcblxuICAgIC8vIGFkZCB0aGUgYGNvbG9yYCBpZiBub3Qgc2V0XG4gICAgaWYgKG51bGwgPT0gc2VsZi51c2VDb2xvcnMpIHNlbGYudXNlQ29sb3JzID0gZXhwb3J0cy51c2VDb2xvcnMoKTtcbiAgICBpZiAobnVsbCA9PSBzZWxmLmNvbG9yICYmIHNlbGYudXNlQ29sb3JzKSBzZWxmLmNvbG9yID0gc2VsZWN0Q29sb3IoKTtcblxuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgIGFyZ3NbMF0gPSBleHBvcnRzLmNvZXJjZShhcmdzWzBdKTtcblxuICAgIGlmICgnc3RyaW5nJyAhPT0gdHlwZW9mIGFyZ3NbMF0pIHtcbiAgICAgIC8vIGFueXRoaW5nIGVsc2UgbGV0J3MgaW5zcGVjdCB3aXRoICVvXG4gICAgICBhcmdzID0gWyclbyddLmNvbmNhdChhcmdzKTtcbiAgICB9XG5cbiAgICAvLyBhcHBseSBhbnkgYGZvcm1hdHRlcnNgIHRyYW5zZm9ybWF0aW9uc1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgYXJnc1swXSA9IGFyZ3NbMF0ucmVwbGFjZSgvJShbYS16JV0pL2csIGZ1bmN0aW9uKG1hdGNoLCBmb3JtYXQpIHtcbiAgICAgIC8vIGlmIHdlIGVuY291bnRlciBhbiBlc2NhcGVkICUgdGhlbiBkb24ndCBpbmNyZWFzZSB0aGUgYXJyYXkgaW5kZXhcbiAgICAgIGlmIChtYXRjaCA9PT0gJyUlJykgcmV0dXJuIG1hdGNoO1xuICAgICAgaW5kZXgrKztcbiAgICAgIHZhciBmb3JtYXR0ZXIgPSBleHBvcnRzLmZvcm1hdHRlcnNbZm9ybWF0XTtcbiAgICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgZm9ybWF0dGVyKSB7XG4gICAgICAgIHZhciB2YWwgPSBhcmdzW2luZGV4XTtcbiAgICAgICAgbWF0Y2ggPSBmb3JtYXR0ZXIuY2FsbChzZWxmLCB2YWwpO1xuXG4gICAgICAgIC8vIG5vdyB3ZSBuZWVkIHRvIHJlbW92ZSBgYXJnc1tpbmRleF1gIHNpbmNlIGl0J3MgaW5saW5lZCBpbiB0aGUgYGZvcm1hdGBcbiAgICAgICAgYXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBpbmRleC0tO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH0pO1xuXG4gICAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBleHBvcnRzLmZvcm1hdEFyZ3MpIHtcbiAgICAgIGFyZ3MgPSBleHBvcnRzLmZvcm1hdEFyZ3MuYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgfVxuICAgIHZhciBsb2dGbiA9IGVuYWJsZWQubG9nIHx8IGV4cG9ydHMubG9nIHx8IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSk7XG4gICAgbG9nRm4uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbiAgZW5hYmxlZC5lbmFibGVkID0gdHJ1ZTtcblxuICB2YXIgZm4gPSBleHBvcnRzLmVuYWJsZWQobmFtZXNwYWNlKSA/IGVuYWJsZWQgOiBkaXNhYmxlZDtcblxuICBmbi5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7XG5cbiAgcmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgYSBkZWJ1ZyBtb2RlIGJ5IG5hbWVzcGFjZXMuIFRoaXMgY2FuIGluY2x1ZGUgbW9kZXNcbiAqIHNlcGFyYXRlZCBieSBhIGNvbG9uIGFuZCB3aWxkY2FyZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZW5hYmxlKG5hbWVzcGFjZXMpIHtcbiAgZXhwb3J0cy5zYXZlKG5hbWVzcGFjZXMpO1xuXG4gIHZhciBzcGxpdCA9IChuYW1lc3BhY2VzIHx8ICcnKS5zcGxpdCgvW1xccyxdKy8pO1xuICB2YXIgbGVuID0gc3BsaXQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoIXNwbGl0W2ldKSBjb250aW51ZTsgLy8gaWdub3JlIGVtcHR5IHN0cmluZ3NcbiAgICBuYW1lc3BhY2VzID0gc3BsaXRbaV0ucmVwbGFjZSgvXFwqL2csICcuKj8nKTtcbiAgICBpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG4gICAgICBleHBvcnRzLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzLnN1YnN0cigxKSArICckJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzICsgJyQnKSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGlzYWJsZSBkZWJ1ZyBvdXRwdXQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkaXNhYmxlKCkge1xuICBleHBvcnRzLmVuYWJsZSgnJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RlIG5hbWUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGVkKG5hbWUpIHtcbiAgdmFyIGksIGxlbjtcbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLnNraXBzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5uYW1lcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLm5hbWVzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29lcmNlIGB2YWxgLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjb2VyY2UodmFsKSB7XG4gIGlmICh2YWwgaW5zdGFuY2VvZiBFcnJvcikgcmV0dXJuIHZhbC5zdGFjayB8fCB2YWwubWVzc2FnZTtcbiAgcmV0dXJuIHZhbDtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///bb16\n")},bff6:function(module,exports){eval("/**\n * This module defines a single unique missing value indicator.\n * All invalid, absent, or user-indicated missing value is internally set to this value.\n *\n * @example\n * var misval = require('./framework/misval');\n * if ( a === misval ) {\n *   ...\n * }\n * @module client/misval\n */\n\n// module.exports = -Number.MAX_VALUE;\nmodule.exports = 'missing';\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmZmNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9taXN2YWwuanM/YjI3OSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoaXMgbW9kdWxlIGRlZmluZXMgYSBzaW5nbGUgdW5pcXVlIG1pc3NpbmcgdmFsdWUgaW5kaWNhdG9yLlxuICogQWxsIGludmFsaWQsIGFic2VudCwgb3IgdXNlci1pbmRpY2F0ZWQgbWlzc2luZyB2YWx1ZSBpcyBpbnRlcm5hbGx5IHNldCB0byB0aGlzIHZhbHVlLlxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbWlzdmFsID0gcmVxdWlyZSgnLi9mcmFtZXdvcmsvbWlzdmFsJyk7XG4gKiBpZiAoIGEgPT09IG1pc3ZhbCApIHtcbiAqICAgLi4uXG4gKiB9XG4gKiBAbW9kdWxlIGNsaWVudC9taXN2YWxcbiAqL1xuXG4vLyBtb2R1bGUuZXhwb3J0cyA9IC1OdW1iZXIuTUFYX1ZBTFVFO1xubW9kdWxlLmV4cG9ydHMgPSAnbWlzc2luZyc7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///bff6\n")},c59b:function(module,exports,__webpack_require__){eval('\nmodule.exports = __webpack_require__(/*! ./lib/index */ "58ab");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYzU5Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9pbmRleC5qcz80NmEyIl0sInNvdXJjZXNDb250ZW50IjpbIlxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9pbmRleCcpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///c59b\n')},d45b:function(module,exports,__webpack_require__){eval("var AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar AmpersandColllection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\n/*\n * Time is grouped by truncating; the resolution is determined in util-time.getResolution()\n * See [this table](http://momentjs.com/docs/#/durations/creating/) for accpetable values\n * when using a crossfilter dataset.\n */\nfunction unitsForMilliseconds (milliseconds) {\n  var count = milliseconds;\n  if (count < 10000) { // 10 seconds\n    return 'milliseconds';\n  }\n  count = count / 1000;\n\n  if (count < 15 * 60) { // 15 minutes\n    return 'seconds';\n  }\n  count = count / 60;\n\n  if (count < 3 * 60) { // 3 hours\n    return 'minutes';\n  }\n  count = count / 60;\n\n  if (count < 3 * 24) { // 3 days\n    return 'hours';\n  }\n  count = count / 24;\n\n  if (count < 3 * 7) { // 3 weeks\n    return 'days';\n  }\n  if (count < 7 * 52) { // 52 weeks\n    return 'weeks';\n  }\n  if (count < 2 * 365) { // 2 years\n    return 'months';\n  }\n  return 'years';\n}\n\nfunction getFormat (units) {\n  var fmt;\n  if (units === 'seconds') {\n    fmt = 'mm:ss';\n  } else if (units === 'minutes') {\n    fmt = 'HH:mm';\n  } else if (units === 'hours') {\n    fmt = 'HH:00';\n  } else if (units === 'days') {\n    fmt = 'dddd do';\n  } else if (units === 'weeks') {\n    fmt = 'wo';\n  } else if (units === 'months') {\n    fmt = 'YY MMM';\n  } else if (units === 'years') {\n    fmt = 'YYYY';\n  }\n  return fmt;\n}\n\nfunction getDatetimeResolution (start, end) {\n  var difference = end.diff(start);\n  return unitsForMilliseconds(difference);\n}\n\nfunction getDurationResolution (min, max) {\n  var length = moment.duration(max.as('milliseconds') - min.as('milliseconds'), 'milliseconds');\n  return unitsForMilliseconds(length);\n}\n\nvar TimePart = AmpersandModel.extend({\n  props: {\n    /**\n     * The format string for momentjs\n     * @memberof! TimePart\n     * @type {string}\n     */\n    momentFormat: ['string', true],\n    /**\n     * The format string for postgresql\n     * @memberof! TimePart\n     * @type {string}\n     */\n    postgresFormat: ['string', true],\n    /**\n     * The human readable descprition of the datetime part\n     * @memberof! TimePart\n     * @type {string}\n     */\n    description: ['string', true],\n    /**\n     * Data type after conversion: 'continuous', or 'categorial'\n     * @memberof! TimePart\n     * @type {string}\n     */\n    type: ['string', true],\n    /**\n     * For continuous datetime parts (ie, day-of-year), the minimum value\n     * @memberof! TimePart\n     * @type {number}\n     */\n    min: ['number', true, 0],\n    /**\n     * For continuous datetime parts (ie, day-of-year), the maximum value\n     * @memberof! TimePart\n     * @type {number}\n     */\n    max: ['number', true, 1],\n    /**\n     * When true, calculate the minimum and maximum value from the\n     * original datetime limits. Used for continuous datetime parts (ie, year)\n     * @memberof! TimePart\n     * @type {boolean}\n     */\n    calculate: ['boolean', true, false],\n    /**\n     * For categorial datetime parts (Mon, Tue, ..), the array of possible values\n     * @memberof! TimePart\n     * @type {String[]}\n     */\n    groups: ['array']\n  }\n});\n\nvar TimeParts = AmpersandColllection.extend({\n  model: TimePart,\n  indexes: ['description']\n});\n\nvar timeParts = new TimeParts([\n  { description: 'ISO8601', type: 'datetime', calculate: true },\n  { postgresFormat: 'month', momentFormat: 'M', description: 'Month (1-12)', type: 'continuous', min: 1, max: 12 },\n  { postgresFormat: 'quarter', momentFormat: 'Q', description: 'Quarter (1-4)', type: 'continuous', min: 1, max: 4 },\n  { postgresFormat: 'day', momentFormat: 'D', description: 'Day of Month  (1-31)', type: 'continuous', min: 1, max: 31 },\n  { postgresFormat: 'doy', momentFormat: 'DDD', description: 'Day of Year (1-365)', type: 'continuous', min: 1, max: 365 },\n  { postgresFormat: 'dow', momentFormat: 'd', description: 'Day of Week (0-6)', type: 'continuous', min: 0, max: 6 },\n  { postgresFormat: 'isodow', momentFormat: 'E', description: 'Day of Week ISO (1-7)', type: 'continuous', min: 1, max: 7 },\n  { postgresFormat: 'week', momentFormat: 'W', description: 'Week of Year ISO  (1-53)', type: 'continuous', min: 1, max: 53 },\n  { postgresFormat: 'year', momentFormat: 'Y', description: 'Year', type: 'continuous', calculate: true },\n  { postgresFormat: 'hours', momentFormat: 'H', description: 'Hour (0-23)', type: 'continuous', min: 0, max: 23 },\n  { postgresFormat: 'minute', momentFormat: 'm', description: 'Minute (0-59)', type: 'continuous', min: 0, max: 59 },\n  { postgresFormat: 'second', momentFormat: 's', description: 'Second (0-59)', type: 'continuous', min: 0, max: 59 },\n  { postgresFormat: 'milliseconds', momentFormat: 'SSS', description: 'Milliseconds (0-999)', type: 'continuous', min: 0, max: 999 },\n  { postgresFormat: 'microseconds', momentFormat: 'SSSSSS', description: 'microseconds (0-999999)', type: 'continuous', min: 0, max: 999999 },\n  { postgresFormat: 'epoch', momentFormat: 'X', description: 'Unix Timestamp', type: 'continuous', calculate: true },\n  { postgresFormat: 'Mon', momentFormat: 'MMM', description: 'Month (Jan - Dec)', type: 'categorial', groups: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] },\n  { postgresFormat: 'Month', momentFormat: 'MMMM', description: 'Month (January - December)', type: 'categorial', groups: ['January', 'Feburary', 'March', 'April', 'May', 'June', 'July', 'August', 'Septebmer', 'October', 'November', 'December'] },\n  { postgresFormat: 'Dy', momentFormat: 'ddd', description: 'Day of Week (Sun-Sat)', type: 'categorial', groups: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] },\n  { postgresFormat: 'Day', momentFormat: 'dddd', description: 'Day of Week (Sunday-Saturday)', type: 'categorial', groups: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] },\n  { postgresFormat: 'AM', momentFormat: 'A', description: 'AM/PM', type: 'categorial', groups: ['AM', 'PM'] }\n]);\n\nvar DurationUnit = AmpersandModel.extend({\n  props: {\n    /**\n     * The descriptive name of the time unit\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    description: ['string'],\n    /**\n     * Momentjs parsing format\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    momentFormat: ['string'],\n    /**\n     * Postgres parsing format\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    postgresFormat: ['string'],\n    /**\n     * Conversion factor to seconds\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    seconds: ['number']\n  }\n});\n\nvar DurationUnits = AmpersandColllection.extend({\n  indexes: ['description'],\n  model: DurationUnit\n});\n\nvar durationUnits = new DurationUnits([\n  {\n    description: 'ISO8601',\n    seconds: 1\n  }, {\n    description: 'millenium',\n    momentFormat: 'millenium',\n    postgresFormat: 'millenium',\n    seconds: 100 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'century',\n    momentFormat: 'century',\n    postgresFormat: 'century',\n    seconds: 100 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'decades',\n    momentFormat: 'decades',\n    postgresFormat: 'decade',\n    seconds: 10 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'years',\n    momentFormat: 'years',\n    postgresFormat: 'year',\n    seconds: 365.25 * 24 * 60 * 60\n  }, {\n    description: 'quarters',\n    momentFormat: '',\n    postgresFormat: 'quarter',\n    seconds: 365.25 * 8 * 60 * 60\n  }, {\n    description: 'months',\n    momentFormat: 'months',\n    postgresFormat: 'month',\n    seconds: 30 * 24 * 60 * 60\n  }, {\n    description: 'weeks',\n    momentFormat: 'weeks',\n    postgresFormat: 'week',\n    seconds: 7 * 24 * 60 * 60\n  }, {\n    description: 'days',\n    momentFormat: 'days',\n    postgresFormat: 'day',\n    seconds: 24 * 60 * 60\n  }, {\n    description: 'hours',\n    momentFormat: 'hours',\n    postgresFormat: 'hour',\n    seconds: 60 * 60\n  }, {\n    description: 'minutes',\n    momentFormat: 'minutes',\n    postgresFormat: 'minute',\n    seconds: 60\n  }, {\n    description: 'seconds',\n    momentFormat: 'seconds',\n    postgresFormat: 'second',\n    seconds: 1\n  }, {\n    description: 'milliseconds',\n    momentFormat: 'milliseconds',\n    postgresFormat: 'milliseconds',\n    seconds: 0.001\n  }, {\n    description: 'microseconds',\n    momentFormat: 'microseconds',\n    postgresFormat: 'microseconds',\n    seconds: 0.000001\n  }\n]);\n\nvar TimeZone = AmpersandModel.extend({\n  props: {\n    /**\n     * The descriptive name of the time zone\n     * @memberof! TimeZone\n     * @type {string}\n     */\n    description: ['string'],\n    /**\n     * The time zone format\n     * @memberof! TimeZone\n     * @type {string}\n     */\n    format: ['string']\n  }\n});\n\nvar TimeZones = AmpersandColllection.extend({\n  indexes: ['description'],\n  model: TimeZone\n});\n\nvar timeZones = new TimeZones();\ntimeZones.add({\n  description: 'ISO8601',\n  format: 'ISO8601'\n});\n\nmoment.tz.names().forEach(function (tz) {\n  timeZones.add({\n    description: tz,\n    format: tz\n  });\n});\n\nmodule.exports = {\n  timeParts: timeParts,\n  timeZones: timeZones,\n  durationUnits: durationUnits,\n  getDatetimeResolution: getDatetimeResolution,\n  getDurationResolution: getDurationResolution,\n  getFormat: getFormat\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZDQ1Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC90aW1lLmpzP2ExMzkiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIEFtcGVyc2FuZE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG52YXIgQW1wZXJzYW5kQ29sbGxlY3Rpb24gPSByZXF1aXJlKCdhbXBlcnNhbmQtY29sbGVjdGlvbicpO1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xuXG4vKlxuICogVGltZSBpcyBncm91cGVkIGJ5IHRydW5jYXRpbmc7IHRoZSByZXNvbHV0aW9uIGlzIGRldGVybWluZWQgaW4gdXRpbC10aW1lLmdldFJlc29sdXRpb24oKVxuICogU2VlIFt0aGlzIHRhYmxlXShodHRwOi8vbW9tZW50anMuY29tL2RvY3MvIy9kdXJhdGlvbnMvY3JlYXRpbmcvKSBmb3IgYWNjcGV0YWJsZSB2YWx1ZXNcbiAqIHdoZW4gdXNpbmcgYSBjcm9zc2ZpbHRlciBkYXRhc2V0LlxuICovXG5mdW5jdGlvbiB1bml0c0Zvck1pbGxpc2Vjb25kcyAobWlsbGlzZWNvbmRzKSB7XG4gIHZhciBjb3VudCA9IG1pbGxpc2Vjb25kcztcbiAgaWYgKGNvdW50IDwgMTAwMDApIHsgLy8gMTAgc2Vjb25kc1xuICAgIHJldHVybiAnbWlsbGlzZWNvbmRzJztcbiAgfVxuICBjb3VudCA9IGNvdW50IC8gMTAwMDtcblxuICBpZiAoY291bnQgPCAxNSAqIDYwKSB7IC8vIDE1IG1pbnV0ZXNcbiAgICByZXR1cm4gJ3NlY29uZHMnO1xuICB9XG4gIGNvdW50ID0gY291bnQgLyA2MDtcblxuICBpZiAoY291bnQgPCAzICogNjApIHsgLy8gMyBob3Vyc1xuICAgIHJldHVybiAnbWludXRlcyc7XG4gIH1cbiAgY291bnQgPSBjb3VudCAvIDYwO1xuXG4gIGlmIChjb3VudCA8IDMgKiAyNCkgeyAvLyAzIGRheXNcbiAgICByZXR1cm4gJ2hvdXJzJztcbiAgfVxuICBjb3VudCA9IGNvdW50IC8gMjQ7XG5cbiAgaWYgKGNvdW50IDwgMyAqIDcpIHsgLy8gMyB3ZWVrc1xuICAgIHJldHVybiAnZGF5cyc7XG4gIH1cbiAgaWYgKGNvdW50IDwgNyAqIDUyKSB7IC8vIDUyIHdlZWtzXG4gICAgcmV0dXJuICd3ZWVrcyc7XG4gIH1cbiAgaWYgKGNvdW50IDwgMiAqIDM2NSkgeyAvLyAyIHllYXJzXG4gICAgcmV0dXJuICdtb250aHMnO1xuICB9XG4gIHJldHVybiAneWVhcnMnO1xufVxuXG5mdW5jdGlvbiBnZXRGb3JtYXQgKHVuaXRzKSB7XG4gIHZhciBmbXQ7XG4gIGlmICh1bml0cyA9PT0gJ3NlY29uZHMnKSB7XG4gICAgZm10ID0gJ21tOnNzJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ21pbnV0ZXMnKSB7XG4gICAgZm10ID0gJ0hIOm1tJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ2hvdXJzJykge1xuICAgIGZtdCA9ICdISDowMCc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICdkYXlzJykge1xuICAgIGZtdCA9ICdkZGRkIGRvJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ3dlZWtzJykge1xuICAgIGZtdCA9ICd3byc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICdtb250aHMnKSB7XG4gICAgZm10ID0gJ1lZIE1NTSc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICd5ZWFycycpIHtcbiAgICBmbXQgPSAnWVlZWSc7XG4gIH1cbiAgcmV0dXJuIGZtdDtcbn1cblxuZnVuY3Rpb24gZ2V0RGF0ZXRpbWVSZXNvbHV0aW9uIChzdGFydCwgZW5kKSB7XG4gIHZhciBkaWZmZXJlbmNlID0gZW5kLmRpZmYoc3RhcnQpO1xuICByZXR1cm4gdW5pdHNGb3JNaWxsaXNlY29uZHMoZGlmZmVyZW5jZSk7XG59XG5cbmZ1bmN0aW9uIGdldER1cmF0aW9uUmVzb2x1dGlvbiAobWluLCBtYXgpIHtcbiAgdmFyIGxlbmd0aCA9IG1vbWVudC5kdXJhdGlvbihtYXguYXMoJ21pbGxpc2Vjb25kcycpIC0gbWluLmFzKCdtaWxsaXNlY29uZHMnKSwgJ21pbGxpc2Vjb25kcycpO1xuICByZXR1cm4gdW5pdHNGb3JNaWxsaXNlY29uZHMobGVuZ3RoKTtcbn1cblxudmFyIFRpbWVQYXJ0ID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBUaGUgZm9ybWF0IHN0cmluZyBmb3IgbW9tZW50anNcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBtb21lbnRGb3JtYXQ6IFsnc3RyaW5nJywgdHJ1ZV0sXG4gICAgLyoqXG4gICAgICogVGhlIGZvcm1hdCBzdHJpbmcgZm9yIHBvc3RncmVzcWxcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBwb3N0Z3Jlc0Zvcm1hdDogWydzdHJpbmcnLCB0cnVlXSxcbiAgICAvKipcbiAgICAgKiBUaGUgaHVtYW4gcmVhZGFibGUgZGVzY3ByaXRpb24gb2YgdGhlIGRhdGV0aW1lIHBhcnRcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBkZXNjcmlwdGlvbjogWydzdHJpbmcnLCB0cnVlXSxcbiAgICAvKipcbiAgICAgKiBEYXRhIHR5cGUgYWZ0ZXIgY29udmVyc2lvbjogJ2NvbnRpbnVvdXMnLCBvciAnY2F0ZWdvcmlhbCdcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0eXBlOiBbJ3N0cmluZycsIHRydWVdLFxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIGRhdGV0aW1lIHBhcnRzIChpZSwgZGF5LW9mLXllYXIpLCB0aGUgbWluaW11bSB2YWx1ZVxuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIG1pbjogWydudW1iZXInLCB0cnVlLCAwXSxcbiAgICAvKipcbiAgICAgKiBGb3IgY29udGludW91cyBkYXRldGltZSBwYXJ0cyAoaWUsIGRheS1vZi15ZWFyKSwgdGhlIG1heGltdW0gdmFsdWVcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBtYXg6IFsnbnVtYmVyJywgdHJ1ZSwgMV0sXG4gICAgLyoqXG4gICAgICogV2hlbiB0cnVlLCBjYWxjdWxhdGUgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gdmFsdWUgZnJvbSB0aGVcbiAgICAgKiBvcmlnaW5hbCBkYXRldGltZSBsaW1pdHMuIFVzZWQgZm9yIGNvbnRpbnVvdXMgZGF0ZXRpbWUgcGFydHMgKGllLCB5ZWFyKVxuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBjYWxjdWxhdGU6IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXSxcbiAgICAvKipcbiAgICAgKiBGb3IgY2F0ZWdvcmlhbCBkYXRldGltZSBwYXJ0cyAoTW9uLCBUdWUsIC4uKSwgdGhlIGFycmF5IG9mIHBvc3NpYmxlIHZhbHVlc1xuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7U3RyaW5nW119XG4gICAgICovXG4gICAgZ3JvdXBzOiBbJ2FycmF5J11cbiAgfVxufSk7XG5cbnZhciBUaW1lUGFydHMgPSBBbXBlcnNhbmRDb2xsbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogVGltZVBhcnQsXG4gIGluZGV4ZXM6IFsnZGVzY3JpcHRpb24nXVxufSk7XG5cbnZhciB0aW1lUGFydHMgPSBuZXcgVGltZVBhcnRzKFtcbiAgeyBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLCB0eXBlOiAnZGF0ZXRpbWUnLCBjYWxjdWxhdGU6IHRydWUgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ21vbnRoJywgbW9tZW50Rm9ybWF0OiAnTScsIGRlc2NyaXB0aW9uOiAnTW9udGggKDEtMTIpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogMTIgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3F1YXJ0ZXInLCBtb21lbnRGb3JtYXQ6ICdRJywgZGVzY3JpcHRpb246ICdRdWFydGVyICgxLTQpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogNCB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZGF5JywgbW9tZW50Rm9ybWF0OiAnRCcsIGRlc2NyaXB0aW9uOiAnRGF5IG9mIE1vbnRoICAoMS0zMSknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMSwgbWF4OiAzMSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZG95JywgbW9tZW50Rm9ybWF0OiAnREREJywgZGVzY3JpcHRpb246ICdEYXkgb2YgWWVhciAoMS0zNjUpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogMzY1IH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdkb3cnLCBtb21lbnRGb3JtYXQ6ICdkJywgZGVzY3JpcHRpb246ICdEYXkgb2YgV2VlayAoMC02KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDYgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ2lzb2RvdycsIG1vbWVudEZvcm1hdDogJ0UnLCBkZXNjcmlwdGlvbjogJ0RheSBvZiBXZWVrIElTTyAoMS03KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAxLCBtYXg6IDcgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3dlZWsnLCBtb21lbnRGb3JtYXQ6ICdXJywgZGVzY3JpcHRpb246ICdXZWVrIG9mIFllYXIgSVNPICAoMS01MyknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMSwgbWF4OiA1MyB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAneWVhcicsIG1vbWVudEZvcm1hdDogJ1knLCBkZXNjcmlwdGlvbjogJ1llYXInLCB0eXBlOiAnY29udGludW91cycsIGNhbGN1bGF0ZTogdHJ1ZSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnaG91cnMnLCBtb21lbnRGb3JtYXQ6ICdIJywgZGVzY3JpcHRpb246ICdIb3VyICgwLTIzKScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDIzIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdtaW51dGUnLCBtb21lbnRGb3JtYXQ6ICdtJywgZGVzY3JpcHRpb246ICdNaW51dGUgKDAtNTkpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDAsIG1heDogNTkgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3NlY29uZCcsIG1vbWVudEZvcm1hdDogJ3MnLCBkZXNjcmlwdGlvbjogJ1NlY29uZCAoMC01OSknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMCwgbWF4OiA1OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnbWlsbGlzZWNvbmRzJywgbW9tZW50Rm9ybWF0OiAnU1NTJywgZGVzY3JpcHRpb246ICdNaWxsaXNlY29uZHMgKDAtOTk5KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDk5OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnbWljcm9zZWNvbmRzJywgbW9tZW50Rm9ybWF0OiAnU1NTU1NTJywgZGVzY3JpcHRpb246ICdtaWNyb3NlY29uZHMgKDAtOTk5OTk5KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDk5OTk5OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZXBvY2gnLCBtb21lbnRGb3JtYXQ6ICdYJywgZGVzY3JpcHRpb246ICdVbml4IFRpbWVzdGFtcCcsIHR5cGU6ICdjb250aW51b3VzJywgY2FsY3VsYXRlOiB0cnVlIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdNb24nLCBtb21lbnRGb3JtYXQ6ICdNTU0nLCBkZXNjcmlwdGlvbjogJ01vbnRoIChKYW4gLSBEZWMpJywgdHlwZTogJ2NhdGVnb3JpYWwnLCBncm91cHM6IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLCAnT2N0JywgJ05vdicsICdEZWMnXSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnTW9udGgnLCBtb21lbnRGb3JtYXQ6ICdNTU1NJywgZGVzY3JpcHRpb246ICdNb250aCAoSmFudWFyeSAtIERlY2VtYmVyKScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ0phbnVhcnknLCAnRmVidXJhcnknLCAnTWFyY2gnLCAnQXByaWwnLCAnTWF5JywgJ0p1bmUnLCAnSnVseScsICdBdWd1c3QnLCAnU2VwdGVibWVyJywgJ09jdG9iZXInLCAnTm92ZW1iZXInLCAnRGVjZW1iZXInXSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnRHknLCBtb21lbnRGb3JtYXQ6ICdkZGQnLCBkZXNjcmlwdGlvbjogJ0RheSBvZiBXZWVrIChTdW4tU2F0KScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ1N1bicsICdNb24nLCAnVHVlJywgJ1dlZCcsICdUaHUnLCAnRnJpJywgJ1NhdCddIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdEYXknLCBtb21lbnRGb3JtYXQ6ICdkZGRkJywgZGVzY3JpcHRpb246ICdEYXkgb2YgV2VlayAoU3VuZGF5LVNhdHVyZGF5KScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknLCAnU3VuZGF5J10gfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ0FNJywgbW9tZW50Rm9ybWF0OiAnQScsIGRlc2NyaXB0aW9uOiAnQU0vUE0nLCB0eXBlOiAnY2F0ZWdvcmlhbCcsIGdyb3VwczogWydBTScsICdQTSddIH1cbl0pO1xuXG52YXIgRHVyYXRpb25Vbml0ID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBUaGUgZGVzY3JpcHRpdmUgbmFtZSBvZiB0aGUgdGltZSB1bml0XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRlc2NyaXB0aW9uOiBbJ3N0cmluZyddLFxuICAgIC8qKlxuICAgICAqIE1vbWVudGpzIHBhcnNpbmcgZm9ybWF0XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG1vbWVudEZvcm1hdDogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBQb3N0Z3JlcyBwYXJzaW5nIGZvcm1hdFxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25Vbml0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBwb3N0Z3Jlc0Zvcm1hdDogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBDb252ZXJzaW9uIGZhY3RvciB0byBzZWNvbmRzXG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHNlY29uZHM6IFsnbnVtYmVyJ11cbiAgfVxufSk7XG5cbnZhciBEdXJhdGlvblVuaXRzID0gQW1wZXJzYW5kQ29sbGxlY3Rpb24uZXh0ZW5kKHtcbiAgaW5kZXhlczogWydkZXNjcmlwdGlvbiddLFxuICBtb2RlbDogRHVyYXRpb25Vbml0XG59KTtcblxudmFyIGR1cmF0aW9uVW5pdHMgPSBuZXcgRHVyYXRpb25Vbml0cyhbXG4gIHtcbiAgICBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLFxuICAgIHNlY29uZHM6IDFcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnbWlsbGVuaXVtJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaWxsZW5pdW0nLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnbWlsbGVuaXVtJyxcbiAgICBzZWNvbmRzOiAxMDAgKiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnY2VudHVyeScsXG4gICAgbW9tZW50Rm9ybWF0OiAnY2VudHVyeScsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdjZW50dXJ5JyxcbiAgICBzZWNvbmRzOiAxMDAgKiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnZGVjYWRlcycsXG4gICAgbW9tZW50Rm9ybWF0OiAnZGVjYWRlcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdkZWNhZGUnLFxuICAgIHNlY29uZHM6IDEwICogMzY1LjI1ICogMjQgKiA2MCAqIDYwXG4gIH0sIHtcbiAgICBkZXNjcmlwdGlvbjogJ3llYXJzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICd5ZWFycycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICd5ZWFyJyxcbiAgICBzZWNvbmRzOiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAncXVhcnRlcnMnLFxuICAgIG1vbWVudEZvcm1hdDogJycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdxdWFydGVyJyxcbiAgICBzZWNvbmRzOiAzNjUuMjUgKiA4ICogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtb250aHMnLFxuICAgIG1vbWVudEZvcm1hdDogJ21vbnRocycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdtb250aCcsXG4gICAgc2Vjb25kczogMzAgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnd2Vla3MnLFxuICAgIG1vbWVudEZvcm1hdDogJ3dlZWtzJyxcbiAgICBwb3N0Z3Jlc0Zvcm1hdDogJ3dlZWsnLFxuICAgIHNlY29uZHM6IDcgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnZGF5cycsXG4gICAgbW9tZW50Rm9ybWF0OiAnZGF5cycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdkYXknLFxuICAgIHNlY29uZHM6IDI0ICogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdob3VycycsXG4gICAgbW9tZW50Rm9ybWF0OiAnaG91cnMnLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnaG91cicsXG4gICAgc2Vjb25kczogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtaW51dGVzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaW51dGVzJyxcbiAgICBwb3N0Z3Jlc0Zvcm1hdDogJ21pbnV0ZScsXG4gICAgc2Vjb25kczogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnc2Vjb25kcycsXG4gICAgbW9tZW50Rm9ybWF0OiAnc2Vjb25kcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdzZWNvbmQnLFxuICAgIHNlY29uZHM6IDFcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnbWlsbGlzZWNvbmRzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaWxsaXNlY29uZHMnLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnbWlsbGlzZWNvbmRzJyxcbiAgICBzZWNvbmRzOiAwLjAwMVxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtaWNyb3NlY29uZHMnLFxuICAgIG1vbWVudEZvcm1hdDogJ21pY3Jvc2Vjb25kcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdtaWNyb3NlY29uZHMnLFxuICAgIHNlY29uZHM6IDAuMDAwMDAxXG4gIH1cbl0pO1xuXG52YXIgVGltZVpvbmUgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRoZSBkZXNjcmlwdGl2ZSBuYW1lIG9mIHRoZSB0aW1lIHpvbmVcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVab25lXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBkZXNjcmlwdGlvbjogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSB6b25lIGZvcm1hdFxuICAgICAqIEBtZW1iZXJvZiEgVGltZVpvbmVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZvcm1hdDogWydzdHJpbmcnXVxuICB9XG59KTtcblxudmFyIFRpbWVab25lcyA9IEFtcGVyc2FuZENvbGxsZWN0aW9uLmV4dGVuZCh7XG4gIGluZGV4ZXM6IFsnZGVzY3JpcHRpb24nXSxcbiAgbW9kZWw6IFRpbWVab25lXG59KTtcblxudmFyIHRpbWVab25lcyA9IG5ldyBUaW1lWm9uZXMoKTtcbnRpbWVab25lcy5hZGQoe1xuICBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLFxuICBmb3JtYXQ6ICdJU084NjAxJ1xufSk7XG5cbm1vbWVudC50ei5uYW1lcygpLmZvckVhY2goZnVuY3Rpb24gKHR6KSB7XG4gIHRpbWVab25lcy5hZGQoe1xuICAgIGRlc2NyaXB0aW9uOiB0eixcbiAgICBmb3JtYXQ6IHR6XG4gIH0pO1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB0aW1lUGFydHM6IHRpbWVQYXJ0cyxcbiAgdGltZVpvbmVzOiB0aW1lWm9uZXMsXG4gIGR1cmF0aW9uVW5pdHM6IGR1cmF0aW9uVW5pdHMsXG4gIGdldERhdGV0aW1lUmVzb2x1dGlvbjogZ2V0RGF0ZXRpbWVSZXNvbHV0aW9uLFxuICBnZXREdXJhdGlvblJlc29sdXRpb246IGdldER1cmF0aW9uUmVzb2x1dGlvbixcbiAgZ2V0Rm9ybWF0OiBnZXRGb3JtYXRcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///d45b\n")},e59a:function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Partition = __webpack_require__(/*! ../partition */ \"8191\");\n\nmodule.exports = Collection.extend({\n  model: Partition,\n  indexes: ['rank'],\n  comparator: 'rank',\n  initialize: function () {\n    this.on('add', function (newPartition) {\n      newPartition.reset();\n    });\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTU5YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2NvbGxlY3Rpb24uanM/YzRiOCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgUGFydGl0aW9uID0gcmVxdWlyZSgnLi4vcGFydGl0aW9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogUGFydGl0aW9uLFxuICBpbmRleGVzOiBbJ3JhbmsnXSxcbiAgY29tcGFyYXRvcjogJ3JhbmsnLFxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5vbignYWRkJywgZnVuY3Rpb24gKG5ld1BhcnRpdGlvbikge1xuICAgICAgbmV3UGFydGl0aW9uLnJlc2V0KCk7XG4gICAgfSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///e59a\n")},e810:function(module,exports,__webpack_require__){eval("/**\n * ContinuousTransfrom defines a transformation on continuous (nummerical) data.\n * Currently linear interpolation between a set of control points is implemented.\n *\n * @class ContinuousTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'text',\n      values: ['text']\n    },\n    transformedMin: {\n      type: 'number',\n      required: true,\n      default: 0\n    },\n    transformedMax: {\n      type: 'number',\n      required: true,\n      default: 100\n    }\n  },\n  reset: function () {\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTgxMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvdGV4dC10cmFuc2Zvcm0uanM/MzQ1MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbnRpbnVvdXNUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNvbnRpbnVvdXMgKG51bW1lcmljYWwpIGRhdGEuXG4gKiBDdXJyZW50bHkgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiBhIHNldCBvZiBjb250cm9sIHBvaW50cyBpcyBpbXBsZW1lbnRlZC5cbiAqXG4gKiBAY2xhc3MgQ29udGludW91c1RyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIHRyYW5zZm9ybWVkVHlwZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICd0ZXh0JyxcbiAgICAgIHZhbHVlczogWyd0ZXh0J11cbiAgICB9LFxuICAgIHRyYW5zZm9ybWVkTWluOiB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogMFxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNYXg6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAxMDBcbiAgICB9XG4gIH0sXG4gIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///e810\n")},ea82:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/*global Blob,File*/\n\n/**\n * Module requirements\n */\n\nvar isArray = __webpack_require__(/*! isarray */ \"6176\");\nvar isBuf = __webpack_require__(/*! ./is-buffer */ \"419b\");\n\n/**\n * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.\n * Anything with blobs or files should be fed through removeBlobs before coming\n * here.\n *\n * @param {Object} packet - socket.io event packet\n * @return {Object} with deconstructed packet and list of buffers\n * @api public\n */\n\nexports.deconstructPacket = function(packet){\n  var buffers = [];\n  var packetData = packet.data;\n\n  function _deconstructPacket(data) {\n    if (!data) return data;\n\n    if (isBuf(data)) {\n      var placeholder = { _placeholder: true, num: buffers.length };\n      buffers.push(data);\n      return placeholder;\n    } else if (isArray(data)) {\n      var newData = new Array(data.length);\n      for (var i = 0; i < data.length; i++) {\n        newData[i] = _deconstructPacket(data[i]);\n      }\n      return newData;\n    } else if ('object' == typeof data && !(data instanceof Date)) {\n      var newData = {};\n      for (var key in data) {\n        newData[key] = _deconstructPacket(data[key]);\n      }\n      return newData;\n    }\n    return data;\n  }\n\n  var pack = packet;\n  pack.data = _deconstructPacket(packetData);\n  pack.attachments = buffers.length; // number of binary 'attachments'\n  return {packet: pack, buffers: buffers};\n};\n\n/**\n * Reconstructs a binary packet from its placeholder packet and buffers\n *\n * @param {Object} packet - event packet with placeholders\n * @param {Array} buffers - binary buffers to put in placeholder positions\n * @return {Object} reconstructed packet\n * @api public\n */\n\nexports.reconstructPacket = function(packet, buffers) {\n  var curPlaceHolder = 0;\n\n  function _reconstructPacket(data) {\n    if (data && data._placeholder) {\n      var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway)\n      return buf;\n    } else if (isArray(data)) {\n      for (var i = 0; i < data.length; i++) {\n        data[i] = _reconstructPacket(data[i]);\n      }\n      return data;\n    } else if (data && 'object' == typeof data) {\n      for (var key in data) {\n        data[key] = _reconstructPacket(data[key]);\n      }\n      return data;\n    }\n    return data;\n  }\n\n  packet.data = _reconstructPacket(packet.data);\n  packet.attachments = undefined; // no longer useful\n  return packet;\n};\n\n/**\n * Asynchronously removes Blobs or Files from data via\n * FileReader's readAsArrayBuffer method. Used before encoding\n * data as msgpack. Calls callback with the blobless data.\n *\n * @param {Object} data\n * @param {Function} callback\n * @api private\n */\n\nexports.removeBlobs = function(data, callback) {\n  function _removeBlobs(obj, curKey, containingObject) {\n    if (!obj) return obj;\n\n    // convert any blob\n    if ((global.Blob && obj instanceof Blob) ||\n        (global.File && obj instanceof File)) {\n      pendingBlobs++;\n\n      // async filereader\n      var fileReader = new FileReader();\n      fileReader.onload = function() { // this.result == arraybuffer\n        if (containingObject) {\n          containingObject[curKey] = this.result;\n        }\n        else {\n          bloblessData = this.result;\n        }\n\n        // if nothing pending its callback time\n        if(! --pendingBlobs) {\n          callback(bloblessData);\n        }\n      };\n\n      fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer\n    } else if (isArray(obj)) { // handle array\n      for (var i = 0; i < obj.length; i++) {\n        _removeBlobs(obj[i], i, obj);\n      }\n    } else if (obj && 'object' == typeof obj && !isBuf(obj)) { // and object\n      for (var key in obj) {\n        _removeBlobs(obj[key], key, obj);\n      }\n    }\n  }\n\n  var pendingBlobs = 0;\n  var bloblessData = data;\n  _removeBlobs(bloblessData);\n  if (!pendingBlobs) {\n    callback(bloblessData);\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWE4Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9iaW5hcnkuanM/ZGQwNyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKmdsb2JhbCBCbG9iLEZpbGUqL1xuXG4vKipcbiAqIE1vZHVsZSByZXF1aXJlbWVudHNcbiAqL1xuXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcbnZhciBpc0J1ZiA9IHJlcXVpcmUoJy4vaXMtYnVmZmVyJyk7XG5cbi8qKlxuICogUmVwbGFjZXMgZXZlcnkgQnVmZmVyIHwgQXJyYXlCdWZmZXIgaW4gcGFja2V0IHdpdGggYSBudW1iZXJlZCBwbGFjZWhvbGRlci5cbiAqIEFueXRoaW5nIHdpdGggYmxvYnMgb3IgZmlsZXMgc2hvdWxkIGJlIGZlZCB0aHJvdWdoIHJlbW92ZUJsb2JzIGJlZm9yZSBjb21pbmdcbiAqIGhlcmUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldCAtIHNvY2tldC5pbyBldmVudCBwYWNrZXRcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBkZWNvbnN0cnVjdGVkIHBhY2tldCBhbmQgbGlzdCBvZiBidWZmZXJzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb25zdHJ1Y3RQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQpe1xuICB2YXIgYnVmZmVycyA9IFtdO1xuICB2YXIgcGFja2V0RGF0YSA9IHBhY2tldC5kYXRhO1xuXG4gIGZ1bmN0aW9uIF9kZWNvbnN0cnVjdFBhY2tldChkYXRhKSB7XG4gICAgaWYgKCFkYXRhKSByZXR1cm4gZGF0YTtcblxuICAgIGlmIChpc0J1ZihkYXRhKSkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0geyBfcGxhY2Vob2xkZXI6IHRydWUsIG51bTogYnVmZmVycy5sZW5ndGggfTtcbiAgICAgIGJ1ZmZlcnMucHVzaChkYXRhKTtcbiAgICAgIHJldHVybiBwbGFjZWhvbGRlcjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIHZhciBuZXdEYXRhID0gbmV3IEFycmF5KGRhdGEubGVuZ3RoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBuZXdEYXRhW2ldID0gX2RlY29uc3RydWN0UGFja2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgfSBlbHNlIGlmICgnb2JqZWN0JyA9PSB0eXBlb2YgZGF0YSAmJiAhKGRhdGEgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgdmFyIG5ld0RhdGEgPSB7fTtcbiAgICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICAgIG5ld0RhdGFba2V5XSA9IF9kZWNvbnN0cnVjdFBhY2tldChkYXRhW2tleV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgdmFyIHBhY2sgPSBwYWNrZXQ7XG4gIHBhY2suZGF0YSA9IF9kZWNvbnN0cnVjdFBhY2tldChwYWNrZXREYXRhKTtcbiAgcGFjay5hdHRhY2htZW50cyA9IGJ1ZmZlcnMubGVuZ3RoOyAvLyBudW1iZXIgb2YgYmluYXJ5ICdhdHRhY2htZW50cydcbiAgcmV0dXJuIHtwYWNrZXQ6IHBhY2ssIGJ1ZmZlcnM6IGJ1ZmZlcnN9O1xufTtcblxuLyoqXG4gKiBSZWNvbnN0cnVjdHMgYSBiaW5hcnkgcGFja2V0IGZyb20gaXRzIHBsYWNlaG9sZGVyIHBhY2tldCBhbmQgYnVmZmVyc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQgLSBldmVudCBwYWNrZXQgd2l0aCBwbGFjZWhvbGRlcnNcbiAqIEBwYXJhbSB7QXJyYXl9IGJ1ZmZlcnMgLSBiaW5hcnkgYnVmZmVycyB0byBwdXQgaW4gcGxhY2Vob2xkZXIgcG9zaXRpb25zXG4gKiBAcmV0dXJuIHtPYmplY3R9IHJlY29uc3RydWN0ZWQgcGFja2V0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMucmVjb25zdHJ1Y3RQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQsIGJ1ZmZlcnMpIHtcbiAgdmFyIGN1clBsYWNlSG9sZGVyID0gMDtcblxuICBmdW5jdGlvbiBfcmVjb25zdHJ1Y3RQYWNrZXQoZGF0YSkge1xuICAgIGlmIChkYXRhICYmIGRhdGEuX3BsYWNlaG9sZGVyKSB7XG4gICAgICB2YXIgYnVmID0gYnVmZmVyc1tkYXRhLm51bV07IC8vIGFwcHJvcHJpYXRlIGJ1ZmZlciAoc2hvdWxkIGJlIG5hdHVyYWwgb3JkZXIgYW55d2F5KVxuICAgICAgcmV0dXJuIGJ1ZjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBkYXRhW2ldID0gX3JlY29uc3RydWN0UGFja2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSBlbHNlIGlmIChkYXRhICYmICdvYmplY3QnID09IHR5cGVvZiBkYXRhKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkge1xuICAgICAgICBkYXRhW2tleV0gPSBfcmVjb25zdHJ1Y3RQYWNrZXQoZGF0YVtrZXldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIHBhY2tldC5kYXRhID0gX3JlY29uc3RydWN0UGFja2V0KHBhY2tldC5kYXRhKTtcbiAgcGFja2V0LmF0dGFjaG1lbnRzID0gdW5kZWZpbmVkOyAvLyBubyBsb25nZXIgdXNlZnVsXG4gIHJldHVybiBwYWNrZXQ7XG59O1xuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IHJlbW92ZXMgQmxvYnMgb3IgRmlsZXMgZnJvbSBkYXRhIHZpYVxuICogRmlsZVJlYWRlcidzIHJlYWRBc0FycmF5QnVmZmVyIG1ldGhvZC4gVXNlZCBiZWZvcmUgZW5jb2RpbmdcbiAqIGRhdGEgYXMgbXNncGFjay4gQ2FsbHMgY2FsbGJhY2sgd2l0aCB0aGUgYmxvYmxlc3MgZGF0YS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMucmVtb3ZlQmxvYnMgPSBmdW5jdGlvbihkYXRhLCBjYWxsYmFjaykge1xuICBmdW5jdGlvbiBfcmVtb3ZlQmxvYnMob2JqLCBjdXJLZXksIGNvbnRhaW5pbmdPYmplY3QpIHtcbiAgICBpZiAoIW9iaikgcmV0dXJuIG9iajtcblxuICAgIC8vIGNvbnZlcnQgYW55IGJsb2JcbiAgICBpZiAoKGdsb2JhbC5CbG9iICYmIG9iaiBpbnN0YW5jZW9mIEJsb2IpIHx8XG4gICAgICAgIChnbG9iYWwuRmlsZSAmJiBvYmogaW5zdGFuY2VvZiBGaWxlKSkge1xuICAgICAgcGVuZGluZ0Jsb2JzKys7XG5cbiAgICAgIC8vIGFzeW5jIGZpbGVyZWFkZXJcbiAgICAgIHZhciBmaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gZnVuY3Rpb24oKSB7IC8vIHRoaXMucmVzdWx0ID09IGFycmF5YnVmZmVyXG4gICAgICAgIGlmIChjb250YWluaW5nT2JqZWN0KSB7XG4gICAgICAgICAgY29udGFpbmluZ09iamVjdFtjdXJLZXldID0gdGhpcy5yZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYmxvYmxlc3NEYXRhID0gdGhpcy5yZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBub3RoaW5nIHBlbmRpbmcgaXRzIGNhbGxiYWNrIHRpbWVcbiAgICAgICAgaWYoISAtLXBlbmRpbmdCbG9icykge1xuICAgICAgICAgIGNhbGxiYWNrKGJsb2JsZXNzRGF0YSk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIob2JqKTsgLy8gYmxvYiAtPiBhcnJheWJ1ZmZlclxuICAgIH0gZWxzZSBpZiAoaXNBcnJheShvYmopKSB7IC8vIGhhbmRsZSBhcnJheVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtpXSwgaSwgb2JqKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9iaiAmJiAnb2JqZWN0JyA9PSB0eXBlb2Ygb2JqICYmICFpc0J1ZihvYmopKSB7IC8vIGFuZCBvYmplY3RcbiAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHBlbmRpbmdCbG9icyA9IDA7XG4gIHZhciBibG9ibGVzc0RhdGEgPSBkYXRhO1xuICBfcmVtb3ZlQmxvYnMoYmxvYmxlc3NEYXRhKTtcbiAgaWYgKCFwZW5kaW5nQmxvYnMpIHtcbiAgICBjYWxsYmFjayhibG9ibGVzc0RhdGEpO1xuICB9XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///ea82\n")},ef13:function(module,exports){eval("/**\n * An abstraction for slicing an arraybuffer even when\n * ArrayBuffer.prototype.slice is not supported\n *\n * @api public\n */\n\nmodule.exports = function(arraybuffer, start, end) {\n  var bytes = arraybuffer.byteLength;\n  start = start || 0;\n  end = end || bytes;\n\n  if (arraybuffer.slice) { return arraybuffer.slice(start, end); }\n\n  if (start < 0) { start += bytes; }\n  if (end < 0) { end += bytes; }\n  if (end > bytes) { end = bytes; }\n\n  if (start >= bytes || start >= end || bytes === 0) {\n    return new ArrayBuffer(0);\n  }\n\n  var abv = new Uint8Array(arraybuffer);\n  var result = new Uint8Array(end - start);\n  for (var i = start, ii = 0; i < end; i++, ii++) {\n    result[ii] = abv[i];\n  }\n  return result.buffer;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWYxMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvYXJyYXlidWZmZXIuc2xpY2UvaW5kZXguanM/NTM3NCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFuIGFic3RyYWN0aW9uIGZvciBzbGljaW5nIGFuIGFycmF5YnVmZmVyIGV2ZW4gd2hlblxuICogQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlIGlzIG5vdCBzdXBwb3J0ZWRcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYXJyYXlidWZmZXIsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYXJyYXlidWZmZXIuYnl0ZUxlbmd0aDtcbiAgc3RhcnQgPSBzdGFydCB8fCAwO1xuICBlbmQgPSBlbmQgfHwgYnl0ZXM7XG5cbiAgaWYgKGFycmF5YnVmZmVyLnNsaWNlKSB7IHJldHVybiBhcnJheWJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTsgfVxuXG4gIGlmIChzdGFydCA8IDApIHsgc3RhcnQgKz0gYnl0ZXM7IH1cbiAgaWYgKGVuZCA8IDApIHsgZW5kICs9IGJ5dGVzOyB9XG4gIGlmIChlbmQgPiBieXRlcykgeyBlbmQgPSBieXRlczsgfVxuXG4gIGlmIChzdGFydCA+PSBieXRlcyB8fCBzdGFydCA+PSBlbmQgfHwgYnl0ZXMgPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xuICB9XG5cbiAgdmFyIGFidiA9IG5ldyBVaW50OEFycmF5KGFycmF5YnVmZmVyKTtcbiAgdmFyIHJlc3VsdCA9IG5ldyBVaW50OEFycmF5KGVuZCAtIHN0YXJ0KTtcbiAgZm9yICh2YXIgaSA9IHN0YXJ0LCBpaSA9IDA7IGkgPCBlbmQ7IGkrKywgaWkrKykge1xuICAgIHJlc3VsdFtpaV0gPSBhYnZbaV07XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5idWZmZXI7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///ef13\n")},faaa:function(module,exports){eval("\n/**\n * Module exports.\n */\n\nmodule.exports = on;\n\n/**\n * Helper for subscriptions.\n *\n * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`\n * @param {String} event name\n * @param {Function} callback\n * @api public\n */\n\nfunction on (obj, ev, fn) {\n  obj.on(ev, fn);\n  return {\n    destroy: function () {\n      obj.removeListener(ev, fn);\n    }\n  };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFhYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvb24uanM/MTBkYiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBvbjtcblxuLyoqXG4gKiBIZWxwZXIgZm9yIHN1YnNjcmlwdGlvbnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8RXZlbnRFbWl0dGVyfSBvYmogd2l0aCBgRW1pdHRlcmAgbWl4aW4gb3IgYEV2ZW50RW1pdHRlcmBcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBuYW1lXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBvbiAob2JqLCBldiwgZm4pIHtcbiAgb2JqLm9uKGV2LCBmbik7XG4gIHJldHVybiB7XG4gICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgb2JqLnJlbW92ZUxpc3RlbmVyKGV2LCBmbik7XG4gICAgfVxuICB9O1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///faaa\n")},fbef:function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Aggregate = __webpack_require__(/*! ../aggregate */ \"9d63\");\n\nmodule.exports = Collection.extend({\n  model: Aggregate,\n  indexes: ['rank'],\n  comparator: 'rank'\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmJlZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvYWdncmVnYXRlL2NvbGxlY3Rpb24uanM/YmJhNiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgQWdncmVnYXRlID0gcmVxdWlyZSgnLi4vYWdncmVnYXRlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogQWdncmVnYXRlLFxuICBpbmRleGVzOiBbJ3JhbmsnXSxcbiAgY29tcGFyYXRvcjogJ3JhbmsnXG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///fbef\n")}}]);

HACK found
Open

* HACK: Even though the intention is to have the current .mdl-spinner__layer-N
Severity: Minor
Found in dist/app.css by fixme

TODO found
Open

/* TODO end */
Severity: Minor
Found in stylesheets/styles.css by fixme

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.moment"],{da01:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js\n\n;(function (global, factory) {\n     true ? module.exports = factory() :\n    undefined\n}(this, (function () { 'use strict';\n\n    var hookCallback;\n\n    function hooks () {\n        return hookCallback.apply(null, arguments);\n    }\n\n    // This is done to register the method called with moment()\n    // without creating circular dependencies.\n    function setHookCallback (callback) {\n        hookCallback = callback;\n    }\n\n    function isArray(input) {\n        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n    }\n\n    function isObject(input) {\n        // IE8 will treat undefined and null as object if it wasn't for\n        // input != null\n        return input != null && Object.prototype.toString.call(input) === '[object Object]';\n    }\n\n    function isObjectEmpty(obj) {\n        if (Object.getOwnPropertyNames) {\n            return (Object.getOwnPropertyNames(obj).length === 0);\n        } else {\n            var k;\n            for (k in obj) {\n                if (obj.hasOwnProperty(k)) {\n                    return false;\n                }\n            }\n            return true;\n        }\n    }\n\n    function isUndefined(input) {\n        return input === void 0;\n    }\n\n    function isNumber(input) {\n        return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n    }\n\n    function isDate(input) {\n        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n    }\n\n    function map(arr, fn) {\n        var res = [], i;\n        for (i = 0; i < arr.length; ++i) {\n            res.push(fn(arr[i], i));\n        }\n        return res;\n    }\n\n    function hasOwnProp(a, b) {\n        return Object.prototype.hasOwnProperty.call(a, b);\n    }\n\n    function extend(a, b) {\n        for (var i in b) {\n            if (hasOwnProp(b, i)) {\n                a[i] = b[i];\n            }\n        }\n\n        if (hasOwnProp(b, 'toString')) {\n            a.toString = b.toString;\n        }\n\n        if (hasOwnProp(b, 'valueOf')) {\n            a.valueOf = b.valueOf;\n        }\n\n        return a;\n    }\n\n    function createUTC (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, true).utc();\n    }\n\n    function defaultParsingFlags() {\n        // We need to deep clone this object.\n        return {\n            empty           : false,\n            unusedTokens    : [],\n            unusedInput     : [],\n            overflow        : -2,\n            charsLeftOver   : 0,\n            nullInput       : false,\n            invalidMonth    : null,\n            invalidFormat   : false,\n            userInvalidated : false,\n            iso             : false,\n            parsedDateParts : [],\n            meridiem        : null,\n            rfc2822         : false,\n            weekdayMismatch : false\n        };\n    }\n\n    function getParsingFlags(m) {\n        if (m._pf == null) {\n            m._pf = defaultParsingFlags();\n        }\n        return m._pf;\n    }\n\n    var some;\n    if (Array.prototype.some) {\n        some = Array.prototype.some;\n    } else {\n        some = function (fun) {\n            var t = Object(this);\n            var len = t.length >>> 0;\n\n            for (var i = 0; i < len; i++) {\n                if (i in t && fun.call(this, t[i], i, t)) {\n                    return true;\n                }\n            }\n\n            return false;\n        };\n    }\n\n    function isValid(m) {\n        if (m._isValid == null) {\n            var flags = getParsingFlags(m);\n            var parsedParts = some.call(flags.parsedDateParts, function (i) {\n                return i != null;\n            });\n            var isNowValid = !isNaN(m._d.getTime()) &&\n                flags.overflow < 0 &&\n                !flags.empty &&\n                !flags.invalidMonth &&\n                !flags.invalidWeekday &&\n                !flags.weekdayMismatch &&\n                !flags.nullInput &&\n                !flags.invalidFormat &&\n                !flags.userInvalidated &&\n                (!flags.meridiem || (flags.meridiem && parsedParts));\n\n            if (m._strict) {\n                isNowValid = isNowValid &&\n                    flags.charsLeftOver === 0 &&\n                    flags.unusedTokens.length === 0 &&\n                    flags.bigHour === undefined;\n            }\n\n            if (Object.isFrozen == null || !Object.isFrozen(m)) {\n                m._isValid = isNowValid;\n            }\n            else {\n                return isNowValid;\n            }\n        }\n        return m._isValid;\n    }\n\n    function createInvalid (flags) {\n        var m = createUTC(NaN);\n        if (flags != null) {\n            extend(getParsingFlags(m), flags);\n        }\n        else {\n            getParsingFlags(m).userInvalidated = true;\n        }\n\n        return m;\n    }\n\n    // Plugins that add properties should also add the key here (null value),\n    // so we can properly clone ourselves.\n    var momentProperties = hooks.momentProperties = [];\n\n    function copyConfig(to, from) {\n        var i, prop, val;\n\n        if (!isUndefined(from._isAMomentObject)) {\n            to._isAMomentObject = from._isAMomentObject;\n        }\n        if (!isUndefined(from._i)) {\n            to._i = from._i;\n        }\n        if (!isUndefined(from._f)) {\n            to._f = from._f;\n        }\n        if (!isUndefined(from._l)) {\n            to._l = from._l;\n        }\n        if (!isUndefined(from._strict)) {\n            to._strict = from._strict;\n        }\n        if (!isUndefined(from._tzm)) {\n            to._tzm = from._tzm;\n        }\n        if (!isUndefined(from._isUTC)) {\n            to._isUTC = from._isUTC;\n        }\n        if (!isUndefined(from._offset)) {\n            to._offset = from._offset;\n        }\n        if (!isUndefined(from._pf)) {\n            to._pf = getParsingFlags(from);\n        }\n        if (!isUndefined(from._locale)) {\n            to._locale = from._locale;\n        }\n\n        if (momentProperties.length > 0) {\n            for (i = 0; i < momentProperties.length; i++) {\n                prop = momentProperties[i];\n                val = from[prop];\n                if (!isUndefined(val)) {\n                    to[prop] = val;\n                }\n            }\n        }\n\n        return to;\n    }\n\n    var updateInProgress = false;\n\n    // Moment prototype object\n    function Moment(config) {\n        copyConfig(this, config);\n        this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n        if (!this.isValid()) {\n            this._d = new Date(NaN);\n        }\n        // Prevent infinite loop in case updateOffset creates new moment\n        // objects.\n        if (updateInProgress === false) {\n            updateInProgress = true;\n            hooks.updateOffset(this);\n            updateInProgress = false;\n        }\n    }\n\n    function isMoment (obj) {\n        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n    }\n\n    function absFloor (number) {\n        if (number < 0) {\n            // -0 -> 0\n            return Math.ceil(number) || 0;\n        } else {\n            return Math.floor(number);\n        }\n    }\n\n    function toInt(argumentForCoercion) {\n        var coercedNumber = +argumentForCoercion,\n            value = 0;\n\n        if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n            value = absFloor(coercedNumber);\n        }\n\n        return value;\n    }\n\n    // compare two arrays, return the number of differences\n    function compareArrays(array1, array2, dontConvert) {\n        var len = Math.min(array1.length, array2.length),\n            lengthDiff = Math.abs(array1.length - array2.length),\n            diffs = 0,\n            i;\n        for (i = 0; i < len; i++) {\n            if ((dontConvert && array1[i] !== array2[i]) ||\n                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n                diffs++;\n            }\n        }\n        return diffs + lengthDiff;\n    }\n\n    function warn(msg) {\n        if (hooks.suppressDeprecationWarnings === false &&\n                (typeof console !==  'undefined') && console.warn) {\n            console.warn('Deprecation warning: ' + msg);\n        }\n    }\n\n    function deprecate(msg, fn) {\n        var firstTime = true;\n\n        return extend(function () {\n            if (hooks.deprecationHandler != null) {\n                hooks.deprecationHandler(null, msg);\n            }\n            if (firstTime) {\n                var args = [];\n                var arg;\n                for (var i = 0; i < arguments.length; i++) {\n                    arg = '';\n                    if (typeof arguments[i] === 'object') {\n                        arg += '\\n[' + i + '] ';\n                        for (var key in arguments[0]) {\n                            arg += key + ': ' + arguments[0][key] + ', ';\n                        }\n                        arg = arg.slice(0, -2); // Remove trailing comma and space\n                    } else {\n                        arg = arguments[i];\n                    }\n                    args.push(arg);\n                }\n                warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n                firstTime = false;\n            }\n            return fn.apply(this, arguments);\n        }, fn);\n    }\n\n    var deprecations = {};\n\n    function deprecateSimple(name, msg) {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(name, msg);\n        }\n        if (!deprecations[name]) {\n            warn(msg);\n            deprecations[name] = true;\n        }\n    }\n\n    hooks.suppressDeprecationWarnings = false;\n    hooks.deprecationHandler = null;\n\n    function isFunction(input) {\n        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n    }\n\n    function set (config) {\n        var prop, i;\n        for (i in config) {\n            prop = config[i];\n            if (isFunction(prop)) {\n                this[i] = prop;\n            } else {\n                this['_' + i] = prop;\n            }\n        }\n        this._config = config;\n        // Lenient ordinal parsing accepts just a number in addition to\n        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n        // TODO: Remove \"ordinalParse\" fallback in next major release.\n        this._dayOfMonthOrdinalParseLenient = new RegExp(\n            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n                '|' + (/\\d{1,2}/).source);\n    }\n\n    function mergeConfigs(parentConfig, childConfig) {\n        var res = extend({}, parentConfig), prop;\n        for (prop in childConfig) {\n            if (hasOwnProp(childConfig, prop)) {\n                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                    res[prop] = {};\n                    extend(res[prop], parentConfig[prop]);\n                    extend(res[prop], childConfig[prop]);\n                } else if (childConfig[prop] != null) {\n                    res[prop] = childConfig[prop];\n                } else {\n                    delete res[prop];\n                }\n            }\n        }\n        for (prop in parentConfig) {\n            if (hasOwnProp(parentConfig, prop) &&\n                    !hasOwnProp(childConfig, prop) &&\n                    isObject(parentConfig[prop])) {\n                // make sure changes to properties don't modify parent config\n                res[prop] = extend({}, res[prop]);\n            }\n        }\n        return res;\n    }\n\n    function Locale(config) {\n        if (config != null) {\n            this.set(config);\n        }\n    }\n\n    var keys;\n\n    if (Object.keys) {\n        keys = Object.keys;\n    } else {\n        keys = function (obj) {\n            var i, res = [];\n            for (i in obj) {\n                if (hasOwnProp(obj, i)) {\n                    res.push(i);\n                }\n            }\n            return res;\n        };\n    }\n\n    var defaultCalendar = {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    };\n\n    function calendar (key, mom, now) {\n        var output = this._calendar[key] || this._calendar['sameElse'];\n        return isFunction(output) ? output.call(mom, now) : output;\n    }\n\n    var defaultLongDateFormat = {\n        LTS  : 'h:mm:ss A',\n        LT   : 'h:mm A',\n        L    : 'MM/DD/YYYY',\n        LL   : 'MMMM D, YYYY',\n        LLL  : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    };\n\n    function longDateFormat (key) {\n        var format = this._longDateFormat[key],\n            formatUpper = this._longDateFormat[key.toUpperCase()];\n\n        if (format || !formatUpper) {\n            return format;\n        }\n\n        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n            return val.slice(1);\n        });\n\n        return this._longDateFormat[key];\n    }\n\n    var defaultInvalidDate = 'Invalid date';\n\n    function invalidDate () {\n        return this._invalidDate;\n    }\n\n    var defaultOrdinal = '%d';\n    var defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\n    function ordinal (number) {\n        return this._ordinal.replace('%d', number);\n    }\n\n    var defaultRelativeTime = {\n        future : 'in %s',\n        past   : '%s ago',\n        s  : 'a few seconds',\n        ss : '%d seconds',\n        m  : 'a minute',\n        mm : '%d minutes',\n        h  : 'an hour',\n        hh : '%d hours',\n        d  : 'a day',\n        dd : '%d days',\n        M  : 'a month',\n        MM : '%d months',\n        y  : 'a year',\n        yy : '%d years'\n    };\n\n    function relativeTime (number, withoutSuffix, string, isFuture) {\n        var output = this._relativeTime[string];\n        return (isFunction(output)) ?\n            output(number, withoutSuffix, string, isFuture) :\n            output.replace(/%d/i, number);\n    }\n\n    function pastFuture (diff, output) {\n        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n        return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n    }\n\n    var aliases = {};\n\n    function addUnitAlias (unit, shorthand) {\n        var lowerCase = unit.toLowerCase();\n        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n    }\n\n    function normalizeUnits(units) {\n        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n    }\n\n    function normalizeObjectUnits(inputObject) {\n        var normalizedInput = {},\n            normalizedProp,\n            prop;\n\n        for (prop in inputObject) {\n            if (hasOwnProp(inputObject, prop)) {\n                normalizedProp = normalizeUnits(prop);\n                if (normalizedProp) {\n                    normalizedInput[normalizedProp] = inputObject[prop];\n                }\n            }\n        }\n\n        return normalizedInput;\n    }\n\n    var priorities = {};\n\n    function addUnitPriority(unit, priority) {\n        priorities[unit] = priority;\n    }\n\n    function getPrioritizedUnits(unitsObj) {\n        var units = [];\n        for (var u in unitsObj) {\n            units.push({unit: u, priority: priorities[u]});\n        }\n        units.sort(function (a, b) {\n            return a.priority - b.priority;\n        });\n        return units;\n    }\n\n    function zeroFill(number, targetLength, forceSign) {\n        var absNumber = '' + Math.abs(number),\n            zerosToFill = targetLength - absNumber.length,\n            sign = number >= 0;\n        return (sign ? (forceSign ? '+' : '') : '-') +\n            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n    }\n\n    var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\n    var localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\n    var formatFunctions = {};\n\n    var formatTokenFunctions = {};\n\n    // token:    'M'\n    // padded:   ['MM', 2]\n    // ordinal:  'Mo'\n    // callback: function () { this.month() + 1 }\n    function addFormatToken (token, padded, ordinal, callback) {\n        var func = callback;\n        if (typeof callback === 'string') {\n            func = function () {\n                return this[callback]();\n            };\n        }\n        if (token) {\n            formatTokenFunctions[token] = func;\n        }\n        if (padded) {\n            formatTokenFunctions[padded[0]] = function () {\n                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n            };\n        }\n        if (ordinal) {\n            formatTokenFunctions[ordinal] = function () {\n                return this.localeData().ordinal(func.apply(this, arguments), token);\n            };\n        }\n    }\n\n    function removeFormattingTokens(input) {\n        if (input.match(/\\[[\\s\\S]/)) {\n            return input.replace(/^\\[|\\]$/g, '');\n        }\n        return input.replace(/\\\\/g, '');\n    }\n\n    function makeFormatFunction(format) {\n        var array = format.match(formattingTokens), i, length;\n\n        for (i = 0, length = array.length; i < length; i++) {\n            if (formatTokenFunctions[array[i]]) {\n                array[i] = formatTokenFunctions[array[i]];\n            } else {\n                array[i] = removeFormattingTokens(array[i]);\n            }\n        }\n\n        return function (mom) {\n            var output = '', i;\n            for (i = 0; i < length; i++) {\n                output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n            }\n            return output;\n        };\n    }\n\n    // format date using native date object\n    function formatMoment(m, format) {\n        if (!m.isValid()) {\n            return m.localeData().invalidDate();\n        }\n\n        format = expandFormat(format, m.localeData());\n        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n        return formatFunctions[format](m);\n    }\n\n    function expandFormat(format, locale) {\n        var i = 5;\n\n        function replaceLongDateFormatTokens(input) {\n            return locale.longDateFormat(input) || input;\n        }\n\n        localFormattingTokens.lastIndex = 0;\n        while (i >= 0 && localFormattingTokens.test(format)) {\n            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n            localFormattingTokens.lastIndex = 0;\n            i -= 1;\n        }\n\n        return format;\n    }\n\n    var match1         = /\\d/;            //       0 - 9\n    var match2         = /\\d\\d/;          //      00 - 99\n    var match3         = /\\d{3}/;         //     000 - 999\n    var match4         = /\\d{4}/;         //    0000 - 9999\n    var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\n    var match1to2      = /\\d\\d?/;         //       0 - 99\n    var match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\n    var match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\n    var match1to3      = /\\d{1,3}/;       //       0 - 999\n    var match1to4      = /\\d{1,4}/;       //       0 - 9999\n    var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\n    var matchUnsigned  = /\\d+/;           //       0 - inf\n    var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\n    var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n    var matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\n    var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n    // any word (or two) characters or numbers including two/three word month in arabic.\n    // includes scottish gaelic two word and hyphenated months\n    var matchWord = /[0-9]{0,256}['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFF07\\uFF10-\\uFFEF]{1,256}|[\\u0600-\\u06FF\\/]{1,256}(\\s*?[\\u0600-\\u06FF]{1,256}){1,2}/i;\n\n    var regexes = {};\n\n    function addRegexToken (token, regex, strictRegex) {\n        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n            return (isStrict && strictRegex) ? strictRegex : regex;\n        };\n    }\n\n    function getParseRegexForToken (token, config) {\n        if (!hasOwnProp(regexes, token)) {\n            return new RegExp(unescapeFormat(token));\n        }\n\n        return regexes[token](config._strict, config._locale);\n    }\n\n    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\n    function unescapeFormat(s) {\n        return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n            return p1 || p2 || p3 || p4;\n        }));\n    }\n\n    function regexEscape(s) {\n        return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n    }\n\n    var tokens = {};\n\n    function addParseToken (token, callback) {\n        var i, func = callback;\n        if (typeof token === 'string') {\n            token = [token];\n        }\n        if (isNumber(callback)) {\n            func = function (input, array) {\n                array[callback] = toInt(input);\n            };\n        }\n        for (i = 0; i < token.length; i++) {\n            tokens[token[i]] = func;\n        }\n    }\n\n    function addWeekParseToken (token, callback) {\n        addParseToken(token, function (input, array, config, token) {\n            config._w = config._w || {};\n            callback(input, config._w, config, token);\n        });\n    }\n\n    function addTimeToArrayFromToken(token, input, config) {\n        if (input != null && hasOwnProp(tokens, token)) {\n            tokens[token](input, config._a, config, token);\n        }\n    }\n\n    var YEAR = 0;\n    var MONTH = 1;\n    var DATE = 2;\n    var HOUR = 3;\n    var MINUTE = 4;\n    var SECOND = 5;\n    var MILLISECOND = 6;\n    var WEEK = 7;\n    var WEEKDAY = 8;\n\n    // FORMATTING\n\n    addFormatToken('Y', 0, 0, function () {\n        var y = this.year();\n        return y <= 9999 ? '' + y : '+' + y;\n    });\n\n    addFormatToken(0, ['YY', 2], 0, function () {\n        return this.year() % 100;\n    });\n\n    addFormatToken(0, ['YYYY',   4],       0, 'year');\n    addFormatToken(0, ['YYYYY',  5],       0, 'year');\n    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n    // ALIASES\n\n    addUnitAlias('year', 'y');\n\n    // PRIORITIES\n\n    addUnitPriority('year', 1);\n\n    // PARSING\n\n    addRegexToken('Y',      matchSigned);\n    addRegexToken('YY',     match1to2, match2);\n    addRegexToken('YYYY',   match1to4, match4);\n    addRegexToken('YYYYY',  match1to6, match6);\n    addRegexToken('YYYYYY', match1to6, match6);\n\n    addParseToken(['YYYYY', 'YYYYYY'], YEAR);\n    addParseToken('YYYY', function (input, array) {\n        array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n    });\n    addParseToken('YY', function (input, array) {\n        array[YEAR] = hooks.parseTwoDigitYear(input);\n    });\n    addParseToken('Y', function (input, array) {\n        array[YEAR] = parseInt(input, 10);\n    });\n\n    // HELPERS\n\n    function daysInYear(year) {\n        return isLeapYear(year) ? 366 : 365;\n    }\n\n    function isLeapYear(year) {\n        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n    }\n\n    // HOOKS\n\n    hooks.parseTwoDigitYear = function (input) {\n        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n    };\n\n    // MOMENTS\n\n    var getSetYear = makeGetSet('FullYear', true);\n\n    function getIsLeapYear () {\n        return isLeapYear(this.year());\n    }\n\n    function makeGetSet (unit, keepTime) {\n        return function (value) {\n            if (value != null) {\n                set$1(this, unit, value);\n                hooks.updateOffset(this, keepTime);\n                return this;\n            } else {\n                return get(this, unit);\n            }\n        };\n    }\n\n    function get (mom, unit) {\n        return mom.isValid() ?\n            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n    }\n\n    function set$1 (mom, unit, value) {\n        if (mom.isValid() && !isNaN(value)) {\n            if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {\n                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));\n            }\n            else {\n                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function stringGet (units) {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units]();\n        }\n        return this;\n    }\n\n\n    function stringSet (units, value) {\n        if (typeof units === 'object') {\n            units = normalizeObjectUnits(units);\n            var prioritized = getPrioritizedUnits(units);\n            for (var i = 0; i < prioritized.length; i++) {\n                this[prioritized[i].unit](units[prioritized[i].unit]);\n            }\n        } else {\n            units = normalizeUnits(units);\n            if (isFunction(this[units])) {\n                return this[units](value);\n            }\n        }\n        return this;\n    }\n\n    function mod(n, x) {\n        return ((n % x) + x) % x;\n    }\n\n    var indexOf;\n\n    if (Array.prototype.indexOf) {\n        indexOf = Array.prototype.indexOf;\n    } else {\n        indexOf = function (o) {\n            // I know\n            var i;\n            for (i = 0; i < this.length; ++i) {\n                if (this[i] === o) {\n                    return i;\n                }\n            }\n            return -1;\n        };\n    }\n\n    function daysInMonth(year, month) {\n        if (isNaN(year) || isNaN(month)) {\n            return NaN;\n        }\n        var modMonth = mod(month, 12);\n        year += (month - modMonth) / 12;\n        return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);\n    }\n\n    // FORMATTING\n\n    addFormatToken('M', ['MM', 2], 'Mo', function () {\n        return this.month() + 1;\n    });\n\n    addFormatToken('MMM', 0, 0, function (format) {\n        return this.localeData().monthsShort(this, format);\n    });\n\n    addFormatToken('MMMM', 0, 0, function (format) {\n        return this.localeData().months(this, format);\n    });\n\n    // ALIASES\n\n    addUnitAlias('month', 'M');\n\n    // PRIORITY\n\n    addUnitPriority('month', 8);\n\n    // PARSING\n\n    addRegexToken('M',    match1to2);\n    addRegexToken('MM',   match1to2, match2);\n    addRegexToken('MMM',  function (isStrict, locale) {\n        return locale.monthsShortRegex(isStrict);\n    });\n    addRegexToken('MMMM', function (isStrict, locale) {\n        return locale.monthsRegex(isStrict);\n    });\n\n    addParseToken(['M', 'MM'], function (input, array) {\n        array[MONTH] = toInt(input) - 1;\n    });\n\n    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n        var month = config._locale.monthsParse(input, token, config._strict);\n        // if we didn't find a month name, mark the date as invalid.\n        if (month != null) {\n            array[MONTH] = month;\n        } else {\n            getParsingFlags(config).invalidMonth = input;\n        }\n    });\n\n    // LOCALES\n\n    var MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\n    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\n    function localeMonths (m, format) {\n        if (!m) {\n            return isArray(this._months) ? this._months :\n                this._months['standalone'];\n        }\n        return isArray(this._months) ? this._months[m.month()] :\n            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n    }\n\n    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\n    function localeMonthsShort (m, format) {\n        if (!m) {\n            return isArray(this._monthsShort) ? this._monthsShort :\n                this._monthsShort['standalone'];\n        }\n        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n    }\n\n    function handleStrictParse(monthName, format, strict) {\n        var i, ii, mom, llc = monthName.toLocaleLowerCase();\n        if (!this._monthsParse) {\n            // this is not used\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n            for (i = 0; i < 12; ++i) {\n                mom = createUTC([2000, i]);\n                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n            }\n        }\n\n        if (strict) {\n            if (format === 'MMM') {\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._longMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        } else {\n            if (format === 'MMM') {\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._longMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._longMonthsParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        }\n    }\n\n    function localeMonthsParse (monthName, format, strict) {\n        var i, mom, regex;\n\n        if (this._monthsParseExact) {\n            return handleStrictParse.call(this, monthName, format, strict);\n        }\n\n        if (!this._monthsParse) {\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n        }\n\n        // TODO: add sorting\n        // Sorting makes sure if one month (or abbr) is a prefix of another\n        // see sorting in computeMonthsParse\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, i]);\n            if (strict && !this._longMonthsParse[i]) {\n                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n            }\n            if (!strict && !this._monthsParse[i]) {\n                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (!strict && this._monthsParse[i].test(monthName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function setMonth (mom, value) {\n        var dayOfMonth;\n\n        if (!mom.isValid()) {\n            // No op\n            return mom;\n        }\n\n        if (typeof value === 'string') {\n            if (/^\\d+$/.test(value)) {\n                value = toInt(value);\n            } else {\n                value = mom.localeData().monthsParse(value);\n                // TODO: Another silent failure?\n                if (!isNumber(value)) {\n                    return mom;\n                }\n            }\n        }\n\n        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n        return mom;\n    }\n\n    function getSetMonth (value) {\n        if (value != null) {\n            setMonth(this, value);\n            hooks.updateOffset(this, true);\n            return this;\n        } else {\n            return get(this, 'Month');\n        }\n    }\n\n    function getDaysInMonth () {\n        return daysInMonth(this.year(), this.month());\n    }\n\n    var defaultMonthsShortRegex = matchWord;\n    function monthsShortRegex (isStrict) {\n        if (this._monthsParseExact) {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                computeMonthsParse.call(this);\n            }\n            if (isStrict) {\n                return this._monthsShortStrictRegex;\n            } else {\n                return this._monthsShortRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_monthsShortRegex')) {\n                this._monthsShortRegex = defaultMonthsShortRegex;\n            }\n            return this._monthsShortStrictRegex && isStrict ?\n                this._monthsShortStrictRegex : this._monthsShortRegex;\n        }\n    }\n\n    var defaultMonthsRegex = matchWord;\n    function monthsRegex (isStrict) {\n        if (this._monthsParseExact) {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                computeMonthsParse.call(this);\n            }\n            if (isStrict) {\n                return this._monthsStrictRegex;\n            } else {\n                return this._monthsRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                this._monthsRegex = defaultMonthsRegex;\n            }\n            return this._monthsStrictRegex && isStrict ?\n                this._monthsStrictRegex : this._monthsRegex;\n        }\n    }\n\n    function computeMonthsParse () {\n        function cmpLenRev(a, b) {\n            return b.length - a.length;\n        }\n\n        var shortPieces = [], longPieces = [], mixedPieces = [],\n            i, mom;\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, i]);\n            shortPieces.push(this.monthsShort(mom, ''));\n            longPieces.push(this.months(mom, ''));\n            mixedPieces.push(this.months(mom, ''));\n            mixedPieces.push(this.monthsShort(mom, ''));\n        }\n        // Sorting makes sure if one month (or abbr) is a prefix of another it\n        // will match the longer piece.\n        shortPieces.sort(cmpLenRev);\n        longPieces.sort(cmpLenRev);\n        mixedPieces.sort(cmpLenRev);\n        for (i = 0; i < 12; i++) {\n            shortPieces[i] = regexEscape(shortPieces[i]);\n            longPieces[i] = regexEscape(longPieces[i]);\n        }\n        for (i = 0; i < 24; i++) {\n            mixedPieces[i] = regexEscape(mixedPieces[i]);\n        }\n\n        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n        this._monthsShortRegex = this._monthsRegex;\n        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    }\n\n    function createDate (y, m, d, h, M, s, ms) {\n        // can't just apply() to create a date:\n        // https://stackoverflow.com/q/181348\n        var date;\n        // the date constructor remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            date = new Date(y + 400, m, d, h, M, s, ms);\n            if (isFinite(date.getFullYear())) {\n                date.setFullYear(y);\n            }\n        } else {\n            date = new Date(y, m, d, h, M, s, ms);\n        }\n\n        return date;\n    }\n\n    function createUTCDate (y) {\n        var date;\n        // the Date.UTC function remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            var args = Array.prototype.slice.call(arguments);\n            // preserve leap years using a full 400 year cycle, then reset\n            args[0] = y + 400;\n            date = new Date(Date.UTC.apply(null, args));\n            if (isFinite(date.getUTCFullYear())) {\n                date.setUTCFullYear(y);\n            }\n        } else {\n            date = new Date(Date.UTC.apply(null, arguments));\n        }\n\n        return date;\n    }\n\n    // start-of-first-week - start-of-year\n    function firstWeekOffset(year, dow, doy) {\n        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n            fwd = 7 + dow - doy,\n            // first-week day local weekday -- which local weekday is fwd\n            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n        return -fwdlw + fwd - 1;\n    }\n\n    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\n    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n        var localWeekday = (7 + weekday - dow) % 7,\n            weekOffset = firstWeekOffset(year, dow, doy),\n            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n            resYear, resDayOfYear;\n\n        if (dayOfYear <= 0) {\n            resYear = year - 1;\n            resDayOfYear = daysInYear(resYear) + dayOfYear;\n        } else if (dayOfYear > daysInYear(year)) {\n            resYear = year + 1;\n            resDayOfYear = dayOfYear - daysInYear(year);\n        } else {\n            resYear = year;\n            resDayOfYear = dayOfYear;\n        }\n\n        return {\n            year: resYear,\n            dayOfYear: resDayOfYear\n        };\n    }\n\n    function weekOfYear(mom, dow, doy) {\n        var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n            resWeek, resYear;\n\n        if (week < 1) {\n            resYear = mom.year() - 1;\n            resWeek = week + weeksInYear(resYear, dow, doy);\n        } else if (week > weeksInYear(mom.year(), dow, doy)) {\n            resWeek = week - weeksInYear(mom.year(), dow, doy);\n            resYear = mom.year() + 1;\n        } else {\n            resYear = mom.year();\n            resWeek = week;\n        }\n\n        return {\n            week: resWeek,\n            year: resYear\n        };\n    }\n\n    function weeksInYear(year, dow, doy) {\n        var weekOffset = firstWeekOffset(year, dow, doy),\n            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n    }\n\n    // FORMATTING\n\n    addFormatToken('w', ['ww', 2], 'wo', 'week');\n    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n    // ALIASES\n\n    addUnitAlias('week', 'w');\n    addUnitAlias('isoWeek', 'W');\n\n    // PRIORITIES\n\n    addUnitPriority('week', 5);\n    addUnitPriority('isoWeek', 5);\n\n    // PARSING\n\n    addRegexToken('w',  match1to2);\n    addRegexToken('ww', match1to2, match2);\n    addRegexToken('W',  match1to2);\n    addRegexToken('WW', match1to2, match2);\n\n    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n        week[token.substr(0, 1)] = toInt(input);\n    });\n\n    // HELPERS\n\n    // LOCALES\n\n    function localeWeek (mom) {\n        return weekOfYear(mom, this._week.dow, this._week.doy).week;\n    }\n\n    var defaultLocaleWeek = {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 6th is the first week of the year.\n    };\n\n    function localeFirstDayOfWeek () {\n        return this._week.dow;\n    }\n\n    function localeFirstDayOfYear () {\n        return this._week.doy;\n    }\n\n    // MOMENTS\n\n    function getSetWeek (input) {\n        var week = this.localeData().week(this);\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    function getSetISOWeek (input) {\n        var week = weekOfYear(this, 1, 4).week;\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    // FORMATTING\n\n    addFormatToken('d', 0, 'do', 'day');\n\n    addFormatToken('dd', 0, 0, function (format) {\n        return this.localeData().weekdaysMin(this, format);\n    });\n\n    addFormatToken('ddd', 0, 0, function (format) {\n        return this.localeData().weekdaysShort(this, format);\n    });\n\n    addFormatToken('dddd', 0, 0, function (format) {\n        return this.localeData().weekdays(this, format);\n    });\n\n    addFormatToken('e', 0, 0, 'weekday');\n    addFormatToken('E', 0, 0, 'isoWeekday');\n\n    // ALIASES\n\n    addUnitAlias('day', 'd');\n    addUnitAlias('weekday', 'e');\n    addUnitAlias('isoWeekday', 'E');\n\n    // PRIORITY\n    addUnitPriority('day', 11);\n    addUnitPriority('weekday', 11);\n    addUnitPriority('isoWeekday', 11);\n\n    // PARSING\n\n    addRegexToken('d',    match1to2);\n    addRegexToken('e',    match1to2);\n    addRegexToken('E',    match1to2);\n    addRegexToken('dd',   function (isStrict, locale) {\n        return locale.weekdaysMinRegex(isStrict);\n    });\n    addRegexToken('ddd',   function (isStrict, locale) {\n        return locale.weekdaysShortRegex(isStrict);\n    });\n    addRegexToken('dddd',   function (isStrict, locale) {\n        return locale.weekdaysRegex(isStrict);\n    });\n\n    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n        var weekday = config._locale.weekdaysParse(input, token, config._strict);\n        // if we didn't get a weekday name, mark the date as invalid\n        if (weekday != null) {\n            week.d = weekday;\n        } else {\n            getParsingFlags(config).invalidWeekday = input;\n        }\n    });\n\n    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n        week[token] = toInt(input);\n    });\n\n    // HELPERS\n\n    function parseWeekday(input, locale) {\n        if (typeof input !== 'string') {\n            return input;\n        }\n\n        if (!isNaN(input)) {\n            return parseInt(input, 10);\n        }\n\n        input = locale.weekdaysParse(input);\n        if (typeof input === 'number') {\n            return input;\n        }\n\n        return null;\n    }\n\n    function parseIsoWeekday(input, locale) {\n        if (typeof input === 'string') {\n            return locale.weekdaysParse(input) % 7 || 7;\n        }\n        return isNaN(input) ? null : input;\n    }\n\n    // LOCALES\n    function shiftWeekdays (ws, n) {\n        return ws.slice(n, 7).concat(ws.slice(0, n));\n    }\n\n    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\n    function localeWeekdays (m, format) {\n        var weekdays = isArray(this._weekdays) ? this._weekdays :\n            this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone'];\n        return (m === true) ? shiftWeekdays(weekdays, this._week.dow)\n            : (m) ? weekdays[m.day()] : weekdays;\n    }\n\n    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\n    function localeWeekdaysShort (m) {\n        return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow)\n            : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n    }\n\n    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\n    function localeWeekdaysMin (m) {\n        return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow)\n            : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n    }\n\n    function handleStrictParse$1(weekdayName, format, strict) {\n        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n            this._shortWeekdaysParse = [];\n            this._minWeekdaysParse = [];\n\n            for (i = 0; i < 7; ++i) {\n                mom = createUTC([2000, 1]).day(i);\n                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n            }\n        }\n\n        if (strict) {\n            if (format === 'dddd') {\n                ii = indexOf.call(this._weekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else if (format === 'ddd') {\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        } else {\n            if (format === 'dddd') {\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else if (format === 'ddd') {\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        }\n    }\n\n    function localeWeekdaysParse (weekdayName, format, strict) {\n        var i, mom, regex;\n\n        if (this._weekdaysParseExact) {\n            return handleStrictParse$1.call(this, weekdayName, format, strict);\n        }\n\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n            this._minWeekdaysParse = [];\n            this._shortWeekdaysParse = [];\n            this._fullWeekdaysParse = [];\n        }\n\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n\n            mom = createUTC([2000, 1]).day(i);\n            if (strict && !this._fullWeekdaysParse[i]) {\n                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\\\.?') + '$', 'i');\n                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\\\.?') + '$', 'i');\n                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\\\.?') + '$', 'i');\n            }\n            if (!this._weekdaysParse[i]) {\n                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function getSetDayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n        if (input != null) {\n            input = parseWeekday(input, this.localeData());\n            return this.add(input - day, 'd');\n        } else {\n            return day;\n        }\n    }\n\n    function getSetLocaleDayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n        return input == null ? weekday : this.add(input - weekday, 'd');\n    }\n\n    function getSetISODayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n\n        // behaves the same as moment#day except\n        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n        // as a setter, sunday should belong to the previous week.\n\n        if (input != null) {\n            var weekday = parseIsoWeekday(input, this.localeData());\n            return this.day(this.day() % 7 ? weekday : weekday - 7);\n        } else {\n            return this.day() || 7;\n        }\n    }\n\n    var defaultWeekdaysRegex = matchWord;\n    function weekdaysRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysStrictRegex;\n            } else {\n                return this._weekdaysRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                this._weekdaysRegex = defaultWeekdaysRegex;\n            }\n            return this._weekdaysStrictRegex && isStrict ?\n                this._weekdaysStrictRegex : this._weekdaysRegex;\n        }\n    }\n\n    var defaultWeekdaysShortRegex = matchWord;\n    function weekdaysShortRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysShortStrictRegex;\n            } else {\n                return this._weekdaysShortRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n                this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n            }\n            return this._weekdaysShortStrictRegex && isStrict ?\n                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n        }\n    }\n\n    var defaultWeekdaysMinRegex = matchWord;\n    function weekdaysMinRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysMinStrictRegex;\n            } else {\n                return this._weekdaysMinRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n                this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n            }\n            return this._weekdaysMinStrictRegex && isStrict ?\n                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n        }\n    }\n\n\n    function computeWeekdaysParse () {\n        function cmpLenRev(a, b) {\n            return b.length - a.length;\n        }\n\n        var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n            i, mom, minp, shortp, longp;\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, 1]).day(i);\n            minp = this.weekdaysMin(mom, '');\n            shortp = this.weekdaysShort(mom, '');\n            longp = this.weekdays(mom, '');\n            minPieces.push(minp);\n            shortPieces.push(shortp);\n            longPieces.push(longp);\n            mixedPieces.push(minp);\n            mixedPieces.push(shortp);\n            mixedPieces.push(longp);\n        }\n        // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n        // will match the longer piece.\n        minPieces.sort(cmpLenRev);\n        shortPieces.sort(cmpLenRev);\n        longPieces.sort(cmpLenRev);\n        mixedPieces.sort(cmpLenRev);\n        for (i = 0; i < 7; i++) {\n            shortPieces[i] = regexEscape(shortPieces[i]);\n            longPieces[i] = regexEscape(longPieces[i]);\n            mixedPieces[i] = regexEscape(mixedPieces[i]);\n        }\n\n        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n        this._weekdaysShortRegex = this._weekdaysRegex;\n        this._weekdaysMinRegex = this._weekdaysRegex;\n\n        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n    }\n\n    // FORMATTING\n\n    function hFormat() {\n        return this.hours() % 12 || 12;\n    }\n\n    function kFormat() {\n        return this.hours() || 24;\n    }\n\n    addFormatToken('H', ['HH', 2], 0, 'hour');\n    addFormatToken('h', ['hh', 2], 0, hFormat);\n    addFormatToken('k', ['kk', 2], 0, kFormat);\n\n    addFormatToken('hmm', 0, 0, function () {\n        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n    });\n\n    addFormatToken('hmmss', 0, 0, function () {\n        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n            zeroFill(this.seconds(), 2);\n    });\n\n    addFormatToken('Hmm', 0, 0, function () {\n        return '' + this.hours() + zeroFill(this.minutes(), 2);\n    });\n\n    addFormatToken('Hmmss', 0, 0, function () {\n        return '' + this.hours() + zeroFill(this.minutes(), 2) +\n            zeroFill(this.seconds(), 2);\n    });\n\n    function meridiem (token, lowercase) {\n        addFormatToken(token, 0, 0, function () {\n            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n        });\n    }\n\n    meridiem('a', true);\n    meridiem('A', false);\n\n    // ALIASES\n\n    addUnitAlias('hour', 'h');\n\n    // PRIORITY\n    addUnitPriority('hour', 13);\n\n    // PARSING\n\n    function matchMeridiem (isStrict, locale) {\n        return locale._meridiemParse;\n    }\n\n    addRegexToken('a',  matchMeridiem);\n    addRegexToken('A',  matchMeridiem);\n    addRegexToken('H',  match1to2);\n    addRegexToken('h',  match1to2);\n    addRegexToken('k',  match1to2);\n    addRegexToken('HH', match1to2, match2);\n    addRegexToken('hh', match1to2, match2);\n    addRegexToken('kk', match1to2, match2);\n\n    addRegexToken('hmm', match3to4);\n    addRegexToken('hmmss', match5to6);\n    addRegexToken('Hmm', match3to4);\n    addRegexToken('Hmmss', match5to6);\n\n    addParseToken(['H', 'HH'], HOUR);\n    addParseToken(['k', 'kk'], function (input, array, config) {\n        var kInput = toInt(input);\n        array[HOUR] = kInput === 24 ? 0 : kInput;\n    });\n    addParseToken(['a', 'A'], function (input, array, config) {\n        config._isPm = config._locale.isPM(input);\n        config._meridiem = input;\n    });\n    addParseToken(['h', 'hh'], function (input, array, config) {\n        array[HOUR] = toInt(input);\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('hmm', function (input, array, config) {\n        var pos = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos));\n        array[MINUTE] = toInt(input.substr(pos));\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('hmmss', function (input, array, config) {\n        var pos1 = input.length - 4;\n        var pos2 = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos1));\n        array[MINUTE] = toInt(input.substr(pos1, 2));\n        array[SECOND] = toInt(input.substr(pos2));\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('Hmm', function (input, array, config) {\n        var pos = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos));\n        array[MINUTE] = toInt(input.substr(pos));\n    });\n    addParseToken('Hmmss', function (input, array, config) {\n        var pos1 = input.length - 4;\n        var pos2 = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos1));\n        array[MINUTE] = toInt(input.substr(pos1, 2));\n        array[SECOND] = toInt(input.substr(pos2));\n    });\n\n    // LOCALES\n\n    function localeIsPM (input) {\n        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n        // Using charAt should be more compatible.\n        return ((input + '').toLowerCase().charAt(0) === 'p');\n    }\n\n    var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\n    function localeMeridiem (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'pm' : 'PM';\n        } else {\n            return isLower ? 'am' : 'AM';\n        }\n    }\n\n\n    // MOMENTS\n\n    // Setting the hour should keep the time, because the user explicitly\n    // specified which hour they want. So trying to maintain the same hour (in\n    // a new timezone) makes sense. Adding/subtracting hours does not follow\n    // this rule.\n    var getSetHour = makeGetSet('Hours', true);\n\n    var baseConfig = {\n        calendar: defaultCalendar,\n        longDateFormat: defaultLongDateFormat,\n        invalidDate: defaultInvalidDate,\n        ordinal: defaultOrdinal,\n        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n        relativeTime: defaultRelativeTime,\n\n        months: defaultLocaleMonths,\n        monthsShort: defaultLocaleMonthsShort,\n\n        week: defaultLocaleWeek,\n\n        weekdays: defaultLocaleWeekdays,\n        weekdaysMin: defaultLocaleWeekdaysMin,\n        weekdaysShort: defaultLocaleWeekdaysShort,\n\n        meridiemParse: defaultLocaleMeridiemParse\n    };\n\n    // internal storage for locale config files\n    var locales = {};\n    var localeFamilies = {};\n    var globalLocale;\n\n    function normalizeLocale(key) {\n        return key ? key.toLowerCase().replace('_', '-') : key;\n    }\n\n    // pick the locale from the array\n    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\n    function chooseLocale(names) {\n        var i = 0, j, next, locale, split;\n\n        while (i < names.length) {\n            split = normalizeLocale(names[i]).split('-');\n            j = split.length;\n            next = normalizeLocale(names[i + 1]);\n            next = next ? next.split('-') : null;\n            while (j > 0) {\n                locale = loadLocale(split.slice(0, j).join('-'));\n                if (locale) {\n                    return locale;\n                }\n                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                    //the next array item is better than a shallower substring of this one\n                    break;\n                }\n                j--;\n            }\n            i++;\n        }\n        return globalLocale;\n    }\n\n    function loadLocale(name) {\n        var oldLocale = null;\n        // TODO: Find a better way to register and load all the locales in Node\n        if (!locales[name] && (typeof module !== 'undefined') &&\n                module && module.exports) {\n            try {\n                oldLocale = globalLocale._abbr;\n                var aliasedRequire = require;\n                !(function webpackMissingModule() { var e = new Error(\"Cannot find module 'undefined'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }());\n                getSetGlobalLocale(oldLocale);\n            } catch (e) {}\n        }\n        return locales[name];\n    }\n\n    // This function will load locale and then set the global locale.  If\n    // no arguments are passed in, it will simply return the current global\n    // locale key.\n    function getSetGlobalLocale (key, values) {\n        var data;\n        if (key) {\n            if (isUndefined(values)) {\n                data = getLocale(key);\n            }\n            else {\n                data = defineLocale(key, values);\n            }\n\n            if (data) {\n                // moment.duration._locale = moment._locale = data;\n                globalLocale = data;\n            }\n            else {\n                if ((typeof console !==  'undefined') && console.warn) {\n                    //warn user if arguments are passed but the locale could not be set\n                    console.warn('Locale ' + key +  ' not found. Did you forget to load it?');\n                }\n            }\n        }\n\n        return globalLocale._abbr;\n    }\n\n    function defineLocale (name, config) {\n        if (config !== null) {\n            var locale, parentConfig = baseConfig;\n            config.abbr = name;\n            if (locales[name] != null) {\n                deprecateSimple('defineLocaleOverride',\n                        'use moment.updateLocale(localeName, config) to change ' +\n                        'an existing locale. moment.defineLocale(localeName, ' +\n                        'config) should only be used for creating a new locale ' +\n                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n                parentConfig = locales[name]._config;\n            } else if (config.parentLocale != null) {\n                if (locales[config.parentLocale] != null) {\n                    parentConfig = locales[config.parentLocale]._config;\n                } else {\n                    locale = loadLocale(config.parentLocale);\n                    if (locale != null) {\n                        parentConfig = locale._config;\n                    } else {\n                        if (!localeFamilies[config.parentLocale]) {\n                            localeFamilies[config.parentLocale] = [];\n                        }\n                        localeFamilies[config.parentLocale].push({\n                            name: name,\n                            config: config\n                        });\n                        return null;\n                    }\n                }\n            }\n            locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n            if (localeFamilies[name]) {\n                localeFamilies[name].forEach(function (x) {\n                    defineLocale(x.name, x.config);\n                });\n            }\n\n            // backwards compat for now: also set the locale\n            // make sure we set the locale AFTER all child locales have been\n            // created, so we won't end up with the child locale set.\n            getSetGlobalLocale(name);\n\n\n            return locales[name];\n        } else {\n            // useful for testing\n            delete locales[name];\n            return null;\n        }\n    }\n\n    function updateLocale(name, config) {\n        if (config != null) {\n            var locale, tmpLocale, parentConfig = baseConfig;\n            // MERGE\n            tmpLocale = loadLocale(name);\n            if (tmpLocale != null) {\n                parentConfig = tmpLocale._config;\n            }\n            config = mergeConfigs(parentConfig, config);\n            locale = new Locale(config);\n            locale.parentLocale = locales[name];\n            locales[name] = locale;\n\n            // backwards compat for now: also set the locale\n            getSetGlobalLocale(name);\n        } else {\n            // pass null for config to unupdate, useful for tests\n            if (locales[name] != null) {\n                if (locales[name].parentLocale != null) {\n                    locales[name] = locales[name].parentLocale;\n                } else if (locales[name] != null) {\n                    delete locales[name];\n                }\n            }\n        }\n        return locales[name];\n    }\n\n    // returns locale data\n    function getLocale (key) {\n        var locale;\n\n        if (key && key._locale && key._locale._abbr) {\n            key = key._locale._abbr;\n        }\n\n        if (!key) {\n            return globalLocale;\n        }\n\n        if (!isArray(key)) {\n            //short-circuit everything else\n            locale = loadLocale(key);\n            if (locale) {\n                return locale;\n            }\n            key = [key];\n        }\n\n        return chooseLocale(key);\n    }\n\n    function listLocales() {\n        return keys(locales);\n    }\n\n    function checkOverflow (m) {\n        var overflow;\n        var a = m._a;\n\n        if (a && getParsingFlags(m).overflow === -2) {\n            overflow =\n                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n                -1;\n\n            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n                overflow = DATE;\n            }\n            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n                overflow = WEEK;\n            }\n            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n                overflow = WEEKDAY;\n            }\n\n            getParsingFlags(m).overflow = overflow;\n        }\n\n        return m;\n    }\n\n    // Pick the first defined of two or three arguments.\n    function defaults(a, b, c) {\n        if (a != null) {\n            return a;\n        }\n        if (b != null) {\n            return b;\n        }\n        return c;\n    }\n\n    function currentDateArray(config) {\n        // hooks is actually the exported moment object\n        var nowValue = new Date(hooks.now());\n        if (config._useUTC) {\n            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n        }\n        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n    }\n\n    // convert an array to a date.\n    // the array should mirror the parameters below\n    // note: all values past the year are optional and will default to the lowest possible value.\n    // [year, month, day , hour, minute, second, millisecond]\n    function configFromArray (config) {\n        var i, date, input = [], currentDate, expectedWeekday, yearToUse;\n\n        if (config._d) {\n            return;\n        }\n\n        currentDate = currentDateArray(config);\n\n        //compute day of the year from weeks and weekdays\n        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n            dayOfYearFromWeekInfo(config);\n        }\n\n        //if the day of the year is set, figure out what it is\n        if (config._dayOfYear != null) {\n            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n            if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n                getParsingFlags(config)._overflowDayOfYear = true;\n            }\n\n            date = createUTCDate(yearToUse, 0, config._dayOfYear);\n            config._a[MONTH] = date.getUTCMonth();\n            config._a[DATE] = date.getUTCDate();\n        }\n\n        // Default to current date.\n        // * if no year, month, day of month are given, default to today\n        // * if day of month is given, default month and year\n        // * if month is given, default only year\n        // * if year is given, don't default anything\n        for (i = 0; i < 3 && config._a[i] == null; ++i) {\n            config._a[i] = input[i] = currentDate[i];\n        }\n\n        // Zero out whatever was not defaulted, including time\n        for (; i < 7; i++) {\n            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n        }\n\n        // Check for 24:00:00.000\n        if (config._a[HOUR] === 24 &&\n                config._a[MINUTE] === 0 &&\n                config._a[SECOND] === 0 &&\n                config._a[MILLISECOND] === 0) {\n            config._nextDay = true;\n            config._a[HOUR] = 0;\n        }\n\n        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n        expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();\n\n        // Apply timezone offset from input. The actual utcOffset can be changed\n        // with parseZone.\n        if (config._tzm != null) {\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n        }\n\n        if (config._nextDay) {\n            config._a[HOUR] = 24;\n        }\n\n        // check for mismatching day of week\n        if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {\n            getParsingFlags(config).weekdayMismatch = true;\n        }\n    }\n\n    function dayOfYearFromWeekInfo(config) {\n        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n        w = config._w;\n        if (w.GG != null || w.W != null || w.E != null) {\n            dow = 1;\n            doy = 4;\n\n            // TODO: We need to take the current isoWeekYear, but that depends on\n            // how we interpret now (local, utc, fixed offset). So create\n            // a now version of current config (take local/utc/offset flags, and\n            // create now).\n            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n            week = defaults(w.W, 1);\n            weekday = defaults(w.E, 1);\n            if (weekday < 1 || weekday > 7) {\n                weekdayOverflow = true;\n            }\n        } else {\n            dow = config._locale._week.dow;\n            doy = config._locale._week.doy;\n\n            var curWeek = weekOfYear(createLocal(), dow, doy);\n\n            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n            // Default to current week.\n            week = defaults(w.w, curWeek.week);\n\n            if (w.d != null) {\n                // weekday -- low day numbers are considered next week\n                weekday = w.d;\n                if (weekday < 0 || weekday > 6) {\n                    weekdayOverflow = true;\n                }\n            } else if (w.e != null) {\n                // local weekday -- counting starts from beginning of week\n                weekday = w.e + dow;\n                if (w.e < 0 || w.e > 6) {\n                    weekdayOverflow = true;\n                }\n            } else {\n                // default to beginning of week\n                weekday = dow;\n            }\n        }\n        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n            getParsingFlags(config)._overflowWeeks = true;\n        } else if (weekdayOverflow != null) {\n            getParsingFlags(config)._overflowWeekday = true;\n        } else {\n            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n            config._a[YEAR] = temp.year;\n            config._dayOfYear = temp.dayOfYear;\n        }\n    }\n\n    // iso 8601 regex\n    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\n    var extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n    var basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\n    var tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\n    var isoDates = [\n        ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n        ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n        ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n        ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n        ['YYYY-DDD', /\\d{4}-\\d{3}/],\n        ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n        ['YYYYYYMMDD', /[+-]\\d{10}/],\n        ['YYYYMMDD', /\\d{8}/],\n        // YYYYMM is NOT allowed by the standard\n        ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n        ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n        ['YYYYDDD', /\\d{7}/]\n    ];\n\n    // iso time formats and regexes\n    var isoTimes = [\n        ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n        ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n        ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n        ['HH:mm', /\\d\\d:\\d\\d/],\n        ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n        ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n        ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n        ['HHmm', /\\d\\d\\d\\d/],\n        ['HH', /\\d\\d/]\n    ];\n\n    var aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n    // date from iso format\n    function configFromISO(config) {\n        var i, l,\n            string = config._i,\n            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n            allowTime, dateFormat, timeFormat, tzFormat;\n\n        if (match) {\n            getParsingFlags(config).iso = true;\n\n            for (i = 0, l = isoDates.length; i < l; i++) {\n                if (isoDates[i][1].exec(match[1])) {\n                    dateFormat = isoDates[i][0];\n                    allowTime = isoDates[i][2] !== false;\n                    break;\n                }\n            }\n            if (dateFormat == null) {\n                config._isValid = false;\n                return;\n            }\n            if (match[3]) {\n                for (i = 0, l = isoTimes.length; i < l; i++) {\n                    if (isoTimes[i][1].exec(match[3])) {\n                        // match[2] should be 'T' or space\n                        timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                        break;\n                    }\n                }\n                if (timeFormat == null) {\n                    config._isValid = false;\n                    return;\n                }\n            }\n            if (!allowTime && timeFormat != null) {\n                config._isValid = false;\n                return;\n            }\n            if (match[4]) {\n                if (tzRegex.exec(match[4])) {\n                    tzFormat = 'Z';\n                } else {\n                    config._isValid = false;\n                    return;\n                }\n            }\n            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n            configFromStringAndFormat(config);\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\n    var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d{1,2})\\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(\\d{2,4})\\s(\\d\\d):(\\d\\d)(?::(\\d\\d))?\\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\\d{4}))$/;\n\n    function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {\n        var result = [\n            untruncateYear(yearStr),\n            defaultLocaleMonthsShort.indexOf(monthStr),\n            parseInt(dayStr, 10),\n            parseInt(hourStr, 10),\n            parseInt(minuteStr, 10)\n        ];\n\n        if (secondStr) {\n            result.push(parseInt(secondStr, 10));\n        }\n\n        return result;\n    }\n\n    function untruncateYear(yearStr) {\n        var year = parseInt(yearStr, 10);\n        if (year <= 49) {\n            return 2000 + year;\n        } else if (year <= 999) {\n            return 1900 + year;\n        }\n        return year;\n    }\n\n    function preprocessRFC2822(s) {\n        // Remove comments and folding whitespace and replace multiple-spaces with a single space\n        return s.replace(/\\([^)]*\\)|[\\n\\t]/g, ' ').replace(/(\\s\\s+)/g, ' ').replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n    }\n\n    function checkWeekday(weekdayStr, parsedInput, config) {\n        if (weekdayStr) {\n            // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),\n                weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();\n            if (weekdayProvided !== weekdayActual) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return false;\n            }\n        }\n        return true;\n    }\n\n    var obsOffsets = {\n        UT: 0,\n        GMT: 0,\n        EDT: -4 * 60,\n        EST: -5 * 60,\n        CDT: -5 * 60,\n        CST: -6 * 60,\n        MDT: -6 * 60,\n        MST: -7 * 60,\n        PDT: -7 * 60,\n        PST: -8 * 60\n    };\n\n    function calculateOffset(obsOffset, militaryOffset, numOffset) {\n        if (obsOffset) {\n            return obsOffsets[obsOffset];\n        } else if (militaryOffset) {\n            // the only allowed military tz is Z\n            return 0;\n        } else {\n            var hm = parseInt(numOffset, 10);\n            var m = hm % 100, h = (hm - m) / 100;\n            return h * 60 + m;\n        }\n    }\n\n    // date and time from ref 2822 format\n    function configFromRFC2822(config) {\n        var match = rfc2822.exec(preprocessRFC2822(config._i));\n        if (match) {\n            var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);\n            if (!checkWeekday(match[1], parsedArray, config)) {\n                return;\n            }\n\n            config._a = parsedArray;\n            config._tzm = calculateOffset(match[8], match[9], match[10]);\n\n            config._d = createUTCDate.apply(null, config._a);\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n\n            getParsingFlags(config).rfc2822 = true;\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // date from iso format or fallback\n    function configFromString(config) {\n        var matched = aspNetJsonRegex.exec(config._i);\n\n        if (matched !== null) {\n            config._d = new Date(+matched[1]);\n            return;\n        }\n\n        configFromISO(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n        } else {\n            return;\n        }\n\n        configFromRFC2822(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n        } else {\n            return;\n        }\n\n        // Final attempt, use Input Fallback\n        hooks.createFromInputFallback(config);\n    }\n\n    hooks.createFromInputFallback = deprecate(\n        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n        'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n        'discouraged and will be removed in an upcoming major release. Please refer to ' +\n        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n        function (config) {\n            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n        }\n    );\n\n    // constant that refers to the ISO standard\n    hooks.ISO_8601 = function () {};\n\n    // constant that refers to the RFC 2822 form\n    hooks.RFC_2822 = function () {};\n\n    // date from string and format string\n    function configFromStringAndFormat(config) {\n        // TODO: Move this to another part of the creation flow to prevent circular deps\n        if (config._f === hooks.ISO_8601) {\n            configFromISO(config);\n            return;\n        }\n        if (config._f === hooks.RFC_2822) {\n            configFromRFC2822(config);\n            return;\n        }\n        config._a = [];\n        getParsingFlags(config).empty = true;\n\n        // This array is used to make a Date, either with `new Date` or `Date.UTC`\n        var string = '' + config._i,\n            i, parsedInput, tokens, token, skipped,\n            stringLength = string.length,\n            totalParsedInputLength = 0;\n\n        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n        for (i = 0; i < tokens.length; i++) {\n            token = tokens[i];\n            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n            // console.log('token', token, 'parsedInput', parsedInput,\n            //         'regex', getParseRegexForToken(token, config));\n            if (parsedInput) {\n                skipped = string.substr(0, string.indexOf(parsedInput));\n                if (skipped.length > 0) {\n                    getParsingFlags(config).unusedInput.push(skipped);\n                }\n                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n                totalParsedInputLength += parsedInput.length;\n            }\n            // don't parse if it's not a known token\n            if (formatTokenFunctions[token]) {\n                if (parsedInput) {\n                    getParsingFlags(config).empty = false;\n                }\n                else {\n                    getParsingFlags(config).unusedTokens.push(token);\n                }\n                addTimeToArrayFromToken(token, parsedInput, config);\n            }\n            else if (config._strict && !parsedInput) {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n        }\n\n        // add remaining unparsed input length to the string\n        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n        if (string.length > 0) {\n            getParsingFlags(config).unusedInput.push(string);\n        }\n\n        // clear _12h flag if hour is <= 12\n        if (config._a[HOUR] <= 12 &&\n            getParsingFlags(config).bigHour === true &&\n            config._a[HOUR] > 0) {\n            getParsingFlags(config).bigHour = undefined;\n        }\n\n        getParsingFlags(config).parsedDateParts = config._a.slice(0);\n        getParsingFlags(config).meridiem = config._meridiem;\n        // handle meridiem\n        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n        configFromArray(config);\n        checkOverflow(config);\n    }\n\n\n    function meridiemFixWrap (locale, hour, meridiem) {\n        var isPm;\n\n        if (meridiem == null) {\n            // nothing to do\n            return hour;\n        }\n        if (locale.meridiemHour != null) {\n            return locale.meridiemHour(hour, meridiem);\n        } else if (locale.isPM != null) {\n            // Fallback\n            isPm = locale.isPM(meridiem);\n            if (isPm && hour < 12) {\n                hour += 12;\n            }\n            if (!isPm && hour === 12) {\n                hour = 0;\n            }\n            return hour;\n        } else {\n            // this is not supposed to happen\n            return hour;\n        }\n    }\n\n    // date from string and array of format strings\n    function configFromStringAndArray(config) {\n        var tempConfig,\n            bestMoment,\n\n            scoreToBeat,\n            i,\n            currentScore;\n\n        if (config._f.length === 0) {\n            getParsingFlags(config).invalidFormat = true;\n            config._d = new Date(NaN);\n            return;\n        }\n\n        for (i = 0; i < config._f.length; i++) {\n            currentScore = 0;\n            tempConfig = copyConfig({}, config);\n            if (config._useUTC != null) {\n                tempConfig._useUTC = config._useUTC;\n            }\n            tempConfig._f = config._f[i];\n            configFromStringAndFormat(tempConfig);\n\n            if (!isValid(tempConfig)) {\n                continue;\n            }\n\n            // if there is any input that was not parsed add a penalty for that format\n            currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n            //or tokens\n            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n            getParsingFlags(tempConfig).score = currentScore;\n\n            if (scoreToBeat == null || currentScore < scoreToBeat) {\n                scoreToBeat = currentScore;\n                bestMoment = tempConfig;\n            }\n        }\n\n        extend(config, bestMoment || tempConfig);\n    }\n\n    function configFromObject(config) {\n        if (config._d) {\n            return;\n        }\n\n        var i = normalizeObjectUnits(config._i);\n        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n            return obj && parseInt(obj, 10);\n        });\n\n        configFromArray(config);\n    }\n\n    function createFromConfig (config) {\n        var res = new Moment(checkOverflow(prepareConfig(config)));\n        if (res._nextDay) {\n            // Adding is smart enough around DST\n            res.add(1, 'd');\n            res._nextDay = undefined;\n        }\n\n        return res;\n    }\n\n    function prepareConfig (config) {\n        var input = config._i,\n            format = config._f;\n\n        config._locale = config._locale || getLocale(config._l);\n\n        if (input === null || (format === undefined && input === '')) {\n            return createInvalid({nullInput: true});\n        }\n\n        if (typeof input === 'string') {\n            config._i = input = config._locale.preparse(input);\n        }\n\n        if (isMoment(input)) {\n            return new Moment(checkOverflow(input));\n        } else if (isDate(input)) {\n            config._d = input;\n        } else if (isArray(format)) {\n            configFromStringAndArray(config);\n        } else if (format) {\n            configFromStringAndFormat(config);\n        }  else {\n            configFromInput(config);\n        }\n\n        if (!isValid(config)) {\n            config._d = null;\n        }\n\n        return config;\n    }\n\n    function configFromInput(config) {\n        var input = config._i;\n        if (isUndefined(input)) {\n            config._d = new Date(hooks.now());\n        } else if (isDate(input)) {\n            config._d = new Date(input.valueOf());\n        } else if (typeof input === 'string') {\n            configFromString(config);\n        } else if (isArray(input)) {\n            config._a = map(input.slice(0), function (obj) {\n                return parseInt(obj, 10);\n            });\n            configFromArray(config);\n        } else if (isObject(input)) {\n            configFromObject(config);\n        } else if (isNumber(input)) {\n            // from milliseconds\n            config._d = new Date(input);\n        } else {\n            hooks.createFromInputFallback(config);\n        }\n    }\n\n    function createLocalOrUTC (input, format, locale, strict, isUTC) {\n        var c = {};\n\n        if (locale === true || locale === false) {\n            strict = locale;\n            locale = undefined;\n        }\n\n        if ((isObject(input) && isObjectEmpty(input)) ||\n                (isArray(input) && input.length === 0)) {\n            input = undefined;\n        }\n        // object construction must be done this way.\n        // https://github.com/moment/moment/issues/1423\n        c._isAMomentObject = true;\n        c._useUTC = c._isUTC = isUTC;\n        c._l = locale;\n        c._i = input;\n        c._f = format;\n        c._strict = strict;\n\n        return createFromConfig(c);\n    }\n\n    function createLocal (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, false);\n    }\n\n    var prototypeMin = deprecate(\n        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n        function () {\n            var other = createLocal.apply(null, arguments);\n            if (this.isValid() && other.isValid()) {\n                return other < this ? this : other;\n            } else {\n                return createInvalid();\n            }\n        }\n    );\n\n    var prototypeMax = deprecate(\n        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n        function () {\n            var other = createLocal.apply(null, arguments);\n            if (this.isValid() && other.isValid()) {\n                return other > this ? this : other;\n            } else {\n                return createInvalid();\n            }\n        }\n    );\n\n    // Pick a moment m from moments so that m[fn](other) is true for all\n    // other. This relies on the function fn to be transitive.\n    //\n    // moments should either be an array of moment objects or an array, whose\n    // first element is an array of moment objects.\n    function pickBy(fn, moments) {\n        var res, i;\n        if (moments.length === 1 && isArray(moments[0])) {\n            moments = moments[0];\n        }\n        if (!moments.length) {\n            return createLocal();\n        }\n        res = moments[0];\n        for (i = 1; i < moments.length; ++i) {\n            if (!moments[i].isValid() || moments[i][fn](res)) {\n                res = moments[i];\n            }\n        }\n        return res;\n    }\n\n    // TODO: Use [].sort instead?\n    function min () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isBefore', args);\n    }\n\n    function max () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isAfter', args);\n    }\n\n    var now = function () {\n        return Date.now ? Date.now() : +(new Date());\n    };\n\n    var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\n    function isDurationValid(m) {\n        for (var key in m) {\n            if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n                return false;\n            }\n        }\n\n        var unitHasDecimal = false;\n        for (var i = 0; i < ordering.length; ++i) {\n            if (m[ordering[i]]) {\n                if (unitHasDecimal) {\n                    return false; // only allow non-integers for smallest unit\n                }\n                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                    unitHasDecimal = true;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    function isValid$1() {\n        return this._isValid;\n    }\n\n    function createInvalid$1() {\n        return createDuration(NaN);\n    }\n\n    function Duration (duration) {\n        var normalizedInput = normalizeObjectUnits(duration),\n            years = normalizedInput.year || 0,\n            quarters = normalizedInput.quarter || 0,\n            months = normalizedInput.month || 0,\n            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,\n            days = normalizedInput.day || 0,\n            hours = normalizedInput.hour || 0,\n            minutes = normalizedInput.minute || 0,\n            seconds = normalizedInput.second || 0,\n            milliseconds = normalizedInput.millisecond || 0;\n\n        this._isValid = isDurationValid(normalizedInput);\n\n        // representation for dateAddRemove\n        this._milliseconds = +milliseconds +\n            seconds * 1e3 + // 1000\n            minutes * 6e4 + // 1000 * 60\n            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n        // Because of dateAddRemove treats 24 hours as different from a\n        // day when working around DST, we need to store them separately\n        this._days = +days +\n            weeks * 7;\n        // It is impossible to translate months into days without knowing\n        // which months you are are talking about, so we have to store\n        // it separately.\n        this._months = +months +\n            quarters * 3 +\n            years * 12;\n\n        this._data = {};\n\n        this._locale = getLocale();\n\n        this._bubble();\n    }\n\n    function isDuration (obj) {\n        return obj instanceof Duration;\n    }\n\n    function absRound (number) {\n        if (number < 0) {\n            return Math.round(-1 * number) * -1;\n        } else {\n            return Math.round(number);\n        }\n    }\n\n    // FORMATTING\n\n    function offset (token, separator) {\n        addFormatToken(token, 0, 0, function () {\n            var offset = this.utcOffset();\n            var sign = '+';\n            if (offset < 0) {\n                offset = -offset;\n                sign = '-';\n            }\n            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n        });\n    }\n\n    offset('Z', ':');\n    offset('ZZ', '');\n\n    // PARSING\n\n    addRegexToken('Z',  matchShortOffset);\n    addRegexToken('ZZ', matchShortOffset);\n    addParseToken(['Z', 'ZZ'], function (input, array, config) {\n        config._useUTC = true;\n        config._tzm = offsetFromString(matchShortOffset, input);\n    });\n\n    // HELPERS\n\n    // timezone chunker\n    // '+10:00' > ['10',  '00']\n    // '-1530'  > ['-15', '30']\n    var chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\n    function offsetFromString(matcher, string) {\n        var matches = (string || '').match(matcher);\n\n        if (matches === null) {\n            return null;\n        }\n\n        var chunk   = matches[matches.length - 1] || [];\n        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n        var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n        return minutes === 0 ?\n          0 :\n          parts[0] === '+' ? minutes : -minutes;\n    }\n\n    // Return a moment from input, that is local/utc/zone equivalent to model.\n    function cloneWithOffset(input, model) {\n        var res, diff;\n        if (model._isUTC) {\n            res = model.clone();\n            diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n            // Use low-level api, because this fn is low-level api.\n            res._d.setTime(res._d.valueOf() + diff);\n            hooks.updateOffset(res, false);\n            return res;\n        } else {\n            return createLocal(input).local();\n        }\n    }\n\n    function getDateOffset (m) {\n        // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n        // https://github.com/moment/moment/pull/1871\n        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n    }\n\n    // HOOKS\n\n    // This function will be called whenever a moment is mutated.\n    // It is intended to keep the offset in sync with the timezone.\n    hooks.updateOffset = function () {};\n\n    // MOMENTS\n\n    // keepLocalTime = true means only change the timezone, without\n    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--\x3e\n    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n    // +0200, so we adjust the time as needed, to be valid.\n    //\n    // Keeping the time actually adds/subtracts (one hour)\n    // from the actual represented time. That is why we call updateOffset\n    // a second time. In case it wants us to change the offset again\n    // _changeInProgress == true case, then we have to adjust, because\n    // there is no such time in the given timezone.\n    function getSetOffset (input, keepLocalTime, keepMinutes) {\n        var offset = this._offset || 0,\n            localAdjust;\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        if (input != null) {\n            if (typeof input === 'string') {\n                input = offsetFromString(matchShortOffset, input);\n                if (input === null) {\n                    return this;\n                }\n            } else if (Math.abs(input) < 16 && !keepMinutes) {\n                input = input * 60;\n            }\n            if (!this._isUTC && keepLocalTime) {\n                localAdjust = getDateOffset(this);\n            }\n            this._offset = input;\n            this._isUTC = true;\n            if (localAdjust != null) {\n                this.add(localAdjust, 'm');\n            }\n            if (offset !== input) {\n                if (!keepLocalTime || this._changeInProgress) {\n                    addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n                } else if (!this._changeInProgress) {\n                    this._changeInProgress = true;\n                    hooks.updateOffset(this, true);\n                    this._changeInProgress = null;\n                }\n            }\n            return this;\n        } else {\n            return this._isUTC ? offset : getDateOffset(this);\n        }\n    }\n\n    function getSetZone (input, keepLocalTime) {\n        if (input != null) {\n            if (typeof input !== 'string') {\n                input = -input;\n            }\n\n            this.utcOffset(input, keepLocalTime);\n\n            return this;\n        } else {\n            return -this.utcOffset();\n        }\n    }\n\n    function setOffsetToUTC (keepLocalTime) {\n        return this.utcOffset(0, keepLocalTime);\n    }\n\n    function setOffsetToLocal (keepLocalTime) {\n        if (this._isUTC) {\n            this.utcOffset(0, keepLocalTime);\n            this._isUTC = false;\n\n            if (keepLocalTime) {\n                this.subtract(getDateOffset(this), 'm');\n            }\n        }\n        return this;\n    }\n\n    function setOffsetToParsedOffset () {\n        if (this._tzm != null) {\n            this.utcOffset(this._tzm, false, true);\n        } else if (typeof this._i === 'string') {\n            var tZone = offsetFromString(matchOffset, this._i);\n            if (tZone != null) {\n                this.utcOffset(tZone);\n            }\n            else {\n                this.utcOffset(0, true);\n            }\n        }\n        return this;\n    }\n\n    function hasAlignedHourOffset (input) {\n        if (!this.isValid()) {\n            return false;\n        }\n        input = input ? createLocal(input).utcOffset() : 0;\n\n        return (this.utcOffset() - input) % 60 === 0;\n    }\n\n    function isDaylightSavingTime () {\n        return (\n            this.utcOffset() > this.clone().month(0).utcOffset() ||\n            this.utcOffset() > this.clone().month(5).utcOffset()\n        );\n    }\n\n    function isDaylightSavingTimeShifted () {\n        if (!isUndefined(this._isDSTShifted)) {\n            return this._isDSTShifted;\n        }\n\n        var c = {};\n\n        copyConfig(c, this);\n        c = prepareConfig(c);\n\n        if (c._a) {\n            var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n            this._isDSTShifted = this.isValid() &&\n                compareArrays(c._a, other.toArray()) > 0;\n        } else {\n            this._isDSTShifted = false;\n        }\n\n        return this._isDSTShifted;\n    }\n\n    function isLocal () {\n        return this.isValid() ? !this._isUTC : false;\n    }\n\n    function isUtcOffset () {\n        return this.isValid() ? this._isUTC : false;\n    }\n\n    function isUtc () {\n        return this.isValid() ? this._isUTC && this._offset === 0 : false;\n    }\n\n    // ASP.NET json date format regex\n    var aspNetRegex = /^(\\-|\\+)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n    // and further modified to allow for strings containing both week and day\n    var isoRegex = /^(-|\\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;\n\n    function createDuration (input, key) {\n        var duration = input,\n            // matching against regexp is expensive, do it on demand\n            match = null,\n            sign,\n            ret,\n            diffRes;\n\n        if (isDuration(input)) {\n            duration = {\n                ms : input._milliseconds,\n                d  : input._days,\n                M  : input._months\n            };\n        } else if (isNumber(input)) {\n            duration = {};\n            if (key) {\n                duration[key] = input;\n            } else {\n                duration.milliseconds = input;\n            }\n        } else if (!!(match = aspNetRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y  : 0,\n                d  : toInt(match[DATE])                         * sign,\n                h  : toInt(match[HOUR])                         * sign,\n                m  : toInt(match[MINUTE])                       * sign,\n                s  : toInt(match[SECOND])                       * sign,\n                ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n            };\n        } else if (!!(match = isoRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y : parseIso(match[2], sign),\n                M : parseIso(match[3], sign),\n                w : parseIso(match[4], sign),\n                d : parseIso(match[5], sign),\n                h : parseIso(match[6], sign),\n                m : parseIso(match[7], sign),\n                s : parseIso(match[8], sign)\n            };\n        } else if (duration == null) {// checks for null or undefined\n            duration = {};\n        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n            diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n            duration = {};\n            duration.ms = diffRes.milliseconds;\n            duration.M = diffRes.months;\n        }\n\n        ret = new Duration(duration);\n\n        if (isDuration(input) && hasOwnProp(input, '_locale')) {\n            ret._locale = input._locale;\n        }\n\n        return ret;\n    }\n\n    createDuration.fn = Duration.prototype;\n    createDuration.invalid = createInvalid$1;\n\n    function parseIso (inp, sign) {\n        // We'd normally use ~~inp for this, but unfortunately it also\n        // converts floats to ints.\n        // inp may be undefined, so careful calling replace on it.\n        var res = inp && parseFloat(inp.replace(',', '.'));\n        // apply sign while we're at it\n        return (isNaN(res) ? 0 : res) * sign;\n    }\n\n    function positiveMomentsDifference(base, other) {\n        var res = {};\n\n        res.months = other.month() - base.month() +\n            (other.year() - base.year()) * 12;\n        if (base.clone().add(res.months, 'M').isAfter(other)) {\n            --res.months;\n        }\n\n        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n        return res;\n    }\n\n    function momentsDifference(base, other) {\n        var res;\n        if (!(base.isValid() && other.isValid())) {\n            return {milliseconds: 0, months: 0};\n        }\n\n        other = cloneWithOffset(other, base);\n        if (base.isBefore(other)) {\n            res = positiveMomentsDifference(base, other);\n        } else {\n            res = positiveMomentsDifference(other, base);\n            res.milliseconds = -res.milliseconds;\n            res.months = -res.months;\n        }\n\n        return res;\n    }\n\n    // TODO: remove 'name' arg after deprecation is removed\n    function createAdder(direction, name) {\n        return function (val, period) {\n            var dur, tmp;\n            //invert the arguments, but complain about it\n            if (period !== null && !isNaN(+period)) {\n                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n                'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n                tmp = val; val = period; period = tmp;\n            }\n\n            val = typeof val === 'string' ? +val : val;\n            dur = createDuration(val, period);\n            addSubtract(this, dur, direction);\n            return this;\n        };\n    }\n\n    function addSubtract (mom, duration, isAdding, updateOffset) {\n        var milliseconds = duration._milliseconds,\n            days = absRound(duration._days),\n            months = absRound(duration._months);\n\n        if (!mom.isValid()) {\n            // No op\n            return;\n        }\n\n        updateOffset = updateOffset == null ? true : updateOffset;\n\n        if (months) {\n            setMonth(mom, get(mom, 'Month') + months * isAdding);\n        }\n        if (days) {\n            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n        }\n        if (milliseconds) {\n            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n        }\n        if (updateOffset) {\n            hooks.updateOffset(mom, days || months);\n        }\n    }\n\n    var add      = createAdder(1, 'add');\n    var subtract = createAdder(-1, 'subtract');\n\n    function getCalendarFormat(myMoment, now) {\n        var diff = myMoment.diff(now, 'days', true);\n        return diff < -6 ? 'sameElse' :\n                diff < -1 ? 'lastWeek' :\n                diff < 0 ? 'lastDay' :\n                diff < 1 ? 'sameDay' :\n                diff < 2 ? 'nextDay' :\n                diff < 7 ? 'nextWeek' : 'sameElse';\n    }\n\n    function calendar$1 (time, formats) {\n        // We want to compare the start of today, vs this.\n        // Getting start-of-today depends on whether we're local/utc/offset or not.\n        var now = time || createLocal(),\n            sod = cloneWithOffset(now, this).startOf('day'),\n            format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n        return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n    }\n\n    function clone () {\n        return new Moment(this);\n    }\n\n    function isAfter (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input);\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() > localInput.valueOf();\n        } else {\n            return localInput.valueOf() < this.clone().startOf(units).valueOf();\n        }\n    }\n\n    function isBefore (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input);\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() < localInput.valueOf();\n        } else {\n            return this.clone().endOf(units).valueOf() < localInput.valueOf();\n        }\n    }\n\n    function isBetween (from, to, units, inclusivity) {\n        var localFrom = isMoment(from) ? from : createLocal(from),\n            localTo = isMoment(to) ? to : createLocal(to);\n        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {\n            return false;\n        }\n        inclusivity = inclusivity || '()';\n        return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) &&\n            (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));\n    }\n\n    function isSame (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input),\n            inputMs;\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() === localInput.valueOf();\n        } else {\n            inputMs = localInput.valueOf();\n            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n        }\n    }\n\n    function isSameOrAfter (input, units) {\n        return this.isSame(input, units) || this.isAfter(input, units);\n    }\n\n    function isSameOrBefore (input, units) {\n        return this.isSame(input, units) || this.isBefore(input, units);\n    }\n\n    function diff (input, units, asFloat) {\n        var that,\n            zoneDelta,\n            output;\n\n        if (!this.isValid()) {\n            return NaN;\n        }\n\n        that = cloneWithOffset(input, this);\n\n        if (!that.isValid()) {\n            return NaN;\n        }\n\n        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n        units = normalizeUnits(units);\n\n        switch (units) {\n            case 'year': output = monthDiff(this, that) / 12; break;\n            case 'month': output = monthDiff(this, that); break;\n            case 'quarter': output = monthDiff(this, that) / 3; break;\n            case 'second': output = (this - that) / 1e3; break; // 1000\n            case 'minute': output = (this - that) / 6e4; break; // 1000 * 60\n            case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60\n            case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst\n            case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst\n            default: output = this - that;\n        }\n\n        return asFloat ? output : absFloor(output);\n    }\n\n    function monthDiff (a, b) {\n        // difference in months\n        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n            // b is in (anchor - 1 month, anchor + 1 month)\n            anchor = a.clone().add(wholeMonthDiff, 'months'),\n            anchor2, adjust;\n\n        if (b - anchor < 0) {\n            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor - anchor2);\n        } else {\n            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor2 - anchor);\n        }\n\n        //check for negative zero, return zero if negative zero\n        return -(wholeMonthDiff + adjust) || 0;\n    }\n\n    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\n    function toString () {\n        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n    }\n\n    function toISOString(keepOffset) {\n        if (!this.isValid()) {\n            return null;\n        }\n        var utc = keepOffset !== true;\n        var m = utc ? this.clone().utc() : this;\n        if (m.year() < 0 || m.year() > 9999) {\n            return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');\n        }\n        if (isFunction(Date.prototype.toISOString)) {\n            // native implementation is ~50x faster, use it when we can\n            if (utc) {\n                return this.toDate().toISOString();\n            } else {\n                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));\n            }\n        }\n        return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');\n    }\n\n    /**\n     * Return a human readable representation of a moment that can\n     * also be evaluated to get a new moment which is the same\n     *\n     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n     */\n    function inspect () {\n        if (!this.isValid()) {\n            return 'moment.invalid(/* ' + this._i + ' */)';\n        }\n        var func = 'moment';\n        var zone = '';\n        if (!this.isLocal()) {\n            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n            zone = 'Z';\n        }\n        var prefix = '[' + func + '(\"]';\n        var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n        var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n        var suffix = zone + '[\")]';\n\n        return this.format(prefix + year + datetime + suffix);\n    }\n\n    function format (inputString) {\n        if (!inputString) {\n            inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n        }\n        var output = formatMoment(this, inputString);\n        return this.localeData().postformat(output);\n    }\n\n    function from (time, withoutSuffix) {\n        if (this.isValid() &&\n                ((isMoment(time) && time.isValid()) ||\n                 createLocal(time).isValid())) {\n            return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n        } else {\n            return this.localeData().invalidDate();\n        }\n    }\n\n    function fromNow (withoutSuffix) {\n        return this.from(createLocal(), withoutSuffix);\n    }\n\n    function to (time, withoutSuffix) {\n        if (this.isValid() &&\n                ((isMoment(time) && time.isValid()) ||\n                 createLocal(time).isValid())) {\n            return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n        } else {\n            return this.localeData().invalidDate();\n        }\n    }\n\n    function toNow (withoutSuffix) {\n        return this.to(createLocal(), withoutSuffix);\n    }\n\n    // If passed a locale key, it will set the locale for this\n    // instance.  Otherwise, it will return the locale configuration\n    // variables for this instance.\n    function locale (key) {\n        var newLocaleData;\n\n        if (key === undefined) {\n            return this._locale._abbr;\n        } else {\n            newLocaleData = getLocale(key);\n            if (newLocaleData != null) {\n                this._locale = newLocaleData;\n            }\n            return this;\n        }\n    }\n\n    var lang = deprecate(\n        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n        function (key) {\n            if (key === undefined) {\n                return this.localeData();\n            } else {\n                return this.locale(key);\n            }\n        }\n    );\n\n    function localeData () {\n        return this._locale;\n    }\n\n    var MS_PER_SECOND = 1000;\n    var MS_PER_MINUTE = 60 * MS_PER_SECOND;\n    var MS_PER_HOUR = 60 * MS_PER_MINUTE;\n    var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;\n\n    // actual modulo - handles negative numbers (for dates before 1970):\n    function mod$1(dividend, divisor) {\n        return (dividend % divisor + divisor) % divisor;\n    }\n\n    function localStartOfDate(y, m, d) {\n        // the date constructor remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            return new Date(y + 400, m, d) - MS_PER_400_YEARS;\n        } else {\n            return new Date(y, m, d).valueOf();\n        }\n    }\n\n    function utcStartOfDate(y, m, d) {\n        // Date.UTC remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;\n        } else {\n            return Date.UTC(y, m, d);\n        }\n    }\n\n    function startOf (units) {\n        var time;\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond' || !this.isValid()) {\n            return this;\n        }\n\n        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;\n\n        switch (units) {\n            case 'year':\n                time = startOfDate(this.year(), 0, 1);\n                break;\n            case 'quarter':\n                time = startOfDate(this.year(), this.month() - this.month() % 3, 1);\n                break;\n            case 'month':\n                time = startOfDate(this.year(), this.month(), 1);\n                break;\n            case 'week':\n                time = startOfDate(this.year(), this.month(), this.date() - this.weekday());\n                break;\n            case 'isoWeek':\n                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));\n                break;\n            case 'day':\n            case 'date':\n                time = startOfDate(this.year(), this.month(), this.date());\n                break;\n            case 'hour':\n                time = this._d.valueOf();\n                time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);\n                break;\n            case 'minute':\n                time = this._d.valueOf();\n                time -= mod$1(time, MS_PER_MINUTE);\n                break;\n            case 'second':\n                time = this._d.valueOf();\n                time -= mod$1(time, MS_PER_SECOND);\n                break;\n        }\n\n        this._d.setTime(time);\n        hooks.updateOffset(this, true);\n        return this;\n    }\n\n    function endOf (units) {\n        var time;\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond' || !this.isValid()) {\n            return this;\n        }\n\n        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;\n\n        switch (units) {\n            case 'year':\n                time = startOfDate(this.year() + 1, 0, 1) - 1;\n                break;\n            case 'quarter':\n                time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;\n                break;\n            case 'month':\n                time = startOfDate(this.year(), this.month() + 1, 1) - 1;\n                break;\n            case 'week':\n                time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;\n                break;\n            case 'isoWeek':\n                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;\n                break;\n            case 'day':\n            case 'date':\n                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;\n                break;\n            case 'hour':\n                time = this._d.valueOf();\n                time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;\n                break;\n            case 'minute':\n                time = this._d.valueOf();\n                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;\n                break;\n            case 'second':\n                time = this._d.valueOf();\n                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;\n                break;\n        }\n\n        this._d.setTime(time);\n        hooks.updateOffset(this, true);\n        return this;\n    }\n\n    function valueOf () {\n        return this._d.valueOf() - ((this._offset || 0) * 60000);\n    }\n\n    function unix () {\n        return Math.floor(this.valueOf() / 1000);\n    }\n\n    function toDate () {\n        return new Date(this.valueOf());\n    }\n\n    function toArray () {\n        var m = this;\n        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n    }\n\n    function toObject () {\n        var m = this;\n        return {\n            years: m.year(),\n            months: m.month(),\n            date: m.date(),\n            hours: m.hours(),\n            minutes: m.minutes(),\n            seconds: m.seconds(),\n            milliseconds: m.milliseconds()\n        };\n    }\n\n    function toJSON () {\n        // new Date(NaN).toJSON() === null\n        return this.isValid() ? this.toISOString() : null;\n    }\n\n    function isValid$2 () {\n        return isValid(this);\n    }\n\n    function parsingFlags () {\n        return extend({}, getParsingFlags(this));\n    }\n\n    function invalidAt () {\n        return getParsingFlags(this).overflow;\n    }\n\n    function creationData() {\n        return {\n            input: this._i,\n            format: this._f,\n            locale: this._locale,\n            isUTC: this._isUTC,\n            strict: this._strict\n        };\n    }\n\n    // FORMATTING\n\n    addFormatToken(0, ['gg', 2], 0, function () {\n        return this.weekYear() % 100;\n    });\n\n    addFormatToken(0, ['GG', 2], 0, function () {\n        return this.isoWeekYear() % 100;\n    });\n\n    function addWeekYearFormatToken (token, getter) {\n        addFormatToken(0, [token, token.length], 0, getter);\n    }\n\n    addWeekYearFormatToken('gggg',     'weekYear');\n    addWeekYearFormatToken('ggggg',    'weekYear');\n    addWeekYearFormatToken('GGGG',  'isoWeekYear');\n    addWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n    // ALIASES\n\n    addUnitAlias('weekYear', 'gg');\n    addUnitAlias('isoWeekYear', 'GG');\n\n    // PRIORITY\n\n    addUnitPriority('weekYear', 1);\n    addUnitPriority('isoWeekYear', 1);\n\n\n    // PARSING\n\n    addRegexToken('G',      matchSigned);\n    addRegexToken('g',      matchSigned);\n    addRegexToken('GG',     match1to2, match2);\n    addRegexToken('gg',     match1to2, match2);\n    addRegexToken('GGGG',   match1to4, match4);\n    addRegexToken('gggg',   match1to4, match4);\n    addRegexToken('GGGGG',  match1to6, match6);\n    addRegexToken('ggggg',  match1to6, match6);\n\n    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n        week[token.substr(0, 2)] = toInt(input);\n    });\n\n    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n        week[token] = hooks.parseTwoDigitYear(input);\n    });\n\n    // MOMENTS\n\n    function getSetWeekYear (input) {\n        return getSetWeekYearHelper.call(this,\n                input,\n                this.week(),\n                this.weekday(),\n                this.localeData()._week.dow,\n                this.localeData()._week.doy);\n    }\n\n    function getSetISOWeekYear (input) {\n        return getSetWeekYearHelper.call(this,\n                input, this.isoWeek(), this.isoWeekday(), 1, 4);\n    }\n\n    function getISOWeeksInYear () {\n        return weeksInYear(this.year(), 1, 4);\n    }\n\n    function getWeeksInYear () {\n        var weekInfo = this.localeData()._week;\n        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n    }\n\n    function getSetWeekYearHelper(input, week, weekday, dow, doy) {\n        var weeksTarget;\n        if (input == null) {\n            return weekOfYear(this, dow, doy).year;\n        } else {\n            weeksTarget = weeksInYear(input, dow, doy);\n            if (week > weeksTarget) {\n                week = weeksTarget;\n            }\n            return setWeekAll.call(this, input, week, weekday, dow, doy);\n        }\n    }\n\n    function setWeekAll(weekYear, week, weekday, dow, doy) {\n        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n        this.year(date.getUTCFullYear());\n        this.month(date.getUTCMonth());\n        this.date(date.getUTCDate());\n        return this;\n    }\n\n    // FORMATTING\n\n    addFormatToken('Q', 0, 'Qo', 'quarter');\n\n    // ALIASES\n\n    addUnitAlias('quarter', 'Q');\n\n    // PRIORITY\n\n    addUnitPriority('quarter', 7);\n\n    // PARSING\n\n    addRegexToken('Q', match1);\n    addParseToken('Q', function (input, array) {\n        array[MONTH] = (toInt(input) - 1) * 3;\n    });\n\n    // MOMENTS\n\n    function getSetQuarter (input) {\n        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n    }\n\n    // FORMATTING\n\n    addFormatToken('D', ['DD', 2], 'Do', 'date');\n\n    // ALIASES\n\n    addUnitAlias('date', 'D');\n\n    // PRIORITY\n    addUnitPriority('date', 9);\n\n    // PARSING\n\n    addRegexToken('D',  match1to2);\n    addRegexToken('DD', match1to2, match2);\n    addRegexToken('Do', function (isStrict, locale) {\n        // TODO: Remove \"ordinalParse\" fallback in next major release.\n        return isStrict ?\n          (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n          locale._dayOfMonthOrdinalParseLenient;\n    });\n\n    addParseToken(['D', 'DD'], DATE);\n    addParseToken('Do', function (input, array) {\n        array[DATE] = toInt(input.match(match1to2)[0]);\n    });\n\n    // MOMENTS\n\n    var getSetDayOfMonth = makeGetSet('Date', true);\n\n    // FORMATTING\n\n    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n    // ALIASES\n\n    addUnitAlias('dayOfYear', 'DDD');\n\n    // PRIORITY\n    addUnitPriority('dayOfYear', 4);\n\n    // PARSING\n\n    addRegexToken('DDD',  match1to3);\n    addRegexToken('DDDD', match3);\n    addParseToken(['DDD', 'DDDD'], function (input, array, config) {\n        config._dayOfYear = toInt(input);\n    });\n\n    // HELPERS\n\n    // MOMENTS\n\n    function getSetDayOfYear (input) {\n        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n    }\n\n    // FORMATTING\n\n    addFormatToken('m', ['mm', 2], 0, 'minute');\n\n    // ALIASES\n\n    addUnitAlias('minute', 'm');\n\n    // PRIORITY\n\n    addUnitPriority('minute', 14);\n\n    // PARSING\n\n    addRegexToken('m',  match1to2);\n    addRegexToken('mm', match1to2, match2);\n    addParseToken(['m', 'mm'], MINUTE);\n\n    // MOMENTS\n\n    var getSetMinute = makeGetSet('Minutes', false);\n\n    // FORMATTING\n\n    addFormatToken('s', ['ss', 2], 0, 'second');\n\n    // ALIASES\n\n    addUnitAlias('second', 's');\n\n    // PRIORITY\n\n    addUnitPriority('second', 15);\n\n    // PARSING\n\n    addRegexToken('s',  match1to2);\n    addRegexToken('ss', match1to2, match2);\n    addParseToken(['s', 'ss'], SECOND);\n\n    // MOMENTS\n\n    var getSetSecond = makeGetSet('Seconds', false);\n\n    // FORMATTING\n\n    addFormatToken('S', 0, 0, function () {\n        return ~~(this.millisecond() / 100);\n    });\n\n    addFormatToken(0, ['SS', 2], 0, function () {\n        return ~~(this.millisecond() / 10);\n    });\n\n    addFormatToken(0, ['SSS', 3], 0, 'millisecond');\n    addFormatToken(0, ['SSSS', 4], 0, function () {\n        return this.millisecond() * 10;\n    });\n    addFormatToken(0, ['SSSSS', 5], 0, function () {\n        return this.millisecond() * 100;\n    });\n    addFormatToken(0, ['SSSSSS', 6], 0, function () {\n        return this.millisecond() * 1000;\n    });\n    addFormatToken(0, ['SSSSSSS', 7], 0, function () {\n        return this.millisecond() * 10000;\n    });\n    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n        return this.millisecond() * 100000;\n    });\n    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n        return this.millisecond() * 1000000;\n    });\n\n\n    // ALIASES\n\n    addUnitAlias('millisecond', 'ms');\n\n    // PRIORITY\n\n    addUnitPriority('millisecond', 16);\n\n    // PARSING\n\n    addRegexToken('S',    match1to3, match1);\n    addRegexToken('SS',   match1to3, match2);\n    addRegexToken('SSS',  match1to3, match3);\n\n    var token;\n    for (token = 'SSSS'; token.length <= 9; token += 'S') {\n        addRegexToken(token, matchUnsigned);\n    }\n\n    function parseMs(input, array) {\n        array[MILLISECOND] = toInt(('0.' + input) * 1000);\n    }\n\n    for (token = 'S'; token.length <= 9; token += 'S') {\n        addParseToken(token, parseMs);\n    }\n    // MOMENTS\n\n    var getSetMillisecond = makeGetSet('Milliseconds', false);\n\n    // FORMATTING\n\n    addFormatToken('z',  0, 0, 'zoneAbbr');\n    addFormatToken('zz', 0, 0, 'zoneName');\n\n    // MOMENTS\n\n    function getZoneAbbr () {\n        return this._isUTC ? 'UTC' : '';\n    }\n\n    function getZoneName () {\n        return this._isUTC ? 'Coordinated Universal Time' : '';\n    }\n\n    var proto = Moment.prototype;\n\n    proto.add               = add;\n    proto.calendar          = calendar$1;\n    proto.clone             = clone;\n    proto.diff              = diff;\n    proto.endOf             = endOf;\n    proto.format            = format;\n    proto.from              = from;\n    proto.fromNow           = fromNow;\n    proto.to                = to;\n    proto.toNow             = toNow;\n    proto.get               = stringGet;\n    proto.invalidAt         = invalidAt;\n    proto.isAfter           = isAfter;\n    proto.isBefore          = isBefore;\n    proto.isBetween         = isBetween;\n    proto.isSame            = isSame;\n    proto.isSameOrAfter     = isSameOrAfter;\n    proto.isSameOrBefore    = isSameOrBefore;\n    proto.isValid           = isValid$2;\n    proto.lang              = lang;\n    proto.locale            = locale;\n    proto.localeData        = localeData;\n    proto.max               = prototypeMax;\n    proto.min               = prototypeMin;\n    proto.parsingFlags      = parsingFlags;\n    proto.set               = stringSet;\n    proto.startOf           = startOf;\n    proto.subtract          = subtract;\n    proto.toArray           = toArray;\n    proto.toObject          = toObject;\n    proto.toDate            = toDate;\n    proto.toISOString       = toISOString;\n    proto.inspect           = inspect;\n    proto.toJSON            = toJSON;\n    proto.toString          = toString;\n    proto.unix              = unix;\n    proto.valueOf           = valueOf;\n    proto.creationData      = creationData;\n    proto.year       = getSetYear;\n    proto.isLeapYear = getIsLeapYear;\n    proto.weekYear    = getSetWeekYear;\n    proto.isoWeekYear = getSetISOWeekYear;\n    proto.quarter = proto.quarters = getSetQuarter;\n    proto.month       = getSetMonth;\n    proto.daysInMonth = getDaysInMonth;\n    proto.week           = proto.weeks        = getSetWeek;\n    proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\n    proto.weeksInYear    = getWeeksInYear;\n    proto.isoWeeksInYear = getISOWeeksInYear;\n    proto.date       = getSetDayOfMonth;\n    proto.day        = proto.days             = getSetDayOfWeek;\n    proto.weekday    = getSetLocaleDayOfWeek;\n    proto.isoWeekday = getSetISODayOfWeek;\n    proto.dayOfYear  = getSetDayOfYear;\n    proto.hour = proto.hours = getSetHour;\n    proto.minute = proto.minutes = getSetMinute;\n    proto.second = proto.seconds = getSetSecond;\n    proto.millisecond = proto.milliseconds = getSetMillisecond;\n    proto.utcOffset            = getSetOffset;\n    proto.utc                  = setOffsetToUTC;\n    proto.local                = setOffsetToLocal;\n    proto.parseZone            = setOffsetToParsedOffset;\n    proto.hasAlignedHourOffset = hasAlignedHourOffset;\n    proto.isDST                = isDaylightSavingTime;\n    proto.isLocal              = isLocal;\n    proto.isUtcOffset          = isUtcOffset;\n    proto.isUtc                = isUtc;\n    proto.isUTC                = isUtc;\n    proto.zoneAbbr = getZoneAbbr;\n    proto.zoneName = getZoneName;\n    proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\n    proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\n    proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\n    proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\n    proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\n    function createUnix (input) {\n        return createLocal(input * 1000);\n    }\n\n    function createInZone () {\n        return createLocal.apply(null, arguments).parseZone();\n    }\n\n    function preParsePostFormat (string) {\n        return string;\n    }\n\n    var proto$1 = Locale.prototype;\n\n    proto$1.calendar        = calendar;\n    proto$1.longDateFormat  = longDateFormat;\n    proto$1.invalidDate     = invalidDate;\n    proto$1.ordinal         = ordinal;\n    proto$1.preparse        = preParsePostFormat;\n    proto$1.postformat      = preParsePostFormat;\n    proto$1.relativeTime    = relativeTime;\n    proto$1.pastFuture      = pastFuture;\n    proto$1.set             = set;\n\n    proto$1.months            =        localeMonths;\n    proto$1.monthsShort       =        localeMonthsShort;\n    proto$1.monthsParse       =        localeMonthsParse;\n    proto$1.monthsRegex       = monthsRegex;\n    proto$1.monthsShortRegex  = monthsShortRegex;\n    proto$1.week = localeWeek;\n    proto$1.firstDayOfYear = localeFirstDayOfYear;\n    proto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n    proto$1.weekdays       =        localeWeekdays;\n    proto$1.weekdaysMin    =        localeWeekdaysMin;\n    proto$1.weekdaysShort  =        localeWeekdaysShort;\n    proto$1.weekdaysParse  =        localeWeekdaysParse;\n\n    proto$1.weekdaysRegex       =        weekdaysRegex;\n    proto$1.weekdaysShortRegex  =        weekdaysShortRegex;\n    proto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n    proto$1.isPM = localeIsPM;\n    proto$1.meridiem = localeMeridiem;\n\n    function get$1 (format, index, field, setter) {\n        var locale = getLocale();\n        var utc = createUTC().set(setter, index);\n        return locale[field](utc, format);\n    }\n\n    function listMonthsImpl (format, index, field) {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n\n        if (index != null) {\n            return get$1(format, index, field, 'month');\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < 12; i++) {\n            out[i] = get$1(format, i, field, 'month');\n        }\n        return out;\n    }\n\n    // ()\n    // (5)\n    // (fmt, 5)\n    // (fmt)\n    // (true)\n    // (true, 5)\n    // (true, fmt, 5)\n    // (true, fmt)\n    function listWeekdaysImpl (localeSorted, format, index, field) {\n        if (typeof localeSorted === 'boolean') {\n            if (isNumber(format)) {\n                index = format;\n                format = undefined;\n            }\n\n            format = format || '';\n        } else {\n            format = localeSorted;\n            index = format;\n            localeSorted = false;\n\n            if (isNumber(format)) {\n                index = format;\n                format = undefined;\n            }\n\n            format = format || '';\n        }\n\n        var locale = getLocale(),\n            shift = localeSorted ? locale._week.dow : 0;\n\n        if (index != null) {\n            return get$1(format, (index + shift) % 7, field, 'day');\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < 7; i++) {\n            out[i] = get$1(format, (i + shift) % 7, field, 'day');\n        }\n        return out;\n    }\n\n    function listMonths (format, index) {\n        return listMonthsImpl(format, index, 'months');\n    }\n\n    function listMonthsShort (format, index) {\n        return listMonthsImpl(format, index, 'monthsShort');\n    }\n\n    function listWeekdays (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n    }\n\n    function listWeekdaysShort (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n    }\n\n    function listWeekdaysMin (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n    }\n\n    getSetGlobalLocale('en', {\n        dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (toInt(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    // Side effect imports\n\n    hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\n    hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\n    var mathAbs = Math.abs;\n\n    function abs () {\n        var data           = this._data;\n\n        this._milliseconds = mathAbs(this._milliseconds);\n        this._days         = mathAbs(this._days);\n        this._months       = mathAbs(this._months);\n\n        data.milliseconds  = mathAbs(data.milliseconds);\n        data.seconds       = mathAbs(data.seconds);\n        data.minutes       = mathAbs(data.minutes);\n        data.hours         = mathAbs(data.hours);\n        data.months        = mathAbs(data.months);\n        data.years         = mathAbs(data.years);\n\n        return this;\n    }\n\n    function addSubtract$1 (duration, input, value, direction) {\n        var other = createDuration(input, value);\n\n        duration._milliseconds += direction * other._milliseconds;\n        duration._days         += direction * other._days;\n        duration._months       += direction * other._months;\n\n        return duration._bubble();\n    }\n\n    // supports only 2.0-style add(1, 's') or add(duration)\n    function add$1 (input, value) {\n        return addSubtract$1(this, input, value, 1);\n    }\n\n    // supports only 2.0-style subtract(1, 's') or subtract(duration)\n    function subtract$1 (input, value) {\n        return addSubtract$1(this, input, value, -1);\n    }\n\n    function absCeil (number) {\n        if (number < 0) {\n            return Math.floor(number);\n        } else {\n            return Math.ceil(number);\n        }\n    }\n\n    function bubble () {\n        var milliseconds = this._milliseconds;\n        var days         = this._days;\n        var months       = this._months;\n        var data         = this._data;\n        var seconds, minutes, hours, years, monthsFromDays;\n\n        // if we have a mix of positive and negative values, bubble down first\n        // check: https://github.com/moment/moment/issues/2166\n        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n                (milliseconds <= 0 && days <= 0 && months <= 0))) {\n            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n            days = 0;\n            months = 0;\n        }\n\n        // The following code bubbles up values, see the tests for\n        // examples of what that means.\n        data.milliseconds = milliseconds % 1000;\n\n        seconds           = absFloor(milliseconds / 1000);\n        data.seconds      = seconds % 60;\n\n        minutes           = absFloor(seconds / 60);\n        data.minutes      = minutes % 60;\n\n        hours             = absFloor(minutes / 60);\n        data.hours        = hours % 24;\n\n        days += absFloor(hours / 24);\n\n        // convert days to months\n        monthsFromDays = absFloor(daysToMonths(days));\n        months += monthsFromDays;\n        days -= absCeil(monthsToDays(monthsFromDays));\n\n        // 12 months -> 1 year\n        years = absFloor(months / 12);\n        months %= 12;\n\n        data.days   = days;\n        data.months = months;\n        data.years  = years;\n\n        return this;\n    }\n\n    function daysToMonths (days) {\n        // 400 years have 146097 days (taking into account leap year rules)\n        // 400 years have 12 months === 4800\n        return days * 4800 / 146097;\n    }\n\n    function monthsToDays (months) {\n        // the reverse of daysToMonths\n        return months * 146097 / 4800;\n    }\n\n    function as (units) {\n        if (!this.isValid()) {\n            return NaN;\n        }\n        var days;\n        var months;\n        var milliseconds = this._milliseconds;\n\n        units = normalizeUnits(units);\n\n        if (units === 'month' || units === 'quarter' || units === 'year') {\n            days = this._days + milliseconds / 864e5;\n            months = this._months + daysToMonths(days);\n            switch (units) {\n                case 'month':   return months;\n                case 'quarter': return months / 3;\n                case 'year':    return months / 12;\n            }\n        } else {\n            // handle milliseconds separately because of floating point math errors (issue #1867)\n            days = this._days + Math.round(monthsToDays(this._months));\n            switch (units) {\n                case 'week'   : return days / 7     + milliseconds / 6048e5;\n                case 'day'    : return days         + milliseconds / 864e5;\n                case 'hour'   : return days * 24    + milliseconds / 36e5;\n                case 'minute' : return days * 1440  + milliseconds / 6e4;\n                case 'second' : return days * 86400 + milliseconds / 1000;\n                // Math.floor prevents floating point math errors here\n                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n                default: throw new Error('Unknown unit ' + units);\n            }\n        }\n    }\n\n    // TODO: Use this.as('ms')?\n    function valueOf$1 () {\n        if (!this.isValid()) {\n            return NaN;\n        }\n        return (\n            this._milliseconds +\n            this._days * 864e5 +\n            (this._months % 12) * 2592e6 +\n            toInt(this._months / 12) * 31536e6\n        );\n    }\n\n    function makeAs (alias) {\n        return function () {\n            return this.as(alias);\n        };\n    }\n\n    var asMilliseconds = makeAs('ms');\n    var asSeconds      = makeAs('s');\n    var asMinutes      = makeAs('m');\n    var asHours        = makeAs('h');\n    var asDays         = makeAs('d');\n    var asWeeks        = makeAs('w');\n    var asMonths       = makeAs('M');\n    var asQuarters     = makeAs('Q');\n    var asYears        = makeAs('y');\n\n    function clone$1 () {\n        return createDuration(this);\n    }\n\n    function get$2 (units) {\n        units = normalizeUnits(units);\n        return this.isValid() ? this[units + 's']() : NaN;\n    }\n\n    function makeGetter(name) {\n        return function () {\n            return this.isValid() ? this._data[name] : NaN;\n        };\n    }\n\n    var milliseconds = makeGetter('milliseconds');\n    var seconds      = makeGetter('seconds');\n    var minutes      = makeGetter('minutes');\n    var hours        = makeGetter('hours');\n    var days         = makeGetter('days');\n    var months       = makeGetter('months');\n    var years        = makeGetter('years');\n\n    function weeks () {\n        return absFloor(this.days() / 7);\n    }\n\n    var round = Math.round;\n    var thresholds = {\n        ss: 44,         // a few seconds to seconds\n        s : 45,         // seconds to minute\n        m : 45,         // minutes to hour\n        h : 22,         // hours to day\n        d : 26,         // days to month\n        M : 11          // months to year\n    };\n\n    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\n    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n    }\n\n    function relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n        var duration = createDuration(posNegDuration).abs();\n        var seconds  = round(duration.as('s'));\n        var minutes  = round(duration.as('m'));\n        var hours    = round(duration.as('h'));\n        var days     = round(duration.as('d'));\n        var months   = round(duration.as('M'));\n        var years    = round(duration.as('y'));\n\n        var a = seconds <= thresholds.ss && ['s', seconds]  ||\n                seconds < thresholds.s   && ['ss', seconds] ||\n                minutes <= 1             && ['m']           ||\n                minutes < thresholds.m   && ['mm', minutes] ||\n                hours   <= 1             && ['h']           ||\n                hours   < thresholds.h   && ['hh', hours]   ||\n                days    <= 1             && ['d']           ||\n                days    < thresholds.d   && ['dd', days]    ||\n                months  <= 1             && ['M']           ||\n                months  < thresholds.M   && ['MM', months]  ||\n                years   <= 1             && ['y']           || ['yy', years];\n\n        a[2] = withoutSuffix;\n        a[3] = +posNegDuration > 0;\n        a[4] = locale;\n        return substituteTimeAgo.apply(null, a);\n    }\n\n    // This function allows you to set the rounding function for relative time strings\n    function getSetRelativeTimeRounding (roundingFunction) {\n        if (roundingFunction === undefined) {\n            return round;\n        }\n        if (typeof(roundingFunction) === 'function') {\n            round = roundingFunction;\n            return true;\n        }\n        return false;\n    }\n\n    // This function allows you to set a threshold for relative time strings\n    function getSetRelativeTimeThreshold (threshold, limit) {\n        if (thresholds[threshold] === undefined) {\n            return false;\n        }\n        if (limit === undefined) {\n            return thresholds[threshold];\n        }\n        thresholds[threshold] = limit;\n        if (threshold === 's') {\n            thresholds.ss = limit - 1;\n        }\n        return true;\n    }\n\n    function humanize (withSuffix) {\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n\n        var locale = this.localeData();\n        var output = relativeTime$1(this, !withSuffix, locale);\n\n        if (withSuffix) {\n            output = locale.pastFuture(+this, output);\n        }\n\n        return locale.postformat(output);\n    }\n\n    var abs$1 = Math.abs;\n\n    function sign(x) {\n        return ((x > 0) - (x < 0)) || +x;\n    }\n\n    function toISOString$1() {\n        // for ISO strings we do not use the normal bubbling rules:\n        //  * milliseconds bubble up until they become hours\n        //  * days do not bubble at all\n        //  * months bubble up until they become years\n        // This is because there is no context-free conversion between hours and days\n        // (think of clock changes)\n        // and also not between days and months (28-31 days per month)\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n\n        var seconds = abs$1(this._milliseconds) / 1000;\n        var days         = abs$1(this._days);\n        var months       = abs$1(this._months);\n        var minutes, hours, years;\n\n        // 3600 seconds -> 60 minutes -> 1 hour\n        minutes           = absFloor(seconds / 60);\n        hours             = absFloor(minutes / 60);\n        seconds %= 60;\n        minutes %= 60;\n\n        // 12 months -> 1 year\n        years  = absFloor(months / 12);\n        months %= 12;\n\n\n        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n        var Y = years;\n        var M = months;\n        var D = days;\n        var h = hours;\n        var m = minutes;\n        var s = seconds ? seconds.toFixed(3).replace(/\\.?0+$/, '') : '';\n        var total = this.asSeconds();\n\n        if (!total) {\n            // this is the same as C#'s (Noda) and python (isodate)...\n            // but not other JS (goog.date)\n            return 'P0D';\n        }\n\n        var totalSign = total < 0 ? '-' : '';\n        var ymSign = sign(this._months) !== sign(total) ? '-' : '';\n        var daysSign = sign(this._days) !== sign(total) ? '-' : '';\n        var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';\n\n        return totalSign + 'P' +\n            (Y ? ymSign + Y + 'Y' : '') +\n            (M ? ymSign + M + 'M' : '') +\n            (D ? daysSign + D + 'D' : '') +\n            ((h || m || s) ? 'T' : '') +\n            (h ? hmsSign + h + 'H' : '') +\n            (m ? hmsSign + m + 'M' : '') +\n            (s ? hmsSign + s + 'S' : '');\n    }\n\n    var proto$2 = Duration.prototype;\n\n    proto$2.isValid        = isValid$1;\n    proto$2.abs            = abs;\n    proto$2.add            = add$1;\n    proto$2.subtract       = subtract$1;\n    proto$2.as             = as;\n    proto$2.asMilliseconds = asMilliseconds;\n    proto$2.asSeconds      = asSeconds;\n    proto$2.asMinutes      = asMinutes;\n    proto$2.asHours        = asHours;\n    proto$2.asDays         = asDays;\n    proto$2.asWeeks        = asWeeks;\n    proto$2.asMonths       = asMonths;\n    proto$2.asQuarters     = asQuarters;\n    proto$2.asYears        = asYears;\n    proto$2.valueOf        = valueOf$1;\n    proto$2._bubble        = bubble;\n    proto$2.clone          = clone$1;\n    proto$2.get            = get$2;\n    proto$2.milliseconds   = milliseconds;\n    proto$2.seconds        = seconds;\n    proto$2.minutes        = minutes;\n    proto$2.hours          = hours;\n    proto$2.days           = days;\n    proto$2.weeks          = weeks;\n    proto$2.months         = months;\n    proto$2.years          = years;\n    proto$2.humanize       = humanize;\n    proto$2.toISOString    = toISOString$1;\n    proto$2.toString       = toISOString$1;\n    proto$2.toJSON         = toISOString$1;\n    proto$2.locale         = locale;\n    proto$2.localeData     = localeData;\n\n    proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\n    proto$2.lang = lang;\n\n    // Side effect imports\n\n    // FORMATTING\n\n    addFormatToken('X', 0, 0, 'unix');\n    addFormatToken('x', 0, 0, 'valueOf');\n\n    // PARSING\n\n    addRegexToken('x', matchSigned);\n    addRegexToken('X', matchTimestamp);\n    addParseToken('X', function (input, array, config) {\n        config._d = new Date(parseFloat(input, 10) * 1000);\n    });\n    addParseToken('x', function (input, array, config) {\n        config._d = new Date(toInt(input));\n    });\n\n    // Side effect imports\n\n\n    hooks.version = '2.24.0';\n\n    setHookCallback(createLocal);\n\n    hooks.fn                    = proto;\n    hooks.min                   = min;\n    hooks.max                   = max;\n    hooks.now                   = now;\n    hooks.utc                   = createUTC;\n    hooks.unix                  = createUnix;\n    hooks.months                = listMonths;\n    hooks.isDate                = isDate;\n    hooks.locale                = getSetGlobalLocale;\n    hooks.invalid               = createInvalid;\n    hooks.duration              = createDuration;\n    hooks.isMoment              = isMoment;\n    hooks.weekdays              = listWeekdays;\n    hooks.parseZone             = createInZone;\n    hooks.localeData            = getLocale;\n    hooks.isDuration            = isDuration;\n    hooks.monthsShort           = listMonthsShort;\n    hooks.weekdaysMin           = listWeekdaysMin;\n    hooks.defineLocale          = defineLocale;\n    hooks.updateLocale          = updateLocale;\n    hooks.locales               = listLocales;\n    hooks.weekdaysShort         = listWeekdaysShort;\n    hooks.normalizeUnits        = normalizeUnits;\n    hooks.relativeTimeRounding  = getSetRelativeTimeRounding;\n    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\n    hooks.calendarFormat        = getCalendarFormat;\n    hooks.prototype             = proto;\n\n    // currently HTML5 input type only supports 24-hour formats\n    hooks.HTML5_FMT = {\n        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type=\"datetime-local\" />\n        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type=\"datetime-local\" step=\"1\" />\n        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type=\"datetime-local\" step=\"0.001\" />\n        DATE: 'YYYY-MM-DD',                             // <input type=\"date\" />\n        TIME: 'HH:mm',                                  // <input type=\"time\" />\n        TIME_SECONDS: 'HH:mm:ss',                       // <input type=\"time\" step=\"1\" />\n        TIME_MS: 'HH:mm:ss.SSS',                        // <input type=\"time\" step=\"0.001\" />\n        WEEK: 'GGGG-[W]WW',                             // <input type=\"week\" />\n        MONTH: 'YYYY-MM'                                // <input type=\"month\" />\n    };\n\n    return hooks;\n\n})));\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/module.js */ \"f586\")(module)))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGEwMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9tb21lbnQvbW9tZW50LmpzP2MxZGYiXSwic291cmNlc0NvbnRlbnQiOlsiLy8hIG1vbWVudC5qc1xuXG47KGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG4gICAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgICBnbG9iYWwubW9tZW50ID0gZmFjdG9yeSgpXG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuICAgIHZhciBob29rQ2FsbGJhY2s7XG5cbiAgICBmdW5jdGlvbiBob29rcyAoKSB7XG4gICAgICAgIHJldHVybiBob29rQ2FsbGJhY2suYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGlzIGRvbmUgdG8gcmVnaXN0ZXIgdGhlIG1ldGhvZCBjYWxsZWQgd2l0aCBtb21lbnQoKVxuICAgIC8vIHdpdGhvdXQgY3JlYXRpbmcgY2lyY3VsYXIgZGVwZW5kZW5jaWVzLlxuICAgIGZ1bmN0aW9uIHNldEhvb2tDYWxsYmFjayAoY2FsbGJhY2spIHtcbiAgICAgICAgaG9va0NhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBcnJheShpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXQgaW5zdGFuY2VvZiBBcnJheSB8fCBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaW5wdXQpID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzT2JqZWN0KGlucHV0KSB7XG4gICAgICAgIC8vIElFOCB3aWxsIHRyZWF0IHVuZGVmaW5lZCBhbmQgbnVsbCBhcyBvYmplY3QgaWYgaXQgd2Fzbid0IGZvclxuICAgICAgICAvLyBpbnB1dCAhPSBudWxsXG4gICAgICAgIHJldHVybiBpbnB1dCAhPSBudWxsICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IE9iamVjdF0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzT2JqZWN0RW1wdHkob2JqKSB7XG4gICAgICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcykge1xuICAgICAgICAgICAgcmV0dXJuIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCA9PT0gMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaztcbiAgICAgICAgICAgIGZvciAoayBpbiBvYmopIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVW5kZWZpbmVkKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBpbnB1dCA9PT0gdm9pZCAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzTnVtYmVyKGlucHV0KSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IE51bWJlcl0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzRGF0ZShpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXQgaW5zdGFuY2VvZiBEYXRlIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IERhdGVdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXAoYXJyLCBmbikge1xuICAgICAgICB2YXIgcmVzID0gW10sIGk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHJlcy5wdXNoKGZuKGFycltpXSwgaSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzT3duUHJvcChhLCBiKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSwgYik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXh0ZW5kKGEsIGIpIHtcbiAgICAgICAgZm9yICh2YXIgaSBpbiBiKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChiLCBpKSkge1xuICAgICAgICAgICAgICAgIGFbaV0gPSBiW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc093blByb3AoYiwgJ3RvU3RyaW5nJykpIHtcbiAgICAgICAgICAgIGEudG9TdHJpbmcgPSBiLnRvU3RyaW5nO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc093blByb3AoYiwgJ3ZhbHVlT2YnKSkge1xuICAgICAgICAgICAgYS52YWx1ZU9mID0gYi52YWx1ZU9mO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlVVRDIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWxPclVUQyhpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCwgdHJ1ZSkudXRjKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmYXVsdFBhcnNpbmdGbGFncygpIHtcbiAgICAgICAgLy8gV2UgbmVlZCB0byBkZWVwIGNsb25lIHRoaXMgb2JqZWN0LlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZW1wdHkgICAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICB1bnVzZWRUb2tlbnMgICAgOiBbXSxcbiAgICAgICAgICAgIHVudXNlZElucHV0ICAgICA6IFtdLFxuICAgICAgICAgICAgb3ZlcmZsb3cgICAgICAgIDogLTIsXG4gICAgICAgICAgICBjaGFyc0xlZnRPdmVyICAgOiAwLFxuICAgICAgICAgICAgbnVsbElucHV0ICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICBpbnZhbGlkTW9udGggICAgOiBudWxsLFxuICAgICAgICAgICAgaW52YWxpZEZvcm1hdCAgIDogZmFsc2UsXG4gICAgICAgICAgICB1c2VySW52YWxpZGF0ZWQgOiBmYWxzZSxcbiAgICAgICAgICAgIGlzbyAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICAgICAgcGFyc2VkRGF0ZVBhcnRzIDogW10sXG4gICAgICAgICAgICBtZXJpZGllbSAgICAgICAgOiBudWxsLFxuICAgICAgICAgICAgcmZjMjgyMiAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICB3ZWVrZGF5TWlzbWF0Y2ggOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFBhcnNpbmdGbGFncyhtKSB7XG4gICAgICAgIGlmIChtLl9wZiA9PSBudWxsKSB7XG4gICAgICAgICAgICBtLl9wZiA9IGRlZmF1bHRQYXJzaW5nRmxhZ3MoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbS5fcGY7XG4gICAgfVxuXG4gICAgdmFyIHNvbWU7XG4gICAgaWYgKEFycmF5LnByb3RvdHlwZS5zb21lKSB7XG4gICAgICAgIHNvbWUgPSBBcnJheS5wcm90b3R5cGUuc29tZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBzb21lID0gZnVuY3Rpb24gKGZ1bikge1xuICAgICAgICAgICAgdmFyIHQgPSBPYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgbGVuID0gdC5sZW5ndGggPj4+IDA7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiB0ICYmIGZ1bi5jYWxsKHRoaXMsIHRbaV0sIGksIHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVmFsaWQobSkge1xuICAgICAgICBpZiAobS5faXNWYWxpZCA9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgZmxhZ3MgPSBnZXRQYXJzaW5nRmxhZ3MobSk7XG4gICAgICAgICAgICB2YXIgcGFyc2VkUGFydHMgPSBzb21lLmNhbGwoZmxhZ3MucGFyc2VkRGF0ZVBhcnRzLCBmdW5jdGlvbiAoaSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpICE9IG51bGw7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhciBpc05vd1ZhbGlkID0gIWlzTmFOKG0uX2QuZ2V0VGltZSgpKSAmJlxuICAgICAgICAgICAgICAgIGZsYWdzLm92ZXJmbG93IDwgMCAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5lbXB0eSAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5pbnZhbGlkTW9udGggJiZcbiAgICAgICAgICAgICAgICAhZmxhZ3MuaW52YWxpZFdlZWtkYXkgJiZcbiAgICAgICAgICAgICAgICAhZmxhZ3Mud2Vla2RheU1pc21hdGNoICYmXG4gICAgICAgICAgICAgICAgIWZsYWdzLm51bGxJbnB1dCAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5pbnZhbGlkRm9ybWF0ICYmXG4gICAgICAgICAgICAgICAgIWZsYWdzLnVzZXJJbnZhbGlkYXRlZCAmJlxuICAgICAgICAgICAgICAgICghZmxhZ3MubWVyaWRpZW0gfHwgKGZsYWdzLm1lcmlkaWVtICYmIHBhcnNlZFBhcnRzKSk7XG5cbiAgICAgICAgICAgIGlmIChtLl9zdHJpY3QpIHtcbiAgICAgICAgICAgICAgICBpc05vd1ZhbGlkID0gaXNOb3dWYWxpZCAmJlxuICAgICAgICAgICAgICAgICAgICBmbGFncy5jaGFyc0xlZnRPdmVyID09PSAwICYmXG4gICAgICAgICAgICAgICAgICAgIGZsYWdzLnVudXNlZFRva2Vucy5sZW5ndGggPT09IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgZmxhZ3MuYmlnSG91ciA9PT0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoT2JqZWN0LmlzRnJvemVuID09IG51bGwgfHwgIU9iamVjdC5pc0Zyb3plbihtKSkge1xuICAgICAgICAgICAgICAgIG0uX2lzVmFsaWQgPSBpc05vd1ZhbGlkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzTm93VmFsaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG0uX2lzVmFsaWQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlSW52YWxpZCAoZmxhZ3MpIHtcbiAgICAgICAgdmFyIG0gPSBjcmVhdGVVVEMoTmFOKTtcbiAgICAgICAgaWYgKGZsYWdzICE9IG51bGwpIHtcbiAgICAgICAgICAgIGV4dGVuZChnZXRQYXJzaW5nRmxhZ3MobSksIGZsYWdzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhtKS51c2VySW52YWxpZGF0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG07XG4gICAgfVxuXG4gICAgLy8gUGx1Z2lucyB0aGF0IGFkZCBwcm9wZXJ0aWVzIHNob3VsZCBhbHNvIGFkZCB0aGUga2V5IGhlcmUgKG51bGwgdmFsdWUpLFxuICAgIC8vIHNvIHdlIGNhbiBwcm9wZXJseSBjbG9uZSBvdXJzZWx2ZXMuXG4gICAgdmFyIG1vbWVudFByb3BlcnRpZXMgPSBob29rcy5tb21lbnRQcm9wZXJ0aWVzID0gW107XG5cbiAgICBmdW5jdGlvbiBjb3B5Q29uZmlnKHRvLCBmcm9tKSB7XG4gICAgICAgIHZhciBpLCBwcm9wLCB2YWw7XG5cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9pc0FNb21lbnRPYmplY3QpKSB7XG4gICAgICAgICAgICB0by5faXNBTW9tZW50T2JqZWN0ID0gZnJvbS5faXNBTW9tZW50T2JqZWN0O1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5faSkpIHtcbiAgICAgICAgICAgIHRvLl9pID0gZnJvbS5faTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX2YpKSB7XG4gICAgICAgICAgICB0by5fZiA9IGZyb20uX2Y7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9sKSkge1xuICAgICAgICAgICAgdG8uX2wgPSBmcm9tLl9sO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fc3RyaWN0KSkge1xuICAgICAgICAgICAgdG8uX3N0cmljdCA9IGZyb20uX3N0cmljdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX3R6bSkpIHtcbiAgICAgICAgICAgIHRvLl90em0gPSBmcm9tLl90em07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9pc1VUQykpIHtcbiAgICAgICAgICAgIHRvLl9pc1VUQyA9IGZyb20uX2lzVVRDO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fb2Zmc2V0KSkge1xuICAgICAgICAgICAgdG8uX29mZnNldCA9IGZyb20uX29mZnNldDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX3BmKSkge1xuICAgICAgICAgICAgdG8uX3BmID0gZ2V0UGFyc2luZ0ZsYWdzKGZyb20pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fbG9jYWxlKSkge1xuICAgICAgICAgICAgdG8uX2xvY2FsZSA9IGZyb20uX2xvY2FsZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtb21lbnRQcm9wZXJ0aWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBtb21lbnRQcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcHJvcCA9IG1vbWVudFByb3BlcnRpZXNbaV07XG4gICAgICAgICAgICAgICAgdmFsID0gZnJvbVtwcm9wXTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKHZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9bcHJvcF0gPSB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRvO1xuICAgIH1cblxuICAgIHZhciB1cGRhdGVJblByb2dyZXNzID0gZmFsc2U7XG5cbiAgICAvLyBNb21lbnQgcHJvdG90eXBlIG9iamVjdFxuICAgIGZ1bmN0aW9uIE1vbWVudChjb25maWcpIHtcbiAgICAgICAgY29weUNvbmZpZyh0aGlzLCBjb25maWcpO1xuICAgICAgICB0aGlzLl9kID0gbmV3IERhdGUoY29uZmlnLl9kICE9IG51bGwgPyBjb25maWcuX2QuZ2V0VGltZSgpIDogTmFOKTtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgdGhpcy5fZCA9IG5ldyBEYXRlKE5hTik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUHJldmVudCBpbmZpbml0ZSBsb29wIGluIGNhc2UgdXBkYXRlT2Zmc2V0IGNyZWF0ZXMgbmV3IG1vbWVudFxuICAgICAgICAvLyBvYmplY3RzLlxuICAgICAgICBpZiAodXBkYXRlSW5Qcm9ncmVzcyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHVwZGF0ZUluUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMpO1xuICAgICAgICAgICAgdXBkYXRlSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNNb21lbnQgKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgTW9tZW50IHx8IChvYmogIT0gbnVsbCAmJiBvYmouX2lzQU1vbWVudE9iamVjdCAhPSBudWxsKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhYnNGbG9vciAobnVtYmVyKSB7XG4gICAgICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICAgICAgICAvLyAtMCAtPiAwXG4gICAgICAgICAgICByZXR1cm4gTWF0aC5jZWlsKG51bWJlcikgfHwgMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKG51bWJlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0ludChhcmd1bWVudEZvckNvZXJjaW9uKSB7XG4gICAgICAgIHZhciBjb2VyY2VkTnVtYmVyID0gK2FyZ3VtZW50Rm9yQ29lcmNpb24sXG4gICAgICAgICAgICB2YWx1ZSA9IDA7XG5cbiAgICAgICAgaWYgKGNvZXJjZWROdW1iZXIgIT09IDAgJiYgaXNGaW5pdGUoY29lcmNlZE51bWJlcikpIHtcbiAgICAgICAgICAgIHZhbHVlID0gYWJzRmxvb3IoY29lcmNlZE51bWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gY29tcGFyZSB0d28gYXJyYXlzLCByZXR1cm4gdGhlIG51bWJlciBvZiBkaWZmZXJlbmNlc1xuICAgIGZ1bmN0aW9uIGNvbXBhcmVBcnJheXMoYXJyYXkxLCBhcnJheTIsIGRvbnRDb252ZXJ0KSB7XG4gICAgICAgIHZhciBsZW4gPSBNYXRoLm1pbihhcnJheTEubGVuZ3RoLCBhcnJheTIubGVuZ3RoKSxcbiAgICAgICAgICAgIGxlbmd0aERpZmYgPSBNYXRoLmFicyhhcnJheTEubGVuZ3RoIC0gYXJyYXkyLmxlbmd0aCksXG4gICAgICAgICAgICBkaWZmcyA9IDAsXG4gICAgICAgICAgICBpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmICgoZG9udENvbnZlcnQgJiYgYXJyYXkxW2ldICE9PSBhcnJheTJbaV0pIHx8XG4gICAgICAgICAgICAgICAgKCFkb250Q29udmVydCAmJiB0b0ludChhcnJheTFbaV0pICE9PSB0b0ludChhcnJheTJbaV0pKSkge1xuICAgICAgICAgICAgICAgIGRpZmZzKys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRpZmZzICsgbGVuZ3RoRGlmZjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3YXJuKG1zZykge1xuICAgICAgICBpZiAoaG9va3Muc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmdzID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICh0eXBlb2YgY29uc29sZSAhPT0gICd1bmRlZmluZWQnKSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRGVwcmVjYXRpb24gd2FybmluZzogJyArIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkZXByZWNhdGUobXNnLCBmbikge1xuICAgICAgICB2YXIgZmlyc3RUaW1lID0gdHJ1ZTtcblxuICAgICAgICByZXR1cm4gZXh0ZW5kKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChob29rcy5kZXByZWNhdGlvbkhhbmRsZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGhvb2tzLmRlcHJlY2F0aW9uSGFuZGxlcihudWxsLCBtc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZpcnN0VGltZSkge1xuICAgICAgICAgICAgICAgIHZhciBhcmdzID0gW107XG4gICAgICAgICAgICAgICAgdmFyIGFyZztcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBhcmcgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbaV0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgKz0gJ1xcblsnICsgaSArICddICc7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gYXJndW1lbnRzWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnICs9IGtleSArICc6ICcgKyBhcmd1bWVudHNbMF1ba2V5XSArICcsICc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBhcmcuc2xpY2UoMCwgLTIpOyAvLyBSZW1vdmUgdHJhaWxpbmcgY29tbWEgYW5kIHNwYWNlXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKGFyZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdhcm4obXNnICsgJ1xcbkFyZ3VtZW50czogJyArIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MpLmpvaW4oJycpICsgJ1xcbicgKyAobmV3IEVycm9yKCkpLnN0YWNrKTtcbiAgICAgICAgICAgICAgICBmaXJzdFRpbWUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9LCBmbik7XG4gICAgfVxuXG4gICAgdmFyIGRlcHJlY2F0aW9ucyA9IHt9O1xuXG4gICAgZnVuY3Rpb24gZGVwcmVjYXRlU2ltcGxlKG5hbWUsIG1zZykge1xuICAgICAgICBpZiAoaG9va3MuZGVwcmVjYXRpb25IYW5kbGVyICE9IG51bGwpIHtcbiAgICAgICAgICAgIGhvb2tzLmRlcHJlY2F0aW9uSGFuZGxlcihuYW1lLCBtc2cpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZGVwcmVjYXRpb25zW25hbWVdKSB7XG4gICAgICAgICAgICB3YXJuKG1zZyk7XG4gICAgICAgICAgICBkZXByZWNhdGlvbnNbbmFtZV0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaG9va3Muc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmdzID0gZmFsc2U7XG4gICAgaG9va3MuZGVwcmVjYXRpb25IYW5kbGVyID0gbnVsbDtcblxuICAgIGZ1bmN0aW9uIGlzRnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0IGluc3RhbmNlb2YgRnVuY3Rpb24gfHwgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGlucHV0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXQgKGNvbmZpZykge1xuICAgICAgICB2YXIgcHJvcCwgaTtcbiAgICAgICAgZm9yIChpIGluIGNvbmZpZykge1xuICAgICAgICAgICAgcHJvcCA9IGNvbmZpZ1tpXTtcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHByb3ApKSB7XG4gICAgICAgICAgICAgICAgdGhpc1tpXSA9IHByb3A7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXNbJ18nICsgaV0gPSBwcm9wO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgLy8gTGVuaWVudCBvcmRpbmFsIHBhcnNpbmcgYWNjZXB0cyBqdXN0IGEgbnVtYmVyIGluIGFkZGl0aW9uIHRvXG4gICAgICAgIC8vIG51bWJlciArIChwb3NzaWJseSkgc3R1ZmYgY29taW5nIGZyb20gX2RheU9mTW9udGhPcmRpbmFsUGFyc2UuXG4gICAgICAgIC8vIFRPRE86IFJlbW92ZSBcIm9yZGluYWxQYXJzZVwiIGZhbGxiYWNrIGluIG5leHQgbWFqb3IgcmVsZWFzZS5cbiAgICAgICAgdGhpcy5fZGF5T2ZNb250aE9yZGluYWxQYXJzZUxlbmllbnQgPSBuZXcgUmVnRXhwKFxuICAgICAgICAgICAgKHRoaXMuX2RheU9mTW9udGhPcmRpbmFsUGFyc2Uuc291cmNlIHx8IHRoaXMuX29yZGluYWxQYXJzZS5zb3VyY2UpICtcbiAgICAgICAgICAgICAgICAnfCcgKyAoL1xcZHsxLDJ9Lykuc291cmNlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtZXJnZUNvbmZpZ3MocGFyZW50Q29uZmlnLCBjaGlsZENvbmZpZykge1xuICAgICAgICB2YXIgcmVzID0gZXh0ZW5kKHt9LCBwYXJlbnRDb25maWcpLCBwcm9wO1xuICAgICAgICBmb3IgKHByb3AgaW4gY2hpbGRDb25maWcpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd25Qcm9wKGNoaWxkQ29uZmlnLCBwcm9wKSkge1xuICAgICAgICAgICAgICAgIGlmIChpc09iamVjdChwYXJlbnRDb25maWdbcHJvcF0pICYmIGlzT2JqZWN0KGNoaWxkQ29uZmlnW3Byb3BdKSkge1xuICAgICAgICAgICAgICAgICAgICByZXNbcHJvcF0gPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kKHJlc1twcm9wXSwgcGFyZW50Q29uZmlnW3Byb3BdKTtcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kKHJlc1twcm9wXSwgY2hpbGRDb25maWdbcHJvcF0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hpbGRDb25maWdbcHJvcF0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXNbcHJvcF0gPSBjaGlsZENvbmZpZ1twcm9wXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcmVzW3Byb3BdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKHByb3AgaW4gcGFyZW50Q29uZmlnKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChwYXJlbnRDb25maWcsIHByb3ApICYmXG4gICAgICAgICAgICAgICAgICAgICFoYXNPd25Qcm9wKGNoaWxkQ29uZmlnLCBwcm9wKSAmJlxuICAgICAgICAgICAgICAgICAgICBpc09iamVjdChwYXJlbnRDb25maWdbcHJvcF0pKSB7XG4gICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGNoYW5nZXMgdG8gcHJvcGVydGllcyBkb24ndCBtb2RpZnkgcGFyZW50IGNvbmZpZ1xuICAgICAgICAgICAgICAgIHJlc1twcm9wXSA9IGV4dGVuZCh7fSwgcmVzW3Byb3BdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIExvY2FsZShjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZyAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnNldChjb25maWcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGtleXM7XG5cbiAgICBpZiAoT2JqZWN0LmtleXMpIHtcbiAgICAgICAga2V5cyA9IE9iamVjdC5rZXlzO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGtleXMgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICB2YXIgaSwgcmVzID0gW107XG4gICAgICAgICAgICBmb3IgKGkgaW4gb2JqKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhc093blByb3Aob2JqLCBpKSkge1xuICAgICAgICAgICAgICAgICAgICByZXMucHVzaChpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0Q2FsZW5kYXIgPSB7XG4gICAgICAgIHNhbWVEYXkgOiAnW1RvZGF5IGF0XSBMVCcsXG4gICAgICAgIG5leHREYXkgOiAnW1RvbW9ycm93IGF0XSBMVCcsXG4gICAgICAgIG5leHRXZWVrIDogJ2RkZGQgW2F0XSBMVCcsXG4gICAgICAgIGxhc3REYXkgOiAnW1llc3RlcmRheSBhdF0gTFQnLFxuICAgICAgICBsYXN0V2VlayA6ICdbTGFzdF0gZGRkZCBbYXRdIExUJyxcbiAgICAgICAgc2FtZUVsc2UgOiAnTCdcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gY2FsZW5kYXIgKGtleSwgbW9tLCBub3cpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX2NhbGVuZGFyW2tleV0gfHwgdGhpcy5fY2FsZW5kYXJbJ3NhbWVFbHNlJ107XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKG91dHB1dCkgPyBvdXRwdXQuY2FsbChtb20sIG5vdykgOiBvdXRwdXQ7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb25nRGF0ZUZvcm1hdCA9IHtcbiAgICAgICAgTFRTICA6ICdoOm1tOnNzIEEnLFxuICAgICAgICBMVCAgIDogJ2g6bW0gQScsXG4gICAgICAgIEwgICAgOiAnTU0vREQvWVlZWScsXG4gICAgICAgIExMICAgOiAnTU1NTSBELCBZWVlZJyxcbiAgICAgICAgTExMICA6ICdNTU1NIEQsIFlZWVkgaDptbSBBJyxcbiAgICAgICAgTExMTCA6ICdkZGRkLCBNTU1NIEQsIFlZWVkgaDptbSBBJ1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb25nRGF0ZUZvcm1hdCAoa2V5KSB7XG4gICAgICAgIHZhciBmb3JtYXQgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldLFxuICAgICAgICAgICAgZm9ybWF0VXBwZXIgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXkudG9VcHBlckNhc2UoKV07XG5cbiAgICAgICAgaWYgKGZvcm1hdCB8fCAhZm9ybWF0VXBwZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldID0gZm9ybWF0VXBwZXIucmVwbGFjZSgvTU1NTXxNTXxERHxkZGRkL2csIGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWwuc2xpY2UoMSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0SW52YWxpZERhdGUgPSAnSW52YWxpZCBkYXRlJztcblxuICAgIGZ1bmN0aW9uIGludmFsaWREYXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ludmFsaWREYXRlO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0T3JkaW5hbCA9ICclZCc7XG4gICAgdmFyIGRlZmF1bHREYXlPZk1vbnRoT3JkaW5hbFBhcnNlID0gL1xcZHsxLDJ9LztcblxuICAgIGZ1bmN0aW9uIG9yZGluYWwgKG51bWJlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3JkaW5hbC5yZXBsYWNlKCclZCcsIG51bWJlcik7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRSZWxhdGl2ZVRpbWUgPSB7XG4gICAgICAgIGZ1dHVyZSA6ICdpbiAlcycsXG4gICAgICAgIHBhc3QgICA6ICclcyBhZ28nLFxuICAgICAgICBzICA6ICdhIGZldyBzZWNvbmRzJyxcbiAgICAgICAgc3MgOiAnJWQgc2Vjb25kcycsXG4gICAgICAgIG0gIDogJ2EgbWludXRlJyxcbiAgICAgICAgbW0gOiAnJWQgbWludXRlcycsXG4gICAgICAgIGggIDogJ2FuIGhvdXInLFxuICAgICAgICBoaCA6ICclZCBob3VycycsXG4gICAgICAgIGQgIDogJ2EgZGF5JyxcbiAgICAgICAgZGQgOiAnJWQgZGF5cycsXG4gICAgICAgIE0gIDogJ2EgbW9udGgnLFxuICAgICAgICBNTSA6ICclZCBtb250aHMnLFxuICAgICAgICB5ICA6ICdhIHllYXInLFxuICAgICAgICB5eSA6ICclZCB5ZWFycydcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcmVsYXRpdmVUaW1lIChudW1iZXIsIHdpdGhvdXRTdWZmaXgsIHN0cmluZywgaXNGdXR1cmUpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX3JlbGF0aXZlVGltZVtzdHJpbmddO1xuICAgICAgICByZXR1cm4gKGlzRnVuY3Rpb24ob3V0cHV0KSkgP1xuICAgICAgICAgICAgb3V0cHV0KG51bWJlciwgd2l0aG91dFN1ZmZpeCwgc3RyaW5nLCBpc0Z1dHVyZSkgOlxuICAgICAgICAgICAgb3V0cHV0LnJlcGxhY2UoLyVkL2ksIG51bWJlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFzdEZ1dHVyZSAoZGlmZiwgb3V0cHV0KSB7XG4gICAgICAgIHZhciBmb3JtYXQgPSB0aGlzLl9yZWxhdGl2ZVRpbWVbZGlmZiA+IDAgPyAnZnV0dXJlJyA6ICdwYXN0J107XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKGZvcm1hdCkgPyBmb3JtYXQob3V0cHV0KSA6IGZvcm1hdC5yZXBsYWNlKC8lcy9pLCBvdXRwdXQpO1xuICAgIH1cblxuICAgIHZhciBhbGlhc2VzID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRVbml0QWxpYXMgKHVuaXQsIHNob3J0aGFuZCkge1xuICAgICAgICB2YXIgbG93ZXJDYXNlID0gdW5pdC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBhbGlhc2VzW2xvd2VyQ2FzZV0gPSBhbGlhc2VzW2xvd2VyQ2FzZSArICdzJ10gPSBhbGlhc2VzW3Nob3J0aGFuZF0gPSB1bml0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdW5pdHMgPT09ICdzdHJpbmcnID8gYWxpYXNlc1t1bml0c10gfHwgYWxpYXNlc1t1bml0cy50b0xvd2VyQ2FzZSgpXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBub3JtYWxpemVPYmplY3RVbml0cyhpbnB1dE9iamVjdCkge1xuICAgICAgICB2YXIgbm9ybWFsaXplZElucHV0ID0ge30sXG4gICAgICAgICAgICBub3JtYWxpemVkUHJvcCxcbiAgICAgICAgICAgIHByb3A7XG5cbiAgICAgICAgZm9yIChwcm9wIGluIGlucHV0T2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChpbnB1dE9iamVjdCwgcHJvcCkpIHtcbiAgICAgICAgICAgICAgICBub3JtYWxpemVkUHJvcCA9IG5vcm1hbGl6ZVVuaXRzKHByb3ApO1xuICAgICAgICAgICAgICAgIGlmIChub3JtYWxpemVkUHJvcCkge1xuICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkSW5wdXRbbm9ybWFsaXplZFByb3BdID0gaW5wdXRPYmplY3RbcHJvcF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRJbnB1dDtcbiAgICB9XG5cbiAgICB2YXIgcHJpb3JpdGllcyA9IHt9O1xuXG4gICAgZnVuY3Rpb24gYWRkVW5pdFByaW9yaXR5KHVuaXQsIHByaW9yaXR5KSB7XG4gICAgICAgIHByaW9yaXRpZXNbdW5pdF0gPSBwcmlvcml0eTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRQcmlvcml0aXplZFVuaXRzKHVuaXRzT2JqKSB7XG4gICAgICAgIHZhciB1bml0cyA9IFtdO1xuICAgICAgICBmb3IgKHZhciB1IGluIHVuaXRzT2JqKSB7XG4gICAgICAgICAgICB1bml0cy5wdXNoKHt1bml0OiB1LCBwcmlvcml0eTogcHJpb3JpdGllc1t1XX0pO1xuICAgICAgICB9XG4gICAgICAgIHVuaXRzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgIHJldHVybiBhLnByaW9yaXR5IC0gYi5wcmlvcml0eTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB1bml0cztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB6ZXJvRmlsbChudW1iZXIsIHRhcmdldExlbmd0aCwgZm9yY2VTaWduKSB7XG4gICAgICAgIHZhciBhYnNOdW1iZXIgPSAnJyArIE1hdGguYWJzKG51bWJlciksXG4gICAgICAgICAgICB6ZXJvc1RvRmlsbCA9IHRhcmdldExlbmd0aCAtIGFic051bWJlci5sZW5ndGgsXG4gICAgICAgICAgICBzaWduID0gbnVtYmVyID49IDA7XG4gICAgICAgIHJldHVybiAoc2lnbiA/IChmb3JjZVNpZ24gPyAnKycgOiAnJykgOiAnLScpICtcbiAgICAgICAgICAgIE1hdGgucG93KDEwLCBNYXRoLm1heCgwLCB6ZXJvc1RvRmlsbCkpLnRvU3RyaW5nKCkuc3Vic3RyKDEpICsgYWJzTnVtYmVyO1xuICAgIH1cblxuICAgIHZhciBmb3JtYXR0aW5nVG9rZW5zID0gLyhcXFtbXlxcW10qXFxdKXwoXFxcXCk/KFtIaF1tbShzcyk/fE1vfE1NP00/TT98RG98REREb3xERD9EP0Q/fGRkZD9kP3xkbz98d1tvfHddP3xXW298V10/fFFvP3xZWVlZWVl8WVlZWVl8WVlZWXxZWXxnZyhnZ2c/KT98R0coR0dHPyk/fGV8RXxhfEF8aGg/fEhIP3xraz98bW0/fHNzP3xTezEsOX18eHxYfHp6P3xaWj98LikvZztcblxuICAgIHZhciBsb2NhbEZvcm1hdHRpbmdUb2tlbnMgPSAvKFxcW1teXFxbXSpcXF0pfChcXFxcKT8oTFRTfExUfExMP0w/TD98bHsxLDR9KS9nO1xuXG4gICAgdmFyIGZvcm1hdEZ1bmN0aW9ucyA9IHt9O1xuXG4gICAgdmFyIGZvcm1hdFRva2VuRnVuY3Rpb25zID0ge307XG5cbiAgICAvLyB0b2tlbjogICAgJ00nXG4gICAgLy8gcGFkZGVkOiAgIFsnTU0nLCAyXVxuICAgIC8vIG9yZGluYWw6ICAnTW8nXG4gICAgLy8gY2FsbGJhY2s6IGZ1bmN0aW9uICgpIHsgdGhpcy5tb250aCgpICsgMSB9XG4gICAgZnVuY3Rpb24gYWRkRm9ybWF0VG9rZW4gKHRva2VuLCBwYWRkZWQsIG9yZGluYWwsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBmdW5jID0gY2FsbGJhY2s7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBmdW5jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW2NhbGxiYWNrXSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9rZW4pIHtcbiAgICAgICAgICAgIGZvcm1hdFRva2VuRnVuY3Rpb25zW3Rva2VuXSA9IGZ1bmM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhZGRlZCkge1xuICAgICAgICAgICAgZm9ybWF0VG9rZW5GdW5jdGlvbnNbcGFkZGVkWzBdXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gemVyb0ZpbGwoZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpLCBwYWRkZWRbMV0sIHBhZGRlZFsyXSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcmRpbmFsKSB7XG4gICAgICAgICAgICBmb3JtYXRUb2tlbkZ1bmN0aW9uc1tvcmRpbmFsXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkub3JkaW5hbChmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIHRva2VuKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGlucHV0KSB7XG4gICAgICAgIGlmIChpbnB1dC5tYXRjaCgvXFxbW1xcc1xcU10vKSkge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL15cXFt8XFxdJC9nLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL1xcXFwvZywgJycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VGb3JtYXRGdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgICAgdmFyIGFycmF5ID0gZm9ybWF0Lm1hdGNoKGZvcm1hdHRpbmdUb2tlbnMpLCBpLCBsZW5ndGg7XG5cbiAgICAgICAgZm9yIChpID0gMCwgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXRUb2tlbkZ1bmN0aW9uc1thcnJheVtpXV0pIHtcbiAgICAgICAgICAgICAgICBhcnJheVtpXSA9IGZvcm1hdFRva2VuRnVuY3Rpb25zW2FycmF5W2ldXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXJyYXlbaV0gPSByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGFycmF5W2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAobW9tKSB7XG4gICAgICAgICAgICB2YXIgb3V0cHV0ID0gJycsIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gaXNGdW5jdGlvbihhcnJheVtpXSkgPyBhcnJheVtpXS5jYWxsKG1vbSwgZm9ybWF0KSA6IGFycmF5W2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBmb3JtYXQgZGF0ZSB1c2luZyBuYXRpdmUgZGF0ZSBvYmplY3RcbiAgICBmdW5jdGlvbiBmb3JtYXRNb21lbnQobSwgZm9ybWF0KSB7XG4gICAgICAgIGlmICghbS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBtLmxvY2FsZURhdGEoKS5pbnZhbGlkRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9ybWF0ID0gZXhwYW5kRm9ybWF0KGZvcm1hdCwgbS5sb2NhbGVEYXRhKCkpO1xuICAgICAgICBmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XSA9IGZvcm1hdEZ1bmN0aW9uc1tmb3JtYXRdIHx8IG1ha2VGb3JtYXRGdW5jdGlvbihmb3JtYXQpO1xuXG4gICAgICAgIHJldHVybiBmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XShtKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBleHBhbmRGb3JtYXQoZm9ybWF0LCBsb2NhbGUpIHtcbiAgICAgICAgdmFyIGkgPSA1O1xuXG4gICAgICAgIGZ1bmN0aW9uIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2VucyhpbnB1dCkge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS5sb25nRGF0ZUZvcm1hdChpbnB1dCkgfHwgaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPj0gMCAmJiBsb2NhbEZvcm1hdHRpbmdUb2tlbnMudGVzdChmb3JtYXQpKSB7XG4gICAgICAgICAgICBmb3JtYXQgPSBmb3JtYXQucmVwbGFjZShsb2NhbEZvcm1hdHRpbmdUb2tlbnMsIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2Vucyk7XG4gICAgICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgfVxuXG4gICAgdmFyIG1hdGNoMSAgICAgICAgID0gL1xcZC87ICAgICAgICAgICAgLy8gICAgICAgMCAtIDlcbiAgICB2YXIgbWF0Y2gyICAgICAgICAgPSAvXFxkXFxkLzsgICAgICAgICAgLy8gICAgICAwMCAtIDk5XG4gICAgdmFyIG1hdGNoMyAgICAgICAgID0gL1xcZHszfS87ICAgICAgICAgLy8gICAgIDAwMCAtIDk5OVxuICAgIHZhciBtYXRjaDQgICAgICAgICA9IC9cXGR7NH0vOyAgICAgICAgIC8vICAgIDAwMDAgLSA5OTk5XG4gICAgdmFyIG1hdGNoNiAgICAgICAgID0gL1srLV0/XFxkezZ9LzsgICAgLy8gLTk5OTk5OSAtIDk5OTk5OVxuICAgIHZhciBtYXRjaDF0bzIgICAgICA9IC9cXGRcXGQ/LzsgICAgICAgICAvLyAgICAgICAwIC0gOTlcbiAgICB2YXIgbWF0Y2gzdG80ICAgICAgPSAvXFxkXFxkXFxkXFxkPy87ICAgICAvLyAgICAgOTk5IC0gOTk5OVxuICAgIHZhciBtYXRjaDV0bzYgICAgICA9IC9cXGRcXGRcXGRcXGRcXGRcXGQ/LzsgLy8gICA5OTk5OSAtIDk5OTk5OVxuICAgIHZhciBtYXRjaDF0bzMgICAgICA9IC9cXGR7MSwzfS87ICAgICAgIC8vICAgICAgIDAgLSA5OTlcbiAgICB2YXIgbWF0Y2gxdG80ICAgICAgPSAvXFxkezEsNH0vOyAgICAgICAvLyAgICAgICAwIC0gOTk5OVxuICAgIHZhciBtYXRjaDF0bzYgICAgICA9IC9bKy1dP1xcZHsxLDZ9LzsgIC8vIC05OTk5OTkgLSA5OTk5OTlcblxuICAgIHZhciBtYXRjaFVuc2lnbmVkICA9IC9cXGQrLzsgICAgICAgICAgIC8vICAgICAgIDAgLSBpbmZcbiAgICB2YXIgbWF0Y2hTaWduZWQgICAgPSAvWystXT9cXGQrLzsgICAgICAvLyAgICAtaW5mIC0gaW5mXG5cbiAgICB2YXIgbWF0Y2hPZmZzZXQgICAgPSAvWnxbKy1dXFxkXFxkOj9cXGRcXGQvZ2k7IC8vICswMDowMCAtMDA6MDAgKzAwMDAgLTAwMDAgb3IgWlxuICAgIHZhciBtYXRjaFNob3J0T2Zmc2V0ID0gL1p8WystXVxcZFxcZCg/Ojo/XFxkXFxkKT8vZ2k7IC8vICswMCAtMDAgKzAwOjAwIC0wMDowMCArMDAwMCAtMDAwMCBvciBaXG5cbiAgICB2YXIgbWF0Y2hUaW1lc3RhbXAgPSAvWystXT9cXGQrKFxcLlxcZHsxLDN9KT8vOyAvLyAxMjM0NTY3ODkgMTIzNDU2Nzg5LjEyM1xuXG4gICAgLy8gYW55IHdvcmQgKG9yIHR3bykgY2hhcmFjdGVycyBvciBudW1iZXJzIGluY2x1ZGluZyB0d28vdGhyZWUgd29yZCBtb250aCBpbiBhcmFiaWMuXG4gICAgLy8gaW5jbHVkZXMgc2NvdHRpc2ggZ2FlbGljIHR3byB3b3JkIGFuZCBoeXBoZW5hdGVkIG1vbnRoc1xuICAgIHZhciBtYXRjaFdvcmQgPSAvWzAtOV17MCwyNTZ9WydhLXpcXHUwMEEwLVxcdTA1RkZcXHUwNzAwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGMDdcXHVGRjEwLVxcdUZGRUZdezEsMjU2fXxbXFx1MDYwMC1cXHUwNkZGXFwvXXsxLDI1Nn0oXFxzKj9bXFx1MDYwMC1cXHUwNkZGXXsxLDI1Nn0pezEsMn0vaTtcblxuICAgIHZhciByZWdleGVzID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRSZWdleFRva2VuICh0b2tlbiwgcmVnZXgsIHN0cmljdFJlZ2V4KSB7XG4gICAgICAgIHJlZ2V4ZXNbdG9rZW5dID0gaXNGdW5jdGlvbihyZWdleCkgPyByZWdleCA6IGZ1bmN0aW9uIChpc1N0cmljdCwgbG9jYWxlRGF0YSkge1xuICAgICAgICAgICAgcmV0dXJuIChpc1N0cmljdCAmJiBzdHJpY3RSZWdleCkgPyBzdHJpY3RSZWdleCA6IHJlZ2V4O1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFBhcnNlUmVnZXhGb3JUb2tlbiAodG9rZW4sIGNvbmZpZykge1xuICAgICAgICBpZiAoIWhhc093blByb3AocmVnZXhlcywgdG9rZW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cCh1bmVzY2FwZUZvcm1hdCh0b2tlbikpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlZ2V4ZXNbdG9rZW5dKGNvbmZpZy5fc3RyaWN0LCBjb25maWcuX2xvY2FsZSk7XG4gICAgfVxuXG4gICAgLy8gQ29kZSBmcm9tIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzU2MTQ5My9pcy10aGVyZS1hLXJlZ2V4cC1lc2NhcGUtZnVuY3Rpb24taW4tamF2YXNjcmlwdFxuICAgIGZ1bmN0aW9uIHVuZXNjYXBlRm9ybWF0KHMpIHtcbiAgICAgICAgcmV0dXJuIHJlZ2V4RXNjYXBlKHMucmVwbGFjZSgnXFxcXCcsICcnKS5yZXBsYWNlKC9cXFxcKFxcWyl8XFxcXChcXF0pfFxcWyhbXlxcXVxcW10qKVxcXXxcXFxcKC4pL2csIGZ1bmN0aW9uIChtYXRjaGVkLCBwMSwgcDIsIHAzLCBwNCkge1xuICAgICAgICAgICAgcmV0dXJuIHAxIHx8IHAyIHx8IHAzIHx8IHA0O1xuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVnZXhFc2NhcGUocykge1xuICAgICAgICByZXR1cm4gcy5yZXBsYWNlKC9bLVxcL1xcXFxeJCorPy4oKXxbXFxde31dL2csICdcXFxcJCYnKTtcbiAgICB9XG5cbiAgICB2YXIgdG9rZW5zID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRQYXJzZVRva2VuICh0b2tlbiwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGksIGZ1bmMgPSBjYWxsYmFjaztcbiAgICAgICAgaWYgKHR5cGVvZiB0b2tlbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRva2VuID0gW3Rva2VuXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNOdW1iZXIoY2FsbGJhY2spKSB7XG4gICAgICAgICAgICBmdW5jID0gZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICAgICAgICAgIGFycmF5W2NhbGxiYWNrXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRva2VuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0b2tlbnNbdG9rZW5baV1dID0gZnVuYztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFdlZWtQYXJzZVRva2VuICh0b2tlbiwgY2FsbGJhY2spIHtcbiAgICAgICAgYWRkUGFyc2VUb2tlbih0b2tlbiwgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnLCB0b2tlbikge1xuICAgICAgICAgICAgY29uZmlnLl93ID0gY29uZmlnLl93IHx8IHt9O1xuICAgICAgICAgICAgY2FsbGJhY2soaW5wdXQsIGNvbmZpZy5fdywgY29uZmlnLCB0b2tlbik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFRpbWVUb0FycmF5RnJvbVRva2VuKHRva2VuLCBpbnB1dCwgY29uZmlnKSB7XG4gICAgICAgIGlmIChpbnB1dCAhPSBudWxsICYmIGhhc093blByb3AodG9rZW5zLCB0b2tlbikpIHtcbiAgICAgICAgICAgIHRva2Vuc1t0b2tlbl0oaW5wdXQsIGNvbmZpZy5fYSwgY29uZmlnLCB0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgWUVBUiA9IDA7XG4gICAgdmFyIE1PTlRIID0gMTtcbiAgICB2YXIgREFURSA9IDI7XG4gICAgdmFyIEhPVVIgPSAzO1xuICAgIHZhciBNSU5VVEUgPSA0O1xuICAgIHZhciBTRUNPTkQgPSA1O1xuICAgIHZhciBNSUxMSVNFQ09ORCA9IDY7XG4gICAgdmFyIFdFRUsgPSA3O1xuICAgIHZhciBXRUVLREFZID0gODtcblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdZJywgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgeSA9IHRoaXMueWVhcigpO1xuICAgICAgICByZXR1cm4geSA8PSA5OTk5ID8gJycgKyB5IDogJysnICsgeTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnWVknLCAyXSwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy55ZWFyKCkgJSAxMDA7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1lZWVknLCAgIDRdLCAgICAgICAwLCAneWVhcicpO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnWVlZWVknLCAgNV0sICAgICAgIDAsICd5ZWFyJyk7XG4gICAgYWRkRm9ybWF0VG9rZW4oMCwgWydZWVlZWVknLCA2LCB0cnVlXSwgMCwgJ3llYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygneWVhcicsICd5Jyk7XG5cbiAgICAvLyBQUklPUklUSUVTXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ3llYXInLCAxKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1knLCAgICAgIG1hdGNoU2lnbmVkKTtcbiAgICBhZGRSZWdleFRva2VuKCdZWScsICAgICBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignWVlZWScsICAgbWF0Y2gxdG80LCBtYXRjaDQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1lZWVlZJywgIG1hdGNoMXRvNiwgbWF0Y2g2KTtcbiAgICBhZGRSZWdleFRva2VuKCdZWVlZWVknLCBtYXRjaDF0bzYsIG1hdGNoNik7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnWVlZWVknLCAnWVlZWVlZJ10sIFlFQVIpO1xuICAgIGFkZFBhcnNlVG9rZW4oJ1lZWVknLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5KSB7XG4gICAgICAgIGFycmF5W1lFQVJdID0gaW5wdXQubGVuZ3RoID09PSAyID8gaG9va3MucGFyc2VUd29EaWdpdFllYXIoaW5wdXQpIDogdG9JbnQoaW5wdXQpO1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oJ1lZJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtZRUFSXSA9IGhvb2tzLnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCdZJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtZRUFSXSA9IHBhcnNlSW50KGlucHV0LCAxMCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICBmdW5jdGlvbiBkYXlzSW5ZZWFyKHllYXIpIHtcbiAgICAgICAgcmV0dXJuIGlzTGVhcFllYXIoeWVhcikgPyAzNjYgOiAzNjU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNMZWFwWWVhcih5ZWFyKSB7XG4gICAgICAgIHJldHVybiAoeWVhciAlIDQgPT09IDAgJiYgeWVhciAlIDEwMCAhPT0gMCkgfHwgeWVhciAlIDQwMCA9PT0gMDtcbiAgICB9XG5cbiAgICAvLyBIT09LU1xuXG4gICAgaG9va3MucGFyc2VUd29EaWdpdFllYXIgPSBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHRvSW50KGlucHV0KSArICh0b0ludChpbnB1dCkgPiA2OCA/IDE5MDAgOiAyMDAwKTtcbiAgICB9O1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgdmFyIGdldFNldFllYXIgPSBtYWtlR2V0U2V0KCdGdWxsWWVhcicsIHRydWUpO1xuXG4gICAgZnVuY3Rpb24gZ2V0SXNMZWFwWWVhciAoKSB7XG4gICAgICAgIHJldHVybiBpc0xlYXBZZWFyKHRoaXMueWVhcigpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlR2V0U2V0ICh1bml0LCBrZWVwVGltZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHNldCQxKHRoaXMsIHVuaXQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywga2VlcFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0KHRoaXMsIHVuaXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldCAobW9tLCB1bml0KSB7XG4gICAgICAgIHJldHVybiBtb20uaXNWYWxpZCgpID9cbiAgICAgICAgICAgIG1vbS5fZFsnZ2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyB1bml0XSgpIDogTmFOO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldCQxIChtb20sIHVuaXQsIHZhbHVlKSB7XG4gICAgICAgIGlmIChtb20uaXNWYWxpZCgpICYmICFpc05hTih2YWx1ZSkpIHtcbiAgICAgICAgICAgIGlmICh1bml0ID09PSAnRnVsbFllYXInICYmIGlzTGVhcFllYXIobW9tLnllYXIoKSkgJiYgbW9tLm1vbnRoKCkgPT09IDEgJiYgbW9tLmRhdGUoKSA9PT0gMjkpIHtcbiAgICAgICAgICAgICAgICBtb20uX2RbJ3NldCcgKyAobW9tLl9pc1VUQyA/ICdVVEMnIDogJycpICsgdW5pdF0odmFsdWUsIG1vbS5tb250aCgpLCBkYXlzSW5Nb250aCh2YWx1ZSwgbW9tLm1vbnRoKCkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyB1bml0XSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBzdHJpbmdHZXQgKHVuaXRzKSB7XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICBpZiAoaXNGdW5jdGlvbih0aGlzW3VuaXRzXSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzXSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gc3RyaW5nU2V0ICh1bml0cywgdmFsdWUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB1bml0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHVuaXRzID0gbm9ybWFsaXplT2JqZWN0VW5pdHModW5pdHMpO1xuICAgICAgICAgICAgdmFyIHByaW9yaXRpemVkID0gZ2V0UHJpb3JpdGl6ZWRVbml0cyh1bml0cyk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByaW9yaXRpemVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpc1twcmlvcml0aXplZFtpXS51bml0XSh1bml0c1twcmlvcml0aXplZFtpXS51bml0XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHRoaXNbdW5pdHNdKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzXSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbW9kKG4sIHgpIHtcbiAgICAgICAgcmV0dXJuICgobiAlIHgpICsgeCkgJSB4O1xuICAgIH1cblxuICAgIHZhciBpbmRleE9mO1xuXG4gICAgaWYgKEFycmF5LnByb3RvdHlwZS5pbmRleE9mKSB7XG4gICAgICAgIGluZGV4T2YgPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZjtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpbmRleE9mID0gZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgICAgIC8vIEkga25vd1xuICAgICAgICAgICAgdmFyIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSBvKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlzSW5Nb250aCh5ZWFyLCBtb250aCkge1xuICAgICAgICBpZiAoaXNOYU4oeWVhcikgfHwgaXNOYU4obW9udGgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtb2RNb250aCA9IG1vZChtb250aCwgMTIpO1xuICAgICAgICB5ZWFyICs9IChtb250aCAtIG1vZE1vbnRoKSAvIDEyO1xuICAgICAgICByZXR1cm4gbW9kTW9udGggPT09IDEgPyAoaXNMZWFwWWVhcih5ZWFyKSA/IDI5IDogMjgpIDogKDMxIC0gbW9kTW9udGggJSA3ICUgMik7XG4gICAgfVxuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ00nLCBbJ01NJywgMl0sICdNbycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9udGgoKSArIDE7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignTU1NJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzU2hvcnQodGhpcywgZm9ybWF0KTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdNTU1NJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzKHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21vbnRoJywgJ00nKTtcblxuICAgIC8vIFBSSU9SSVRZXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ21vbnRoJywgOCk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdNJywgICAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdNTScsICAgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ01NTScsICBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLm1vbnRoc1Nob3J0UmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ01NTU0nLCBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLm1vbnRoc1JlZ2V4KGlzU3RyaWN0KTtcbiAgICB9KTtcblxuICAgIGFkZFBhcnNlVG9rZW4oWydNJywgJ01NJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbTU9OVEhdID0gdG9JbnQoaW5wdXQpIC0gMTtcbiAgICB9KTtcblxuICAgIGFkZFBhcnNlVG9rZW4oWydNTU0nLCAnTU1NTSddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcsIHRva2VuKSB7XG4gICAgICAgIHZhciBtb250aCA9IGNvbmZpZy5fbG9jYWxlLm1vbnRoc1BhcnNlKGlucHV0LCB0b2tlbiwgY29uZmlnLl9zdHJpY3QpO1xuICAgICAgICAvLyBpZiB3ZSBkaWRuJ3QgZmluZCBhIG1vbnRoIG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZC5cbiAgICAgICAgaWYgKG1vbnRoICE9IG51bGwpIHtcbiAgICAgICAgICAgIGFycmF5W01PTlRIXSA9IG1vbnRoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuaW52YWxpZE1vbnRoID0gaW5wdXQ7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIExPQ0FMRVNcblxuICAgIHZhciBNT05USFNfSU5fRk9STUFUID0gL0Rbb0RdPyhcXFtbXlxcW1xcXV0qXFxdfFxccykrTU1NTT8vO1xuICAgIHZhciBkZWZhdWx0TG9jYWxlTW9udGhzID0gJ0phbnVhcnlfRmVicnVhcnlfTWFyY2hfQXByaWxfTWF5X0p1bmVfSnVseV9BdWd1c3RfU2VwdGVtYmVyX09jdG9iZXJfTm92ZW1iZXJfRGVjZW1iZXInLnNwbGl0KCdfJyk7XG4gICAgZnVuY3Rpb24gbG9jYWxlTW9udGhzIChtLCBmb3JtYXQpIHtcbiAgICAgICAgaWYgKCFtKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNBcnJheSh0aGlzLl9tb250aHMpID8gdGhpcy5fbW9udGhzIDpcbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNbJ3N0YW5kYWxvbmUnXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNBcnJheSh0aGlzLl9tb250aHMpID8gdGhpcy5fbW9udGhzW20ubW9udGgoKV0gOlxuICAgICAgICAgICAgdGhpcy5fbW9udGhzWyh0aGlzLl9tb250aHMuaXNGb3JtYXQgfHwgTU9OVEhTX0lOX0ZPUk1BVCkudGVzdChmb3JtYXQpID8gJ2Zvcm1hdCcgOiAnc3RhbmRhbG9uZSddW20ubW9udGgoKV07XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb2NhbGVNb250aHNTaG9ydCA9ICdKYW5fRmViX01hcl9BcHJfTWF5X0p1bl9KdWxfQXVnX1NlcF9PY3RfTm92X0RlYycuc3BsaXQoJ18nKTtcbiAgICBmdW5jdGlvbiBsb2NhbGVNb250aHNTaG9ydCAobSwgZm9ybWF0KSB7XG4gICAgICAgIGlmICghbSkge1xuICAgICAgICAgICAgcmV0dXJuIGlzQXJyYXkodGhpcy5fbW9udGhzU2hvcnQpID8gdGhpcy5fbW9udGhzU2hvcnQgOlxuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1Nob3J0WydzdGFuZGFsb25lJ107XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlzQXJyYXkodGhpcy5fbW9udGhzU2hvcnQpID8gdGhpcy5fbW9udGhzU2hvcnRbbS5tb250aCgpXSA6XG4gICAgICAgICAgICB0aGlzLl9tb250aHNTaG9ydFtNT05USFNfSU5fRk9STUFULnRlc3QoZm9ybWF0KSA/ICdmb3JtYXQnIDogJ3N0YW5kYWxvbmUnXVttLm1vbnRoKCldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZVN0cmljdFBhcnNlKG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGksIGlpLCBtb20sIGxsYyA9IG1vbnRoTmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoIXRoaXMuX21vbnRoc1BhcnNlKSB7XG4gICAgICAgICAgICAvLyB0aGlzIGlzIG5vdCB1c2VkXG4gICAgICAgICAgICB0aGlzLl9tb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTI7ICsraSkge1xuICAgICAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgaV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Nob3J0TW9udGhzUGFyc2VbaV0gPSB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldID0gdGhpcy5tb250aHMobW9tLCAnJykudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdNTU0nKSB7XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9sb25nTW9udGhzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdNTU0nKSB7XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fbG9uZ01vbnRoc1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpaSAhPT0gLTEgPyBpaSA6IG51bGw7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX2xvbmdNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9jYWxlTW9udGhzUGFyc2UgKG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGksIG1vbSwgcmVnZXg7XG5cbiAgICAgICAgaWYgKHRoaXMuX21vbnRoc1BhcnNlRXhhY3QpIHtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVTdHJpY3RQYXJzZS5jYWxsKHRoaXMsIG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLl9tb250aHNQYXJzZSkge1xuICAgICAgICAgICAgdGhpcy5fbW9udGhzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX2xvbmdNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVE9ETzogYWRkIHNvcnRpbmdcbiAgICAgICAgLy8gU29ydGluZyBtYWtlcyBzdXJlIGlmIG9uZSBtb250aCAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlclxuICAgICAgICAvLyBzZWUgc29ydGluZyBpbiBjb21wdXRlTW9udGhzUGFyc2VcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuICAgICAgICAgICAgbW9tID0gY3JlYXRlVVRDKFsyMDAwLCBpXSk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmICF0aGlzLl9sb25nTW9udGhzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb25nTW9udGhzUGFyc2VbaV0gPSBuZXcgUmVnRXhwKCdeJyArIHRoaXMubW9udGhzKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnJykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZVtpXSA9IG5ldyBSZWdFeHAoJ14nICsgdGhpcy5tb250aHNTaG9ydChtb20sICcnKS5yZXBsYWNlKCcuJywgJycpICsgJyQnLCAnaScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFzdHJpY3QgJiYgIXRoaXMuX21vbnRoc1BhcnNlW2ldKSB7XG4gICAgICAgICAgICAgICAgcmVnZXggPSAnXicgKyB0aGlzLm1vbnRocyhtb20sICcnKSArICd8XicgKyB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1BhcnNlW2ldID0gbmV3IFJlZ0V4cChyZWdleC5yZXBsYWNlKCcuJywgJycpLCAnaScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdGVzdCB0aGUgcmVnZXhcbiAgICAgICAgICAgIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NTScgJiYgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NJyAmJiB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghc3RyaWN0ICYmIHRoaXMuX21vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgZnVuY3Rpb24gc2V0TW9udGggKG1vbSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIGRheU9mTW9udGg7XG5cbiAgICAgICAgaWYgKCFtb20uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICAvLyBObyBvcFxuICAgICAgICAgICAgcmV0dXJuIG1vbTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAoL15cXGQrJC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRvSW50KHZhbHVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBtb20ubG9jYWxlRGF0YSgpLm1vbnRoc1BhcnNlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBBbm90aGVyIHNpbGVudCBmYWlsdXJlP1xuICAgICAgICAgICAgICAgIGlmICghaXNOdW1iZXIodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtb207XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZGF5T2ZNb250aCA9IE1hdGgubWluKG1vbS5kYXRlKCksIGRheXNJbk1vbnRoKG1vbS55ZWFyKCksIHZhbHVlKSk7XG4gICAgICAgIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyAnTW9udGgnXSh2YWx1ZSwgZGF5T2ZNb250aCk7XG4gICAgICAgIHJldHVybiBtb207XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2V0TW9udGggKHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBzZXRNb250aCh0aGlzLCB2YWx1ZSk7XG4gICAgICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBnZXQodGhpcywgJ01vbnRoJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXREYXlzSW5Nb250aCAoKSB7XG4gICAgICAgIHJldHVybiBkYXlzSW5Nb250aCh0aGlzLnllYXIoKSwgdGhpcy5tb250aCgpKTtcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdE1vbnRoc1Nob3J0UmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gbW9udGhzU2hvcnRSZWdleCAoaXNTdHJpY3QpIHtcbiAgICAgICAgaWYgKHRoaXMuX21vbnRoc1BhcnNlRXhhY3QpIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlTW9udGhzUGFyc2UuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1N0cmljdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1Nob3J0UmVnZXgnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1Nob3J0UmVnZXggPSBkZWZhdWx0TW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4ICYmIGlzU3RyaWN0ID9cbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4IDogdGhpcy5fbW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TW9udGhzUmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gbW9udGhzUmVnZXggKGlzU3RyaWN0KSB7XG4gICAgICAgIGlmICh0aGlzLl9tb250aHNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ19tb250aHNSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgY29tcHV0ZU1vbnRoc1BhcnNlLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNTdHJpY3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNSZWdleCA9IGRlZmF1bHRNb250aHNSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTdHJpY3RSZWdleCAmJiBpc1N0cmljdCA/XG4gICAgICAgICAgICAgICAgdGhpcy5fbW9udGhzU3RyaWN0UmVnZXggOiB0aGlzLl9tb250aHNSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbXB1dGVNb250aHNQYXJzZSAoKSB7XG4gICAgICAgIGZ1bmN0aW9uIGNtcExlblJldihhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi5sZW5ndGggLSBhLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzaG9ydFBpZWNlcyA9IFtdLCBsb25nUGllY2VzID0gW10sIG1peGVkUGllY2VzID0gW10sXG4gICAgICAgICAgICBpLCBtb207XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG4gICAgICAgICAgICAvLyBtYWtlIHRoZSByZWdleCBpZiB3ZSBkb24ndCBoYXZlIGl0IGFscmVhZHlcbiAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgaV0pO1xuICAgICAgICAgICAgc2hvcnRQaWVjZXMucHVzaCh0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpKTtcbiAgICAgICAgICAgIGxvbmdQaWVjZXMucHVzaCh0aGlzLm1vbnRocyhtb20sICcnKSk7XG4gICAgICAgICAgICBtaXhlZFBpZWNlcy5wdXNoKHRoaXMubW9udGhzKG1vbSwgJycpKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2godGhpcy5tb250aHNTaG9ydChtb20sICcnKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU29ydGluZyBtYWtlcyBzdXJlIGlmIG9uZSBtb250aCAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlciBpdFxuICAgICAgICAvLyB3aWxsIG1hdGNoIHRoZSBsb25nZXIgcGllY2UuXG4gICAgICAgIHNob3J0UGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgbG9uZ1BpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIG1peGVkUGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgIHNob3J0UGllY2VzW2ldID0gcmVnZXhFc2NhcGUoc2hvcnRQaWVjZXNbaV0pO1xuICAgICAgICAgICAgbG9uZ1BpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKGxvbmdQaWVjZXNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNDsgaSsrKSB7XG4gICAgICAgICAgICBtaXhlZFBpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKG1peGVkUGllY2VzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX21vbnRoc1JlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbWl4ZWRQaWVjZXMuam9pbignfCcpICsgJyknLCAnaScpO1xuICAgICAgICB0aGlzLl9tb250aHNTaG9ydFJlZ2V4ID0gdGhpcy5fbW9udGhzUmVnZXg7XG4gICAgICAgIHRoaXMuX21vbnRoc1N0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbG9uZ1BpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgICAgIHRoaXMuX21vbnRoc1Nob3J0U3RyaWN0UmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBzaG9ydFBpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlRGF0ZSAoeSwgbSwgZCwgaCwgTSwgcywgbXMpIHtcbiAgICAgICAgLy8gY2FuJ3QganVzdCBhcHBseSgpIHRvIGNyZWF0ZSBhIGRhdGU6XG4gICAgICAgIC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcS8xODEzNDhcbiAgICAgICAgdmFyIGRhdGU7XG4gICAgICAgIC8vIHRoZSBkYXRlIGNvbnN0cnVjdG9yIHJlbWFwcyB5ZWFycyAwLTk5IHRvIDE5MDAtMTk5OVxuICAgICAgICBpZiAoeSA8IDEwMCAmJiB5ID49IDApIHtcbiAgICAgICAgICAgIC8vIHByZXNlcnZlIGxlYXAgeWVhcnMgdXNpbmcgYSBmdWxsIDQwMCB5ZWFyIGN5Y2xlLCB0aGVuIHJlc2V0XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoeSArIDQwMCwgbSwgZCwgaCwgTSwgcywgbXMpO1xuICAgICAgICAgICAgaWYgKGlzRmluaXRlKGRhdGUuZ2V0RnVsbFllYXIoKSkpIHtcbiAgICAgICAgICAgICAgICBkYXRlLnNldEZ1bGxZZWFyKHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKHksIG0sIGQsIGgsIE0sIHMsIG1zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkYXRlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZVVUQ0RhdGUgKHkpIHtcbiAgICAgICAgdmFyIGRhdGU7XG4gICAgICAgIC8vIHRoZSBEYXRlLlVUQyBmdW5jdGlvbiByZW1hcHMgeWVhcnMgMC05OSB0byAxOTAwLTE5OTlcbiAgICAgICAgaWYgKHkgPCAxMDAgJiYgeSA+PSAwKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAvLyBwcmVzZXJ2ZSBsZWFwIHllYXJzIHVzaW5nIGEgZnVsbCA0MDAgeWVhciBjeWNsZSwgdGhlbiByZXNldFxuICAgICAgICAgICAgYXJnc1swXSA9IHkgKyA0MDA7XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoRGF0ZS5VVEMuYXBwbHkobnVsbCwgYXJncykpO1xuICAgICAgICAgICAgaWYgKGlzRmluaXRlKGRhdGUuZ2V0VVRDRnVsbFllYXIoKSkpIHtcbiAgICAgICAgICAgICAgICBkYXRlLnNldFVUQ0Z1bGxZZWFyKHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDLmFwcGx5KG51bGwsIGFyZ3VtZW50cykpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgLy8gc3RhcnQtb2YtZmlyc3Qtd2VlayAtIHN0YXJ0LW9mLXllYXJcbiAgICBmdW5jdGlvbiBmaXJzdFdlZWtPZmZzZXQoeWVhciwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIC8vIGZpcnN0LXdlZWsgZGF5IC0tIHdoaWNoIGphbnVhcnkgaXMgYWx3YXlzIGluIHRoZSBmaXJzdCB3ZWVrICg0IGZvciBpc28sIDEgZm9yIG90aGVyKVxuICAgICAgICAgICAgZndkID0gNyArIGRvdyAtIGRveSxcbiAgICAgICAgICAgIC8vIGZpcnN0LXdlZWsgZGF5IGxvY2FsIHdlZWtkYXkgLS0gd2hpY2ggbG9jYWwgd2Vla2RheSBpcyBmd2RcbiAgICAgICAgICAgIGZ3ZGx3ID0gKDcgKyBjcmVhdGVVVENEYXRlKHllYXIsIDAsIGZ3ZCkuZ2V0VVRDRGF5KCkgLSBkb3cpICUgNztcblxuICAgICAgICByZXR1cm4gLWZ3ZGx3ICsgZndkIC0gMTtcbiAgICB9XG5cbiAgICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlI0NhbGN1bGF0aW5nX2FfZGF0ZV9naXZlbl90aGVfeWVhci4yQ193ZWVrX251bWJlcl9hbmRfd2Vla2RheVxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrcyh5ZWFyLCB3ZWVrLCB3ZWVrZGF5LCBkb3csIGRveSkge1xuICAgICAgICB2YXIgbG9jYWxXZWVrZGF5ID0gKDcgKyB3ZWVrZGF5IC0gZG93KSAlIDcsXG4gICAgICAgICAgICB3ZWVrT2Zmc2V0ID0gZmlyc3RXZWVrT2Zmc2V0KHllYXIsIGRvdywgZG95KSxcbiAgICAgICAgICAgIGRheU9mWWVhciA9IDEgKyA3ICogKHdlZWsgLSAxKSArIGxvY2FsV2Vla2RheSArIHdlZWtPZmZzZXQsXG4gICAgICAgICAgICByZXNZZWFyLCByZXNEYXlPZlllYXI7XG5cbiAgICAgICAgaWYgKGRheU9mWWVhciA8PSAwKSB7XG4gICAgICAgICAgICByZXNZZWFyID0geWVhciAtIDE7XG4gICAgICAgICAgICByZXNEYXlPZlllYXIgPSBkYXlzSW5ZZWFyKHJlc1llYXIpICsgZGF5T2ZZZWFyO1xuICAgICAgICB9IGVsc2UgaWYgKGRheU9mWWVhciA+IGRheXNJblllYXIoeWVhcikpIHtcbiAgICAgICAgICAgIHJlc1llYXIgPSB5ZWFyICsgMTtcbiAgICAgICAgICAgIHJlc0RheU9mWWVhciA9IGRheU9mWWVhciAtIGRheXNJblllYXIoeWVhcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNZZWFyID0geWVhcjtcbiAgICAgICAgICAgIHJlc0RheU9mWWVhciA9IGRheU9mWWVhcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB5ZWFyOiByZXNZZWFyLFxuICAgICAgICAgICAgZGF5T2ZZZWFyOiByZXNEYXlPZlllYXJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3ZWVrT2ZZZWFyKG1vbSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIHdlZWtPZmZzZXQgPSBmaXJzdFdlZWtPZmZzZXQobW9tLnllYXIoKSwgZG93LCBkb3kpLFxuICAgICAgICAgICAgd2VlayA9IE1hdGguZmxvb3IoKG1vbS5kYXlPZlllYXIoKSAtIHdlZWtPZmZzZXQgLSAxKSAvIDcpICsgMSxcbiAgICAgICAgICAgIHJlc1dlZWssIHJlc1llYXI7XG5cbiAgICAgICAgaWYgKHdlZWsgPCAxKSB7XG4gICAgICAgICAgICByZXNZZWFyID0gbW9tLnllYXIoKSAtIDE7XG4gICAgICAgICAgICByZXNXZWVrID0gd2VlayArIHdlZWtzSW5ZZWFyKHJlc1llYXIsIGRvdywgZG95KTtcbiAgICAgICAgfSBlbHNlIGlmICh3ZWVrID4gd2Vla3NJblllYXIobW9tLnllYXIoKSwgZG93LCBkb3kpKSB7XG4gICAgICAgICAgICByZXNXZWVrID0gd2VlayAtIHdlZWtzSW5ZZWFyKG1vbS55ZWFyKCksIGRvdywgZG95KTtcbiAgICAgICAgICAgIHJlc1llYXIgPSBtb20ueWVhcigpICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc1llYXIgPSBtb20ueWVhcigpO1xuICAgICAgICAgICAgcmVzV2VlayA9IHdlZWs7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgd2VlazogcmVzV2VlayxcbiAgICAgICAgICAgIHllYXI6IHJlc1llYXJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3ZWVrc0luWWVhcih5ZWFyLCBkb3csIGRveSkge1xuICAgICAgICB2YXIgd2Vla09mZnNldCA9IGZpcnN0V2Vla09mZnNldCh5ZWFyLCBkb3csIGRveSksXG4gICAgICAgICAgICB3ZWVrT2Zmc2V0TmV4dCA9IGZpcnN0V2Vla09mZnNldCh5ZWFyICsgMSwgZG93LCBkb3kpO1xuICAgICAgICByZXR1cm4gKGRheXNJblllYXIoeWVhcikgLSB3ZWVrT2Zmc2V0ICsgd2Vla09mZnNldE5leHQpIC8gNztcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigndycsIFsnd3cnLCAyXSwgJ3dvJywgJ3dlZWsnKTtcbiAgICBhZGRGb3JtYXRUb2tlbignVycsIFsnV1cnLCAyXSwgJ1dvJywgJ2lzb1dlZWsnKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnd2VlaycsICd3Jyk7XG4gICAgYWRkVW5pdEFsaWFzKCdpc29XZWVrJywgJ1cnKTtcblxuICAgIC8vIFBSSU9SSVRJRVNcblxuICAgIGFkZFVuaXRQcmlvcml0eSgnd2VlaycsIDUpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2VlaycsIDUpO1xuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbigndycsICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ3d3JywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1cnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdXVycsIG1hdGNoMXRvMiwgbWF0Y2gyKTtcblxuICAgIGFkZFdlZWtQYXJzZVRva2VuKFsndycsICd3dycsICdXJywgJ1dXJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuLnN1YnN0cigwLCAxKV0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICAvLyBMT0NBTEVTXG5cbiAgICBmdW5jdGlvbiBsb2NhbGVXZWVrIChtb20pIHtcbiAgICAgICAgcmV0dXJuIHdlZWtPZlllYXIobW9tLCB0aGlzLl93ZWVrLmRvdywgdGhpcy5fd2Vlay5kb3kpLndlZWs7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb2NhbGVXZWVrID0ge1xuICAgICAgICBkb3cgOiAwLCAvLyBTdW5kYXkgaXMgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2Vlay5cbiAgICAgICAgZG95IDogNiAgLy8gVGhlIHdlZWsgdGhhdCBjb250YWlucyBKYW4gNnRoIGlzIHRoZSBmaXJzdCB3ZWVrIG9mIHRoZSB5ZWFyLlxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2NhbGVGaXJzdERheU9mV2VlayAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93ZWVrLmRvdztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsb2NhbGVGaXJzdERheU9mWWVhciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93ZWVrLmRveTtcbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBnZXRTZXRXZWVrIChpbnB1dCkge1xuICAgICAgICB2YXIgd2VlayA9IHRoaXMubG9jYWxlRGF0YSgpLndlZWsodGhpcyk7XG4gICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8gd2VlayA6IHRoaXMuYWRkKChpbnB1dCAtIHdlZWspICogNywgJ2QnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRJU09XZWVrIChpbnB1dCkge1xuICAgICAgICB2YXIgd2VlayA9IHdlZWtPZlllYXIodGhpcywgMSwgNCkud2VlaztcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrIDogdGhpcy5hZGQoKGlucHV0IC0gd2VlaykgKiA3LCAnZCcpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdkJywgMCwgJ2RvJywgJ2RheScpO1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ2RkJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkud2Vla2RheXNNaW4odGhpcywgZm9ybWF0KTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdkZGQnLCAwLCAwLCBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS53ZWVrZGF5c1Nob3J0KHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignZGRkZCcsIDAsIDAsIGZ1bmN0aW9uIChmb3JtYXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLndlZWtkYXlzKHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignZScsIDAsIDAsICd3ZWVrZGF5Jyk7XG4gICAgYWRkRm9ybWF0VG9rZW4oJ0UnLCAwLCAwLCAnaXNvV2Vla2RheScpO1xuXG4gICAgLy8gQUxJQVNFU1xuXG4gICAgYWRkVW5pdEFsaWFzKCdkYXknLCAnZCcpO1xuICAgIGFkZFVuaXRBbGlhcygnd2Vla2RheScsICdlJyk7XG4gICAgYWRkVW5pdEFsaWFzKCdpc29XZWVrZGF5JywgJ0UnKTtcblxuICAgIC8vIFBSSU9SSVRZXG4gICAgYWRkVW5pdFByaW9yaXR5KCdkYXknLCAxMSk7XG4gICAgYWRkVW5pdFByaW9yaXR5KCd3ZWVrZGF5JywgMTEpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2Vla2RheScsIDExKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ2QnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2UnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0UnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkJywgICBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLndlZWtkYXlzTWluUmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkZCcsICAgZnVuY3Rpb24gKGlzU3RyaWN0LCBsb2NhbGUpIHtcbiAgICAgICAgcmV0dXJuIGxvY2FsZS53ZWVrZGF5c1Nob3J0UmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkZGQnLCAgIGZ1bmN0aW9uIChpc1N0cmljdCwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUud2Vla2RheXNSZWdleChpc1N0cmljdCk7XG4gICAgfSk7XG5cbiAgICBhZGRXZWVrUGFyc2VUb2tlbihbJ2RkJywgJ2RkZCcsICdkZGRkJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB2YXIgd2Vla2RheSA9IGNvbmZpZy5fbG9jYWxlLndlZWtkYXlzUGFyc2UoaW5wdXQsIHRva2VuLCBjb25maWcuX3N0cmljdCk7XG4gICAgICAgIC8vIGlmIHdlIGRpZG4ndCBnZXQgYSB3ZWVrZGF5IG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZFxuICAgICAgICBpZiAod2Vla2RheSAhPSBudWxsKSB7XG4gICAgICAgICAgICB3ZWVrLmQgPSB3ZWVrZGF5O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuaW52YWxpZFdlZWtkYXkgPSBpbnB1dDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgYWRkV2Vla1BhcnNlVG9rZW4oWydkJywgJ2UnLCAnRSddLCBmdW5jdGlvbiAoaW5wdXQsIHdlZWssIGNvbmZpZywgdG9rZW4pIHtcbiAgICAgICAgd2Vla1t0b2tlbl0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICBmdW5jdGlvbiBwYXJzZVdlZWtkYXkoaW5wdXQsIGxvY2FsZSkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc05hTihpbnB1dCkpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUludChpbnB1dCwgMTApO1xuICAgICAgICB9XG5cbiAgICAgICAgaW5wdXQgPSBsb2NhbGUud2Vla2RheXNQYXJzZShpbnB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZUlzb1dlZWtkYXkoaW5wdXQsIGxvY2FsZSkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS53ZWVrZGF5c1BhcnNlKGlucHV0KSAlIDcgfHwgNztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNOYU4oaW5wdXQpID8gbnVsbCA6IGlucHV0O1xuICAgIH1cblxuICAgIC8vIExPQ0FMRVNcbiAgICBmdW5jdGlvbiBzaGlmdFdlZWtkYXlzICh3cywgbikge1xuICAgICAgICByZXR1cm4gd3Muc2xpY2UobiwgNykuY29uY2F0KHdzLnNsaWNlKDAsIG4pKTtcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdExvY2FsZVdlZWtkYXlzID0gJ1N1bmRheV9Nb25kYXlfVHVlc2RheV9XZWRuZXNkYXlfVGh1cnNkYXlfRnJpZGF5X1NhdHVyZGF5Jy5zcGxpdCgnXycpO1xuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzIChtLCBmb3JtYXQpIHtcbiAgICAgICAgdmFyIHdlZWtkYXlzID0gaXNBcnJheSh0aGlzLl93ZWVrZGF5cykgPyB0aGlzLl93ZWVrZGF5cyA6XG4gICAgICAgICAgICB0aGlzLl93ZWVrZGF5c1sobSAmJiBtICE9PSB0cnVlICYmIHRoaXMuX3dlZWtkYXlzLmlzRm9ybWF0LnRlc3QoZm9ybWF0KSkgPyAnZm9ybWF0JyA6ICdzdGFuZGFsb25lJ107XG4gICAgICAgIHJldHVybiAobSA9PT0gdHJ1ZSkgPyBzaGlmdFdlZWtkYXlzKHdlZWtkYXlzLCB0aGlzLl93ZWVrLmRvdylcbiAgICAgICAgICAgIDogKG0pID8gd2Vla2RheXNbbS5kYXkoKV0gOiB3ZWVrZGF5cztcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdExvY2FsZVdlZWtkYXlzU2hvcnQgPSAnU3VuX01vbl9UdWVfV2VkX1RodV9GcmlfU2F0Jy5zcGxpdCgnXycpO1xuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzU2hvcnQgKG0pIHtcbiAgICAgICAgcmV0dXJuIChtID09PSB0cnVlKSA/IHNoaWZ0V2Vla2RheXModGhpcy5fd2Vla2RheXNTaG9ydCwgdGhpcy5fd2Vlay5kb3cpXG4gICAgICAgICAgICA6IChtKSA/IHRoaXMuX3dlZWtkYXlzU2hvcnRbbS5kYXkoKV0gOiB0aGlzLl93ZWVrZGF5c1Nob3J0O1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TG9jYWxlV2Vla2RheXNNaW4gPSAnU3VfTW9fVHVfV2VfVGhfRnJfU2EnLnNwbGl0KCdfJyk7XG4gICAgZnVuY3Rpb24gbG9jYWxlV2Vla2RheXNNaW4gKG0pIHtcbiAgICAgICAgcmV0dXJuIChtID09PSB0cnVlKSA/IHNoaWZ0V2Vla2RheXModGhpcy5fd2Vla2RheXNNaW4sIHRoaXMuX3dlZWsuZG93KVxuICAgICAgICAgICAgOiAobSkgPyB0aGlzLl93ZWVrZGF5c01pblttLmRheSgpXSA6IHRoaXMuX3dlZWtkYXlzTWluO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZVN0cmljdFBhcnNlJDEod2Vla2RheU5hbWUsIGZvcm1hdCwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBpLCBpaSwgbW9tLCBsbGMgPSB3ZWVrZGF5TmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fbWluV2Vla2RheXNQYXJzZSA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNzsgKytpKSB7XG4gICAgICAgICAgICAgICAgbW9tID0gY3JlYXRlVVRDKFsyMDAwLCAxXSkuZGF5KGkpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21pbldlZWtkYXlzUGFyc2VbaV0gPSB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRXZWVrZGF5c1BhcnNlW2ldID0gdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZVtpXSA9IHRoaXMud2Vla2RheXMobW9tLCAnJykudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdkZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3dlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9taW5XZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpaSAhPT0gLTEgPyBpaSA6IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoZm9ybWF0ID09PSAnZGRkZCcpIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl93ZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9zaG9ydFdlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgaWYgKGlpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX21pbldlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fd2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fbWluV2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9taW5XZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl93ZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9zaG9ydFdlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzUGFyc2UgKHdlZWtkYXlOYW1lLCBmb3JtYXQsIHN0cmljdCkge1xuICAgICAgICB2YXIgaSwgbW9tLCByZWdleDtcblxuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlU3RyaWN0UGFyc2UkMS5jYWxsKHRoaXMsIHdlZWtkYXlOYW1lLCBmb3JtYXQsIHN0cmljdCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX21pbldlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fZnVsbFdlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuXG4gICAgICAgICAgICBtb20gPSBjcmVhdGVVVEMoWzIwMDAsIDFdKS5kYXkoaSk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmICF0aGlzLl9mdWxsV2Vla2RheXNQYXJzZVtpXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2Z1bGxXZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnXFxcXC4/JykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRXZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzU2hvcnQobW9tLCAnJykucmVwbGFjZSgnLicsICdcXFxcLj8nKSArICckJywgJ2knKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9taW5XZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnXFxcXC4/JykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICByZWdleCA9ICdeJyArIHRoaXMud2Vla2RheXMobW9tLCAnJykgKyAnfF4nICsgdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpICsgJ3xeJyArIHRoaXMud2Vla2RheXNNaW4obW9tLCAnJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZVtpXSA9IG5ldyBSZWdFeHAocmVnZXgucmVwbGFjZSgnLicsICcnKSwgJ2knKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHRlc3QgdGhlIHJlZ2V4XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmIGZvcm1hdCA9PT0gJ2RkZGQnICYmIHRoaXMuX2Z1bGxXZWVrZGF5c1BhcnNlW2ldLnRlc3Qod2Vla2RheU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmljdCAmJiBmb3JtYXQgPT09ICdkZGQnICYmIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZVtpXS50ZXN0KHdlZWtkYXlOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnZGQnICYmIHRoaXMuX21pbldlZWtkYXlzUGFyc2VbaV0udGVzdCh3ZWVrZGF5TmFtZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXN0cmljdCAmJiB0aGlzLl93ZWVrZGF5c1BhcnNlW2ldLnRlc3Qod2Vla2RheU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBnZXRTZXREYXlPZldlZWsgKGlucHV0KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnB1dCAhPSBudWxsID8gdGhpcyA6IE5hTjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF5ID0gdGhpcy5faXNVVEMgPyB0aGlzLl9kLmdldFVUQ0RheSgpIDogdGhpcy5fZC5nZXREYXkoKTtcbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlucHV0ID0gcGFyc2VXZWVrZGF5KGlucHV0LCB0aGlzLmxvY2FsZURhdGEoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGQoaW5wdXQgLSBkYXksICdkJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZGF5O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2V0TG9jYWxlRGF5T2ZXZWVrIChpbnB1dCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgIT0gbnVsbCA/IHRoaXMgOiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHdlZWtkYXkgPSAodGhpcy5kYXkoKSArIDcgLSB0aGlzLmxvY2FsZURhdGEoKS5fd2Vlay5kb3cpICUgNztcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrZGF5IDogdGhpcy5hZGQoaW5wdXQgLSB3ZWVrZGF5LCAnZCcpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNldElTT0RheU9mV2VlayAoaW5wdXQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0ICE9IG51bGwgPyB0aGlzIDogTmFOO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYmVoYXZlcyB0aGUgc2FtZSBhcyBtb21lbnQjZGF5IGV4Y2VwdFxuICAgICAgICAvLyBhcyBhIGdldHRlciwgcmV0dXJucyA3IGluc3RlYWQgb2YgMCAoMS03IHJhbmdlIGluc3RlYWQgb2YgMC02KVxuICAgICAgICAvLyBhcyBhIHNldHRlciwgc3VuZGF5IHNob3VsZCBiZWxvbmcgdG8gdGhlIHByZXZpb3VzIHdlZWsuXG5cbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhciB3ZWVrZGF5ID0gcGFyc2VJc29XZWVrZGF5KGlucHV0LCB0aGlzLmxvY2FsZURhdGEoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kYXkodGhpcy5kYXkoKSAlIDcgPyB3ZWVrZGF5IDogd2Vla2RheSAtIDcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF5KCkgfHwgNztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0V2Vla2RheXNSZWdleCA9IG1hdGNoV29yZDtcbiAgICBmdW5jdGlvbiB3ZWVrZGF5c1JlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wKHRoaXMsICdfd2Vla2RheXNSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNSZWdleCA9IGRlZmF1bHRXZWVrZGF5c1JlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggOiB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRXZWVrZGF5c1Nob3J0UmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gd2Vla2RheXNTaG9ydFJlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU2hvcnRTdHJpY3RSZWdleDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX3dlZWtkYXlzU2hvcnRSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNTaG9ydFJlZ2V4ID0gZGVmYXVsdFdlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c1Nob3J0U3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzU2hvcnRTdHJpY3RSZWdleCA6IHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0V2Vla2RheXNNaW5SZWdleCA9IG1hdGNoV29yZDtcbiAgICBmdW5jdGlvbiB3ZWVrZGF5c01pblJlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wKHRoaXMsICdfd2Vla2RheXNNaW5SZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNNaW5SZWdleCA9IGRlZmF1bHRXZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXggOiB0aGlzLl93ZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjb21wdXRlV2Vla2RheXNQYXJzZSAoKSB7XG4gICAgICAgIGZ1bmN0aW9uIGNtcExlblJldihhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi5sZW5ndGggLSBhLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtaW5QaWVjZXMgPSBbXSwgc2hvcnRQaWVjZXMgPSBbXSwgbG9uZ1BpZWNlcyA9IFtdLCBtaXhlZFBpZWNlcyA9IFtdLFxuICAgICAgICAgICAgaSwgbW9tLCBtaW5wLCBzaG9ydHAsIGxvbmdwO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNzsgaSsrKSB7XG4gICAgICAgICAgICAvLyBtYWtlIHRoZSByZWdleCBpZiB3ZSBkb24ndCBoYXZlIGl0IGFscmVhZHlcbiAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgMV0pLmRheShpKTtcbiAgICAgICAgICAgIG1pbnAgPSB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpO1xuICAgICAgICAgICAgc2hvcnRwID0gdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpO1xuICAgICAgICAgICAgbG9uZ3AgPSB0aGlzLndlZWtkYXlzKG1vbSwgJycpO1xuICAgICAgICAgICAgbWluUGllY2VzLnB1c2gobWlucCk7XG4gICAgICAgICAgICBzaG9ydFBpZWNlcy5wdXNoKHNob3J0cCk7XG4gICAgICAgICAgICBsb25nUGllY2VzLnB1c2gobG9uZ3ApO1xuICAgICAgICAgICAgbWl4ZWRQaWVjZXMucHVzaChtaW5wKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2goc2hvcnRwKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2gobG9uZ3ApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNvcnRpbmcgbWFrZXMgc3VyZSBpZiBvbmUgd2Vla2RheSAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlciBpdFxuICAgICAgICAvLyB3aWxsIG1hdGNoIHRoZSBsb25nZXIgcGllY2UuXG4gICAgICAgIG1pblBpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIHNob3J0UGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgbG9uZ1BpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIG1peGVkUGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDc7IGkrKykge1xuICAgICAgICAgICAgc2hvcnRQaWVjZXNbaV0gPSByZWdleEVzY2FwZShzaG9ydFBpZWNlc1tpXSk7XG4gICAgICAgICAgICBsb25nUGllY2VzW2ldID0gcmVnZXhFc2NhcGUobG9uZ1BpZWNlc1tpXSk7XG4gICAgICAgICAgICBtaXhlZFBpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKG1peGVkUGllY2VzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3dlZWtkYXlzUmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBtaXhlZFBpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgICAgIHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleCA9IHRoaXMuX3dlZWtkYXlzUmVnZXg7XG4gICAgICAgIHRoaXMuX3dlZWtkYXlzTWluUmVnZXggPSB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuXG4gICAgICAgIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBsb25nUGllY2VzLmpvaW4oJ3wnKSArICcpJywgJ2knKTtcbiAgICAgICAgdGhpcy5fd2Vla2RheXNTaG9ydFN0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgc2hvcnRQaWVjZXMuam9pbignfCcpICsgJyknLCAnaScpO1xuICAgICAgICB0aGlzLl93ZWVrZGF5c01pblN0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbWluUGllY2VzLmpvaW4oJ3wnKSArICcpJywgJ2knKTtcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBmdW5jdGlvbiBoRm9ybWF0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ob3VycygpICUgMTIgfHwgMTI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24ga0Zvcm1hdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaG91cnMoKSB8fCAyNDtcbiAgICB9XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSCcsIFsnSEgnLCAyXSwgMCwgJ2hvdXInKTtcbiAgICBhZGRGb3JtYXRUb2tlbignaCcsIFsnaGgnLCAyXSwgMCwgaEZvcm1hdCk7XG4gICAgYWRkRm9ybWF0VG9rZW4oJ2snLCBbJ2trJywgMl0sIDAsIGtGb3JtYXQpO1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ2htbScsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnICsgaEZvcm1hdC5hcHBseSh0aGlzKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdobW1zcycsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnICsgaEZvcm1hdC5hcHBseSh0aGlzKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKSArXG4gICAgICAgICAgICB6ZXJvRmlsbCh0aGlzLnNlY29uZHMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSG1tJywgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gJycgKyB0aGlzLmhvdXJzKCkgKyB6ZXJvRmlsbCh0aGlzLm1pbnV0ZXMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSG1tc3MnLCAwLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAnJyArIHRoaXMuaG91cnMoKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKSArXG4gICAgICAgICAgICB6ZXJvRmlsbCh0aGlzLnNlY29uZHMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBtZXJpZGllbSAodG9rZW4sIGxvd2VyY2FzZSkge1xuICAgICAgICBhZGRGb3JtYXRUb2tlbih0b2tlbiwgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLm1lcmlkaWVtKHRoaXMuaG91cnMoKSwgdGhpcy5taW51dGVzKCksIGxvd2VyY2FzZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG1lcmlkaWVtKCdhJywgdHJ1ZSk7XG4gICAgbWVyaWRpZW0oJ0EnLCBmYWxzZSk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ2hvdXInLCAnaCcpO1xuXG4gICAgLy8gUFJJT1JJVFlcbiAgICBhZGRVbml0UHJpb3JpdHkoJ2hvdXInLCAxMyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBmdW5jdGlvbiBtYXRjaE1lcmlkaWVtIChpc1N0cmljdCwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUuX21lcmlkaWVtUGFyc2U7XG4gICAgfVxuXG4gICAgYWRkUmVnZXhUb2tlbignYScsICBtYXRjaE1lcmlkaWVtKTtcbiAgICBhZGRSZWdleFRva2VuKCdBJywgIG1hdGNoTWVyaWRpZW0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0gnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdoJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignaycsICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0hIJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2hoJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2trJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuXG4gICAgYWRkUmVnZXhUb2tlbignaG1tJywgbWF0Y2gzdG80KTtcbiAgICBhZGRSZWdleFRva2VuKCdobW1zcycsIG1hdGNoNXRvNik7XG4gICAgYWRkUmVnZXhUb2tlbignSG1tJywgbWF0Y2gzdG80KTtcbiAgICBhZGRSZWdleFRva2VuKCdIbW1zcycsIG1hdGNoNXRvNik7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnSCcsICdISCddLCBIT1VSKTtcbiAgICBhZGRQYXJzZVRva2VuKFsnaycsICdrayddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIGtJbnB1dCA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgYXJyYXlbSE9VUl0gPSBrSW5wdXQgPT09IDI0ID8gMCA6IGtJbnB1dDtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKFsnYScsICdBJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2lzUG0gPSBjb25maWcuX2xvY2FsZS5pc1BNKGlucHV0KTtcbiAgICAgICAgY29uZmlnLl9tZXJpZGllbSA9IGlucHV0O1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oWydoJywgJ2hoJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuYmlnSG91ciA9IHRydWU7XG4gICAgfSk7XG4gICAgYWRkUGFyc2VUb2tlbignaG1tJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIHZhciBwb3MgPSBpbnB1dC5sZW5ndGggLSAyO1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0LnN1YnN0cigwLCBwb3MpKTtcbiAgICAgICAgYXJyYXlbTUlOVVRFXSA9IHRvSW50KGlucHV0LnN1YnN0cihwb3MpKTtcbiAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuYmlnSG91ciA9IHRydWU7XG4gICAgfSk7XG4gICAgYWRkUGFyc2VUb2tlbignaG1tc3MnLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIHBvczEgPSBpbnB1dC5sZW5ndGggLSA0O1xuICAgICAgICB2YXIgcG9zMiA9IGlucHV0Lmxlbmd0aCAtIDI7XG4gICAgICAgIGFycmF5W0hPVVJdID0gdG9JbnQoaW5wdXQuc3Vic3RyKDAsIHBvczEpKTtcbiAgICAgICAgYXJyYXlbTUlOVVRFXSA9IHRvSW50KGlucHV0LnN1YnN0cihwb3MxLCAyKSk7XG4gICAgICAgIGFycmF5W1NFQ09ORF0gPSB0b0ludChpbnB1dC5zdWJzdHIocG9zMikpO1xuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5iaWdIb3VyID0gdHJ1ZTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCdIbW0nLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIHBvcyA9IGlucHV0Lmxlbmd0aCAtIDI7XG4gICAgICAgIGFycmF5W0hPVVJdID0gdG9JbnQoaW5wdXQuc3Vic3RyKDAsIHBvcykpO1xuICAgICAgICBhcnJheVtNSU5VVEVdID0gdG9JbnQoaW5wdXQuc3Vic3RyKHBvcykpO1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oJ0htbXNzJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIHZhciBwb3MxID0gaW5wdXQubGVuZ3RoIC0gNDtcbiAgICAgICAgdmFyIHBvczIgPSBpbnB1dC5sZW5ndGggLSAyO1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0LnN1YnN0cigwLCBwb3MxKSk7XG4gICAgICAgIGFycmF5W01JTlVURV0gPSB0b0ludChpbnB1dC5zdWJzdHIocG9zMSwgMikpO1xuICAgICAgICBhcnJheVtTRUNPTkRdID0gdG9JbnQoaW5wdXQuc3Vic3RyKHBvczIpKTtcbiAgICB9KTtcblxuICAgIC8vIExPQ0FMRVNcblxuICAgIGZ1bmN0aW9uIGxvY2FsZUlzUE0gKGlucHV0KSB7XG4gICAgICAgIC8vIElFOCBRdWlya3MgTW9kZSAmIElFNyBTdGFuZGFyZHMgTW9kZSBkbyBub3QgYWxsb3cgYWNjZXNzaW5nIHN0cmluZ3MgbGlrZSBhcnJheXNcbiAgICAgICAgLy8gVXNpbmcgY2hhckF0IHNob3VsZCBiZSBtb3JlIGNvbXBhdGlibGUuXG4gICAgICAgIHJldHVybiAoKGlucHV0ICsgJycpLnRvTG93ZXJDYXNlKCkuY2hhckF0KDApID09PSAncCcpO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TG9jYWxlTWVyaWRpZW1QYXJzZSA9IC9bYXBdXFwuP20/XFwuPy9pO1xuICAgIGZ1bmN0aW9uIGxvY2FsZU1lcmlkaWVtIChob3VycywgbWludXRlcywgaXNMb3dlcikge1xuICAgICAgICBpZiAoaG91cnMgPiAxMSkge1xuICAgICAgICAgICAgcmV0dXJuIGlzTG93ZXIgPyAncG0nIDogJ1BNJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBpc0xvd2VyID8gJ2FtJyA6ICdBTSc7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8vIE1PTUVOVFNcblxuICAgIC8vIFNldHRpbmcgdGhlIGhvdXIgc2hvdWxkIGtlZXAgdGhlIHRpbWUsIGJlY2F1c2UgdGhlIHVzZXIgZXhwbGljaXRseVxuICAgIC8vIHNwZWNpZmllZCB3aGljaCBob3VyIHRoZXkgd2FudC4gU28gdHJ5aW5nIHRvIG1haW50YWluIHRoZSBzYW1lIGhvdXIgKGluXG4gICAgLy8gYSBuZXcgdGltZXpvbmUpIG1ha2VzIHNlbnNlLiBBZGRpbmcvc3VidHJhY3RpbmcgaG91cnMgZG9lcyBub3QgZm9sbG93XG4gICAgLy8gdGhpcyBydWxlLlxuICAgIHZhciBnZXRTZXRIb3VyID0gbWFrZUdldFNldCgnSG91cnMnLCB0cnVlKTtcblxuICAgIHZhciBiYXNlQ29uZmlnID0ge1xuICAgICAgICBjYWxlbmRhcjogZGVmYXVsdENhbGVuZGFyLFxuICAgICAgICBsb25nRGF0ZUZvcm1hdDogZGVmYXVsdExvbmdEYXRlRm9ybWF0LFxuICAgICAgICBpbnZhbGlkRGF0ZTogZGVmYXVsdEludmFsaWREYXRlLFxuICAgICAgICBvcmRpbmFsOiBkZWZhdWx0T3JkaW5hbCxcbiAgICAgICAgZGF5T2ZNb250aE9yZGluYWxQYXJzZTogZGVmYXVsdERheU9mTW9udGhPcmRpbmFsUGFyc2UsXG4gICAgICAgIHJlbGF0aXZlVGltZTogZGVmYXVsdFJlbGF0aXZlVGltZSxcblxuICAgICAgICBtb250aHM6IGRlZmF1bHRMb2NhbGVNb250aHMsXG4gICAgICAgIG1vbnRoc1Nob3J0OiBkZWZhdWx0TG9jYWxlTW9udGhzU2hvcnQsXG5cbiAgICAgICAgd2VlazogZGVmYXVsdExvY2FsZVdlZWssXG5cbiAgICAgICAgd2Vla2RheXM6IGRlZmF1bHRMb2NhbGVXZWVrZGF5cyxcbiAgICAgICAgd2Vla2RheXNNaW46IGRlZmF1bHRMb2NhbGVXZWVrZGF5c01pbixcbiAgICAgICAgd2Vla2RheXNTaG9ydDogZGVmYXVsdExvY2FsZVdlZWtkYXlzU2hvcnQsXG5cbiAgICAgICAgbWVyaWRpZW1QYXJzZTogZGVmYXVsdExvY2FsZU1lcmlkaWVtUGFyc2VcbiAgICB9O1xuXG4gICAgLy8gaW50ZXJuYWwgc3RvcmFnZSBmb3IgbG9jYWxlIGNvbmZpZyBmaWxlc1xuICAgIHZhciBsb2NhbGVzID0ge307XG4gICAgdmFyIGxvY2FsZUZhbWlsaWVzID0ge307XG4gICAgdmFyIGdsb2JhbExvY2FsZTtcblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZUxvY2FsZShrZXkpIHtcbiAgICAgICAgcmV0dXJuIGtleSA/IGtleS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoJ18nLCAnLScpIDoga2V5O1xuICAgIH1cblxuICAgIC8vIHBpY2sgdGhlIGxvY2FsZSBmcm9tIHRoZSBhcnJheVxuICAgIC8vIHRyeSBbJ2VuLWF1JywgJ2VuLWdiJ10gYXMgJ2VuLWF1JywgJ2VuLWdiJywgJ2VuJywgYXMgaW4gbW92ZSB0aHJvdWdoIHRoZSBsaXN0IHRyeWluZyBlYWNoXG4gICAgLy8gc3Vic3RyaW5nIGZyb20gbW9zdCBzcGVjaWZpYyB0byBsZWFzdCwgYnV0IG1vdmUgdG8gdGhlIG5leHQgYXJyYXkgaXRlbSBpZiBpdCdzIGEgbW9yZSBzcGVjaWZpYyB2YXJpYW50IHRoYW4gdGhlIGN1cnJlbnQgcm9vdFxuICAgIGZ1bmN0aW9uIGNob29zZUxvY2FsZShuYW1lcykge1xuICAgICAgICB2YXIgaSA9IDAsIGosIG5leHQsIGxvY2FsZSwgc3BsaXQ7XG5cbiAgICAgICAgd2hpbGUgKGkgPCBuYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHNwbGl0ID0gbm9ybWFsaXplTG9jYWxlKG5hbWVzW2ldKS5zcGxpdCgnLScpO1xuICAgICAgICAgICAgaiA9IHNwbGl0Lmxlbmd0aDtcbiAgICAgICAgICAgIG5leHQgPSBub3JtYWxpemVMb2NhbGUobmFtZXNbaSArIDFdKTtcbiAgICAgICAgICAgIG5leHQgPSBuZXh0ID8gbmV4dC5zcGxpdCgnLScpIDogbnVsbDtcbiAgICAgICAgICAgIHdoaWxlIChqID4gMCkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGxvYWRMb2NhbGUoc3BsaXQuc2xpY2UoMCwgaikuam9pbignLScpKTtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChuZXh0ICYmIG5leHQubGVuZ3RoID49IGogJiYgY29tcGFyZUFycmF5cyhzcGxpdCwgbmV4dCwgdHJ1ZSkgPj0gaiAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgLy90aGUgbmV4dCBhcnJheSBpdGVtIGlzIGJldHRlciB0aGFuIGEgc2hhbGxvd2VyIHN1YnN0cmluZyBvZiB0aGlzIG9uZVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgai0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9hZExvY2FsZShuYW1lKSB7XG4gICAgICAgIHZhciBvbGRMb2NhbGUgPSBudWxsO1xuICAgICAgICAvLyBUT0RPOiBGaW5kIGEgYmV0dGVyIHdheSB0byByZWdpc3RlciBhbmQgbG9hZCBhbGwgdGhlIGxvY2FsZXMgaW4gTm9kZVxuICAgICAgICBpZiAoIWxvY2FsZXNbbmFtZV0gJiYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgICAgICAgICAgIG1vZHVsZSAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBvbGRMb2NhbGUgPSBnbG9iYWxMb2NhbGUuX2FiYnI7XG4gICAgICAgICAgICAgICAgdmFyIGFsaWFzZWRSZXF1aXJlID0gcmVxdWlyZTtcbiAgICAgICAgICAgICAgICBhbGlhc2VkUmVxdWlyZSgnLi9sb2NhbGUvJyArIG5hbWUpO1xuICAgICAgICAgICAgICAgIGdldFNldEdsb2JhbExvY2FsZShvbGRMb2NhbGUpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbG9jYWxlc1tuYW1lXTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgbG9hZCBsb2NhbGUgYW5kIHRoZW4gc2V0IHRoZSBnbG9iYWwgbG9jYWxlLiAgSWZcbiAgICAvLyBubyBhcmd1bWVudHMgYXJlIHBhc3NlZCBpbiwgaXQgd2lsbCBzaW1wbHkgcmV0dXJuIHRoZSBjdXJyZW50IGdsb2JhbFxuICAgIC8vIGxvY2FsZSBrZXkuXG4gICAgZnVuY3Rpb24gZ2V0U2V0R2xvYmFsTG9jYWxlIChrZXksIHZhbHVlcykge1xuICAgICAgICB2YXIgZGF0YTtcbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlcykpIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZ2V0TG9jYWxlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZGVmaW5lTG9jYWxlKGtleSwgdmFsdWVzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAvLyBtb21lbnQuZHVyYXRpb24uX2xvY2FsZSA9IG1vbWVudC5fbG9jYWxlID0gZGF0YTtcbiAgICAgICAgICAgICAgICBnbG9iYWxMb2NhbGUgPSBkYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKCh0eXBlb2YgY29uc29sZSAhPT0gICd1bmRlZmluZWQnKSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICAgICAgICAgICAgLy93YXJuIHVzZXIgaWYgYXJndW1lbnRzIGFyZSBwYXNzZWQgYnV0IHRoZSBsb2NhbGUgY291bGQgbm90IGJlIHNldFxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0xvY2FsZSAnICsga2V5ICsgICcgbm90IGZvdW5kLiBEaWQgeW91IGZvcmdldCB0byBsb2FkIGl0PycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGUuX2FiYnI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmaW5lTG9jYWxlIChuYW1lLCBjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxvY2FsZSwgcGFyZW50Q29uZmlnID0gYmFzZUNvbmZpZztcbiAgICAgICAgICAgIGNvbmZpZy5hYmJyID0gbmFtZTtcbiAgICAgICAgICAgIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkZXByZWNhdGVTaW1wbGUoJ2RlZmluZUxvY2FsZU92ZXJyaWRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICd1c2UgbW9tZW50LnVwZGF0ZUxvY2FsZShsb2NhbGVOYW1lLCBjb25maWcpIHRvIGNoYW5nZSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdhbiBleGlzdGluZyBsb2NhbGUuIG1vbWVudC5kZWZpbmVMb2NhbGUobG9jYWxlTmFtZSwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnY29uZmlnKSBzaG91bGQgb25seSBiZSB1c2VkIGZvciBjcmVhdGluZyBhIG5ldyBsb2NhbGUgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnU2VlIGh0dHA6Ly9tb21lbnRqcy5jb20vZ3VpZGVzLyMvd2FybmluZ3MvZGVmaW5lLWxvY2FsZS8gZm9yIG1vcmUgaW5mby4nKTtcbiAgICAgICAgICAgICAgICBwYXJlbnRDb25maWcgPSBsb2NhbGVzW25hbWVdLl9jb25maWc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNvbmZpZy5wYXJlbnRMb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChsb2NhbGVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29uZmlnID0gbG9jYWxlc1tjb25maWcucGFyZW50TG9jYWxlXS5fY29uZmlnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvY2FsZSA9IGxvYWRMb2NhbGUoY29uZmlnLnBhcmVudExvY2FsZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29uZmlnID0gbG9jYWxlLl9jb25maWc7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWxvY2FsZUZhbWlsaWVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlRmFtaWxpZXNbY29uZmlnLnBhcmVudExvY2FsZV0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsZUZhbWlsaWVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnOiBjb25maWdcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhbGVzW25hbWVdID0gbmV3IExvY2FsZShtZXJnZUNvbmZpZ3MocGFyZW50Q29uZmlnLCBjb25maWcpKTtcblxuICAgICAgICAgICAgaWYgKGxvY2FsZUZhbWlsaWVzW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgbG9jYWxlRmFtaWxpZXNbbmFtZV0uZm9yRWFjaChmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgICAgICAgICBkZWZpbmVMb2NhbGUoeC5uYW1lLCB4LmNvbmZpZyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgZm9yIG5vdzogYWxzbyBzZXQgdGhlIGxvY2FsZVxuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHdlIHNldCB0aGUgbG9jYWxlIEFGVEVSIGFsbCBjaGlsZCBsb2NhbGVzIGhhdmUgYmVlblxuICAgICAgICAgICAgLy8gY3JlYXRlZCwgc28gd2Ugd29uJ3QgZW5kIHVwIHdpdGggdGhlIGNoaWxkIGxvY2FsZSBzZXQuXG4gICAgICAgICAgICBnZXRTZXRHbG9iYWxMb2NhbGUobmFtZSk7XG5cblxuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZXNbbmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyB1c2VmdWwgZm9yIHRlc3RpbmdcbiAgICAgICAgICAgIGRlbGV0ZSBsb2NhbGVzW25hbWVdO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1cGRhdGVMb2NhbGUobmFtZSwgY29uZmlnKSB7XG4gICAgICAgIGlmIChjb25maWcgIT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxvY2FsZSwgdG1wTG9jYWxlLCBwYXJlbnRDb25maWcgPSBiYXNlQ29uZmlnO1xuICAgICAgICAgICAgLy8gTUVSR0VcbiAgICAgICAgICAgIHRtcExvY2FsZSA9IGxvYWRMb2NhbGUobmFtZSk7XG4gICAgICAgICAgICBpZiAodG1wTG9jYWxlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnRDb25maWcgPSB0bXBMb2NhbGUuX2NvbmZpZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbmZpZyA9IG1lcmdlQ29uZmlncyhwYXJlbnRDb25maWcsIGNvbmZpZyk7XG4gICAgICAgICAgICBsb2NhbGUgPSBuZXcgTG9jYWxlKGNvbmZpZyk7XG4gICAgICAgICAgICBsb2NhbGUucGFyZW50TG9jYWxlID0gbG9jYWxlc1tuYW1lXTtcbiAgICAgICAgICAgIGxvY2FsZXNbbmFtZV0gPSBsb2NhbGU7XG5cbiAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgZm9yIG5vdzogYWxzbyBzZXQgdGhlIGxvY2FsZVxuICAgICAgICAgICAgZ2V0U2V0R2xvYmFsTG9jYWxlKG5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gcGFzcyBudWxsIGZvciBjb25maWcgdG8gdW51cGRhdGUsIHVzZWZ1bCBmb3IgdGVzdHNcbiAgICAgICAgICAgIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxlc1tuYW1lXS5wYXJlbnRMb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBsb2NhbGVzW25hbWVdID0gbG9jYWxlc1tuYW1lXS5wYXJlbnRMb2NhbGU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGxvY2FsZXNbbmFtZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsb2NhbGVzW25hbWVdO1xuICAgIH1cblxuICAgIC8vIHJldHVybnMgbG9jYWxlIGRhdGFcbiAgICBmdW5jdGlvbiBnZXRMb2NhbGUgKGtleSkge1xuICAgICAgICB2YXIgbG9jYWxlO1xuXG4gICAgICAgIGlmIChrZXkgJiYga2V5Ll9sb2NhbGUgJiYga2V5Ll9sb2NhbGUuX2FiYnIpIHtcbiAgICAgICAgICAgIGtleSA9IGtleS5fbG9jYWxlLl9hYmJyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFrZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzQXJyYXkoa2V5KSkge1xuICAgICAgICAgICAgLy9zaG9ydC1jaXJjdWl0IGV2ZXJ5dGhpbmcgZWxzZVxuICAgICAgICAgICAgbG9jYWxlID0gbG9hZExvY2FsZShrZXkpO1xuICAgICAgICAgICAgaWYgKGxvY2FsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBrZXkgPSBba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjaG9vc2VMb2NhbGUoa2V5KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0TG9jYWxlcygpIHtcbiAgICAgICAgcmV0dXJuIGtleXMobG9jYWxlcyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2tPdmVyZmxvdyAobSkge1xuICAgICAgICB2YXIgb3ZlcmZsb3c7XG4gICAgICAgIHZhciBhID0gbS5fYTtcblxuICAgICAgICBpZiAoYSAmJiBnZXRQYXJzaW5nRmxhZ3MobSkub3ZlcmZsb3cgPT09IC0yKSB7XG4gICAgICAgICAgICBvdmVyZmxvdyA9XG4gICAgICAgICAgICAgICAgYVtNT05USF0gICAgICAgPCAwIHx8IGFbTU9OVEhdICAgICAgID4gMTEgID8gTU9OVEggOlxuICAgICAgICAgICAgICAgIGFbREFURV0gICAgICAgIDwgMSB8fCBhW0RBVEVdICAgICAgICA+IGRheXNJbk1vbnRoKGFbWUVBUl0sIGFbTU9OVEhdKSA/IERBVEUgOlxuICAgICAgICAgICAgICAgIGFbSE9VUl0gICAgICAgIDwgMCB8fCBhW0hPVVJdICAgICAgICA+IDI0IHx8IChhW0hPVVJdID09PSAyNCAmJiAoYVtNSU5VVEVdICE9PSAwIHx8IGFbU0VDT05EXSAhPT0gMCB8fCBhW01JTExJU0VDT05EXSAhPT0gMCkpID8gSE9VUiA6XG4gICAgICAgICAgICAgICAgYVtNSU5VVEVdICAgICAgPCAwIHx8IGFbTUlOVVRFXSAgICAgID4gNTkgID8gTUlOVVRFIDpcbiAgICAgICAgICAgICAgICBhW1NFQ09ORF0gICAgICA8IDAgfHwgYVtTRUNPTkRdICAgICAgPiA1OSAgPyBTRUNPTkQgOlxuICAgICAgICAgICAgICAgIGFbTUlMTElTRUNPTkRdIDwgMCB8fCBhW01JTExJU0VDT05EXSA+IDk5OSA/IE1JTExJU0VDT05EIDpcbiAgICAgICAgICAgICAgICAtMTtcblxuICAgICAgICAgICAgaWYgKGdldFBhcnNpbmdGbGFncyhtKS5fb3ZlcmZsb3dEYXlPZlllYXIgJiYgKG92ZXJmbG93IDwgWUVBUiB8fCBvdmVyZmxvdyA+IERBVEUpKSB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3cgPSBEQVRFO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGdldFBhcnNpbmdGbGFncyhtKS5fb3ZlcmZsb3dXZWVrcyAmJiBvdmVyZmxvdyA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBvdmVyZmxvdyA9IFdFRUs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZ2V0UGFyc2luZ0ZsYWdzKG0pLl9vdmVyZmxvd1dlZWtkYXkgJiYgb3ZlcmZsb3cgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3cgPSBXRUVLREFZO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MobSkub3ZlcmZsb3cgPSBvdmVyZmxvdztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtO1xuICAgIH1cblxuICAgIC8vIFBpY2sgdGhlIGZpcnN0IGRlZmluZWQgb2YgdHdvIG9yIHRocmVlIGFyZ3VtZW50cy5cbiAgICBmdW5jdGlvbiBkZWZhdWx0cyhhLCBiLCBjKSB7XG4gICAgICAgIGlmIChhICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBhO1xuICAgICAgICB9XG4gICAgICAgIGlmIChiICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKSB7XG4gICAgICAgIC8vIGhvb2tzIGlzIGFjdHVhbGx5IHRoZSBleHBvcnRlZCBtb21lbnQgb2JqZWN0XG4gICAgICAgIHZhciBub3dWYWx1ZSA9IG5ldyBEYXRlKGhvb2tzLm5vdygpKTtcbiAgICAgICAgaWYgKGNvbmZpZy5fdXNlVVRDKSB7XG4gICAgICAgICAgICByZXR1cm4gW25vd1ZhbHVlLmdldFVUQ0Z1bGxZZWFyKCksIG5vd1ZhbHVlLmdldFVUQ01vbnRoKCksIG5vd1ZhbHVlLmdldFVUQ0RhdGUoKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtub3dWYWx1ZS5nZXRGdWxsWWVhcigpLCBub3dWYWx1ZS5nZXRNb250aCgpLCBub3dWYWx1ZS5nZXREYXRlKCldO1xuICAgIH1cblxuICAgIC8vIGNvbnZlcnQgYW4gYXJyYXkgdG8gYSBkYXRlLlxuICAgIC8vIHRoZSBhcnJheSBzaG91bGQgbWlycm9yIHRoZSBwYXJhbWV0ZXJzIGJlbG93XG4gICAgLy8gbm90ZTogYWxsIHZhbHVlcyBwYXN0IHRoZSB5ZWFyIGFyZSBvcHRpb25hbCBhbmQgd2lsbCBkZWZhdWx0IHRvIHRoZSBsb3dlc3QgcG9zc2libGUgdmFsdWUuXG4gICAgLy8gW3llYXIsIG1vbnRoLCBkYXkgLCBob3VyLCBtaW51dGUsIHNlY29uZCwgbWlsbGlzZWNvbmRdXG4gICAgZnVuY3Rpb24gY29uZmlnRnJvbUFycmF5IChjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGRhdGUsIGlucHV0ID0gW10sIGN1cnJlbnREYXRlLCBleHBlY3RlZFdlZWtkYXksIHllYXJUb1VzZTtcblxuICAgICAgICBpZiAoY29uZmlnLl9kKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50RGF0ZSA9IGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKTtcblxuICAgICAgICAvL2NvbXB1dGUgZGF5IG9mIHRoZSB5ZWFyIGZyb20gd2Vla3MgYW5kIHdlZWtkYXlzXG4gICAgICAgIGlmIChjb25maWcuX3cgJiYgY29uZmlnLl9hW0RBVEVdID09IG51bGwgJiYgY29uZmlnLl9hW01PTlRIXSA9PSBudWxsKSB7XG4gICAgICAgICAgICBkYXlPZlllYXJGcm9tV2Vla0luZm8oY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vaWYgdGhlIGRheSBvZiB0aGUgeWVhciBpcyBzZXQsIGZpZ3VyZSBvdXQgd2hhdCBpdCBpc1xuICAgICAgICBpZiAoY29uZmlnLl9kYXlPZlllYXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgeWVhclRvVXNlID0gZGVmYXVsdHMoY29uZmlnLl9hW1lFQVJdLCBjdXJyZW50RGF0ZVtZRUFSXSk7XG5cbiAgICAgICAgICAgIGlmIChjb25maWcuX2RheU9mWWVhciA+IGRheXNJblllYXIoeWVhclRvVXNlKSB8fCBjb25maWcuX2RheU9mWWVhciA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLl9vdmVyZmxvd0RheU9mWWVhciA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRhdGUgPSBjcmVhdGVVVENEYXRlKHllYXJUb1VzZSwgMCwgY29uZmlnLl9kYXlPZlllYXIpO1xuICAgICAgICAgICAgY29uZmlnLl9hW01PTlRIXSA9IGRhdGUuZ2V0VVRDTW9udGgoKTtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtEQVRFXSA9IGRhdGUuZ2V0VVRDRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGVmYXVsdCB0byBjdXJyZW50IGRhdGUuXG4gICAgICAgIC8vICogaWYgbm8geWVhciwgbW9udGgsIGRheSBvZiBtb250aCBhcmUgZ2l2ZW4sIGRlZmF1bHQgdG8gdG9kYXlcbiAgICAgICAgLy8gKiBpZiBkYXkgb2YgbW9udGggaXMgZ2l2ZW4sIGRlZmF1bHQgbW9udGggYW5kIHllYXJcbiAgICAgICAgLy8gKiBpZiBtb250aCBpcyBnaXZlbiwgZGVmYXVsdCBvbmx5IHllYXJcbiAgICAgICAgLy8gKiBpZiB5ZWFyIGlzIGdpdmVuLCBkb24ndCBkZWZhdWx0IGFueXRoaW5nXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAzICYmIGNvbmZpZy5fYVtpXSA9PSBudWxsOyArK2kpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gY3VycmVudERhdGVbaV07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBaZXJvIG91dCB3aGF0ZXZlciB3YXMgbm90IGRlZmF1bHRlZCwgaW5jbHVkaW5nIHRpbWVcbiAgICAgICAgZm9yICg7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gKGNvbmZpZy5fYVtpXSA9PSBudWxsKSA/IChpID09PSAyID8gMSA6IDApIDogY29uZmlnLl9hW2ldO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIDI0OjAwOjAwLjAwMFxuICAgICAgICBpZiAoY29uZmlnLl9hW0hPVVJdID09PSAyNCAmJlxuICAgICAgICAgICAgICAgIGNvbmZpZy5fYVtNSU5VVEVdID09PSAwICYmXG4gICAgICAgICAgICAgICAgY29uZmlnLl9hW1NFQ09ORF0gPT09IDAgJiZcbiAgICAgICAgICAgICAgICBjb25maWcuX2FbTUlMTElTRUNPTkRdID09PSAwKSB7XG4gICAgICAgICAgICBjb25maWcuX25leHREYXkgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9hW0hPVVJdID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZy5fZCA9IChjb25maWcuX3VzZVVUQyA/IGNyZWF0ZVVUQ0RhdGUgOiBjcmVhdGVEYXRlKS5hcHBseShudWxsLCBpbnB1dCk7XG4gICAgICAgIGV4cGVjdGVkV2Vla2RheSA9IGNvbmZpZy5fdXNlVVRDID8gY29uZmlnLl9kLmdldFVUQ0RheSgpIDogY29uZmlnLl9kLmdldERheSgpO1xuXG4gICAgICAgIC8vIEFwcGx5IHRpbWV6b25lIG9mZnNldCBmcm9tIGlucHV0LiBUaGUgYWN0dWFsIHV0Y09mZnNldCBjYW4gYmUgY2hhbmdlZFxuICAgICAgICAvLyB3aXRoIHBhcnNlWm9uZS5cbiAgICAgICAgaWYgKGNvbmZpZy5fdHptICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZC5zZXRVVENNaW51dGVzKGNvbmZpZy5fZC5nZXRVVENNaW51dGVzKCkgLSBjb25maWcuX3R6bSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLl9uZXh0RGF5KSB7XG4gICAgICAgICAgICBjb25maWcuX2FbSE9VUl0gPSAyNDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGZvciBtaXNtYXRjaGluZyBkYXkgb2Ygd2Vla1xuICAgICAgICBpZiAoY29uZmlnLl93ICYmIHR5cGVvZiBjb25maWcuX3cuZCAhPT0gJ3VuZGVmaW5lZCcgJiYgY29uZmlnLl93LmQgIT09IGV4cGVjdGVkV2Vla2RheSkge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykud2Vla2RheU1pc21hdGNoID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrSW5mbyhjb25maWcpIHtcbiAgICAgICAgdmFyIHcsIHdlZWtZZWFyLCB3ZWVrLCB3ZWVrZGF5LCBkb3csIGRveSwgdGVtcCwgd2Vla2RheU92ZXJmbG93O1xuXG4gICAgICAgIHcgPSBjb25maWcuX3c7XG4gICAgICAgIGlmICh3LkdHICE9IG51bGwgfHwgdy5XICE9IG51bGwgfHwgdy5FICE9IG51bGwpIHtcbiAgICAgICAgICAgIGRvdyA9IDE7XG4gICAgICAgICAgICBkb3kgPSA0O1xuXG4gICAgICAgICAgICAvLyBUT0RPOiBXZSBuZWVkIHRvIHRha2UgdGhlIGN1cnJlbnQgaXNvV2Vla1llYXIsIGJ1dCB0aGF0IGRlcGVuZHMgb25cbiAgICAgICAgICAgIC8vIGhvdyB3ZSBpbnRlcnByZXQgbm93IChsb2NhbCwgdXRjLCBmaXhlZCBvZmZzZXQpLiBTbyBjcmVhdGVcbiAgICAgICAgICAgIC8vIGEgbm93IHZlcnNpb24gb2YgY3VycmVudCBjb25maWcgKHRha2UgbG9jYWwvdXRjL29mZnNldCBmbGFncywgYW5kXG4gICAgICAgICAgICAvLyBjcmVhdGUgbm93KS5cbiAgICAgICAgICAgIHdlZWtZZWFyID0gZGVmYXVsdHMody5HRywgY29uZmlnLl9hW1lFQVJdLCB3ZWVrT2ZZZWFyKGNyZWF0ZUxvY2FsKCksIDEsIDQpLnllYXIpO1xuICAgICAgICAgICAgd2VlayA9IGRlZmF1bHRzKHcuVywgMSk7XG4gICAgICAgICAgICB3ZWVrZGF5ID0gZGVmYXVsdHMody5FLCAxKTtcbiAgICAgICAgICAgIGlmICh3ZWVrZGF5IDwgMSB8fCB3ZWVrZGF5ID4gNykge1xuICAgICAgICAgICAgICAgIHdlZWtkYXlPdmVyZmxvdyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkb3cgPSBjb25maWcuX2xvY2FsZS5fd2Vlay5kb3c7XG4gICAgICAgICAgICBkb3kgPSBjb25maWcuX2xvY2FsZS5fd2Vlay5kb3k7XG5cbiAgICAgICAgICAgIHZhciBjdXJXZWVrID0gd2Vla09mWWVhcihjcmVhdGVMb2NhbCgpLCBkb3csIGRveSk7XG5cbiAgICAgICAgICAgIHdlZWtZZWFyID0gZGVmYXVsdHMody5nZywgY29uZmlnLl9hW1lFQVJdLCBjdXJXZWVrLnllYXIpO1xuXG4gICAgICAgICAgICAvLyBEZWZhdWx0IHRvIGN1cnJlbnQgd2Vlay5cbiAgICAgICAgICAgIHdlZWsgPSBkZWZhdWx0cyh3LncsIGN1cldlZWsud2Vlayk7XG5cbiAgICAgICAgICAgIGlmICh3LmQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIHdlZWtkYXkgLS0gbG93IGRheSBudW1iZXJzIGFyZSBjb25zaWRlcmVkIG5leHQgd2Vla1xuICAgICAgICAgICAgICAgIHdlZWtkYXkgPSB3LmQ7XG4gICAgICAgICAgICAgICAgaWYgKHdlZWtkYXkgPCAwIHx8IHdlZWtkYXkgPiA2KSB7XG4gICAgICAgICAgICAgICAgICAgIHdlZWtkYXlPdmVyZmxvdyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh3LmUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIGxvY2FsIHdlZWtkYXkgLS0gY291bnRpbmcgc3RhcnRzIGZyb20gYmVnaW5uaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gdy5lICsgZG93O1xuICAgICAgICAgICAgICAgIGlmICh3LmUgPCAwIHx8IHcuZSA+IDYpIHtcbiAgICAgICAgICAgICAgICAgICAgd2Vla2RheU92ZXJmbG93ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGRlZmF1bHQgdG8gYmVnaW5uaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gZG93O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh3ZWVrIDwgMSB8fCB3ZWVrID4gd2Vla3NJblllYXIod2Vla1llYXIsIGRvdywgZG95KSkge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuX292ZXJmbG93V2Vla3MgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHdlZWtkYXlPdmVyZmxvdyAhPSBudWxsKSB7XG4gICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5fb3ZlcmZsb3dXZWVrZGF5ID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRlbXAgPSBkYXlPZlllYXJGcm9tV2Vla3Mod2Vla1llYXIsIHdlZWssIHdlZWtkYXksIGRvdywgZG95KTtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtZRUFSXSA9IHRlbXAueWVhcjtcbiAgICAgICAgICAgIGNvbmZpZy5fZGF5T2ZZZWFyID0gdGVtcC5kYXlPZlllYXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpc28gODYwMSByZWdleFxuICAgIC8vIDAwMDAtMDAtMDAgMDAwMC1XMDAgb3IgMDAwMC1XMDAtMCArIFQgKyAwMCBvciAwMDowMCBvciAwMDowMDowMCBvciAwMDowMDowMC4wMDAgKyArMDA6MDAgb3IgKzAwMDAgb3IgKzAwKVxuICAgIHZhciBleHRlbmRlZElzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KS0oPzpcXGRcXGQtXFxkXFxkfFdcXGRcXGQtXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86OlxcZFxcZCg/OjpcXGRcXGQoPzpbLixdXFxkKyk/KT8pPykoW1xcK1xcLV1cXGRcXGQoPzo6P1xcZFxcZCk/fFxccypaKT8pPyQvO1xuICAgIHZhciBiYXNpY0lzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KSg/OlxcZFxcZFxcZFxcZHxXXFxkXFxkXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86XFxkXFxkKD86XFxkXFxkKD86Wy4sXVxcZCspPyk/KT8pKFtcXCtcXC1dXFxkXFxkKD86Oj9cXGRcXGQpP3xcXHMqWik/KT8kLztcblxuICAgIHZhciB0elJlZ2V4ID0gL1p8WystXVxcZFxcZCg/Ojo/XFxkXFxkKT8vO1xuXG4gICAgdmFyIGlzb0RhdGVzID0gW1xuICAgICAgICBbJ1lZWVlZWS1NTS1ERCcsIC9bKy1dXFxkezZ9LVxcZFxcZC1cXGRcXGQvXSxcbiAgICAgICAgWydZWVlZLU1NLUREJywgL1xcZHs0fS1cXGRcXGQtXFxkXFxkL10sXG4gICAgICAgIFsnR0dHRy1bV11XVy1FJywgL1xcZHs0fS1XXFxkXFxkLVxcZC9dLFxuICAgICAgICBbJ0dHR0ctW1ddV1cnLCAvXFxkezR9LVdcXGRcXGQvLCBmYWxzZV0sXG4gICAgICAgIFsnWVlZWS1EREQnLCAvXFxkezR9LVxcZHszfS9dLFxuICAgICAgICBbJ1lZWVktTU0nLCAvXFxkezR9LVxcZFxcZC8sIGZhbHNlXSxcbiAgICAgICAgWydZWVlZWVlNTUREJywgL1srLV1cXGR7MTB9L10sXG4gICAgICAgIFsnWVlZWU1NREQnLCAvXFxkezh9L10sXG4gICAgICAgIC8vIFlZWVlNTSBpcyBOT1QgYWxsb3dlZCBieSB0aGUgc3RhbmRhcmRcbiAgICAgICAgWydHR0dHW1ddV1dFJywgL1xcZHs0fVdcXGR7M30vXSxcbiAgICAgICAgWydHR0dHW1ddV1cnLCAvXFxkezR9V1xcZHsyfS8sIGZhbHNlXSxcbiAgICAgICAgWydZWVlZREREJywgL1xcZHs3fS9dXG4gICAgXTtcblxuICAgIC8vIGlzbyB0aW1lIGZvcm1hdHMgYW5kIHJlZ2V4ZXNcbiAgICB2YXIgaXNvVGltZXMgPSBbXG4gICAgICAgIFsnSEg6bW06c3MuU1NTUycsIC9cXGRcXGQ6XFxkXFxkOlxcZFxcZFxcLlxcZCsvXSxcbiAgICAgICAgWydISDptbTpzcyxTU1NTJywgL1xcZFxcZDpcXGRcXGQ6XFxkXFxkLFxcZCsvXSxcbiAgICAgICAgWydISDptbTpzcycsIC9cXGRcXGQ6XFxkXFxkOlxcZFxcZC9dLFxuICAgICAgICBbJ0hIOm1tJywgL1xcZFxcZDpcXGRcXGQvXSxcbiAgICAgICAgWydISG1tc3MuU1NTUycsIC9cXGRcXGRcXGRcXGRcXGRcXGRcXC5cXGQrL10sXG4gICAgICAgIFsnSEhtbXNzLFNTU1MnLCAvXFxkXFxkXFxkXFxkXFxkXFxkLFxcZCsvXSxcbiAgICAgICAgWydISG1tc3MnLCAvXFxkXFxkXFxkXFxkXFxkXFxkL10sXG4gICAgICAgIFsnSEhtbScsIC9cXGRcXGRcXGRcXGQvXSxcbiAgICAgICAgWydISCcsIC9cXGRcXGQvXVxuICAgIF07XG5cbiAgICB2YXIgYXNwTmV0SnNvblJlZ2V4ID0gL15cXC8/RGF0ZVxcKChcXC0/XFxkKykvaTtcblxuICAgIC8vIGRhdGUgZnJvbSBpc28gZm9ybWF0XG4gICAgZnVuY3Rpb24gY29uZmlnRnJvbUlTTyhjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGwsXG4gICAgICAgICAgICBzdHJpbmcgPSBjb25maWcuX2ksXG4gICAgICAgICAgICBtYXRjaCA9IGV4dGVuZGVkSXNvUmVnZXguZXhlYyhzdHJpbmcpIHx8IGJhc2ljSXNvUmVnZXguZXhlYyhzdHJpbmcpLFxuICAgICAgICAgICAgYWxsb3dUaW1lLCBkYXRlRm9ybWF0LCB0aW1lRm9ybWF0LCB0ekZvcm1hdDtcblxuICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmlzbyA9IHRydWU7XG5cbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBpc29EYXRlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNvRGF0ZXNbaV1bMV0uZXhlYyhtYXRjaFsxXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdCA9IGlzb0RhdGVzW2ldWzBdO1xuICAgICAgICAgICAgICAgICAgICBhbGxvd1RpbWUgPSBpc29EYXRlc1tpXVsyXSAhPT0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRlRm9ybWF0ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25maWcuX2lzVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWF0Y2hbM10pIHtcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gaXNvVGltZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc29UaW1lc1tpXVsxXS5leGVjKG1hdGNoWzNdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWF0Y2hbMl0gc2hvdWxkIGJlICdUJyBvciBzcGFjZVxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZUZvcm1hdCA9IChtYXRjaFsyXSB8fCAnICcpICsgaXNvVGltZXNbaV1bMF07XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGltZUZvcm1hdCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFhbGxvd1RpbWUgJiYgdGltZUZvcm1hdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1hdGNoWzRdKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR6UmVnZXguZXhlYyhtYXRjaFs0XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHpGb3JtYXQgPSAnWic7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25maWcuX2YgPSBkYXRlRm9ybWF0ICsgKHRpbWVGb3JtYXQgfHwgJycpICsgKHR6Rm9ybWF0IHx8ICcnKTtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUkZDIDI4MjIgcmVnZXg6IEZvciBkZXRhaWxzIHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMjgyMiNzZWN0aW9uLTMuM1xuICAgIHZhciByZmMyODIyID0gL14oPzooTW9ufFR1ZXxXZWR8VGh1fEZyaXxTYXR8U3VuKSw/XFxzKT8oXFxkezEsMn0pXFxzKEphbnxGZWJ8TWFyfEFwcnxNYXl8SnVufEp1bHxBdWd8U2VwfE9jdHxOb3Z8RGVjKVxccyhcXGR7Miw0fSlcXHMoXFxkXFxkKTooXFxkXFxkKSg/OjooXFxkXFxkKSk/XFxzKD86KFVUfEdNVHxbRUNNUF1bU0RdVCl8KFtael0pfChbKy1dXFxkezR9KSkkLztcblxuICAgIGZ1bmN0aW9uIGV4dHJhY3RGcm9tUkZDMjgyMlN0cmluZ3MoeWVhclN0ciwgbW9udGhTdHIsIGRheVN0ciwgaG91clN0ciwgbWludXRlU3RyLCBzZWNvbmRTdHIpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtcbiAgICAgICAgICAgIHVudHJ1bmNhdGVZZWFyKHllYXJTdHIpLFxuICAgICAgICAgICAgZGVmYXVsdExvY2FsZU1vbnRoc1Nob3J0LmluZGV4T2YobW9udGhTdHIpLFxuICAgICAgICAgICAgcGFyc2VJbnQoZGF5U3RyLCAxMCksXG4gICAgICAgICAgICBwYXJzZUludChob3VyU3RyLCAxMCksXG4gICAgICAgICAgICBwYXJzZUludChtaW51dGVTdHIsIDEwKVxuICAgICAgICBdO1xuXG4gICAgICAgIGlmIChzZWNvbmRTdHIpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBhcnNlSW50KHNlY29uZFN0ciwgMTApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdW50cnVuY2F0ZVllYXIoeWVhclN0cikge1xuICAgICAgICB2YXIgeWVhciA9IHBhcnNlSW50KHllYXJTdHIsIDEwKTtcbiAgICAgICAgaWYgKHllYXIgPD0gNDkpIHtcbiAgICAgICAgICAgIHJldHVybiAyMDAwICsgeWVhcjtcbiAgICAgICAgfSBlbHNlIGlmICh5ZWFyIDw9IDk5OSkge1xuICAgICAgICAgICAgcmV0dXJuIDE5MDAgKyB5ZWFyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB5ZWFyO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByZXByb2Nlc3NSRkMyODIyKHMpIHtcbiAgICAgICAgLy8gUmVtb3ZlIGNvbW1lbnRzIGFuZCBmb2xkaW5nIHdoaXRlc3BhY2UgYW5kIHJlcGxhY2UgbXVsdGlwbGUtc3BhY2VzIHdpdGggYSBzaW5nbGUgc3BhY2VcbiAgICAgICAgcmV0dXJuIHMucmVwbGFjZSgvXFwoW14pXSpcXCl8W1xcblxcdF0vZywgJyAnKS5yZXBsYWNlKC8oXFxzXFxzKykvZywgJyAnKS5yZXBsYWNlKC9eXFxzXFxzKi8sICcnKS5yZXBsYWNlKC9cXHNcXHMqJC8sICcnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja1dlZWtkYXkod2Vla2RheVN0ciwgcGFyc2VkSW5wdXQsIGNvbmZpZykge1xuICAgICAgICBpZiAod2Vla2RheVN0cikge1xuICAgICAgICAgICAgLy8gVE9ETzogUmVwbGFjZSB0aGUgdmFuaWxsYSBKUyBEYXRlIG9iamVjdCB3aXRoIGFuIGluZGVwZW50ZW50IGRheS1vZi13ZWVrIGNoZWNrLlxuICAgICAgICAgICAgdmFyIHdlZWtkYXlQcm92aWRlZCA9IGRlZmF1bHRMb2NhbGVXZWVrZGF5c1Nob3J0LmluZGV4T2Yod2Vla2RheVN0ciksXG4gICAgICAgICAgICAgICAgd2Vla2RheUFjdHVhbCA9IG5ldyBEYXRlKHBhcnNlZElucHV0WzBdLCBwYXJzZWRJbnB1dFsxXSwgcGFyc2VkSW5wdXRbMl0pLmdldERheSgpO1xuICAgICAgICAgICAgaWYgKHdlZWtkYXlQcm92aWRlZCAhPT0gd2Vla2RheUFjdHVhbCkge1xuICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLndlZWtkYXlNaXNtYXRjaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciBvYnNPZmZzZXRzID0ge1xuICAgICAgICBVVDogMCxcbiAgICAgICAgR01UOiAwLFxuICAgICAgICBFRFQ6IC00ICogNjAsXG4gICAgICAgIEVTVDogLTUgKiA2MCxcbiAgICAgICAgQ0RUOiAtNSAqIDYwLFxuICAgICAgICBDU1Q6IC02ICogNjAsXG4gICAgICAgIE1EVDogLTYgKiA2MCxcbiAgICAgICAgTVNUOiAtNyAqIDYwLFxuICAgICAgICBQRFQ6IC03ICogNjAsXG4gICAgICAgIFBTVDogLTggKiA2MFxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBjYWxjdWxhdGVPZmZzZXQob2JzT2Zmc2V0LCBtaWxpdGFyeU9mZnNldCwgbnVtT2Zmc2V0KSB7XG4gICAgICAgIGlmIChvYnNPZmZzZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBvYnNPZmZzZXRzW29ic09mZnNldF07XG4gICAgICAgIH0gZWxzZSBpZiAobWlsaXRhcnlPZmZzZXQpIHtcbiAgICAgICAgICAgIC8vIHRoZSBvbmx5IGFsbG93ZWQgbWlsaXRhcnkgdHogaXMgWlxuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaG0gPSBwYXJzZUludChudW1PZmZzZXQsIDEwKTtcbiAgICAgICAgICAgIHZhciBtID0gaG0gJSAxMDAsIGggPSAoaG0gLSBtKSAvIDEwMDtcbiAgICAgICAgICAgIHJldHVybiBoICogNjAgKyBtO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZGF0ZSBhbmQgdGltZSBmcm9tIHJlZiAyODIyIGZvcm1hdFxuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21SRkMyODIyKGNvbmZpZykge1xuICAgICAgICB2YXIgbWF0Y2ggPSByZmMyODIyLmV4ZWMocHJlcHJvY2Vzc1JGQzI4MjIoY29uZmlnLl9pKSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgdmFyIHBhcnNlZEFycmF5ID0gZXh0cmFjdEZyb21SRkMyODIyU3RyaW5ncyhtYXRjaFs0XSwgbWF0Y2hbM10sIG1hdGNoWzJdLCBtYXRjaFs1XSwgbWF0Y2hbNl0sIG1hdGNoWzddKTtcbiAgICAgICAgICAgIGlmICghY2hlY2tXZWVrZGF5KG1hdGNoWzFdLCBwYXJzZWRBcnJheSwgY29uZmlnKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uZmlnLl9hID0gcGFyc2VkQXJyYXk7XG4gICAgICAgICAgICBjb25maWcuX3R6bSA9IGNhbGN1bGF0ZU9mZnNldChtYXRjaFs4XSwgbWF0Y2hbOV0sIG1hdGNoWzEwXSk7XG5cbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IGNyZWF0ZVVUQ0RhdGUuYXBwbHkobnVsbCwgY29uZmlnLl9hKTtcbiAgICAgICAgICAgIGNvbmZpZy5fZC5zZXRVVENNaW51dGVzKGNvbmZpZy5fZC5nZXRVVENNaW51dGVzKCkgLSBjb25maWcuX3R6bSk7XG5cbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnJmYzI4MjIgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gaXNvIGZvcm1hdCBvciBmYWxsYmFja1xuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21TdHJpbmcoY29uZmlnKSB7XG4gICAgICAgIHZhciBtYXRjaGVkID0gYXNwTmV0SnNvblJlZ2V4LmV4ZWMoY29uZmlnLl9pKTtcblxuICAgICAgICBpZiAobWF0Y2hlZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoK21hdGNoZWRbMV0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uZmlnRnJvbUlTTyhjb25maWcpO1xuICAgICAgICBpZiAoY29uZmlnLl9pc1ZhbGlkID09PSBmYWxzZSkge1xuICAgICAgICAgICAgZGVsZXRlIGNvbmZpZy5faXNWYWxpZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZ0Zyb21SRkMyODIyKGNvbmZpZyk7XG4gICAgICAgIGlmIChjb25maWcuX2lzVmFsaWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBkZWxldGUgY29uZmlnLl9pc1ZhbGlkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluYWwgYXR0ZW1wdCwgdXNlIElucHV0IEZhbGxiYWNrXG4gICAgICAgIGhvb2tzLmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgfVxuXG4gICAgaG9va3MuY3JlYXRlRnJvbUlucHV0RmFsbGJhY2sgPSBkZXByZWNhdGUoXG4gICAgICAgICd2YWx1ZSBwcm92aWRlZCBpcyBub3QgaW4gYSByZWNvZ25pemVkIFJGQzI4MjIgb3IgSVNPIGZvcm1hdC4gbW9tZW50IGNvbnN0cnVjdGlvbiBmYWxscyBiYWNrIHRvIGpzIERhdGUoKSwgJyArXG4gICAgICAgICd3aGljaCBpcyBub3QgcmVsaWFibGUgYWNyb3NzIGFsbCBicm93c2VycyBhbmQgdmVyc2lvbnMuIE5vbiBSRkMyODIyL0lTTyBkYXRlIGZvcm1hdHMgYXJlICcgK1xuICAgICAgICAnZGlzY291cmFnZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhbiB1cGNvbWluZyBtYWpvciByZWxlYXNlLiBQbGVhc2UgcmVmZXIgdG8gJyArXG4gICAgICAgICdodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2pzLWRhdGUvIGZvciBtb3JlIGluZm8uJyxcbiAgICAgICAgZnVuY3Rpb24gKGNvbmZpZykge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoY29uZmlnLl9pICsgKGNvbmZpZy5fdXNlVVRDID8gJyBVVEMnIDogJycpKTtcbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBjb25zdGFudCB0aGF0IHJlZmVycyB0byB0aGUgSVNPIHN0YW5kYXJkXG4gICAgaG9va3MuSVNPXzg2MDEgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIGNvbnN0YW50IHRoYXQgcmVmZXJzIHRvIHRoZSBSRkMgMjgyMiBmb3JtXG4gICAgaG9va3MuUkZDXzI4MjIgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIGRhdGUgZnJvbSBzdHJpbmcgYW5kIGZvcm1hdCBzdHJpbmdcbiAgICBmdW5jdGlvbiBjb25maWdGcm9tU3RyaW5nQW5kRm9ybWF0KGNvbmZpZykge1xuICAgICAgICAvLyBUT0RPOiBNb3ZlIHRoaXMgdG8gYW5vdGhlciBwYXJ0IG9mIHRoZSBjcmVhdGlvbiBmbG93IHRvIHByZXZlbnQgY2lyY3VsYXIgZGVwc1xuICAgICAgICBpZiAoY29uZmlnLl9mID09PSBob29rcy5JU09fODYwMSkge1xuICAgICAgICAgICAgY29uZmlnRnJvbUlTTyhjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25maWcuX2YgPT09IGhvb2tzLlJGQ18yODIyKSB7XG4gICAgICAgICAgICBjb25maWdGcm9tUkZDMjgyMihjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbmZpZy5fYSA9IFtdO1xuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5lbXB0eSA9IHRydWU7XG5cbiAgICAgICAgLy8gVGhpcyBhcnJheSBpcyB1c2VkIHRvIG1ha2UgYSBEYXRlLCBlaXRoZXIgd2l0aCBgbmV3IERhdGVgIG9yIGBEYXRlLlVUQ2BcbiAgICAgICAgdmFyIHN0cmluZyA9ICcnICsgY29uZmlnLl9pLFxuICAgICAgICAgICAgaSwgcGFyc2VkSW5wdXQsIHRva2VucywgdG9rZW4sIHNraXBwZWQsXG4gICAgICAgICAgICBzdHJpbmdMZW5ndGggPSBzdHJpbmcubGVuZ3RoLFxuICAgICAgICAgICAgdG90YWxQYXJzZWRJbnB1dExlbmd0aCA9IDA7XG5cbiAgICAgICAgdG9rZW5zID0gZXhwYW5kRm9ybWF0KGNvbmZpZy5fZiwgY29uZmlnLl9sb2NhbGUpLm1hdGNoKGZvcm1hdHRpbmdUb2tlbnMpIHx8IFtdO1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRva2VuID0gdG9rZW5zW2ldO1xuICAgICAgICAgICAgcGFyc2VkSW5wdXQgPSAoc3RyaW5nLm1hdGNoKGdldFBhcnNlUmVnZXhGb3JUb2tlbih0b2tlbiwgY29uZmlnKSkgfHwgW10pWzBdO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ3Rva2VuJywgdG9rZW4sICdwYXJzZWRJbnB1dCcsIHBhcnNlZElucHV0LFxuICAgICAgICAgICAgLy8gICAgICAgICAncmVnZXgnLCBnZXRQYXJzZVJlZ2V4Rm9yVG9rZW4odG9rZW4sIGNvbmZpZykpO1xuICAgICAgICAgICAgaWYgKHBhcnNlZElucHV0KSB7XG4gICAgICAgICAgICAgICAgc2tpcHBlZCA9IHN0cmluZy5zdWJzdHIoMCwgc3RyaW5nLmluZGV4T2YocGFyc2VkSW5wdXQpKTtcbiAgICAgICAgICAgICAgICBpZiAoc2tpcHBlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnVudXNlZElucHV0LnB1c2goc2tpcHBlZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN0cmluZyA9IHN0cmluZy5zbGljZShzdHJpbmcuaW5kZXhPZihwYXJzZWRJbnB1dCkgKyBwYXJzZWRJbnB1dC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIHRvdGFsUGFyc2VkSW5wdXRMZW5ndGggKz0gcGFyc2VkSW5wdXQubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZG9uJ3QgcGFyc2UgaWYgaXQncyBub3QgYSBrbm93biB0b2tlblxuICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuRnVuY3Rpb25zW3Rva2VuXSkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZWRJbnB1dCkge1xuICAgICAgICAgICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5lbXB0eSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykudW51c2VkVG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhZGRUaW1lVG9BcnJheUZyb21Ub2tlbih0b2tlbiwgcGFyc2VkSW5wdXQsIGNvbmZpZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb25maWcuX3N0cmljdCAmJiAhcGFyc2VkSW5wdXQpIHtcbiAgICAgICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS51bnVzZWRUb2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGQgcmVtYWluaW5nIHVucGFyc2VkIGlucHV0IGxlbmd0aCB0byB0aGUgc3RyaW5nXG4gICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmNoYXJzTGVmdE92ZXIgPSBzdHJpbmdMZW5ndGggLSB0b3RhbFBhcnNlZElucHV0TGVuZ3RoO1xuICAgICAgICBpZiAoc3RyaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnVudXNlZElucHV0LnB1c2goc3RyaW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNsZWFyIF8xMmggZmxhZyBpZiBob3VyIGlzIDw9IDEyXG4gICAgICAgIGlmIChjb25maWcuX2FbSE9VUl0gPD0gMTIgJiZcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmJpZ0hvdXIgPT09IHRydWUgJiZcbiAgICAgICAgICAgIGNvbmZpZy5fYVtIT1VSXSA+IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmJpZ0hvdXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5wYXJzZWREYXRlUGFydHMgPSBjb25maWcuX2Euc2xpY2UoMCk7XG4gICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLm1lcmlkaWVtID0gY29uZmlnLl9tZXJpZGllbTtcbiAgICAgICAgLy8gaGFuZGxlIG1lcmlkaWVtXG4gICAgICAgIGNvbmZpZy5fYVtIT1VSXSA9IG1lcmlkaWVtRml4V3JhcChjb25maWcuX2xvY2FsZSwgY29uZmlnLl9hW0hPVVJdLCBjb25maWcuX21lcmlkaWVtKTtcblxuICAgICAgICBjb25maWdGcm9tQXJyYXkoY29uZmlnKTtcbiAgICAgICAgY2hlY2tPdmVyZmxvdyhjb25maWcpO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gbWVyaWRpZW1GaXhXcmFwIChsb2NhbGUsIGhvdXIsIG1lcmlkaWVtKSB7XG4gICAgICAgIHZhciBpc1BtO1xuXG4gICAgICAgIGlmIChtZXJpZGllbSA9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBub3RoaW5nIHRvIGRvXG4gICAgICAgICAgICByZXR1cm4gaG91cjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobG9jYWxlLm1lcmlkaWVtSG91ciAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbG9jYWxlLm1lcmlkaWVtSG91cihob3VyLCBtZXJpZGllbSk7XG4gICAgICAgIH0gZWxzZSBpZiAobG9jYWxlLmlzUE0gIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gRmFsbGJhY2tcbiAgICAgICAgICAgIGlzUG0gPSBsb2NhbGUuaXNQTShtZXJpZGllbSk7XG4gICAgICAgICAgICBpZiAoaXNQbSAmJiBob3VyIDwgMTIpIHtcbiAgICAgICAgICAgICAgICBob3VyICs9IDEyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc1BtICYmIGhvdXIgPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgaG91ciA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaG91cjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgbm90IHN1cHBvc2VkIHRvIGhhcHBlblxuICAgICAgICAgICAgcmV0dXJuIGhvdXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gc3RyaW5nIGFuZCBhcnJheSBvZiBmb3JtYXQgc3RyaW5nc1xuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21TdHJpbmdBbmRBcnJheShjb25maWcpIHtcbiAgICAgICAgdmFyIHRlbXBDb25maWcsXG4gICAgICAgICAgICBiZXN0TW9tZW50LFxuXG4gICAgICAgICAgICBzY29yZVRvQmVhdCxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBjdXJyZW50U2NvcmU7XG5cbiAgICAgICAgaWYgKGNvbmZpZy5fZi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmludmFsaWRGb3JtYXQgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoTmFOKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb25maWcuX2YubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGN1cnJlbnRTY29yZSA9IDA7XG4gICAgICAgICAgICB0ZW1wQ29uZmlnID0gY29weUNvbmZpZyh7fSwgY29uZmlnKTtcbiAgICAgICAgICAgIGlmIChjb25maWcuX3VzZVVUQyAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGVtcENvbmZpZy5fdXNlVVRDID0gY29uZmlnLl91c2VVVEM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZW1wQ29uZmlnLl9mID0gY29uZmlnLl9mW2ldO1xuICAgICAgICAgICAgY29uZmlnRnJvbVN0cmluZ0FuZEZvcm1hdCh0ZW1wQ29uZmlnKTtcblxuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKHRlbXBDb25maWcpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFueSBpbnB1dCB0aGF0IHdhcyBub3QgcGFyc2VkIGFkZCBhIHBlbmFsdHkgZm9yIHRoYXQgZm9ybWF0XG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgKz0gZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLmNoYXJzTGVmdE92ZXI7XG5cbiAgICAgICAgICAgIC8vb3IgdG9rZW5zXG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgKz0gZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLnVudXNlZFRva2Vucy5sZW5ndGggKiAxMDtcblxuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLnNjb3JlID0gY3VycmVudFNjb3JlO1xuXG4gICAgICAgICAgICBpZiAoc2NvcmVUb0JlYXQgPT0gbnVsbCB8fCBjdXJyZW50U2NvcmUgPCBzY29yZVRvQmVhdCkge1xuICAgICAgICAgICAgICAgIHNjb3JlVG9CZWF0ID0gY3VycmVudFNjb3JlO1xuICAgICAgICAgICAgICAgIGJlc3RNb21lbnQgPSB0ZW1wQ29uZmlnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZXh0ZW5kKGNvbmZpZywgYmVzdE1vbWVudCB8fCB0ZW1wQ29uZmlnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb25maWdGcm9tT2JqZWN0KGNvbmZpZykge1xuICAgICAgICBpZiAoY29uZmlnLl9kKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaSA9IG5vcm1hbGl6ZU9iamVjdFVuaXRzKGNvbmZpZy5faSk7XG4gICAgICAgIGNvbmZpZy5fYSA9IG1hcChbaS55ZWFyLCBpLm1vbnRoLCBpLmRheSB8fCBpLmRhdGUsIGkuaG91ciwgaS5taW51dGUsIGkuc2Vjb25kLCBpLm1pbGxpc2Vjb25kXSwgZnVuY3Rpb24gKG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIG9iaiAmJiBwYXJzZUludChvYmosIDEwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uZmlnRnJvbUFycmF5KGNvbmZpZyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlRnJvbUNvbmZpZyAoY29uZmlnKSB7XG4gICAgICAgIHZhciByZXMgPSBuZXcgTW9tZW50KGNoZWNrT3ZlcmZsb3cocHJlcGFyZUNvbmZpZyhjb25maWcpKSk7XG4gICAgICAgIGlmIChyZXMuX25leHREYXkpIHtcbiAgICAgICAgICAgIC8vIEFkZGluZyBpcyBzbWFydCBlbm91Z2ggYXJvdW5kIERTVFxuICAgICAgICAgICAgcmVzLmFkZCgxLCAnZCcpO1xuICAgICAgICAgICAgcmVzLl9uZXh0RGF5ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVwYXJlQ29uZmlnIChjb25maWcpIHtcbiAgICAgICAgdmFyIGlucHV0ID0gY29uZmlnLl9pLFxuICAgICAgICAgICAgZm9ybWF0ID0gY29uZmlnLl9mO1xuXG4gICAgICAgIGNvbmZpZy5fbG9jYWxlID0gY29uZmlnLl9sb2NhbGUgfHwgZ2V0TG9jYWxlKGNvbmZpZy5fbCk7XG5cbiAgICAgICAgaWYgKGlucHV0ID09PSBudWxsIHx8IChmb3JtYXQgPT09IHVuZGVmaW5lZCAmJiBpbnB1dCA9PT0gJycpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlSW52YWxpZCh7bnVsbElucHV0OiB0cnVlfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uZmlnLl9pID0gaW5wdXQgPSBjb25maWcuX2xvY2FsZS5wcmVwYXJzZShpbnB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNNb21lbnQoaW5wdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE1vbWVudChjaGVja092ZXJmbG93KGlucHV0KSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNEYXRlKGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gaW5wdXQ7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNBcnJheShmb3JtYXQpKSB7XG4gICAgICAgICAgICBjb25maWdGcm9tU3RyaW5nQW5kQXJyYXkoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQpIHtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgfSAgZWxzZSB7XG4gICAgICAgICAgICBjb25maWdGcm9tSW5wdXQoY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNWYWxpZChjb25maWcpKSB7XG4gICAgICAgICAgICBjb25maWcuX2QgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb25maWdGcm9tSW5wdXQoY29uZmlnKSB7XG4gICAgICAgIHZhciBpbnB1dCA9IGNvbmZpZy5faTtcbiAgICAgICAgaWYgKGlzVW5kZWZpbmVkKGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoaG9va3Mubm93KCkpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzRGF0ZShpbnB1dCkpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKGlucHV0LnZhbHVlT2YoKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uZmlnRnJvbVN0cmluZyhjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkoaW5wdXQpKSB7XG4gICAgICAgICAgICBjb25maWcuX2EgPSBtYXAoaW5wdXQuc2xpY2UoMCksIGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQob2JqLCAxMCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21BcnJheShjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnRnJvbU9iamVjdChjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKGlucHV0KSkge1xuICAgICAgICAgICAgLy8gZnJvbSBtaWxsaXNlY29uZHNcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKGlucHV0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhvb2tzLmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVMb2NhbE9yVVRDIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCwgaXNVVEMpIHtcbiAgICAgICAgdmFyIGMgPSB7fTtcblxuICAgICAgICBpZiAobG9jYWxlID09PSB0cnVlIHx8IGxvY2FsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHN0cmljdCA9IGxvY2FsZTtcbiAgICAgICAgICAgIGxvY2FsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgoaXNPYmplY3QoaW5wdXQpICYmIGlzT2JqZWN0RW1wdHkoaW5wdXQpKSB8fFxuICAgICAgICAgICAgICAgIChpc0FycmF5KGlucHV0KSAmJiBpbnB1dC5sZW5ndGggPT09IDApKSB7XG4gICAgICAgICAgICBpbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBvYmplY3QgY29uc3RydWN0aW9uIG11c3QgYmUgZG9uZSB0aGlzIHdheS5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzE0MjNcbiAgICAgICAgYy5faXNBTW9tZW50T2JqZWN0ID0gdHJ1ZTtcbiAgICAgICAgYy5fdXNlVVRDID0gYy5faXNVVEMgPSBpc1VUQztcbiAgICAgICAgYy5fbCA9IGxvY2FsZTtcbiAgICAgICAgYy5faSA9IGlucHV0O1xuICAgICAgICBjLl9mID0gZm9ybWF0O1xuICAgICAgICBjLl9zdHJpY3QgPSBzdHJpY3Q7XG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZyb21Db25maWcoYyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlTG9jYWwgKGlucHV0LCBmb3JtYXQsIGxvY2FsZSwgc3RyaWN0KSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVMb2NhbE9yVVRDKGlucHV0LCBmb3JtYXQsIGxvY2FsZSwgc3RyaWN0LCBmYWxzZSk7XG4gICAgfVxuXG4gICAgdmFyIHByb3RvdHlwZU1pbiA9IGRlcHJlY2F0ZShcbiAgICAgICAgJ21vbWVudCgpLm1pbiBpcyBkZXByZWNhdGVkLCB1c2UgbW9tZW50Lm1heCBpbnN0ZWFkLiBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL21pbi1tYXgvJyxcbiAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIG90aGVyID0gY3JlYXRlTG9jYWwuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzVmFsaWQoKSAmJiBvdGhlci5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3RoZXIgPCB0aGlzID8gdGhpcyA6IG90aGVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlSW52YWxpZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIHZhciBwcm90b3R5cGVNYXggPSBkZXByZWNhdGUoXG4gICAgICAgICdtb21lbnQoKS5tYXggaXMgZGVwcmVjYXRlZCwgdXNlIG1vbWVudC5taW4gaW5zdGVhZC4gaHR0cDovL21vbWVudGpzLmNvbS9ndWlkZXMvIy93YXJuaW5ncy9taW4tbWF4LycsXG4gICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBvdGhlciA9IGNyZWF0ZUxvY2FsLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICBpZiAodGhpcy5pc1ZhbGlkKCkgJiYgb3RoZXIuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG90aGVyID4gdGhpcyA/IHRoaXMgOiBvdGhlcjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUludmFsaWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBQaWNrIGEgbW9tZW50IG0gZnJvbSBtb21lbnRzIHNvIHRoYXQgbVtmbl0ob3RoZXIpIGlzIHRydWUgZm9yIGFsbFxuICAgIC8vIG90aGVyLiBUaGlzIHJlbGllcyBvbiB0aGUgZnVuY3Rpb24gZm4gdG8gYmUgdHJhbnNpdGl2ZS5cbiAgICAvL1xuICAgIC8vIG1vbWVudHMgc2hvdWxkIGVpdGhlciBiZSBhbiBhcnJheSBvZiBtb21lbnQgb2JqZWN0cyBvciBhbiBhcnJheSwgd2hvc2VcbiAgICAvLyBmaXJzdCBlbGVtZW50IGlzIGFuIGFycmF5IG9mIG1vbWVudCBvYmplY3RzLlxuICAgIGZ1bmN0aW9uIHBpY2tCeShmbiwgbW9tZW50cykge1xuICAgICAgICB2YXIgcmVzLCBpO1xuICAgICAgICBpZiAobW9tZW50cy5sZW5ndGggPT09IDEgJiYgaXNBcnJheShtb21lbnRzWzBdKSkge1xuICAgICAgICAgICAgbW9tZW50cyA9IG1vbWVudHNbMF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtb21lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUxvY2FsKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzID0gbW9tZW50c1swXTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IG1vbWVudHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmICghbW9tZW50c1tpXS5pc1ZhbGlkKCkgfHwgbW9tZW50c1tpXVtmbl0ocmVzKSkge1xuICAgICAgICAgICAgICAgIHJlcyA9IG1vbWVudHNbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBVc2UgW10uc29ydCBpbnN0ZWFkP1xuICAgIGZ1bmN0aW9uIG1pbiAoKSB7XG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuXG4gICAgICAgIHJldHVybiBwaWNrQnkoJ2lzQmVmb3JlJywgYXJncyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF4ICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG5cbiAgICAgICAgcmV0dXJuIHBpY2tCeSgnaXNBZnRlcicsIGFyZ3MpO1xuICAgIH1cblxuICAgIHZhciBub3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBEYXRlLm5vdyA/IERhdGUubm93KCkgOiArKG5ldyBEYXRlKCkpO1xuICAgIH07XG5cbiAgICB2YXIgb3JkZXJpbmcgPSBbJ3llYXInLCAncXVhcnRlcicsICdtb250aCcsICd3ZWVrJywgJ2RheScsICdob3VyJywgJ21pbnV0ZScsICdzZWNvbmQnLCAnbWlsbGlzZWNvbmQnXTtcblxuICAgIGZ1bmN0aW9uIGlzRHVyYXRpb25WYWxpZChtKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBtKSB7XG4gICAgICAgICAgICBpZiAoIShpbmRleE9mLmNhbGwob3JkZXJpbmcsIGtleSkgIT09IC0xICYmIChtW2tleV0gPT0gbnVsbCB8fCAhaXNOYU4obVtrZXldKSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHVuaXRIYXNEZWNpbWFsID0gZmFsc2U7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3JkZXJpbmcubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChtW29yZGVyaW5nW2ldXSkge1xuICAgICAgICAgICAgICAgIGlmICh1bml0SGFzRGVjaW1hbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG9ubHkgYWxsb3cgbm9uLWludGVnZXJzIGZvciBzbWFsbGVzdCB1bml0XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChwYXJzZUZsb2F0KG1bb3JkZXJpbmdbaV1dKSAhPT0gdG9JbnQobVtvcmRlcmluZ1tpXV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHVuaXRIYXNEZWNpbWFsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkJDEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1ZhbGlkO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUludmFsaWQkMSgpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKE5hTik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gRHVyYXRpb24gKGR1cmF0aW9uKSB7XG4gICAgICAgIHZhciBub3JtYWxpemVkSW5wdXQgPSBub3JtYWxpemVPYmplY3RVbml0cyhkdXJhdGlvbiksXG4gICAgICAgICAgICB5ZWFycyA9IG5vcm1hbGl6ZWRJbnB1dC55ZWFyIHx8IDAsXG4gICAgICAgICAgICBxdWFydGVycyA9IG5vcm1hbGl6ZWRJbnB1dC5xdWFydGVyIHx8IDAsXG4gICAgICAgICAgICBtb250aHMgPSBub3JtYWxpemVkSW5wdXQubW9udGggfHwgMCxcbiAgICAgICAgICAgIHdlZWtzID0gbm9ybWFsaXplZElucHV0LndlZWsgfHwgbm9ybWFsaXplZElucHV0Lmlzb1dlZWsgfHwgMCxcbiAgICAgICAgICAgIGRheXMgPSBub3JtYWxpemVkSW5wdXQuZGF5IHx8IDAsXG4gICAgICAgICAgICBob3VycyA9IG5vcm1hbGl6ZWRJbnB1dC5ob3VyIHx8IDAsXG4gICAgICAgICAgICBtaW51dGVzID0gbm9ybWFsaXplZElucHV0Lm1pbnV0ZSB8fCAwLFxuICAgICAgICAgICAgc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5zZWNvbmQgfHwgMCxcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5taWxsaXNlY29uZCB8fCAwO1xuXG4gICAgICAgIHRoaXMuX2lzVmFsaWQgPSBpc0R1cmF0aW9uVmFsaWQobm9ybWFsaXplZElucHV0KTtcblxuICAgICAgICAvLyByZXByZXNlbnRhdGlvbiBmb3IgZGF0ZUFkZFJlbW92ZVxuICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgPSArbWlsbGlzZWNvbmRzICtcbiAgICAgICAgICAgIHNlY29uZHMgKiAxZTMgKyAvLyAxMDAwXG4gICAgICAgICAgICBtaW51dGVzICogNmU0ICsgLy8gMTAwMCAqIDYwXG4gICAgICAgICAgICBob3VycyAqIDEwMDAgKiA2MCAqIDYwOyAvL3VzaW5nIDEwMDAgKiA2MCAqIDYwIGluc3RlYWQgb2YgMzZlNSB0byBhdm9pZCBmbG9hdGluZyBwb2ludCByb3VuZGluZyBlcnJvcnMgaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzI5NzhcbiAgICAgICAgLy8gQmVjYXVzZSBvZiBkYXRlQWRkUmVtb3ZlIHRyZWF0cyAyNCBob3VycyBhcyBkaWZmZXJlbnQgZnJvbSBhXG4gICAgICAgIC8vIGRheSB3aGVuIHdvcmtpbmcgYXJvdW5kIERTVCwgd2UgbmVlZCB0byBzdG9yZSB0aGVtIHNlcGFyYXRlbHlcbiAgICAgICAgdGhpcy5fZGF5cyA9ICtkYXlzICtcbiAgICAgICAgICAgIHdlZWtzICogNztcbiAgICAgICAgLy8gSXQgaXMgaW1wb3NzaWJsZSB0byB0cmFuc2xhdGUgbW9udGhzIGludG8gZGF5cyB3aXRob3V0IGtub3dpbmdcbiAgICAgICAgLy8gd2hpY2ggbW9udGhzIHlvdSBhcmUgYXJlIHRhbGtpbmcgYWJvdXQsIHNvIHdlIGhhdmUgdG8gc3RvcmVcbiAgICAgICAgLy8gaXQgc2VwYXJhdGVseS5cbiAgICAgICAgdGhpcy5fbW9udGhzID0gK21vbnRocyArXG4gICAgICAgICAgICBxdWFydGVycyAqIDMgK1xuICAgICAgICAgICAgeWVhcnMgKiAxMjtcblxuICAgICAgICB0aGlzLl9kYXRhID0ge307XG5cbiAgICAgICAgdGhpcy5fbG9jYWxlID0gZ2V0TG9jYWxlKCk7XG5cbiAgICAgICAgdGhpcy5fYnViYmxlKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEdXJhdGlvbiAob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmogaW5zdGFuY2VvZiBEdXJhdGlvbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhYnNSb3VuZCAobnVtYmVyKSB7XG4gICAgICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCgtMSAqIG51bWJlcikgKiAtMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKG51bWJlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBmdW5jdGlvbiBvZmZzZXQgKHRva2VuLCBzZXBhcmF0b3IpIHtcbiAgICAgICAgYWRkRm9ybWF0VG9rZW4odG9rZW4sIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLnV0Y09mZnNldCgpO1xuICAgICAgICAgICAgdmFyIHNpZ24gPSAnKyc7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IC1vZmZzZXQ7XG4gICAgICAgICAgICAgICAgc2lnbiA9ICctJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzaWduICsgemVyb0ZpbGwofn4ob2Zmc2V0IC8gNjApLCAyKSArIHNlcGFyYXRvciArIHplcm9GaWxsKH5+KG9mZnNldCkgJSA2MCwgMik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9mZnNldCgnWicsICc6Jyk7XG4gICAgb2Zmc2V0KCdaWicsICcnKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1onLCAgbWF0Y2hTaG9ydE9mZnNldCk7XG4gICAgYWRkUmVnZXhUb2tlbignWlonLCBtYXRjaFNob3J0T2Zmc2V0KTtcbiAgICBhZGRQYXJzZVRva2VuKFsnWicsICdaWiddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgY29uZmlnLl91c2VVVEMgPSB0cnVlO1xuICAgICAgICBjb25maWcuX3R6bSA9IG9mZnNldEZyb21TdHJpbmcobWF0Y2hTaG9ydE9mZnNldCwgaW5wdXQpO1xuICAgIH0pO1xuXG4gICAgLy8gSEVMUEVSU1xuXG4gICAgLy8gdGltZXpvbmUgY2h1bmtlclxuICAgIC8vICcrMTA6MDAnID4gWycxMCcsICAnMDAnXVxuICAgIC8vICctMTUzMCcgID4gWyctMTUnLCAnMzAnXVxuICAgIHZhciBjaHVua09mZnNldCA9IC8oW1xcK1xcLV18XFxkXFxkKS9naTtcblxuICAgIGZ1bmN0aW9uIG9mZnNldEZyb21TdHJpbmcobWF0Y2hlciwgc3RyaW5nKSB7XG4gICAgICAgIHZhciBtYXRjaGVzID0gKHN0cmluZyB8fCAnJykubWF0Y2gobWF0Y2hlcik7XG5cbiAgICAgICAgaWYgKG1hdGNoZXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNodW5rICAgPSBtYXRjaGVzW21hdGNoZXMubGVuZ3RoIC0gMV0gfHwgW107XG4gICAgICAgIHZhciBwYXJ0cyAgID0gKGNodW5rICsgJycpLm1hdGNoKGNodW5rT2Zmc2V0KSB8fCBbJy0nLCAwLCAwXTtcbiAgICAgICAgdmFyIG1pbnV0ZXMgPSArKHBhcnRzWzFdICogNjApICsgdG9JbnQocGFydHNbMl0pO1xuXG4gICAgICAgIHJldHVybiBtaW51dGVzID09PSAwID9cbiAgICAgICAgICAwIDpcbiAgICAgICAgICBwYXJ0c1swXSA9PT0gJysnID8gbWludXRlcyA6IC1taW51dGVzO1xuICAgIH1cblxuICAgIC8vIFJldHVybiBhIG1vbWVudCBmcm9tIGlucHV0LCB0aGF0IGlzIGxvY2FsL3V0Yy96b25lIGVxdWl2YWxlbnQgdG8gbW9kZWwuXG4gICAgZnVuY3Rpb24gY2xvbmVXaXRoT2Zmc2V0KGlucHV0LCBtb2RlbCkge1xuICAgICAgICB2YXIgcmVzLCBkaWZmO1xuICAgICAgICBpZiAobW9kZWwuX2lzVVRDKSB7XG4gICAgICAgICAgICByZXMgPSBtb2RlbC5jbG9uZSgpO1xuICAgICAgICAgICAgZGlmZiA9IChpc01vbWVudChpbnB1dCkgfHwgaXNEYXRlKGlucHV0KSA/IGlucHV0LnZhbHVlT2YoKSA6IGNyZWF0ZUxvY2FsKGlucHV0KS52YWx1ZU9mKCkpIC0gcmVzLnZhbHVlT2YoKTtcbiAgICAgICAgICAgIC8vIFVzZSBsb3ctbGV2ZWwgYXBpLCBiZWNhdXNlIHRoaXMgZm4gaXMgbG93LWxldmVsIGFwaS5cbiAgICAgICAgICAgIHJlcy5fZC5zZXRUaW1lKHJlcy5fZC52YWx1ZU9mKCkgKyBkaWZmKTtcbiAgICAgICAgICAgIGhvb2tzLnVwZGF0ZU9mZnNldChyZXMsIGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwoaW5wdXQpLmxvY2FsKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXREYXRlT2Zmc2V0IChtKSB7XG4gICAgICAgIC8vIE9uIEZpcmVmb3guMjQgRGF0ZSNnZXRUaW1lem9uZU9mZnNldCByZXR1cm5zIGEgZmxvYXRpbmcgcG9pbnQuXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tb21lbnQvbW9tZW50L3B1bGwvMTg3MVxuICAgICAgICByZXR1cm4gLU1hdGgucm91bmQobS5fZC5nZXRUaW1lem9uZU9mZnNldCgpIC8gMTUpICogMTU7XG4gICAgfVxuXG4gICAgLy8gSE9PS1NcblxuICAgIC8vIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgd2hlbmV2ZXIgYSBtb21lbnQgaXMgbXV0YXRlZC5cbiAgICAvLyBJdCBpcyBpbnRlbmRlZCB0byBrZWVwIHRoZSBvZmZzZXQgaW4gc3luYyB3aXRoIHRoZSB0aW1lem9uZS5cbiAgICBob29rcy51cGRhdGVPZmZzZXQgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIC8vIGtlZXBMb2NhbFRpbWUgPSB0cnVlIG1lYW5zIG9ubHkgY2hhbmdlIHRoZSB0aW1lem9uZSwgd2l0aG91dFxuICAgIC8vIGFmZmVjdGluZyB0aGUgbG9jYWwgaG91ci4gU28gNTozMToyNiArMDMwMCAtLVt1dGNPZmZzZXQoMiwgdHJ1ZSldLS0+XG4gICAgLy8gNTozMToyNiArMDIwMCBJdCBpcyBwb3NzaWJsZSB0aGF0IDU6MzE6MjYgZG9lc24ndCBleGlzdCB3aXRoIG9mZnNldFxuICAgIC8vICswMjAwLCBzbyB3ZSBhZGp1c3QgdGhlIHRpbWUgYXMgbmVlZGVkLCB0byBiZSB2YWxpZC5cbiAgICAvL1xuICAgIC8vIEtlZXBpbmcgdGhlIHRpbWUgYWN0dWFsbHkgYWRkcy9zdWJ0cmFjdHMgKG9uZSBob3VyKVxuICAgIC8vIGZyb20gdGhlIGFjdHVhbCByZXByZXNlbnRlZCB0aW1lLiBUaGF0IGlzIHdoeSB3ZSBjYWxsIHVwZGF0ZU9mZnNldFxuICAgIC8vIGEgc2Vjb25kIHRpbWUuIEluIGNhc2UgaXQgd2FudHMgdXMgdG8gY2hhbmdlIHRoZSBvZmZzZXQgYWdhaW5cbiAgICAvLyBfY2hhbmdlSW5Qcm9ncmVzcyA9PSB0cnVlIGNhc2UsIHRoZW4gd2UgaGF2ZSB0byBhZGp1c3QsIGJlY2F1c2VcbiAgICAvLyB0aGVyZSBpcyBubyBzdWNoIHRpbWUgaW4gdGhlIGdpdmVuIHRpbWV6b25lLlxuICAgIGZ1bmN0aW9uIGdldFNldE9mZnNldCAoaW5wdXQsIGtlZXBMb2NhbFRpbWUsIGtlZXBNaW51dGVzKSB7XG4gICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLl9vZmZzZXQgfHwgMCxcbiAgICAgICAgICAgIGxvY2FsQWRqdXN0O1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgIT0gbnVsbCA/IHRoaXMgOiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSBvZmZzZXRGcm9tU3RyaW5nKG1hdGNoU2hvcnRPZmZzZXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChNYXRoLmFicyhpbnB1dCkgPCAxNiAmJiAha2VlcE1pbnV0ZXMpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IGlucHV0ICogNjA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuX2lzVVRDICYmIGtlZXBMb2NhbFRpbWUpIHtcbiAgICAgICAgICAgICAgICBsb2NhbEFkanVzdCA9IGdldERhdGVPZmZzZXQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9vZmZzZXQgPSBpbnB1dDtcbiAgICAgICAgICAgIHRoaXMuX2lzVVRDID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChsb2NhbEFkanVzdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGQobG9jYWxBZGp1c3QsICdtJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2Zmc2V0ICE9PSBpbnB1dCkge1xuICAgICAgICAgICAgICAgIGlmICgha2VlcExvY2FsVGltZSB8fCB0aGlzLl9jaGFuZ2VJblByb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZFN1YnRyYWN0KHRoaXMsIGNyZWF0ZUR1cmF0aW9uKGlucHV0IC0gb2Zmc2V0LCAnbScpLCAxLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5fY2hhbmdlSW5Qcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/IG9mZnNldCA6IGdldERhdGVPZmZzZXQodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRab25lIChpbnB1dCwga2VlcExvY2FsVGltZSkge1xuICAgICAgICBpZiAoaW5wdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IC1pbnB1dDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoaW5wdXQsIGtlZXBMb2NhbFRpbWUpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAtdGhpcy51dGNPZmZzZXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldE9mZnNldFRvVVRDIChrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnV0Y09mZnNldCgwLCBrZWVwTG9jYWxUaW1lKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRPZmZzZXRUb0xvY2FsIChrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9pc1VUQykge1xuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoMCwga2VlcExvY2FsVGltZSk7XG4gICAgICAgICAgICB0aGlzLl9pc1VUQyA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoa2VlcExvY2FsVGltZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3VidHJhY3QoZ2V0RGF0ZU9mZnNldCh0aGlzKSwgJ20nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRPZmZzZXRUb1BhcnNlZE9mZnNldCAoKSB7XG4gICAgICAgIGlmICh0aGlzLl90em0gIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQodGhpcy5fdHptLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuX2kgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB2YXIgdFpvbmUgPSBvZmZzZXRGcm9tU3RyaW5nKG1hdGNoT2Zmc2V0LCB0aGlzLl9pKTtcbiAgICAgICAgICAgIGlmICh0Wm9uZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQodFpvbmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoMCwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzQWxpZ25lZEhvdXJPZmZzZXQgKGlucHV0KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dCA9IGlucHV0ID8gY3JlYXRlTG9jYWwoaW5wdXQpLnV0Y09mZnNldCgpIDogMDtcblxuICAgICAgICByZXR1cm4gKHRoaXMudXRjT2Zmc2V0KCkgLSBpbnB1dCkgJSA2MCA9PT0gMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0RheWxpZ2h0U2F2aW5nVGltZSAoKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLnV0Y09mZnNldCgpID4gdGhpcy5jbG9uZSgpLm1vbnRoKDApLnV0Y09mZnNldCgpIHx8XG4gICAgICAgICAgICB0aGlzLnV0Y09mZnNldCgpID4gdGhpcy5jbG9uZSgpLm1vbnRoKDUpLnV0Y09mZnNldCgpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEYXlsaWdodFNhdmluZ1RpbWVTaGlmdGVkICgpIHtcbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9pc0RTVFNoaWZ0ZWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faXNEU1RTaGlmdGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGMgPSB7fTtcblxuICAgICAgICBjb3B5Q29uZmlnKGMsIHRoaXMpO1xuICAgICAgICBjID0gcHJlcGFyZUNvbmZpZyhjKTtcblxuICAgICAgICBpZiAoYy5fYSkge1xuICAgICAgICAgICAgdmFyIG90aGVyID0gYy5faXNVVEMgPyBjcmVhdGVVVEMoYy5fYSkgOiBjcmVhdGVMb2NhbChjLl9hKTtcbiAgICAgICAgICAgIHRoaXMuX2lzRFNUU2hpZnRlZCA9IHRoaXMuaXNWYWxpZCgpICYmXG4gICAgICAgICAgICAgICAgY29tcGFyZUFycmF5cyhjLl9hLCBvdGhlci50b0FycmF5KCkpID4gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2lzRFNUU2hpZnRlZCA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzRFNUU2hpZnRlZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0xvY2FsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gIXRoaXMuX2lzVVRDIDogZmFsc2U7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNVdGNPZmZzZXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1ZhbGlkKCkgPyB0aGlzLl9pc1VUQyA6IGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVXRjICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpcy5faXNVVEMgJiYgdGhpcy5fb2Zmc2V0ID09PSAwIDogZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQVNQLk5FVCBqc29uIGRhdGUgZm9ybWF0IHJlZ2V4XG4gICAgdmFyIGFzcE5ldFJlZ2V4ID0gL14oXFwtfFxcKyk/KD86KFxcZCopWy4gXSk/KFxcZCspXFw6KFxcZCspKD86XFw6KFxcZCspKFxcLlxcZCopPyk/JC87XG5cbiAgICAvLyBmcm9tIGh0dHA6Ly9kb2NzLmNsb3N1cmUtbGlicmFyeS5nb29nbGVjb2RlLmNvbS9naXQvY2xvc3VyZV9nb29nX2RhdGVfZGF0ZS5qcy5zb3VyY2UuaHRtbFxuICAgIC8vIHNvbWV3aGF0IG1vcmUgaW4gbGluZSB3aXRoIDQuNC4zLjIgMjAwNCBzcGVjLCBidXQgYWxsb3dzIGRlY2ltYWwgYW55d2hlcmVcbiAgICAvLyBhbmQgZnVydGhlciBtb2RpZmllZCB0byBhbGxvdyBmb3Igc3RyaW5ncyBjb250YWluaW5nIGJvdGggd2VlayBhbmQgZGF5XG4gICAgdmFyIGlzb1JlZ2V4ID0gL14oLXxcXCspP1AoPzooWy0rXT9bMC05LC5dKilZKT8oPzooWy0rXT9bMC05LC5dKilNKT8oPzooWy0rXT9bMC05LC5dKilXKT8oPzooWy0rXT9bMC05LC5dKilEKT8oPzpUKD86KFstK10/WzAtOSwuXSopSCk/KD86KFstK10/WzAtOSwuXSopTSk/KD86KFstK10/WzAtOSwuXSopUyk/KT8kLztcblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUR1cmF0aW9uIChpbnB1dCwga2V5KSB7XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IGlucHV0LFxuICAgICAgICAgICAgLy8gbWF0Y2hpbmcgYWdhaW5zdCByZWdleHAgaXMgZXhwZW5zaXZlLCBkbyBpdCBvbiBkZW1hbmRcbiAgICAgICAgICAgIG1hdGNoID0gbnVsbCxcbiAgICAgICAgICAgIHNpZ24sXG4gICAgICAgICAgICByZXQsXG4gICAgICAgICAgICBkaWZmUmVzO1xuXG4gICAgICAgIGlmIChpc0R1cmF0aW9uKGlucHV0KSkge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgbXMgOiBpbnB1dC5fbWlsbGlzZWNvbmRzLFxuICAgICAgICAgICAgICAgIGQgIDogaW5wdXQuX2RheXMsXG4gICAgICAgICAgICAgICAgTSAgOiBpbnB1dC5fbW9udGhzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKGlucHV0KSkge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbltrZXldID0gaW5wdXQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uLm1pbGxpc2Vjb25kcyA9IGlucHV0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEhKG1hdGNoID0gYXNwTmV0UmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeSAgOiAwLFxuICAgICAgICAgICAgICAgIGQgIDogdG9JbnQobWF0Y2hbREFURV0pICAgICAgICAgICAgICAgICAgICAgICAgICogc2lnbixcbiAgICAgICAgICAgICAgICBoICA6IHRvSW50KG1hdGNoW0hPVVJdKSAgICAgICAgICAgICAgICAgICAgICAgICAqIHNpZ24sXG4gICAgICAgICAgICAgICAgbSAgOiB0b0ludChtYXRjaFtNSU5VVEVdKSAgICAgICAgICAgICAgICAgICAgICAgKiBzaWduLFxuICAgICAgICAgICAgICAgIHMgIDogdG9JbnQobWF0Y2hbU0VDT05EXSkgICAgICAgICAgICAgICAgICAgICAgICogc2lnbixcbiAgICAgICAgICAgICAgICBtcyA6IHRvSW50KGFic1JvdW5kKG1hdGNoW01JTExJU0VDT05EXSAqIDEwMDApKSAqIHNpZ24gLy8gdGhlIG1pbGxpc2Vjb25kIGRlY2ltYWwgcG9pbnQgaXMgaW5jbHVkZWQgaW4gdGhlIG1hdGNoXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKCEhKG1hdGNoID0gaXNvUmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeSA6IHBhcnNlSXNvKG1hdGNoWzJdLCBzaWduKSxcbiAgICAgICAgICAgICAgICBNIDogcGFyc2VJc28obWF0Y2hbM10sIHNpZ24pLFxuICAgICAgICAgICAgICAgIHcgOiBwYXJzZUlzbyhtYXRjaFs0XSwgc2lnbiksXG4gICAgICAgICAgICAgICAgZCA6IHBhcnNlSXNvKG1hdGNoWzVdLCBzaWduKSxcbiAgICAgICAgICAgICAgICBoIDogcGFyc2VJc28obWF0Y2hbNl0sIHNpZ24pLFxuICAgICAgICAgICAgICAgIG0gOiBwYXJzZUlzbyhtYXRjaFs3XSwgc2lnbiksXG4gICAgICAgICAgICAgICAgcyA6IHBhcnNlSXNvKG1hdGNoWzhdLCBzaWduKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmIChkdXJhdGlvbiA9PSBudWxsKSB7Ly8gY2hlY2tzIGZvciBudWxsIG9yIHVuZGVmaW5lZFxuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZHVyYXRpb24gPT09ICdvYmplY3QnICYmICgnZnJvbScgaW4gZHVyYXRpb24gfHwgJ3RvJyBpbiBkdXJhdGlvbikpIHtcbiAgICAgICAgICAgIGRpZmZSZXMgPSBtb21lbnRzRGlmZmVyZW5jZShjcmVhdGVMb2NhbChkdXJhdGlvbi5mcm9tKSwgY3JlYXRlTG9jYWwoZHVyYXRpb24udG8pKTtcblxuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGR1cmF0aW9uLm1zID0gZGlmZlJlcy5taWxsaXNlY29uZHM7XG4gICAgICAgICAgICBkdXJhdGlvbi5NID0gZGlmZlJlcy5tb250aHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXQgPSBuZXcgRHVyYXRpb24oZHVyYXRpb24pO1xuXG4gICAgICAgIGlmIChpc0R1cmF0aW9uKGlucHV0KSAmJiBoYXNPd25Qcm9wKGlucHV0LCAnX2xvY2FsZScpKSB7XG4gICAgICAgICAgICByZXQuX2xvY2FsZSA9IGlucHV0Ll9sb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIGNyZWF0ZUR1cmF0aW9uLmZuID0gRHVyYXRpb24ucHJvdG90eXBlO1xuICAgIGNyZWF0ZUR1cmF0aW9uLmludmFsaWQgPSBjcmVhdGVJbnZhbGlkJDE7XG5cbiAgICBmdW5jdGlvbiBwYXJzZUlzbyAoaW5wLCBzaWduKSB7XG4gICAgICAgIC8vIFdlJ2Qgbm9ybWFsbHkgdXNlIH5+aW5wIGZvciB0aGlzLCBidXQgdW5mb3J0dW5hdGVseSBpdCBhbHNvXG4gICAgICAgIC8vIGNvbnZlcnRzIGZsb2F0cyB0byBpbnRzLlxuICAgICAgICAvLyBpbnAgbWF5IGJlIHVuZGVmaW5lZCwgc28gY2FyZWZ1bCBjYWxsaW5nIHJlcGxhY2Ugb24gaXQuXG4gICAgICAgIHZhciByZXMgPSBpbnAgJiYgcGFyc2VGbG9hdChpbnAucmVwbGFjZSgnLCcsICcuJykpO1xuICAgICAgICAvLyBhcHBseSBzaWduIHdoaWxlIHdlJ3JlIGF0IGl0XG4gICAgICAgIHJldHVybiAoaXNOYU4ocmVzKSA/IDAgOiByZXMpICogc2lnbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKSB7XG4gICAgICAgIHZhciByZXMgPSB7fTtcblxuICAgICAgICByZXMubW9udGhzID0gb3RoZXIubW9udGgoKSAtIGJhc2UubW9udGgoKSArXG4gICAgICAgICAgICAob3RoZXIueWVhcigpIC0gYmFzZS55ZWFyKCkpICogMTI7XG4gICAgICAgIGlmIChiYXNlLmNsb25lKCkuYWRkKHJlcy5tb250aHMsICdNJykuaXNBZnRlcihvdGhlcikpIHtcbiAgICAgICAgICAgIC0tcmVzLm1vbnRocztcbiAgICAgICAgfVxuXG4gICAgICAgIHJlcy5taWxsaXNlY29uZHMgPSArb3RoZXIgLSArKGJhc2UuY2xvbmUoKS5hZGQocmVzLm1vbnRocywgJ00nKSk7XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb21lbnRzRGlmZmVyZW5jZShiYXNlLCBvdGhlcikge1xuICAgICAgICB2YXIgcmVzO1xuICAgICAgICBpZiAoIShiYXNlLmlzVmFsaWQoKSAmJiBvdGhlci5pc1ZhbGlkKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4ge21pbGxpc2Vjb25kczogMCwgbW9udGhzOiAwfTtcbiAgICAgICAgfVxuXG4gICAgICAgIG90aGVyID0gY2xvbmVXaXRoT2Zmc2V0KG90aGVyLCBiYXNlKTtcbiAgICAgICAgaWYgKGJhc2UuaXNCZWZvcmUob3RoZXIpKSB7XG4gICAgICAgICAgICByZXMgPSBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcyA9IHBvc2l0aXZlTW9tZW50c0RpZmZlcmVuY2Uob3RoZXIsIGJhc2UpO1xuICAgICAgICAgICAgcmVzLm1pbGxpc2Vjb25kcyA9IC1yZXMubWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgcmVzLm1vbnRocyA9IC1yZXMubW9udGhzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvLyBUT0RPOiByZW1vdmUgJ25hbWUnIGFyZyBhZnRlciBkZXByZWNhdGlvbiBpcyByZW1vdmVkXG4gICAgZnVuY3Rpb24gY3JlYXRlQWRkZXIoZGlyZWN0aW9uLCBuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsLCBwZXJpb2QpIHtcbiAgICAgICAgICAgIHZhciBkdXIsIHRtcDtcbiAgICAgICAgICAgIC8vaW52ZXJ0IHRoZSBhcmd1bWVudHMsIGJ1dCBjb21wbGFpbiBhYm91dCBpdFxuICAgICAgICAgICAgaWYgKHBlcmlvZCAhPT0gbnVsbCAmJiAhaXNOYU4oK3BlcmlvZCkpIHtcbiAgICAgICAgICAgICAgICBkZXByZWNhdGVTaW1wbGUobmFtZSwgJ21vbWVudCgpLicgKyBuYW1lICArICcocGVyaW9kLCBudW1iZXIpIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgbW9tZW50KCkuJyArIG5hbWUgKyAnKG51bWJlciwgcGVyaW9kKS4gJyArXG4gICAgICAgICAgICAgICAgJ1NlZSBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2FkZC1pbnZlcnRlZC1wYXJhbS8gZm9yIG1vcmUgaW5mby4nKTtcbiAgICAgICAgICAgICAgICB0bXAgPSB2YWw7IHZhbCA9IHBlcmlvZDsgcGVyaW9kID0gdG1wO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YWwgPSB0eXBlb2YgdmFsID09PSAnc3RyaW5nJyA/ICt2YWwgOiB2YWw7XG4gICAgICAgICAgICBkdXIgPSBjcmVhdGVEdXJhdGlvbih2YWwsIHBlcmlvZCk7XG4gICAgICAgICAgICBhZGRTdWJ0cmFjdCh0aGlzLCBkdXIsIGRpcmVjdGlvbik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRTdWJ0cmFjdCAobW9tLCBkdXJhdGlvbiwgaXNBZGRpbmcsIHVwZGF0ZU9mZnNldCkge1xuICAgICAgICB2YXIgbWlsbGlzZWNvbmRzID0gZHVyYXRpb24uX21pbGxpc2Vjb25kcyxcbiAgICAgICAgICAgIGRheXMgPSBhYnNSb3VuZChkdXJhdGlvbi5fZGF5cyksXG4gICAgICAgICAgICBtb250aHMgPSBhYnNSb3VuZChkdXJhdGlvbi5fbW9udGhzKTtcblxuICAgICAgICBpZiAoIW1vbS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIC8vIE5vIG9wXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB1cGRhdGVPZmZzZXQgPSB1cGRhdGVPZmZzZXQgPT0gbnVsbCA/IHRydWUgOiB1cGRhdGVPZmZzZXQ7XG5cbiAgICAgICAgaWYgKG1vbnRocykge1xuICAgICAgICAgICAgc2V0TW9udGgobW9tLCBnZXQobW9tLCAnTW9udGgnKSArIG1vbnRocyAqIGlzQWRkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF5cykge1xuICAgICAgICAgICAgc2V0JDEobW9tLCAnRGF0ZScsIGdldChtb20sICdEYXRlJykgKyBkYXlzICogaXNBZGRpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtaWxsaXNlY29uZHMpIHtcbiAgICAgICAgICAgIG1vbS5fZC5zZXRUaW1lKG1vbS5fZC52YWx1ZU9mKCkgKyBtaWxsaXNlY29uZHMgKiBpc0FkZGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVwZGF0ZU9mZnNldCkge1xuICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KG1vbSwgZGF5cyB8fCBtb250aHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGFkZCAgICAgID0gY3JlYXRlQWRkZXIoMSwgJ2FkZCcpO1xuICAgIHZhciBzdWJ0cmFjdCA9IGNyZWF0ZUFkZGVyKC0xLCAnc3VidHJhY3QnKTtcblxuICAgIGZ1bmN0aW9uIGdldENhbGVuZGFyRm9ybWF0KG15TW9tZW50LCBub3cpIHtcbiAgICAgICAgdmFyIGRpZmYgPSBteU1vbWVudC5kaWZmKG5vdywgJ2RheXMnLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIGRpZmYgPCAtNiA/ICdzYW1lRWxzZScgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCAtMSA/ICdsYXN0V2VlaycgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCAwID8gJ2xhc3REYXknIDpcbiAgICAgICAgICAgICAgICBkaWZmIDwgMSA/ICdzYW1lRGF5JyA6XG4gICAgICAgICAgICAgICAgZGlmZiA8IDIgPyAnbmV4dERheScgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCA3ID8gJ25leHRXZWVrJyA6ICdzYW1lRWxzZSc7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsZW5kYXIkMSAodGltZSwgZm9ybWF0cykge1xuICAgICAgICAvLyBXZSB3YW50IHRvIGNvbXBhcmUgdGhlIHN0YXJ0IG9mIHRvZGF5LCB2cyB0aGlzLlxuICAgICAgICAvLyBHZXR0aW5nIHN0YXJ0LW9mLXRvZGF5IGRlcGVuZHMgb24gd2hldGhlciB3ZSdyZSBsb2NhbC91dGMvb2Zmc2V0IG9yIG5vdC5cbiAgICAgICAgdmFyIG5vdyA9IHRpbWUgfHwgY3JlYXRlTG9jYWwoKSxcbiAgICAgICAgICAgIHNvZCA9IGNsb25lV2l0aE9mZnNldChub3csIHRoaXMpLnN0YXJ0T2YoJ2RheScpLFxuICAgICAgICAgICAgZm9ybWF0ID0gaG9va3MuY2FsZW5kYXJGb3JtYXQodGhpcywgc29kKSB8fCAnc2FtZUVsc2UnO1xuXG4gICAgICAgIHZhciBvdXRwdXQgPSBmb3JtYXRzICYmIChpc0Z1bmN0aW9uKGZvcm1hdHNbZm9ybWF0XSkgPyBmb3JtYXRzW2Zvcm1hdF0uY2FsbCh0aGlzLCBub3cpIDogZm9ybWF0c1tmb3JtYXRdKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXQob3V0cHV0IHx8IHRoaXMubG9jYWxlRGF0YSgpLmNhbGVuZGFyKGZvcm1hdCwgdGhpcywgY3JlYXRlTG9jYWwobm93KSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsb25lICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBNb21lbnQodGhpcyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBZnRlciAoaW5wdXQsIHVuaXRzKSB7XG4gICAgICAgIHZhciBsb2NhbElucHV0ID0gaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBjcmVhdGVMb2NhbChpbnB1dCk7XG4gICAgICAgIGlmICghKHRoaXMuaXNWYWxpZCgpICYmIGxvY2FsSW5wdXQuaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpIHx8ICdtaWxsaXNlY29uZCc7XG4gICAgICAgIGlmICh1bml0cyA9PT0gJ21pbGxpc2Vjb25kJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpID4gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbG9jYWxJbnB1dC52YWx1ZU9mKCkgPCB0aGlzLmNsb25lKCkuc3RhcnRPZih1bml0cykudmFsdWVPZigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNCZWZvcmUgKGlucHV0LCB1bml0cykge1xuICAgICAgICB2YXIgbG9jYWxJbnB1dCA9IGlzTW9tZW50KGlucHV0KSA/IGlucHV0IDogY3JlYXRlTG9jYWwoaW5wdXQpO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbElucHV0LmlzVmFsaWQoKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB8fCAnbWlsbGlzZWNvbmQnO1xuICAgICAgICBpZiAodW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKSA8IGxvY2FsSW5wdXQudmFsdWVPZigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmRPZih1bml0cykudmFsdWVPZigpIDwgbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0JldHdlZW4gKGZyb20sIHRvLCB1bml0cywgaW5jbHVzaXZpdHkpIHtcbiAgICAgICAgdmFyIGxvY2FsRnJvbSA9IGlzTW9tZW50KGZyb20pID8gZnJvbSA6IGNyZWF0ZUxvY2FsKGZyb20pLFxuICAgICAgICAgICAgbG9jYWxUbyA9IGlzTW9tZW50KHRvKSA/IHRvIDogY3JlYXRlTG9jYWwodG8pO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbEZyb20uaXNWYWxpZCgpICYmIGxvY2FsVG8uaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGluY2x1c2l2aXR5ID0gaW5jbHVzaXZpdHkgfHwgJygpJztcbiAgICAgICAgcmV0dXJuIChpbmNsdXNpdml0eVswXSA9PT0gJygnID8gdGhpcy5pc0FmdGVyKGxvY2FsRnJvbSwgdW5pdHMpIDogIXRoaXMuaXNCZWZvcmUobG9jYWxGcm9tLCB1bml0cykpICYmXG4gICAgICAgICAgICAoaW5jbHVzaXZpdHlbMV0gPT09ICcpJyA/IHRoaXMuaXNCZWZvcmUobG9jYWxUbywgdW5pdHMpIDogIXRoaXMuaXNBZnRlcihsb2NhbFRvLCB1bml0cykpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzU2FtZSAoaW5wdXQsIHVuaXRzKSB7XG4gICAgICAgIHZhciBsb2NhbElucHV0ID0gaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBjcmVhdGVMb2NhbChpbnB1dCksXG4gICAgICAgICAgICBpbnB1dE1zO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbElucHV0LmlzVmFsaWQoKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB8fCAnbWlsbGlzZWNvbmQnO1xuICAgICAgICBpZiAodW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKSA9PT0gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbnB1dE1zID0gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jbG9uZSgpLnN0YXJ0T2YodW5pdHMpLnZhbHVlT2YoKSA8PSBpbnB1dE1zICYmIGlucHV0TXMgPD0gdGhpcy5jbG9uZSgpLmVuZE9mKHVuaXRzKS52YWx1ZU9mKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1NhbWVPckFmdGVyIChpbnB1dCwgdW5pdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNTYW1lKGlucHV0LCB1bml0cykgfHwgdGhpcy5pc0FmdGVyKGlucHV0LCB1bml0cyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNTYW1lT3JCZWZvcmUgKGlucHV0LCB1bml0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1NhbWUoaW5wdXQsIHVuaXRzKSB8fCB0aGlzLmlzQmVmb3JlKGlucHV0LCB1bml0cyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGlmZiAoaW5wdXQsIHVuaXRzLCBhc0Zsb2F0KSB7XG4gICAgICAgIHZhciB0aGF0LFxuICAgICAgICAgICAgem9uZURlbHRhLFxuICAgICAgICAgICAgb3V0cHV0O1xuXG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgIH1cblxuICAgICAgICB0aGF0ID0gY2xvbmVXaXRoT2Zmc2V0KGlucHV0LCB0aGlzKTtcblxuICAgICAgICBpZiAoIXRoYXQuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG5cbiAgICAgICAgem9uZURlbHRhID0gKHRoYXQudXRjT2Zmc2V0KCkgLSB0aGlzLnV0Y09mZnNldCgpKSAqIDZlNDtcblxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzogb3V0cHV0ID0gbW9udGhEaWZmKHRoaXMsIHRoYXQpIC8gMTI7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOiBvdXRwdXQgPSBtb250aERpZmYodGhpcywgdGhhdCk7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6IG91dHB1dCA9IG1vbnRoRGlmZih0aGlzLCB0aGF0KSAvIDM7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzogb3V0cHV0ID0gKHRoaXMgLSB0aGF0KSAvIDFlMzsgYnJlYWs7IC8vIDEwMDBcbiAgICAgICAgICAgIGNhc2UgJ21pbnV0ZSc6IG91dHB1dCA9ICh0aGlzIC0gdGhhdCkgLyA2ZTQ7IGJyZWFrOyAvLyAxMDAwICogNjBcbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOiBvdXRwdXQgPSAodGhpcyAtIHRoYXQpIC8gMzZlNTsgYnJlYWs7IC8vIDEwMDAgKiA2MCAqIDYwXG4gICAgICAgICAgICBjYXNlICdkYXknOiBvdXRwdXQgPSAodGhpcyAtIHRoYXQgLSB6b25lRGVsdGEpIC8gODY0ZTU7IGJyZWFrOyAvLyAxMDAwICogNjAgKiA2MCAqIDI0LCBuZWdhdGUgZHN0XG4gICAgICAgICAgICBjYXNlICd3ZWVrJzogb3V0cHV0ID0gKHRoaXMgLSB0aGF0IC0gem9uZURlbHRhKSAvIDYwNDhlNTsgYnJlYWs7IC8vIDEwMDAgKiA2MCAqIDYwICogMjQgKiA3LCBuZWdhdGUgZHN0XG4gICAgICAgICAgICBkZWZhdWx0OiBvdXRwdXQgPSB0aGlzIC0gdGhhdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhc0Zsb2F0ID8gb3V0cHV0IDogYWJzRmxvb3Iob3V0cHV0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb250aERpZmYgKGEsIGIpIHtcbiAgICAgICAgLy8gZGlmZmVyZW5jZSBpbiBtb250aHNcbiAgICAgICAgdmFyIHdob2xlTW9udGhEaWZmID0gKChiLnllYXIoKSAtIGEueWVhcigpKSAqIDEyKSArIChiLm1vbnRoKCkgLSBhLm1vbnRoKCkpLFxuICAgICAgICAgICAgLy8gYiBpcyBpbiAoYW5jaG9yIC0gMSBtb250aCwgYW5jaG9yICsgMSBtb250aClcbiAgICAgICAgICAgIGFuY2hvciA9IGEuY2xvbmUoKS5hZGQod2hvbGVNb250aERpZmYsICdtb250aHMnKSxcbiAgICAgICAgICAgIGFuY2hvcjIsIGFkanVzdDtcblxuICAgICAgICBpZiAoYiAtIGFuY2hvciA8IDApIHtcbiAgICAgICAgICAgIGFuY2hvcjIgPSBhLmNsb25lKCkuYWRkKHdob2xlTW9udGhEaWZmIC0gMSwgJ21vbnRocycpO1xuICAgICAgICAgICAgLy8gbGluZWFyIGFjcm9zcyB0aGUgbW9udGhcbiAgICAgICAgICAgIGFkanVzdCA9IChiIC0gYW5jaG9yKSAvIChhbmNob3IgLSBhbmNob3IyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFuY2hvcjIgPSBhLmNsb25lKCkuYWRkKHdob2xlTW9udGhEaWZmICsgMSwgJ21vbnRocycpO1xuICAgICAgICAgICAgLy8gbGluZWFyIGFjcm9zcyB0aGUgbW9udGhcbiAgICAgICAgICAgIGFkanVzdCA9IChiIC0gYW5jaG9yKSAvIChhbmNob3IyIC0gYW5jaG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vY2hlY2sgZm9yIG5lZ2F0aXZlIHplcm8sIHJldHVybiB6ZXJvIGlmIG5lZ2F0aXZlIHplcm9cbiAgICAgICAgcmV0dXJuIC0od2hvbGVNb250aERpZmYgKyBhZGp1c3QpIHx8IDA7XG4gICAgfVxuXG4gICAgaG9va3MuZGVmYXVsdEZvcm1hdCA9ICdZWVlZLU1NLUREVEhIOm1tOnNzWic7XG4gICAgaG9va3MuZGVmYXVsdEZvcm1hdFV0YyA9ICdZWVlZLU1NLUREVEhIOm1tOnNzW1pdJztcblxuICAgIGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5sb2NhbGUoJ2VuJykuZm9ybWF0KCdkZGQgTU1NIEREIFlZWVkgSEg6bW06c3MgW0dNVF1aWicpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvSVNPU3RyaW5nKGtlZXBPZmZzZXQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHV0YyA9IGtlZXBPZmZzZXQgIT09IHRydWU7XG4gICAgICAgIHZhciBtID0gdXRjID8gdGhpcy5jbG9uZSgpLnV0YygpIDogdGhpcztcbiAgICAgICAgaWYgKG0ueWVhcigpIDwgMCB8fCBtLnllYXIoKSA+IDk5OTkpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXRNb21lbnQobSwgdXRjID8gJ1lZWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1taXScgOiAnWVlZWVlZLU1NLUREW1RdSEg6bW06c3MuU1NTWicpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nKSkge1xuICAgICAgICAgICAgLy8gbmF0aXZlIGltcGxlbWVudGF0aW9uIGlzIH41MHggZmFzdGVyLCB1c2UgaXQgd2hlbiB3ZSBjYW5cbiAgICAgICAgICAgIGlmICh1dGMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0RhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkgKyB0aGlzLnV0Y09mZnNldCgpICogNjAgKiAxMDAwKS50b0lTT1N0cmluZygpLnJlcGxhY2UoJ1onLCBmb3JtYXRNb21lbnQobSwgJ1onKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdE1vbWVudChtLCB1dGMgPyAnWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1taXScgOiAnWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1onKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gYSBodW1hbiByZWFkYWJsZSByZXByZXNlbnRhdGlvbiBvZiBhIG1vbWVudCB0aGF0IGNhblxuICAgICAqIGFsc28gYmUgZXZhbHVhdGVkIHRvIGdldCBhIG5ldyBtb21lbnQgd2hpY2ggaXMgdGhlIHNhbWVcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHBzOi8vbm9kZWpzLm9yZy9kaXN0L2xhdGVzdC9kb2NzL2FwaS91dGlsLmh0bWwjdXRpbF9jdXN0b21faW5zcGVjdF9mdW5jdGlvbl9vbl9vYmplY3RzXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiAnbW9tZW50LmludmFsaWQoLyogJyArIHRoaXMuX2kgKyAnICovKSc7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZ1bmMgPSAnbW9tZW50JztcbiAgICAgICAgdmFyIHpvbmUgPSAnJztcbiAgICAgICAgaWYgKCF0aGlzLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgZnVuYyA9IHRoaXMudXRjT2Zmc2V0KCkgPT09IDAgPyAnbW9tZW50LnV0YycgOiAnbW9tZW50LnBhcnNlWm9uZSc7XG4gICAgICAgICAgICB6b25lID0gJ1onO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcmVmaXggPSAnWycgKyBmdW5jICsgJyhcIl0nO1xuICAgICAgICB2YXIgeWVhciA9ICgwIDw9IHRoaXMueWVhcigpICYmIHRoaXMueWVhcigpIDw9IDk5OTkpID8gJ1lZWVknIDogJ1lZWVlZWSc7XG4gICAgICAgIHZhciBkYXRldGltZSA9ICctTU0tRERbVF1ISDptbTpzcy5TU1MnO1xuICAgICAgICB2YXIgc3VmZml4ID0gem9uZSArICdbXCIpXSc7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0KHByZWZpeCArIHllYXIgKyBkYXRldGltZSArIHN1ZmZpeCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0IChpbnB1dFN0cmluZykge1xuICAgICAgICBpZiAoIWlucHV0U3RyaW5nKSB7XG4gICAgICAgICAgICBpbnB1dFN0cmluZyA9IHRoaXMuaXNVdGMoKSA/IGhvb2tzLmRlZmF1bHRGb3JtYXRVdGMgOiBob29rcy5kZWZhdWx0Rm9ybWF0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBvdXRwdXQgPSBmb3JtYXRNb21lbnQodGhpcywgaW5wdXRTdHJpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkucG9zdGZvcm1hdChvdXRwdXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZyb20gKHRpbWUsIHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNWYWxpZCgpICYmXG4gICAgICAgICAgICAgICAgKChpc01vbWVudCh0aW1lKSAmJiB0aW1lLmlzVmFsaWQoKSkgfHxcbiAgICAgICAgICAgICAgICAgY3JlYXRlTG9jYWwodGltZSkuaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKHt0bzogdGhpcywgZnJvbTogdGltZX0pLmxvY2FsZSh0aGlzLmxvY2FsZSgpKS5odW1hbml6ZSghd2l0aG91dFN1ZmZpeCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkuaW52YWxpZERhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZyb21Ob3cgKHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbShjcmVhdGVMb2NhbCgpLCB3aXRob3V0U3VmZml4KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0byAodGltZSwgd2l0aG91dFN1ZmZpeCkge1xuICAgICAgICBpZiAodGhpcy5pc1ZhbGlkKCkgJiZcbiAgICAgICAgICAgICAgICAoKGlzTW9tZW50KHRpbWUpICYmIHRpbWUuaXNWYWxpZCgpKSB8fFxuICAgICAgICAgICAgICAgICBjcmVhdGVMb2NhbCh0aW1lKS5pc1ZhbGlkKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlRHVyYXRpb24oe2Zyb206IHRoaXMsIHRvOiB0aW1lfSkubG9jYWxlKHRoaXMubG9jYWxlKCkpLmh1bWFuaXplKCF3aXRob3V0U3VmZml4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS5pbnZhbGlkRGF0ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9Ob3cgKHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG8oY3JlYXRlTG9jYWwoKSwgd2l0aG91dFN1ZmZpeCk7XG4gICAgfVxuXG4gICAgLy8gSWYgcGFzc2VkIGEgbG9jYWxlIGtleSwgaXQgd2lsbCBzZXQgdGhlIGxvY2FsZSBmb3IgdGhpc1xuICAgIC8vIGluc3RhbmNlLiAgT3RoZXJ3aXNlLCBpdCB3aWxsIHJldHVybiB0aGUgbG9jYWxlIGNvbmZpZ3VyYXRpb25cbiAgICAvLyB2YXJpYWJsZXMgZm9yIHRoaXMgaW5zdGFuY2UuXG4gICAgZnVuY3Rpb24gbG9jYWxlIChrZXkpIHtcbiAgICAgICAgdmFyIG5ld0xvY2FsZURhdGE7XG5cbiAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlLl9hYmJyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3TG9jYWxlRGF0YSA9IGdldExvY2FsZShrZXkpO1xuICAgICAgICAgICAgaWYgKG5ld0xvY2FsZURhdGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvY2FsZSA9IG5ld0xvY2FsZURhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBsYW5nID0gZGVwcmVjYXRlKFxuICAgICAgICAnbW9tZW50KCkubGFuZygpIGlzIGRlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZSBtb21lbnQoKS5sb2NhbGVEYXRhKCkgdG8gZ2V0IHRoZSBsYW5ndWFnZSBjb25maWd1cmF0aW9uLiBVc2UgbW9tZW50KCkubG9jYWxlKCkgdG8gY2hhbmdlIGxhbmd1YWdlcy4nLFxuICAgICAgICBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZShrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIGZ1bmN0aW9uIGxvY2FsZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlO1xuICAgIH1cblxuICAgIHZhciBNU19QRVJfU0VDT05EID0gMTAwMDtcbiAgICB2YXIgTVNfUEVSX01JTlVURSA9IDYwICogTVNfUEVSX1NFQ09ORDtcbiAgICB2YXIgTVNfUEVSX0hPVVIgPSA2MCAqIE1TX1BFUl9NSU5VVEU7XG4gICAgdmFyIE1TX1BFUl80MDBfWUVBUlMgPSAoMzY1ICogNDAwICsgOTcpICogMjQgKiBNU19QRVJfSE9VUjtcblxuICAgIC8vIGFjdHVhbCBtb2R1bG8gLSBoYW5kbGVzIG5lZ2F0aXZlIG51bWJlcnMgKGZvciBkYXRlcyBiZWZvcmUgMTk3MCk6XG4gICAgZnVuY3Rpb24gbW9kJDEoZGl2aWRlbmQsIGRpdmlzb3IpIHtcbiAgICAgICAgcmV0dXJuIChkaXZpZGVuZCAlIGRpdmlzb3IgKyBkaXZpc29yKSAlIGRpdmlzb3I7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9jYWxTdGFydE9mRGF0ZSh5LCBtLCBkKSB7XG4gICAgICAgIC8vIHRoZSBkYXRlIGNvbnN0cnVjdG9yIHJlbWFwcyB5ZWFycyAwLTk5IHRvIDE5MDAtMTk5OVxuICAgICAgICBpZiAoeSA8IDEwMCAmJiB5ID49IDApIHtcbiAgICAgICAgICAgIC8vIHByZXNlcnZlIGxlYXAgeWVhcnMgdXNpbmcgYSBmdWxsIDQwMCB5ZWFyIGN5Y2xlLCB0aGVuIHJlc2V0XG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoeSArIDQwMCwgbSwgZCkgLSBNU19QRVJfNDAwX1lFQVJTO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHksIG0sIGQpLnZhbHVlT2YoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHV0Y1N0YXJ0T2ZEYXRlKHksIG0sIGQpIHtcbiAgICAgICAgLy8gRGF0ZS5VVEMgcmVtYXBzIHllYXJzIDAtOTkgdG8gMTkwMC0xOTk5XG4gICAgICAgIGlmICh5IDwgMTAwICYmIHkgPj0gMCkge1xuICAgICAgICAgICAgLy8gcHJlc2VydmUgbGVhcCB5ZWFycyB1c2luZyBhIGZ1bGwgNDAwIHllYXIgY3ljbGUsIHRoZW4gcmVzZXRcbiAgICAgICAgICAgIHJldHVybiBEYXRlLlVUQyh5ICsgNDAwLCBtLCBkKSAtIE1TX1BFUl80MDBfWUVBUlM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gRGF0ZS5VVEMoeSwgbSwgZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdGFydE9mICh1bml0cykge1xuICAgICAgICB2YXIgdGltZTtcbiAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh1bml0cyk7XG4gICAgICAgIGlmICh1bml0cyA9PT0gdW5kZWZpbmVkIHx8IHVuaXRzID09PSAnbWlsbGlzZWNvbmQnIHx8ICF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc3RhcnRPZkRhdGUgPSB0aGlzLl9pc1VUQyA/IHV0Y1N0YXJ0T2ZEYXRlIDogbG9jYWxTdGFydE9mRGF0ZTtcblxuICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIDAsIDEpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCkgLSB0aGlzLm1vbnRoKCkgJSAzLCAxKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgMSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSB0aGlzLndlZWtkYXkoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdpc29XZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSAodGhpcy5pc29XZWVrZGF5KCkgLSAxKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdkYXknOlxuICAgICAgICAgICAgY2FzZSAnZGF0ZSc6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCksIHRoaXMuZGF0ZSgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOlxuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLl9kLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB0aW1lIC09IG1vZCQxKHRpbWUgKyAodGhpcy5faXNVVEMgPyAwIDogdGhpcy51dGNPZmZzZXQoKSAqIE1TX1BFUl9NSU5VVEUpLCBNU19QRVJfSE9VUik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLl9kLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB0aW1lIC09IG1vZCQxKHRpbWUsIE1TX1BFUl9NSU5VVEUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSAtPSBtb2QkMSh0aW1lLCBNU19QRVJfU0VDT05EKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2Quc2V0VGltZSh0aW1lKTtcbiAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMsIHRydWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBlbmRPZiAodW5pdHMpIHtcbiAgICAgICAgdmFyIHRpbWU7XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICBpZiAodW5pdHMgPT09IHVuZGVmaW5lZCB8fCB1bml0cyA9PT0gJ21pbGxpc2Vjb25kJyB8fCAhdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHN0YXJ0T2ZEYXRlID0gdGhpcy5faXNVVEMgPyB1dGNTdGFydE9mRGF0ZSA6IGxvY2FsU3RhcnRPZkRhdGU7XG5cbiAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpICsgMSwgMCwgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCkgLSB0aGlzLm1vbnRoKCkgJSAzICsgMywgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOlxuICAgICAgICAgICAgICAgIHRpbWUgPSBzdGFydE9mRGF0ZSh0aGlzLnllYXIoKSwgdGhpcy5tb250aCgpICsgMSwgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCksIHRoaXMuZGF0ZSgpIC0gdGhpcy53ZWVrZGF5KCkgKyA3KSAtIDE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdpc29XZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSAodGhpcy5pc29XZWVrZGF5KCkgLSAxKSArIDcpIC0gMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2RheSc6XG4gICAgICAgICAgICBjYXNlICdkYXRlJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgKyAxKSAtIDE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfSE9VUiAtIG1vZCQxKHRpbWUgKyAodGhpcy5faXNVVEMgPyAwIDogdGhpcy51dGNPZmZzZXQoKSAqIE1TX1BFUl9NSU5VVEUpLCBNU19QRVJfSE9VUikgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbWludXRlJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfTUlOVVRFIC0gbW9kJDEodGltZSwgTVNfUEVSX01JTlVURSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfU0VDT05EIC0gbW9kJDEodGltZSwgTVNfUEVSX1NFQ09ORCkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fZC5zZXRUaW1lKHRpbWUpO1xuICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbHVlT2YgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZC52YWx1ZU9mKCkgLSAoKHRoaXMuX29mZnNldCB8fCAwKSAqIDYwMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1bml4ICgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IodGhpcy52YWx1ZU9mKCkgLyAxMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0RhdGUgKCkge1xuICAgICAgICByZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvQXJyYXkgKCkge1xuICAgICAgICB2YXIgbSA9IHRoaXM7XG4gICAgICAgIHJldHVybiBbbS55ZWFyKCksIG0ubW9udGgoKSwgbS5kYXRlKCksIG0uaG91cigpLCBtLm1pbnV0ZSgpLCBtLnNlY29uZCgpLCBtLm1pbGxpc2Vjb25kKCldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvT2JqZWN0ICgpIHtcbiAgICAgICAgdmFyIG0gPSB0aGlzO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeWVhcnM6IG0ueWVhcigpLFxuICAgICAgICAgICAgbW9udGhzOiBtLm1vbnRoKCksXG4gICAgICAgICAgICBkYXRlOiBtLmRhdGUoKSxcbiAgICAgICAgICAgIGhvdXJzOiBtLmhvdXJzKCksXG4gICAgICAgICAgICBtaW51dGVzOiBtLm1pbnV0ZXMoKSxcbiAgICAgICAgICAgIHNlY29uZHM6IG0uc2Vjb25kcygpLFxuICAgICAgICAgICAgbWlsbGlzZWNvbmRzOiBtLm1pbGxpc2Vjb25kcygpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgICAgICAgLy8gbmV3IERhdGUoTmFOKS50b0pTT04oKSA9PT0gbnVsbFxuICAgICAgICByZXR1cm4gdGhpcy5pc1ZhbGlkKCkgPyB0aGlzLnRvSVNPU3RyaW5nKCkgOiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVmFsaWQkMiAoKSB7XG4gICAgICAgIHJldHVybiBpc1ZhbGlkKHRoaXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNpbmdGbGFncyAoKSB7XG4gICAgICAgIHJldHVybiBleHRlbmQoe30sIGdldFBhcnNpbmdGbGFncyh0aGlzKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW52YWxpZEF0ICgpIHtcbiAgICAgICAgcmV0dXJuIGdldFBhcnNpbmdGbGFncyh0aGlzKS5vdmVyZmxvdztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGlvbkRhdGEoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpbnB1dDogdGhpcy5faSxcbiAgICAgICAgICAgIGZvcm1hdDogdGhpcy5fZixcbiAgICAgICAgICAgIGxvY2FsZTogdGhpcy5fbG9jYWxlLFxuICAgICAgICAgICAgaXNVVEM6IHRoaXMuX2lzVVRDLFxuICAgICAgICAgICAgc3RyaWN0OiB0aGlzLl9zdHJpY3RcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ2dnJywgMl0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2Vla1llYXIoKSAlIDEwMDtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnR0cnLCAyXSwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc29XZWVrWWVhcigpICUgMTAwO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYWRkV2Vla1llYXJGb3JtYXRUb2tlbiAodG9rZW4sIGdldHRlcikge1xuICAgICAgICBhZGRGb3JtYXRUb2tlbigwLCBbdG9rZW4sIHRva2VuLmxlbmd0aF0sIDAsIGdldHRlcik7XG4gICAgfVxuXG4gICAgYWRkV2Vla1llYXJGb3JtYXRUb2tlbignZ2dnZycsICAgICAnd2Vla1llYXInKTtcbiAgICBhZGRXZWVrWWVhckZvcm1hdFRva2VuKCdnZ2dnZycsICAgICd3ZWVrWWVhcicpO1xuICAgIGFkZFdlZWtZZWFyRm9ybWF0VG9rZW4oJ0dHR0cnLCAgJ2lzb1dlZWtZZWFyJyk7XG4gICAgYWRkV2Vla1llYXJGb3JtYXRUb2tlbignR0dHR0cnLCAnaXNvV2Vla1llYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnd2Vla1llYXInLCAnZ2cnKTtcbiAgICBhZGRVbml0QWxpYXMoJ2lzb1dlZWtZZWFyJywgJ0dHJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCd3ZWVrWWVhcicsIDEpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2Vla1llYXInLCAxKTtcblxuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbignRycsICAgICAgbWF0Y2hTaWduZWQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2cnLCAgICAgIG1hdGNoU2lnbmVkKTtcbiAgICBhZGRSZWdleFRva2VuKCdHRycsICAgICBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignZ2cnLCAgICAgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0dHR0cnLCAgIG1hdGNoMXRvNCwgbWF0Y2g0KTtcbiAgICBhZGRSZWdleFRva2VuKCdnZ2dnJywgICBtYXRjaDF0bzQsIG1hdGNoNCk7XG4gICAgYWRkUmVnZXhUb2tlbignR0dHR0cnLCAgbWF0Y2gxdG82LCBtYXRjaDYpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2dnZ2dnJywgIG1hdGNoMXRvNiwgbWF0Y2g2KTtcblxuICAgIGFkZFdlZWtQYXJzZVRva2VuKFsnZ2dnZycsICdnZ2dnZycsICdHR0dHJywgJ0dHR0dHJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuLnN1YnN0cigwLCAyKV0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICBhZGRXZWVrUGFyc2VUb2tlbihbJ2dnJywgJ0dHJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuXSA9IGhvb2tzLnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICB9KTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFNldFdlZWtZZWFyIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gZ2V0U2V0V2Vla1llYXJIZWxwZXIuY2FsbCh0aGlzLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIHRoaXMud2VlaygpLFxuICAgICAgICAgICAgICAgIHRoaXMud2Vla2RheSgpLFxuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrLmRvdyxcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsZURhdGEoKS5fd2Vlay5kb3kpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNldElTT1dlZWtZZWFyIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gZ2V0U2V0V2Vla1llYXJIZWxwZXIuY2FsbCh0aGlzLFxuICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLmlzb1dlZWsoKSwgdGhpcy5pc29XZWVrZGF5KCksIDEsIDQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldElTT1dlZWtzSW5ZZWFyICgpIHtcbiAgICAgICAgcmV0dXJuIHdlZWtzSW5ZZWFyKHRoaXMueWVhcigpLCAxLCA0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRXZWVrc0luWWVhciAoKSB7XG4gICAgICAgIHZhciB3ZWVrSW5mbyA9IHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrO1xuICAgICAgICByZXR1cm4gd2Vla3NJblllYXIodGhpcy55ZWFyKCksIHdlZWtJbmZvLmRvdywgd2Vla0luZm8uZG95KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRXZWVrWWVhckhlbHBlcihpbnB1dCwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIHdlZWtzVGFyZ2V0O1xuICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHdlZWtPZlllYXIodGhpcywgZG93LCBkb3kpLnllYXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3ZWVrc1RhcmdldCA9IHdlZWtzSW5ZZWFyKGlucHV0LCBkb3csIGRveSk7XG4gICAgICAgICAgICBpZiAod2VlayA+IHdlZWtzVGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgd2VlayA9IHdlZWtzVGFyZ2V0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNldFdlZWtBbGwuY2FsbCh0aGlzLCBpbnB1dCwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0V2Vla0FsbCh3ZWVrWWVhciwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIGRheU9mWWVhckRhdGEgPSBkYXlPZlllYXJGcm9tV2Vla3Mod2Vla1llYXIsIHdlZWssIHdlZWtkYXksIGRvdywgZG95KSxcbiAgICAgICAgICAgIGRhdGUgPSBjcmVhdGVVVENEYXRlKGRheU9mWWVhckRhdGEueWVhciwgMCwgZGF5T2ZZZWFyRGF0YS5kYXlPZlllYXIpO1xuXG4gICAgICAgIHRoaXMueWVhcihkYXRlLmdldFVUQ0Z1bGxZZWFyKCkpO1xuICAgICAgICB0aGlzLm1vbnRoKGRhdGUuZ2V0VVRDTW9udGgoKSk7XG4gICAgICAgIHRoaXMuZGF0ZShkYXRlLmdldFVUQ0RhdGUoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdRJywgMCwgJ1FvJywgJ3F1YXJ0ZXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygncXVhcnRlcicsICdRJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdxdWFydGVyJywgNyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdRJywgbWF0Y2gxKTtcbiAgICBhZGRQYXJzZVRva2VuKCdRJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtNT05USF0gPSAodG9JbnQoaW5wdXQpIC0gMSkgKiAzO1xuICAgIH0pO1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgZnVuY3Rpb24gZ2V0U2V0UXVhcnRlciAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyBNYXRoLmNlaWwoKHRoaXMubW9udGgoKSArIDEpIC8gMykgOiB0aGlzLm1vbnRoKChpbnB1dCAtIDEpICogMyArIHRoaXMubW9udGgoKSAlIDMpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdEJywgWydERCcsIDJdLCAnRG8nLCAnZGF0ZScpO1xuXG4gICAgLy8gQUxJQVNFU1xuXG4gICAgYWRkVW5pdEFsaWFzKCdkYXRlJywgJ0QnKTtcblxuICAgIC8vIFBSSU9SSVRZXG4gICAgYWRkVW5pdFByaW9yaXR5KCdkYXRlJywgOSk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdEJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignREQnLCBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignRG8nLCBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICAvLyBUT0RPOiBSZW1vdmUgXCJvcmRpbmFsUGFyc2VcIiBmYWxsYmFjayBpbiBuZXh0IG1ham9yIHJlbGVhc2UuXG4gICAgICAgIHJldHVybiBpc1N0cmljdCA/XG4gICAgICAgICAgKGxvY2FsZS5fZGF5T2ZNb250aE9yZGluYWxQYXJzZSB8fCBsb2NhbGUuX29yZGluYWxQYXJzZSkgOlxuICAgICAgICAgIGxvY2FsZS5fZGF5T2ZNb250aE9yZGluYWxQYXJzZUxlbmllbnQ7XG4gICAgfSk7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnRCcsICdERCddLCBEQVRFKTtcbiAgICBhZGRQYXJzZVRva2VuKCdEbycsIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbREFURV0gPSB0b0ludChpbnB1dC5tYXRjaChtYXRjaDF0bzIpWzBdKTtcbiAgICB9KTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIHZhciBnZXRTZXREYXlPZk1vbnRoID0gbWFrZUdldFNldCgnRGF0ZScsIHRydWUpO1xuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ0RERCcsIFsnRERERCcsIDNdLCAnREREbycsICdkYXlPZlllYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnZGF5T2ZZZWFyJywgJ0RERCcpO1xuXG4gICAgLy8gUFJJT1JJVFlcbiAgICBhZGRVbml0UHJpb3JpdHkoJ2RheU9mWWVhcicsIDQpO1xuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbignREREJywgIG1hdGNoMXRvMyk7XG4gICAgYWRkUmVnZXhUb2tlbignRERERCcsIG1hdGNoMyk7XG4gICAgYWRkUGFyc2VUb2tlbihbJ0RERCcsICdEREREJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2RheU9mWWVhciA9IHRvSW50KGlucHV0KTtcbiAgICB9KTtcblxuICAgIC8vIEhFTFBFUlNcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFNldERheU9mWWVhciAoaW5wdXQpIHtcbiAgICAgICAgdmFyIGRheU9mWWVhciA9IE1hdGgucm91bmQoKHRoaXMuY2xvbmUoKS5zdGFydE9mKCdkYXknKSAtIHRoaXMuY2xvbmUoKS5zdGFydE9mKCd5ZWFyJykpIC8gODY0ZTUpICsgMTtcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyBkYXlPZlllYXIgOiB0aGlzLmFkZCgoaW5wdXQgLSBkYXlPZlllYXIpLCAnZCcpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdtJywgWydtbScsIDJdLCAwLCAnbWludXRlJyk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21pbnV0ZScsICdtJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdtaW51dGUnLCAxNCk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdtJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignbW0nLCBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUGFyc2VUb2tlbihbJ20nLCAnbW0nXSwgTUlOVVRFKTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIHZhciBnZXRTZXRNaW51dGUgPSBtYWtlR2V0U2V0KCdNaW51dGVzJywgZmFsc2UpO1xuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ3MnLCBbJ3NzJywgMl0sIDAsICdzZWNvbmQnKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnc2Vjb25kJywgJ3MnKTtcblxuICAgIC8vIFBSSU9SSVRZXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ3NlY29uZCcsIDE1KTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ3MnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdzcycsIG1hdGNoMXRvMiwgbWF0Y2gyKTtcbiAgICBhZGRQYXJzZVRva2VuKFsncycsICdzcyddLCBTRUNPTkQpO1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgdmFyIGdldFNldFNlY29uZCA9IG1ha2VHZXRTZXQoJ1NlY29uZHMnLCBmYWxzZSk7XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbignUycsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIH5+KHRoaXMubWlsbGlzZWNvbmQoKSAvIDEwMCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTJywgMl0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIH5+KHRoaXMubWlsbGlzZWNvbmQoKSAvIDEwKTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTJywgM10sIDAsICdtaWxsaXNlY29uZCcpO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTUycsIDRdLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTJywgNV0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWlsbGlzZWNvbmQoKSAqIDEwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTUycsIDZdLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwO1xuICAgIH0pO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTU1NTUycsIDddLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTU1NTJywgOF0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWlsbGlzZWNvbmQoKSAqIDEwMDAwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTU1NTUycsIDldLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwMDAwO1xuICAgIH0pO1xuXG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21pbGxpc2Vjb25kJywgJ21zJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdtaWxsaXNlY29uZCcsIDE2KTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1MnLCAgICBtYXRjaDF0bzMsIG1hdGNoMSk7XG4gICAgYWRkUmVnZXhUb2tlbignU1MnLCAgIG1hdGNoMXRvMywgbWF0Y2gyKTtcbiAgICBhZGRSZWdleFRva2VuKCdTU1MnLCAgbWF0Y2gxdG8zLCBtYXRjaDMpO1xuXG4gICAgdmFyIHRva2VuO1xuICAgIGZvciAodG9rZW4gPSAnU1NTUyc7IHRva2VuLmxlbmd0aCA8PSA5OyB0b2tlbiArPSAnUycpIHtcbiAgICAgICAgYWRkUmVnZXhUb2tlbih0b2tlbiwgbWF0Y2hVbnNpZ25lZCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VNcyhpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbTUlMTElTRUNPTkRdID0gdG9JbnQoKCcwLicgKyBpbnB1dCkgKiAxMDAwKTtcbiAgICB9XG5cbiAgICBmb3IgKHRva2VuID0gJ1MnOyB0b2tlbi5sZW5ndGggPD0gOTsgdG9rZW4gKz0gJ1MnKSB7XG4gICAgICAgIGFkZFBhcnNlVG9rZW4odG9rZW4sIHBhcnNlTXMpO1xuICAgIH1cbiAgICAvLyBNT01FTlRTXG5cbiAgICB2YXIgZ2V0U2V0TWlsbGlzZWNvbmQgPSBtYWtlR2V0U2V0KCdNaWxsaXNlY29uZHMnLCBmYWxzZSk7XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigneicsICAwLCAwLCAnem9uZUFiYnInKTtcbiAgICBhZGRGb3JtYXRUb2tlbignenonLCAwLCAwLCAnem9uZU5hbWUnKTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFpvbmVBYmJyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzVVRDID8gJ1VUQycgOiAnJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRab25lTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/ICdDb29yZGluYXRlZCBVbml2ZXJzYWwgVGltZScgOiAnJztcbiAgICB9XG5cbiAgICB2YXIgcHJvdG8gPSBNb21lbnQucHJvdG90eXBlO1xuXG4gICAgcHJvdG8uYWRkICAgICAgICAgICAgICAgPSBhZGQ7XG4gICAgcHJvdG8uY2FsZW5kYXIgICAgICAgICAgPSBjYWxlbmRhciQxO1xuICAgIHByb3RvLmNsb25lICAgICAgICAgICAgID0gY2xvbmU7XG4gICAgcHJvdG8uZGlmZiAgICAgICAgICAgICAgPSBkaWZmO1xuICAgIHByb3RvLmVuZE9mICAgICAgICAgICAgID0gZW5kT2Y7XG4gICAgcHJvdG8uZm9ybWF0ICAgICAgICAgICAgPSBmb3JtYXQ7XG4gICAgcHJvdG8uZnJvbSAgICAgICAgICAgICAgPSBmcm9tO1xuICAgIHByb3RvLmZyb21Ob3cgICAgICAgICAgID0gZnJvbU5vdztcbiAgICBwcm90by50byAgICAgICAgICAgICAgICA9IHRvO1xuICAgIHByb3RvLnRvTm93ICAgICAgICAgICAgID0gdG9Ob3c7XG4gICAgcHJvdG8uZ2V0ICAgICAgICAgICAgICAgPSBzdHJpbmdHZXQ7XG4gICAgcHJvdG8uaW52YWxpZEF0ICAgICAgICAgPSBpbnZhbGlkQXQ7XG4gICAgcHJvdG8uaXNBZnRlciAgICAgICAgICAgPSBpc0FmdGVyO1xuICAgIHByb3RvLmlzQmVmb3JlICAgICAgICAgID0gaXNCZWZvcmU7XG4gICAgcHJvdG8uaXNCZXR3ZWVuICAgICAgICAgPSBpc0JldHdlZW47XG4gICAgcHJvdG8uaXNTYW1lICAgICAgICAgICAgPSBpc1NhbWU7XG4gICAgcHJvdG8uaXNTYW1lT3JBZnRlciAgICAgPSBpc1NhbWVPckFmdGVyO1xuICAgIHByb3RvLmlzU2FtZU9yQmVmb3JlICAgID0gaXNTYW1lT3JCZWZvcmU7XG4gICAgcHJvdG8uaXNWYWxpZCAgICAgICAgICAgPSBpc1ZhbGlkJDI7XG4gICAgcHJvdG8ubGFuZyAgICAgICAgICAgICAgPSBsYW5nO1xuICAgIHByb3RvLmxvY2FsZSAgICAgICAgICAgID0gbG9jYWxlO1xuICAgIHByb3RvLmxvY2FsZURhdGEgICAgICAgID0gbG9jYWxlRGF0YTtcbiAgICBwcm90by5tYXggICAgICAgICAgICAgICA9IHByb3RvdHlwZU1heDtcbiAgICBwcm90by5taW4gICAgICAgICAgICAgICA9IHByb3RvdHlwZU1pbjtcbiAgICBwcm90by5wYXJzaW5nRmxhZ3MgICAgICA9IHBhcnNpbmdGbGFncztcbiAgICBwcm90by5zZXQgICAgICAgICAgICAgICA9IHN0cmluZ1NldDtcbiAgICBwcm90by5zdGFydE9mICAgICAgICAgICA9IHN0YXJ0T2Y7XG4gICAgcHJvdG8uc3VidHJhY3QgICAgICAgICAgPSBzdWJ0cmFjdDtcbiAgICBwcm90by50b0FycmF5ICAgICAgICAgICA9IHRvQXJyYXk7XG4gICAgcHJvdG8udG9PYmplY3QgICAgICAgICAgPSB0b09iamVjdDtcbiAgICBwcm90by50b0RhdGUgICAgICAgICAgICA9IHRvRGF0ZTtcbiAgICBwcm90by50b0lTT1N0cmluZyAgICAgICA9IHRvSVNPU3RyaW5nO1xuICAgIHByb3RvLmluc3BlY3QgICAgICAgICAgID0gaW5zcGVjdDtcbiAgICBwcm90by50b0pTT04gICAgICAgICAgICA9IHRvSlNPTjtcbiAgICBwcm90by50b1N0cmluZyAgICAgICAgICA9IHRvU3RyaW5nO1xuICAgIHByb3RvLnVuaXggICAgICAgICAgICAgID0gdW5peDtcbiAgICBwcm90by52YWx1ZU9mICAgICAgICAgICA9IHZhbHVlT2Y7XG4gICAgcHJvdG8uY3JlYXRpb25EYXRhICAgICAgPSBjcmVhdGlvbkRhdGE7XG4gICAgcHJvdG8ueWVhciAgICAgICA9IGdldFNldFllYXI7XG4gICAgcHJvdG8uaXNMZWFwWWVhciA9IGdldElzTGVhcFllYXI7XG4gICAgcHJvdG8ud2Vla1llYXIgICAgPSBnZXRTZXRXZWVrWWVhcjtcbiAgICBwcm90by5pc29XZWVrWWVhciA9IGdldFNldElTT1dlZWtZZWFyO1xuICAgIHByb3RvLnF1YXJ0ZXIgPSBwcm90by5xdWFydGVycyA9IGdldFNldFF1YXJ0ZXI7XG4gICAgcHJvdG8ubW9udGggICAgICAgPSBnZXRTZXRNb250aDtcbiAgICBwcm90by5kYXlzSW5Nb250aCA9IGdldERheXNJbk1vbnRoO1xuICAgIHByb3RvLndlZWsgICAgICAgICAgID0gcHJvdG8ud2Vla3MgICAgICAgID0gZ2V0U2V0V2VlaztcbiAgICBwcm90by5pc29XZWVrICAgICAgICA9IHByb3RvLmlzb1dlZWtzICAgICA9IGdldFNldElTT1dlZWs7XG4gICAgcHJvdG8ud2Vla3NJblllYXIgICAgPSBnZXRXZWVrc0luWWVhcjtcbiAgICBwcm90by5pc29XZWVrc0luWWVhciA9IGdldElTT1dlZWtzSW5ZZWFyO1xuICAgIHByb3RvLmRhdGUgICAgICAgPSBnZXRTZXREYXlPZk1vbnRoO1xuICAgIHByb3RvLmRheSAgICAgICAgPSBwcm90by5kYXlzICAgICAgICAgICAgID0gZ2V0U2V0RGF5T2ZXZWVrO1xuICAgIHByb3RvLndlZWtkYXkgICAgPSBnZXRTZXRMb2NhbGVEYXlPZldlZWs7XG4gICAgcHJvdG8uaXNvV2Vla2RheSA9IGdldFNldElTT0RheU9mV2VlaztcbiAgICBwcm90by5kYXlPZlllYXIgID0gZ2V0U2V0RGF5T2ZZZWFyO1xuICAgIHByb3RvLmhvdXIgPSBwcm90by5ob3VycyA9IGdldFNldEhvdXI7XG4gICAgcHJvdG8ubWludXRlID0gcHJvdG8ubWludXRlcyA9IGdldFNldE1pbnV0ZTtcbiAgICBwcm90by5zZWNvbmQgPSBwcm90by5zZWNvbmRzID0gZ2V0U2V0U2Vjb25kO1xuICAgIHByb3RvLm1pbGxpc2Vjb25kID0gcHJvdG8ubWlsbGlzZWNvbmRzID0gZ2V0U2V0TWlsbGlzZWNvbmQ7XG4gICAgcHJvdG8udXRjT2Zmc2V0ICAgICAgICAgICAgPSBnZXRTZXRPZmZzZXQ7XG4gICAgcHJvdG8udXRjICAgICAgICAgICAgICAgICAgPSBzZXRPZmZzZXRUb1VUQztcbiAgICBwcm90by5sb2NhbCAgICAgICAgICAgICAgICA9IHNldE9mZnNldFRvTG9jYWw7XG4gICAgcHJvdG8ucGFyc2Vab25lICAgICAgICAgICAgPSBzZXRPZmZzZXRUb1BhcnNlZE9mZnNldDtcbiAgICBwcm90by5oYXNBbGlnbmVkSG91ck9mZnNldCA9IGhhc0FsaWduZWRIb3VyT2Zmc2V0O1xuICAgIHByb3RvLmlzRFNUICAgICAgICAgICAgICAgID0gaXNEYXlsaWdodFNhdmluZ1RpbWU7XG4gICAgcHJvdG8uaXNMb2NhbCAgICAgICAgICAgICAgPSBpc0xvY2FsO1xuICAgIHByb3RvLmlzVXRjT2Zmc2V0ICAgICAgICAgID0gaXNVdGNPZmZzZXQ7XG4gICAgcHJvdG8uaXNVdGMgICAgICAgICAgICAgICAgPSBpc1V0YztcbiAgICBwcm90by5pc1VUQyAgICAgICAgICAgICAgICA9IGlzVXRjO1xuICAgIHByb3RvLnpvbmVBYmJyID0gZ2V0Wm9uZUFiYnI7XG4gICAgcHJvdG8uem9uZU5hbWUgPSBnZXRab25lTmFtZTtcbiAgICBwcm90by5kYXRlcyAgPSBkZXByZWNhdGUoJ2RhdGVzIGFjY2Vzc29yIGlzIGRlcHJlY2F0ZWQuIFVzZSBkYXRlIGluc3RlYWQuJywgZ2V0U2V0RGF5T2ZNb250aCk7XG4gICAgcHJvdG8ubW9udGhzID0gZGVwcmVjYXRlKCdtb250aHMgYWNjZXNzb3IgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbnRoIGluc3RlYWQnLCBnZXRTZXRNb250aCk7XG4gICAgcHJvdG8ueWVhcnMgID0gZGVwcmVjYXRlKCd5ZWFycyBhY2Nlc3NvciBpcyBkZXByZWNhdGVkLiBVc2UgeWVhciBpbnN0ZWFkJywgZ2V0U2V0WWVhcik7XG4gICAgcHJvdG8uem9uZSAgID0gZGVwcmVjYXRlKCdtb21lbnQoKS56b25lIGlzIGRlcHJlY2F0ZWQsIHVzZSBtb21lbnQoKS51dGNPZmZzZXQgaW5zdGVhZC4gaHR0cDovL21vbWVudGpzLmNvbS9ndWlkZXMvIy93YXJuaW5ncy96b25lLycsIGdldFNldFpvbmUpO1xuICAgIHByb3RvLmlzRFNUU2hpZnRlZCA9IGRlcHJlY2F0ZSgnaXNEU1RTaGlmdGVkIGlzIGRlcHJlY2F0ZWQuIFNlZSBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2RzdC1zaGlmdGVkLyBmb3IgbW9yZSBpbmZvcm1hdGlvbicsIGlzRGF5bGlnaHRTYXZpbmdUaW1lU2hpZnRlZCk7XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVVbml4IChpbnB1dCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwoaW5wdXQgKiAxMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVJblpvbmUgKCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwuYXBwbHkobnVsbCwgYXJndW1lbnRzKS5wYXJzZVpvbmUoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVQYXJzZVBvc3RGb3JtYXQgKHN0cmluZykge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgIH1cblxuICAgIHZhciBwcm90byQxID0gTG9jYWxlLnByb3RvdHlwZTtcblxuICAgIHByb3RvJDEuY2FsZW5kYXIgICAgICAgID0gY2FsZW5kYXI7XG4gICAgcHJvdG8kMS5sb25nRGF0ZUZvcm1hdCAgPSBsb25nRGF0ZUZvcm1hdDtcbiAgICBwcm90byQxLmludmFsaWREYXRlICAgICA9IGludmFsaWREYXRlO1xuICAgIHByb3RvJDEub3JkaW5hbCAgICAgICAgID0gb3JkaW5hbDtcbiAgICBwcm90byQxLnByZXBhcnNlICAgICAgICA9IHByZVBhcnNlUG9zdEZvcm1hdDtcbiAgICBwcm90byQxLnBvc3Rmb3JtYXQgICAgICA9IHByZVBhcnNlUG9zdEZvcm1hdDtcbiAgICBwcm90byQxLnJlbGF0aXZlVGltZSAgICA9IHJlbGF0aXZlVGltZTtcbiAgICBwcm90byQxLnBhc3RGdXR1cmUgICAgICA9IHBhc3RGdXR1cmU7XG4gICAgcHJvdG8kMS5zZXQgICAgICAgICAgICAgPSBzZXQ7XG5cbiAgICBwcm90byQxLm1vbnRocyAgICAgICAgICAgID0gICAgICAgIGxvY2FsZU1vbnRocztcbiAgICBwcm90byQxLm1vbnRoc1Nob3J0ICAgICAgID0gICAgICAgIGxvY2FsZU1vbnRoc1Nob3J0O1xuICAgIHByb3RvJDEubW9udGhzUGFyc2UgICAgICAgPSAgICAgICAgbG9jYWxlTW9udGhzUGFyc2U7XG4gICAgcHJvdG8kMS5tb250aHNSZWdleCAgICAgICA9IG1vbnRoc1JlZ2V4O1xuICAgIHByb3RvJDEubW9udGhzU2hvcnRSZWdleCAgPSBtb250aHNTaG9ydFJlZ2V4O1xuICAgIHByb3RvJDEud2VlayA9IGxvY2FsZVdlZWs7XG4gICAgcHJvdG8kMS5maXJzdERheU9mWWVhciA9IGxvY2FsZUZpcnN0RGF5T2ZZZWFyO1xuICAgIHByb3RvJDEuZmlyc3REYXlPZldlZWsgPSBsb2NhbGVGaXJzdERheU9mV2VlaztcblxuICAgIHByb3RvJDEud2Vla2RheXMgICAgICAgPSAgICAgICAgbG9jYWxlV2Vla2RheXM7XG4gICAgcHJvdG8kMS53ZWVrZGF5c01pbiAgICA9ICAgICAgICBsb2NhbGVXZWVrZGF5c01pbjtcbiAgICBwcm90byQxLndlZWtkYXlzU2hvcnQgID0gICAgICAgIGxvY2FsZVdlZWtkYXlzU2hvcnQ7XG4gICAgcHJvdG8kMS53ZWVrZGF5c1BhcnNlICA9ICAgICAgICBsb2NhbGVXZWVrZGF5c1BhcnNlO1xuXG4gICAgcHJvdG8kMS53ZWVrZGF5c1JlZ2V4ICAgICAgID0gICAgICAgIHdlZWtkYXlzUmVnZXg7XG4gICAgcHJvdG8kMS53ZWVrZGF5c1Nob3J0UmVnZXggID0gICAgICAgIHdlZWtkYXlzU2hvcnRSZWdleDtcbiAgICBwcm90byQxLndlZWtkYXlzTWluUmVnZXggICAgPSAgICAgICAgd2Vla2RheXNNaW5SZWdleDtcblxuICAgIHByb3RvJDEuaXNQTSA9IGxvY2FsZUlzUE07XG4gICAgcHJvdG8kMS5tZXJpZGllbSA9IGxvY2FsZU1lcmlkaWVtO1xuXG4gICAgZnVuY3Rpb24gZ2V0JDEgKGZvcm1hdCwgaW5kZXgsIGZpZWxkLCBzZXR0ZXIpIHtcbiAgICAgICAgdmFyIGxvY2FsZSA9IGdldExvY2FsZSgpO1xuICAgICAgICB2YXIgdXRjID0gY3JlYXRlVVRDKCkuc2V0KHNldHRlciwgaW5kZXgpO1xuICAgICAgICByZXR1cm4gbG9jYWxlW2ZpZWxkXSh1dGMsIGZvcm1hdCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdE1vbnRoc0ltcGwgKGZvcm1hdCwgaW5kZXgsIGZpZWxkKSB7XG4gICAgICAgIGlmIChpc051bWJlcihmb3JtYXQpKSB7XG4gICAgICAgICAgICBpbmRleCA9IGZvcm1hdDtcbiAgICAgICAgICAgIGZvcm1hdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvcm1hdCA9IGZvcm1hdCB8fCAnJztcblxuICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldCQxKGZvcm1hdCwgaW5kZXgsIGZpZWxkLCAnbW9udGgnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgb3V0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG4gICAgICAgICAgICBvdXRbaV0gPSBnZXQkMShmb3JtYXQsIGksIGZpZWxkLCAnbW9udGgnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH1cblxuICAgIC8vICgpXG4gICAgLy8gKDUpXG4gICAgLy8gKGZtdCwgNSlcbiAgICAvLyAoZm10KVxuICAgIC8vICh0cnVlKVxuICAgIC8vICh0cnVlLCA1KVxuICAgIC8vICh0cnVlLCBmbXQsIDUpXG4gICAgLy8gKHRydWUsIGZtdClcbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNJbXBsIChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgsIGZpZWxkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbG9jYWxlU29ydGVkID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIGlmIChpc051bWJlcihmb3JtYXQpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBmb3JtYXQ7XG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3JtYXQgPSBmb3JtYXQgfHwgJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3JtYXQgPSBsb2NhbGVTb3J0ZWQ7XG4gICAgICAgICAgICBpbmRleCA9IGZvcm1hdDtcbiAgICAgICAgICAgIGxvY2FsZVNvcnRlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoaXNOdW1iZXIoZm9ybWF0KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gZm9ybWF0O1xuICAgICAgICAgICAgICAgIGZvcm1hdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9ybWF0ID0gZm9ybWF0IHx8ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGxvY2FsZSA9IGdldExvY2FsZSgpLFxuICAgICAgICAgICAgc2hpZnQgPSBsb2NhbGVTb3J0ZWQgPyBsb2NhbGUuX3dlZWsuZG93IDogMDtcblxuICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldCQxKGZvcm1hdCwgKGluZGV4ICsgc2hpZnQpICUgNywgZmllbGQsICdkYXknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgb3V0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIG91dFtpXSA9IGdldCQxKGZvcm1hdCwgKGkgKyBzaGlmdCkgJSA3LCBmaWVsZCwgJ2RheScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdE1vbnRocyAoZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdE1vbnRoc0ltcGwoZm9ybWF0LCBpbmRleCwgJ21vbnRocycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpc3RNb250aHNTaG9ydCAoZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdE1vbnRoc0ltcGwoZm9ybWF0LCBpbmRleCwgJ21vbnRoc1Nob3J0Jyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdFdlZWtkYXlzIChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGxpc3RXZWVrZGF5c0ltcGwobG9jYWxlU29ydGVkLCBmb3JtYXQsIGluZGV4LCAnd2Vla2RheXMnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNTaG9ydCAobG9jYWxlU29ydGVkLCBmb3JtYXQsIGluZGV4KSB7XG4gICAgICAgIHJldHVybiBsaXN0V2Vla2RheXNJbXBsKGxvY2FsZVNvcnRlZCwgZm9ybWF0LCBpbmRleCwgJ3dlZWtkYXlzU2hvcnQnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNNaW4gKGxvY2FsZVNvcnRlZCwgZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdFdlZWtkYXlzSW1wbChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgsICd3ZWVrZGF5c01pbicpO1xuICAgIH1cblxuICAgIGdldFNldEdsb2JhbExvY2FsZSgnZW4nLCB7XG4gICAgICAgIGRheU9mTW9udGhPcmRpbmFsUGFyc2U6IC9cXGR7MSwyfSh0aHxzdHxuZHxyZCkvLFxuICAgICAgICBvcmRpbmFsIDogZnVuY3Rpb24gKG51bWJlcikge1xuICAgICAgICAgICAgdmFyIGIgPSBudW1iZXIgJSAxMCxcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSAodG9JbnQobnVtYmVyICUgMTAwIC8gMTApID09PSAxKSA/ICd0aCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAxKSA/ICdzdCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAyKSA/ICduZCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAzKSA/ICdyZCcgOiAndGgnO1xuICAgICAgICAgICAgcmV0dXJuIG51bWJlciArIG91dHB1dDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gU2lkZSBlZmZlY3QgaW1wb3J0c1xuXG4gICAgaG9va3MubGFuZyA9IGRlcHJlY2F0ZSgnbW9tZW50LmxhbmcgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGUgaW5zdGVhZC4nLCBnZXRTZXRHbG9iYWxMb2NhbGUpO1xuICAgIGhvb2tzLmxhbmdEYXRhID0gZGVwcmVjYXRlKCdtb21lbnQubGFuZ0RhdGEgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGVEYXRhIGluc3RlYWQuJywgZ2V0TG9jYWxlKTtcblxuICAgIHZhciBtYXRoQWJzID0gTWF0aC5hYnM7XG5cbiAgICBmdW5jdGlvbiBhYnMgKCkge1xuICAgICAgICB2YXIgZGF0YSAgICAgICAgICAgPSB0aGlzLl9kYXRhO1xuXG4gICAgICAgIHRoaXMuX21pbGxpc2Vjb25kcyA9IG1hdGhBYnModGhpcy5fbWlsbGlzZWNvbmRzKTtcbiAgICAgICAgdGhpcy5fZGF5cyAgICAgICAgID0gbWF0aEFicyh0aGlzLl9kYXlzKTtcbiAgICAgICAgdGhpcy5fbW9udGhzICAgICAgID0gbWF0aEFicyh0aGlzLl9tb250aHMpO1xuXG4gICAgICAgIGRhdGEubWlsbGlzZWNvbmRzICA9IG1hdGhBYnMoZGF0YS5taWxsaXNlY29uZHMpO1xuICAgICAgICBkYXRhLnNlY29uZHMgICAgICAgPSBtYXRoQWJzKGRhdGEuc2Vjb25kcyk7XG4gICAgICAgIGRhdGEubWludXRlcyAgICAgICA9IG1hdGhBYnMoZGF0YS5taW51dGVzKTtcbiAgICAgICAgZGF0YS5ob3VycyAgICAgICAgID0gbWF0aEFicyhkYXRhLmhvdXJzKTtcbiAgICAgICAgZGF0YS5tb250aHMgICAgICAgID0gbWF0aEFicyhkYXRhLm1vbnRocyk7XG4gICAgICAgIGRhdGEueWVhcnMgICAgICAgICA9IG1hdGhBYnMoZGF0YS55ZWFycyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWRkU3VidHJhY3QkMSAoZHVyYXRpb24sIGlucHV0LCB2YWx1ZSwgZGlyZWN0aW9uKSB7XG4gICAgICAgIHZhciBvdGhlciA9IGNyZWF0ZUR1cmF0aW9uKGlucHV0LCB2YWx1ZSk7XG5cbiAgICAgICAgZHVyYXRpb24uX21pbGxpc2Vjb25kcyArPSBkaXJlY3Rpb24gKiBvdGhlci5fbWlsbGlzZWNvbmRzO1xuICAgICAgICBkdXJhdGlvbi5fZGF5cyAgICAgICAgICs9IGRpcmVjdGlvbiAqIG90aGVyLl9kYXlzO1xuICAgICAgICBkdXJhdGlvbi5fbW9udGhzICAgICAgICs9IGRpcmVjdGlvbiAqIG90aGVyLl9tb250aHM7XG5cbiAgICAgICAgcmV0dXJuIGR1cmF0aW9uLl9idWJibGUoKTtcbiAgICB9XG5cbiAgICAvLyBzdXBwb3J0cyBvbmx5IDIuMC1zdHlsZSBhZGQoMSwgJ3MnKSBvciBhZGQoZHVyYXRpb24pXG4gICAgZnVuY3Rpb24gYWRkJDEgKGlucHV0LCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gYWRkU3VidHJhY3QkMSh0aGlzLCBpbnB1dCwgdmFsdWUsIDEpO1xuICAgIH1cblxuICAgIC8vIHN1cHBvcnRzIG9ubHkgMi4wLXN0eWxlIHN1YnRyYWN0KDEsICdzJykgb3Igc3VidHJhY3QoZHVyYXRpb24pXG4gICAgZnVuY3Rpb24gc3VidHJhY3QkMSAoaW5wdXQsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBhZGRTdWJ0cmFjdCQxKHRoaXMsIGlucHV0LCB2YWx1ZSwgLTEpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFic0NlaWwgKG51bWJlcikge1xuICAgICAgICBpZiAobnVtYmVyIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IobnVtYmVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmNlaWwobnVtYmVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJ1YmJsZSAoKSB7XG4gICAgICAgIHZhciBtaWxsaXNlY29uZHMgPSB0aGlzLl9taWxsaXNlY29uZHM7XG4gICAgICAgIHZhciBkYXlzICAgICAgICAgPSB0aGlzLl9kYXlzO1xuICAgICAgICB2YXIgbW9udGhzICAgICAgID0gdGhpcy5fbW9udGhzO1xuICAgICAgICB2YXIgZGF0YSAgICAgICAgID0gdGhpcy5fZGF0YTtcbiAgICAgICAgdmFyIHNlY29uZHMsIG1pbnV0ZXMsIGhvdXJzLCB5ZWFycywgbW9udGhzRnJvbURheXM7XG5cbiAgICAgICAgLy8gaWYgd2UgaGF2ZSBhIG1peCBvZiBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgdmFsdWVzLCBidWJibGUgZG93biBmaXJzdFxuICAgICAgICAvLyBjaGVjazogaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzIxNjZcbiAgICAgICAgaWYgKCEoKG1pbGxpc2Vjb25kcyA+PSAwICYmIGRheXMgPj0gMCAmJiBtb250aHMgPj0gMCkgfHxcbiAgICAgICAgICAgICAgICAobWlsbGlzZWNvbmRzIDw9IDAgJiYgZGF5cyA8PSAwICYmIG1vbnRocyA8PSAwKSkpIHtcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kcyArPSBhYnNDZWlsKG1vbnRoc1RvRGF5cyhtb250aHMpICsgZGF5cykgKiA4NjRlNTtcbiAgICAgICAgICAgIGRheXMgPSAwO1xuICAgICAgICAgICAgbW9udGhzID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgY29kZSBidWJibGVzIHVwIHZhbHVlcywgc2VlIHRoZSB0ZXN0cyBmb3JcbiAgICAgICAgLy8gZXhhbXBsZXMgb2Ygd2hhdCB0aGF0IG1lYW5zLlxuICAgICAgICBkYXRhLm1pbGxpc2Vjb25kcyA9IG1pbGxpc2Vjb25kcyAlIDEwMDA7XG5cbiAgICAgICAgc2Vjb25kcyAgICAgICAgICAgPSBhYnNGbG9vcihtaWxsaXNlY29uZHMgLyAxMDAwKTtcbiAgICAgICAgZGF0YS5zZWNvbmRzICAgICAgPSBzZWNvbmRzICUgNjA7XG5cbiAgICAgICAgbWludXRlcyAgICAgICAgICAgPSBhYnNGbG9vcihzZWNvbmRzIC8gNjApO1xuICAgICAgICBkYXRhLm1pbnV0ZXMgICAgICA9IG1pbnV0ZXMgJSA2MDtcblxuICAgICAgICBob3VycyAgICAgICAgICAgICA9IGFic0Zsb29yKG1pbnV0ZXMgLyA2MCk7XG4gICAgICAgIGRhdGEuaG91cnMgICAgICAgID0gaG91cnMgJSAyNDtcblxuICAgICAgICBkYXlzICs9IGFic0Zsb29yKGhvdXJzIC8gMjQpO1xuXG4gICAgICAgIC8vIGNvbnZlcnQgZGF5cyB0byBtb250aHNcbiAgICAgICAgbW9udGhzRnJvbURheXMgPSBhYnNGbG9vcihkYXlzVG9Nb250aHMoZGF5cykpO1xuICAgICAgICBtb250aHMgKz0gbW9udGhzRnJvbURheXM7XG4gICAgICAgIGRheXMgLT0gYWJzQ2VpbChtb250aHNUb0RheXMobW9udGhzRnJvbURheXMpKTtcblxuICAgICAgICAvLyAxMiBtb250aHMgLT4gMSB5ZWFyXG4gICAgICAgIHllYXJzID0gYWJzRmxvb3IobW9udGhzIC8gMTIpO1xuICAgICAgICBtb250aHMgJT0gMTI7XG5cbiAgICAgICAgZGF0YS5kYXlzICAgPSBkYXlzO1xuICAgICAgICBkYXRhLm1vbnRocyA9IG1vbnRocztcbiAgICAgICAgZGF0YS55ZWFycyAgPSB5ZWFycztcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlzVG9Nb250aHMgKGRheXMpIHtcbiAgICAgICAgLy8gNDAwIHllYXJzIGhhdmUgMTQ2MDk3IGRheXMgKHRha2luZyBpbnRvIGFjY291bnQgbGVhcCB5ZWFyIHJ1bGVzKVxuICAgICAgICAvLyA0MDAgeWVhcnMgaGF2ZSAxMiBtb250aHMgPT09IDQ4MDBcbiAgICAgICAgcmV0dXJuIGRheXMgKiA0ODAwIC8gMTQ2MDk3O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1vbnRoc1RvRGF5cyAobW9udGhzKSB7XG4gICAgICAgIC8vIHRoZSByZXZlcnNlIG9mIGRheXNUb01vbnRoc1xuICAgICAgICByZXR1cm4gbW9udGhzICogMTQ2MDk3IC8gNDgwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhcyAodW5pdHMpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIE5hTjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF5cztcbiAgICAgICAgdmFyIG1vbnRocztcbiAgICAgICAgdmFyIG1pbGxpc2Vjb25kcyA9IHRoaXMuX21pbGxpc2Vjb25kcztcblxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICBpZiAodW5pdHMgPT09ICdtb250aCcgfHwgdW5pdHMgPT09ICdxdWFydGVyJyB8fCB1bml0cyA9PT0gJ3llYXInKSB7XG4gICAgICAgICAgICBkYXlzID0gdGhpcy5fZGF5cyArIG1pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgbW9udGhzID0gdGhpcy5fbW9udGhzICsgZGF5c1RvTW9udGhzKGRheXMpO1xuICAgICAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgICAgIGNhc2UgJ21vbnRoJzogICByZXR1cm4gbW9udGhzO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3F1YXJ0ZXInOiByZXR1cm4gbW9udGhzIC8gMztcbiAgICAgICAgICAgICAgICBjYXNlICd5ZWFyJzogICAgcmV0dXJuIG1vbnRocyAvIDEyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaGFuZGxlIG1pbGxpc2Vjb25kcyBzZXBhcmF0ZWx5IGJlY2F1c2Ugb2YgZmxvYXRpbmcgcG9pbnQgbWF0aCBlcnJvcnMgKGlzc3VlICMxODY3KVxuICAgICAgICAgICAgZGF5cyA9IHRoaXMuX2RheXMgKyBNYXRoLnJvdW5kKG1vbnRoc1RvRGF5cyh0aGlzLl9tb250aHMpKTtcbiAgICAgICAgICAgIHN3aXRjaCAodW5pdHMpIHtcbiAgICAgICAgICAgICAgICBjYXNlICd3ZWVrJyAgIDogcmV0dXJuIGRheXMgLyA3ICAgICArIG1pbGxpc2Vjb25kcyAvIDYwNDhlNTtcbiAgICAgICAgICAgICAgICBjYXNlICdkYXknICAgIDogcmV0dXJuIGRheXMgICAgICAgICArIG1pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgICAgIGNhc2UgJ2hvdXInICAgOiByZXR1cm4gZGF5cyAqIDI0ICAgICsgbWlsbGlzZWNvbmRzIC8gMzZlNTtcbiAgICAgICAgICAgICAgICBjYXNlICdtaW51dGUnIDogcmV0dXJuIGRheXMgKiAxNDQwICArIG1pbGxpc2Vjb25kcyAvIDZlNDtcbiAgICAgICAgICAgICAgICBjYXNlICdzZWNvbmQnIDogcmV0dXJuIGRheXMgKiA4NjQwMCArIG1pbGxpc2Vjb25kcyAvIDEwMDA7XG4gICAgICAgICAgICAgICAgLy8gTWF0aC5mbG9vciBwcmV2ZW50cyBmbG9hdGluZyBwb2ludCBtYXRoIGVycm9ycyBoZXJlXG4gICAgICAgICAgICAgICAgY2FzZSAnbWlsbGlzZWNvbmQnOiByZXR1cm4gTWF0aC5mbG9vcihkYXlzICogODY0ZTUpICsgbWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcignVW5rbm93biB1bml0ICcgKyB1bml0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPOiBVc2UgdGhpcy5hcygnbXMnKT9cbiAgICBmdW5jdGlvbiB2YWx1ZU9mJDEgKCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgK1xuICAgICAgICAgICAgdGhpcy5fZGF5cyAqIDg2NGU1ICtcbiAgICAgICAgICAgICh0aGlzLl9tb250aHMgJSAxMikgKiAyNTkyZTYgK1xuICAgICAgICAgICAgdG9JbnQodGhpcy5fbW9udGhzIC8gMTIpICogMzE1MzZlNlxuICAgICAgICApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VBcyAoYWxpYXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFzKGFsaWFzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgYXNNaWxsaXNlY29uZHMgPSBtYWtlQXMoJ21zJyk7XG4gICAgdmFyIGFzU2Vjb25kcyAgICAgID0gbWFrZUFzKCdzJyk7XG4gICAgdmFyIGFzTWludXRlcyAgICAgID0gbWFrZUFzKCdtJyk7XG4gICAgdmFyIGFzSG91cnMgICAgICAgID0gbWFrZUFzKCdoJyk7XG4gICAgdmFyIGFzRGF5cyAgICAgICAgID0gbWFrZUFzKCdkJyk7XG4gICAgdmFyIGFzV2Vla3MgICAgICAgID0gbWFrZUFzKCd3Jyk7XG4gICAgdmFyIGFzTW9udGhzICAgICAgID0gbWFrZUFzKCdNJyk7XG4gICAgdmFyIGFzUXVhcnRlcnMgICAgID0gbWFrZUFzKCdRJyk7XG4gICAgdmFyIGFzWWVhcnMgICAgICAgID0gbWFrZUFzKCd5Jyk7XG5cbiAgICBmdW5jdGlvbiBjbG9uZSQxICgpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKHRoaXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldCQyICh1bml0cykge1xuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpc1t1bml0cyArICdzJ10oKSA6IE5hTjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlR2V0dGVyKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmlzVmFsaWQoKSA/IHRoaXMuX2RhdGFbbmFtZV0gOiBOYU47XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIG1pbGxpc2Vjb25kcyA9IG1ha2VHZXR0ZXIoJ21pbGxpc2Vjb25kcycpO1xuICAgIHZhciBzZWNvbmRzICAgICAgPSBtYWtlR2V0dGVyKCdzZWNvbmRzJyk7XG4gICAgdmFyIG1pbnV0ZXMgICAgICA9IG1ha2VHZXR0ZXIoJ21pbnV0ZXMnKTtcbiAgICB2YXIgaG91cnMgICAgICAgID0gbWFrZUdldHRlcignaG91cnMnKTtcbiAgICB2YXIgZGF5cyAgICAgICAgID0gbWFrZUdldHRlcignZGF5cycpO1xuICAgIHZhciBtb250aHMgICAgICAgPSBtYWtlR2V0dGVyKCdtb250aHMnKTtcbiAgICB2YXIgeWVhcnMgICAgICAgID0gbWFrZUdldHRlcigneWVhcnMnKTtcblxuICAgIGZ1bmN0aW9uIHdlZWtzICgpIHtcbiAgICAgICAgcmV0dXJuIGFic0Zsb29yKHRoaXMuZGF5cygpIC8gNyk7XG4gICAgfVxuXG4gICAgdmFyIHJvdW5kID0gTWF0aC5yb3VuZDtcbiAgICB2YXIgdGhyZXNob2xkcyA9IHtcbiAgICAgICAgc3M6IDQ0LCAgICAgICAgIC8vIGEgZmV3IHNlY29uZHMgdG8gc2Vjb25kc1xuICAgICAgICBzIDogNDUsICAgICAgICAgLy8gc2Vjb25kcyB0byBtaW51dGVcbiAgICAgICAgbSA6IDQ1LCAgICAgICAgIC8vIG1pbnV0ZXMgdG8gaG91clxuICAgICAgICBoIDogMjIsICAgICAgICAgLy8gaG91cnMgdG8gZGF5XG4gICAgICAgIGQgOiAyNiwgICAgICAgICAvLyBkYXlzIHRvIG1vbnRoXG4gICAgICAgIE0gOiAxMSAgICAgICAgICAvLyBtb250aHMgdG8geWVhclxuICAgIH07XG5cbiAgICAvLyBoZWxwZXIgZnVuY3Rpb24gZm9yIG1vbWVudC5mbi5mcm9tLCBtb21lbnQuZm4uZnJvbU5vdywgYW5kIG1vbWVudC5kdXJhdGlvbi5mbi5odW1hbml6ZVxuICAgIGZ1bmN0aW9uIHN1YnN0aXR1dGVUaW1lQWdvKHN0cmluZywgbnVtYmVyLCB3aXRob3V0U3VmZml4LCBpc0Z1dHVyZSwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUucmVsYXRpdmVUaW1lKG51bWJlciB8fCAxLCAhIXdpdGhvdXRTdWZmaXgsIHN0cmluZywgaXNGdXR1cmUpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbGF0aXZlVGltZSQxIChwb3NOZWdEdXJhdGlvbiwgd2l0aG91dFN1ZmZpeCwgbG9jYWxlKSB7XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IGNyZWF0ZUR1cmF0aW9uKHBvc05lZ0R1cmF0aW9uKS5hYnMoKTtcbiAgICAgICAgdmFyIHNlY29uZHMgID0gcm91bmQoZHVyYXRpb24uYXMoJ3MnKSk7XG4gICAgICAgIHZhciBtaW51dGVzICA9IHJvdW5kKGR1cmF0aW9uLmFzKCdtJykpO1xuICAgICAgICB2YXIgaG91cnMgICAgPSByb3VuZChkdXJhdGlvbi5hcygnaCcpKTtcbiAgICAgICAgdmFyIGRheXMgICAgID0gcm91bmQoZHVyYXRpb24uYXMoJ2QnKSk7XG4gICAgICAgIHZhciBtb250aHMgICA9IHJvdW5kKGR1cmF0aW9uLmFzKCdNJykpO1xuICAgICAgICB2YXIgeWVhcnMgICAgPSByb3VuZChkdXJhdGlvbi5hcygneScpKTtcblxuICAgICAgICB2YXIgYSA9IHNlY29uZHMgPD0gdGhyZXNob2xkcy5zcyAmJiBbJ3MnLCBzZWNvbmRzXSAgfHxcbiAgICAgICAgICAgICAgICBzZWNvbmRzIDwgdGhyZXNob2xkcy5zICAgJiYgWydzcycsIHNlY29uZHNdIHx8XG4gICAgICAgICAgICAgICAgbWludXRlcyA8PSAxICAgICAgICAgICAgICYmIFsnbSddICAgICAgICAgICB8fFxuICAgICAgICAgICAgICAgIG1pbnV0ZXMgPCB0aHJlc2hvbGRzLm0gICAmJiBbJ21tJywgbWludXRlc10gfHxcbiAgICAgICAgICAgICAgICBob3VycyAgIDw9IDEgICAgICAgICAgICAgJiYgWydoJ10gICAgICAgICAgIHx8XG4gICAgICAgICAgICAgICAgaG91cnMgICA8IHRocmVzaG9sZHMuaCAgICYmIFsnaGgnLCBob3Vyc10gICB8fFxuICAgICAgICAgICAgICAgIGRheXMgICAgPD0gMSAgICAgICAgICAgICAmJiBbJ2QnXSAgICAgICAgICAgfHxcbiAgICAgICAgICAgICAgICBkYXlzICAgIDwgdGhyZXNob2xkcy5kICAgJiYgWydkZCcsIGRheXNdICAgIHx8XG4gICAgICAgICAgICAgICAgbW9udGhzICA8PSAxICAgICAgICAgICAgICYmIFsnTSddICAgICAgICAgICB8fFxuICAgICAgICAgICAgICAgIG1vbnRocyAgPCB0aHJlc2hvbGRzLk0gICAmJiBbJ01NJywgbW9udGhzXSAgfHxcbiAgICAgICAgICAgICAgICB5ZWFycyAgIDw9IDEgICAgICAgICAgICAgJiYgWyd5J10gICAgICAgICAgIHx8IFsneXknLCB5ZWFyc107XG5cbiAgICAgICAgYVsyXSA9IHdpdGhvdXRTdWZmaXg7XG4gICAgICAgIGFbM10gPSArcG9zTmVnRHVyYXRpb24gPiAwO1xuICAgICAgICBhWzRdID0gbG9jYWxlO1xuICAgICAgICByZXR1cm4gc3Vic3RpdHV0ZVRpbWVBZ28uYXBwbHkobnVsbCwgYSk7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHNldCB0aGUgcm91bmRpbmcgZnVuY3Rpb24gZm9yIHJlbGF0aXZlIHRpbWUgc3RyaW5nc1xuICAgIGZ1bmN0aW9uIGdldFNldFJlbGF0aXZlVGltZVJvdW5kaW5nIChyb3VuZGluZ0Z1bmN0aW9uKSB7XG4gICAgICAgIGlmIChyb3VuZGluZ0Z1bmN0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiByb3VuZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mKHJvdW5kaW5nRnVuY3Rpb24pID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByb3VuZCA9IHJvdW5kaW5nRnVuY3Rpb247XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHNldCBhIHRocmVzaG9sZCBmb3IgcmVsYXRpdmUgdGltZSBzdHJpbmdzXG4gICAgZnVuY3Rpb24gZ2V0U2V0UmVsYXRpdmVUaW1lVGhyZXNob2xkICh0aHJlc2hvbGQsIGxpbWl0KSB7XG4gICAgICAgIGlmICh0aHJlc2hvbGRzW3RocmVzaG9sZF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW1pdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhyZXNob2xkc1t0aHJlc2hvbGRdO1xuICAgICAgICB9XG4gICAgICAgIHRocmVzaG9sZHNbdGhyZXNob2xkXSA9IGxpbWl0O1xuICAgICAgICBpZiAodGhyZXNob2xkID09PSAncycpIHtcbiAgICAgICAgICAgIHRocmVzaG9sZHMuc3MgPSBsaW1pdCAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaHVtYW5pemUgKHdpdGhTdWZmaXgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLmludmFsaWREYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbG9jYWxlID0gdGhpcy5sb2NhbGVEYXRhKCk7XG4gICAgICAgIHZhciBvdXRwdXQgPSByZWxhdGl2ZVRpbWUkMSh0aGlzLCAhd2l0aFN1ZmZpeCwgbG9jYWxlKTtcblxuICAgICAgICBpZiAod2l0aFN1ZmZpeCkge1xuICAgICAgICAgICAgb3V0cHV0ID0gbG9jYWxlLnBhc3RGdXR1cmUoK3RoaXMsIG91dHB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbG9jYWxlLnBvc3Rmb3JtYXQob3V0cHV0KTtcbiAgICB9XG5cbiAgICB2YXIgYWJzJDEgPSBNYXRoLmFicztcblxuICAgIGZ1bmN0aW9uIHNpZ24oeCkge1xuICAgICAgICByZXR1cm4gKCh4ID4gMCkgLSAoeCA8IDApKSB8fCAreDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0lTT1N0cmluZyQxKCkge1xuICAgICAgICAvLyBmb3IgSVNPIHN0cmluZ3Mgd2UgZG8gbm90IHVzZSB0aGUgbm9ybWFsIGJ1YmJsaW5nIHJ1bGVzOlxuICAgICAgICAvLyAgKiBtaWxsaXNlY29uZHMgYnViYmxlIHVwIHVudGlsIHRoZXkgYmVjb21lIGhvdXJzXG4gICAgICAgIC8vICAqIGRheXMgZG8gbm90IGJ1YmJsZSBhdCBhbGxcbiAgICAgICAgLy8gICogbW9udGhzIGJ1YmJsZSB1cCB1bnRpbCB0aGV5IGJlY29tZSB5ZWFyc1xuICAgICAgICAvLyBUaGlzIGlzIGJlY2F1c2UgdGhlcmUgaXMgbm8gY29udGV4dC1mcmVlIGNvbnZlcnNpb24gYmV0d2VlbiBob3VycyBhbmQgZGF5c1xuICAgICAgICAvLyAodGhpbmsgb2YgY2xvY2sgY2hhbmdlcylcbiAgICAgICAgLy8gYW5kIGFsc28gbm90IGJldHdlZW4gZGF5cyBhbmQgbW9udGhzICgyOC0zMSBkYXlzIHBlciBtb250aClcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLmludmFsaWREYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc2Vjb25kcyA9IGFicyQxKHRoaXMuX21pbGxpc2Vjb25kcykgLyAxMDAwO1xuICAgICAgICB2YXIgZGF5cyAgICAgICAgID0gYWJzJDEodGhpcy5fZGF5cyk7XG4gICAgICAgIHZhciBtb250aHMgICAgICAgPSBhYnMkMSh0aGlzLl9tb250aHMpO1xuICAgICAgICB2YXIgbWludXRlcywgaG91cnMsIHllYXJzO1xuXG4gICAgICAgIC8vIDM2MDAgc2Vjb25kcyAtPiA2MCBtaW51dGVzIC0+IDEgaG91clxuICAgICAgICBtaW51dGVzICAgICAgICAgICA9IGFic0Zsb29yKHNlY29uZHMgLyA2MCk7XG4gICAgICAgIGhvdXJzICAgICAgICAgICAgID0gYWJzRmxvb3IobWludXRlcyAvIDYwKTtcbiAgICAgICAgc2Vjb25kcyAlPSA2MDtcbiAgICAgICAgbWludXRlcyAlPSA2MDtcblxuICAgICAgICAvLyAxMiBtb250aHMgLT4gMSB5ZWFyXG4gICAgICAgIHllYXJzICA9IGFic0Zsb29yKG1vbnRocyAvIDEyKTtcbiAgICAgICAgbW9udGhzICU9IDEyO1xuXG5cbiAgICAgICAgLy8gaW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2RvcmRpbGxlL21vbWVudC1pc29kdXJhdGlvbi9ibG9iL21hc3Rlci9tb21lbnQuaXNvZHVyYXRpb24uanNcbiAgICAgICAgdmFyIFkgPSB5ZWFycztcbiAgICAgICAgdmFyIE0gPSBtb250aHM7XG4gICAgICAgIHZhciBEID0gZGF5cztcbiAgICAgICAgdmFyIGggPSBob3VycztcbiAgICAgICAgdmFyIG0gPSBtaW51dGVzO1xuICAgICAgICB2YXIgcyA9IHNlY29uZHMgPyBzZWNvbmRzLnRvRml4ZWQoMykucmVwbGFjZSgvXFwuPzArJC8sICcnKSA6ICcnO1xuICAgICAgICB2YXIgdG90YWwgPSB0aGlzLmFzU2Vjb25kcygpO1xuXG4gICAgICAgIGlmICghdG90YWwpIHtcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgdGhlIHNhbWUgYXMgQyMncyAoTm9kYSkgYW5kIHB5dGhvbiAoaXNvZGF0ZSkuLi5cbiAgICAgICAgICAgIC8vIGJ1dCBub3Qgb3RoZXIgSlMgKGdvb2cuZGF0ZSlcbiAgICAgICAgICAgIHJldHVybiAnUDBEJztcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0b3RhbFNpZ24gPSB0b3RhbCA8IDAgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIHltU2lnbiA9IHNpZ24odGhpcy5fbW9udGhzKSAhPT0gc2lnbih0b3RhbCkgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIGRheXNTaWduID0gc2lnbih0aGlzLl9kYXlzKSAhPT0gc2lnbih0b3RhbCkgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIGhtc1NpZ24gPSBzaWduKHRoaXMuX21pbGxpc2Vjb25kcykgIT09IHNpZ24odG90YWwpID8gJy0nIDogJyc7XG5cbiAgICAgICAgcmV0dXJuIHRvdGFsU2lnbiArICdQJyArXG4gICAgICAgICAgICAoWSA/IHltU2lnbiArIFkgKyAnWScgOiAnJykgK1xuICAgICAgICAgICAgKE0gPyB5bVNpZ24gKyBNICsgJ00nIDogJycpICtcbiAgICAgICAgICAgIChEID8gZGF5c1NpZ24gKyBEICsgJ0QnIDogJycpICtcbiAgICAgICAgICAgICgoaCB8fCBtIHx8IHMpID8gJ1QnIDogJycpICtcbiAgICAgICAgICAgIChoID8gaG1zU2lnbiArIGggKyAnSCcgOiAnJykgK1xuICAgICAgICAgICAgKG0gPyBobXNTaWduICsgbSArICdNJyA6ICcnKSArXG4gICAgICAgICAgICAocyA/IGhtc1NpZ24gKyBzICsgJ1MnIDogJycpO1xuICAgIH1cblxuICAgIHZhciBwcm90byQyID0gRHVyYXRpb24ucHJvdG90eXBlO1xuXG4gICAgcHJvdG8kMi5pc1ZhbGlkICAgICAgICA9IGlzVmFsaWQkMTtcbiAgICBwcm90byQyLmFicyAgICAgICAgICAgID0gYWJzO1xuICAgIHByb3RvJDIuYWRkICAgICAgICAgICAgPSBhZGQkMTtcbiAgICBwcm90byQyLnN1YnRyYWN0ICAgICAgID0gc3VidHJhY3QkMTtcbiAgICBwcm90byQyLmFzICAgICAgICAgICAgID0gYXM7XG4gICAgcHJvdG8kMi5hc01pbGxpc2Vjb25kcyA9IGFzTWlsbGlzZWNvbmRzO1xuICAgIHByb3RvJDIuYXNTZWNvbmRzICAgICAgPSBhc1NlY29uZHM7XG4gICAgcHJvdG8kMi5hc01pbnV0ZXMgICAgICA9IGFzTWludXRlcztcbiAgICBwcm90byQyLmFzSG91cnMgICAgICAgID0gYXNIb3VycztcbiAgICBwcm90byQyLmFzRGF5cyAgICAgICAgID0gYXNEYXlzO1xuICAgIHByb3RvJDIuYXNXZWVrcyAgICAgICAgPSBhc1dlZWtzO1xuICAgIHByb3RvJDIuYXNNb250aHMgICAgICAgPSBhc01vbnRocztcbiAgICBwcm90byQyLmFzUXVhcnRlcnMgICAgID0gYXNRdWFydGVycztcbiAgICBwcm90byQyLmFzWWVhcnMgICAgICAgID0gYXNZZWFycztcbiAgICBwcm90byQyLnZhbHVlT2YgICAgICAgID0gdmFsdWVPZiQxO1xuICAgIHByb3RvJDIuX2J1YmJsZSAgICAgICAgPSBidWJibGU7XG4gICAgcHJvdG8kMi5jbG9uZSAgICAgICAgICA9IGNsb25lJDE7XG4gICAgcHJvdG8kMi5nZXQgICAgICAgICAgICA9IGdldCQyO1xuICAgIHByb3RvJDIubWlsbGlzZWNvbmRzICAgPSBtaWxsaXNlY29uZHM7XG4gICAgcHJvdG8kMi5zZWNvbmRzICAgICAgICA9IHNlY29uZHM7XG4gICAgcHJvdG8kMi5taW51dGVzICAgICAgICA9IG1pbnV0ZXM7XG4gICAgcHJvdG8kMi5ob3VycyAgICAgICAgICA9IGhvdXJzO1xuICAgIHByb3RvJDIuZGF5cyAgICAgICAgICAgPSBkYXlzO1xuICAgIHByb3RvJDIud2Vla3MgICAgICAgICAgPSB3ZWVrcztcbiAgICBwcm90byQyLm1vbnRocyAgICAgICAgID0gbW9udGhzO1xuICAgIHByb3RvJDIueWVhcnMgICAgICAgICAgPSB5ZWFycztcbiAgICBwcm90byQyLmh1bWFuaXplICAgICAgID0gaHVtYW5pemU7XG4gICAgcHJvdG8kMi50b0lTT1N0cmluZyAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi50b1N0cmluZyAgICAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi50b0pTT04gICAgICAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi5sb2NhbGUgICAgICAgICA9IGxvY2FsZTtcbiAgICBwcm90byQyLmxvY2FsZURhdGEgICAgID0gbG9jYWxlRGF0YTtcblxuICAgIHByb3RvJDIudG9Jc29TdHJpbmcgPSBkZXByZWNhdGUoJ3RvSXNvU3RyaW5nKCkgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSB0b0lTT1N0cmluZygpIGluc3RlYWQgKG5vdGljZSB0aGUgY2FwaXRhbHMpJywgdG9JU09TdHJpbmckMSk7XG4gICAgcHJvdG8kMi5sYW5nID0gbGFuZztcblxuICAgIC8vIFNpZGUgZWZmZWN0IGltcG9ydHNcblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdYJywgMCwgMCwgJ3VuaXgnKTtcbiAgICBhZGRGb3JtYXRUb2tlbigneCcsIDAsIDAsICd2YWx1ZU9mJyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCd4JywgbWF0Y2hTaWduZWQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1gnLCBtYXRjaFRpbWVzdGFtcCk7XG4gICAgYWRkUGFyc2VUb2tlbignWCcsIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2QgPSBuZXcgRGF0ZShwYXJzZUZsb2F0KGlucHV0LCAxMCkgKiAxMDAwKTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCd4JywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKHRvSW50KGlucHV0KSk7XG4gICAgfSk7XG5cbiAgICAvLyBTaWRlIGVmZmVjdCBpbXBvcnRzXG5cblxuICAgIGhvb2tzLnZlcnNpb24gPSAnMi4yNC4wJztcblxuICAgIHNldEhvb2tDYWxsYmFjayhjcmVhdGVMb2NhbCk7XG5cbiAgICBob29rcy5mbiAgICAgICAgICAgICAgICAgICAgPSBwcm90bztcbiAgICBob29rcy5taW4gICAgICAgICAgICAgICAgICAgPSBtaW47XG4gICAgaG9va3MubWF4ICAgICAgICAgICAgICAgICAgID0gbWF4O1xuICAgIGhvb2tzLm5vdyAgICAgICAgICAgICAgICAgICA9IG5vdztcbiAgICBob29rcy51dGMgICAgICAgICAgICAgICAgICAgPSBjcmVhdGVVVEM7XG4gICAgaG9va3MudW5peCAgICAgICAgICAgICAgICAgID0gY3JlYXRlVW5peDtcbiAgICBob29rcy5tb250aHMgICAgICAgICAgICAgICAgPSBsaXN0TW9udGhzO1xuICAgIGhvb2tzLmlzRGF0ZSAgICAgICAgICAgICAgICA9IGlzRGF0ZTtcbiAgICBob29rcy5sb2NhbGUgICAgICAgICAgICAgICAgPSBnZXRTZXRHbG9iYWxMb2NhbGU7XG4gICAgaG9va3MuaW52YWxpZCAgICAgICAgICAgICAgID0gY3JlYXRlSW52YWxpZDtcbiAgICBob29rcy5kdXJhdGlvbiAgICAgICAgICAgICAgPSBjcmVhdGVEdXJhdGlvbjtcbiAgICBob29rcy5pc01vbWVudCAgICAgICAgICAgICAgPSBpc01vbWVudDtcbiAgICBob29rcy53ZWVrZGF5cyAgICAgICAgICAgICAgPSBsaXN0V2Vla2RheXM7XG4gICAgaG9va3MucGFyc2Vab25lICAgICAgICAgICAgID0gY3JlYXRlSW5ab25lO1xuICAgIGhvb2tzLmxvY2FsZURhdGEgICAgICAgICAgICA9IGdldExvY2FsZTtcbiAgICBob29rcy5pc0R1cmF0aW9uICAgICAgICAgICAgPSBpc0R1cmF0aW9uO1xuICAgIGhvb2tzLm1vbnRoc1Nob3J0ICAgICAgICAgICA9IGxpc3RNb250aHNTaG9ydDtcbiAgICBob29rcy53ZWVrZGF5c01pbiAgICAgICAgICAgPSBsaXN0V2Vla2RheXNNaW47XG4gICAgaG9va3MuZGVmaW5lTG9jYWxlICAgICAgICAgID0gZGVmaW5lTG9jYWxlO1xuICAgIGhvb2tzLnVwZGF0ZUxvY2FsZSAgICAgICAgICA9IHVwZGF0ZUxvY2FsZTtcbiAgICBob29rcy5sb2NhbGVzICAgICAgICAgICAgICAgPSBsaXN0TG9jYWxlcztcbiAgICBob29rcy53ZWVrZGF5c1Nob3J0ICAgICAgICAgPSBsaXN0V2Vla2RheXNTaG9ydDtcbiAgICBob29rcy5ub3JtYWxpemVVbml0cyAgICAgICAgPSBub3JtYWxpemVVbml0cztcbiAgICBob29rcy5yZWxhdGl2ZVRpbWVSb3VuZGluZyAgPSBnZXRTZXRSZWxhdGl2ZVRpbWVSb3VuZGluZztcbiAgICBob29rcy5yZWxhdGl2ZVRpbWVUaHJlc2hvbGQgPSBnZXRTZXRSZWxhdGl2ZVRpbWVUaHJlc2hvbGQ7XG4gICAgaG9va3MuY2FsZW5kYXJGb3JtYXQgICAgICAgID0gZ2V0Q2FsZW5kYXJGb3JtYXQ7XG4gICAgaG9va3MucHJvdG90eXBlICAgICAgICAgICAgID0gcHJvdG87XG5cbiAgICAvLyBjdXJyZW50bHkgSFRNTDUgaW5wdXQgdHlwZSBvbmx5IHN1cHBvcnRzIDI0LWhvdXIgZm9ybWF0c1xuICAgIGhvb2tzLkhUTUw1X0ZNVCA9IHtcbiAgICAgICAgREFURVRJTUVfTE9DQUw6ICdZWVlZLU1NLUREVEhIOm1tJywgICAgICAgICAgICAgLy8gPGlucHV0IHR5cGU9XCJkYXRldGltZS1sb2NhbFwiIC8+XG4gICAgICAgIERBVEVUSU1FX0xPQ0FMX1NFQ09ORFM6ICdZWVlZLU1NLUREVEhIOm1tOnNzJywgIC8vIDxpbnB1dCB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIiBzdGVwPVwiMVwiIC8+XG4gICAgICAgIERBVEVUSU1FX0xPQ0FMX01TOiAnWVlZWS1NTS1ERFRISDptbTpzcy5TU1MnLCAgIC8vIDxpbnB1dCB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIiBzdGVwPVwiMC4wMDFcIiAvPlxuICAgICAgICBEQVRFOiAnWVlZWS1NTS1ERCcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cImRhdGVcIiAvPlxuICAgICAgICBUSU1FOiAnSEg6bW0nLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cInRpbWVcIiAvPlxuICAgICAgICBUSU1FX1NFQ09ORFM6ICdISDptbTpzcycsICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cInRpbWVcIiBzdGVwPVwiMVwiIC8+XG4gICAgICAgIFRJTUVfTVM6ICdISDptbTpzcy5TU1MnLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwidGltZVwiIHN0ZXA9XCIwLjAwMVwiIC8+XG4gICAgICAgIFdFRUs6ICdHR0dHLVtXXVdXJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwid2Vla1wiIC8+XG4gICAgICAgIE1PTlRIOiAnWVlZWS1NTScgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwibW9udGhcIiAvPlxuICAgIH07XG5cbiAgICByZXR1cm4gaG9va3M7XG5cbn0pKSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///da01\n")}}]);

TODO found
Open

/* TODO: Find a proper solution to have the graphs
Severity: Minor
Found in dist/app.css by fixme

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.spot-framework"],{"0056":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Group = __webpack_require__(/*! ./group */ \"9083\");\n\nfunction setOrdering (groups, ordering) {\n  if (ordering === 'count') {\n    groups.comparator = function (a, b) {\n      if (a.count === b.count) {\n        return a.value < b.value ? -1 : 1;\n      } else {\n        return b.count - a.count;\n      }\n    };\n  } else if (ordering === 'value') {\n    groups.comparator = 'value';\n  } else {\n    console.error('Ordering not implemented for partition: ', ordering);\n  }\n  groups.sort();\n}\n\nmodule.exports = Collection.extend({\n  indexes: ['value', 'label', 'group', 'groupIndex'],\n  model: Group,\n  comparator: 'label',\n  initialize: function (models, options) {\n    var groups = this;\n    var partition = options.parent;\n\n    // update group index on resort\n    this.on('sort', function () {\n      this.forEach(function (group, i) {\n        group.groupIndex = i;\n      });\n    }, this);\n\n    // this.parent := partition\n    if (partition) {\n      setOrdering(groups, partition.ordering);\n\n      partition.on('change ordering', function () {\n        setOrdering(groups, partition.ordering);\n      });\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDA1Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2dyb3VwLWNvbGxlY3Rpb24uanM/OGM1ZiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgR3JvdXAgPSByZXF1aXJlKCcuL2dyb3VwJyk7XG5cbmZ1bmN0aW9uIHNldE9yZGVyaW5nIChncm91cHMsIG9yZGVyaW5nKSB7XG4gIGlmIChvcmRlcmluZyA9PT0gJ2NvdW50Jykge1xuICAgIGdyb3Vwcy5jb21wYXJhdG9yID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIGlmIChhLmNvdW50ID09PSBiLmNvdW50KSB7XG4gICAgICAgIHJldHVybiBhLnZhbHVlIDwgYi52YWx1ZSA/IC0xIDogMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBiLmNvdW50IC0gYS5jb3VudDtcbiAgICAgIH1cbiAgICB9O1xuICB9IGVsc2UgaWYgKG9yZGVyaW5nID09PSAndmFsdWUnKSB7XG4gICAgZ3JvdXBzLmNvbXBhcmF0b3IgPSAndmFsdWUnO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUuZXJyb3IoJ09yZGVyaW5nIG5vdCBpbXBsZW1lbnRlZCBmb3IgcGFydGl0aW9uOiAnLCBvcmRlcmluZyk7XG4gIH1cbiAgZ3JvdXBzLnNvcnQoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDb2xsZWN0aW9uLmV4dGVuZCh7XG4gIGluZGV4ZXM6IFsndmFsdWUnLCAnbGFiZWwnLCAnZ3JvdXAnLCAnZ3JvdXBJbmRleCddLFxuICBtb2RlbDogR3JvdXAsXG4gIGNvbXBhcmF0b3I6ICdsYWJlbCcsXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uIChtb2RlbHMsIG9wdGlvbnMpIHtcbiAgICB2YXIgZ3JvdXBzID0gdGhpcztcbiAgICB2YXIgcGFydGl0aW9uID0gb3B0aW9ucy5wYXJlbnQ7XG5cbiAgICAvLyB1cGRhdGUgZ3JvdXAgaW5kZXggb24gcmVzb3J0XG4gICAgdGhpcy5vbignc29ydCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZ3JvdXAsIGkpIHtcbiAgICAgICAgZ3JvdXAuZ3JvdXBJbmRleCA9IGk7XG4gICAgICB9KTtcbiAgICB9LCB0aGlzKTtcblxuICAgIC8vIHRoaXMucGFyZW50IDo9IHBhcnRpdGlvblxuICAgIGlmIChwYXJ0aXRpb24pIHtcbiAgICAgIHNldE9yZGVyaW5nKGdyb3VwcywgcGFydGl0aW9uLm9yZGVyaW5nKTtcblxuICAgICAgcGFydGl0aW9uLm9uKCdjaGFuZ2Ugb3JkZXJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNldE9yZGVyaW5nKGdyb3VwcywgcGFydGl0aW9uLm9yZGVyaW5nKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///0056\n")},"0112":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar transports = __webpack_require__(/*! ./transports/index */ \"834b\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:socket');\nvar index = __webpack_require__(/*! indexof */ \"3294\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar parseuri = __webpack_require__(/*! parseuri */ \"64a0\");\nvar parsejson = __webpack_require__(/*! parsejson */ \"185c\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = Socket;\n\n/**\n * Socket constructor.\n *\n * @param {String|Object} uri or options\n * @param {Object} options\n * @api public\n */\n\nfunction Socket (uri, opts) {\n  if (!(this instanceof Socket)) return new Socket(uri, opts);\n\n  opts = opts || {};\n\n  if (uri && 'object' === typeof uri) {\n    opts = uri;\n    uri = null;\n  }\n\n  if (uri) {\n    uri = parseuri(uri);\n    opts.hostname = uri.host;\n    opts.secure = uri.protocol === 'https' || uri.protocol === 'wss';\n    opts.port = uri.port;\n    if (uri.query) opts.query = uri.query;\n  } else if (opts.host) {\n    opts.hostname = parseuri(opts.host).host;\n  }\n\n  this.secure = null != opts.secure ? opts.secure\n    : (global.location && 'https:' === location.protocol);\n\n  if (opts.hostname && !opts.port) {\n    // if no port is specified manually, use the protocol default\n    opts.port = this.secure ? '443' : '80';\n  }\n\n  this.agent = opts.agent || false;\n  this.hostname = opts.hostname ||\n    (global.location ? location.hostname : 'localhost');\n  this.port = opts.port || (global.location && location.port\n      ? location.port\n      : (this.secure ? 443 : 80));\n  this.query = opts.query || {};\n  if ('string' === typeof this.query) this.query = parseqs.decode(this.query);\n  this.upgrade = false !== opts.upgrade;\n  this.path = (opts.path || '/engine.io').replace(/\\/$/, '') + '/';\n  this.forceJSONP = !!opts.forceJSONP;\n  this.jsonp = false !== opts.jsonp;\n  this.forceBase64 = !!opts.forceBase64;\n  this.enablesXDR = !!opts.enablesXDR;\n  this.timestampParam = opts.timestampParam || 't';\n  this.timestampRequests = opts.timestampRequests;\n  this.transports = opts.transports || ['polling', 'websocket'];\n  this.readyState = '';\n  this.writeBuffer = [];\n  this.prevBufferLen = 0;\n  this.policyPort = opts.policyPort || 843;\n  this.rememberUpgrade = opts.rememberUpgrade || false;\n  this.binaryType = null;\n  this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;\n  this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || {}) : false;\n\n  if (true === this.perMessageDeflate) this.perMessageDeflate = {};\n  if (this.perMessageDeflate && null == this.perMessageDeflate.threshold) {\n    this.perMessageDeflate.threshold = 1024;\n  }\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx || null;\n  this.key = opts.key || null;\n  this.passphrase = opts.passphrase || null;\n  this.cert = opts.cert || null;\n  this.ca = opts.ca || null;\n  this.ciphers = opts.ciphers || null;\n  this.rejectUnauthorized = opts.rejectUnauthorized === undefined ? null : opts.rejectUnauthorized;\n  this.forceNode = !!opts.forceNode;\n\n  // other options for Node.js client\n  var freeGlobal = typeof global === 'object' && global;\n  if (freeGlobal.global === freeGlobal) {\n    if (opts.extraHeaders && Object.keys(opts.extraHeaders).length > 0) {\n      this.extraHeaders = opts.extraHeaders;\n    }\n\n    if (opts.localAddress) {\n      this.localAddress = opts.localAddress;\n    }\n  }\n\n  // set on handshake\n  this.id = null;\n  this.upgrades = null;\n  this.pingInterval = null;\n  this.pingTimeout = null;\n\n  // set on heartbeat\n  this.pingIntervalTimer = null;\n  this.pingTimeoutTimer = null;\n\n  this.open();\n}\n\nSocket.priorWebsocketSuccess = false;\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Socket.prototype);\n\n/**\n * Protocol version.\n *\n * @api public\n */\n\nSocket.protocol = parser.protocol; // this is an int\n\n/**\n * Expose deps for legacy compatibility\n * and standalone browser access.\n */\n\nSocket.Socket = Socket;\nSocket.Transport = __webpack_require__(/*! ./transport */ \"0d97\");\nSocket.transports = __webpack_require__(/*! ./transports/index */ \"834b\");\nSocket.parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\n\n/**\n * Creates transport of the given type.\n *\n * @param {String} transport name\n * @return {Transport}\n * @api private\n */\n\nSocket.prototype.createTransport = function (name) {\n  debug('creating transport \"%s\"', name);\n  var query = clone(this.query);\n\n  // append engine.io protocol identifier\n  query.EIO = parser.protocol;\n\n  // transport name\n  query.transport = name;\n\n  // session id if we already have one\n  if (this.id) query.sid = this.id;\n\n  var transport = new transports[name]({\n    agent: this.agent,\n    hostname: this.hostname,\n    port: this.port,\n    secure: this.secure,\n    path: this.path,\n    query: query,\n    forceJSONP: this.forceJSONP,\n    jsonp: this.jsonp,\n    forceBase64: this.forceBase64,\n    enablesXDR: this.enablesXDR,\n    timestampRequests: this.timestampRequests,\n    timestampParam: this.timestampParam,\n    policyPort: this.policyPort,\n    socket: this,\n    pfx: this.pfx,\n    key: this.key,\n    passphrase: this.passphrase,\n    cert: this.cert,\n    ca: this.ca,\n    ciphers: this.ciphers,\n    rejectUnauthorized: this.rejectUnauthorized,\n    perMessageDeflate: this.perMessageDeflate,\n    extraHeaders: this.extraHeaders,\n    forceNode: this.forceNode,\n    localAddress: this.localAddress\n  });\n\n  return transport;\n};\n\nfunction clone (obj) {\n  var o = {};\n  for (var i in obj) {\n    if (obj.hasOwnProperty(i)) {\n      o[i] = obj[i];\n    }\n  }\n  return o;\n}\n\n/**\n * Initializes transport to use and starts probe.\n *\n * @api private\n */\nSocket.prototype.open = function () {\n  var transport;\n  if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') !== -1) {\n    transport = 'websocket';\n  } else if (0 === this.transports.length) {\n    // Emit error on next tick so it can be listened to\n    var self = this;\n    setTimeout(function () {\n      self.emit('error', 'No transports available');\n    }, 0);\n    return;\n  } else {\n    transport = this.transports[0];\n  }\n  this.readyState = 'opening';\n\n  // Retry with the next transport if the transport is disabled (jsonp: false)\n  try {\n    transport = this.createTransport(transport);\n  } catch (e) {\n    this.transports.shift();\n    this.open();\n    return;\n  }\n\n  transport.open();\n  this.setTransport(transport);\n};\n\n/**\n * Sets the current transport. Disables the existing one (if any).\n *\n * @api private\n */\n\nSocket.prototype.setTransport = function (transport) {\n  debug('setting transport %s', transport.name);\n  var self = this;\n\n  if (this.transport) {\n    debug('clearing existing transport %s', this.transport.name);\n    this.transport.removeAllListeners();\n  }\n\n  // set up transport\n  this.transport = transport;\n\n  // set up transport listeners\n  transport\n  .on('drain', function () {\n    self.onDrain();\n  })\n  .on('packet', function (packet) {\n    self.onPacket(packet);\n  })\n  .on('error', function (e) {\n    self.onError(e);\n  })\n  .on('close', function () {\n    self.onClose('transport close');\n  });\n};\n\n/**\n * Probes a transport.\n *\n * @param {String} transport name\n * @api private\n */\n\nSocket.prototype.probe = function (name) {\n  debug('probing transport \"%s\"', name);\n  var transport = this.createTransport(name, { probe: 1 });\n  var failed = false;\n  var self = this;\n\n  Socket.priorWebsocketSuccess = false;\n\n  function onTransportOpen () {\n    if (self.onlyBinaryUpgrades) {\n      var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;\n      failed = failed || upgradeLosesBinary;\n    }\n    if (failed) return;\n\n    debug('probe transport \"%s\" opened', name);\n    transport.send([{ type: 'ping', data: 'probe' }]);\n    transport.once('packet', function (msg) {\n      if (failed) return;\n      if ('pong' === msg.type && 'probe' === msg.data) {\n        debug('probe transport \"%s\" pong', name);\n        self.upgrading = true;\n        self.emit('upgrading', transport);\n        if (!transport) return;\n        Socket.priorWebsocketSuccess = 'websocket' === transport.name;\n\n        debug('pausing current transport \"%s\"', self.transport.name);\n        self.transport.pause(function () {\n          if (failed) return;\n          if ('closed' === self.readyState) return;\n          debug('changing transport and sending upgrade packet');\n\n          cleanup();\n\n          self.setTransport(transport);\n          transport.send([{ type: 'upgrade' }]);\n          self.emit('upgrade', transport);\n          transport = null;\n          self.upgrading = false;\n          self.flush();\n        });\n      } else {\n        debug('probe transport \"%s\" failed', name);\n        var err = new Error('probe error');\n        err.transport = transport.name;\n        self.emit('upgradeError', err);\n      }\n    });\n  }\n\n  function freezeTransport () {\n    if (failed) return;\n\n    // Any callback called by transport should be ignored since now\n    failed = true;\n\n    cleanup();\n\n    transport.close();\n    transport = null;\n  }\n\n  // Handle any error that happens while probing\n  function onerror (err) {\n    var error = new Error('probe error: ' + err);\n    error.transport = transport.name;\n\n    freezeTransport();\n\n    debug('probe transport \"%s\" failed because of error: %s', name, err);\n\n    self.emit('upgradeError', error);\n  }\n\n  function onTransportClose () {\n    onerror('transport closed');\n  }\n\n  // When the socket is closed while we're probing\n  function onclose () {\n    onerror('socket closed');\n  }\n\n  // When the socket is upgraded while we're probing\n  function onupgrade (to) {\n    if (transport && to.name !== transport.name) {\n      debug('\"%s\" works - aborting \"%s\"', to.name, transport.name);\n      freezeTransport();\n    }\n  }\n\n  // Remove all listeners on the transport and on self\n  function cleanup () {\n    transport.removeListener('open', onTransportOpen);\n    transport.removeListener('error', onerror);\n    transport.removeListener('close', onTransportClose);\n    self.removeListener('close', onclose);\n    self.removeListener('upgrading', onupgrade);\n  }\n\n  transport.once('open', onTransportOpen);\n  transport.once('error', onerror);\n  transport.once('close', onTransportClose);\n\n  this.once('close', onclose);\n  this.once('upgrading', onupgrade);\n\n  transport.open();\n};\n\n/**\n * Called when connection is deemed open.\n *\n * @api public\n */\n\nSocket.prototype.onOpen = function () {\n  debug('socket open');\n  this.readyState = 'open';\n  Socket.priorWebsocketSuccess = 'websocket' === this.transport.name;\n  this.emit('open');\n  this.flush();\n\n  // we check for `readyState` in case an `open`\n  // listener already closed the socket\n  if ('open' === this.readyState && this.upgrade && this.transport.pause) {\n    debug('starting upgrade probes');\n    for (var i = 0, l = this.upgrades.length; i < l; i++) {\n      this.probe(this.upgrades[i]);\n    }\n  }\n};\n\n/**\n * Handles a packet.\n *\n * @api private\n */\n\nSocket.prototype.onPacket = function (packet) {\n  if ('opening' === this.readyState || 'open' === this.readyState ||\n      'closing' === this.readyState) {\n    debug('socket receive: type \"%s\", data \"%s\"', packet.type, packet.data);\n\n    this.emit('packet', packet);\n\n    // Socket is live - any packet counts\n    this.emit('heartbeat');\n\n    switch (packet.type) {\n      case 'open':\n        this.onHandshake(parsejson(packet.data));\n        break;\n\n      case 'pong':\n        this.setPing();\n        this.emit('pong');\n        break;\n\n      case 'error':\n        var err = new Error('server error');\n        err.code = packet.data;\n        this.onError(err);\n        break;\n\n      case 'message':\n        this.emit('data', packet.data);\n        this.emit('message', packet.data);\n        break;\n    }\n  } else {\n    debug('packet received with socket readyState \"%s\"', this.readyState);\n  }\n};\n\n/**\n * Called upon handshake completion.\n *\n * @param {Object} handshake obj\n * @api private\n */\n\nSocket.prototype.onHandshake = function (data) {\n  this.emit('handshake', data);\n  this.id = data.sid;\n  this.transport.query.sid = data.sid;\n  this.upgrades = this.filterUpgrades(data.upgrades);\n  this.pingInterval = data.pingInterval;\n  this.pingTimeout = data.pingTimeout;\n  this.onOpen();\n  // In case open handler closes socket\n  if ('closed' === this.readyState) return;\n  this.setPing();\n\n  // Prolong liveness of socket on heartbeat\n  this.removeListener('heartbeat', this.onHeartbeat);\n  this.on('heartbeat', this.onHeartbeat);\n};\n\n/**\n * Resets ping timeout.\n *\n * @api private\n */\n\nSocket.prototype.onHeartbeat = function (timeout) {\n  clearTimeout(this.pingTimeoutTimer);\n  var self = this;\n  self.pingTimeoutTimer = setTimeout(function () {\n    if ('closed' === self.readyState) return;\n    self.onClose('ping timeout');\n  }, timeout || (self.pingInterval + self.pingTimeout));\n};\n\n/**\n * Pings server every `this.pingInterval` and expects response\n * within `this.pingTimeout` or closes connection.\n *\n * @api private\n */\n\nSocket.prototype.setPing = function () {\n  var self = this;\n  clearTimeout(self.pingIntervalTimer);\n  self.pingIntervalTimer = setTimeout(function () {\n    debug('writing ping packet - expecting pong within %sms', self.pingTimeout);\n    self.ping();\n    self.onHeartbeat(self.pingTimeout);\n  }, self.pingInterval);\n};\n\n/**\n* Sends a ping packet.\n*\n* @api private\n*/\n\nSocket.prototype.ping = function () {\n  var self = this;\n  this.sendPacket('ping', function () {\n    self.emit('ping');\n  });\n};\n\n/**\n * Called on `drain` event\n *\n * @api private\n */\n\nSocket.prototype.onDrain = function () {\n  this.writeBuffer.splice(0, this.prevBufferLen);\n\n  // setting prevBufferLen = 0 is very important\n  // for example, when upgrading, upgrade packet is sent over,\n  // and a nonzero prevBufferLen could cause problems on `drain`\n  this.prevBufferLen = 0;\n\n  if (0 === this.writeBuffer.length) {\n    this.emit('drain');\n  } else {\n    this.flush();\n  }\n};\n\n/**\n * Flush write buffers.\n *\n * @api private\n */\n\nSocket.prototype.flush = function () {\n  if ('closed' !== this.readyState && this.transport.writable &&\n    !this.upgrading && this.writeBuffer.length) {\n    debug('flushing %d packets in socket', this.writeBuffer.length);\n    this.transport.send(this.writeBuffer);\n    // keep track of current length of writeBuffer\n    // splice writeBuffer and callbackBuffer on `drain`\n    this.prevBufferLen = this.writeBuffer.length;\n    this.emit('flush');\n  }\n};\n\n/**\n * Sends a message.\n *\n * @param {String} message.\n * @param {Function} callback function.\n * @param {Object} options.\n * @return {Socket} for chaining.\n * @api public\n */\n\nSocket.prototype.write =\nSocket.prototype.send = function (msg, options, fn) {\n  this.sendPacket('message', msg, options, fn);\n  return this;\n};\n\n/**\n * Sends a packet.\n *\n * @param {String} packet type.\n * @param {String} data.\n * @param {Object} options.\n * @param {Function} callback function.\n * @api private\n */\n\nSocket.prototype.sendPacket = function (type, data, options, fn) {\n  if ('function' === typeof data) {\n    fn = data;\n    data = undefined;\n  }\n\n  if ('function' === typeof options) {\n    fn = options;\n    options = null;\n  }\n\n  if ('closing' === this.readyState || 'closed' === this.readyState) {\n    return;\n  }\n\n  options = options || {};\n  options.compress = false !== options.compress;\n\n  var packet = {\n    type: type,\n    data: data,\n    options: options\n  };\n  this.emit('packetCreate', packet);\n  this.writeBuffer.push(packet);\n  if (fn) this.once('flush', fn);\n  this.flush();\n};\n\n/**\n * Closes the connection.\n *\n * @api private\n */\n\nSocket.prototype.close = function () {\n  if ('opening' === this.readyState || 'open' === this.readyState) {\n    this.readyState = 'closing';\n\n    var self = this;\n\n    if (this.writeBuffer.length) {\n      this.once('drain', function () {\n        if (this.upgrading) {\n          waitForUpgrade();\n        } else {\n          close();\n        }\n      });\n    } else if (this.upgrading) {\n      waitForUpgrade();\n    } else {\n      close();\n    }\n  }\n\n  function close () {\n    self.onClose('forced close');\n    debug('socket closing - telling transport to close');\n    self.transport.close();\n  }\n\n  function cleanupAndClose () {\n    self.removeListener('upgrade', cleanupAndClose);\n    self.removeListener('upgradeError', cleanupAndClose);\n    close();\n  }\n\n  function waitForUpgrade () {\n    // wait for upgrade to finish since we can't send packets while pausing a transport\n    self.once('upgrade', cleanupAndClose);\n    self.once('upgradeError', cleanupAndClose);\n  }\n\n  return this;\n};\n\n/**\n * Called upon transport error\n *\n * @api private\n */\n\nSocket.prototype.onError = function (err) {\n  debug('socket error %j', err);\n  Socket.priorWebsocketSuccess = false;\n  this.emit('error', err);\n  this.onClose('transport error', err);\n};\n\n/**\n * Called upon transport close.\n *\n * @api private\n */\n\nSocket.prototype.onClose = function (reason, desc) {\n  if ('opening' === this.readyState || 'open' === this.readyState || 'closing' === this.readyState) {\n    debug('socket close with reason: \"%s\"', reason);\n    var self = this;\n\n    // clear timers\n    clearTimeout(this.pingIntervalTimer);\n    clearTimeout(this.pingTimeoutTimer);\n\n    // stop event from firing again for transport\n    this.transport.removeAllListeners('close');\n\n    // ensure transport won't stay open\n    this.transport.close();\n\n    // ignore further transport communication\n    this.transport.removeAllListeners();\n\n    // set ready state\n    this.readyState = 'closed';\n\n    // clear session id\n    this.id = null;\n\n    // emit close event\n    this.emit('close', reason, desc);\n\n    // clean buffers after, so users can still\n    // grab the buffers on `close` event\n    self.writeBuffer = [];\n    self.prevBufferLen = 0;\n  }\n};\n\n/**\n * Filters upgrades, returning only those matching client transports.\n *\n * @param {Array} server upgrades\n * @api private\n *\n */\n\nSocket.prototype.filterUpgrades = function (upgrades) {\n  var filteredUpgrades = [];\n  for (var i = 0, j = upgrades.length; i < j; i++) {\n    if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);\n  }\n  return filteredUpgrades;\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDExMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvc29ja2V0LmpzPzM1YjUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL2luZGV4Jyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnNvY2tldCcpO1xudmFyIGluZGV4ID0gcmVxdWlyZSgnaW5kZXhvZicpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBwYXJzZXVyaSA9IHJlcXVpcmUoJ3BhcnNldXJpJyk7XG52YXIgcGFyc2Vqc29uID0gcmVxdWlyZSgncGFyc2Vqc29uJyk7XG52YXIgcGFyc2VxcyA9IHJlcXVpcmUoJ3BhcnNlcXMnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNvY2tldDtcblxuLyoqXG4gKiBTb2NrZXQgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSB1cmkgb3Igb3B0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gU29ja2V0ICh1cmksIG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNvY2tldCkpIHJldHVybiBuZXcgU29ja2V0KHVyaSwgb3B0cyk7XG5cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgaWYgKHVyaSAmJiAnb2JqZWN0JyA9PT0gdHlwZW9mIHVyaSkge1xuICAgIG9wdHMgPSB1cmk7XG4gICAgdXJpID0gbnVsbDtcbiAgfVxuXG4gIGlmICh1cmkpIHtcbiAgICB1cmkgPSBwYXJzZXVyaSh1cmkpO1xuICAgIG9wdHMuaG9zdG5hbWUgPSB1cmkuaG9zdDtcbiAgICBvcHRzLnNlY3VyZSA9IHVyaS5wcm90b2NvbCA9PT0gJ2h0dHBzJyB8fCB1cmkucHJvdG9jb2wgPT09ICd3c3MnO1xuICAgIG9wdHMucG9ydCA9IHVyaS5wb3J0O1xuICAgIGlmICh1cmkucXVlcnkpIG9wdHMucXVlcnkgPSB1cmkucXVlcnk7XG4gIH0gZWxzZSBpZiAob3B0cy5ob3N0KSB7XG4gICAgb3B0cy5ob3N0bmFtZSA9IHBhcnNldXJpKG9wdHMuaG9zdCkuaG9zdDtcbiAgfVxuXG4gIHRoaXMuc2VjdXJlID0gbnVsbCAhPSBvcHRzLnNlY3VyZSA/IG9wdHMuc2VjdXJlXG4gICAgOiAoZ2xvYmFsLmxvY2F0aW9uICYmICdodHRwczonID09PSBsb2NhdGlvbi5wcm90b2NvbCk7XG5cbiAgaWYgKG9wdHMuaG9zdG5hbWUgJiYgIW9wdHMucG9ydCkge1xuICAgIC8vIGlmIG5vIHBvcnQgaXMgc3BlY2lmaWVkIG1hbnVhbGx5LCB1c2UgdGhlIHByb3RvY29sIGRlZmF1bHRcbiAgICBvcHRzLnBvcnQgPSB0aGlzLnNlY3VyZSA/ICc0NDMnIDogJzgwJztcbiAgfVxuXG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50IHx8IGZhbHNlO1xuICB0aGlzLmhvc3RuYW1lID0gb3B0cy5ob3N0bmFtZSB8fFxuICAgIChnbG9iYWwubG9jYXRpb24gPyBsb2NhdGlvbi5ob3N0bmFtZSA6ICdsb2NhbGhvc3QnKTtcbiAgdGhpcy5wb3J0ID0gb3B0cy5wb3J0IHx8IChnbG9iYWwubG9jYXRpb24gJiYgbG9jYXRpb24ucG9ydFxuICAgICAgPyBsb2NhdGlvbi5wb3J0XG4gICAgICA6ICh0aGlzLnNlY3VyZSA/IDQ0MyA6IDgwKSk7XG4gIHRoaXMucXVlcnkgPSBvcHRzLnF1ZXJ5IHx8IHt9O1xuICBpZiAoJ3N0cmluZycgPT09IHR5cGVvZiB0aGlzLnF1ZXJ5KSB0aGlzLnF1ZXJ5ID0gcGFyc2Vxcy5kZWNvZGUodGhpcy5xdWVyeSk7XG4gIHRoaXMudXBncmFkZSA9IGZhbHNlICE9PSBvcHRzLnVwZ3JhZGU7XG4gIHRoaXMucGF0aCA9IChvcHRzLnBhdGggfHwgJy9lbmdpbmUuaW8nKS5yZXBsYWNlKC9cXC8kLywgJycpICsgJy8nO1xuICB0aGlzLmZvcmNlSlNPTlAgPSAhIW9wdHMuZm9yY2VKU09OUDtcbiAgdGhpcy5qc29ucCA9IGZhbHNlICE9PSBvcHRzLmpzb25wO1xuICB0aGlzLmZvcmNlQmFzZTY0ID0gISFvcHRzLmZvcmNlQmFzZTY0O1xuICB0aGlzLmVuYWJsZXNYRFIgPSAhIW9wdHMuZW5hYmxlc1hEUjtcbiAgdGhpcy50aW1lc3RhbXBQYXJhbSA9IG9wdHMudGltZXN0YW1wUGFyYW0gfHwgJ3QnO1xuICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgdGhpcy50cmFuc3BvcnRzID0gb3B0cy50cmFuc3BvcnRzIHx8IFsncG9sbGluZycsICd3ZWJzb2NrZXQnXTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gIHRoaXMud3JpdGVCdWZmZXIgPSBbXTtcbiAgdGhpcy5wcmV2QnVmZmVyTGVuID0gMDtcbiAgdGhpcy5wb2xpY3lQb3J0ID0gb3B0cy5wb2xpY3lQb3J0IHx8IDg0MztcbiAgdGhpcy5yZW1lbWJlclVwZ3JhZGUgPSBvcHRzLnJlbWVtYmVyVXBncmFkZSB8fCBmYWxzZTtcbiAgdGhpcy5iaW5hcnlUeXBlID0gbnVsbDtcbiAgdGhpcy5vbmx5QmluYXJ5VXBncmFkZXMgPSBvcHRzLm9ubHlCaW5hcnlVcGdyYWRlcztcbiAgdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZSA9IGZhbHNlICE9PSBvcHRzLnBlck1lc3NhZ2VEZWZsYXRlID8gKG9wdHMucGVyTWVzc2FnZURlZmxhdGUgfHwge30pIDogZmFsc2U7XG5cbiAgaWYgKHRydWUgPT09IHRoaXMucGVyTWVzc2FnZURlZmxhdGUpIHRoaXMucGVyTWVzc2FnZURlZmxhdGUgPSB7fTtcbiAgaWYgKHRoaXMucGVyTWVzc2FnZURlZmxhdGUgJiYgbnVsbCA9PSB0aGlzLnBlck1lc3NhZ2VEZWZsYXRlLnRocmVzaG9sZCkge1xuICAgIHRoaXMucGVyTWVzc2FnZURlZmxhdGUudGhyZXNob2xkID0gMTAyNDtcbiAgfVxuXG4gIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLnBmeCA9IG9wdHMucGZ4IHx8IG51bGw7XG4gIHRoaXMua2V5ID0gb3B0cy5rZXkgfHwgbnVsbDtcbiAgdGhpcy5wYXNzcGhyYXNlID0gb3B0cy5wYXNzcGhyYXNlIHx8IG51bGw7XG4gIHRoaXMuY2VydCA9IG9wdHMuY2VydCB8fCBudWxsO1xuICB0aGlzLmNhID0gb3B0cy5jYSB8fCBudWxsO1xuICB0aGlzLmNpcGhlcnMgPSBvcHRzLmNpcGhlcnMgfHwgbnVsbDtcbiAgdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQgPSBvcHRzLnJlamVjdFVuYXV0aG9yaXplZCA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IG9wdHMucmVqZWN0VW5hdXRob3JpemVkO1xuICB0aGlzLmZvcmNlTm9kZSA9ICEhb3B0cy5mb3JjZU5vZGU7XG5cbiAgLy8gb3RoZXIgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgdmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09PSAnb2JqZWN0JyAmJiBnbG9iYWw7XG4gIGlmIChmcmVlR2xvYmFsLmdsb2JhbCA9PT0gZnJlZUdsb2JhbCkge1xuICAgIGlmIChvcHRzLmV4dHJhSGVhZGVycyAmJiBPYmplY3Qua2V5cyhvcHRzLmV4dHJhSGVhZGVycykubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5leHRyYUhlYWRlcnMgPSBvcHRzLmV4dHJhSGVhZGVycztcbiAgICB9XG5cbiAgICBpZiAob3B0cy5sb2NhbEFkZHJlc3MpIHtcbiAgICAgIHRoaXMubG9jYWxBZGRyZXNzID0gb3B0cy5sb2NhbEFkZHJlc3M7XG4gICAgfVxuICB9XG5cbiAgLy8gc2V0IG9uIGhhbmRzaGFrZVxuICB0aGlzLmlkID0gbnVsbDtcbiAgdGhpcy51cGdyYWRlcyA9IG51bGw7XG4gIHRoaXMucGluZ0ludGVydmFsID0gbnVsbDtcbiAgdGhpcy5waW5nVGltZW91dCA9IG51bGw7XG5cbiAgLy8gc2V0IG9uIGhlYXJ0YmVhdFxuICB0aGlzLnBpbmdJbnRlcnZhbFRpbWVyID0gbnVsbDtcbiAgdGhpcy5waW5nVGltZW91dFRpbWVyID0gbnVsbDtcblxuICB0aGlzLm9wZW4oKTtcbn1cblxuU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuXG4vKipcbiAqIE1peCBpbiBgRW1pdHRlcmAuXG4gKi9cblxuRW1pdHRlcihTb2NrZXQucHJvdG90eXBlKTtcblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sOyAvLyB0aGlzIGlzIGFuIGludFxuXG4vKipcbiAqIEV4cG9zZSBkZXBzIGZvciBsZWdhY3kgY29tcGF0aWJpbGl0eVxuICogYW5kIHN0YW5kYWxvbmUgYnJvd3NlciBhY2Nlc3MuXG4gKi9cblxuU29ja2V0LlNvY2tldCA9IFNvY2tldDtcblNvY2tldC5UcmFuc3BvcnQgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpO1xuU29ja2V0LnRyYW5zcG9ydHMgPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMvaW5kZXgnKTtcblNvY2tldC5wYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyB0cmFuc3BvcnQgb2YgdGhlIGdpdmVuIHR5cGUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHRyYW5zcG9ydCBuYW1lXG4gKiBAcmV0dXJuIHtUcmFuc3BvcnR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNyZWF0ZVRyYW5zcG9ydCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlYnVnKCdjcmVhdGluZyB0cmFuc3BvcnQgXCIlc1wiJywgbmFtZSk7XG4gIHZhciBxdWVyeSA9IGNsb25lKHRoaXMucXVlcnkpO1xuXG4gIC8vIGFwcGVuZCBlbmdpbmUuaW8gcHJvdG9jb2wgaWRlbnRpZmllclxuICBxdWVyeS5FSU8gPSBwYXJzZXIucHJvdG9jb2w7XG5cbiAgLy8gdHJhbnNwb3J0IG5hbWVcbiAgcXVlcnkudHJhbnNwb3J0ID0gbmFtZTtcblxuICAvLyBzZXNzaW9uIGlkIGlmIHdlIGFscmVhZHkgaGF2ZSBvbmVcbiAgaWYgKHRoaXMuaWQpIHF1ZXJ5LnNpZCA9IHRoaXMuaWQ7XG5cbiAgdmFyIHRyYW5zcG9ydCA9IG5ldyB0cmFuc3BvcnRzW25hbWVdKHtcbiAgICBhZ2VudDogdGhpcy5hZ2VudCxcbiAgICBob3N0bmFtZTogdGhpcy5ob3N0bmFtZSxcbiAgICBwb3J0OiB0aGlzLnBvcnQsXG4gICAgc2VjdXJlOiB0aGlzLnNlY3VyZSxcbiAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgcXVlcnk6IHF1ZXJ5LFxuICAgIGZvcmNlSlNPTlA6IHRoaXMuZm9yY2VKU09OUCxcbiAgICBqc29ucDogdGhpcy5qc29ucCxcbiAgICBmb3JjZUJhc2U2NDogdGhpcy5mb3JjZUJhc2U2NCxcbiAgICBlbmFibGVzWERSOiB0aGlzLmVuYWJsZXNYRFIsXG4gICAgdGltZXN0YW1wUmVxdWVzdHM6IHRoaXMudGltZXN0YW1wUmVxdWVzdHMsXG4gICAgdGltZXN0YW1wUGFyYW06IHRoaXMudGltZXN0YW1wUGFyYW0sXG4gICAgcG9saWN5UG9ydDogdGhpcy5wb2xpY3lQb3J0LFxuICAgIHNvY2tldDogdGhpcyxcbiAgICBwZng6IHRoaXMucGZ4LFxuICAgIGtleTogdGhpcy5rZXksXG4gICAgcGFzc3BocmFzZTogdGhpcy5wYXNzcGhyYXNlLFxuICAgIGNlcnQ6IHRoaXMuY2VydCxcbiAgICBjYTogdGhpcy5jYSxcbiAgICBjaXBoZXJzOiB0aGlzLmNpcGhlcnMsXG4gICAgcmVqZWN0VW5hdXRob3JpemVkOiB0aGlzLnJlamVjdFVuYXV0aG9yaXplZCxcbiAgICBwZXJNZXNzYWdlRGVmbGF0ZTogdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZSxcbiAgICBleHRyYUhlYWRlcnM6IHRoaXMuZXh0cmFIZWFkZXJzLFxuICAgIGZvcmNlTm9kZTogdGhpcy5mb3JjZU5vZGUsXG4gICAgbG9jYWxBZGRyZXNzOiB0aGlzLmxvY2FsQWRkcmVzc1xuICB9KTtcblxuICByZXR1cm4gdHJhbnNwb3J0O1xufTtcblxuZnVuY3Rpb24gY2xvbmUgKG9iaikge1xuICB2YXIgbyA9IHt9O1xuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgIG9baV0gPSBvYmpbaV07XG4gICAgfVxuICB9XG4gIHJldHVybiBvO1xufVxuXG4vKipcbiAqIEluaXRpYWxpemVzIHRyYW5zcG9ydCB0byB1c2UgYW5kIHN0YXJ0cyBwcm9iZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuU29ja2V0LnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdHJhbnNwb3J0O1xuICBpZiAodGhpcy5yZW1lbWJlclVwZ3JhZGUgJiYgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyAmJiB0aGlzLnRyYW5zcG9ydHMuaW5kZXhPZignd2Vic29ja2V0JykgIT09IC0xKSB7XG4gICAgdHJhbnNwb3J0ID0gJ3dlYnNvY2tldCc7XG4gIH0gZWxzZSBpZiAoMCA9PT0gdGhpcy50cmFuc3BvcnRzLmxlbmd0aCkge1xuICAgIC8vIEVtaXQgZXJyb3Igb24gbmV4dCB0aWNrIHNvIGl0IGNhbiBiZSBsaXN0ZW5lZCB0b1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCAnTm8gdHJhbnNwb3J0cyBhdmFpbGFibGUnKTtcbiAgICB9LCAwKTtcbiAgICByZXR1cm47XG4gIH0gZWxzZSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy50cmFuc3BvcnRzWzBdO1xuICB9XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcblxuICAvLyBSZXRyeSB3aXRoIHRoZSBuZXh0IHRyYW5zcG9ydCBpZiB0aGUgdHJhbnNwb3J0IGlzIGRpc2FibGVkIChqc29ucDogZmFsc2UpXG4gIHRyeSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy5jcmVhdGVUcmFuc3BvcnQodHJhbnNwb3J0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRoaXMudHJhbnNwb3J0cy5zaGlmdCgpO1xuICAgIHRoaXMub3BlbigpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyYW5zcG9ydC5vcGVuKCk7XG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGN1cnJlbnQgdHJhbnNwb3J0LiBEaXNhYmxlcyB0aGUgZXhpc3Rpbmcgb25lIChpZiBhbnkpLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24gKHRyYW5zcG9ydCkge1xuICBkZWJ1Zygnc2V0dGluZyB0cmFuc3BvcnQgJXMnLCB0cmFuc3BvcnQubmFtZSk7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAodGhpcy50cmFuc3BvcnQpIHtcbiAgICBkZWJ1ZygnY2xlYXJpbmcgZXhpc3RpbmcgdHJhbnNwb3J0ICVzJywgdGhpcy50cmFuc3BvcnQubmFtZSk7XG4gICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gIH1cblxuICAvLyBzZXQgdXAgdHJhbnNwb3J0XG4gIHRoaXMudHJhbnNwb3J0ID0gdHJhbnNwb3J0O1xuXG4gIC8vIHNldCB1cCB0cmFuc3BvcnQgbGlzdGVuZXJzXG4gIHRyYW5zcG9ydFxuICAub24oJ2RyYWluJywgZnVuY3Rpb24gKCkge1xuICAgIHNlbGYub25EcmFpbigpO1xuICB9KVxuICAub24oJ3BhY2tldCcsIGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgICBzZWxmLm9uUGFja2V0KHBhY2tldCk7XG4gIH0pXG4gIC5vbignZXJyb3InLCBmdW5jdGlvbiAoZSkge1xuICAgIHNlbGYub25FcnJvcihlKTtcbiAgfSlcbiAgLm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtcbiAgICBzZWxmLm9uQ2xvc2UoJ3RyYW5zcG9ydCBjbG9zZScpO1xuICB9KTtcbn07XG5cbi8qKlxuICogUHJvYmVzIGEgdHJhbnNwb3J0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0cmFuc3BvcnQgbmFtZVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5wcm9iZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlYnVnKCdwcm9iaW5nIHRyYW5zcG9ydCBcIiVzXCInLCBuYW1lKTtcbiAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuY3JlYXRlVHJhbnNwb3J0KG5hbWUsIHsgcHJvYmU6IDEgfSk7XG4gIHZhciBmYWlsZWQgPSBmYWxzZTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIFNvY2tldC5wcmlvcldlYnNvY2tldFN1Y2Nlc3MgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBvblRyYW5zcG9ydE9wZW4gKCkge1xuICAgIGlmIChzZWxmLm9ubHlCaW5hcnlVcGdyYWRlcykge1xuICAgICAgdmFyIHVwZ3JhZGVMb3Nlc0JpbmFyeSA9ICF0aGlzLnN1cHBvcnRzQmluYXJ5ICYmIHNlbGYudHJhbnNwb3J0LnN1cHBvcnRzQmluYXJ5O1xuICAgICAgZmFpbGVkID0gZmFpbGVkIHx8IHVwZ3JhZGVMb3Nlc0JpbmFyeTtcbiAgICB9XG4gICAgaWYgKGZhaWxlZCkgcmV0dXJuO1xuXG4gICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgb3BlbmVkJywgbmFtZSk7XG4gICAgdHJhbnNwb3J0LnNlbmQoW3sgdHlwZTogJ3BpbmcnLCBkYXRhOiAncHJvYmUnIH1dKTtcbiAgICB0cmFuc3BvcnQub25jZSgncGFja2V0JywgZnVuY3Rpb24gKG1zZykge1xuICAgICAgaWYgKGZhaWxlZCkgcmV0dXJuO1xuICAgICAgaWYgKCdwb25nJyA9PT0gbXNnLnR5cGUgJiYgJ3Byb2JlJyA9PT0gbXNnLmRhdGEpIHtcbiAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgcG9uZycsIG5hbWUpO1xuICAgICAgICBzZWxmLnVwZ3JhZGluZyA9IHRydWU7XG4gICAgICAgIHNlbGYuZW1pdCgndXBncmFkaW5nJywgdHJhbnNwb3J0KTtcbiAgICAgICAgaWYgKCF0cmFuc3BvcnQpIHJldHVybjtcbiAgICAgICAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9ICd3ZWJzb2NrZXQnID09PSB0cmFuc3BvcnQubmFtZTtcblxuICAgICAgICBkZWJ1ZygncGF1c2luZyBjdXJyZW50IHRyYW5zcG9ydCBcIiVzXCInLCBzZWxmLnRyYW5zcG9ydC5uYW1lKTtcbiAgICAgICAgc2VsZi50cmFuc3BvcnQucGF1c2UoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmIChmYWlsZWQpIHJldHVybjtcbiAgICAgICAgICBpZiAoJ2Nsb3NlZCcgPT09IHNlbGYucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICAgIGRlYnVnKCdjaGFuZ2luZyB0cmFuc3BvcnQgYW5kIHNlbmRpbmcgdXBncmFkZSBwYWNrZXQnKTtcblxuICAgICAgICAgIGNsZWFudXAoKTtcblxuICAgICAgICAgIHNlbGYuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG4gICAgICAgICAgdHJhbnNwb3J0LnNlbmQoW3sgdHlwZTogJ3VwZ3JhZGUnIH1dKTtcbiAgICAgICAgICBzZWxmLmVtaXQoJ3VwZ3JhZGUnLCB0cmFuc3BvcnQpO1xuICAgICAgICAgIHRyYW5zcG9ydCA9IG51bGw7XG4gICAgICAgICAgc2VsZi51cGdyYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLmZsdXNoKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgZmFpbGVkJywgbmFtZSk7XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3Byb2JlIGVycm9yJyk7XG4gICAgICAgIGVyci50cmFuc3BvcnQgPSB0cmFuc3BvcnQubmFtZTtcbiAgICAgICAgc2VsZi5lbWl0KCd1cGdyYWRlRXJyb3InLCBlcnIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZnJlZXplVHJhbnNwb3J0ICgpIHtcbiAgICBpZiAoZmFpbGVkKSByZXR1cm47XG5cbiAgICAvLyBBbnkgY2FsbGJhY2sgY2FsbGVkIGJ5IHRyYW5zcG9ydCBzaG91bGQgYmUgaWdub3JlZCBzaW5jZSBub3dcbiAgICBmYWlsZWQgPSB0cnVlO1xuXG4gICAgY2xlYW51cCgpO1xuXG4gICAgdHJhbnNwb3J0LmNsb3NlKCk7XG4gICAgdHJhbnNwb3J0ID0gbnVsbDtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhbnkgZXJyb3IgdGhhdCBoYXBwZW5zIHdoaWxlIHByb2JpbmdcbiAgZnVuY3Rpb24gb25lcnJvciAoZXJyKSB7XG4gICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdwcm9iZSBlcnJvcjogJyArIGVycik7XG4gICAgZXJyb3IudHJhbnNwb3J0ID0gdHJhbnNwb3J0Lm5hbWU7XG5cbiAgICBmcmVlemVUcmFuc3BvcnQoKTtcblxuICAgIGRlYnVnKCdwcm9iZSB0cmFuc3BvcnQgXCIlc1wiIGZhaWxlZCBiZWNhdXNlIG9mIGVycm9yOiAlcycsIG5hbWUsIGVycik7XG5cbiAgICBzZWxmLmVtaXQoJ3VwZ3JhZGVFcnJvcicsIGVycm9yKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVHJhbnNwb3J0Q2xvc2UgKCkge1xuICAgIG9uZXJyb3IoJ3RyYW5zcG9ydCBjbG9zZWQnKTtcbiAgfVxuXG4gIC8vIFdoZW4gdGhlIHNvY2tldCBpcyBjbG9zZWQgd2hpbGUgd2UncmUgcHJvYmluZ1xuICBmdW5jdGlvbiBvbmNsb3NlICgpIHtcbiAgICBvbmVycm9yKCdzb2NrZXQgY2xvc2VkJyk7XG4gIH1cblxuICAvLyBXaGVuIHRoZSBzb2NrZXQgaXMgdXBncmFkZWQgd2hpbGUgd2UncmUgcHJvYmluZ1xuICBmdW5jdGlvbiBvbnVwZ3JhZGUgKHRvKSB7XG4gICAgaWYgKHRyYW5zcG9ydCAmJiB0by5uYW1lICE9PSB0cmFuc3BvcnQubmFtZSkge1xuICAgICAgZGVidWcoJ1wiJXNcIiB3b3JrcyAtIGFib3J0aW5nIFwiJXNcIicsIHRvLm5hbWUsIHRyYW5zcG9ydC5uYW1lKTtcbiAgICAgIGZyZWV6ZVRyYW5zcG9ydCgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIG9uIHRoZSB0cmFuc3BvcnQgYW5kIG9uIHNlbGZcbiAgZnVuY3Rpb24gY2xlYW51cCAoKSB7XG4gICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdvcGVuJywgb25UcmFuc3BvcnRPcGVuKTtcbiAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uVHJhbnNwb3J0Q2xvc2UpO1xuICAgIHNlbGYucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkaW5nJywgb251cGdyYWRlKTtcbiAgfVxuXG4gIHRyYW5zcG9ydC5vbmNlKCdvcGVuJywgb25UcmFuc3BvcnRPcGVuKTtcbiAgdHJhbnNwb3J0Lm9uY2UoJ2Vycm9yJywgb25lcnJvcik7XG4gIHRyYW5zcG9ydC5vbmNlKCdjbG9zZScsIG9uVHJhbnNwb3J0Q2xvc2UpO1xuXG4gIHRoaXMub25jZSgnY2xvc2UnLCBvbmNsb3NlKTtcbiAgdGhpcy5vbmNlKCd1cGdyYWRpbmcnLCBvbnVwZ3JhZGUpO1xuXG4gIHRyYW5zcG9ydC5vcGVuKCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aGVuIGNvbm5lY3Rpb24gaXMgZGVlbWVkIG9wZW4uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgZGVidWcoJ3NvY2tldCBvcGVuJyk7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuJztcbiAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9ICd3ZWJzb2NrZXQnID09PSB0aGlzLnRyYW5zcG9ydC5uYW1lO1xuICB0aGlzLmVtaXQoJ29wZW4nKTtcbiAgdGhpcy5mbHVzaCgpO1xuXG4gIC8vIHdlIGNoZWNrIGZvciBgcmVhZHlTdGF0ZWAgaW4gY2FzZSBhbiBgb3BlbmBcbiAgLy8gbGlzdGVuZXIgYWxyZWFkeSBjbG9zZWQgdGhlIHNvY2tldFxuICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgJiYgdGhpcy51cGdyYWRlICYmIHRoaXMudHJhbnNwb3J0LnBhdXNlKSB7XG4gICAgZGVidWcoJ3N0YXJ0aW5nIHVwZ3JhZGUgcHJvYmVzJyk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLnVwZ3JhZGVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdGhpcy5wcm9iZSh0aGlzLnVwZ3JhZGVzW2ldKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogSGFuZGxlcyBhIHBhY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uUGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICBpZiAoJ29wZW5pbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgfHxcbiAgICAgICdjbG9zaW5nJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgZGVidWcoJ3NvY2tldCByZWNlaXZlOiB0eXBlIFwiJXNcIiwgZGF0YSBcIiVzXCInLCBwYWNrZXQudHlwZSwgcGFja2V0LmRhdGEpO1xuXG4gICAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xuXG4gICAgLy8gU29ja2V0IGlzIGxpdmUgLSBhbnkgcGFja2V0IGNvdW50c1xuICAgIHRoaXMuZW1pdCgnaGVhcnRiZWF0Jyk7XG5cbiAgICBzd2l0Y2ggKHBhY2tldC50eXBlKSB7XG4gICAgICBjYXNlICdvcGVuJzpcbiAgICAgICAgdGhpcy5vbkhhbmRzaGFrZShwYXJzZWpzb24ocGFja2V0LmRhdGEpKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3BvbmcnOlxuICAgICAgICB0aGlzLnNldFBpbmcoKTtcbiAgICAgICAgdGhpcy5lbWl0KCdwb25nJyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3NlcnZlciBlcnJvcicpO1xuICAgICAgICBlcnIuY29kZSA9IHBhY2tldC5kYXRhO1xuICAgICAgICB0aGlzLm9uRXJyb3IoZXJyKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ21lc3NhZ2UnOlxuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBwYWNrZXQuZGF0YSk7XG4gICAgICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIHBhY2tldC5kYXRhKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGRlYnVnKCdwYWNrZXQgcmVjZWl2ZWQgd2l0aCBzb2NrZXQgcmVhZHlTdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGhhbmRzaGFrZSBjb21wbGV0aW9uLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBoYW5kc2hha2Ugb2JqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uSGFuZHNoYWtlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5lbWl0KCdoYW5kc2hha2UnLCBkYXRhKTtcbiAgdGhpcy5pZCA9IGRhdGEuc2lkO1xuICB0aGlzLnRyYW5zcG9ydC5xdWVyeS5zaWQgPSBkYXRhLnNpZDtcbiAgdGhpcy51cGdyYWRlcyA9IHRoaXMuZmlsdGVyVXBncmFkZXMoZGF0YS51cGdyYWRlcyk7XG4gIHRoaXMucGluZ0ludGVydmFsID0gZGF0YS5waW5nSW50ZXJ2YWw7XG4gIHRoaXMucGluZ1RpbWVvdXQgPSBkYXRhLnBpbmdUaW1lb3V0O1xuICB0aGlzLm9uT3BlbigpO1xuICAvLyBJbiBjYXNlIG9wZW4gaGFuZGxlciBjbG9zZXMgc29ja2V0XG4gIGlmICgnY2xvc2VkJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSByZXR1cm47XG4gIHRoaXMuc2V0UGluZygpO1xuXG4gIC8vIFByb2xvbmcgbGl2ZW5lc3Mgb2Ygc29ja2V0IG9uIGhlYXJ0YmVhdFxuICB0aGlzLnJlbW92ZUxpc3RlbmVyKCdoZWFydGJlYXQnLCB0aGlzLm9uSGVhcnRiZWF0KTtcbiAgdGhpcy5vbignaGVhcnRiZWF0JywgdGhpcy5vbkhlYXJ0YmVhdCk7XG59O1xuXG4vKipcbiAqIFJlc2V0cyBwaW5nIHRpbWVvdXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkhlYXJ0YmVhdCA9IGZ1bmN0aW9uICh0aW1lb3V0KSB7XG4gIGNsZWFyVGltZW91dCh0aGlzLnBpbmdUaW1lb3V0VGltZXIpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHNlbGYucGluZ1RpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGlmICgnY2xvc2VkJyA9PT0gc2VsZi5yZWFkeVN0YXRlKSByZXR1cm47XG4gICAgc2VsZi5vbkNsb3NlKCdwaW5nIHRpbWVvdXQnKTtcbiAgfSwgdGltZW91dCB8fCAoc2VsZi5waW5nSW50ZXJ2YWwgKyBzZWxmLnBpbmdUaW1lb3V0KSk7XG59O1xuXG4vKipcbiAqIFBpbmdzIHNlcnZlciBldmVyeSBgdGhpcy5waW5nSW50ZXJ2YWxgIGFuZCBleHBlY3RzIHJlc3BvbnNlXG4gKiB3aXRoaW4gYHRoaXMucGluZ1RpbWVvdXRgIG9yIGNsb3NlcyBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2V0UGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBjbGVhclRpbWVvdXQoc2VsZi5waW5nSW50ZXJ2YWxUaW1lcik7XG4gIHNlbGYucGluZ0ludGVydmFsVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JpdGluZyBwaW5nIHBhY2tldCAtIGV4cGVjdGluZyBwb25nIHdpdGhpbiAlc21zJywgc2VsZi5waW5nVGltZW91dCk7XG4gICAgc2VsZi5waW5nKCk7XG4gICAgc2VsZi5vbkhlYXJ0YmVhdChzZWxmLnBpbmdUaW1lb3V0KTtcbiAgfSwgc2VsZi5waW5nSW50ZXJ2YWwpO1xufTtcblxuLyoqXG4qIFNlbmRzIGEgcGluZyBwYWNrZXQuXG4qXG4qIEBhcGkgcHJpdmF0ZVxuKi9cblxuU29ja2V0LnByb3RvdHlwZS5waW5nID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuc2VuZFBhY2tldCgncGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBzZWxmLmVtaXQoJ3BpbmcnKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIENhbGxlZCBvbiBgZHJhaW5gIGV2ZW50XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkRyYWluID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLndyaXRlQnVmZmVyLnNwbGljZSgwLCB0aGlzLnByZXZCdWZmZXJMZW4pO1xuXG4gIC8vIHNldHRpbmcgcHJldkJ1ZmZlckxlbiA9IDAgaXMgdmVyeSBpbXBvcnRhbnRcbiAgLy8gZm9yIGV4YW1wbGUsIHdoZW4gdXBncmFkaW5nLCB1cGdyYWRlIHBhY2tldCBpcyBzZW50IG92ZXIsXG4gIC8vIGFuZCBhIG5vbnplcm8gcHJldkJ1ZmZlckxlbiBjb3VsZCBjYXVzZSBwcm9ibGVtcyBvbiBgZHJhaW5gXG4gIHRoaXMucHJldkJ1ZmZlckxlbiA9IDA7XG5cbiAgaWYgKDAgPT09IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgdGhpcy5lbWl0KCdkcmFpbicpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuZmx1c2goKTtcbiAgfVxufTtcblxuLyoqXG4gKiBGbHVzaCB3cml0ZSBidWZmZXJzLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnY2xvc2VkJyAhPT0gdGhpcy5yZWFkeVN0YXRlICYmIHRoaXMudHJhbnNwb3J0LndyaXRhYmxlICYmXG4gICAgIXRoaXMudXBncmFkaW5nICYmIHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgZGVidWcoJ2ZsdXNoaW5nICVkIHBhY2tldHMgaW4gc29ja2V0JywgdGhpcy53cml0ZUJ1ZmZlci5sZW5ndGgpO1xuICAgIHRoaXMudHJhbnNwb3J0LnNlbmQodGhpcy53cml0ZUJ1ZmZlcik7XG4gICAgLy8ga2VlcCB0cmFjayBvZiBjdXJyZW50IGxlbmd0aCBvZiB3cml0ZUJ1ZmZlclxuICAgIC8vIHNwbGljZSB3cml0ZUJ1ZmZlciBhbmQgY2FsbGJhY2tCdWZmZXIgb24gYGRyYWluYFxuICAgIHRoaXMucHJldkJ1ZmZlckxlbiA9IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoO1xuICAgIHRoaXMuZW1pdCgnZmx1c2gnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZW5kcyBhIG1lc3NhZ2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQHJldHVybiB7U29ja2V0fSBmb3IgY2hhaW5pbmcuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUud3JpdGUgPVxuU29ja2V0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKG1zZywgb3B0aW9ucywgZm4pIHtcbiAgdGhpcy5zZW5kUGFja2V0KCdtZXNzYWdlJywgbXNnLCBvcHRpb25zLCBmbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZW5kcyBhIHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFja2V0IHR5cGUuXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgZnVuY3Rpb24uXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNlbmRQYWNrZXQgPSBmdW5jdGlvbiAodHlwZSwgZGF0YSwgb3B0aW9ucywgZm4pIHtcbiAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBkYXRhKSB7XG4gICAgZm4gPSBkYXRhO1xuICAgIGRhdGEgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIG9wdGlvbnMpIHtcbiAgICBmbiA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9IG51bGw7XG4gIH1cblxuICBpZiAoJ2Nsb3NpbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ2Nsb3NlZCcgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBvcHRpb25zLmNvbXByZXNzID0gZmFsc2UgIT09IG9wdGlvbnMuY29tcHJlc3M7XG5cbiAgdmFyIHBhY2tldCA9IHtcbiAgICB0eXBlOiB0eXBlLFxuICAgIGRhdGE6IGRhdGEsXG4gICAgb3B0aW9uczogb3B0aW9uc1xuICB9O1xuICB0aGlzLmVtaXQoJ3BhY2tldENyZWF0ZScsIHBhY2tldCk7XG4gIHRoaXMud3JpdGVCdWZmZXIucHVzaChwYWNrZXQpO1xuICBpZiAoZm4pIHRoaXMub25jZSgnZmx1c2gnLCBmbik7XG4gIHRoaXMuZmx1c2goKTtcbn07XG5cbi8qKlxuICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zaW5nJztcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIGlmICh0aGlzLndyaXRlQnVmZmVyLmxlbmd0aCkge1xuICAgICAgdGhpcy5vbmNlKCdkcmFpbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMudXBncmFkaW5nKSB7XG4gICAgICAgICAgd2FpdEZvclVwZ3JhZGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudXBncmFkaW5nKSB7XG4gICAgICB3YWl0Rm9yVXBncmFkZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNsb3NlICgpIHtcbiAgICBzZWxmLm9uQ2xvc2UoJ2ZvcmNlZCBjbG9zZScpO1xuICAgIGRlYnVnKCdzb2NrZXQgY2xvc2luZyAtIHRlbGxpbmcgdHJhbnNwb3J0IHRvIGNsb3NlJyk7XG4gICAgc2VsZi50cmFuc3BvcnQuY2xvc2UoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsZWFudXBBbmRDbG9zZSAoKSB7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkZScsIGNsZWFudXBBbmRDbG9zZSk7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkZUVycm9yJywgY2xlYW51cEFuZENsb3NlKTtcbiAgICBjbG9zZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gd2FpdEZvclVwZ3JhZGUgKCkge1xuICAgIC8vIHdhaXQgZm9yIHVwZ3JhZGUgdG8gZmluaXNoIHNpbmNlIHdlIGNhbid0IHNlbmQgcGFja2V0cyB3aGlsZSBwYXVzaW5nIGEgdHJhbnNwb3J0XG4gICAgc2VsZi5vbmNlKCd1cGdyYWRlJywgY2xlYW51cEFuZENsb3NlKTtcbiAgICBzZWxmLm9uY2UoJ3VwZ3JhZGVFcnJvcicsIGNsZWFudXBBbmRDbG9zZSk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IGVycm9yXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKGVycikge1xuICBkZWJ1Zygnc29ja2V0IGVycm9yICVqJywgZXJyKTtcbiAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5vbkNsb3NlKCd0cmFuc3BvcnQgZXJyb3InLCBlcnIpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiB0cmFuc3BvcnQgY2xvc2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbiwgZGVzYykge1xuICBpZiAoJ29wZW5pbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ2Nsb3NpbmcnID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICBkZWJ1Zygnc29ja2V0IGNsb3NlIHdpdGggcmVhc29uOiBcIiVzXCInLCByZWFzb24pO1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIC8vIGNsZWFyIHRpbWVyc1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnBpbmdJbnRlcnZhbFRpbWVyKTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nVGltZW91dFRpbWVyKTtcblxuICAgIC8vIHN0b3AgZXZlbnQgZnJvbSBmaXJpbmcgYWdhaW4gZm9yIHRyYW5zcG9ydFxuICAgIHRoaXMudHJhbnNwb3J0LnJlbW92ZUFsbExpc3RlbmVycygnY2xvc2UnKTtcblxuICAgIC8vIGVuc3VyZSB0cmFuc3BvcnQgd29uJ3Qgc3RheSBvcGVuXG4gICAgdGhpcy50cmFuc3BvcnQuY2xvc2UoKTtcblxuICAgIC8vIGlnbm9yZSBmdXJ0aGVyIHRyYW5zcG9ydCBjb21tdW5pY2F0aW9uXG4gICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG5cbiAgICAvLyBzZXQgcmVhZHkgc3RhdGVcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcblxuICAgIC8vIGNsZWFyIHNlc3Npb24gaWRcbiAgICB0aGlzLmlkID0gbnVsbDtcblxuICAgIC8vIGVtaXQgY2xvc2UgZXZlbnRcbiAgICB0aGlzLmVtaXQoJ2Nsb3NlJywgcmVhc29uLCBkZXNjKTtcblxuICAgIC8vIGNsZWFuIGJ1ZmZlcnMgYWZ0ZXIsIHNvIHVzZXJzIGNhbiBzdGlsbFxuICAgIC8vIGdyYWIgdGhlIGJ1ZmZlcnMgb24gYGNsb3NlYCBldmVudFxuICAgIHNlbGYud3JpdGVCdWZmZXIgPSBbXTtcbiAgICBzZWxmLnByZXZCdWZmZXJMZW4gPSAwO1xuICB9XG59O1xuXG4vKipcbiAqIEZpbHRlcnMgdXBncmFkZXMsIHJldHVybmluZyBvbmx5IHRob3NlIG1hdGNoaW5nIGNsaWVudCB0cmFuc3BvcnRzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHNlcnZlciB1cGdyYWRlc1xuICogQGFwaSBwcml2YXRlXG4gKlxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZmlsdGVyVXBncmFkZXMgPSBmdW5jdGlvbiAodXBncmFkZXMpIHtcbiAgdmFyIGZpbHRlcmVkVXBncmFkZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGogPSB1cGdyYWRlcy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcbiAgICBpZiAofmluZGV4KHRoaXMudHJhbnNwb3J0cywgdXBncmFkZXNbaV0pKSBmaWx0ZXJlZFVwZ3JhZGVzLnB1c2godXBncmFkZXNbaV0pO1xuICB9XG4gIHJldHVybiBmaWx0ZXJlZFVwZ3JhZGVzO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0112\n")},"0352":function(module,exports,__webpack_require__){eval('// https://crossfilter.github.io/crossfilter/ v1.5.4 Copyright 2020 Mike Bostock\n!function(r,e){ true?module.exports=e():undefined}(this,(function(){"use strict";let r=o,e=o,n=o,t=f,u=i;function o(r){for(var e=new Array(r),n=-1;++n<r;)e[n]=0;return e}function f(r,e){for(var n=r.length;n<e;)r[n++]=0;return r}function i(r,e){if(e>32)throw new Error("invalid array width!");return r}function a(e){this.length=e,this.subarrays=1,this.width=8,this.masks={0:0},this[0]=r(e)}"undefined"!=typeof Uint8Array&&(r=function(r){return new Uint8Array(r)},e=function(r){return new Uint16Array(r)},n=function(r){return new Uint32Array(r)},t=function(r,e){if(r.length>=e)return r;var n=new r.constructor(e);return n.set(r),n},u=function(r,t){var u;switch(t){case 16:u=e(r.length);break;case 32:u=n(r.length);break;default:throw new Error("invalid array width!")}return u.set(r),u}),a.prototype.lengthen=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)this[e]=t(this[e],r);this.length=r},a.prototype.add=function(){var e,n,t,o,f;for(o=0,f=this.subarrays;o<f;++o)if(t=(~(e=this.masks[o])&e+1)>>>0,!((n=this.width-32*o)>=32)||t)return n<32&&t&1<<n&&(this[o]=u(this[o],n<<=1),this.width=32*o+n),this.masks[o]|=t,{offset:o,one:t};return this[this.subarrays]=r(this.length),this.masks[this.subarrays]=1,this.width+=8,{offset:this.subarrays++,one:1}},a.prototype.copy=function(r,e){var n,t;for(n=0,t=this.subarrays;n<t;++n)this[n][r]=this[n][e]},a.prototype.truncate=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)for(var t=this.length-1;t>=r;t--)this[e][t]=0;this.length=r},a.prototype.zero=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)if(this[e][r])return!1;return!0},a.prototype.zeroExcept=function(r,e,n){var t,u;for(t=0,u=this.subarrays;t<u;++t)if(t===e?this[t][r]&n:this[t][r])return!1;return!0},a.prototype.zeroExceptMask=function(r,e){var n,t;for(n=0,t=this.subarrays;n<t;++n)if(this[n][r]&e[n])return!1;return!0},a.prototype.only=function(r,e,n){var t,u;for(t=0,u=this.subarrays;t<u;++t)if(this[t][r]!=(t===e?n:0))return!1;return!0},a.prototype.onlyExcept=function(r,e,n,t,u){var o,f,i;for(f=0,i=this.subarrays;f<i;++f)if(o=this[f][r],f===e&&(o=(o&n)>>>0),o!=(f===t?u:0))return!1;return!0};var l={array8:o,array16:o,array32:o,arrayLengthen:f,arrayWiden:i,bitarray:a};var s={filterExact:(r,e)=>(function(n){var t=n.length;return[r.left(n,e,0,t),r.right(n,e,0,t)]}),filterRange:(r,e)=>{var n=e[0],t=e[1];return function(e){var u=e.length;return[r.left(e,n,0,u),r.left(e,t,0,u)]}},filterAll:r=>[0,r.length]},c=r=>r,h=()=>null,v=()=>0;function p(r){function e(r,e,t){for(var u=t-e,o=1+(u>>>1);--o>0;)n(r,o,u,e);return r}function n(e,n,t,u){for(var o,f=e[--u+n],i=r(f);(o=n<<1)<=t&&(o<t&&r(e[u+o])>r(e[u+o+1])&&o++,!(i<=r(e[u+o])));)e[u+n]=e[u+o],n=o;e[u+n]=f}return e.sort=function(r,e,t){for(var u,o=t-e;--o>0;)u=r[e],r[e]=r[e+o],r[e+o]=u,n(r,1,o,e);return r},e}const d=p(c);function g(r){var e=d.by(r);return function(n,t,u,o){var f,i,a,l=new Array(o=Math.min(u-t,o));for(i=0;i<o;++i)l[i]=n[t++];if(e(l,0,o),t<u){f=r(l[0]);do{r(a=n[t])>f&&(l[0]=a,f=r(e(l,0,o)[0]))}while(++t<u)}return l}}d.by=p;const y=g(c);function x(r){function e(e,n,t,u){for(;t<u;){var o=t+u>>>1;n<r(e[o])?u=o:t=o+1}return t}return e.right=e,e.left=function(e,n,t,u){for(;t<u;){var o=t+u>>>1;r(e[o])<n?t=o+1:u=o}return t},e}y.by=g;const b=x(c);b.by=x;var m=(r,e,n)=>{for(var t=0,u=e.length,o=n?JSON.parse(JSON.stringify(r)):new Array(u);t<u;++t)o[t]=r[e[t]];return o};var E={reduceIncrement:r=>r+1,reduceDecrement:r=>r-1,reduceAdd:r=>(function(e,n){return e+ +r(n)}),reduceSubtract:r=>(function(e,n){return e-r(n)})};const w=(r,e)=>{const n=r[e];return"function"==typeof n?n.call(r):n},A=/\\[([\\w\\d]+)\\]/g;var z=(r,e)=>(function(r,e,n,t,u){for(u in t=(n=n.split(".")).splice(-1,1),n)e=e[n[u]]=e[n[u]]||{};return r(e,t)})(w,r,e.replace(A,".$1")),k=-1;function O(){var r,e={add:a,remove:function(e){for(var o=new Array(t),i=[],a="function"==typeof e,l=0,s=0;l<t;++l)c=l,(a?e(n[c],c):r.zero(c))?(i.push(l),o[l]=k):o[l]=s++;var c;u.forEach((function(r){r(-1,-1,[],i,!0)})),f.forEach((function(r){r(o)}));for(var h=0,v=0;h<t;++h)o[h]!==k&&(h!==v&&(r.copy(v,h),n[v]=n[h]),++v);n.length=t=v,r.truncate(v),g("dataRemoved")},dimension:function(e,i){if("string"==typeof e){var a=e;e=function(r){return z(r,a)}}var p,x,w,A,O,F,N,R,U,D,I,L,W,J,j={filter:function(r){return null==r?er():Array.isArray(r)?rr(r):"function"==typeof r?nr(r):_(r)},filterExact:_,filterRange:rr,filterFunction:nr,filterAll:er,currentFilter:function(){return L},hasCurrentFilter:function(){return W},top:function(e,t){var u,o=[],f=P,a=0;t&&t>0&&(a=t);for(;--f>=K&&e>0;)r.zero(u=F[f])&&(a>0?--a:(o.push(n[u]),--e));if(i)for(f=0;f<$.length&&e>0;f++)r.zero(u=$[f])&&(a>0?--a:(o.push(n[u]),--e));return o},bottom:function(e,t){var u,o,f=[],a=0;t&&t>0&&(a=t);if(i)for(u=0;u<$.length&&e>0;u++)r.zero(o=$[u])&&(a>0?--a:(f.push(n[o]),--e));u=K;for(;u<P&&e>0;)r.zero(o=F[u])&&(a>0?--a:(f.push(n[o]),--e)),u++;return f},group:ur,groupAll:function(){var r=ur(h),e=r.all;return delete r.all,delete r.top,delete r.order,delete r.orderNatural,delete r.size,r.value=function(){return e()[0].value},r},dispose:or,remove:or,accessor:e,id:function(){return A}},$=[],q=function(r){return S(r).sort((function(r,e){var n=N[r],t=N[e];return n<t?-1:n>t?1:r-e}))},B=s.filterAll,G=[],H=[],K=0,P=0,Q=0;o.unshift(V),o.push(X),f.push(Y);var T=r.add();function V(n,u,o){var f,a;if(i){Q=0,G=0,J=[];for(var s=0;s<n.length;s++)for(G=0,J=e(n[s]);G<J.length;G++)Q++;N=[],f=S(n.length),a=M(Q,1);for(var c=S(Q),h=0,v=0;v<n.length;v++)if((J=e(n[v])).length)for(f[v]=J.length,G=0;G<J.length;G++)N.push(J[G]),c[h]=v,h++;else f[v]=0,$.push(v+u);var d=q(Q);N=m(N,d),R=m(c,d)}else N=n.map(e),R=q(o),N=m(N,R);var g,y,x,b=B(N),E=b[0],A=b[1];if(i)if(o=Q,I)for(g=0;g<o;++g)I(N[g],g)||(0==--f[R[g]]&&(r[w][R[g]+u]|=p),a[g]=1);else{for(y=0;y<E;++y)0==--f[R[y]]&&(r[w][R[y]+u]|=p),a[y]=1;for(x=A;x<o;++x)0==--f[R[x]]&&(r[w][R[x]+u]|=p),a[x]=1}else if(I)for(g=0;g<o;++g)I(N[g],g)||(r[w][R[g]+u]|=p);else{for(y=0;y<E;++y)r[w][R[y]+u]|=p;for(x=A;x<o;++x)r[w][R[x]+u]|=p}if(!u)return O=N,F=R,U=f,D=a,K=E,void(P=A);var z,k=O,C=F,L=D,W=0;if(s=0,i&&(z=u,u=k.length,o=Q),O=new Array(i?u+o:t),F=i?new Array(u+o):M(t,t),i&&(D=M(u+o,1)),i){var j=U.length;U=l.arrayLengthen(U,t);for(var G=0;G+j<t;G++)U[G+j]=f[G]}for(var H=0;s<u&&W<o;++H)k[s]<N[W]?(O[H]=k[s],i&&(D[H]=L[s]),F[H]=C[s++]):(O[H]=N[W],i&&(D[H]=a[W]),F[H]=R[W++]+(i?z:u));for(;s<u;++s,++H)O[H]=k[s],i&&(D[H]=L[s]),F[H]=C[s];for(;W<o;++W,++H)O[H]=N[W],i&&(D[H]=a[W]),F[H]=R[W]+(i?z:u);b=B(O),K=b[0],P=b[1]}function X(r,e,n){G.forEach((function(r){r(N,R,e,n)})),N=R=null}function Y(r){if(i){for(var e=0,n=0;e<$.length;e++)r[$[e]]!==k&&($[n]=r[$[e]],n++);for($.length=n,e=0,n=0;e<t;e++)r[e]!==k&&(n!==e&&(U[n]=U[e]),n++);U=U.slice(0,n)}for(var u,o=O.length,f=0,a=0;f<o;++f)r[u=F[f]]!==k&&(f!==a&&(O[a]=O[f]),F[a]=r[u],i&&(D[a]=D[f]),++a);for(O.length=a,i&&(D=D.slice(0,a));a<o;)F[a++]=0;var l=B(O);K=l[0],P=l[1]}function Z(e){var n=e[0],t=e[1];if(I)return I=null,tr((function(r,e){return n<=e&&e<t}),0===e[0]&&e[1]===O.length),K=n,P=t,j;var o,f,a,l=[],c=[],h=[],v=[];if(n<K)for(o=n,f=Math.min(K,t);o<f;++o)l.push(F[o]),h.push(o);else if(n>K)for(o=K,f=Math.min(n,P);o<f;++o)c.push(F[o]),v.push(o);if(t>P)for(o=Math.max(n,P),f=t;o<f;++o)l.push(F[o]),h.push(o);else if(t<P)for(o=Math.max(K,t),f=P;o<f;++o)c.push(F[o]),v.push(o);if(i){var d=[],y=[];for(o=0;o<l.length;o++)U[l[o]]++,D[h[o]]=0,1===U[l[o]]&&(r[w][l[o]]^=p,d.push(l[o]));for(o=0;o<c.length;o++)U[c[o]]--,D[v[o]]=1,0===U[c[o]]&&(r[w][c[o]]^=p,y.push(c[o]));if(l=d,c=y,B===s.filterAll)for(o=0;o<$.length;o++)r[w][a=$[o]]&p&&(r[w][a]^=p,l.push(a));else for(o=0;o<$.length;o++)r[w][a=$[o]]&p||(r[w][a]^=p,c.push(a))}else{for(o=0;o<l.length;o++)r[w][l[o]]^=p;for(o=0;o<c.length;o++)r[w][c[o]]^=p}return K=n,P=t,u.forEach((function(r){r(p,w,l,c)})),g("filtered"),j}function _(r){return L=r,W=!0,Z((B=s.filterExact(b,r))(O))}function rr(r){return L=r,W=!0,Z((B=s.filterRange(b,r))(O))}function er(){return L=void 0,W=!1,Z((B=s.filterAll)(O))}function nr(r){L=r,W=!0,I=r,B=s.filterAll,tr(r,!1);var e=B(O);return K=e[0],P=e[1],j}function tr(e,n){var t,o,f,a=[],l=[],s=[],c=[],h=O.length;if(!i)for(t=0;t<h;++t)!(r[w][o=F[t]]&p)^!!(f=e(O[t],t))&&(f?a.push(o):l.push(o));if(i)for(t=0;t<h;++t)e(O[t],t)?(a.push(F[t]),s.push(t)):(l.push(F[t]),c.push(t));if(i){var v=[],d=[];for(t=0;t<a.length;t++)1===D[s[t]]&&(U[a[t]]++,D[s[t]]=0,1===U[a[t]]&&(r[w][a[t]]^=p,v.push(a[t])));for(t=0;t<l.length;t++)0===D[c[t]]&&(U[l[t]]--,D[c[t]]=1,0===U[l[t]]&&(r[w][l[t]]^=p,d.push(l[t])));if(a=v,l=d,n)for(t=0;t<$.length;t++)r[w][o=$[t]]&p&&(r[w][o]^=p,a.push(o));else for(t=0;t<$.length;t++)r[w][o=$[t]]&p||(r[w][o]^=p,l.push(o))}else{for(t=0;t<a.length;t++)r[w][a[t]]&p&&(r[w][a[t]]&=x);for(t=0;t<l.length;t++)r[w][l[t]]&p||(r[w][l[t]]|=p)}u.forEach((function(r){r(p,w,a,l)})),g("filtered")}function ur(e){var o={top:function(r){var e=g(P(),0,a.length,r);return b.sort(e,0,e.length)},all:P,reduce:Q,reduceCount:T,reduceSum:function(r){return Q(E.reduceAdd(r),E.reduceSubtract(r),v)},order:V,orderNatural:function(){return V(c)},size:function(){return U},dispose:X,remove:X};H.push(o);var a,s,g,b,m,A,z,S,N=8,R=C(N),U=0,D=h,I=h,L=!0,W=e===h;function J(o,f,c,v){i&&(S=c,c=O.length-o.length,v=o.length);var p,d,g,y,b,E,k=a,F=i?[]:M(U,R),J=m,j=A,G=z,H=U,P=0,Q=0;for(L&&(J=G=h),L&&(j=G=h),a=new Array(U),U=0,s=i?H?s:[]:H>1?l.arrayLengthen(s,t):M(t,R),H&&(g=(d=k[0]).key);Q<v&&!((y=e(o[Q]))>=y);)++Q;for(;Q<v;){for(d&&g<=y?(b=d,E=g,F[P]=U,(d=k[++P])&&(g=d.key)):(b={key:y,value:G()},E=y),a[U]=b;y<=E&&(p=f[Q]+(i?S:c),i?s[p]?s[p].push(U):s[p]=[U]:s[p]=U,b.value=J(b.value,n[p],!0),r.zeroExcept(p,w,x)||(b.value=j(b.value,n[p],!1)),!(++Q>=v));)y=e(o[Q]);V()}for(;P<H;)a[F[P]=U]=k[P++],V();if(i)for(var T=0;T<t;T++)s[T]||(s[T]=[]);if(U>P)if(i)for(P=0;P<S;++P)for(T=0;T<s[P].length;T++)s[P][T]=F[s[P][T]];else for(P=0;P<c;++P)s[P]=F[s[P]];function V(){i?U++:++U===R&&(F=l.arrayWiden(F,N<<=1),s=l.arrayWiden(s,N),R=C(N))}p=u.indexOf(D),U>1||i?(D=$,I=B):(!U&&W&&(U=1,a=[{key:null,value:G()}]),1===U?(D=q,I=K):(D=h,I=h),s=null),u[p]=D}function j(r){if(U>1||i){var e,n,o,f=U,l=a,c=M(f,f);if(i){for(e=0,o=0;e<t;++e)if(r[e]!==k){for(s[o]=s[e],n=0;n<s[o].length;n++)c[s[o][n]]=1;++o}s=s.slice(0,o)}else for(e=0,o=0;e<t;++e)r[e]!==k&&(c[s[o]=s[e]]=1,++o);for(a=[],U=0,e=0;e<f;++e)c[e]&&(c[e]=U++,a.push(l[e]));if(U>1||i)if(i)for(e=0;e<o;++e)for(n=0;n<s[e].length;++n)s[e][n]=c[s[e][n]];else for(e=0;e<o;++e)s[e]=c[s[e]];else s=null;u[u.indexOf(D)]=U>1||i?(I=B,D=$):1===U?(I=K,D=q):I=D=h}else if(1===U){if(W)return;for(var v=0;v<t;++v)if(r[v]!==k)return;a=[],U=0,u[u.indexOf(D)]=D=I=h}}function $(e,t,u,o,f){var l,c,h,v,d;if(!(e===p&&t===w||L))if(i){for(l=0,v=u.length;l<v;++l)if(r.zeroExcept(h=u[l],w,x))for(c=0;c<s[h].length;c++)(d=a[s[h][c]]).value=m(d.value,n[h],!1,c);for(l=0,v=o.length;l<v;++l)if(r.onlyExcept(h=o[l],w,x,t,e))for(c=0;c<s[h].length;c++)(d=a[s[h][c]]).value=A(d.value,n[h],f,c)}else{for(l=0,v=u.length;l<v;++l)r.zeroExcept(h=u[l],w,x)&&((d=a[s[h]]).value=m(d.value,n[h],!1));for(l=0,v=o.length;l<v;++l)r.onlyExcept(h=o[l],w,x,t,e)&&((d=a[s[h]]).value=A(d.value,n[h],f))}}function q(e,t,u,o,f){if(!(e===p&&t===w||L)){var i,l,s,c=a[0];for(i=0,s=u.length;i<s;++i)r.zeroExcept(l=u[i],w,x)&&(c.value=m(c.value,n[l],!1));for(i=0,s=o.length;i<s;++i)r.onlyExcept(l=o[i],w,x,t,e)&&(c.value=A(c.value,n[l],f))}}function B(){var e,u,o;for(e=0;e<U;++e)a[e].value=z();if(i){for(e=0;e<t;++e)for(u=0;u<s[e].length;u++)(o=a[s[e][u]]).value=m(o.value,n[e],!0,u);for(e=0;e<t;++e)if(!r.zeroExcept(e,w,x))for(u=0;u<s[e].length;u++)(o=a[s[e][u]]).value=A(o.value,n[e],!1,u)}else{for(e=0;e<t;++e)(o=a[s[e]]).value=m(o.value,n[e],!0);for(e=0;e<t;++e)r.zeroExcept(e,w,x)||((o=a[s[e]]).value=A(o.value,n[e],!1))}}function K(){var e,u=a[0];for(u.value=z(),e=0;e<t;++e)u.value=m(u.value,n[e],!0);for(e=0;e<t;++e)r.zeroExcept(e,w,x)||(u.value=A(u.value,n[e],!1))}function P(){return L&&(I(),L=!1),a}function Q(r,e,n){return m=r,A=e,z=n,L=!0,o}function T(){return Q(E.reduceIncrement,E.reduceDecrement,v)}function V(r){function e(e){return r(e.value)}return g=y.by(e),b=d.by(e),o}function X(){var r=u.indexOf(D);return r>=0&&u.splice(r,1),(r=G.indexOf(J))>=0&&G.splice(r,1),(r=f.indexOf(j))>=0&&f.splice(r,1),(r=H.indexOf(o))>=0&&H.splice(r,1),o}return arguments.length<1&&(e=c),u.push(D),G.push(J),f.push(j),J(O,F,0,t),T().orderNatural()}function or(){H.forEach((function(r){r.dispose()}));var e=o.indexOf(V);return e>=0&&o.splice(e,1),(e=o.indexOf(X))>=0&&o.splice(e,1),(e=f.indexOf(Y))>=0&&f.splice(e,1),r.masks[w]&=x,er()}return w=T.offset,p=T.one,x=~p,A=w<<7|Math.log(p)/Math.log(2),V(n,0,t),X(n,0,t),j},groupAll:function(){var e,f,i,a,l={reduce:p,reduceCount:d,reduceSum:function(r){return p(E.reduceAdd(r),E.reduceSubtract(r),v)},value:function(){s&&(function(){var u;for(e=a(),u=0;u<t;++u)e=f(e,n[u],!0),r.zero(u)||(e=i(e,n[u],!1))}(),s=!1);return e},dispose:g,remove:g},s=!0;function c(u,o){var a;if(!s)for(a=o;a<t;++a)e=f(e,n[a],!0),r.zero(a)||(e=i(e,n[a],!1))}function h(t,u,o,a,l){var c,h,v;if(!s){for(c=0,v=o.length;c<v;++c)r.zero(h=o[c])&&(e=f(e,n[h],l));for(c=0,v=a.length;c<v;++c)r.only(h=a[c],u,t)&&(e=i(e,n[h],l))}}function p(r,e,n){return f=r,i=e,a=n,s=!0,l}function d(){return p(E.reduceIncrement,E.reduceDecrement,v)}function g(){var r=u.indexOf(h);return r>=0&&u.splice(r,1),(r=o.indexOf(c))>=0&&o.splice(r,1),l}return(u.push(h),o.push(c),c(n,0),d())},size:function(){return t},all:function(){return n},allFiltered:function(e){var u=[],o=0,f=p(e||[]);for(o=0;o<t;o++)r.zeroExceptMask(o,f)&&u.push(n[o]);return u},onChange:function(r){if("function"!=typeof r)return void console.warn("onChange callback parameter must be a function!");return i.push(r),function(){i.splice(i.indexOf(r),1)}},isElementFiltered:function(e,n){var t=p(n||[]);return r.zeroExceptMask(e,t)}},n=[],t=0,u=[],o=[],f=[],i=[];function a(u){var f=t,i=u.length;return i&&(n=n.concat(u),r.lengthen(t+=i),o.forEach((function(r){r(u,f,i)})),g("dataAdded")),e}function p(e){var n,t,u,o,f=Array(r.subarrays);for(n=0;n<r.subarrays;n++)f[n]=-1;for(t=0,u=e.length;t<u;t++)f[(o=e[t].id())>>7]&=~(1<<(63&o));return f}function g(r){for(var e=0;e<i.length;e++)i[e](r)}return r=new l.bitarray(0),arguments.length?a(arguments[0]):e}function M(r,e){return(e<257?l.array8:e<65537?l.array16:l.array32)(r)}function S(r){for(var e=M(r,r),n=-1;++n<r;)e[n]=n;return e}function C(r){return 8===r?256:16===r?65536:4294967296}O.heap=d,O.heapselect=y,O.bisect=b,O.permute=m;return O.version="1.5.4",O}));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDM1Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvY3Jvc3NmaWx0ZXIyL2Nyb3NzZmlsdGVyLm1pbi5qcz82ZTBjIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIGh0dHBzOi8vY3Jvc3NmaWx0ZXIuZ2l0aHViLmlvL2Nyb3NzZmlsdGVyLyB2MS41LjQgQ29weXJpZ2h0IDIwMjAgTWlrZSBCb3N0b2NrXG4hZnVuY3Rpb24ocixlKXtcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1lKCk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShlKToocj1yfHxzZWxmKS5jcm9zc2ZpbHRlcj1lKCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7bGV0IHI9byxlPW8sbj1vLHQ9Zix1PWk7ZnVuY3Rpb24gbyhyKXtmb3IodmFyIGU9bmV3IEFycmF5KHIpLG49LTE7KytuPHI7KWVbbl09MDtyZXR1cm4gZX1mdW5jdGlvbiBmKHIsZSl7Zm9yKHZhciBuPXIubGVuZ3RoO248ZTspcltuKytdPTA7cmV0dXJuIHJ9ZnVuY3Rpb24gaShyLGUpe2lmKGU+MzIpdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBhcnJheSB3aWR0aCFcIik7cmV0dXJuIHJ9ZnVuY3Rpb24gYShlKXt0aGlzLmxlbmd0aD1lLHRoaXMuc3ViYXJyYXlzPTEsdGhpcy53aWR0aD04LHRoaXMubWFza3M9ezA6MH0sdGhpc1swXT1yKGUpfVwidW5kZWZpbmVkXCIhPXR5cGVvZiBVaW50OEFycmF5JiYocj1mdW5jdGlvbihyKXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkocil9LGU9ZnVuY3Rpb24ocil7cmV0dXJuIG5ldyBVaW50MTZBcnJheShyKX0sbj1mdW5jdGlvbihyKXtyZXR1cm4gbmV3IFVpbnQzMkFycmF5KHIpfSx0PWZ1bmN0aW9uKHIsZSl7aWYoci5sZW5ndGg+PWUpcmV0dXJuIHI7dmFyIG49bmV3IHIuY29uc3RydWN0b3IoZSk7cmV0dXJuIG4uc2V0KHIpLG59LHU9ZnVuY3Rpb24ocix0KXt2YXIgdTtzd2l0Y2godCl7Y2FzZSAxNjp1PWUoci5sZW5ndGgpO2JyZWFrO2Nhc2UgMzI6dT1uKHIubGVuZ3RoKTticmVhaztkZWZhdWx0OnRocm93IG5ldyBFcnJvcihcImludmFsaWQgYXJyYXkgd2lkdGghXCIpfXJldHVybiB1LnNldChyKSx1fSksYS5wcm90b3R5cGUubGVuZ3RoZW49ZnVuY3Rpb24ocil7dmFyIGUsbjtmb3IoZT0wLG49dGhpcy5zdWJhcnJheXM7ZTxuOysrZSl0aGlzW2VdPXQodGhpc1tlXSxyKTt0aGlzLmxlbmd0aD1yfSxhLnByb3RvdHlwZS5hZGQ9ZnVuY3Rpb24oKXt2YXIgZSxuLHQsbyxmO2ZvcihvPTAsZj10aGlzLnN1YmFycmF5cztvPGY7KytvKWlmKHQ9KH4oZT10aGlzLm1hc2tzW29dKSZlKzEpPj4+MCwhKChuPXRoaXMud2lkdGgtMzIqbyk+PTMyKXx8dClyZXR1cm4gbjwzMiYmdCYxPDxuJiYodGhpc1tvXT11KHRoaXNbb10sbjw8PTEpLHRoaXMud2lkdGg9MzIqbytuKSx0aGlzLm1hc2tzW29dfD10LHtvZmZzZXQ6byxvbmU6dH07cmV0dXJuIHRoaXNbdGhpcy5zdWJhcnJheXNdPXIodGhpcy5sZW5ndGgpLHRoaXMubWFza3NbdGhpcy5zdWJhcnJheXNdPTEsdGhpcy53aWR0aCs9OCx7b2Zmc2V0OnRoaXMuc3ViYXJyYXlzKyssb25lOjF9fSxhLnByb3RvdHlwZS5jb3B5PWZ1bmN0aW9uKHIsZSl7dmFyIG4sdDtmb3Iobj0wLHQ9dGhpcy5zdWJhcnJheXM7bjx0Oysrbil0aGlzW25dW3JdPXRoaXNbbl1bZV19LGEucHJvdG90eXBlLnRydW5jYXRlPWZ1bmN0aW9uKHIpe3ZhciBlLG47Zm9yKGU9MCxuPXRoaXMuc3ViYXJyYXlzO2U8bjsrK2UpZm9yKHZhciB0PXRoaXMubGVuZ3RoLTE7dD49cjt0LS0pdGhpc1tlXVt0XT0wO3RoaXMubGVuZ3RoPXJ9LGEucHJvdG90eXBlLnplcm89ZnVuY3Rpb24ocil7dmFyIGUsbjtmb3IoZT0wLG49dGhpcy5zdWJhcnJheXM7ZTxuOysrZSlpZih0aGlzW2VdW3JdKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS56ZXJvRXhjZXB0PWZ1bmN0aW9uKHIsZSxuKXt2YXIgdCx1O2Zvcih0PTAsdT10aGlzLnN1YmFycmF5czt0PHU7Kyt0KWlmKHQ9PT1lP3RoaXNbdF1bcl0mbjp0aGlzW3RdW3JdKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS56ZXJvRXhjZXB0TWFzaz1mdW5jdGlvbihyLGUpe3ZhciBuLHQ7Zm9yKG49MCx0PXRoaXMuc3ViYXJyYXlzO248dDsrK24paWYodGhpc1tuXVtyXSZlW25dKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS5vbmx5PWZ1bmN0aW9uKHIsZSxuKXt2YXIgdCx1O2Zvcih0PTAsdT10aGlzLnN1YmFycmF5czt0PHU7Kyt0KWlmKHRoaXNbdF1bcl0hPSh0PT09ZT9uOjApKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS5vbmx5RXhjZXB0PWZ1bmN0aW9uKHIsZSxuLHQsdSl7dmFyIG8sZixpO2ZvcihmPTAsaT10aGlzLnN1YmFycmF5cztmPGk7KytmKWlmKG89dGhpc1tmXVtyXSxmPT09ZSYmKG89KG8mbik+Pj4wKSxvIT0oZj09PXQ/dTowKSlyZXR1cm4hMTtyZXR1cm4hMH07dmFyIGw9e2FycmF5ODpvLGFycmF5MTY6byxhcnJheTMyOm8sYXJyYXlMZW5ndGhlbjpmLGFycmF5V2lkZW46aSxiaXRhcnJheTphfTt2YXIgcz17ZmlsdGVyRXhhY3Q6KHIsZSk9PihmdW5jdGlvbihuKXt2YXIgdD1uLmxlbmd0aDtyZXR1cm5bci5sZWZ0KG4sZSwwLHQpLHIucmlnaHQobixlLDAsdCldfSksZmlsdGVyUmFuZ2U6KHIsZSk9Pnt2YXIgbj1lWzBdLHQ9ZVsxXTtyZXR1cm4gZnVuY3Rpb24oZSl7dmFyIHU9ZS5sZW5ndGg7cmV0dXJuW3IubGVmdChlLG4sMCx1KSxyLmxlZnQoZSx0LDAsdSldfX0sZmlsdGVyQWxsOnI9PlswLHIubGVuZ3RoXX0sYz1yPT5yLGg9KCk9Pm51bGwsdj0oKT0+MDtmdW5jdGlvbiBwKHIpe2Z1bmN0aW9uIGUocixlLHQpe2Zvcih2YXIgdT10LWUsbz0xKyh1Pj4+MSk7LS1vPjA7KW4ocixvLHUsZSk7cmV0dXJuIHJ9ZnVuY3Rpb24gbihlLG4sdCx1KXtmb3IodmFyIG8sZj1lWy0tdStuXSxpPXIoZik7KG89bjw8MSk8PXQmJihvPHQmJnIoZVt1K29dKT5yKGVbdStvKzFdKSYmbysrLCEoaTw9cihlW3Urb10pKSk7KWVbdStuXT1lW3Urb10sbj1vO2VbdStuXT1mfXJldHVybiBlLnNvcnQ9ZnVuY3Rpb24ocixlLHQpe2Zvcih2YXIgdSxvPXQtZTstLW8+MDspdT1yW2VdLHJbZV09cltlK29dLHJbZStvXT11LG4ociwxLG8sZSk7cmV0dXJuIHJ9LGV9Y29uc3QgZD1wKGMpO2Z1bmN0aW9uIGcocil7dmFyIGU9ZC5ieShyKTtyZXR1cm4gZnVuY3Rpb24obix0LHUsbyl7dmFyIGYsaSxhLGw9bmV3IEFycmF5KG89TWF0aC5taW4odS10LG8pKTtmb3IoaT0wO2k8bzsrK2kpbFtpXT1uW3QrK107aWYoZShsLDAsbyksdDx1KXtmPXIobFswXSk7ZG97cihhPW5bdF0pPmYmJihsWzBdPWEsZj1yKGUobCwwLG8pWzBdKSl9d2hpbGUoKyt0PHUpfXJldHVybiBsfX1kLmJ5PXA7Y29uc3QgeT1nKGMpO2Z1bmN0aW9uIHgocil7ZnVuY3Rpb24gZShlLG4sdCx1KXtmb3IoO3Q8dTspe3ZhciBvPXQrdT4+PjE7bjxyKGVbb10pP3U9bzp0PW8rMX1yZXR1cm4gdH1yZXR1cm4gZS5yaWdodD1lLGUubGVmdD1mdW5jdGlvbihlLG4sdCx1KXtmb3IoO3Q8dTspe3ZhciBvPXQrdT4+PjE7cihlW29dKTxuP3Q9bysxOnU9b31yZXR1cm4gdH0sZX15LmJ5PWc7Y29uc3QgYj14KGMpO2IuYnk9eDt2YXIgbT0ocixlLG4pPT57Zm9yKHZhciB0PTAsdT1lLmxlbmd0aCxvPW4/SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyKSk6bmV3IEFycmF5KHUpO3Q8dTsrK3Qpb1t0XT1yW2VbdF1dO3JldHVybiBvfTt2YXIgRT17cmVkdWNlSW5jcmVtZW50OnI9PnIrMSxyZWR1Y2VEZWNyZW1lbnQ6cj0+ci0xLHJlZHVjZUFkZDpyPT4oZnVuY3Rpb24oZSxuKXtyZXR1cm4gZSsgK3Iobil9KSxyZWR1Y2VTdWJ0cmFjdDpyPT4oZnVuY3Rpb24oZSxuKXtyZXR1cm4gZS1yKG4pfSl9O2NvbnN0IHc9KHIsZSk9Pntjb25zdCBuPXJbZV07cmV0dXJuXCJmdW5jdGlvblwiPT10eXBlb2Ygbj9uLmNhbGwocik6bn0sQT0vXFxbKFtcXHdcXGRdKylcXF0vZzt2YXIgej0ocixlKT0+KGZ1bmN0aW9uKHIsZSxuLHQsdSl7Zm9yKHUgaW4gdD0obj1uLnNwbGl0KFwiLlwiKSkuc3BsaWNlKC0xLDEpLG4pZT1lW25bdV1dPWVbblt1XV18fHt9O3JldHVybiByKGUsdCl9KSh3LHIsZS5yZXBsYWNlKEEsXCIuJDFcIikpLGs9LTE7ZnVuY3Rpb24gTygpe3ZhciByLGU9e2FkZDphLHJlbW92ZTpmdW5jdGlvbihlKXtmb3IodmFyIG89bmV3IEFycmF5KHQpLGk9W10sYT1cImZ1bmN0aW9uXCI9PXR5cGVvZiBlLGw9MCxzPTA7bDx0OysrbCljPWwsKGE/ZShuW2NdLGMpOnIuemVybyhjKSk/KGkucHVzaChsKSxvW2xdPWspOm9bbF09cysrO3ZhciBjO3UuZm9yRWFjaCgoZnVuY3Rpb24ocil7cigtMSwtMSxbXSxpLCEwKX0pKSxmLmZvckVhY2goKGZ1bmN0aW9uKHIpe3Iobyl9KSk7Zm9yKHZhciBoPTAsdj0wO2g8dDsrK2gpb1toXSE9PWsmJihoIT09diYmKHIuY29weSh2LGgpLG5bdl09bltoXSksKyt2KTtuLmxlbmd0aD10PXYsci50cnVuY2F0ZSh2KSxnKFwiZGF0YVJlbW92ZWRcIil9LGRpbWVuc2lvbjpmdW5jdGlvbihlLGkpe2lmKFwic3RyaW5nXCI9PXR5cGVvZiBlKXt2YXIgYT1lO2U9ZnVuY3Rpb24ocil7cmV0dXJuIHoocixhKX19dmFyIHAseCx3LEEsTyxGLE4sUixVLEQsSSxMLFcsSixqPXtmaWx0ZXI6ZnVuY3Rpb24ocil7cmV0dXJuIG51bGw9PXI/ZXIoKTpBcnJheS5pc0FycmF5KHIpP3JyKHIpOlwiZnVuY3Rpb25cIj09dHlwZW9mIHI/bnIocik6XyhyKX0sZmlsdGVyRXhhY3Q6XyxmaWx0ZXJSYW5nZTpycixmaWx0ZXJGdW5jdGlvbjpucixmaWx0ZXJBbGw6ZXIsY3VycmVudEZpbHRlcjpmdW5jdGlvbigpe3JldHVybiBMfSxoYXNDdXJyZW50RmlsdGVyOmZ1bmN0aW9uKCl7cmV0dXJuIFd9LHRvcDpmdW5jdGlvbihlLHQpe3ZhciB1LG89W10sZj1QLGE9MDt0JiZ0PjAmJihhPXQpO2Zvcig7LS1mPj1LJiZlPjA7KXIuemVybyh1PUZbZl0pJiYoYT4wPy0tYTooby5wdXNoKG5bdV0pLC0tZSkpO2lmKGkpZm9yKGY9MDtmPCQubGVuZ3RoJiZlPjA7ZisrKXIuemVybyh1PSRbZl0pJiYoYT4wPy0tYTooby5wdXNoKG5bdV0pLC0tZSkpO3JldHVybiBvfSxib3R0b206ZnVuY3Rpb24oZSx0KXt2YXIgdSxvLGY9W10sYT0wO3QmJnQ+MCYmKGE9dCk7aWYoaSlmb3IodT0wO3U8JC5sZW5ndGgmJmU+MDt1Kyspci56ZXJvKG89JFt1XSkmJihhPjA/LS1hOihmLnB1c2gobltvXSksLS1lKSk7dT1LO2Zvcig7dTxQJiZlPjA7KXIuemVybyhvPUZbdV0pJiYoYT4wPy0tYTooZi5wdXNoKG5bb10pLC0tZSkpLHUrKztyZXR1cm4gZn0sZ3JvdXA6dXIsZ3JvdXBBbGw6ZnVuY3Rpb24oKXt2YXIgcj11cihoKSxlPXIuYWxsO3JldHVybiBkZWxldGUgci5hbGwsZGVsZXRlIHIudG9wLGRlbGV0ZSByLm9yZGVyLGRlbGV0ZSByLm9yZGVyTmF0dXJhbCxkZWxldGUgci5zaXplLHIudmFsdWU9ZnVuY3Rpb24oKXtyZXR1cm4gZSgpWzBdLnZhbHVlfSxyfSxkaXNwb3NlOm9yLHJlbW92ZTpvcixhY2Nlc3NvcjplLGlkOmZ1bmN0aW9uKCl7cmV0dXJuIEF9fSwkPVtdLHE9ZnVuY3Rpb24ocil7cmV0dXJuIFMocikuc29ydCgoZnVuY3Rpb24ocixlKXt2YXIgbj1OW3JdLHQ9TltlXTtyZXR1cm4gbjx0Py0xOm4+dD8xOnItZX0pKX0sQj1zLmZpbHRlckFsbCxHPVtdLEg9W10sSz0wLFA9MCxRPTA7by51bnNoaWZ0KFYpLG8ucHVzaChYKSxmLnB1c2goWSk7dmFyIFQ9ci5hZGQoKTtmdW5jdGlvbiBWKG4sdSxvKXt2YXIgZixhO2lmKGkpe1E9MCxHPTAsSj1bXTtmb3IodmFyIHM9MDtzPG4ubGVuZ3RoO3MrKylmb3IoRz0wLEo9ZShuW3NdKTtHPEoubGVuZ3RoO0crKylRKys7Tj1bXSxmPVMobi5sZW5ndGgpLGE9TShRLDEpO2Zvcih2YXIgYz1TKFEpLGg9MCx2PTA7djxuLmxlbmd0aDt2KyspaWYoKEo9ZShuW3ZdKSkubGVuZ3RoKWZvcihmW3ZdPUoubGVuZ3RoLEc9MDtHPEoubGVuZ3RoO0crKylOLnB1c2goSltHXSksY1toXT12LGgrKztlbHNlIGZbdl09MCwkLnB1c2godit1KTt2YXIgZD1xKFEpO049bShOLGQpLFI9bShjLGQpfWVsc2UgTj1uLm1hcChlKSxSPXEobyksTj1tKE4sUik7dmFyIGcseSx4LGI9QihOKSxFPWJbMF0sQT1iWzFdO2lmKGkpaWYobz1RLEkpZm9yKGc9MDtnPG87KytnKUkoTltnXSxnKXx8KDA9PS0tZltSW2ddXSYmKHJbd11bUltnXSt1XXw9cCksYVtnXT0xKTtlbHNle2Zvcih5PTA7eTxFOysreSkwPT0tLWZbUlt5XV0mJihyW3ddW1JbeV0rdV18PXApLGFbeV09MTtmb3IoeD1BO3g8bzsrK3gpMD09LS1mW1JbeF1dJiYoclt3XVtSW3hdK3VdfD1wKSxhW3hdPTF9ZWxzZSBpZihJKWZvcihnPTA7ZzxvOysrZylJKE5bZ10sZyl8fChyW3ddW1JbZ10rdV18PXApO2Vsc2V7Zm9yKHk9MDt5PEU7Kyt5KXJbd11bUlt5XSt1XXw9cDtmb3IoeD1BO3g8bzsrK3gpclt3XVtSW3hdK3VdfD1wfWlmKCF1KXJldHVybiBPPU4sRj1SLFU9ZixEPWEsSz1FLHZvaWQoUD1BKTt2YXIgeixrPU8sQz1GLEw9RCxXPTA7aWYocz0wLGkmJih6PXUsdT1rLmxlbmd0aCxvPVEpLE89bmV3IEFycmF5KGk/dStvOnQpLEY9aT9uZXcgQXJyYXkodStvKTpNKHQsdCksaSYmKEQ9TSh1K28sMSkpLGkpe3ZhciBqPVUubGVuZ3RoO1U9bC5hcnJheUxlbmd0aGVuKFUsdCk7Zm9yKHZhciBHPTA7RytqPHQ7RysrKVVbRytqXT1mW0ddfWZvcih2YXIgSD0wO3M8dSYmVzxvOysrSClrW3NdPE5bV10/KE9bSF09a1tzXSxpJiYoRFtIXT1MW3NdKSxGW0hdPUNbcysrXSk6KE9bSF09TltXXSxpJiYoRFtIXT1hW1ddKSxGW0hdPVJbVysrXSsoaT96OnUpKTtmb3IoO3M8dTsrK3MsKytIKU9bSF09a1tzXSxpJiYoRFtIXT1MW3NdKSxGW0hdPUNbc107Zm9yKDtXPG87KytXLCsrSClPW0hdPU5bV10saSYmKERbSF09YVtXXSksRltIXT1SW1ddKyhpP3o6dSk7Yj1CKE8pLEs9YlswXSxQPWJbMV19ZnVuY3Rpb24gWChyLGUsbil7Ry5mb3JFYWNoKChmdW5jdGlvbihyKXtyKE4sUixlLG4pfSkpLE49Uj1udWxsfWZ1bmN0aW9uIFkocil7aWYoaSl7Zm9yKHZhciBlPTAsbj0wO2U8JC5sZW5ndGg7ZSsrKXJbJFtlXV0hPT1rJiYoJFtuXT1yWyRbZV1dLG4rKyk7Zm9yKCQubGVuZ3RoPW4sZT0wLG49MDtlPHQ7ZSsrKXJbZV0hPT1rJiYobiE9PWUmJihVW25dPVVbZV0pLG4rKyk7VT1VLnNsaWNlKDAsbil9Zm9yKHZhciB1LG89Ty5sZW5ndGgsZj0wLGE9MDtmPG87KytmKXJbdT1GW2ZdXSE9PWsmJihmIT09YSYmKE9bYV09T1tmXSksRlthXT1yW3VdLGkmJihEW2FdPURbZl0pLCsrYSk7Zm9yKE8ubGVuZ3RoPWEsaSYmKEQ9RC5zbGljZSgwLGEpKTthPG87KUZbYSsrXT0wO3ZhciBsPUIoTyk7Sz1sWzBdLFA9bFsxXX1mdW5jdGlvbiBaKGUpe3ZhciBuPWVbMF0sdD1lWzFdO2lmKEkpcmV0dXJuIEk9bnVsbCx0cigoZnVuY3Rpb24ocixlKXtyZXR1cm4gbjw9ZSYmZTx0fSksMD09PWVbMF0mJmVbMV09PT1PLmxlbmd0aCksSz1uLFA9dCxqO3ZhciBvLGYsYSxsPVtdLGM9W10saD1bXSx2PVtdO2lmKG48Sylmb3Iobz1uLGY9TWF0aC5taW4oSyx0KTtvPGY7KytvKWwucHVzaChGW29dKSxoLnB1c2gobyk7ZWxzZSBpZihuPkspZm9yKG89SyxmPU1hdGgubWluKG4sUCk7bzxmOysrbyljLnB1c2goRltvXSksdi5wdXNoKG8pO2lmKHQ+UClmb3Iobz1NYXRoLm1heChuLFApLGY9dDtvPGY7KytvKWwucHVzaChGW29dKSxoLnB1c2gobyk7ZWxzZSBpZih0PFApZm9yKG89TWF0aC5tYXgoSyx0KSxmPVA7bzxmOysrbyljLnB1c2goRltvXSksdi5wdXNoKG8pO2lmKGkpe3ZhciBkPVtdLHk9W107Zm9yKG89MDtvPGwubGVuZ3RoO28rKylVW2xbb11dKyssRFtoW29dXT0wLDE9PT1VW2xbb11dJiYoclt3XVtsW29dXV49cCxkLnB1c2gobFtvXSkpO2ZvcihvPTA7bzxjLmxlbmd0aDtvKyspVVtjW29dXS0tLERbdltvXV09MSwwPT09VVtjW29dXSYmKHJbd11bY1tvXV1ePXAseS5wdXNoKGNbb10pKTtpZihsPWQsYz15LEI9PT1zLmZpbHRlckFsbClmb3Iobz0wO288JC5sZW5ndGg7bysrKXJbd11bYT0kW29dXSZwJiYoclt3XVthXV49cCxsLnB1c2goYSkpO2Vsc2UgZm9yKG89MDtvPCQubGVuZ3RoO28rKylyW3ddW2E9JFtvXV0mcHx8KHJbd11bYV1ePXAsYy5wdXNoKGEpKX1lbHNle2ZvcihvPTA7bzxsLmxlbmd0aDtvKyspclt3XVtsW29dXV49cDtmb3Iobz0wO288Yy5sZW5ndGg7bysrKXJbd11bY1tvXV1ePXB9cmV0dXJuIEs9bixQPXQsdS5mb3JFYWNoKChmdW5jdGlvbihyKXtyKHAsdyxsLGMpfSkpLGcoXCJmaWx0ZXJlZFwiKSxqfWZ1bmN0aW9uIF8ocil7cmV0dXJuIEw9cixXPSEwLFooKEI9cy5maWx0ZXJFeGFjdChiLHIpKShPKSl9ZnVuY3Rpb24gcnIocil7cmV0dXJuIEw9cixXPSEwLFooKEI9cy5maWx0ZXJSYW5nZShiLHIpKShPKSl9ZnVuY3Rpb24gZXIoKXtyZXR1cm4gTD12b2lkIDAsVz0hMSxaKChCPXMuZmlsdGVyQWxsKShPKSl9ZnVuY3Rpb24gbnIocil7TD1yLFc9ITAsST1yLEI9cy5maWx0ZXJBbGwsdHIociwhMSk7dmFyIGU9QihPKTtyZXR1cm4gSz1lWzBdLFA9ZVsxXSxqfWZ1bmN0aW9uIHRyKGUsbil7dmFyIHQsbyxmLGE9W10sbD1bXSxzPVtdLGM9W10saD1PLmxlbmd0aDtpZighaSlmb3IodD0wO3Q8aDsrK3QpIShyW3ddW289Rlt0XV0mcCleISEoZj1lKE9bdF0sdCkpJiYoZj9hLnB1c2gobyk6bC5wdXNoKG8pKTtpZihpKWZvcih0PTA7dDxoOysrdCllKE9bdF0sdCk/KGEucHVzaChGW3RdKSxzLnB1c2godCkpOihsLnB1c2goRlt0XSksYy5wdXNoKHQpKTtpZihpKXt2YXIgdj1bXSxkPVtdO2Zvcih0PTA7dDxhLmxlbmd0aDt0KyspMT09PURbc1t0XV0mJihVW2FbdF1dKyssRFtzW3RdXT0wLDE9PT1VW2FbdF1dJiYoclt3XVthW3RdXV49cCx2LnB1c2goYVt0XSkpKTtmb3IodD0wO3Q8bC5sZW5ndGg7dCsrKTA9PT1EW2NbdF1dJiYoVVtsW3RdXS0tLERbY1t0XV09MSwwPT09VVtsW3RdXSYmKHJbd11bbFt0XV1ePXAsZC5wdXNoKGxbdF0pKSk7aWYoYT12LGw9ZCxuKWZvcih0PTA7dDwkLmxlbmd0aDt0Kyspclt3XVtvPSRbdF1dJnAmJihyW3ddW29dXj1wLGEucHVzaChvKSk7ZWxzZSBmb3IodD0wO3Q8JC5sZW5ndGg7dCsrKXJbd11bbz0kW3RdXSZwfHwoclt3XVtvXV49cCxsLnB1c2gobykpfWVsc2V7Zm9yKHQ9MDt0PGEubGVuZ3RoO3QrKylyW3ddW2FbdF1dJnAmJihyW3ddW2FbdF1dJj14KTtmb3IodD0wO3Q8bC5sZW5ndGg7dCsrKXJbd11bbFt0XV0mcHx8KHJbd11bbFt0XV18PXApfXUuZm9yRWFjaCgoZnVuY3Rpb24ocil7cihwLHcsYSxsKX0pKSxnKFwiZmlsdGVyZWRcIil9ZnVuY3Rpb24gdXIoZSl7dmFyIG89e3RvcDpmdW5jdGlvbihyKXt2YXIgZT1nKFAoKSwwLGEubGVuZ3RoLHIpO3JldHVybiBiLnNvcnQoZSwwLGUubGVuZ3RoKX0sYWxsOlAscmVkdWNlOlEscmVkdWNlQ291bnQ6VCxyZWR1Y2VTdW06ZnVuY3Rpb24ocil7cmV0dXJuIFEoRS5yZWR1Y2VBZGQociksRS5yZWR1Y2VTdWJ0cmFjdChyKSx2KX0sb3JkZXI6VixvcmRlck5hdHVyYWw6ZnVuY3Rpb24oKXtyZXR1cm4gVihjKX0sc2l6ZTpmdW5jdGlvbigpe3JldHVybiBVfSxkaXNwb3NlOlgscmVtb3ZlOlh9O0gucHVzaChvKTt2YXIgYSxzLGcsYixtLEEseixTLE49OCxSPUMoTiksVT0wLEQ9aCxJPWgsTD0hMCxXPWU9PT1oO2Z1bmN0aW9uIEoobyxmLGMsdil7aSYmKFM9YyxjPU8ubGVuZ3RoLW8ubGVuZ3RoLHY9by5sZW5ndGgpO3ZhciBwLGQsZyx5LGIsRSxrPWEsRj1pP1tdOk0oVSxSKSxKPW0saj1BLEc9eixIPVUsUD0wLFE9MDtmb3IoTCYmKEo9Rz1oKSxMJiYoaj1HPWgpLGE9bmV3IEFycmF5KFUpLFU9MCxzPWk/SD9zOltdOkg+MT9sLmFycmF5TGVuZ3RoZW4ocyx0KTpNKHQsUiksSCYmKGc9KGQ9a1swXSkua2V5KTtRPHYmJiEoKHk9ZShvW1FdKSk+PXkpOykrK1E7Zm9yKDtRPHY7KXtmb3IoZCYmZzw9eT8oYj1kLEU9ZyxGW1BdPVUsKGQ9a1srK1BdKSYmKGc9ZC5rZXkpKTooYj17a2V5OnksdmFsdWU6RygpfSxFPXkpLGFbVV09Yjt5PD1FJiYocD1mW1FdKyhpP1M6YyksaT9zW3BdP3NbcF0ucHVzaChVKTpzW3BdPVtVXTpzW3BdPVUsYi52YWx1ZT1KKGIudmFsdWUsbltwXSwhMCksci56ZXJvRXhjZXB0KHAsdyx4KXx8KGIudmFsdWU9aihiLnZhbHVlLG5bcF0sITEpKSwhKCsrUT49dikpOyl5PWUob1tRXSk7VigpfWZvcig7UDxIOylhW0ZbUF09VV09a1tQKytdLFYoKTtpZihpKWZvcih2YXIgVD0wO1Q8dDtUKyspc1tUXXx8KHNbVF09W10pO2lmKFU+UClpZihpKWZvcihQPTA7UDxTOysrUClmb3IoVD0wO1Q8c1tQXS5sZW5ndGg7VCsrKXNbUF1bVF09RltzW1BdW1RdXTtlbHNlIGZvcihQPTA7UDxjOysrUClzW1BdPUZbc1tQXV07ZnVuY3Rpb24gVigpe2k/VSsrOisrVT09PVImJihGPWwuYXJyYXlXaWRlbihGLE48PD0xKSxzPWwuYXJyYXlXaWRlbihzLE4pLFI9QyhOKSl9cD11LmluZGV4T2YoRCksVT4xfHxpPyhEPSQsST1CKTooIVUmJlcmJihVPTEsYT1be2tleTpudWxsLHZhbHVlOkcoKX1dKSwxPT09VT8oRD1xLEk9Syk6KEQ9aCxJPWgpLHM9bnVsbCksdVtwXT1EfWZ1bmN0aW9uIGoocil7aWYoVT4xfHxpKXt2YXIgZSxuLG8sZj1VLGw9YSxjPU0oZixmKTtpZihpKXtmb3IoZT0wLG89MDtlPHQ7KytlKWlmKHJbZV0hPT1rKXtmb3Ioc1tvXT1zW2VdLG49MDtuPHNbb10ubGVuZ3RoO24rKyljW3Nbb11bbl1dPTE7KytvfXM9cy5zbGljZSgwLG8pfWVsc2UgZm9yKGU9MCxvPTA7ZTx0OysrZSlyW2VdIT09ayYmKGNbc1tvXT1zW2VdXT0xLCsrbyk7Zm9yKGE9W10sVT0wLGU9MDtlPGY7KytlKWNbZV0mJihjW2VdPVUrKyxhLnB1c2gobFtlXSkpO2lmKFU+MXx8aSlpZihpKWZvcihlPTA7ZTxvOysrZSlmb3Iobj0wO248c1tlXS5sZW5ndGg7KytuKXNbZV1bbl09Y1tzW2VdW25dXTtlbHNlIGZvcihlPTA7ZTxvOysrZSlzW2VdPWNbc1tlXV07ZWxzZSBzPW51bGw7dVt1LmluZGV4T2YoRCldPVU+MXx8aT8oST1CLEQ9JCk6MT09PVU/KEk9SyxEPXEpOkk9RD1ofWVsc2UgaWYoMT09PVUpe2lmKFcpcmV0dXJuO2Zvcih2YXIgdj0wO3Y8dDsrK3YpaWYoclt2XSE9PWspcmV0dXJuO2E9W10sVT0wLHVbdS5pbmRleE9mKEQpXT1EPUk9aH19ZnVuY3Rpb24gJChlLHQsdSxvLGYpe3ZhciBsLGMsaCx2LGQ7aWYoIShlPT09cCYmdD09PXd8fEwpKWlmKGkpe2ZvcihsPTAsdj11Lmxlbmd0aDtsPHY7KytsKWlmKHIuemVyb0V4Y2VwdChoPXVbbF0sdyx4KSlmb3IoYz0wO2M8c1toXS5sZW5ndGg7YysrKShkPWFbc1toXVtjXV0pLnZhbHVlPW0oZC52YWx1ZSxuW2hdLCExLGMpO2ZvcihsPTAsdj1vLmxlbmd0aDtsPHY7KytsKWlmKHIub25seUV4Y2VwdChoPW9bbF0sdyx4LHQsZSkpZm9yKGM9MDtjPHNbaF0ubGVuZ3RoO2MrKykoZD1hW3NbaF1bY11dKS52YWx1ZT1BKGQudmFsdWUsbltoXSxmLGMpfWVsc2V7Zm9yKGw9MCx2PXUubGVuZ3RoO2w8djsrK2wpci56ZXJvRXhjZXB0KGg9dVtsXSx3LHgpJiYoKGQ9YVtzW2hdXSkudmFsdWU9bShkLnZhbHVlLG5baF0sITEpKTtmb3IobD0wLHY9by5sZW5ndGg7bDx2OysrbClyLm9ubHlFeGNlcHQoaD1vW2xdLHcseCx0LGUpJiYoKGQ9YVtzW2hdXSkudmFsdWU9QShkLnZhbHVlLG5baF0sZikpfX1mdW5jdGlvbiBxKGUsdCx1LG8sZil7aWYoIShlPT09cCYmdD09PXd8fEwpKXt2YXIgaSxsLHMsYz1hWzBdO2ZvcihpPTAscz11Lmxlbmd0aDtpPHM7KytpKXIuemVyb0V4Y2VwdChsPXVbaV0sdyx4KSYmKGMudmFsdWU9bShjLnZhbHVlLG5bbF0sITEpKTtmb3IoaT0wLHM9by5sZW5ndGg7aTxzOysraSlyLm9ubHlFeGNlcHQobD1vW2ldLHcseCx0LGUpJiYoYy52YWx1ZT1BKGMudmFsdWUsbltsXSxmKSl9fWZ1bmN0aW9uIEIoKXt2YXIgZSx1LG87Zm9yKGU9MDtlPFU7KytlKWFbZV0udmFsdWU9eigpO2lmKGkpe2ZvcihlPTA7ZTx0OysrZSlmb3IodT0wO3U8c1tlXS5sZW5ndGg7dSsrKShvPWFbc1tlXVt1XV0pLnZhbHVlPW0oby52YWx1ZSxuW2VdLCEwLHUpO2ZvcihlPTA7ZTx0OysrZSlpZighci56ZXJvRXhjZXB0KGUsdyx4KSlmb3IodT0wO3U8c1tlXS5sZW5ndGg7dSsrKShvPWFbc1tlXVt1XV0pLnZhbHVlPUEoby52YWx1ZSxuW2VdLCExLHUpfWVsc2V7Zm9yKGU9MDtlPHQ7KytlKShvPWFbc1tlXV0pLnZhbHVlPW0oby52YWx1ZSxuW2VdLCEwKTtmb3IoZT0wO2U8dDsrK2Upci56ZXJvRXhjZXB0KGUsdyx4KXx8KChvPWFbc1tlXV0pLnZhbHVlPUEoby52YWx1ZSxuW2VdLCExKSl9fWZ1bmN0aW9uIEsoKXt2YXIgZSx1PWFbMF07Zm9yKHUudmFsdWU9eigpLGU9MDtlPHQ7KytlKXUudmFsdWU9bSh1LnZhbHVlLG5bZV0sITApO2ZvcihlPTA7ZTx0OysrZSlyLnplcm9FeGNlcHQoZSx3LHgpfHwodS52YWx1ZT1BKHUudmFsdWUsbltlXSwhMSkpfWZ1bmN0aW9uIFAoKXtyZXR1cm4gTCYmKEkoKSxMPSExKSxhfWZ1bmN0aW9uIFEocixlLG4pe3JldHVybiBtPXIsQT1lLHo9bixMPSEwLG99ZnVuY3Rpb24gVCgpe3JldHVybiBRKEUucmVkdWNlSW5jcmVtZW50LEUucmVkdWNlRGVjcmVtZW50LHYpfWZ1bmN0aW9uIFYocil7ZnVuY3Rpb24gZShlKXtyZXR1cm4gcihlLnZhbHVlKX1yZXR1cm4gZz15LmJ5KGUpLGI9ZC5ieShlKSxvfWZ1bmN0aW9uIFgoKXt2YXIgcj11LmluZGV4T2YoRCk7cmV0dXJuIHI+PTAmJnUuc3BsaWNlKHIsMSksKHI9Ry5pbmRleE9mKEopKT49MCYmRy5zcGxpY2UociwxKSwocj1mLmluZGV4T2YoaikpPj0wJiZmLnNwbGljZShyLDEpLChyPUguaW5kZXhPZihvKSk+PTAmJkguc3BsaWNlKHIsMSksb31yZXR1cm4gYXJndW1lbnRzLmxlbmd0aDwxJiYoZT1jKSx1LnB1c2goRCksRy5wdXNoKEopLGYucHVzaChqKSxKKE8sRiwwLHQpLFQoKS5vcmRlck5hdHVyYWwoKX1mdW5jdGlvbiBvcigpe0guZm9yRWFjaCgoZnVuY3Rpb24ocil7ci5kaXNwb3NlKCl9KSk7dmFyIGU9by5pbmRleE9mKFYpO3JldHVybiBlPj0wJiZvLnNwbGljZShlLDEpLChlPW8uaW5kZXhPZihYKSk+PTAmJm8uc3BsaWNlKGUsMSksKGU9Zi5pbmRleE9mKFkpKT49MCYmZi5zcGxpY2UoZSwxKSxyLm1hc2tzW3ddJj14LGVyKCl9cmV0dXJuIHc9VC5vZmZzZXQscD1ULm9uZSx4PX5wLEE9dzw8N3xNYXRoLmxvZyhwKS9NYXRoLmxvZygyKSxWKG4sMCx0KSxYKG4sMCx0KSxqfSxncm91cEFsbDpmdW5jdGlvbigpe3ZhciBlLGYsaSxhLGw9e3JlZHVjZTpwLHJlZHVjZUNvdW50OmQscmVkdWNlU3VtOmZ1bmN0aW9uKHIpe3JldHVybiBwKEUucmVkdWNlQWRkKHIpLEUucmVkdWNlU3VidHJhY3Qociksdil9LHZhbHVlOmZ1bmN0aW9uKCl7cyYmKGZ1bmN0aW9uKCl7dmFyIHU7Zm9yKGU9YSgpLHU9MDt1PHQ7Kyt1KWU9ZihlLG5bdV0sITApLHIuemVybyh1KXx8KGU9aShlLG5bdV0sITEpKX0oKSxzPSExKTtyZXR1cm4gZX0sZGlzcG9zZTpnLHJlbW92ZTpnfSxzPSEwO2Z1bmN0aW9uIGModSxvKXt2YXIgYTtpZighcylmb3IoYT1vO2E8dDsrK2EpZT1mKGUsblthXSwhMCksci56ZXJvKGEpfHwoZT1pKGUsblthXSwhMSkpfWZ1bmN0aW9uIGgodCx1LG8sYSxsKXt2YXIgYyxoLHY7aWYoIXMpe2ZvcihjPTAsdj1vLmxlbmd0aDtjPHY7KytjKXIuemVybyhoPW9bY10pJiYoZT1mKGUsbltoXSxsKSk7Zm9yKGM9MCx2PWEubGVuZ3RoO2M8djsrK2Mpci5vbmx5KGg9YVtjXSx1LHQpJiYoZT1pKGUsbltoXSxsKSl9fWZ1bmN0aW9uIHAocixlLG4pe3JldHVybiBmPXIsaT1lLGE9bixzPSEwLGx9ZnVuY3Rpb24gZCgpe3JldHVybiBwKEUucmVkdWNlSW5jcmVtZW50LEUucmVkdWNlRGVjcmVtZW50LHYpfWZ1bmN0aW9uIGcoKXt2YXIgcj11LmluZGV4T2YoaCk7cmV0dXJuIHI+PTAmJnUuc3BsaWNlKHIsMSksKHI9by5pbmRleE9mKGMpKT49MCYmby5zcGxpY2UociwxKSxsfXJldHVybih1LnB1c2goaCksby5wdXNoKGMpLGMobiwwKSxkKCkpfSxzaXplOmZ1bmN0aW9uKCl7cmV0dXJuIHR9LGFsbDpmdW5jdGlvbigpe3JldHVybiBufSxhbGxGaWx0ZXJlZDpmdW5jdGlvbihlKXt2YXIgdT1bXSxvPTAsZj1wKGV8fFtdKTtmb3Iobz0wO288dDtvKyspci56ZXJvRXhjZXB0TWFzayhvLGYpJiZ1LnB1c2gobltvXSk7cmV0dXJuIHV9LG9uQ2hhbmdlOmZ1bmN0aW9uKHIpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHIpcmV0dXJuIHZvaWQgY29uc29sZS53YXJuKFwib25DaGFuZ2UgY2FsbGJhY2sgcGFyYW1ldGVyIG11c3QgYmUgYSBmdW5jdGlvbiFcIik7cmV0dXJuIGkucHVzaChyKSxmdW5jdGlvbigpe2kuc3BsaWNlKGkuaW5kZXhPZihyKSwxKX19LGlzRWxlbWVudEZpbHRlcmVkOmZ1bmN0aW9uKGUsbil7dmFyIHQ9cChufHxbXSk7cmV0dXJuIHIuemVyb0V4Y2VwdE1hc2soZSx0KX19LG49W10sdD0wLHU9W10sbz1bXSxmPVtdLGk9W107ZnVuY3Rpb24gYSh1KXt2YXIgZj10LGk9dS5sZW5ndGg7cmV0dXJuIGkmJihuPW4uY29uY2F0KHUpLHIubGVuZ3RoZW4odCs9aSksby5mb3JFYWNoKChmdW5jdGlvbihyKXtyKHUsZixpKX0pKSxnKFwiZGF0YUFkZGVkXCIpKSxlfWZ1bmN0aW9uIHAoZSl7dmFyIG4sdCx1LG8sZj1BcnJheShyLnN1YmFycmF5cyk7Zm9yKG49MDtuPHIuc3ViYXJyYXlzO24rKylmW25dPS0xO2Zvcih0PTAsdT1lLmxlbmd0aDt0PHU7dCsrKWZbKG89ZVt0XS5pZCgpKT4+N10mPX4oMTw8KDYzJm8pKTtyZXR1cm4gZn1mdW5jdGlvbiBnKHIpe2Zvcih2YXIgZT0wO2U8aS5sZW5ndGg7ZSsrKWlbZV0ocil9cmV0dXJuIHI9bmV3IGwuYml0YXJyYXkoMCksYXJndW1lbnRzLmxlbmd0aD9hKGFyZ3VtZW50c1swXSk6ZX1mdW5jdGlvbiBNKHIsZSl7cmV0dXJuKGU8MjU3P2wuYXJyYXk4OmU8NjU1Mzc/bC5hcnJheTE2OmwuYXJyYXkzMikocil9ZnVuY3Rpb24gUyhyKXtmb3IodmFyIGU9TShyLHIpLG49LTE7KytuPHI7KWVbbl09bjtyZXR1cm4gZX1mdW5jdGlvbiBDKHIpe3JldHVybiA4PT09cj8yNTY6MTY9PT1yPzY1NTM2OjQyOTQ5NjcyOTZ9Ty5oZWFwPWQsTy5oZWFwc2VsZWN0PXksTy5iaXNlY3Q9YixPLnBlcm11dGU9bTtyZXR1cm4gTy52ZXJzaW9uPVwiMS41LjRcIixPfSkpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0352\n')},"072d":function(module,exports){eval("/**\n * Server side filtering\n *\n * Implementation of a dataset backed by a server, which in turn uses fi. postgreSQL\n * Fully asynchronous, based on socketIO.\n *\n * Most methods below result in a message with the methodName and a data object, containing:\n *  * `datasets` and `dataview`, or `dataset`\n *  * `filterId` or `facetId`\n *\n * Data can be requested using the dataview.getData() method\n * responds with a `newData` message containing `filterId` and `data`.\n *\n * @module driver/server\n */\n\n/**\n * Autoconfigure a dataset\n *\n * @param {Dataset} dataset\n */\nfunction scan (dataset) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    // spot-server will not respond so no use requesting a scan\n    return;\n  }\n\n  spot.socket.emit('scanData', {\n    dataset: dataset.toJSON()\n  });\n}\n\n/**\n * setMinMax sets the range of a continuous or time facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setMinMax (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    spot.socket.emit('setMinMax', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setMinMax', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * setCategories finds finds all values on an ordinal (categorial) axis\n * Updates the categorialTransform of the facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setCategories (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  facet.categorialTransform.rules.reset();\n  if (spot.isLockedDown) {\n    spot.socket.emit('setCategories', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setCategories', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * Calculate 100 percentiles (ie. 1,2,3,4 etc.), and initialize the `facet.continuousTransform`\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setPercentiles (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    spot.socket.emit('setPercentiles', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setPercentiles', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * Initialize the data filter, and construct the getData callback function on the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction initDataFilter (dataview, filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n * related to the filter.\n * @param {Filter} filter\n */\nfunction releaseDataFilter (filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * Change the filter parameters for an initialized filter\n * @param {Filter} filter\n */\nfunction updateDataFilter (filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * Get data for every filter, and trigger a 'newData' event\n *\n * Returns a Promise that resolves to the dataview when all data and metadata has been updated\n *\n * @param {Dataview} dataview\n * @returns {Promise}\n */\nfunction getData (dataview) {\n  var spot = dataview.parent;\n\n  return new Promise(function (resolve, reject) {\n    if (spot.isLockedDown) {\n      spot.socket.emit('getData', {\n        dataview: dataview.toJSON()\n      });\n    } else {\n      spot.socket.emit('getData', {\n        datasets: spot.cachedDatasets,\n        dataview: dataview.toJSON()\n      });\n    }\n\n    dataview.once('newMetaData', function () {\n      resolve(dataview);\n    });\n  });\n}\n\nmodule.exports = {\n  driverType: 'server',\n  scan: scan,\n  setMinMax: setMinMax,\n  setCategories: setCategories,\n  setPercentiles: setPercentiles,\n  initDataFilter: initDataFilter,\n  releaseDataFilter: releaseDataFilter,\n  updateDataFilter: updateDataFilter,\n  getData: getData\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDcyZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZHJpdmVyL3NlcnZlci5qcz9lMzc3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2VydmVyIHNpZGUgZmlsdGVyaW5nXG4gKlxuICogSW1wbGVtZW50YXRpb24gb2YgYSBkYXRhc2V0IGJhY2tlZCBieSBhIHNlcnZlciwgd2hpY2ggaW4gdHVybiB1c2VzIGZpLiBwb3N0Z3JlU1FMXG4gKiBGdWxseSBhc3luY2hyb25vdXMsIGJhc2VkIG9uIHNvY2tldElPLlxuICpcbiAqIE1vc3QgbWV0aG9kcyBiZWxvdyByZXN1bHQgaW4gYSBtZXNzYWdlIHdpdGggdGhlIG1ldGhvZE5hbWUgYW5kIGEgZGF0YSBvYmplY3QsIGNvbnRhaW5pbmc6XG4gKiAgKiBgZGF0YXNldHNgIGFuZCBgZGF0YXZpZXdgLCBvciBgZGF0YXNldGBcbiAqICAqIGBmaWx0ZXJJZGAgb3IgYGZhY2V0SWRgXG4gKlxuICogRGF0YSBjYW4gYmUgcmVxdWVzdGVkIHVzaW5nIHRoZSBkYXRhdmlldy5nZXREYXRhKCkgbWV0aG9kXG4gKiByZXNwb25kcyB3aXRoIGEgYG5ld0RhdGFgIG1lc3NhZ2UgY29udGFpbmluZyBgZmlsdGVySWRgIGFuZCBgZGF0YWAuXG4gKlxuICogQG1vZHVsZSBkcml2ZXIvc2VydmVyXG4gKi9cblxuLyoqXG4gKiBBdXRvY29uZmlndXJlIGEgZGF0YXNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICovXG5mdW5jdGlvbiBzY2FuIChkYXRhc2V0KSB7XG4gIC8vIERhdGFzZXQgLT4gRGF0YXNldHMgLT4gU3BvdFxuICB2YXIgc3BvdCA9IGRhdGFzZXQuY29sbGVjdGlvbi5wYXJlbnQ7XG5cbiAgaWYgKHNwb3QuaXNMb2NrZWREb3duKSB7XG4gICAgLy8gc3BvdC1zZXJ2ZXIgd2lsbCBub3QgcmVzcG9uZCBzbyBubyB1c2UgcmVxdWVzdGluZyBhIHNjYW5cbiAgICByZXR1cm47XG4gIH1cblxuICBzcG90LnNvY2tldC5lbWl0KCdzY2FuRGF0YScsIHtcbiAgICBkYXRhc2V0OiBkYXRhc2V0LnRvSlNPTigpXG4gIH0pO1xufVxuXG4vKipcbiAqIHNldE1pbk1heCBzZXRzIHRoZSByYW5nZSBvZiBhIGNvbnRpbnVvdXMgb3IgdGltZSBmYWNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqL1xuZnVuY3Rpb24gc2V0TWluTWF4IChkYXRhc2V0LCBmYWNldCkge1xuICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgdmFyIHNwb3QgPSBkYXRhc2V0LmNvbGxlY3Rpb24ucGFyZW50O1xuXG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldE1pbk1heCcsIHtcbiAgICAgIGRhdGFzZXRJZDogZGF0YXNldC5nZXRJZCgpLFxuICAgICAgZmFjZXRJZDogZmFjZXQuZ2V0SWQoKVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldE1pbk1heCcsIHtcbiAgICAgIGRhdGFzZXRJZDogZGF0YXNldC5nZXRJZCgpLFxuICAgICAgZGF0YXNldDogZGF0YXNldC50b0pTT04oKSxcbiAgICAgIGZhY2V0SWQ6IGZhY2V0LmdldElkKClcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIHNldENhdGVnb3JpZXMgZmluZHMgZmluZHMgYWxsIHZhbHVlcyBvbiBhbiBvcmRpbmFsIChjYXRlZ29yaWFsKSBheGlzXG4gKiBVcGRhdGVzIHRoZSBjYXRlZ29yaWFsVHJhbnNmb3JtIG9mIHRoZSBmYWNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqL1xuZnVuY3Rpb24gc2V0Q2F0ZWdvcmllcyAoZGF0YXNldCwgZmFjZXQpIHtcbiAgLy8gRGF0YXNldCAtPiBEYXRhc2V0cyAtPiBTcG90XG4gIHZhciBzcG90ID0gZGF0YXNldC5jb2xsZWN0aW9uLnBhcmVudDtcblxuICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLnJlc2V0KCk7XG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldENhdGVnb3JpZXMnLCB7XG4gICAgICBkYXRhc2V0SWQ6IGRhdGFzZXQuZ2V0SWQoKSxcbiAgICAgIGZhY2V0SWQ6IGZhY2V0LmdldElkKClcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBzcG90LnNvY2tldC5lbWl0KCdzZXRDYXRlZ29yaWVzJywge1xuICAgICAgZGF0YXNldElkOiBkYXRhc2V0LmdldElkKCksXG4gICAgICBkYXRhc2V0OiBkYXRhc2V0LnRvSlNPTigpLFxuICAgICAgZmFjZXRJZDogZmFjZXQuZ2V0SWQoKVxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIDEwMCBwZXJjZW50aWxlcyAoaWUuIDEsMiwzLDQgZXRjLiksIGFuZCBpbml0aWFsaXplIHRoZSBgZmFjZXQuY29udGludW91c1RyYW5zZm9ybWBcbiAqXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXRcbiAqIEBwYXJhbSB7RmFjZXR9IGZhY2V0XG4gKi9cbmZ1bmN0aW9uIHNldFBlcmNlbnRpbGVzIChkYXRhc2V0LCBmYWNldCkge1xuICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgdmFyIHNwb3QgPSBkYXRhc2V0LmNvbGxlY3Rpb24ucGFyZW50O1xuXG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldFBlcmNlbnRpbGVzJywge1xuICAgICAgZGF0YXNldElkOiBkYXRhc2V0LmdldElkKCksXG4gICAgICBmYWNldElkOiBmYWNldC5nZXRJZCgpXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgc3BvdC5zb2NrZXQuZW1pdCgnc2V0UGVyY2VudGlsZXMnLCB7XG4gICAgICBkYXRhc2V0SWQ6IGRhdGFzZXQuZ2V0SWQoKSxcbiAgICAgIGRhdGFzZXQ6IGRhdGFzZXQudG9KU09OKCksXG4gICAgICBmYWNldElkOiBmYWNldC5nZXRJZCgpXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gaW5pdERhdGFGaWx0ZXIgKGRhdGF2aWV3LCBmaWx0ZXIpIHtcbiAgLy8gYXMgdGhlIFNRTCBzZXJ2ZXIgaW1wbGVtZW50YXRpb24gaXMgc3RhdGVsZXNzLCBub3RoaW5nIHRvIGRvIGhlcmVcbn1cblxuLyoqXG4gKiBUaGUgb3Bwb3NpdGUgb3IgaW5pdERhdGFGaWx0ZXIsIGl0IHNob3VsZCByZW1vdmUgdGhlIGZpbHRlciBhbmQgZGVhbGxvY2F0ZSBvdGhlciBjb25maWd1cmF0aW9uXG4gKiByZWxhdGVkIHRvIHRoZSBmaWx0ZXIuXG4gKiBAcGFyYW0ge0ZpbHRlcn0gZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHJlbGVhc2VEYXRhRmlsdGVyIChmaWx0ZXIpIHtcbiAgLy8gYXMgdGhlIFNRTCBzZXJ2ZXIgaW1wbGVtZW50YXRpb24gaXMgc3RhdGVsZXNzLCBub3RoaW5nIHRvIGRvIGhlcmVcbn1cblxuLyoqXG4gKiBDaGFuZ2UgdGhlIGZpbHRlciBwYXJhbWV0ZXJzIGZvciBhbiBpbml0aWFsaXplZCBmaWx0ZXJcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGF0YUZpbHRlciAoZmlsdGVyKSB7XG4gIC8vIGFzIHRoZSBTUUwgc2VydmVyIGltcGxlbWVudGF0aW9uIGlzIHN0YXRlbGVzcywgbm90aGluZyB0byBkbyBoZXJlXG59XG5cbi8qKlxuICogR2V0IGRhdGEgZm9yIGV2ZXJ5IGZpbHRlciwgYW5kIHRyaWdnZXIgYSAnbmV3RGF0YScgZXZlbnRcbiAqXG4gKiBSZXR1cm5zIGEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkYXRhdmlldyB3aGVuIGFsbCBkYXRhIGFuZCBtZXRhZGF0YSBoYXMgYmVlbiB1cGRhdGVkXG4gKlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEByZXR1cm5zIHtQcm9taXNlfVxuICovXG5mdW5jdGlvbiBnZXREYXRhIChkYXRhdmlldykge1xuICB2YXIgc3BvdCA9IGRhdGF2aWV3LnBhcmVudDtcblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgICAgc3BvdC5zb2NrZXQuZW1pdCgnZ2V0RGF0YScsIHtcbiAgICAgICAgZGF0YXZpZXc6IGRhdGF2aWV3LnRvSlNPTigpXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3BvdC5zb2NrZXQuZW1pdCgnZ2V0RGF0YScsIHtcbiAgICAgICAgZGF0YXNldHM6IHNwb3QuY2FjaGVkRGF0YXNldHMsXG4gICAgICAgIGRhdGF2aWV3OiBkYXRhdmlldy50b0pTT04oKVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZGF0YXZpZXcub25jZSgnbmV3TWV0YURhdGEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXNvbHZlKGRhdGF2aWV3KTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBkcml2ZXJUeXBlOiAnc2VydmVyJyxcbiAgc2Nhbjogc2NhbixcbiAgc2V0TWluTWF4OiBzZXRNaW5NYXgsXG4gIHNldENhdGVnb3JpZXM6IHNldENhdGVnb3JpZXMsXG4gIHNldFBlcmNlbnRpbGVzOiBzZXRQZXJjZW50aWxlcyxcbiAgaW5pdERhdGFGaWx0ZXI6IGluaXREYXRhRmlsdGVyLFxuICByZWxlYXNlRGF0YUZpbHRlcjogcmVsZWFzZURhdGFGaWx0ZXIsXG4gIHVwZGF0ZURhdGFGaWx0ZXI6IHVwZGF0ZURhdGFGaWx0ZXIsXG4gIGdldERhdGE6IGdldERhdGFcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///072d\n")},"09c5":function(module,exports,__webpack_require__){eval("/**\n * A single control point for a continuous transform\n *\n * @class ControlPoint\n */\nvar BaseModel = __webpack_require__(/*! ../util/base */ \"3902\");\n\n// Data structure for mapping categorial (and textual) data on groups\nmodule.exports = BaseModel.extend({\n  props: {\n    /**\n     * Value\n     * @type {number}\n     * @memberof! ContinuousRule\n     */\n    x: 'number',\n\n    /**\n     * Transformed value\n     * @type {number}\n     * @memberof! ContinuousRule\n     */\n    fx: 'number'\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDljNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29udHJvbC1wb2ludC5qcz82OTJiIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQSBzaW5nbGUgY29udHJvbCBwb2ludCBmb3IgYSBjb250aW51b3VzIHRyYW5zZm9ybVxuICpcbiAqIEBjbGFzcyBDb250cm9sUG9pbnRcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4uL3V0aWwvYmFzZScpO1xuXG4vLyBEYXRhIHN0cnVjdHVyZSBmb3IgbWFwcGluZyBjYXRlZ29yaWFsIChhbmQgdGV4dHVhbCkgZGF0YSBvbiBncm91cHNcbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVmFsdWVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1J1bGVcbiAgICAgKi9cbiAgICB4OiAnbnVtYmVyJyxcblxuICAgIC8qKlxuICAgICAqIFRyYW5zZm9ybWVkIHZhbHVlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNSdWxlXG4gICAgICovXG4gICAgZng6ICdudW1iZXInXG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///09c5\n")},"0b10":function(module,exports){eval("/**\n * Helpers.\n */\n\nvar s = 1000\nvar m = s * 60\nvar h = m * 60\nvar d = h * 24\nvar y = d * 365.25\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function (val, options) {\n  options = options || {}\n  var type = typeof val\n  if (type === 'string' && val.length > 0) {\n    return parse(val)\n  } else if (type === 'number' && isNaN(val) === false) {\n    return options.long ?\n\t\t\tfmtLong(val) :\n\t\t\tfmtShort(val)\n  }\n  throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val))\n}\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n  str = String(str)\n  if (str.length > 10000) {\n    return\n  }\n  var match = /^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str)\n  if (!match) {\n    return\n  }\n  var n = parseFloat(match[1])\n  var type = (match[2] || 'ms').toLowerCase()\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'yrs':\n    case 'yr':\n    case 'y':\n      return n * y\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d\n    case 'hours':\n    case 'hour':\n    case 'hrs':\n    case 'hr':\n    case 'h':\n      return n * h\n    case 'minutes':\n    case 'minute':\n    case 'mins':\n    case 'min':\n    case 'm':\n      return n * m\n    case 'seconds':\n    case 'second':\n    case 'secs':\n    case 'sec':\n    case 's':\n      return n * s\n    case 'milliseconds':\n    case 'millisecond':\n    case 'msecs':\n    case 'msec':\n    case 'ms':\n      return n\n    default:\n      return undefined\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtShort(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd'\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h'\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm'\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's'\n  }\n  return ms + 'ms'\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtLong(ms) {\n  return plural(ms, d, 'day') ||\n    plural(ms, h, 'hour') ||\n    plural(ms, m, 'minute') ||\n    plural(ms, s, 'second') ||\n    ms + ' ms'\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's'\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMGIxMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvbXMvaW5kZXguanM/YjZlOCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhlbHBlcnMuXG4gKi9cblxudmFyIHMgPSAxMDAwXG52YXIgbSA9IHMgKiA2MFxudmFyIGggPSBtICogNjBcbnZhciBkID0gaCAqIDI0XG52YXIgeSA9IGQgKiAzNjUuMjVcblxuLyoqXG4gKiBQYXJzZSBvciBmb3JtYXQgdGhlIGdpdmVuIGB2YWxgLlxuICpcbiAqIE9wdGlvbnM6XG4gKlxuICogIC0gYGxvbmdgIHZlcmJvc2UgZm9ybWF0dGluZyBbZmFsc2VdXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSB2YWxcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhyb3cgYW4gZXJyb3IgaWYgdmFsIGlzIG5vdCBhIG5vbi1lbXB0eSBzdHJpbmcgb3IgYSBudW1iZXJcbiAqIEByZXR1cm4ge1N0cmluZ3xOdW1iZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHZhbCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWxcbiAgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIHZhbC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHBhcnNlKHZhbClcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBpc05hTih2YWwpID09PSBmYWxzZSkge1xuICAgIHJldHVybiBvcHRpb25zLmxvbmcgP1xuXHRcdFx0Zm10TG9uZyh2YWwpIDpcblx0XHRcdGZtdFNob3J0KHZhbClcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ3ZhbCBpcyBub3QgYSBub24tZW1wdHkgc3RyaW5nIG9yIGEgdmFsaWQgbnVtYmVyLiB2YWw9JyArIEpTT04uc3RyaW5naWZ5KHZhbCkpXG59XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGBzdHJgIGFuZCByZXR1cm4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlKHN0cikge1xuICBzdHIgPSBTdHJpbmcoc3RyKVxuICBpZiAoc3RyLmxlbmd0aCA+IDEwMDAwKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIG1hdGNoID0gL14oKD86XFxkKyk/XFwuP1xcZCspICoobWlsbGlzZWNvbmRzP3xtc2Vjcz98bXN8c2Vjb25kcz98c2Vjcz98c3xtaW51dGVzP3xtaW5zP3xtfGhvdXJzP3xocnM/fGh8ZGF5cz98ZHx5ZWFycz98eXJzP3x5KT8kL2kuZXhlYyhzdHIpXG4gIGlmICghbWF0Y2gpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgbiA9IHBhcnNlRmxvYXQobWF0Y2hbMV0pXG4gIHZhciB0eXBlID0gKG1hdGNoWzJdIHx8ICdtcycpLnRvTG93ZXJDYXNlKClcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAneWVhcnMnOlxuICAgIGNhc2UgJ3llYXInOlxuICAgIGNhc2UgJ3lycyc6XG4gICAgY2FzZSAneXInOlxuICAgIGNhc2UgJ3knOlxuICAgICAgcmV0dXJuIG4gKiB5XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZFxuICAgIGNhc2UgJ2hvdXJzJzpcbiAgICBjYXNlICdob3VyJzpcbiAgICBjYXNlICdocnMnOlxuICAgIGNhc2UgJ2hyJzpcbiAgICBjYXNlICdoJzpcbiAgICAgIHJldHVybiBuICogaFxuICAgIGNhc2UgJ21pbnV0ZXMnOlxuICAgIGNhc2UgJ21pbnV0ZSc6XG4gICAgY2FzZSAnbWlucyc6XG4gICAgY2FzZSAnbWluJzpcbiAgICBjYXNlICdtJzpcbiAgICAgIHJldHVybiBuICogbVxuICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgY2FzZSAnc2Vjcyc6XG4gICAgY2FzZSAnc2VjJzpcbiAgICBjYXNlICdzJzpcbiAgICAgIHJldHVybiBuICogc1xuICAgIGNhc2UgJ21pbGxpc2Vjb25kcyc6XG4gICAgY2FzZSAnbWlsbGlzZWNvbmQnOlxuICAgIGNhc2UgJ21zZWNzJzpcbiAgICBjYXNlICdtc2VjJzpcbiAgICBjYXNlICdtcyc6XG4gICAgICByZXR1cm4gblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuLyoqXG4gKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBmbXRTaG9ydChtcykge1xuICBpZiAobXMgPj0gZCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gZCkgKyAnZCdcbiAgfVxuICBpZiAobXMgPj0gaCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gaCkgKyAnaCdcbiAgfVxuICBpZiAobXMgPj0gbSkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gbSkgKyAnbSdcbiAgfVxuICBpZiAobXMgPj0gcykge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gcykgKyAncydcbiAgfVxuICByZXR1cm4gbXMgKyAnbXMnXG59XG5cbi8qKlxuICogTG9uZyBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBmbXRMb25nKG1zKSB7XG4gIHJldHVybiBwbHVyYWwobXMsIGQsICdkYXknKSB8fFxuICAgIHBsdXJhbChtcywgaCwgJ2hvdXInKSB8fFxuICAgIHBsdXJhbChtcywgbSwgJ21pbnV0ZScpIHx8XG4gICAgcGx1cmFsKG1zLCBzLCAnc2Vjb25kJykgfHxcbiAgICBtcyArICcgbXMnXG59XG5cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi9cblxuZnVuY3Rpb24gcGx1cmFsKG1zLCBuLCBuYW1lKSB7XG4gIGlmIChtcyA8IG4pIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAobXMgPCBuICogMS41KSB7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IobXMgLyBuKSArICcgJyArIG5hbWVcbiAgfVxuICByZXR1cm4gTWF0aC5jZWlsKG1zIC8gbikgKyAnICcgKyBuYW1lICsgJ3MnXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0b10\n")},"0d97":function(module,exports,__webpack_require__){eval("/**\n * Module dependencies.\n */\n\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = Transport;\n\n/**\n * Transport abstract constructor.\n *\n * @param {Object} options.\n * @api private\n */\n\nfunction Transport (opts) {\n  this.path = opts.path;\n  this.hostname = opts.hostname;\n  this.port = opts.port;\n  this.secure = opts.secure;\n  this.query = opts.query;\n  this.timestampParam = opts.timestampParam;\n  this.timestampRequests = opts.timestampRequests;\n  this.readyState = '';\n  this.agent = opts.agent || false;\n  this.socket = opts.socket;\n  this.enablesXDR = opts.enablesXDR;\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx;\n  this.key = opts.key;\n  this.passphrase = opts.passphrase;\n  this.cert = opts.cert;\n  this.ca = opts.ca;\n  this.ciphers = opts.ciphers;\n  this.rejectUnauthorized = opts.rejectUnauthorized;\n  this.forceNode = opts.forceNode;\n\n  // other options for Node.js client\n  this.extraHeaders = opts.extraHeaders;\n  this.localAddress = opts.localAddress;\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Transport.prototype);\n\n/**\n * Emits an error.\n *\n * @param {String} str\n * @return {Transport} for chaining\n * @api public\n */\n\nTransport.prototype.onError = function (msg, desc) {\n  var err = new Error(msg);\n  err.type = 'TransportError';\n  err.description = desc;\n  this.emit('error', err);\n  return this;\n};\n\n/**\n * Opens the transport.\n *\n * @api public\n */\n\nTransport.prototype.open = function () {\n  if ('closed' === this.readyState || '' === this.readyState) {\n    this.readyState = 'opening';\n    this.doOpen();\n  }\n\n  return this;\n};\n\n/**\n * Closes the transport.\n *\n * @api private\n */\n\nTransport.prototype.close = function () {\n  if ('opening' === this.readyState || 'open' === this.readyState) {\n    this.doClose();\n    this.onClose();\n  }\n\n  return this;\n};\n\n/**\n * Sends multiple packets.\n *\n * @param {Array} packets\n * @api private\n */\n\nTransport.prototype.send = function (packets) {\n  if ('open' === this.readyState) {\n    this.write(packets);\n  } else {\n    throw new Error('Transport not open');\n  }\n};\n\n/**\n * Called upon open\n *\n * @api private\n */\n\nTransport.prototype.onOpen = function () {\n  this.readyState = 'open';\n  this.writable = true;\n  this.emit('open');\n};\n\n/**\n * Called with data.\n *\n * @param {String} data\n * @api private\n */\n\nTransport.prototype.onData = function (data) {\n  var packet = parser.decodePacket(data, this.socket.binaryType);\n  this.onPacket(packet);\n};\n\n/**\n * Called with a decoded packet.\n */\n\nTransport.prototype.onPacket = function (packet) {\n  this.emit('packet', packet);\n};\n\n/**\n * Called upon close.\n *\n * @api private\n */\n\nTransport.prototype.onClose = function () {\n  this.readyState = 'closed';\n  this.emit('close');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMGQ5Ny5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0LmpzPzMxMmIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBwYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc3BvcnQ7XG5cbi8qKlxuICogVHJhbnNwb3J0IGFic3RyYWN0IGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gVHJhbnNwb3J0IChvcHRzKSB7XG4gIHRoaXMucGF0aCA9IG9wdHMucGF0aDtcbiAgdGhpcy5ob3N0bmFtZSA9IG9wdHMuaG9zdG5hbWU7XG4gIHRoaXMucG9ydCA9IG9wdHMucG9ydDtcbiAgdGhpcy5zZWN1cmUgPSBvcHRzLnNlY3VyZTtcbiAgdGhpcy5xdWVyeSA9IG9wdHMucXVlcnk7XG4gIHRoaXMudGltZXN0YW1wUGFyYW0gPSBvcHRzLnRpbWVzdGFtcFBhcmFtO1xuICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50IHx8IGZhbHNlO1xuICB0aGlzLnNvY2tldCA9IG9wdHMuc29ja2V0O1xuICB0aGlzLmVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG5cbiAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIHRoaXMucGZ4ID0gb3B0cy5wZng7XG4gIHRoaXMua2V5ID0gb3B0cy5rZXk7XG4gIHRoaXMucGFzc3BocmFzZSA9IG9wdHMucGFzc3BocmFzZTtcbiAgdGhpcy5jZXJ0ID0gb3B0cy5jZXJ0O1xuICB0aGlzLmNhID0gb3B0cy5jYTtcbiAgdGhpcy5jaXBoZXJzID0gb3B0cy5jaXBoZXJzO1xuICB0aGlzLnJlamVjdFVuYXV0aG9yaXplZCA9IG9wdHMucmVqZWN0VW5hdXRob3JpemVkO1xuICB0aGlzLmZvcmNlTm9kZSA9IG9wdHMuZm9yY2VOb2RlO1xuXG4gIC8vIG90aGVyIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIHRoaXMuZXh0cmFIZWFkZXJzID0gb3B0cy5leHRyYUhlYWRlcnM7XG4gIHRoaXMubG9jYWxBZGRyZXNzID0gb3B0cy5sb2NhbEFkZHJlc3M7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFRyYW5zcG9ydC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIEVtaXRzIGFuIGVycm9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge1RyYW5zcG9ydH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uIChtc2csIGRlc2MpIHtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcihtc2cpO1xuICBlcnIudHlwZSA9ICdUcmFuc3BvcnRFcnJvcic7XG4gIGVyci5kZXNjcmlwdGlvbiA9IGRlc2M7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3BlbnMgdGhlIHRyYW5zcG9ydC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCdjbG9zZWQnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJycgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcbiAgICB0aGlzLmRvT3BlbigpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENsb3NlcyB0aGUgdHJhbnNwb3J0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMuZG9DbG9zZSgpO1xuICAgIHRoaXMub25DbG9zZSgpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIG11bHRpcGxlIHBhY2tldHMuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFja2V0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuVHJhbnNwb3J0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKHBhY2tldHMpIHtcbiAgaWYgKCdvcGVuJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgdGhpcy53cml0ZShwYWNrZXRzKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zcG9ydCBub3Qgb3BlbicpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIG9wZW5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW4nO1xuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcbiAgdGhpcy5lbWl0KCdvcGVuJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIGRhdGEuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGFcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdmFyIHBhY2tldCA9IHBhcnNlci5kZWNvZGVQYWNrZXQoZGF0YSwgdGhpcy5zb2NrZXQuYmluYXJ5VHlwZSk7XG4gIHRoaXMub25QYWNrZXQocGFja2V0KTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHdpdGggYSBkZWNvZGVkIHBhY2tldC5cbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uUGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICB0aGlzLmVtaXQoJ3BhY2tldCcsIHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGNsb3NlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0d97\n")},"108d":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module requirements.\n */\n\nvar XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ \"86e3\");\nvar Polling = __webpack_require__(/*! ./polling */ \"181d\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:polling-xhr');\n\n/**\n * Module exports.\n */\n\nmodule.exports = XHR;\nmodule.exports.Request = Request;\n\n/**\n * Empty function\n */\n\nfunction empty () {}\n\n/**\n * XHR Polling constructor.\n *\n * @param {Object} opts\n * @api public\n */\n\nfunction XHR (opts) {\n  Polling.call(this, opts);\n  this.requestTimeout = opts.requestTimeout;\n\n  if (global.location) {\n    var isSSL = 'https:' === location.protocol;\n    var port = location.port;\n\n    // some user agents have empty `location.port`\n    if (!port) {\n      port = isSSL ? 443 : 80;\n    }\n\n    this.xd = opts.hostname !== global.location.hostname ||\n      port !== opts.port;\n    this.xs = opts.secure !== isSSL;\n  } else {\n    this.extraHeaders = opts.extraHeaders;\n  }\n}\n\n/**\n * Inherits from Polling.\n */\n\ninherit(XHR, Polling);\n\n/**\n * XHR supports binary\n */\n\nXHR.prototype.supportsBinary = true;\n\n/**\n * Creates a request.\n *\n * @param {String} method\n * @api private\n */\n\nXHR.prototype.request = function (opts) {\n  opts = opts || {};\n  opts.uri = this.uri();\n  opts.xd = this.xd;\n  opts.xs = this.xs;\n  opts.agent = this.agent || false;\n  opts.supportsBinary = this.supportsBinary;\n  opts.enablesXDR = this.enablesXDR;\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n  opts.requestTimeout = this.requestTimeout;\n\n  // other options for Node.js client\n  opts.extraHeaders = this.extraHeaders;\n\n  return new Request(opts);\n};\n\n/**\n * Sends data.\n *\n * @param {String} data to send.\n * @param {Function} called upon flush.\n * @api private\n */\n\nXHR.prototype.doWrite = function (data, fn) {\n  var isBinary = typeof data !== 'string' && data !== undefined;\n  var req = this.request({ method: 'POST', data: data, isBinary: isBinary });\n  var self = this;\n  req.on('success', fn);\n  req.on('error', function (err) {\n    self.onError('xhr post error', err);\n  });\n  this.sendXhr = req;\n};\n\n/**\n * Starts a poll cycle.\n *\n * @api private\n */\n\nXHR.prototype.doPoll = function () {\n  debug('xhr poll');\n  var req = this.request();\n  var self = this;\n  req.on('data', function (data) {\n    self.onData(data);\n  });\n  req.on('error', function (err) {\n    self.onError('xhr poll error', err);\n  });\n  this.pollXhr = req;\n};\n\n/**\n * Request constructor\n *\n * @param {Object} options\n * @api public\n */\n\nfunction Request (opts) {\n  this.method = opts.method || 'GET';\n  this.uri = opts.uri;\n  this.xd = !!opts.xd;\n  this.xs = !!opts.xs;\n  this.async = false !== opts.async;\n  this.data = undefined !== opts.data ? opts.data : null;\n  this.agent = opts.agent;\n  this.isBinary = opts.isBinary;\n  this.supportsBinary = opts.supportsBinary;\n  this.enablesXDR = opts.enablesXDR;\n  this.requestTimeout = opts.requestTimeout;\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx;\n  this.key = opts.key;\n  this.passphrase = opts.passphrase;\n  this.cert = opts.cert;\n  this.ca = opts.ca;\n  this.ciphers = opts.ciphers;\n  this.rejectUnauthorized = opts.rejectUnauthorized;\n\n  // other options for Node.js client\n  this.extraHeaders = opts.extraHeaders;\n\n  this.create();\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Request.prototype);\n\n/**\n * Creates the XHR object and sends the request.\n *\n * @api private\n */\n\nRequest.prototype.create = function () {\n  var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR };\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n\n  var xhr = this.xhr = new XMLHttpRequest(opts);\n  var self = this;\n\n  try {\n    debug('xhr open %s: %s', this.method, this.uri);\n    xhr.open(this.method, this.uri, this.async);\n    try {\n      if (this.extraHeaders) {\n        xhr.setDisableHeaderCheck(true);\n        for (var i in this.extraHeaders) {\n          if (this.extraHeaders.hasOwnProperty(i)) {\n            xhr.setRequestHeader(i, this.extraHeaders[i]);\n          }\n        }\n      }\n    } catch (e) {}\n    if (this.supportsBinary) {\n      // This has to be done after open because Firefox is stupid\n      // http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension\n      xhr.responseType = 'arraybuffer';\n    }\n\n    if ('POST' === this.method) {\n      try {\n        if (this.isBinary) {\n          xhr.setRequestHeader('Content-type', 'application/octet-stream');\n        } else {\n          xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');\n        }\n      } catch (e) {}\n    }\n\n    try {\n      xhr.setRequestHeader('Accept', '*/*');\n    } catch (e) {}\n\n    // ie6 check\n    if ('withCredentials' in xhr) {\n      xhr.withCredentials = true;\n    }\n\n    if (this.requestTimeout) {\n      xhr.timeout = this.requestTimeout;\n    }\n\n    if (this.hasXDR()) {\n      xhr.onload = function () {\n        self.onLoad();\n      };\n      xhr.onerror = function () {\n        self.onError(xhr.responseText);\n      };\n    } else {\n      xhr.onreadystatechange = function () {\n        if (4 !== xhr.readyState) return;\n        if (200 === xhr.status || 1223 === xhr.status) {\n          self.onLoad();\n        } else {\n          // make sure the `error` event handler that's user-set\n          // does not throw in the same tick and gets caught here\n          setTimeout(function () {\n            self.onError(xhr.status);\n          }, 0);\n        }\n      };\n    }\n\n    debug('xhr data %s', this.data);\n    xhr.send(this.data);\n  } catch (e) {\n    // Need to defer since .create() is called directly fhrom the constructor\n    // and thus the 'error' event can only be only bound *after* this exception\n    // occurs.  Therefore, also, we cannot throw here at all.\n    setTimeout(function () {\n      self.onError(e);\n    }, 0);\n    return;\n  }\n\n  if (global.document) {\n    this.index = Request.requestsCount++;\n    Request.requests[this.index] = this;\n  }\n};\n\n/**\n * Called upon successful response.\n *\n * @api private\n */\n\nRequest.prototype.onSuccess = function () {\n  this.emit('success');\n  this.cleanup();\n};\n\n/**\n * Called if we have data.\n *\n * @api private\n */\n\nRequest.prototype.onData = function (data) {\n  this.emit('data', data);\n  this.onSuccess();\n};\n\n/**\n * Called upon error.\n *\n * @api private\n */\n\nRequest.prototype.onError = function (err) {\n  this.emit('error', err);\n  this.cleanup(true);\n};\n\n/**\n * Cleans up house.\n *\n * @api private\n */\n\nRequest.prototype.cleanup = function (fromError) {\n  if ('undefined' === typeof this.xhr || null === this.xhr) {\n    return;\n  }\n  // xmlhttprequest\n  if (this.hasXDR()) {\n    this.xhr.onload = this.xhr.onerror = empty;\n  } else {\n    this.xhr.onreadystatechange = empty;\n  }\n\n  if (fromError) {\n    try {\n      this.xhr.abort();\n    } catch (e) {}\n  }\n\n  if (global.document) {\n    delete Request.requests[this.index];\n  }\n\n  this.xhr = null;\n};\n\n/**\n * Called upon load.\n *\n * @api private\n */\n\nRequest.prototype.onLoad = function () {\n  var data;\n  try {\n    var contentType;\n    try {\n      contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0];\n    } catch (e) {}\n    if (contentType === 'application/octet-stream') {\n      data = this.xhr.response || this.xhr.responseText;\n    } else {\n      if (!this.supportsBinary) {\n        data = this.xhr.responseText;\n      } else {\n        try {\n          data = String.fromCharCode.apply(null, new Uint8Array(this.xhr.response));\n        } catch (e) {\n          var ui8Arr = new Uint8Array(this.xhr.response);\n          var dataArray = [];\n          for (var idx = 0, length = ui8Arr.length; idx < length; idx++) {\n            dataArray.push(ui8Arr[idx]);\n          }\n\n          data = String.fromCharCode.apply(null, dataArray);\n        }\n      }\n    }\n  } catch (e) {\n    this.onError(e);\n  }\n  if (null != data) {\n    this.onData(data);\n  }\n};\n\n/**\n * Check if it has XDomainRequest.\n *\n * @api private\n */\n\nRequest.prototype.hasXDR = function () {\n  return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR;\n};\n\n/**\n * Aborts the request.\n *\n * @api public\n */\n\nRequest.prototype.abort = function () {\n  this.cleanup();\n};\n\n/**\n * Aborts pending requests when unloading the window. This is needed to prevent\n * memory leaks (e.g. when using IE) and to ensure that no spurious error is\n * emitted.\n */\n\nRequest.requestsCount = 0;\nRequest.requests = {};\n\nif (global.document) {\n  if (global.attachEvent) {\n    global.attachEvent('onunload', unloadHandler);\n  } else if (global.addEventListener) {\n    global.addEventListener('beforeunload', unloadHandler, false);\n  }\n}\n\nfunction unloadHandler () {\n  for (var i in Request.requests) {\n    if (Request.requests.hasOwnProperty(i)) {\n      Request.requests[i].abort();\n    }\n  }\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA4ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLXhoci5qcz9mYmY3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAqL1xuXG52YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdC1zc2wnKTtcbnZhciBQb2xsaW5nID0gcmVxdWlyZSgnLi9wb2xsaW5nJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgaW5oZXJpdCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1pbmhlcml0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnBvbGxpbmcteGhyJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBYSFI7XG5tb2R1bGUuZXhwb3J0cy5SZXF1ZXN0ID0gUmVxdWVzdDtcblxuLyoqXG4gKiBFbXB0eSBmdW5jdGlvblxuICovXG5cbmZ1bmN0aW9uIGVtcHR5ICgpIHt9XG5cbi8qKlxuICogWEhSIFBvbGxpbmcgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gWEhSIChvcHRzKSB7XG4gIFBvbGxpbmcuY2FsbCh0aGlzLCBvcHRzKTtcbiAgdGhpcy5yZXF1ZXN0VGltZW91dCA9IG9wdHMucmVxdWVzdFRpbWVvdXQ7XG5cbiAgaWYgKGdsb2JhbC5sb2NhdGlvbikge1xuICAgIHZhciBpc1NTTCA9ICdodHRwczonID09PSBsb2NhdGlvbi5wcm90b2NvbDtcbiAgICB2YXIgcG9ydCA9IGxvY2F0aW9uLnBvcnQ7XG5cbiAgICAvLyBzb21lIHVzZXIgYWdlbnRzIGhhdmUgZW1wdHkgYGxvY2F0aW9uLnBvcnRgXG4gICAgaWYgKCFwb3J0KSB7XG4gICAgICBwb3J0ID0gaXNTU0wgPyA0NDMgOiA4MDtcbiAgICB9XG5cbiAgICB0aGlzLnhkID0gb3B0cy5ob3N0bmFtZSAhPT0gZ2xvYmFsLmxvY2F0aW9uLmhvc3RuYW1lIHx8XG4gICAgICBwb3J0ICE9PSBvcHRzLnBvcnQ7XG4gICAgdGhpcy54cyA9IG9wdHMuc2VjdXJlICE9PSBpc1NTTDtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuICB9XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBQb2xsaW5nLlxuICovXG5cbmluaGVyaXQoWEhSLCBQb2xsaW5nKTtcblxuLyoqXG4gKiBYSFIgc3VwcG9ydHMgYmluYXJ5XG4gKi9cblxuWEhSLnByb3RvdHlwZS5zdXBwb3J0c0JpbmFyeSA9IHRydWU7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHJlcXVlc3QuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuWEhSLnByb3RvdHlwZS5yZXF1ZXN0ID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgb3B0cyA9IG9wdHMgfHwge307XG4gIG9wdHMudXJpID0gdGhpcy51cmkoKTtcbiAgb3B0cy54ZCA9IHRoaXMueGQ7XG4gIG9wdHMueHMgPSB0aGlzLnhzO1xuICBvcHRzLmFnZW50ID0gdGhpcy5hZ2VudCB8fCBmYWxzZTtcbiAgb3B0cy5zdXBwb3J0c0JpbmFyeSA9IHRoaXMuc3VwcG9ydHNCaW5hcnk7XG4gIG9wdHMuZW5hYmxlc1hEUiA9IHRoaXMuZW5hYmxlc1hEUjtcblxuICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgb3B0cy5wZnggPSB0aGlzLnBmeDtcbiAgb3B0cy5rZXkgPSB0aGlzLmtleTtcbiAgb3B0cy5wYXNzcGhyYXNlID0gdGhpcy5wYXNzcGhyYXNlO1xuICBvcHRzLmNlcnQgPSB0aGlzLmNlcnQ7XG4gIG9wdHMuY2EgPSB0aGlzLmNhO1xuICBvcHRzLmNpcGhlcnMgPSB0aGlzLmNpcGhlcnM7XG4gIG9wdHMucmVqZWN0VW5hdXRob3JpemVkID0gdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQ7XG4gIG9wdHMucmVxdWVzdFRpbWVvdXQgPSB0aGlzLnJlcXVlc3RUaW1lb3V0O1xuXG4gIC8vIG90aGVyIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIG9wdHMuZXh0cmFIZWFkZXJzID0gdGhpcy5leHRyYUhlYWRlcnM7XG5cbiAgcmV0dXJuIG5ldyBSZXF1ZXN0KG9wdHMpO1xufTtcblxuLyoqXG4gKiBTZW5kcyBkYXRhLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIHRvIHNlbmQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblhIUi5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uIChkYXRhLCBmbikge1xuICB2YXIgaXNCaW5hcnkgPSB0eXBlb2YgZGF0YSAhPT0gJ3N0cmluZycgJiYgZGF0YSAhPT0gdW5kZWZpbmVkO1xuICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KHsgbWV0aG9kOiAnUE9TVCcsIGRhdGE6IGRhdGEsIGlzQmluYXJ5OiBpc0JpbmFyeSB9KTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICByZXEub24oJ3N1Y2Nlc3MnLCBmbik7XG4gIHJlcS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgc2VsZi5vbkVycm9yKCd4aHIgcG9zdCBlcnJvcicsIGVycik7XG4gIH0pO1xuICB0aGlzLnNlbmRYaHIgPSByZXE7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuWEhSLnByb3RvdHlwZS5kb1BvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCd4aHIgcG9sbCcpO1xuICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KCk7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgcmVxLm9uKCdkYXRhJywgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBzZWxmLm9uRGF0YShkYXRhKTtcbiAgfSk7XG4gIHJlcS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgc2VsZi5vbkVycm9yKCd4aHIgcG9sbCBlcnJvcicsIGVycik7XG4gIH0pO1xuICB0aGlzLnBvbGxYaHIgPSByZXE7XG59O1xuXG4vKipcbiAqIFJlcXVlc3QgY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0IChvcHRzKSB7XG4gIHRoaXMubWV0aG9kID0gb3B0cy5tZXRob2QgfHwgJ0dFVCc7XG4gIHRoaXMudXJpID0gb3B0cy51cmk7XG4gIHRoaXMueGQgPSAhIW9wdHMueGQ7XG4gIHRoaXMueHMgPSAhIW9wdHMueHM7XG4gIHRoaXMuYXN5bmMgPSBmYWxzZSAhPT0gb3B0cy5hc3luYztcbiAgdGhpcy5kYXRhID0gdW5kZWZpbmVkICE9PSBvcHRzLmRhdGEgPyBvcHRzLmRhdGEgOiBudWxsO1xuICB0aGlzLmFnZW50ID0gb3B0cy5hZ2VudDtcbiAgdGhpcy5pc0JpbmFyeSA9IG9wdHMuaXNCaW5hcnk7XG4gIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSBvcHRzLnN1cHBvcnRzQmluYXJ5O1xuICB0aGlzLmVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG4gIHRoaXMucmVxdWVzdFRpbWVvdXQgPSBvcHRzLnJlcXVlc3RUaW1lb3V0O1xuXG4gIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLnBmeCA9IG9wdHMucGZ4O1xuICB0aGlzLmtleSA9IG9wdHMua2V5O1xuICB0aGlzLnBhc3NwaHJhc2UgPSBvcHRzLnBhc3NwaHJhc2U7XG4gIHRoaXMuY2VydCA9IG9wdHMuY2VydDtcbiAgdGhpcy5jYSA9IG9wdHMuY2E7XG4gIHRoaXMuY2lwaGVycyA9IG9wdHMuY2lwaGVycztcbiAgdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQgPSBvcHRzLnJlamVjdFVuYXV0aG9yaXplZDtcblxuICAvLyBvdGhlciBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuXG4gIHRoaXMuY3JlYXRlKCk7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFJlcXVlc3QucHJvdG90eXBlKTtcblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBYSFIgb2JqZWN0IGFuZCBzZW5kcyB0aGUgcmVxdWVzdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBvcHRzID0geyBhZ2VudDogdGhpcy5hZ2VudCwgeGRvbWFpbjogdGhpcy54ZCwgeHNjaGVtZTogdGhpcy54cywgZW5hYmxlc1hEUjogdGhpcy5lbmFibGVzWERSIH07XG5cbiAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIG9wdHMucGZ4ID0gdGhpcy5wZng7XG4gIG9wdHMua2V5ID0gdGhpcy5rZXk7XG4gIG9wdHMucGFzc3BocmFzZSA9IHRoaXMucGFzc3BocmFzZTtcbiAgb3B0cy5jZXJ0ID0gdGhpcy5jZXJ0O1xuICBvcHRzLmNhID0gdGhpcy5jYTtcbiAgb3B0cy5jaXBoZXJzID0gdGhpcy5jaXBoZXJzO1xuICBvcHRzLnJlamVjdFVuYXV0aG9yaXplZCA9IHRoaXMucmVqZWN0VW5hdXRob3JpemVkO1xuXG4gIHZhciB4aHIgPSB0aGlzLnhociA9IG5ldyBYTUxIdHRwUmVxdWVzdChvcHRzKTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRyeSB7XG4gICAgZGVidWcoJ3hociBvcGVuICVzOiAlcycsIHRoaXMubWV0aG9kLCB0aGlzLnVyaSk7XG4gICAgeGhyLm9wZW4odGhpcy5tZXRob2QsIHRoaXMudXJpLCB0aGlzLmFzeW5jKTtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuZXh0cmFIZWFkZXJzKSB7XG4gICAgICAgIHhoci5zZXREaXNhYmxlSGVhZGVyQ2hlY2sodHJ1ZSk7XG4gICAgICAgIGZvciAodmFyIGkgaW4gdGhpcy5leHRyYUhlYWRlcnMpIHtcbiAgICAgICAgICBpZiAodGhpcy5leHRyYUhlYWRlcnMuaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGksIHRoaXMuZXh0cmFIZWFkZXJzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIGlmICh0aGlzLnN1cHBvcnRzQmluYXJ5KSB7XG4gICAgICAvLyBUaGlzIGhhcyB0byBiZSBkb25lIGFmdGVyIG9wZW4gYmVjYXVzZSBGaXJlZm94IGlzIHN0dXBpZFxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMzIxNjkwMy9nZXQtYmluYXJ5LWRhdGEtd2l0aC14bWxodHRwcmVxdWVzdC1pbi1hLWZpcmVmb3gtZXh0ZW5zaW9uXG4gICAgICB4aHIucmVzcG9uc2VUeXBlID0gJ2FycmF5YnVmZmVyJztcbiAgICB9XG5cbiAgICBpZiAoJ1BPU1QnID09PSB0aGlzLm1ldGhvZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHRoaXMuaXNCaW5hcnkpIHtcbiAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdBY2NlcHQnLCAnKi8qJyk7XG4gICAgfSBjYXRjaCAoZSkge31cblxuICAgIC8vIGllNiBjaGVja1xuICAgIGlmICgnd2l0aENyZWRlbnRpYWxzJyBpbiB4aHIpIHtcbiAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnJlcXVlc3RUaW1lb3V0KSB7XG4gICAgICB4aHIudGltZW91dCA9IHRoaXMucmVxdWVzdFRpbWVvdXQ7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaGFzWERSKCkpIHtcbiAgICAgIHhoci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYub25Mb2FkKCk7XG4gICAgICB9O1xuICAgICAgeGhyLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYub25FcnJvcih4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICg0ICE9PSB4aHIucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICBpZiAoMjAwID09PSB4aHIuc3RhdHVzIHx8IDEyMjMgPT09IHhoci5zdGF0dXMpIHtcbiAgICAgICAgICBzZWxmLm9uTG9hZCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgYGVycm9yYCBldmVudCBoYW5kbGVyIHRoYXQncyB1c2VyLXNldFxuICAgICAgICAgIC8vIGRvZXMgbm90IHRocm93IGluIHRoZSBzYW1lIHRpY2sgYW5kIGdldHMgY2F1Z2h0IGhlcmVcbiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNlbGYub25FcnJvcih4aHIuc3RhdHVzKTtcbiAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBkZWJ1ZygneGhyIGRhdGEgJXMnLCB0aGlzLmRhdGEpO1xuICAgIHhoci5zZW5kKHRoaXMuZGF0YSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBOZWVkIHRvIGRlZmVyIHNpbmNlIC5jcmVhdGUoKSBpcyBjYWxsZWQgZGlyZWN0bHkgZmhyb20gdGhlIGNvbnN0cnVjdG9yXG4gICAgLy8gYW5kIHRodXMgdGhlICdlcnJvcicgZXZlbnQgY2FuIG9ubHkgYmUgb25seSBib3VuZCAqYWZ0ZXIqIHRoaXMgZXhjZXB0aW9uXG4gICAgLy8gb2NjdXJzLiAgVGhlcmVmb3JlLCBhbHNvLCB3ZSBjYW5ub3QgdGhyb3cgaGVyZSBhdCBhbGwuXG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBzZWxmLm9uRXJyb3IoZSk7XG4gICAgfSwgMCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGdsb2JhbC5kb2N1bWVudCkge1xuICAgIHRoaXMuaW5kZXggPSBSZXF1ZXN0LnJlcXVlc3RzQ291bnQrKztcbiAgICBSZXF1ZXN0LnJlcXVlc3RzW3RoaXMuaW5kZXhdID0gdGhpcztcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzdWNjZXNzZnVsIHJlc3BvbnNlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLm9uU3VjY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0KCdzdWNjZXNzJyk7XG4gIHRoaXMuY2xlYW51cCgpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgaWYgd2UgaGF2ZSBkYXRhLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuZW1pdCgnZGF0YScsIGRhdGEpO1xuICB0aGlzLm9uU3VjY2VzcygpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKGVycikge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5jbGVhbnVwKHRydWUpO1xufTtcblxuLyoqXG4gKiBDbGVhbnMgdXAgaG91c2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuY2xlYW51cCA9IGZ1bmN0aW9uIChmcm9tRXJyb3IpIHtcbiAgaWYgKCd1bmRlZmluZWQnID09PSB0eXBlb2YgdGhpcy54aHIgfHwgbnVsbCA9PT0gdGhpcy54aHIpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8geG1saHR0cHJlcXVlc3RcbiAgaWYgKHRoaXMuaGFzWERSKCkpIHtcbiAgICB0aGlzLnhoci5vbmxvYWQgPSB0aGlzLnhoci5vbmVycm9yID0gZW1wdHk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZW1wdHk7XG4gIH1cblxuICBpZiAoZnJvbUVycm9yKSB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMueGhyLmFib3J0KCk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfVxuXG4gIGlmIChnbG9iYWwuZG9jdW1lbnQpIHtcbiAgICBkZWxldGUgUmVxdWVzdC5yZXF1ZXN0c1t0aGlzLmluZGV4XTtcbiAgfVxuXG4gIHRoaXMueGhyID0gbnVsbDtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gbG9hZC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vbkxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBkYXRhO1xuICB0cnkge1xuICAgIHZhciBjb250ZW50VHlwZTtcbiAgICB0cnkge1xuICAgICAgY29udGVudFR5cGUgPSB0aGlzLnhoci5nZXRSZXNwb25zZUhlYWRlcignQ29udGVudC1UeXBlJykuc3BsaXQoJzsnKVswXTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIGlmIChjb250ZW50VHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpIHtcbiAgICAgIGRhdGEgPSB0aGlzLnhoci5yZXNwb25zZSB8fCB0aGlzLnhoci5yZXNwb25zZVRleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy5zdXBwb3J0c0JpbmFyeSkge1xuICAgICAgICBkYXRhID0gdGhpcy54aHIucmVzcG9uc2VUZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDhBcnJheSh0aGlzLnhoci5yZXNwb25zZSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdmFyIHVpOEFyciA9IG5ldyBVaW50OEFycmF5KHRoaXMueGhyLnJlc3BvbnNlKTtcbiAgICAgICAgICB2YXIgZGF0YUFycmF5ID0gW107XG4gICAgICAgICAgZm9yICh2YXIgaWR4ID0gMCwgbGVuZ3RoID0gdWk4QXJyLmxlbmd0aDsgaWR4IDwgbGVuZ3RoOyBpZHgrKykge1xuICAgICAgICAgICAgZGF0YUFycmF5LnB1c2godWk4QXJyW2lkeF0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGRhdGFBcnJheSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aGlzLm9uRXJyb3IoZSk7XG4gIH1cbiAgaWYgKG51bGwgIT0gZGF0YSkge1xuICAgIHRoaXMub25EYXRhKGRhdGEpO1xuICB9XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIGl0IGhhcyBYRG9tYWluUmVxdWVzdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5oYXNYRFIgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGdsb2JhbC5YRG9tYWluUmVxdWVzdCAmJiAhdGhpcy54cyAmJiB0aGlzLmVuYWJsZXNYRFI7XG59O1xuXG4vKipcbiAqIEFib3J0cyB0aGUgcmVxdWVzdC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmFib3J0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmNsZWFudXAoKTtcbn07XG5cbi8qKlxuICogQWJvcnRzIHBlbmRpbmcgcmVxdWVzdHMgd2hlbiB1bmxvYWRpbmcgdGhlIHdpbmRvdy4gVGhpcyBpcyBuZWVkZWQgdG8gcHJldmVudFxuICogbWVtb3J5IGxlYWtzIChlLmcuIHdoZW4gdXNpbmcgSUUpIGFuZCB0byBlbnN1cmUgdGhhdCBubyBzcHVyaW91cyBlcnJvciBpc1xuICogZW1pdHRlZC5cbiAqL1xuXG5SZXF1ZXN0LnJlcXVlc3RzQ291bnQgPSAwO1xuUmVxdWVzdC5yZXF1ZXN0cyA9IHt9O1xuXG5pZiAoZ2xvYmFsLmRvY3VtZW50KSB7XG4gIGlmIChnbG9iYWwuYXR0YWNoRXZlbnQpIHtcbiAgICBnbG9iYWwuYXR0YWNoRXZlbnQoJ29udW5sb2FkJywgdW5sb2FkSGFuZGxlcik7XG4gIH0gZWxzZSBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgdW5sb2FkSGFuZGxlciwgZmFsc2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVubG9hZEhhbmRsZXIgKCkge1xuICBmb3IgKHZhciBpIGluIFJlcXVlc3QucmVxdWVzdHMpIHtcbiAgICBpZiAoUmVxdWVzdC5yZXF1ZXN0cy5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgUmVxdWVzdC5yZXF1ZXN0c1tpXS5hYm9ydCgpO1xuICAgIH1cbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///108d\n")},1278:function(module,exports,__webpack_require__){eval("/**\n * Selection\n * @module client/util-selection\n */\nvar misval = __webpack_require__(/*! ./misval */ \"bff6\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\n/*\n * Set a categorial 1D filter function\n * @param {Partition} partition\n */\nfunction filterFunctionCategorial1D (partition) {\n  var haystack = {};\n\n  if (!partition.selected || !partition.selected.length) {\n    partition.groups.forEach(function (group) {\n      haystack[group.value] = true;\n    });\n  } else {\n    partition.selected.forEach(function (h) {\n      haystack[h] = true;\n    });\n  }\n\n  return function (d) {\n    var needle = d;\n    if (!(needle instanceof Array)) {\n      needle = [d];\n    }\n\n    var selected = false;\n    needle.forEach(function (s) {\n      selected = selected | haystack[s];\n    });\n    return !!selected;\n  };\n}\n\n/*\n * Set a text filter function\n * @param {Partition} partition\n */\nfunction filterFunctionText (partition) {\n  var haystack = {};\n\n  // nothing selected, so all selected\n  if (partition.selected.length === 0) {\n    return function () {\n      return true;\n    };\n  }\n\n  partition.selected.forEach(function (h) {\n    haystack[h] = true;\n  });\n\n  return function (d) {\n    var needle = d;\n    if (!(needle instanceof Array)) {\n      needle = [d];\n    }\n\n    var selected = false;\n    needle.forEach(function (s) {\n      selected = selected | haystack[s];\n    });\n    return !!selected;\n  };\n}\n\n/*\n * Set a continuous 1D filter function\n * @param {Partition} partition\n */\nfunction filterFunctionContinuous1D (partition) {\n  var edge = partition.maxval;\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = partition.minval;\n    max = partition.maxval;\n    return function (d) {\n      return ((d >= min && d <= max) && (d !== misval));\n    };\n  } else {\n    min = partition.selected[0];\n    max = partition.selected[1];\n    return function (d) {\n      return ((d >= min && d < max) || ((d === edge) && (max === edge))) && (d !== misval);\n    };\n  }\n}\n\n/*\n * Set a continuous 1D filter function on a datetime dimension\n * @param {Partition} partition\n */\nfunction filterFunctionDatetime1D (partition) {\n  var edge = moment(partition.maxval);\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = moment(partition.minval);\n    max = moment(partition.maxval);\n\n    return function (d) {\n      var m = moment(d);\n      return (m !== misval) && !m.isBefore(min) && !m.isAfter(max);\n    };\n  } else {\n    min = moment(partition.selected[0]);\n    max = moment(partition.selected[1]);\n    return function (d) {\n      var m = moment(d);\n      return (m !== misval) && !min.isAfter(m) && (m.isBefore(max) || (max.isSame(edge) && max.isSame(m)));\n    };\n  }\n}\n\n/*\n * Set a continuous 1D filter function on a duration dimension\n * @param {Partition} partition\n */\nfunction filterFunctionDuration1D (partition) {\n  var edge = partition.maxval;\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = partition.minval;\n    max = partition.maxval;\n\n    return function (d) {\n      if (d === misval) {\n        return false;\n      }\n      var m = moment.duration(d);\n      return moment.isDuration(m) && m >= min && m <= max;\n    };\n  } else {\n    min = moment.duration(partition.selected[0]);\n    max = moment.duration(partition.selected[1]);\n    return function (d) {\n      if (d === misval) {\n        return false;\n      }\n      var m = moment.duration(d);\n      return moment.isDuration(m) && m >= min && (m < max || (m <= max && max >= edge));\n    };\n  }\n}\n\n/**\n * A filter function based for a single partition\n * @function\n * @returns {boolean} selected True if the datapoint is currently selected\n * @param {Partition} partition\n * @param {Object} datapoint\n * @memberof! Selection\n */\nfunction filterFunction (partition) {\n  if (partition.isCategorial || partition.isConstant) {\n    return filterFunctionCategorial1D(partition);\n  } else if (partition.isContinuous) {\n    return filterFunctionContinuous1D(partition);\n  } else if (partition.isDatetime) {\n    return filterFunctionDatetime1D(partition);\n  } else if (partition.isDuration) {\n    return filterFunctionDuration1D(partition);\n  } else if (partition.isText) {\n    return filterFunctionText(partition);\n  } else {\n    console.error('Cannot make filterfunction for partition', partition);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateCategorial1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // 1. none selected:\n    selected.push(group.value);\n  } else if (selected.length === 1) {\n    if (selected[0] === group.value) {\n      // 2. one selected and the group is the same:\n      selected.splice(0, selected.length);\n      partition.groups.forEach(function (g) {\n        if (g.value !== group.value) {\n          selected.push(g.value);\n        }\n      });\n    } else {\n      // 3. one selected and the group is different:\n      selected.push(group.value);\n    }\n  } else {\n    var i;\n    i = selected.indexOf(group.value);\n    if (i > -1) {\n      // 4. more than one selected and the group is in the selection:\n      selected.splice(i, 1);\n    } else {\n      // 5. more than one selected and the group is not in the selection:\n      selected.push(group.value);\n    }\n  }\n\n  // after add: if filters == groups, reset and dont filter\n  if (selected.length === partition.groups.length) {\n    selected.splice(0, selected.length);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateText (partition, group) {\n  var selected = partition.selected;\n\n  var i;\n  i = selected.indexOf(group.value);\n  if (i > -1) {\n    // 1. in the selection, remove it\n    selected.splice(i, 1);\n  } else {\n    // 2. not in the selection, add it\n    selected.push(group.value);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateContinuous1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min;\n    selected[1] = group.max;\n  } else if (group.min >= selected[1]) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max;\n  } else if (group.max <= selected[0]) {\n    // clicked outside to the left of selection\n    selected[0] = group.min;\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    if (partition.groupLog) {\n      d1 = Math.abs(Math.log(selected[0]) - Math.log(group.min));\n      d2 = Math.abs(Math.log(selected[1]) - Math.log(group.max));\n    } else {\n      d1 = Math.abs(selected[0] - group.min);\n      d2 = Math.abs(selected[1] - group.max);\n    }\n    if (d1 < d2) {\n      selected[0] = group.min;\n    } else {\n      selected[1] = group.max;\n    }\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateDatetime1D (partition, group) {\n  var selected = partition.selected;\n\n  if (!selected || selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min.toISOString();\n    selected[1] = group.max.toISOString();\n    return;\n  }\n\n  var selectionStart = moment(selected[0]);\n  var selectionEnd = moment(selected[1]);\n\n  if (!group.min.isBefore(selectionEnd)) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max.toISOString();\n  } else if (!group.max.isAfter(selectionStart)) {\n    // clicked outside to the left of selection\n    selected[0] = group.min.toISOString();\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    d1 = Math.abs(selectionStart.diff(group.min));\n    d2 = Math.abs(selectionEnd.diff(group.max));\n\n    if (d1 < d2) {\n      selected[0] = group.max.toISOString();\n    } else {\n      selected[1] = group.min.toISOString();\n    }\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateDuration1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min.toISOString();\n    selected[1] = group.max.toISOString();\n    return;\n  }\n\n  var selectionStart = moment.duration(selected[0]);\n  var selectionEnd = moment.duration(selected[1]);\n\n  if (group.min >= selectionEnd) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max.toISOString();\n  } else if (group.max <= selectionStart) {\n    // clicked outside to the left of selection\n    selected[0] = group.min.toISOString();\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    d1 = Math.abs(selectionStart - group.min);\n    d2 = Math.abs(selectionEnd - group.max);\n\n    if (d1 < d2) {\n      selected[0] = group.max.toISOString();\n    } else {\n      selected[1] = group.min.toISOString();\n    }\n  }\n}\n\n/**\n * Update the selection with a given group or interval\n * or, if no group is given, clear the selection.\n *\n * For categorial selections the following rules are used:\n * 1. none selected:\n *    add the group to the selection\n * 2. one selected and the group is the same:\n *    invert the selection\n * 3. one selected and the group is different:\n *    add the group to the selection\n * 4. more than one selected and the group is in the selection:\n *    remove the group from the selection\n * 5. more than one selected and the group is not in the selection:\n *    add the group to the selection\n *\n * For continuous selections the following rules are used:\n * 1. no range selected\n *    set the range equal to that of the group\n * 2. a range selected and the group is outside the selection:\n *    extend the selection to include the group\n * 3. a range selected and the group is inside the selection:\n *    set the endpoint closest to the group to that of the group\n *\n * @function\n * @param {Partition} Partition to update\n * @param {(string|number[])} Group or interval\n */\nfunction updateSelection (partition, group) {\n  if (!group) {\n    // Clear the selection (ie. all points are selected)\n    partition.selected.splice(0, partition.selected.length);\n  } else {\n    // Update the selection\n    if (partition.type === 'categorial' || partition.type === 'constant') {\n      updateCategorial1D(partition, group);\n    } else if (partition.type === 'continuous') {\n      updateContinuous1D(partition, group);\n    } else if (partition.type === 'datetime') {\n      updateDatetime1D(partition, group);\n    } else if (partition.type === 'duration') {\n      updateDuration1D(partition, group);\n    } else if (partition.type === 'text') {\n      updateText(partition, group);\n    } else {\n      console.error('Cannot update selection', partition.type);\n    }\n  }\n}\n\nmodule.exports = {\n  filterFunction: filterFunction,\n  updateSelection: updateSelection\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTI3OC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9zZWxlY3Rpb24uanM/NGY5ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNlbGVjdGlvblxuICogQG1vZHVsZSBjbGllbnQvdXRpbC1zZWxlY3Rpb25cbiAqL1xudmFyIG1pc3ZhbCA9IHJlcXVpcmUoJy4vbWlzdmFsJyk7XG52YXIgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50LXRpbWV6b25lJyk7XG5cbi8qXG4gKiBTZXQgYSBjYXRlZ29yaWFsIDFEIGZpbHRlciBmdW5jdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkNhdGVnb3JpYWwxRCAocGFydGl0aW9uKSB7XG4gIHZhciBoYXlzdGFjayA9IHt9O1xuXG4gIGlmICghcGFydGl0aW9uLnNlbGVjdGVkIHx8ICFwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKSB7XG4gICAgcGFydGl0aW9uLmdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgaGF5c3RhY2tbZ3JvdXAudmFsdWVdID0gdHJ1ZTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBwYXJ0aXRpb24uc2VsZWN0ZWQuZm9yRWFjaChmdW5jdGlvbiAoaCkge1xuICAgICAgaGF5c3RhY2tbaF0gPSB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgdmFyIG5lZWRsZSA9IGQ7XG4gICAgaWYgKCEobmVlZGxlIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICBuZWVkbGUgPSBbZF07XG4gICAgfVxuXG4gICAgdmFyIHNlbGVjdGVkID0gZmFsc2U7XG4gICAgbmVlZGxlLmZvckVhY2goZnVuY3Rpb24gKHMpIHtcbiAgICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQgfCBoYXlzdGFja1tzXTtcbiAgICB9KTtcbiAgICByZXR1cm4gISFzZWxlY3RlZDtcbiAgfTtcbn1cblxuLypcbiAqIFNldCBhIHRleHQgZmlsdGVyIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uVGV4dCAocGFydGl0aW9uKSB7XG4gIHZhciBoYXlzdGFjayA9IHt9O1xuXG4gIC8vIG5vdGhpbmcgc2VsZWN0ZWQsIHNvIGFsbCBzZWxlY3RlZFxuICBpZiAocGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuICB9XG5cbiAgcGFydGl0aW9uLnNlbGVjdGVkLmZvckVhY2goZnVuY3Rpb24gKGgpIHtcbiAgICBoYXlzdGFja1toXSA9IHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIHZhciBuZWVkbGUgPSBkO1xuICAgIGlmICghKG5lZWRsZSBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgbmVlZGxlID0gW2RdO1xuICAgIH1cblxuICAgIHZhciBzZWxlY3RlZCA9IGZhbHNlO1xuICAgIG5lZWRsZS5mb3JFYWNoKGZ1bmN0aW9uIChzKSB7XG4gICAgICBzZWxlY3RlZCA9IHNlbGVjdGVkIHwgaGF5c3RhY2tbc107XG4gICAgfSk7XG4gICAgcmV0dXJuICEhc2VsZWN0ZWQ7XG4gIH07XG59XG5cbi8qXG4gKiBTZXQgYSBjb250aW51b3VzIDFEIGZpbHRlciBmdW5jdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkNvbnRpbnVvdXMxRCAocGFydGl0aW9uKSB7XG4gIHZhciBlZGdlID0gcGFydGl0aW9uLm1heHZhbDtcbiAgdmFyIG1pbjtcbiAgdmFyIG1heDtcblxuICBpZiAoIXBhcnRpdGlvbi5zZWxlY3RlZCB8fCAhcGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCkge1xuICAgIG1pbiA9IHBhcnRpdGlvbi5taW52YWw7XG4gICAgbWF4ID0gcGFydGl0aW9uLm1heHZhbDtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHJldHVybiAoKGQgPj0gbWluICYmIGQgPD0gbWF4KSAmJiAoZCAhPT0gbWlzdmFsKSk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBwYXJ0aXRpb24uc2VsZWN0ZWRbMF07XG4gICAgbWF4ID0gcGFydGl0aW9uLnNlbGVjdGVkWzFdO1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgcmV0dXJuICgoZCA+PSBtaW4gJiYgZCA8IG1heCkgfHwgKChkID09PSBlZGdlKSAmJiAobWF4ID09PSBlZGdlKSkpICYmIChkICE9PSBtaXN2YWwpO1xuICAgIH07XG4gIH1cbn1cblxuLypcbiAqIFNldCBhIGNvbnRpbnVvdXMgMUQgZmlsdGVyIGZ1bmN0aW9uIG9uIGEgZGF0ZXRpbWUgZGltZW5zaW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uRGF0ZXRpbWUxRCAocGFydGl0aW9uKSB7XG4gIHZhciBlZGdlID0gbW9tZW50KHBhcnRpdGlvbi5tYXh2YWwpO1xuICB2YXIgbWluO1xuICB2YXIgbWF4O1xuXG4gIGlmICghcGFydGl0aW9uLnNlbGVjdGVkIHx8ICFwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKSB7XG4gICAgbWluID0gbW9tZW50KHBhcnRpdGlvbi5taW52YWwpO1xuICAgIG1heCA9IG1vbWVudChwYXJ0aXRpb24ubWF4dmFsKTtcblxuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIG0gPSBtb21lbnQoZCk7XG4gICAgICByZXR1cm4gKG0gIT09IG1pc3ZhbCkgJiYgIW0uaXNCZWZvcmUobWluKSAmJiAhbS5pc0FmdGVyKG1heCk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBtb21lbnQocGFydGl0aW9uLnNlbGVjdGVkWzBdKTtcbiAgICBtYXggPSBtb21lbnQocGFydGl0aW9uLnNlbGVjdGVkWzFdKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciBtID0gbW9tZW50KGQpO1xuICAgICAgcmV0dXJuIChtICE9PSBtaXN2YWwpICYmICFtaW4uaXNBZnRlcihtKSAmJiAobS5pc0JlZm9yZShtYXgpIHx8IChtYXguaXNTYW1lKGVkZ2UpICYmIG1heC5pc1NhbWUobSkpKTtcbiAgICB9O1xuICB9XG59XG5cbi8qXG4gKiBTZXQgYSBjb250aW51b3VzIDFEIGZpbHRlciBmdW5jdGlvbiBvbiBhIGR1cmF0aW9uIGRpbWVuc2lvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkR1cmF0aW9uMUQgKHBhcnRpdGlvbikge1xuICB2YXIgZWRnZSA9IHBhcnRpdGlvbi5tYXh2YWw7XG4gIHZhciBtaW47XG4gIHZhciBtYXg7XG5cbiAgaWYgKCFwYXJ0aXRpb24uc2VsZWN0ZWQgfHwgIXBhcnRpdGlvbi5zZWxlY3RlZC5sZW5ndGgpIHtcbiAgICBtaW4gPSBwYXJ0aXRpb24ubWludmFsO1xuICAgIG1heCA9IHBhcnRpdGlvbi5tYXh2YWw7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIG0gPSBtb21lbnQuZHVyYXRpb24oZCk7XG4gICAgICByZXR1cm4gbW9tZW50LmlzRHVyYXRpb24obSkgJiYgbSA+PSBtaW4gJiYgbSA8PSBtYXg7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBtb21lbnQuZHVyYXRpb24ocGFydGl0aW9uLnNlbGVjdGVkWzBdKTtcbiAgICBtYXggPSBtb21lbnQuZHVyYXRpb24ocGFydGl0aW9uLnNlbGVjdGVkWzFdKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIG0gPSBtb21lbnQuZHVyYXRpb24oZCk7XG4gICAgICByZXR1cm4gbW9tZW50LmlzRHVyYXRpb24obSkgJiYgbSA+PSBtaW4gJiYgKG0gPCBtYXggfHwgKG0gPD0gbWF4ICYmIG1heCA+PSBlZGdlKSk7XG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIEEgZmlsdGVyIGZ1bmN0aW9uIGJhc2VkIGZvciBhIHNpbmdsZSBwYXJ0aXRpb25cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge2Jvb2xlYW59IHNlbGVjdGVkIFRydWUgaWYgdGhlIGRhdGFwb2ludCBpcyBjdXJyZW50bHkgc2VsZWN0ZWRcbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhcG9pbnRcbiAqIEBtZW1iZXJvZiEgU2VsZWN0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgaWYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwgfHwgcGFydGl0aW9uLmlzQ29uc3RhbnQpIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25DYXRlZ29yaWFsMUQocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNDb250aW51b3VzKSB7XG4gICAgcmV0dXJuIGZpbHRlckZ1bmN0aW9uQ29udGludW91czFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzRGF0ZXRpbWUpIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25EYXRldGltZTFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzRHVyYXRpb24pIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25EdXJhdGlvbjFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzVGV4dCkge1xuICAgIHJldHVybiBmaWx0ZXJGdW5jdGlvblRleHQocGFydGl0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zb2xlLmVycm9yKCdDYW5ub3QgbWFrZSBmaWx0ZXJmdW5jdGlvbiBmb3IgcGFydGl0aW9uJywgcGFydGl0aW9uKTtcbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlQ2F0ZWdvcmlhbDFEIChwYXJ0aXRpb24sIGdyb3VwKSB7XG4gIHZhciBzZWxlY3RlZCA9IHBhcnRpdGlvbi5zZWxlY3RlZDtcblxuICBpZiAoc2VsZWN0ZWQubGVuZ3RoID09PSAwKSB7XG4gICAgLy8gMS4gbm9uZSBzZWxlY3RlZDpcbiAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgfSBlbHNlIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDEpIHtcbiAgICBpZiAoc2VsZWN0ZWRbMF0gPT09IGdyb3VwLnZhbHVlKSB7XG4gICAgICAvLyAyLiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyB0aGUgc2FtZTpcbiAgICAgIHNlbGVjdGVkLnNwbGljZSgwLCBzZWxlY3RlZC5sZW5ndGgpO1xuICAgICAgcGFydGl0aW9uLmdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChnKSB7XG4gICAgICAgIGlmIChnLnZhbHVlICE9PSBncm91cC52YWx1ZSkge1xuICAgICAgICAgIHNlbGVjdGVkLnB1c2goZy52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyAzLiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyBkaWZmZXJlbnQ6XG4gICAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGk7XG4gICAgaSA9IHNlbGVjdGVkLmluZGV4T2YoZ3JvdXAudmFsdWUpO1xuICAgIGlmIChpID4gLTEpIHtcbiAgICAgIC8vIDQuIG1vcmUgdGhhbiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyBpbiB0aGUgc2VsZWN0aW9uOlxuICAgICAgc2VsZWN0ZWQuc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyA1LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgbm90IGluIHRoZSBzZWxlY3Rpb246XG4gICAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvLyBhZnRlciBhZGQ6IGlmIGZpbHRlcnMgPT0gZ3JvdXBzLCByZXNldCBhbmQgZG9udCBmaWx0ZXJcbiAgaWYgKHNlbGVjdGVkLmxlbmd0aCA9PT0gcGFydGl0aW9uLmdyb3Vwcy5sZW5ndGgpIHtcbiAgICBzZWxlY3RlZC5zcGxpY2UoMCwgc2VsZWN0ZWQubGVuZ3RoKTtcbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlVGV4dCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgdmFyIGk7XG4gIGkgPSBzZWxlY3RlZC5pbmRleE9mKGdyb3VwLnZhbHVlKTtcbiAgaWYgKGkgPiAtMSkge1xuICAgIC8vIDEuIGluIHRoZSBzZWxlY3Rpb24sIHJlbW92ZSBpdFxuICAgIHNlbGVjdGVkLnNwbGljZShpLCAxKTtcbiAgfSBlbHNlIHtcbiAgICAvLyAyLiBub3QgaW4gdGhlIHNlbGVjdGlvbiwgYWRkIGl0XG4gICAgc2VsZWN0ZWQucHVzaChncm91cC52YWx1ZSk7XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7R3JvdXB9IGdyb3VwIC0gVGhlIGdyb3VwIHRvIGFkZCBvciByZW1vdmUgZnJvbSB0aGUgZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZUNvbnRpbnVvdXMxRCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgaWYgKHNlbGVjdGVkLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIG5vdGhpbmcgc2VsZWN0ZWQsIHN0YXJ0IGEgcmFuZ2VcbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbjtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heDtcbiAgfSBlbHNlIGlmIChncm91cC5taW4gPj0gc2VsZWN0ZWRbMV0pIHtcbiAgICAvLyBjbGlja2VkIG91dHNpZGUgdG8gdGhlIHJpZ3RoIG9mIHNlbGVjdGlvblxuICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4O1xuICB9IGVsc2UgaWYgKGdyb3VwLm1heCA8PSBzZWxlY3RlZFswXSkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbjtcbiAgfSBlbHNlIHtcbiAgICAvLyBjbGlja2VkIGluc2lkZSBzZWxlY3Rpb25cbiAgICB2YXIgZDEsIGQyO1xuICAgIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAgIGQxID0gTWF0aC5hYnMoTWF0aC5sb2coc2VsZWN0ZWRbMF0pIC0gTWF0aC5sb2coZ3JvdXAubWluKSk7XG4gICAgICBkMiA9IE1hdGguYWJzKE1hdGgubG9nKHNlbGVjdGVkWzFdKSAtIE1hdGgubG9nKGdyb3VwLm1heCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkMSA9IE1hdGguYWJzKHNlbGVjdGVkWzBdIC0gZ3JvdXAubWluKTtcbiAgICAgIGQyID0gTWF0aC5hYnMoc2VsZWN0ZWRbMV0gLSBncm91cC5tYXgpO1xuICAgIH1cbiAgICBpZiAoZDEgPCBkMikge1xuICAgICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW47XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4O1xuICAgIH1cbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGF0ZXRpbWUxRCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgaWYgKCFzZWxlY3RlZCB8fCBzZWxlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICAvLyBub3RoaW5nIHNlbGVjdGVkLCBzdGFydCBhIHJhbmdlXG4gICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxlY3Rpb25TdGFydCA9IG1vbWVudChzZWxlY3RlZFswXSk7XG4gIHZhciBzZWxlY3Rpb25FbmQgPSBtb21lbnQoc2VsZWN0ZWRbMV0pO1xuXG4gIGlmICghZ3JvdXAubWluLmlzQmVmb3JlKHNlbGVjdGlvbkVuZCkpIHtcbiAgICAvLyBjbGlja2VkIG91dHNpZGUgdG8gdGhlIHJpZ3RoIG9mIHNlbGVjdGlvblxuICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4LnRvSVNPU3RyaW5nKCk7XG4gIH0gZWxzZSBpZiAoIWdyb3VwLm1heC5pc0FmdGVyKHNlbGVjdGlvblN0YXJ0KSkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbi50b0lTT1N0cmluZygpO1xuICB9IGVsc2Uge1xuICAgIC8vIGNsaWNrZWQgaW5zaWRlIHNlbGVjdGlvblxuICAgIHZhciBkMSwgZDI7XG4gICAgZDEgPSBNYXRoLmFicyhzZWxlY3Rpb25TdGFydC5kaWZmKGdyb3VwLm1pbikpO1xuICAgIGQyID0gTWF0aC5hYnMoc2VsZWN0aW9uRW5kLmRpZmYoZ3JvdXAubWF4KSk7XG5cbiAgICBpZiAoZDEgPCBkMikge1xuICAgICAgc2VsZWN0ZWRbMF0gPSBncm91cC5tYXgudG9JU09TdHJpbmcoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZWN0ZWRbMV0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICB9XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7R3JvdXB9IGdyb3VwIC0gVGhlIGdyb3VwIHRvIGFkZCBvciByZW1vdmUgZnJvbSB0aGUgZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZUR1cmF0aW9uMUQgKHBhcnRpdGlvbiwgZ3JvdXApIHtcbiAgdmFyIHNlbGVjdGVkID0gcGFydGl0aW9uLnNlbGVjdGVkO1xuXG4gIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICAvLyBub3RoaW5nIHNlbGVjdGVkLCBzdGFydCBhIHJhbmdlXG4gICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxlY3Rpb25TdGFydCA9IG1vbWVudC5kdXJhdGlvbihzZWxlY3RlZFswXSk7XG4gIHZhciBzZWxlY3Rpb25FbmQgPSBtb21lbnQuZHVyYXRpb24oc2VsZWN0ZWRbMV0pO1xuXG4gIGlmIChncm91cC5taW4gPj0gc2VsZWN0aW9uRW5kKSB7XG4gICAgLy8gY2xpY2tlZCBvdXRzaWRlIHRvIHRoZSByaWd0aCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICB9IGVsc2UgaWYgKGdyb3VwLm1heCA8PSBzZWxlY3Rpb25TdGFydCkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbi50b0lTT1N0cmluZygpO1xuICB9IGVsc2Uge1xuICAgIC8vIGNsaWNrZWQgaW5zaWRlIHNlbGVjdGlvblxuICAgIHZhciBkMSwgZDI7XG4gICAgZDEgPSBNYXRoLmFicyhzZWxlY3Rpb25TdGFydCAtIGdyb3VwLm1pbik7XG4gICAgZDIgPSBNYXRoLmFicyhzZWxlY3Rpb25FbmQgLSBncm91cC5tYXgpO1xuXG4gICAgaWYgKGQxIDwgZDIpIHtcbiAgICAgIHNlbGVjdGVkWzBdID0gZ3JvdXAubWF4LnRvSVNPU3RyaW5nKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWluLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVXBkYXRlIHRoZSBzZWxlY3Rpb24gd2l0aCBhIGdpdmVuIGdyb3VwIG9yIGludGVydmFsXG4gKiBvciwgaWYgbm8gZ3JvdXAgaXMgZ2l2ZW4sIGNsZWFyIHRoZSBzZWxlY3Rpb24uXG4gKlxuICogRm9yIGNhdGVnb3JpYWwgc2VsZWN0aW9ucyB0aGUgZm9sbG93aW5nIHJ1bGVzIGFyZSB1c2VkOlxuICogMS4gbm9uZSBzZWxlY3RlZDpcbiAqICAgIGFkZCB0aGUgZ3JvdXAgdG8gdGhlIHNlbGVjdGlvblxuICogMi4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgdGhlIHNhbWU6XG4gKiAgICBpbnZlcnQgdGhlIHNlbGVjdGlvblxuICogMy4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgZGlmZmVyZW50OlxuICogICAgYWRkIHRoZSBncm91cCB0byB0aGUgc2VsZWN0aW9uXG4gKiA0LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgaW4gdGhlIHNlbGVjdGlvbjpcbiAqICAgIHJlbW92ZSB0aGUgZ3JvdXAgZnJvbSB0aGUgc2VsZWN0aW9uXG4gKiA1LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgbm90IGluIHRoZSBzZWxlY3Rpb246XG4gKiAgICBhZGQgdGhlIGdyb3VwIHRvIHRoZSBzZWxlY3Rpb25cbiAqXG4gKiBGb3IgY29udGludW91cyBzZWxlY3Rpb25zIHRoZSBmb2xsb3dpbmcgcnVsZXMgYXJlIHVzZWQ6XG4gKiAxLiBubyByYW5nZSBzZWxlY3RlZFxuICogICAgc2V0IHRoZSByYW5nZSBlcXVhbCB0byB0aGF0IG9mIHRoZSBncm91cFxuICogMi4gYSByYW5nZSBzZWxlY3RlZCBhbmQgdGhlIGdyb3VwIGlzIG91dHNpZGUgdGhlIHNlbGVjdGlvbjpcbiAqICAgIGV4dGVuZCB0aGUgc2VsZWN0aW9uIHRvIGluY2x1ZGUgdGhlIGdyb3VwXG4gKiAzLiBhIHJhbmdlIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgaW5zaWRlIHRoZSBzZWxlY3Rpb246XG4gKiAgICBzZXQgdGhlIGVuZHBvaW50IGNsb3Nlc3QgdG8gdGhlIGdyb3VwIHRvIHRoYXQgb2YgdGhlIGdyb3VwXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gUGFydGl0aW9uIHRvIHVwZGF0ZVxuICogQHBhcmFtIHsoc3RyaW5nfG51bWJlcltdKX0gR3JvdXAgb3IgaW50ZXJ2YWxcbiAqL1xuZnVuY3Rpb24gdXBkYXRlU2VsZWN0aW9uIChwYXJ0aXRpb24sIGdyb3VwKSB7XG4gIGlmICghZ3JvdXApIHtcbiAgICAvLyBDbGVhciB0aGUgc2VsZWN0aW9uIChpZS4gYWxsIHBvaW50cyBhcmUgc2VsZWN0ZWQpXG4gICAgcGFydGl0aW9uLnNlbGVjdGVkLnNwbGljZSgwLCBwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBVcGRhdGUgdGhlIHNlbGVjdGlvblxuICAgIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2NhdGVnb3JpYWwnIHx8IHBhcnRpdGlvbi50eXBlID09PSAnY29uc3RhbnQnKSB7XG4gICAgICB1cGRhdGVDYXRlZ29yaWFsMUQocGFydGl0aW9uLCBncm91cCk7XG4gICAgfSBlbHNlIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2NvbnRpbnVvdXMnKSB7XG4gICAgICB1cGRhdGVDb250aW51b3VzMUQocGFydGl0aW9uLCBncm91cCk7XG4gICAgfSBlbHNlIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgdXBkYXRlRGF0ZXRpbWUxRChwYXJ0aXRpb24sIGdyb3VwKTtcbiAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi50eXBlID09PSAnZHVyYXRpb24nKSB7XG4gICAgICB1cGRhdGVEdXJhdGlvbjFEKHBhcnRpdGlvbiwgZ3JvdXApO1xuICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLnR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgdXBkYXRlVGV4dChwYXJ0aXRpb24sIGdyb3VwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcignQ2Fubm90IHVwZGF0ZSBzZWxlY3Rpb24nLCBwYXJ0aXRpb24udHlwZSk7XG4gICAgfVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBmaWx0ZXJGdW5jdGlvbjogZmlsdGVyRnVuY3Rpb24sXG4gIHVwZGF0ZVNlbGVjdGlvbjogdXBkYXRlU2VsZWN0aW9uXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1278\n")},"181d":function(module,exports,__webpack_require__){eval("/**\n * Module dependencies.\n */\n\nvar Transport = __webpack_require__(/*! ../transport */ \"0d97\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar yeast = __webpack_require__(/*! yeast */ \"c16d\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:polling');\n\n/**\n * Module exports.\n */\n\nmodule.exports = Polling;\n\n/**\n * Is XHR2 supported?\n */\n\nvar hasXHR2 = (function () {\n  var XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ \"86e3\");\n  var xhr = new XMLHttpRequest({ xdomain: false });\n  return null != xhr.responseType;\n})();\n\n/**\n * Polling interface.\n *\n * @param {Object} opts\n * @api private\n */\n\nfunction Polling (opts) {\n  var forceBase64 = (opts && opts.forceBase64);\n  if (!hasXHR2 || forceBase64) {\n    this.supportsBinary = false;\n  }\n  Transport.call(this, opts);\n}\n\n/**\n * Inherits from Transport.\n */\n\ninherit(Polling, Transport);\n\n/**\n * Transport name.\n */\n\nPolling.prototype.name = 'polling';\n\n/**\n * Opens the socket (triggers polling). We write a PING message to determine\n * when the transport is open.\n *\n * @api private\n */\n\nPolling.prototype.doOpen = function () {\n  this.poll();\n};\n\n/**\n * Pauses polling.\n *\n * @param {Function} callback upon buffers are flushed and transport is paused\n * @api private\n */\n\nPolling.prototype.pause = function (onPause) {\n  var self = this;\n\n  this.readyState = 'pausing';\n\n  function pause () {\n    debug('paused');\n    self.readyState = 'paused';\n    onPause();\n  }\n\n  if (this.polling || !this.writable) {\n    var total = 0;\n\n    if (this.polling) {\n      debug('we are currently polling - waiting to pause');\n      total++;\n      this.once('pollComplete', function () {\n        debug('pre-pause polling complete');\n        --total || pause();\n      });\n    }\n\n    if (!this.writable) {\n      debug('we are currently writing - waiting to pause');\n      total++;\n      this.once('drain', function () {\n        debug('pre-pause writing complete');\n        --total || pause();\n      });\n    }\n  } else {\n    pause();\n  }\n};\n\n/**\n * Starts polling cycle.\n *\n * @api public\n */\n\nPolling.prototype.poll = function () {\n  debug('polling');\n  this.polling = true;\n  this.doPoll();\n  this.emit('poll');\n};\n\n/**\n * Overloads onData to detect payloads.\n *\n * @api private\n */\n\nPolling.prototype.onData = function (data) {\n  var self = this;\n  debug('polling got data %s', data);\n  var callback = function (packet, index, total) {\n    // if its the first message we consider the transport open\n    if ('opening' === self.readyState) {\n      self.onOpen();\n    }\n\n    // if its a close packet, we close the ongoing requests\n    if ('close' === packet.type) {\n      self.onClose();\n      return false;\n    }\n\n    // otherwise bypass onData and handle the message\n    self.onPacket(packet);\n  };\n\n  // decode payload\n  parser.decodePayload(data, this.socket.binaryType, callback);\n\n  // if an event did not trigger closing\n  if ('closed' !== this.readyState) {\n    // if we got data we're not polling\n    this.polling = false;\n    this.emit('pollComplete');\n\n    if ('open' === this.readyState) {\n      this.poll();\n    } else {\n      debug('ignoring poll - transport state \"%s\"', this.readyState);\n    }\n  }\n};\n\n/**\n * For polling, send a close packet.\n *\n * @api private\n */\n\nPolling.prototype.doClose = function () {\n  var self = this;\n\n  function close () {\n    debug('writing close packet');\n    self.write([{ type: 'close' }]);\n  }\n\n  if ('open' === this.readyState) {\n    debug('transport open - closing');\n    close();\n  } else {\n    // in case we're trying to close while\n    // handshaking is in progress (GH-164)\n    debug('transport not open - deferring close');\n    this.once('open', close);\n  }\n};\n\n/**\n * Writes a packets payload.\n *\n * @param {Array} data packets\n * @param {Function} drain callback\n * @api private\n */\n\nPolling.prototype.write = function (packets) {\n  var self = this;\n  this.writable = false;\n  var callbackfn = function () {\n    self.writable = true;\n    self.emit('drain');\n  };\n\n  parser.encodePayload(packets, this.supportsBinary, function (data) {\n    self.doWrite(data, callbackfn);\n  });\n};\n\n/**\n * Generates uri for connection.\n *\n * @api private\n */\n\nPolling.prototype.uri = function () {\n  var query = this.query || {};\n  var schema = this.secure ? 'https' : 'http';\n  var port = '';\n\n  // cache busting is forced\n  if (false !== this.timestampRequests) {\n    query[this.timestampParam] = yeast();\n  }\n\n  if (!this.supportsBinary && !query.sid) {\n    query.b64 = 1;\n  }\n\n  query = parseqs.encode(query);\n\n  // avoid port if default for schema\n  if (this.port && (('https' === schema && Number(this.port) !== 443) ||\n     ('http' === schema && Number(this.port) !== 80))) {\n    port = ':' + this.port;\n  }\n\n  // prepend ? to query\n  if (query.length) {\n    query = '?' + query;\n  }\n\n  var ipv6 = this.hostname.indexOf(':') !== -1;\n  return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTgxZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLmpzP2U1ZjkiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBUcmFuc3BvcnQgPSByZXF1aXJlKCcuLi90cmFuc3BvcnQnKTtcbnZhciBwYXJzZXFzID0gcmVxdWlyZSgncGFyc2VxcycpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcbnZhciB5ZWFzdCA9IHJlcXVpcmUoJ3llYXN0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnBvbGxpbmcnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBvbGxpbmc7XG5cbi8qKlxuICogSXMgWEhSMiBzdXBwb3J0ZWQ/XG4gKi9cblxudmFyIGhhc1hIUjIgPSAoZnVuY3Rpb24gKCkge1xuICB2YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdC1zc2wnKTtcbiAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCh7IHhkb21haW46IGZhbHNlIH0pO1xuICByZXR1cm4gbnVsbCAhPSB4aHIucmVzcG9uc2VUeXBlO1xufSkoKTtcblxuLyoqXG4gKiBQb2xsaW5nIGludGVyZmFjZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gUG9sbGluZyAob3B0cykge1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKCFoYXNYSFIyIHx8IGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIFRyYW5zcG9ydC5jYWxsKHRoaXMsIG9wdHMpO1xufVxuXG4vKipcbiAqIEluaGVyaXRzIGZyb20gVHJhbnNwb3J0LlxuICovXG5cbmluaGVyaXQoUG9sbGluZywgVHJhbnNwb3J0KTtcblxuLyoqXG4gKiBUcmFuc3BvcnQgbmFtZS5cbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5uYW1lID0gJ3BvbGxpbmcnO1xuXG4vKipcbiAqIE9wZW5zIHRoZSBzb2NrZXQgKHRyaWdnZXJzIHBvbGxpbmcpLiBXZSB3cml0ZSBhIFBJTkcgbWVzc2FnZSB0byBkZXRlcm1pbmVcbiAqIHdoZW4gdGhlIHRyYW5zcG9ydCBpcyBvcGVuLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLmRvT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5wb2xsKCk7XG59O1xuXG4vKipcbiAqIFBhdXNlcyBwb2xsaW5nLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHVwb24gYnVmZmVycyBhcmUgZmx1c2hlZCBhbmQgdHJhbnNwb3J0IGlzIHBhdXNlZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAob25QYXVzZSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5yZWFkeVN0YXRlID0gJ3BhdXNpbmcnO1xuXG4gIGZ1bmN0aW9uIHBhdXNlICgpIHtcbiAgICBkZWJ1ZygncGF1c2VkJyk7XG4gICAgc2VsZi5yZWFkeVN0YXRlID0gJ3BhdXNlZCc7XG4gICAgb25QYXVzZSgpO1xuICB9XG5cbiAgaWYgKHRoaXMucG9sbGluZyB8fCAhdGhpcy53cml0YWJsZSkge1xuICAgIHZhciB0b3RhbCA9IDA7XG5cbiAgICBpZiAodGhpcy5wb2xsaW5nKSB7XG4gICAgICBkZWJ1Zygnd2UgYXJlIGN1cnJlbnRseSBwb2xsaW5nIC0gd2FpdGluZyB0byBwYXVzZScpO1xuICAgICAgdG90YWwrKztcbiAgICAgIHRoaXMub25jZSgncG9sbENvbXBsZXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZWJ1ZygncHJlLXBhdXNlIHBvbGxpbmcgY29tcGxldGUnKTtcbiAgICAgICAgLS10b3RhbCB8fCBwYXVzZSgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLndyaXRhYmxlKSB7XG4gICAgICBkZWJ1Zygnd2UgYXJlIGN1cnJlbnRseSB3cml0aW5nIC0gd2FpdGluZyB0byBwYXVzZScpO1xuICAgICAgdG90YWwrKztcbiAgICAgIHRoaXMub25jZSgnZHJhaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlYnVnKCdwcmUtcGF1c2Ugd3JpdGluZyBjb21wbGV0ZScpO1xuICAgICAgICAtLXRvdGFsIHx8IHBhdXNlKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcGF1c2UoKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTdGFydHMgcG9sbGluZyBjeWNsZS5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblBvbGxpbmcucHJvdG90eXBlLnBvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCdwb2xsaW5nJyk7XG4gIHRoaXMucG9sbGluZyA9IHRydWU7XG4gIHRoaXMuZG9Qb2xsKCk7XG4gIHRoaXMuZW1pdCgncG9sbCcpO1xufTtcblxuLyoqXG4gKiBPdmVybG9hZHMgb25EYXRhIHRvIGRldGVjdCBwYXlsb2Fkcy5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5vbkRhdGEgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGRlYnVnKCdwb2xsaW5nIGdvdCBkYXRhICVzJywgZGF0YSk7XG4gIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uIChwYWNrZXQsIGluZGV4LCB0b3RhbCkge1xuICAgIC8vIGlmIGl0cyB0aGUgZmlyc3QgbWVzc2FnZSB3ZSBjb25zaWRlciB0aGUgdHJhbnNwb3J0IG9wZW5cbiAgICBpZiAoJ29wZW5pbmcnID09PSBzZWxmLnJlYWR5U3RhdGUpIHtcbiAgICAgIHNlbGYub25PcGVuKCk7XG4gICAgfVxuXG4gICAgLy8gaWYgaXRzIGEgY2xvc2UgcGFja2V0LCB3ZSBjbG9zZSB0aGUgb25nb2luZyByZXF1ZXN0c1xuICAgIGlmICgnY2xvc2UnID09PSBwYWNrZXQudHlwZSkge1xuICAgICAgc2VsZi5vbkNsb3NlKCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gb3RoZXJ3aXNlIGJ5cGFzcyBvbkRhdGEgYW5kIGhhbmRsZSB0aGUgbWVzc2FnZVxuICAgIHNlbGYub25QYWNrZXQocGFja2V0KTtcbiAgfTtcblxuICAvLyBkZWNvZGUgcGF5bG9hZFxuICBwYXJzZXIuZGVjb2RlUGF5bG9hZChkYXRhLCB0aGlzLnNvY2tldC5iaW5hcnlUeXBlLCBjYWxsYmFjayk7XG5cbiAgLy8gaWYgYW4gZXZlbnQgZGlkIG5vdCB0cmlnZ2VyIGNsb3NpbmdcbiAgaWYgKCdjbG9zZWQnICE9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAvLyBpZiB3ZSBnb3QgZGF0YSB3ZSdyZSBub3QgcG9sbGluZ1xuICAgIHRoaXMucG9sbGluZyA9IGZhbHNlO1xuICAgIHRoaXMuZW1pdCgncG9sbENvbXBsZXRlJyk7XG5cbiAgICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAgIHRoaXMucG9sbCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1ZygnaWdub3JpbmcgcG9sbCAtIHRyYW5zcG9ydCBzdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBGb3IgcG9sbGluZywgc2VuZCBhIGNsb3NlIHBhY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gY2xvc2UgKCkge1xuICAgIGRlYnVnKCd3cml0aW5nIGNsb3NlIHBhY2tldCcpO1xuICAgIHNlbGYud3JpdGUoW3sgdHlwZTogJ2Nsb3NlJyB9XSk7XG4gIH1cblxuICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICBkZWJ1ZygndHJhbnNwb3J0IG9wZW4gLSBjbG9zaW5nJyk7XG4gICAgY2xvc2UoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbiBjYXNlIHdlJ3JlIHRyeWluZyB0byBjbG9zZSB3aGlsZVxuICAgIC8vIGhhbmRzaGFraW5nIGlzIGluIHByb2dyZXNzIChHSC0xNjQpXG4gICAgZGVidWcoJ3RyYW5zcG9ydCBub3Qgb3BlbiAtIGRlZmVycmluZyBjbG9zZScpO1xuICAgIHRoaXMub25jZSgnb3BlbicsIGNsb3NlKTtcbiAgfVxufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBwYWNrZXRzIHBheWxvYWQuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gZGF0YSBwYWNrZXRzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBkcmFpbiBjYWxsYmFja1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAocGFja2V0cykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcbiAgdmFyIGNhbGxiYWNrZm4gPSBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi53cml0YWJsZSA9IHRydWU7XG4gICAgc2VsZi5lbWl0KCdkcmFpbicpO1xuICB9O1xuXG4gIHBhcnNlci5lbmNvZGVQYXlsb2FkKHBhY2tldHMsIHRoaXMuc3VwcG9ydHNCaW5hcnksIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgc2VsZi5kb1dyaXRlKGRhdGEsIGNhbGxiYWNrZm4pO1xuICB9KTtcbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIHVyaSBmb3IgY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS51cmkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBxdWVyeSA9IHRoaXMucXVlcnkgfHwge307XG4gIHZhciBzY2hlbWEgPSB0aGlzLnNlY3VyZSA/ICdodHRwcycgOiAnaHR0cCc7XG4gIHZhciBwb3J0ID0gJyc7XG5cbiAgLy8gY2FjaGUgYnVzdGluZyBpcyBmb3JjZWRcbiAgaWYgKGZhbHNlICE9PSB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzKSB7XG4gICAgcXVlcnlbdGhpcy50aW1lc3RhbXBQYXJhbV0gPSB5ZWFzdCgpO1xuICB9XG5cbiAgaWYgKCF0aGlzLnN1cHBvcnRzQmluYXJ5ICYmICFxdWVyeS5zaWQpIHtcbiAgICBxdWVyeS5iNjQgPSAxO1xuICB9XG5cbiAgcXVlcnkgPSBwYXJzZXFzLmVuY29kZShxdWVyeSk7XG5cbiAgLy8gYXZvaWQgcG9ydCBpZiBkZWZhdWx0IGZvciBzY2hlbWFcbiAgaWYgKHRoaXMucG9ydCAmJiAoKCdodHRwcycgPT09IHNjaGVtYSAmJiBOdW1iZXIodGhpcy5wb3J0KSAhPT0gNDQzKSB8fFxuICAgICAoJ2h0dHAnID09PSBzY2hlbWEgJiYgTnVtYmVyKHRoaXMucG9ydCkgIT09IDgwKSkpIHtcbiAgICBwb3J0ID0gJzonICsgdGhpcy5wb3J0O1xuICB9XG5cbiAgLy8gcHJlcGVuZCA/IHRvIHF1ZXJ5XG4gIGlmIChxdWVyeS5sZW5ndGgpIHtcbiAgICBxdWVyeSA9ICc/JyArIHF1ZXJ5O1xuICB9XG5cbiAgdmFyIGlwdjYgPSB0aGlzLmhvc3RuYW1lLmluZGV4T2YoJzonKSAhPT0gLTE7XG4gIHJldHVybiBzY2hlbWEgKyAnOi8vJyArIChpcHY2ID8gJ1snICsgdGhpcy5ob3N0bmFtZSArICddJyA6IHRoaXMuaG9zdG5hbWUpICsgcG9ydCArIHRoaXMucGF0aCArIHF1ZXJ5O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///181d\n")},"1e1f":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar eio = __webpack_require__(/*! engine.io-client */ \"c59b\");\nvar Socket = __webpack_require__(/*! ./socket */ \"4c13\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar on = __webpack_require__(/*! ./on */ \"faaa\");\nvar bind = __webpack_require__(/*! component-bind */ \"b6f6\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:manager');\nvar indexOf = __webpack_require__(/*! indexof */ \"3294\");\nvar Backoff = __webpack_require__(/*! backo2 */ \"f942\");\n\n/**\n * IE6+ hasOwnProperty\n */\n\nvar has = Object.prototype.hasOwnProperty;\n\n/**\n * Module exports\n */\n\nmodule.exports = Manager;\n\n/**\n * `Manager` constructor.\n *\n * @param {String} engine instance or engine uri/opts\n * @param {Object} options\n * @api public\n */\n\nfunction Manager (uri, opts) {\n  if (!(this instanceof Manager)) return new Manager(uri, opts);\n  if (uri && ('object' === typeof uri)) {\n    opts = uri;\n    uri = undefined;\n  }\n  opts = opts || {};\n\n  opts.path = opts.path || '/socket.io';\n  this.nsps = {};\n  this.subs = [];\n  this.opts = opts;\n  this.reconnection(opts.reconnection !== false);\n  this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);\n  this.reconnectionDelay(opts.reconnectionDelay || 1000);\n  this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);\n  this.randomizationFactor(opts.randomizationFactor || 0.5);\n  this.backoff = new Backoff({\n    min: this.reconnectionDelay(),\n    max: this.reconnectionDelayMax(),\n    jitter: this.randomizationFactor()\n  });\n  this.timeout(null == opts.timeout ? 20000 : opts.timeout);\n  this.readyState = 'closed';\n  this.uri = uri;\n  this.connecting = [];\n  this.lastPing = null;\n  this.encoding = false;\n  this.packetBuffer = [];\n  this.encoder = new parser.Encoder();\n  this.decoder = new parser.Decoder();\n  this.autoConnect = opts.autoConnect !== false;\n  if (this.autoConnect) this.open();\n}\n\n/**\n * Propagate given event to sockets and emit on `this`\n *\n * @api private\n */\n\nManager.prototype.emitAll = function () {\n  this.emit.apply(this, arguments);\n  for (var nsp in this.nsps) {\n    if (has.call(this.nsps, nsp)) {\n      this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);\n    }\n  }\n};\n\n/**\n * Update `socket.id` of all sockets\n *\n * @api private\n */\n\nManager.prototype.updateSocketIds = function () {\n  for (var nsp in this.nsps) {\n    if (has.call(this.nsps, nsp)) {\n      this.nsps[nsp].id = this.engine.id;\n    }\n  }\n};\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Manager.prototype);\n\n/**\n * Sets the `reconnection` config.\n *\n * @param {Boolean} true/false if it should automatically reconnect\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnection = function (v) {\n  if (!arguments.length) return this._reconnection;\n  this._reconnection = !!v;\n  return this;\n};\n\n/**\n * Sets the reconnection attempts config.\n *\n * @param {Number} max reconnection attempts before giving up\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionAttempts = function (v) {\n  if (!arguments.length) return this._reconnectionAttempts;\n  this._reconnectionAttempts = v;\n  return this;\n};\n\n/**\n * Sets the delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionDelay = function (v) {\n  if (!arguments.length) return this._reconnectionDelay;\n  this._reconnectionDelay = v;\n  this.backoff && this.backoff.setMin(v);\n  return this;\n};\n\nManager.prototype.randomizationFactor = function (v) {\n  if (!arguments.length) return this._randomizationFactor;\n  this._randomizationFactor = v;\n  this.backoff && this.backoff.setJitter(v);\n  return this;\n};\n\n/**\n * Sets the maximum delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionDelayMax = function (v) {\n  if (!arguments.length) return this._reconnectionDelayMax;\n  this._reconnectionDelayMax = v;\n  this.backoff && this.backoff.setMax(v);\n  return this;\n};\n\n/**\n * Sets the connection timeout. `false` to disable\n *\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.timeout = function (v) {\n  if (!arguments.length) return this._timeout;\n  this._timeout = v;\n  return this;\n};\n\n/**\n * Starts trying to reconnect if reconnection is enabled and we have not\n * started reconnecting yet\n *\n * @api private\n */\n\nManager.prototype.maybeReconnectOnOpen = function () {\n  // Only try to reconnect if it's the first time we're connecting\n  if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) {\n    // keeps reconnection from firing twice for the same reconnection loop\n    this.reconnect();\n  }\n};\n\n/**\n * Sets the current transport `socket`.\n *\n * @param {Function} optional, callback\n * @return {Manager} self\n * @api public\n */\n\nManager.prototype.open =\nManager.prototype.connect = function (fn, opts) {\n  debug('readyState %s', this.readyState);\n  if (~this.readyState.indexOf('open')) return this;\n\n  debug('opening %s', this.uri);\n  this.engine = eio(this.uri, this.opts);\n  var socket = this.engine;\n  var self = this;\n  this.readyState = 'opening';\n  this.skipReconnect = false;\n\n  // emit `open`\n  var openSub = on(socket, 'open', function () {\n    self.onopen();\n    fn && fn();\n  });\n\n  // emit `connect_error`\n  var errorSub = on(socket, 'error', function (data) {\n    debug('connect_error');\n    self.cleanup();\n    self.readyState = 'closed';\n    self.emitAll('connect_error', data);\n    if (fn) {\n      var err = new Error('Connection error');\n      err.data = data;\n      fn(err);\n    } else {\n      // Only do this if there is no fn to handle the error\n      self.maybeReconnectOnOpen();\n    }\n  });\n\n  // emit `connect_timeout`\n  if (false !== this._timeout) {\n    var timeout = this._timeout;\n    debug('connect attempt will timeout after %d', timeout);\n\n    // set timer\n    var timer = setTimeout(function () {\n      debug('connect attempt timed out after %d', timeout);\n      openSub.destroy();\n      socket.close();\n      socket.emit('error', 'timeout');\n      self.emitAll('connect_timeout', timeout);\n    }, timeout);\n\n    this.subs.push({\n      destroy: function () {\n        clearTimeout(timer);\n      }\n    });\n  }\n\n  this.subs.push(openSub);\n  this.subs.push(errorSub);\n\n  return this;\n};\n\n/**\n * Called upon transport open.\n *\n * @api private\n */\n\nManager.prototype.onopen = function () {\n  debug('open');\n\n  // clear old subs\n  this.cleanup();\n\n  // mark as open\n  this.readyState = 'open';\n  this.emit('open');\n\n  // add new subs\n  var socket = this.engine;\n  this.subs.push(on(socket, 'data', bind(this, 'ondata')));\n  this.subs.push(on(socket, 'ping', bind(this, 'onping')));\n  this.subs.push(on(socket, 'pong', bind(this, 'onpong')));\n  this.subs.push(on(socket, 'error', bind(this, 'onerror')));\n  this.subs.push(on(socket, 'close', bind(this, 'onclose')));\n  this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));\n};\n\n/**\n * Called upon a ping.\n *\n * @api private\n */\n\nManager.prototype.onping = function () {\n  this.lastPing = new Date();\n  this.emitAll('ping');\n};\n\n/**\n * Called upon a packet.\n *\n * @api private\n */\n\nManager.prototype.onpong = function () {\n  this.emitAll('pong', new Date() - this.lastPing);\n};\n\n/**\n * Called with data.\n *\n * @api private\n */\n\nManager.prototype.ondata = function (data) {\n  this.decoder.add(data);\n};\n\n/**\n * Called when parser fully decodes a packet.\n *\n * @api private\n */\n\nManager.prototype.ondecoded = function (packet) {\n  this.emit('packet', packet);\n};\n\n/**\n * Called upon socket error.\n *\n * @api private\n */\n\nManager.prototype.onerror = function (err) {\n  debug('error', err);\n  this.emitAll('error', err);\n};\n\n/**\n * Creates a new socket for the given `nsp`.\n *\n * @return {Socket}\n * @api public\n */\n\nManager.prototype.socket = function (nsp, opts) {\n  var socket = this.nsps[nsp];\n  if (!socket) {\n    socket = new Socket(this, nsp, opts);\n    this.nsps[nsp] = socket;\n    var self = this;\n    socket.on('connecting', onConnecting);\n    socket.on('connect', function () {\n      socket.id = self.engine.id;\n    });\n\n    if (this.autoConnect) {\n      // manually call here since connecting evnet is fired before listening\n      onConnecting();\n    }\n  }\n\n  function onConnecting () {\n    if (!~indexOf(self.connecting, socket)) {\n      self.connecting.push(socket);\n    }\n  }\n\n  return socket;\n};\n\n/**\n * Called upon a socket close.\n *\n * @param {Socket} socket\n */\n\nManager.prototype.destroy = function (socket) {\n  var index = indexOf(this.connecting, socket);\n  if (~index) this.connecting.splice(index, 1);\n  if (this.connecting.length) return;\n\n  this.close();\n};\n\n/**\n * Writes a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nManager.prototype.packet = function (packet) {\n  debug('writing packet %j', packet);\n  var self = this;\n  if (packet.query && packet.type === 0) packet.nsp += '?' + packet.query;\n\n  if (!self.encoding) {\n    // encode, then write to engine with result\n    self.encoding = true;\n    this.encoder.encode(packet, function (encodedPackets) {\n      for (var i = 0; i < encodedPackets.length; i++) {\n        self.engine.write(encodedPackets[i], packet.options);\n      }\n      self.encoding = false;\n      self.processPacketQueue();\n    });\n  } else { // add packet to the queue\n    self.packetBuffer.push(packet);\n  }\n};\n\n/**\n * If packet buffer is non-empty, begins encoding the\n * next packet in line.\n *\n * @api private\n */\n\nManager.prototype.processPacketQueue = function () {\n  if (this.packetBuffer.length > 0 && !this.encoding) {\n    var pack = this.packetBuffer.shift();\n    this.packet(pack);\n  }\n};\n\n/**\n * Clean up transport subscriptions and packet buffer.\n *\n * @api private\n */\n\nManager.prototype.cleanup = function () {\n  debug('cleanup');\n\n  var subsLength = this.subs.length;\n  for (var i = 0; i < subsLength; i++) {\n    var sub = this.subs.shift();\n    sub.destroy();\n  }\n\n  this.packetBuffer = [];\n  this.encoding = false;\n  this.lastPing = null;\n\n  this.decoder.destroy();\n};\n\n/**\n * Close the current socket.\n *\n * @api private\n */\n\nManager.prototype.close =\nManager.prototype.disconnect = function () {\n  debug('disconnect');\n  this.skipReconnect = true;\n  this.reconnecting = false;\n  if ('opening' === this.readyState) {\n    // `onclose` will not fire because\n    // an open event never happened\n    this.cleanup();\n  }\n  this.backoff.reset();\n  this.readyState = 'closed';\n  if (this.engine) this.engine.close();\n};\n\n/**\n * Called upon engine close.\n *\n * @api private\n */\n\nManager.prototype.onclose = function (reason) {\n  debug('onclose');\n\n  this.cleanup();\n  this.backoff.reset();\n  this.readyState = 'closed';\n  this.emit('close', reason);\n\n  if (this._reconnection && !this.skipReconnect) {\n    this.reconnect();\n  }\n};\n\n/**\n * Attempt a reconnection.\n *\n * @api private\n */\n\nManager.prototype.reconnect = function () {\n  if (this.reconnecting || this.skipReconnect) return this;\n\n  var self = this;\n\n  if (this.backoff.attempts >= this._reconnectionAttempts) {\n    debug('reconnect failed');\n    this.backoff.reset();\n    this.emitAll('reconnect_failed');\n    this.reconnecting = false;\n  } else {\n    var delay = this.backoff.duration();\n    debug('will wait %dms before reconnect attempt', delay);\n\n    this.reconnecting = true;\n    var timer = setTimeout(function () {\n      if (self.skipReconnect) return;\n\n      debug('attempting reconnect');\n      self.emitAll('reconnect_attempt', self.backoff.attempts);\n      self.emitAll('reconnecting', self.backoff.attempts);\n\n      // check again for the case socket closed in above events\n      if (self.skipReconnect) return;\n\n      self.open(function (err) {\n        if (err) {\n          debug('reconnect attempt error');\n          self.reconnecting = false;\n          self.reconnect();\n          self.emitAll('reconnect_error', err.data);\n        } else {\n          debug('reconnect success');\n          self.onreconnect();\n        }\n      });\n    }, delay);\n\n    this.subs.push({\n      destroy: function () {\n        clearTimeout(timer);\n      }\n    });\n  }\n};\n\n/**\n * Called upon successful reconnect.\n *\n * @api private\n */\n\nManager.prototype.onreconnect = function () {\n  var attempt = this.backoff.attempts;\n  this.reconnecting = false;\n  this.backoff.reset();\n  this.updateSocketIds();\n  this.emitAll('reconnect', attempt);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMWUxZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvbWFuYWdlci5qcz9mMDk3Il0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBlaW8gPSByZXF1aXJlKCdlbmdpbmUuaW8tY2xpZW50Jyk7XG52YXIgU29ja2V0ID0gcmVxdWlyZSgnLi9zb2NrZXQnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgb24gPSByZXF1aXJlKCcuL29uJyk7XG52YXIgYmluZCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1iaW5kJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdzb2NrZXQuaW8tY2xpZW50Om1hbmFnZXInKTtcbnZhciBpbmRleE9mID0gcmVxdWlyZSgnaW5kZXhvZicpO1xudmFyIEJhY2tvZmYgPSByZXF1aXJlKCdiYWNrbzInKTtcblxuLyoqXG4gKiBJRTYrIGhhc093blByb3BlcnR5XG4gKi9cblxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hbmFnZXI7XG5cbi8qKlxuICogYE1hbmFnZXJgIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBlbmdpbmUgaW5zdGFuY2Ugb3IgZW5naW5lIHVyaS9vcHRzXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBNYW5hZ2VyICh1cmksIG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE1hbmFnZXIpKSByZXR1cm4gbmV3IE1hbmFnZXIodXJpLCBvcHRzKTtcbiAgaWYgKHVyaSAmJiAoJ29iamVjdCcgPT09IHR5cGVvZiB1cmkpKSB7XG4gICAgb3B0cyA9IHVyaTtcbiAgICB1cmkgPSB1bmRlZmluZWQ7XG4gIH1cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgb3B0cy5wYXRoID0gb3B0cy5wYXRoIHx8ICcvc29ja2V0LmlvJztcbiAgdGhpcy5uc3BzID0ge307XG4gIHRoaXMuc3VicyA9IFtdO1xuICB0aGlzLm9wdHMgPSBvcHRzO1xuICB0aGlzLnJlY29ubmVjdGlvbihvcHRzLnJlY29ubmVjdGlvbiAhPT0gZmFsc2UpO1xuICB0aGlzLnJlY29ubmVjdGlvbkF0dGVtcHRzKG9wdHMucmVjb25uZWN0aW9uQXR0ZW1wdHMgfHwgSW5maW5pdHkpO1xuICB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KG9wdHMucmVjb25uZWN0aW9uRGVsYXkgfHwgMTAwMCk7XG4gIHRoaXMucmVjb25uZWN0aW9uRGVsYXlNYXgob3B0cy5yZWNvbm5lY3Rpb25EZWxheU1heCB8fCA1MDAwKTtcbiAgdGhpcy5yYW5kb21pemF0aW9uRmFjdG9yKG9wdHMucmFuZG9taXphdGlvbkZhY3RvciB8fCAwLjUpO1xuICB0aGlzLmJhY2tvZmYgPSBuZXcgQmFja29mZih7XG4gICAgbWluOiB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KCksXG4gICAgbWF4OiB0aGlzLnJlY29ubmVjdGlvbkRlbGF5TWF4KCksXG4gICAgaml0dGVyOiB0aGlzLnJhbmRvbWl6YXRpb25GYWN0b3IoKVxuICB9KTtcbiAgdGhpcy50aW1lb3V0KG51bGwgPT0gb3B0cy50aW1lb3V0ID8gMjAwMDAgOiBvcHRzLnRpbWVvdXQpO1xuICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgdGhpcy51cmkgPSB1cmk7XG4gIHRoaXMuY29ubmVjdGluZyA9IFtdO1xuICB0aGlzLmxhc3RQaW5nID0gbnVsbDtcbiAgdGhpcy5lbmNvZGluZyA9IGZhbHNlO1xuICB0aGlzLnBhY2tldEJ1ZmZlciA9IFtdO1xuICB0aGlzLmVuY29kZXIgPSBuZXcgcGFyc2VyLkVuY29kZXIoKTtcbiAgdGhpcy5kZWNvZGVyID0gbmV3IHBhcnNlci5EZWNvZGVyKCk7XG4gIHRoaXMuYXV0b0Nvbm5lY3QgPSBvcHRzLmF1dG9Db25uZWN0ICE9PSBmYWxzZTtcbiAgaWYgKHRoaXMuYXV0b0Nvbm5lY3QpIHRoaXMub3BlbigpO1xufVxuXG4vKipcbiAqIFByb3BhZ2F0ZSBnaXZlbiBldmVudCB0byBzb2NrZXRzIGFuZCBlbWl0IG9uIGB0aGlzYFxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLmVtaXRBbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICBmb3IgKHZhciBuc3AgaW4gdGhpcy5uc3BzKSB7XG4gICAgaWYgKGhhcy5jYWxsKHRoaXMubnNwcywgbnNwKSkge1xuICAgICAgdGhpcy5uc3BzW25zcF0uZW1pdC5hcHBseSh0aGlzLm5zcHNbbnNwXSwgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogVXBkYXRlIGBzb2NrZXQuaWRgIG9mIGFsbCBzb2NrZXRzXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUudXBkYXRlU29ja2V0SWRzID0gZnVuY3Rpb24gKCkge1xuICBmb3IgKHZhciBuc3AgaW4gdGhpcy5uc3BzKSB7XG4gICAgaWYgKGhhcy5jYWxsKHRoaXMubnNwcywgbnNwKSkge1xuICAgICAgdGhpcy5uc3BzW25zcF0uaWQgPSB0aGlzLmVuZ2luZS5pZDtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKE1hbmFnZXIucHJvdG90eXBlKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBgcmVjb25uZWN0aW9uYCBjb25maWcuXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSB0cnVlL2ZhbHNlIGlmIGl0IHNob3VsZCBhdXRvbWF0aWNhbGx5IHJlY29ubmVjdFxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb24gPSBmdW5jdGlvbiAodikge1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb247XG4gIHRoaXMuX3JlY29ubmVjdGlvbiA9ICEhdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIHJlY29ubmVjdGlvbiBhdHRlbXB0cyBjb25maWcuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1heCByZWNvbm5lY3Rpb24gYXR0ZW1wdHMgYmVmb3JlIGdpdmluZyB1cFxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25BdHRlbXB0cyA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JlY29ubmVjdGlvbkF0dGVtcHRzO1xuICB0aGlzLl9yZWNvbm5lY3Rpb25BdHRlbXB0cyA9IHY7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBkZWxheSBiZXR3ZWVuIHJlY29ubmVjdGlvbnMuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGRlbGF5XG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnJlY29ubmVjdGlvbkRlbGF5ID0gZnVuY3Rpb24gKHYpIHtcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fcmVjb25uZWN0aW9uRGVsYXk7XG4gIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5ID0gdjtcbiAgdGhpcy5iYWNrb2ZmICYmIHRoaXMuYmFja29mZi5zZXRNaW4odik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuTWFuYWdlci5wcm90b3R5cGUucmFuZG9taXphdGlvbkZhY3RvciA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JhbmRvbWl6YXRpb25GYWN0b3I7XG4gIHRoaXMuX3JhbmRvbWl6YXRpb25GYWN0b3IgPSB2O1xuICB0aGlzLmJhY2tvZmYgJiYgdGhpcy5iYWNrb2ZmLnNldEppdHRlcih2KTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIG1heGltdW0gZGVsYXkgYmV0d2VlbiByZWNvbm5lY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBkZWxheVxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25EZWxheU1heCA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5TWF4O1xuICB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheU1heCA9IHY7XG4gIHRoaXMuYmFja29mZiAmJiB0aGlzLmJhY2tvZmYuc2V0TWF4KHYpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgY29ubmVjdGlvbiB0aW1lb3V0LiBgZmFsc2VgIHRvIGRpc2FibGVcbiAqXG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnRpbWVvdXQgPSBmdW5jdGlvbiAodikge1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl90aW1lb3V0O1xuICB0aGlzLl90aW1lb3V0ID0gdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyB0cnlpbmcgdG8gcmVjb25uZWN0IGlmIHJlY29ubmVjdGlvbiBpcyBlbmFibGVkIGFuZCB3ZSBoYXZlIG5vdFxuICogc3RhcnRlZCByZWNvbm5lY3RpbmcgeWV0XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUubWF5YmVSZWNvbm5lY3RPbk9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIC8vIE9ubHkgdHJ5IHRvIHJlY29ubmVjdCBpZiBpdCdzIHRoZSBmaXJzdCB0aW1lIHdlJ3JlIGNvbm5lY3RpbmdcbiAgaWYgKCF0aGlzLnJlY29ubmVjdGluZyAmJiB0aGlzLl9yZWNvbm5lY3Rpb24gJiYgdGhpcy5iYWNrb2ZmLmF0dGVtcHRzID09PSAwKSB7XG4gICAgLy8ga2VlcHMgcmVjb25uZWN0aW9uIGZyb20gZmlyaW5nIHR3aWNlIGZvciB0aGUgc2FtZSByZWNvbm5lY3Rpb24gbG9vcFxuICAgIHRoaXMucmVjb25uZWN0KCk7XG4gIH1cbn07XG5cbi8qKlxuICogU2V0cyB0aGUgY3VycmVudCB0cmFuc3BvcnQgYHNvY2tldGAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gb3B0aW9uYWwsIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9wZW4gPVxuTWFuYWdlci5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uIChmbiwgb3B0cykge1xuICBkZWJ1ZygncmVhZHlTdGF0ZSAlcycsIHRoaXMucmVhZHlTdGF0ZSk7XG4gIGlmICh+dGhpcy5yZWFkeVN0YXRlLmluZGV4T2YoJ29wZW4nKSkgcmV0dXJuIHRoaXM7XG5cbiAgZGVidWcoJ29wZW5pbmcgJXMnLCB0aGlzLnVyaSk7XG4gIHRoaXMuZW5naW5lID0gZWlvKHRoaXMudXJpLCB0aGlzLm9wdHMpO1xuICB2YXIgc29ja2V0ID0gdGhpcy5lbmdpbmU7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW5pbmcnO1xuICB0aGlzLnNraXBSZWNvbm5lY3QgPSBmYWxzZTtcblxuICAvLyBlbWl0IGBvcGVuYFxuICB2YXIgb3BlblN1YiA9IG9uKHNvY2tldCwgJ29wZW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5vbm9wZW4oKTtcbiAgICBmbiAmJiBmbigpO1xuICB9KTtcblxuICAvLyBlbWl0IGBjb25uZWN0X2Vycm9yYFxuICB2YXIgZXJyb3JTdWIgPSBvbihzb2NrZXQsICdlcnJvcicsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgZGVidWcoJ2Nvbm5lY3RfZXJyb3InKTtcbiAgICBzZWxmLmNsZWFudXAoKTtcbiAgICBzZWxmLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgICBzZWxmLmVtaXRBbGwoJ2Nvbm5lY3RfZXJyb3InLCBkYXRhKTtcbiAgICBpZiAoZm4pIHtcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gZXJyb3InKTtcbiAgICAgIGVyci5kYXRhID0gZGF0YTtcbiAgICAgIGZuKGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE9ubHkgZG8gdGhpcyBpZiB0aGVyZSBpcyBubyBmbiB0byBoYW5kbGUgdGhlIGVycm9yXG4gICAgICBzZWxmLm1heWJlUmVjb25uZWN0T25PcGVuKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBlbWl0IGBjb25uZWN0X3RpbWVvdXRgXG4gIGlmIChmYWxzZSAhPT0gdGhpcy5fdGltZW91dCkge1xuICAgIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgICBkZWJ1ZygnY29ubmVjdCBhdHRlbXB0IHdpbGwgdGltZW91dCBhZnRlciAlZCcsIHRpbWVvdXQpO1xuXG4gICAgLy8gc2V0IHRpbWVyXG4gICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBkZWJ1ZygnY29ubmVjdCBhdHRlbXB0IHRpbWVkIG91dCBhZnRlciAlZCcsIHRpbWVvdXQpO1xuICAgICAgb3BlblN1Yi5kZXN0cm95KCk7XG4gICAgICBzb2NrZXQuY2xvc2UoKTtcbiAgICAgIHNvY2tldC5lbWl0KCdlcnJvcicsICd0aW1lb3V0Jyk7XG4gICAgICBzZWxmLmVtaXRBbGwoJ2Nvbm5lY3RfdGltZW91dCcsIHRpbWVvdXQpO1xuICAgIH0sIHRpbWVvdXQpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdGhpcy5zdWJzLnB1c2gob3BlblN1Yik7XG4gIHRoaXMuc3Vicy5wdXNoKGVycm9yU3ViKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IG9wZW4uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1Zygnb3BlbicpO1xuXG4gIC8vIGNsZWFyIG9sZCBzdWJzXG4gIHRoaXMuY2xlYW51cCgpO1xuXG4gIC8vIG1hcmsgYXMgb3BlblxuICB0aGlzLnJlYWR5U3RhdGUgPSAnb3Blbic7XG4gIHRoaXMuZW1pdCgnb3BlbicpO1xuXG4gIC8vIGFkZCBuZXcgc3Vic1xuICB2YXIgc29ja2V0ID0gdGhpcy5lbmdpbmU7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2RhdGEnLCBiaW5kKHRoaXMsICdvbmRhdGEnKSkpO1xuICB0aGlzLnN1YnMucHVzaChvbihzb2NrZXQsICdwaW5nJywgYmluZCh0aGlzLCAnb25waW5nJykpKTtcbiAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAncG9uZycsIGJpbmQodGhpcywgJ29ucG9uZycpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2Vycm9yJywgYmluZCh0aGlzLCAnb25lcnJvcicpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2Nsb3NlJywgYmluZCh0aGlzLCAnb25jbG9zZScpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHRoaXMuZGVjb2RlciwgJ2RlY29kZWQnLCBiaW5kKHRoaXMsICdvbmRlY29kZWQnKSkpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBhIHBpbmcuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25waW5nID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmxhc3RQaW5nID0gbmV3IERhdGUoKTtcbiAgdGhpcy5lbWl0QWxsKCdwaW5nJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgcGFja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9ucG9uZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0QWxsKCdwb25nJywgbmV3IERhdGUoKSAtIHRoaXMubGFzdFBpbmcpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgd2l0aCBkYXRhLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uZGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuZGVjb2Rlci5hZGQoZGF0YSk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aGVuIHBhcnNlciBmdWxseSBkZWNvZGVzIGEgcGFja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uZGVjb2RlZCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzb2NrZXQgZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25lcnJvciA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgZGVidWcoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5lbWl0QWxsKCdlcnJvcicsIGVycik7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc29ja2V0IGZvciB0aGUgZ2l2ZW4gYG5zcGAuXG4gKlxuICogQHJldHVybiB7U29ja2V0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5zb2NrZXQgPSBmdW5jdGlvbiAobnNwLCBvcHRzKSB7XG4gIHZhciBzb2NrZXQgPSB0aGlzLm5zcHNbbnNwXTtcbiAgaWYgKCFzb2NrZXQpIHtcbiAgICBzb2NrZXQgPSBuZXcgU29ja2V0KHRoaXMsIG5zcCwgb3B0cyk7XG4gICAgdGhpcy5uc3BzW25zcF0gPSBzb2NrZXQ7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHNvY2tldC5vbignY29ubmVjdGluZycsIG9uQ29ubmVjdGluZyk7XG4gICAgc29ja2V0Lm9uKCdjb25uZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgc29ja2V0LmlkID0gc2VsZi5lbmdpbmUuaWQ7XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5hdXRvQ29ubmVjdCkge1xuICAgICAgLy8gbWFudWFsbHkgY2FsbCBoZXJlIHNpbmNlIGNvbm5lY3RpbmcgZXZuZXQgaXMgZmlyZWQgYmVmb3JlIGxpc3RlbmluZ1xuICAgICAgb25Db25uZWN0aW5nKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25Db25uZWN0aW5nICgpIHtcbiAgICBpZiAoIX5pbmRleE9mKHNlbGYuY29ubmVjdGluZywgc29ja2V0KSkge1xuICAgICAgc2VsZi5jb25uZWN0aW5nLnB1c2goc29ja2V0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc29ja2V0O1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBhIHNvY2tldCBjbG9zZS5cbiAqXG4gKiBAcGFyYW0ge1NvY2tldH0gc29ja2V0XG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uIChzb2NrZXQpIHtcbiAgdmFyIGluZGV4ID0gaW5kZXhPZih0aGlzLmNvbm5lY3RpbmcsIHNvY2tldCk7XG4gIGlmICh+aW5kZXgpIHRoaXMuY29ubmVjdGluZy5zcGxpY2UoaW5kZXgsIDEpO1xuICBpZiAodGhpcy5jb25uZWN0aW5nLmxlbmd0aCkgcmV0dXJuO1xuXG4gIHRoaXMuY2xvc2UoKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgcGFja2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgZGVidWcoJ3dyaXRpbmcgcGFja2V0ICVqJywgcGFja2V0KTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAocGFja2V0LnF1ZXJ5ICYmIHBhY2tldC50eXBlID09PSAwKSBwYWNrZXQubnNwICs9ICc/JyArIHBhY2tldC5xdWVyeTtcblxuICBpZiAoIXNlbGYuZW5jb2RpbmcpIHtcbiAgICAvLyBlbmNvZGUsIHRoZW4gd3JpdGUgdG8gZW5naW5lIHdpdGggcmVzdWx0XG4gICAgc2VsZi5lbmNvZGluZyA9IHRydWU7XG4gICAgdGhpcy5lbmNvZGVyLmVuY29kZShwYWNrZXQsIGZ1bmN0aW9uIChlbmNvZGVkUGFja2V0cykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbmNvZGVkUGFja2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBzZWxmLmVuZ2luZS53cml0ZShlbmNvZGVkUGFja2V0c1tpXSwgcGFja2V0Lm9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgc2VsZi5lbmNvZGluZyA9IGZhbHNlO1xuICAgICAgc2VsZi5wcm9jZXNzUGFja2V0UXVldWUoKTtcbiAgICB9KTtcbiAgfSBlbHNlIHsgLy8gYWRkIHBhY2tldCB0byB0aGUgcXVldWVcbiAgICBzZWxmLnBhY2tldEJ1ZmZlci5wdXNoKHBhY2tldCk7XG4gIH1cbn07XG5cbi8qKlxuICogSWYgcGFja2V0IGJ1ZmZlciBpcyBub24tZW1wdHksIGJlZ2lucyBlbmNvZGluZyB0aGVcbiAqIG5leHQgcGFja2V0IGluIGxpbmUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUucHJvY2Vzc1BhY2tldFF1ZXVlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5wYWNrZXRCdWZmZXIubGVuZ3RoID4gMCAmJiAhdGhpcy5lbmNvZGluZykge1xuICAgIHZhciBwYWNrID0gdGhpcy5wYWNrZXRCdWZmZXIuc2hpZnQoKTtcbiAgICB0aGlzLnBhY2tldChwYWNrKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDbGVhbiB1cCB0cmFuc3BvcnQgc3Vic2NyaXB0aW9ucyBhbmQgcGFja2V0IGJ1ZmZlci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5jbGVhbnVwID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2xlYW51cCcpO1xuXG4gIHZhciBzdWJzTGVuZ3RoID0gdGhpcy5zdWJzLmxlbmd0aDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdWJzTGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc3ViID0gdGhpcy5zdWJzLnNoaWZ0KCk7XG4gICAgc3ViLmRlc3Ryb3koKTtcbiAgfVxuXG4gIHRoaXMucGFja2V0QnVmZmVyID0gW107XG4gIHRoaXMuZW5jb2RpbmcgPSBmYWxzZTtcbiAgdGhpcy5sYXN0UGluZyA9IG51bGw7XG5cbiAgdGhpcy5kZWNvZGVyLmRlc3Ryb3koKTtcbn07XG5cbi8qKlxuICogQ2xvc2UgdGhlIGN1cnJlbnQgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLmNsb3NlID1cbk1hbmFnZXIucHJvdG90eXBlLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCdkaXNjb25uZWN0Jyk7XG4gIHRoaXMuc2tpcFJlY29ubmVjdCA9IHRydWU7XG4gIHRoaXMucmVjb25uZWN0aW5nID0gZmFsc2U7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIC8vIGBvbmNsb3NlYCB3aWxsIG5vdCBmaXJlIGJlY2F1c2VcbiAgICAvLyBhbiBvcGVuIGV2ZW50IG5ldmVyIGhhcHBlbmVkXG4gICAgdGhpcy5jbGVhbnVwKCk7XG4gIH1cbiAgdGhpcy5iYWNrb2ZmLnJlc2V0KCk7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuICBpZiAodGhpcy5lbmdpbmUpIHRoaXMuZW5naW5lLmNsb3NlKCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGVuZ2luZSBjbG9zZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vbmNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICBkZWJ1Zygnb25jbG9zZScpO1xuXG4gIHRoaXMuY2xlYW51cCgpO1xuICB0aGlzLmJhY2tvZmYucmVzZXQoKTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnLCByZWFzb24pO1xuXG4gIGlmICh0aGlzLl9yZWNvbm5lY3Rpb24gJiYgIXRoaXMuc2tpcFJlY29ubmVjdCkge1xuICAgIHRoaXMucmVjb25uZWN0KCk7XG4gIH1cbn07XG5cbi8qKlxuICogQXR0ZW1wdCBhIHJlY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnJlY29ubmVjdGluZyB8fCB0aGlzLnNraXBSZWNvbm5lY3QpIHJldHVybiB0aGlzO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAodGhpcy5iYWNrb2ZmLmF0dGVtcHRzID49IHRoaXMuX3JlY29ubmVjdGlvbkF0dGVtcHRzKSB7XG4gICAgZGVidWcoJ3JlY29ubmVjdCBmYWlsZWQnKTtcbiAgICB0aGlzLmJhY2tvZmYucmVzZXQoKTtcbiAgICB0aGlzLmVtaXRBbGwoJ3JlY29ubmVjdF9mYWlsZWQnKTtcbiAgICB0aGlzLnJlY29ubmVjdGluZyA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHZhciBkZWxheSA9IHRoaXMuYmFja29mZi5kdXJhdGlvbigpO1xuICAgIGRlYnVnKCd3aWxsIHdhaXQgJWRtcyBiZWZvcmUgcmVjb25uZWN0IGF0dGVtcHQnLCBkZWxheSk7XG5cbiAgICB0aGlzLnJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoc2VsZi5za2lwUmVjb25uZWN0KSByZXR1cm47XG5cbiAgICAgIGRlYnVnKCdhdHRlbXB0aW5nIHJlY29ubmVjdCcpO1xuICAgICAgc2VsZi5lbWl0QWxsKCdyZWNvbm5lY3RfYXR0ZW1wdCcsIHNlbGYuYmFja29mZi5hdHRlbXB0cyk7XG4gICAgICBzZWxmLmVtaXRBbGwoJ3JlY29ubmVjdGluZycsIHNlbGYuYmFja29mZi5hdHRlbXB0cyk7XG5cbiAgICAgIC8vIGNoZWNrIGFnYWluIGZvciB0aGUgY2FzZSBzb2NrZXQgY2xvc2VkIGluIGFib3ZlIGV2ZW50c1xuICAgICAgaWYgKHNlbGYuc2tpcFJlY29ubmVjdCkgcmV0dXJuO1xuXG4gICAgICBzZWxmLm9wZW4oZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgZGVidWcoJ3JlY29ubmVjdCBhdHRlbXB0IGVycm9yJyk7XG4gICAgICAgICAgc2VsZi5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLnJlY29ubmVjdCgpO1xuICAgICAgICAgIHNlbGYuZW1pdEFsbCgncmVjb25uZWN0X2Vycm9yJywgZXJyLmRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlYnVnKCdyZWNvbm5lY3Qgc3VjY2VzcycpO1xuICAgICAgICAgIHNlbGYub25yZWNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSwgZGVsYXkpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHN1Y2Nlc3NmdWwgcmVjb25uZWN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9ucmVjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXR0ZW1wdCA9IHRoaXMuYmFja29mZi5hdHRlbXB0cztcbiAgdGhpcy5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgdGhpcy5iYWNrb2ZmLnJlc2V0KCk7XG4gIHRoaXMudXBkYXRlU29ja2V0SWRzKCk7XG4gIHRoaXMuZW1pdEFsbCgncmVjb25uZWN0JywgYXR0ZW1wdCk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1e1f\n")},"1ed2":function(module,exports){eval("/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function(val, options){\n  options = options || {};\n  if ('string' == typeof val) return parse(val);\n  return options.long\n    ? long(val)\n    : short(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n  str = '' + str;\n  if (str.length > 10000) return;\n  var match = /^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);\n  if (!match) return;\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'yrs':\n    case 'yr':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'hrs':\n    case 'hr':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'mins':\n    case 'min':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 'secs':\n    case 'sec':\n    case 's':\n      return n * s;\n    case 'milliseconds':\n    case 'millisecond':\n    case 'msecs':\n    case 'msec':\n    case 'ms':\n      return n;\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction short(ms) {\n  if (ms >= d) return Math.round(ms / d) + 'd';\n  if (ms >= h) return Math.round(ms / h) + 'h';\n  if (ms >= m) return Math.round(ms / m) + 'm';\n  if (ms >= s) return Math.round(ms / s) + 's';\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction long(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, n, name) {\n  if (ms < n) return;\n  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMWVkMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvbXMvaW5kZXguanM/NDg1MiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhlbHBlcnMuXG4gKi9cblxudmFyIHMgPSAxMDAwO1xudmFyIG0gPSBzICogNjA7XG52YXIgaCA9IG0gKiA2MDtcbnZhciBkID0gaCAqIDI0O1xudmFyIHkgPSBkICogMzY1LjI1O1xuXG4vKipcbiAqIFBhcnNlIG9yIGZvcm1hdCB0aGUgZ2l2ZW4gYHZhbGAuXG4gKlxuICogT3B0aW9uczpcbiAqXG4gKiAgLSBgbG9uZ2AgdmVyYm9zZSBmb3JtYXR0aW5nIFtmYWxzZV1cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xOdW1iZXJ9IHZhbFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ3xOdW1iZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24odmFsLCBvcHRpb25zKXtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGlmICgnc3RyaW5nJyA9PSB0eXBlb2YgdmFsKSByZXR1cm4gcGFyc2UodmFsKTtcbiAgcmV0dXJuIG9wdGlvbnMubG9uZ1xuICAgID8gbG9uZyh2YWwpXG4gICAgOiBzaG9ydCh2YWwpO1xufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gYHN0cmAgYW5kIHJldHVybiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7TnVtYmVyfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcGFyc2Uoc3RyKSB7XG4gIHN0ciA9ICcnICsgc3RyO1xuICBpZiAoc3RyLmxlbmd0aCA+IDEwMDAwKSByZXR1cm47XG4gIHZhciBtYXRjaCA9IC9eKCg/OlxcZCspP1xcLj9cXGQrKSAqKG1pbGxpc2Vjb25kcz98bXNlY3M/fG1zfHNlY29uZHM/fHNlY3M/fHN8bWludXRlcz98bWlucz98bXxob3Vycz98aHJzP3xofGRheXM/fGR8eWVhcnM/fHlycz98eSk/JC9pLmV4ZWMoc3RyKTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuO1xuICB2YXIgbiA9IHBhcnNlRmxvYXQobWF0Y2hbMV0pO1xuICB2YXIgdHlwZSA9IChtYXRjaFsyXSB8fCAnbXMnKS50b0xvd2VyQ2FzZSgpO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICd5ZWFycyc6XG4gICAgY2FzZSAneWVhcic6XG4gICAgY2FzZSAneXJzJzpcbiAgICBjYXNlICd5cic6XG4gICAgY2FzZSAneSc6XG4gICAgICByZXR1cm4gbiAqIHk7XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZDtcbiAgICBjYXNlICdob3Vycyc6XG4gICAgY2FzZSAnaG91cic6XG4gICAgY2FzZSAnaHJzJzpcbiAgICBjYXNlICdocic6XG4gICAgY2FzZSAnaCc6XG4gICAgICByZXR1cm4gbiAqIGg7XG4gICAgY2FzZSAnbWludXRlcyc6XG4gICAgY2FzZSAnbWludXRlJzpcbiAgICBjYXNlICdtaW5zJzpcbiAgICBjYXNlICdtaW4nOlxuICAgIGNhc2UgJ20nOlxuICAgICAgcmV0dXJuIG4gKiBtO1xuICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgY2FzZSAnc2Vjcyc6XG4gICAgY2FzZSAnc2VjJzpcbiAgICBjYXNlICdzJzpcbiAgICAgIHJldHVybiBuICogcztcbiAgICBjYXNlICdtaWxsaXNlY29uZHMnOlxuICAgIGNhc2UgJ21pbGxpc2Vjb25kJzpcbiAgICBjYXNlICdtc2Vjcyc6XG4gICAgY2FzZSAnbXNlYyc6XG4gICAgY2FzZSAnbXMnOlxuICAgICAgcmV0dXJuIG47XG4gIH1cbn1cblxuLyoqXG4gKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzaG9ydChtcykge1xuICBpZiAobXMgPj0gZCkgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArICdkJztcbiAgaWYgKG1zID49IGgpIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gaCkgKyAnaCc7XG4gIGlmIChtcyA+PSBtKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIG0pICsgJ20nO1xuICBpZiAobXMgPj0gcykgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArICdzJztcbiAgcmV0dXJuIG1zICsgJ21zJztcbn1cblxuLyoqXG4gKiBMb25nIGZvcm1hdCBmb3IgYG1zYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbXNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvbmcobXMpIHtcbiAgcmV0dXJuIHBsdXJhbChtcywgZCwgJ2RheScpXG4gICAgfHwgcGx1cmFsKG1zLCBoLCAnaG91cicpXG4gICAgfHwgcGx1cmFsKG1zLCBtLCAnbWludXRlJylcbiAgICB8fCBwbHVyYWwobXMsIHMsICdzZWNvbmQnKVxuICAgIHx8IG1zICsgJyBtcyc7XG59XG5cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi9cblxuZnVuY3Rpb24gcGx1cmFsKG1zLCBuLCBuYW1lKSB7XG4gIGlmIChtcyA8IG4pIHJldHVybjtcbiAgaWYgKG1zIDwgbiAqIDEuNSkgcmV0dXJuIE1hdGguZmxvb3IobXMgLyBuKSArICcgJyArIG5hbWU7XG4gIHJldHVybiBNYXRoLmNlaWwobXMgLyBuKSArICcgJyArIG5hbWUgKyAncyc7XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1ed2\n")},"23b1":function(module,exports,__webpack_require__){eval("\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = debug.debug = debug;\nexports.coerce = coerce;\nexports.disable = disable;\nexports.enable = enable;\nexports.enabled = enabled;\nexports.humanize = __webpack_require__(/*! ms */ \"0b10\");\n\n/**\n * The currently active debug mode names, and names to skip.\n */\n\nexports.names = [];\nexports.skips = [];\n\n/**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lowercased letter, i.e. \"n\".\n */\n\nexports.formatters = {};\n\n/**\n * Previously assigned color.\n */\n\nvar prevColor = 0;\n\n/**\n * Previous log timestamp.\n */\n\nvar prevTime;\n\n/**\n * Select a color.\n *\n * @return {Number}\n * @api private\n */\n\nfunction selectColor() {\n  return exports.colors[prevColor++ % exports.colors.length];\n}\n\n/**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\nfunction debug(namespace) {\n\n  // define the `disabled` version\n  function disabled() {\n  }\n  disabled.enabled = false;\n\n  // define the `enabled` version\n  function enabled() {\n\n    var self = enabled;\n\n    // set `diff` timestamp\n    var curr = +new Date();\n    var ms = curr - (prevTime || curr);\n    self.diff = ms;\n    self.prev = prevTime;\n    self.curr = curr;\n    prevTime = curr;\n\n    // add the `color` if not set\n    if (null == self.useColors) self.useColors = exports.useColors();\n    if (null == self.color && self.useColors) self.color = selectColor();\n\n    var args = new Array(arguments.length);\n    for (var i = 0; i < args.length; i++) {\n      args[i] = arguments[i];\n    }\n\n    args[0] = exports.coerce(args[0]);\n\n    if ('string' !== typeof args[0]) {\n      // anything else let's inspect with %o\n      args = ['%o'].concat(args);\n    }\n\n    // apply any `formatters` transformations\n    var index = 0;\n    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {\n      // if we encounter an escaped % then don't increase the array index\n      if (match === '%%') return match;\n      index++;\n      var formatter = exports.formatters[format];\n      if ('function' === typeof formatter) {\n        var val = args[index];\n        match = formatter.call(self, val);\n\n        // now we need to remove `args[index]` since it's inlined in the `format`\n        args.splice(index, 1);\n        index--;\n      }\n      return match;\n    });\n\n    // apply env-specific formatting\n    args = exports.formatArgs.apply(self, args);\n\n    var logFn = enabled.log || exports.log || console.log.bind(console);\n    logFn.apply(self, args);\n  }\n  enabled.enabled = true;\n\n  var fn = exports.enabled(namespace) ? enabled : disabled;\n\n  fn.namespace = namespace;\n\n  return fn;\n}\n\n/**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\nfunction enable(namespaces) {\n  exports.save(namespaces);\n\n  var split = (namespaces || '').split(/[\\s,]+/);\n  var len = split.length;\n\n  for (var i = 0; i < len; i++) {\n    if (!split[i]) continue; // ignore empty strings\n    namespaces = split[i].replace(/[\\\\^$+?.()|[\\]{}]/g, '\\\\$&').replace(/\\*/g, '.*?');\n    if (namespaces[0] === '-') {\n      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n    } else {\n      exports.names.push(new RegExp('^' + namespaces + '$'));\n    }\n  }\n}\n\n/**\n * Disable debug output.\n *\n * @api public\n */\n\nfunction disable() {\n  exports.enable('');\n}\n\n/**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\nfunction enabled(name) {\n  var i, len;\n  for (i = 0, len = exports.skips.length; i < len; i++) {\n    if (exports.skips[i].test(name)) {\n      return false;\n    }\n  }\n  for (i = 0, len = exports.names.length; i < len; i++) {\n    if (exports.names[i].test(name)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\nfunction coerce(val) {\n  if (val instanceof Error) return val.stack || val.message;\n  return val;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjNiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZGVidWcvZGVidWcuanM/NjMxMiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogVGhpcyBpcyB0aGUgY29tbW9uIGxvZ2ljIGZvciBib3RoIHRoZSBOb2RlLmpzIGFuZCB3ZWIgYnJvd3NlclxuICogaW1wbGVtZW50YXRpb25zIG9mIGBkZWJ1ZygpYC5cbiAqXG4gKiBFeHBvc2UgYGRlYnVnKClgIGFzIHRoZSBtb2R1bGUuXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZGVidWcuZGVidWcgPSBkZWJ1ZztcbmV4cG9ydHMuY29lcmNlID0gY29lcmNlO1xuZXhwb3J0cy5kaXNhYmxlID0gZGlzYWJsZTtcbmV4cG9ydHMuZW5hYmxlID0gZW5hYmxlO1xuZXhwb3J0cy5lbmFibGVkID0gZW5hYmxlZDtcbmV4cG9ydHMuaHVtYW5pemUgPSByZXF1aXJlKCdtcycpO1xuXG4vKipcbiAqIFRoZSBjdXJyZW50bHkgYWN0aXZlIGRlYnVnIG1vZGUgbmFtZXMsIGFuZCBuYW1lcyB0byBza2lwLlxuICovXG5cbmV4cG9ydHMubmFtZXMgPSBbXTtcbmV4cG9ydHMuc2tpcHMgPSBbXTtcblxuLyoqXG4gKiBNYXAgb2Ygc3BlY2lhbCBcIiVuXCIgaGFuZGxpbmcgZnVuY3Rpb25zLCBmb3IgdGhlIGRlYnVnIFwiZm9ybWF0XCIgYXJndW1lbnQuXG4gKlxuICogVmFsaWQga2V5IG5hbWVzIGFyZSBhIHNpbmdsZSwgbG93ZXJjYXNlZCBsZXR0ZXIsIGkuZS4gXCJuXCIuXG4gKi9cblxuZXhwb3J0cy5mb3JtYXR0ZXJzID0ge307XG5cbi8qKlxuICogUHJldmlvdXNseSBhc3NpZ25lZCBjb2xvci5cbiAqL1xuXG52YXIgcHJldkNvbG9yID0gMDtcblxuLyoqXG4gKiBQcmV2aW91cyBsb2cgdGltZXN0YW1wLlxuICovXG5cbnZhciBwcmV2VGltZTtcblxuLyoqXG4gKiBTZWxlY3QgYSBjb2xvci5cbiAqXG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzZWxlY3RDb2xvcigpIHtcbiAgcmV0dXJuIGV4cG9ydHMuY29sb3JzW3ByZXZDb2xvcisrICUgZXhwb3J0cy5jb2xvcnMubGVuZ3RoXTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBkZWJ1Z2dlciB3aXRoIHRoZSBnaXZlbiBgbmFtZXNwYWNlYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZGVidWcobmFtZXNwYWNlKSB7XG5cbiAgLy8gZGVmaW5lIHRoZSBgZGlzYWJsZWRgIHZlcnNpb25cbiAgZnVuY3Rpb24gZGlzYWJsZWQoKSB7XG4gIH1cbiAgZGlzYWJsZWQuZW5hYmxlZCA9IGZhbHNlO1xuXG4gIC8vIGRlZmluZSB0aGUgYGVuYWJsZWRgIHZlcnNpb25cbiAgZnVuY3Rpb24gZW5hYmxlZCgpIHtcblxuICAgIHZhciBzZWxmID0gZW5hYmxlZDtcblxuICAgIC8vIHNldCBgZGlmZmAgdGltZXN0YW1wXG4gICAgdmFyIGN1cnIgPSArbmV3IERhdGUoKTtcbiAgICB2YXIgbXMgPSBjdXJyIC0gKHByZXZUaW1lIHx8IGN1cnIpO1xuICAgIHNlbGYuZGlmZiA9IG1zO1xuICAgIHNlbGYucHJldiA9IHByZXZUaW1lO1xuICAgIHNlbGYuY3VyciA9IGN1cnI7XG4gICAgcHJldlRpbWUgPSBjdXJyO1xuXG4gICAgLy8gYWRkIHRoZSBgY29sb3JgIGlmIG5vdCBzZXRcbiAgICBpZiAobnVsbCA9PSBzZWxmLnVzZUNvbG9ycykgc2VsZi51c2VDb2xvcnMgPSBleHBvcnRzLnVzZUNvbG9ycygpO1xuICAgIGlmIChudWxsID09IHNlbGYuY29sb3IgJiYgc2VsZi51c2VDb2xvcnMpIHNlbGYuY29sb3IgPSBzZWxlY3RDb2xvcigpO1xuXG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgIH1cblxuICAgIGFyZ3NbMF0gPSBleHBvcnRzLmNvZXJjZShhcmdzWzBdKTtcblxuICAgIGlmICgnc3RyaW5nJyAhPT0gdHlwZW9mIGFyZ3NbMF0pIHtcbiAgICAgIC8vIGFueXRoaW5nIGVsc2UgbGV0J3MgaW5zcGVjdCB3aXRoICVvXG4gICAgICBhcmdzID0gWyclbyddLmNvbmNhdChhcmdzKTtcbiAgICB9XG5cbiAgICAvLyBhcHBseSBhbnkgYGZvcm1hdHRlcnNgIHRyYW5zZm9ybWF0aW9uc1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgYXJnc1swXSA9IGFyZ3NbMF0ucmVwbGFjZSgvJShbYS16JV0pL2csIGZ1bmN0aW9uKG1hdGNoLCBmb3JtYXQpIHtcbiAgICAgIC8vIGlmIHdlIGVuY291bnRlciBhbiBlc2NhcGVkICUgdGhlbiBkb24ndCBpbmNyZWFzZSB0aGUgYXJyYXkgaW5kZXhcbiAgICAgIGlmIChtYXRjaCA9PT0gJyUlJykgcmV0dXJuIG1hdGNoO1xuICAgICAgaW5kZXgrKztcbiAgICAgIHZhciBmb3JtYXR0ZXIgPSBleHBvcnRzLmZvcm1hdHRlcnNbZm9ybWF0XTtcbiAgICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgZm9ybWF0dGVyKSB7XG4gICAgICAgIHZhciB2YWwgPSBhcmdzW2luZGV4XTtcbiAgICAgICAgbWF0Y2ggPSBmb3JtYXR0ZXIuY2FsbChzZWxmLCB2YWwpO1xuXG4gICAgICAgIC8vIG5vdyB3ZSBuZWVkIHRvIHJlbW92ZSBgYXJnc1tpbmRleF1gIHNpbmNlIGl0J3MgaW5saW5lZCBpbiB0aGUgYGZvcm1hdGBcbiAgICAgICAgYXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBpbmRleC0tO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH0pO1xuXG4gICAgLy8gYXBwbHkgZW52LXNwZWNpZmljIGZvcm1hdHRpbmdcbiAgICBhcmdzID0gZXhwb3J0cy5mb3JtYXRBcmdzLmFwcGx5KHNlbGYsIGFyZ3MpO1xuXG4gICAgdmFyIGxvZ0ZuID0gZW5hYmxlZC5sb2cgfHwgZXhwb3J0cy5sb2cgfHwgY29uc29sZS5sb2cuYmluZChjb25zb2xlKTtcbiAgICBsb2dGbi5hcHBseShzZWxmLCBhcmdzKTtcbiAgfVxuICBlbmFibGVkLmVuYWJsZWQgPSB0cnVlO1xuXG4gIHZhciBmbiA9IGV4cG9ydHMuZW5hYmxlZChuYW1lc3BhY2UpID8gZW5hYmxlZCA6IGRpc2FibGVkO1xuXG4gIGZuLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTtcblxuICByZXR1cm4gZm47XG59XG5cbi8qKlxuICogRW5hYmxlcyBhIGRlYnVnIG1vZGUgYnkgbmFtZXNwYWNlcy4gVGhpcyBjYW4gaW5jbHVkZSBtb2Rlc1xuICogc2VwYXJhdGVkIGJ5IGEgY29sb24gYW5kIHdpbGRjYXJkcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGUobmFtZXNwYWNlcykge1xuICBleHBvcnRzLnNhdmUobmFtZXNwYWNlcyk7XG5cbiAgdmFyIHNwbGl0ID0gKG5hbWVzcGFjZXMgfHwgJycpLnNwbGl0KC9bXFxzLF0rLyk7XG4gIHZhciBsZW4gPSBzcGxpdC5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGlmICghc3BsaXRbaV0pIGNvbnRpbnVlOyAvLyBpZ25vcmUgZW1wdHkgc3RyaW5nc1xuICAgIG5hbWVzcGFjZXMgPSBzcGxpdFtpXS5yZXBsYWNlKC9bXFxcXF4kKz8uKCl8W1xcXXt9XS9nLCAnXFxcXCQmJykucmVwbGFjZSgvXFwqL2csICcuKj8nKTtcbiAgICBpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG4gICAgICBleHBvcnRzLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzLnN1YnN0cigxKSArICckJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzICsgJyQnKSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGlzYWJsZSBkZWJ1ZyBvdXRwdXQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkaXNhYmxlKCkge1xuICBleHBvcnRzLmVuYWJsZSgnJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RlIG5hbWUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGVkKG5hbWUpIHtcbiAgdmFyIGksIGxlbjtcbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLnNraXBzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5uYW1lcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLm5hbWVzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29lcmNlIGB2YWxgLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjb2VyY2UodmFsKSB7XG4gIGlmICh2YWwgaW5zdGFuY2VvZiBFcnJvcikgcmV0dXJuIHZhbC5zdGFjayB8fCB2YWwubWVzc2FnZTtcbiAgcmV0dXJuIHZhbDtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///23b1\n")},"2dce":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {\n/**\n * Module requirements.\n */\n\nvar Polling = __webpack_require__(/*! ./polling */ \"181d\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = JSONPPolling;\n\n/**\n * Cached regular expressions.\n */\n\nvar rNewline = /\\n/g;\nvar rEscapedNewline = /\\\\n/g;\n\n/**\n * Global JSONP callbacks.\n */\n\nvar callbacks;\n\n/**\n * Noop.\n */\n\nfunction empty () { }\n\n/**\n * JSONP Polling constructor.\n *\n * @param {Object} opts.\n * @api public\n */\n\nfunction JSONPPolling (opts) {\n  Polling.call(this, opts);\n\n  this.query = this.query || {};\n\n  // define global callbacks array if not present\n  // we do this here (lazily) to avoid unneeded global pollution\n  if (!callbacks) {\n    // we need to consider multiple engines in the same page\n    if (!global.___eio) global.___eio = [];\n    callbacks = global.___eio;\n  }\n\n  // callback identifier\n  this.index = callbacks.length;\n\n  // add callback to jsonp global\n  var self = this;\n  callbacks.push(function (msg) {\n    self.onData(msg);\n  });\n\n  // append to query string\n  this.query.j = this.index;\n\n  // prevent spurious errors from being emitted when the window is unloaded\n  if (global.document && global.addEventListener) {\n    global.addEventListener('beforeunload', function () {\n      if (self.script) self.script.onerror = empty;\n    }, false);\n  }\n}\n\n/**\n * Inherits from Polling.\n */\n\ninherit(JSONPPolling, Polling);\n\n/*\n * JSONP only supports binary as base64 encoded strings\n */\n\nJSONPPolling.prototype.supportsBinary = false;\n\n/**\n * Closes the socket.\n *\n * @api private\n */\n\nJSONPPolling.prototype.doClose = function () {\n  if (this.script) {\n    this.script.parentNode.removeChild(this.script);\n    this.script = null;\n  }\n\n  if (this.form) {\n    this.form.parentNode.removeChild(this.form);\n    this.form = null;\n    this.iframe = null;\n  }\n\n  Polling.prototype.doClose.call(this);\n};\n\n/**\n * Starts a poll cycle.\n *\n * @api private\n */\n\nJSONPPolling.prototype.doPoll = function () {\n  var self = this;\n  var script = document.createElement('script');\n\n  if (this.script) {\n    this.script.parentNode.removeChild(this.script);\n    this.script = null;\n  }\n\n  script.async = true;\n  script.src = this.uri();\n  script.onerror = function (e) {\n    self.onError('jsonp poll error', e);\n  };\n\n  var insertAt = document.getElementsByTagName('script')[0];\n  if (insertAt) {\n    insertAt.parentNode.insertBefore(script, insertAt);\n  } else {\n    (document.head || document.body).appendChild(script);\n  }\n  this.script = script;\n\n  var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent);\n\n  if (isUAgecko) {\n    setTimeout(function () {\n      var iframe = document.createElement('iframe');\n      document.body.appendChild(iframe);\n      document.body.removeChild(iframe);\n    }, 100);\n  }\n};\n\n/**\n * Writes with a hidden iframe.\n *\n * @param {String} data to send\n * @param {Function} called upon flush.\n * @api private\n */\n\nJSONPPolling.prototype.doWrite = function (data, fn) {\n  var self = this;\n\n  if (!this.form) {\n    var form = document.createElement('form');\n    var area = document.createElement('textarea');\n    var id = this.iframeId = 'eio_iframe_' + this.index;\n    var iframe;\n\n    form.className = 'socketio';\n    form.style.position = 'absolute';\n    form.style.top = '-1000px';\n    form.style.left = '-1000px';\n    form.target = id;\n    form.method = 'POST';\n    form.setAttribute('accept-charset', 'utf-8');\n    area.name = 'd';\n    form.appendChild(area);\n    document.body.appendChild(form);\n\n    this.form = form;\n    this.area = area;\n  }\n\n  this.form.action = this.uri();\n\n  function complete () {\n    initIframe();\n    fn();\n  }\n\n  function initIframe () {\n    if (self.iframe) {\n      try {\n        self.form.removeChild(self.iframe);\n      } catch (e) {\n        self.onError('jsonp polling iframe removal error', e);\n      }\n    }\n\n    try {\n      // ie6 dynamic iframes with target=\"\" support (thanks Chris Lambacher)\n      var html = '<iframe src=\"javascript:0\" name=\"' + self.iframeId + '\">';\n      iframe = document.createElement(html);\n    } catch (e) {\n      iframe = document.createElement('iframe');\n      iframe.name = self.iframeId;\n      iframe.src = 'javascript:0';\n    }\n\n    iframe.id = self.iframeId;\n\n    self.form.appendChild(iframe);\n    self.iframe = iframe;\n  }\n\n  initIframe();\n\n  // escape \\n to prevent it from being converted into \\r\\n by some UAs\n  // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side\n  data = data.replace(rEscapedNewline, '\\\\\\n');\n  this.area.value = data.replace(rNewline, '\\\\n');\n\n  try {\n    this.form.submit();\n  } catch (e) {}\n\n  if (this.iframe.attachEvent) {\n    this.iframe.onreadystatechange = function () {\n      if (self.iframe.readyState === 'complete') {\n        complete();\n      }\n    };\n  } else {\n    this.iframe.onload = complete;\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMmRjZS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLWpzb25wLmpzP2RmZDYiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSByZXF1aXJlbWVudHMuXG4gKi9cblxudmFyIFBvbGxpbmcgPSByZXF1aXJlKCcuL3BvbGxpbmcnKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEpTT05QUG9sbGluZztcblxuLyoqXG4gKiBDYWNoZWQgcmVndWxhciBleHByZXNzaW9ucy5cbiAqL1xuXG52YXIgck5ld2xpbmUgPSAvXFxuL2c7XG52YXIgckVzY2FwZWROZXdsaW5lID0gL1xcXFxuL2c7XG5cbi8qKlxuICogR2xvYmFsIEpTT05QIGNhbGxiYWNrcy5cbiAqL1xuXG52YXIgY2FsbGJhY2tzO1xuXG4vKipcbiAqIE5vb3AuXG4gKi9cblxuZnVuY3Rpb24gZW1wdHkgKCkgeyB9XG5cbi8qKlxuICogSlNPTlAgUG9sbGluZyBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cy5cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gSlNPTlBQb2xsaW5nIChvcHRzKSB7XG4gIFBvbGxpbmcuY2FsbCh0aGlzLCBvcHRzKTtcblxuICB0aGlzLnF1ZXJ5ID0gdGhpcy5xdWVyeSB8fCB7fTtcblxuICAvLyBkZWZpbmUgZ2xvYmFsIGNhbGxiYWNrcyBhcnJheSBpZiBub3QgcHJlc2VudFxuICAvLyB3ZSBkbyB0aGlzIGhlcmUgKGxhemlseSkgdG8gYXZvaWQgdW5uZWVkZWQgZ2xvYmFsIHBvbGx1dGlvblxuICBpZiAoIWNhbGxiYWNrcykge1xuICAgIC8vIHdlIG5lZWQgdG8gY29uc2lkZXIgbXVsdGlwbGUgZW5naW5lcyBpbiB0aGUgc2FtZSBwYWdlXG4gICAgaWYgKCFnbG9iYWwuX19fZWlvKSBnbG9iYWwuX19fZWlvID0gW107XG4gICAgY2FsbGJhY2tzID0gZ2xvYmFsLl9fX2VpbztcbiAgfVxuXG4gIC8vIGNhbGxiYWNrIGlkZW50aWZpZXJcbiAgdGhpcy5pbmRleCA9IGNhbGxiYWNrcy5sZW5ndGg7XG5cbiAgLy8gYWRkIGNhbGxiYWNrIHRvIGpzb25wIGdsb2JhbFxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGNhbGxiYWNrcy5wdXNoKGZ1bmN0aW9uIChtc2cpIHtcbiAgICBzZWxmLm9uRGF0YShtc2cpO1xuICB9KTtcblxuICAvLyBhcHBlbmQgdG8gcXVlcnkgc3RyaW5nXG4gIHRoaXMucXVlcnkuaiA9IHRoaXMuaW5kZXg7XG5cbiAgLy8gcHJldmVudCBzcHVyaW91cyBlcnJvcnMgZnJvbSBiZWluZyBlbWl0dGVkIHdoZW4gdGhlIHdpbmRvdyBpcyB1bmxvYWRlZFxuICBpZiAoZ2xvYmFsLmRvY3VtZW50ICYmIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2JlZm9yZXVubG9hZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLnNjcmlwdCkgc2VsZi5zY3JpcHQub25lcnJvciA9IGVtcHR5O1xuICAgIH0sIGZhbHNlKTtcbiAgfVxufVxuXG4vKipcbiAqIEluaGVyaXRzIGZyb20gUG9sbGluZy5cbiAqL1xuXG5pbmhlcml0KEpTT05QUG9sbGluZywgUG9sbGluZyk7XG5cbi8qXG4gKiBKU09OUCBvbmx5IHN1cHBvcnRzIGJpbmFyeSBhcyBiYXNlNjQgZW5jb2RlZCBzdHJpbmdzXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuXG4vKipcbiAqIENsb3NlcyB0aGUgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkpTT05QUG9sbGluZy5wcm90b3R5cGUuZG9DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuc2NyaXB0KSB7XG4gICAgdGhpcy5zY3JpcHQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnNjcmlwdCk7XG4gICAgdGhpcy5zY3JpcHQgPSBudWxsO1xuICB9XG5cbiAgaWYgKHRoaXMuZm9ybSkge1xuICAgIHRoaXMuZm9ybS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuZm9ybSk7XG4gICAgdGhpcy5mb3JtID0gbnVsbDtcbiAgICB0aGlzLmlmcmFtZSA9IG51bGw7XG4gIH1cblxuICBQb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlLmNhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5kb1BvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gIGlmICh0aGlzLnNjcmlwdCkge1xuICAgIHRoaXMuc2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5zY3JpcHQpO1xuICAgIHRoaXMuc2NyaXB0ID0gbnVsbDtcbiAgfVxuXG4gIHNjcmlwdC5hc3luYyA9IHRydWU7XG4gIHNjcmlwdC5zcmMgPSB0aGlzLnVyaSgpO1xuICBzY3JpcHQub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsIGVycm9yJywgZSk7XG4gIH07XG5cbiAgdmFyIGluc2VydEF0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NjcmlwdCcpWzBdO1xuICBpZiAoaW5zZXJ0QXQpIHtcbiAgICBpbnNlcnRBdC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHQsIGluc2VydEF0KTtcbiAgfSBlbHNlIHtcbiAgICAoZG9jdW1lbnQuaGVhZCB8fCBkb2N1bWVudC5ib2R5KS5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICB9XG4gIHRoaXMuc2NyaXB0ID0gc2NyaXB0O1xuXG4gIHZhciBpc1VBZ2Vja28gPSAndW5kZWZpbmVkJyAhPT0gdHlwZW9mIG5hdmlnYXRvciAmJiAvZ2Vja28vaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG4gIGlmIChpc1VBZ2Vja28pIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgICB9LCAxMDApO1xuICB9XG59O1xuXG4vKipcbiAqIFdyaXRlcyB3aXRoIGEgaGlkZGVuIGlmcmFtZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSB0byBzZW5kXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkpTT05QUG9sbGluZy5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uIChkYXRhLCBmbikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKCF0aGlzLmZvcm0pIHtcbiAgICB2YXIgZm9ybSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2Zvcm0nKTtcbiAgICB2YXIgYXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgdmFyIGlkID0gdGhpcy5pZnJhbWVJZCA9ICdlaW9faWZyYW1lXycgKyB0aGlzLmluZGV4O1xuICAgIHZhciBpZnJhbWU7XG5cbiAgICBmb3JtLmNsYXNzTmFtZSA9ICdzb2NrZXRpbyc7XG4gICAgZm9ybS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgZm9ybS5zdHlsZS50b3AgPSAnLTEwMDBweCc7XG4gICAgZm9ybS5zdHlsZS5sZWZ0ID0gJy0xMDAwcHgnO1xuICAgIGZvcm0udGFyZ2V0ID0gaWQ7XG4gICAgZm9ybS5tZXRob2QgPSAnUE9TVCc7XG4gICAgZm9ybS5zZXRBdHRyaWJ1dGUoJ2FjY2VwdC1jaGFyc2V0JywgJ3V0Zi04Jyk7XG4gICAgYXJlYS5uYW1lID0gJ2QnO1xuICAgIGZvcm0uYXBwZW5kQ2hpbGQoYXJlYSk7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmb3JtKTtcblxuICAgIHRoaXMuZm9ybSA9IGZvcm07XG4gICAgdGhpcy5hcmVhID0gYXJlYTtcbiAgfVxuXG4gIHRoaXMuZm9ybS5hY3Rpb24gPSB0aGlzLnVyaSgpO1xuXG4gIGZ1bmN0aW9uIGNvbXBsZXRlICgpIHtcbiAgICBpbml0SWZyYW1lKCk7XG4gICAgZm4oKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRJZnJhbWUgKCkge1xuICAgIGlmIChzZWxmLmlmcmFtZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2VsZi5mb3JtLnJlbW92ZUNoaWxkKHNlbGYuaWZyYW1lKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsaW5nIGlmcmFtZSByZW1vdmFsIGVycm9yJywgZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIGllNiBkeW5hbWljIGlmcmFtZXMgd2l0aCB0YXJnZXQ9XCJcIiBzdXBwb3J0ICh0aGFua3MgQ2hyaXMgTGFtYmFjaGVyKVxuICAgICAgdmFyIGh0bWwgPSAnPGlmcmFtZSBzcmM9XCJqYXZhc2NyaXB0OjBcIiBuYW1lPVwiJyArIHNlbGYuaWZyYW1lSWQgKyAnXCI+JztcbiAgICAgIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaHRtbCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgICBpZnJhbWUubmFtZSA9IHNlbGYuaWZyYW1lSWQ7XG4gICAgICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6MCc7XG4gICAgfVxuXG4gICAgaWZyYW1lLmlkID0gc2VsZi5pZnJhbWVJZDtcblxuICAgIHNlbGYuZm9ybS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICAgIHNlbGYuaWZyYW1lID0gaWZyYW1lO1xuICB9XG5cbiAgaW5pdElmcmFtZSgpO1xuXG4gIC8vIGVzY2FwZSBcXG4gdG8gcHJldmVudCBpdCBmcm9tIGJlaW5nIGNvbnZlcnRlZCBpbnRvIFxcclxcbiBieSBzb21lIFVBc1xuICAvLyBkb3VibGUgZXNjYXBpbmcgaXMgcmVxdWlyZWQgZm9yIGVzY2FwZWQgbmV3IGxpbmVzIGJlY2F1c2UgdW5lc2NhcGluZyBvZiBuZXcgbGluZXMgY2FuIGJlIGRvbmUgc2FmZWx5IG9uIHNlcnZlci1zaWRlXG4gIGRhdGEgPSBkYXRhLnJlcGxhY2UockVzY2FwZWROZXdsaW5lLCAnXFxcXFxcbicpO1xuICB0aGlzLmFyZWEudmFsdWUgPSBkYXRhLnJlcGxhY2Uock5ld2xpbmUsICdcXFxcbicpO1xuXG4gIHRyeSB7XG4gICAgdGhpcy5mb3JtLnN1Ym1pdCgpO1xuICB9IGNhdGNoIChlKSB7fVxuXG4gIGlmICh0aGlzLmlmcmFtZS5hdHRhY2hFdmVudCkge1xuICAgIHRoaXMuaWZyYW1lLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLmlmcmFtZS5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnKSB7XG4gICAgICAgIGNvbXBsZXRlKCk7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmlmcmFtZS5vbmxvYWQgPSBjb21wbGV0ZTtcbiAgfVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2dce\n")},3902:function(module,exports,__webpack_require__){eval("/**\n * Base class\n *\n * Implements unique ID per instance. It is set once, and can not be updated.\n * An ID is generated during initialization; however it is included in the (de-)serializing of the object.\n * @class Base\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\n// see discussion here: https://gist.github.com/gordonbrander/2230317\nfunction uniqueID () {\n  function chr4 () {\n    return Math.random().toString(16).slice(-4);\n  }\n  return chr4() + chr4() +\n    '-' + chr4() +\n    '-' + chr4() +\n    '-' + chr4() +\n    '-' + chr4() + chr4() + chr4();\n}\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Unique ID for this class\n     * @memberof! Base\n     * @readonly\n     * @type {ID}\n     */\n    id: {\n      type: 'string',\n      default: function () {\n        return uniqueID();\n      },\n      setonce: true\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkwMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9iYXNlLmpzP2NlYTgiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCYXNlIGNsYXNzXG4gKlxuICogSW1wbGVtZW50cyB1bmlxdWUgSUQgcGVyIGluc3RhbmNlLiBJdCBpcyBzZXQgb25jZSwgYW5kIGNhbiBub3QgYmUgdXBkYXRlZC5cbiAqIEFuIElEIGlzIGdlbmVyYXRlZCBkdXJpbmcgaW5pdGlhbGl6YXRpb247IGhvd2V2ZXIgaXQgaXMgaW5jbHVkZWQgaW4gdGhlIChkZS0pc2VyaWFsaXppbmcgb2YgdGhlIG9iamVjdC5cbiAqIEBjbGFzcyBCYXNlXG4gKi9cbnZhciBBbXBlcnNhbmRNb2RlbCA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1tb2RlbCcpO1xuXG4vLyBzZWUgZGlzY3Vzc2lvbiBoZXJlOiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9nb3Jkb25icmFuZGVyLzIyMzAzMTdcbmZ1bmN0aW9uIHVuaXF1ZUlEICgpIHtcbiAgZnVuY3Rpb24gY2hyNCAoKSB7XG4gICAgcmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMTYpLnNsaWNlKC00KTtcbiAgfVxuICByZXR1cm4gY2hyNCgpICsgY2hyNCgpICtcbiAgICAnLScgKyBjaHI0KCkgK1xuICAgICctJyArIGNocjQoKSArXG4gICAgJy0nICsgY2hyNCgpICtcbiAgICAnLScgKyBjaHI0KCkgKyBjaHI0KCkgKyBjaHI0KCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBVbmlxdWUgSUQgZm9yIHRoaXMgY2xhc3NcbiAgICAgKiBAbWVtYmVyb2YhIEJhc2VcbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKiBAdHlwZSB7SUR9XG4gICAgICovXG4gICAgaWQ6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdW5pcXVlSUQoKTtcbiAgICAgIH0sXG4gICAgICBzZXRvbmNlOiB0cnVlXG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3902\n")},"3b07":function(module,exports,__webpack_require__){eval("/**\n * Main spot object.\n *\n * @class Spot\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\nvar Datasets = __webpack_require__(/*! ./dataset/collection */ \"544d\");\nvar driverClient = __webpack_require__(/*! ./driver/client */ \"720c\");\nvar driverServer = __webpack_require__(/*! ./driver/server */ \"072d\");\nvar utildx = __webpack_require__(/*! ./util/crossfilter */ \"adfa\");\nvar timeUtil = __webpack_require__(/*! ./util/time */ \"d45b\");\nvar io = __webpack_require__(/*! socket.io-client */ \"b452\");\n\n/**\n * Connect to the spot-server using a websocket and setup callbacks\n *\n * @function\n * @param {address} Optional. IP address and port number to connect to. fi.  'http://localhost:3000'\n *\n * @memberof! Spot\n */\nfunction connectToServer (address) {\n  var me = this;\n  var socket;\n\n  if (address) {\n    // connect to specified address\n    // necessary for when window.location is not availble (node.js)\n    socket = io.connect(address);\n  } else {\n    // Use socket.io fallback to autodetect address\n    // ie. when a website wants to connect, use the window.location\n    socket = io.connect();\n  }\n\n  socket.on('connect', function () {\n    me.isConnected = true;\n    console.log('Connected to server');\n  });\n\n  socket.on('disconnect', function () {\n    me.isConnected = false;\n  });\n\n  socket.on('syncDatasets', function (req) {\n    // do an incremental update, as we typically start without datasets\n    me.datasets.add(req.data, { merge: true });\n  });\n\n  socket.on('syncDataview', function (req) {\n    me.dataview.reset(req.data);\n  });\n\n  socket.on('syncFacets', function (req) {\n    // do an incremental update, as we typically update only a few properties of a facet\n    // Also, a full reset will orphan the view.model objects in spot-app (ie. crashes)\n    var dataset = me.datasets.get(req.datasetId);\n    dataset.facets.add(req.data, { merge: true });\n\n    me.resetDataview(); // NOTE: the cached (serialized) datasets need to be updated, too\n\n    dataset.trigger('syncFacets');\n  });\n\n  socket.on('newData', function (req) {\n    var filter = me.dataview.filters.get(req.filterId);\n    if (req.data) {\n      filter.data = req.data;\n\n      // for text filters, rebuild partition and count\n      filter.partitions.forEach(function (partition, p) {\n        var columnToName = {1: 'a', 2: 'b', 3: 'c', 4: 'd'};\n\n        if (partition.isText) {\n          partition.groups.reset(null, {silent: true});\n          filter.data.forEach(function (d) {\n            var count = (parseFloat(d.aa) || parseInt(d.count)) || 0;\n\n            if (count) {\n              partition.groups.add({\n                min: 0,\n                max: 100,\n                count: count,\n                label: d[columnToName[(p + 1)]],\n                value: d[columnToName[(p + 1)]]\n              }, {silent: true});\n            }\n          });\n          partition.groups.sort();\n        }\n      });\n      filter.trigger('newData');\n    }\n  });\n\n  socket.on('newMetaData', function (req) {\n    me.dataview.dataTotal = parseInt(req.dataTotal);\n    me.dataview.dataSelected = parseInt(req.dataSelected);\n    console.timeEnd('Get data');\n    me.dataview.trigger('newMetaData');\n  });\n\n  socket.connect();\n  me.socket = socket;\n}\n\n/**\n * Disconnect from the spot-server\n *\n * @function\n * @memberof! Spot\n */\nfunction disconnectFromServer () {\n  this.socket.disconnect();\n}\n\n/**\n * Request a list of available datasets from the server\n *\n * Depending on the driver, this can be an asyncrhonous function.\n * It returns a Promise that resolves to the dataset collection\n *\n * @function\n * @returns {Promise}\n *\n * @memberof! Spot\n */\nfunction getDatasets () {\n  var me = this;\n\n  return new Promise(function (resolve, reject) {\n    me.socket.emit('getDatasets');\n\n    me.datasets.once('reset', function () {\n      resolve(me.datasets);\n    });\n  });\n}\n\n/**\n * Reset min, max, and categories for all facets in the dataview\n *\n * @param {Spot} me Main spot instance\n *\n * @memberof! Spot\n */\nfunction resetDataview () {\n  var toSerialize = [];\n\n  // Update list of active datasets, and serialize the datasets parts we need to send on getData requests\n  this.dataview.datasetIds = [];\n  this.datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      // BUGFIX: the list of datasetIds can get out of sync when using spot-server. Just recreate it always.\n      this.dataview.datasetIds.push(dataset.getId());\n      toSerialize.push(dataset.toJSON()); // TODO: only serialize used facets?\n    }\n  }, this);\n  this.cachedDatasets = JSON.stringify(toSerialize);\n\n  // rescan min/max values and categories for the newly added facets\n  this.dataview.facets.forEach(function (facet) {\n    var newFacet = this.dataview.facets.get(facet.name, 'name');\n\n    if (newFacet.isContinuous || newFacet.isDatetime || newFacet.isDuration) {\n      this.setFacetMinMax(facet);\n    } else if (newFacet.isCategorial) {\n      this.setFacetCategories(facet);\n    }\n  }, this);\n}\n\n/*\n * Add or remove facets from a dataset to the global (merged) dataset\n *\n * @memberof! Spot\n * @param {Spot} me Main spot instance\n * @param {Dataset} dataset Dataset set add or remove\n */\nfunction toggleDatasetFacets (me, dataset) {\n  if (dataset.isActive) {\n    // remove active facets in dataset from the global dataset...\n    dataset.facets.forEach(function (facet) {\n      if (!facet.isActive) {\n        return;\n      }\n\n      // ...but only when no other active dataset contains it\n      var facetIsUnique = true;\n      me.datasets.forEach(function (otherDataset) {\n        if (!otherDataset.isActive || otherDataset === dataset) {\n          return;\n        }\n        if (otherDataset.facets.get(facet.name, 'name')) {\n          facetIsUnique = false;\n        }\n      });\n      if (facetIsUnique) {\n        var toRemove = me.dataview.facets.get(facet.name, 'name');\n        me.dataview.facets.remove(toRemove);\n      }\n    });\n  } else if (!dataset.isActive) {\n    // copy facets\n    dataset.facets.forEach(function (facet) {\n      // do nothing if facet is not active\n      if (!facet.isActive) {\n        return;\n      }\n\n      // default options for all facet types\n      var options = {\n        name: facet.name,\n        accessor: facet.name,\n        description: facet.description,\n        type: facet.transform.transformedType,\n        units: facet.units, // TODO: transformed units?\n        isActive: true\n      };\n\n      // do not add if a similar facet already exists\n      if (!me.dataview.facets.get(facet.name, 'name')) {\n        me.dataview.facets.add(options);\n      }\n    });\n  }\n}\n\n/*\n * Add or remove data from a dataset to the global (merged) dataset\n *\n * @memberof! Spot\n * @param {Spot} me Main spot instance\n * @param {Dataset} dataset Dataset set add or remove\n */\nfunction toggleDatasetData (me, dataset) {\n  if (dataset.isActive) {\n    // if dataset is active, remove it:\n    // ...clear all crossfilter filters\n    me.dataview.filters.forEach(function (filter) {\n      // BUGFIX: when loading sessions, the dataset is not initialized properly\n      // so check for it to be sure\n      if (filter.dimension) {\n        filter.dimension.filterAll();\n      }\n    });\n\n    // ...filter all data, originating from the dataset from the dataset\n    var dimension = me.dataview.crossfilter.dimension(function (d) {\n      return d._OriginalDatasetId;\n    });\n    dimension.filter(dataset.getId());\n\n    // ...remove matching data\n    me.dataview.crossfilter.remove();\n\n    // ...restore original filters\n    dimension.filterAll();\n    dimension.dispose();\n    me.dataview.filters.forEach(function (filter) {\n      filter.updateDataFilter();\n    });\n  } else if (!dataset.isActive) {\n    // if dataset is not active, add it\n    // ...find facets to copy\n    var dataTransforms = [];\n    dataset.facets.forEach(function (facet) {\n      // do nothing if facet is not active\n      if (!facet.isActive) {\n        return;\n      }\n      dataTransforms.push({\n        key: facet.name,\n        fn: utildx.valueFn(facet)\n      });\n    });\n\n    // ...transform data\n    var data = dataset.data;\n    var transformedData = [];\n\n    data.forEach(function (datum) {\n      var transformedDatum = {};\n      dataTransforms.forEach(function (transform) {\n        transformedDatum[transform.key] = transform.fn(datum);\n      });\n      transformedDatum._OriginalDatasetId = dataset.getId();\n      transformedData.push(transformedDatum);\n    });\n\n    // ...add to merged dataset\n    me.dataview.crossfilter.add(transformedData);\n  }\n\n  // update counts\n  me.dataview.dataTotal = me.dataview.crossfilter.size();\n  me.dataview.dataSelected = me.dataview.countGroup.value();\n}\n\n/**\n * Add or remove a dataset from the dataview\n * @param {Dataset} dataset Dataset set add or remove\n *\n * @function\n * @memberof! Spot\n */\nfunction toggleDataset (dataset) {\n  if (this.sessionType === 'server') {\n    toggleDatasetFacets(this, dataset);\n  } else if (this.sessionType === 'client') {\n    // release all filters\n    this.dataview.filters.forEach(function (filter) {\n      filter.releaseDataFilter();\n    });\n\n    // manually merge the datasets\n    toggleDatasetFacets(this, dataset);\n    toggleDatasetData(this, dataset);\n  }\n\n  dataset.isActive = !dataset.isActive;\n\n  this.resetDataview();\n}\n\nfunction setFacetMinMax (facet) {\n  // This should work for all kinds of facets:\n  // numbers, durations, and datatimes all implement the relevant operations\n  var datasets = this.datasets;\n\n  var first = true;\n  datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      var subFacet = dataset.facets.get(facet.name, 'name');\n      if (first) {\n        facet.minvalAsText = subFacet.transform.transformedMinAsText;\n        facet.maxvalAsText = subFacet.transform.transformedMaxAsText;\n        first = false;\n      } else {\n        if (subFacet.minval < facet.minval) {\n          facet.minvalAsText = subFacet.transform.transformedMinAsText;\n        }\n        if (subFacet.maxval > facet.maxval) {\n          facet.maxvalAsText = subFacet.transform.transformedMaxAsText;\n        }\n      }\n    }\n  });\n}\n\nfunction setFacetCategories (facet) {\n  var datasets = this.datasets;\n\n  facet.categorialTransform.reset();\n\n  // get categories by combining the sets for the separate datasets\n  datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      var subFacet = dataset.facets.get(facet.name, 'name');\n\n      if (subFacet.isCategorial) {\n        // merge rules from subFacet into those of Facet\n        subFacet.categorialTransform.rules.forEach(function (rule) {\n          var newRule = facet.categorialTransform.rules.get(rule.expression, 'expression');\n          if (newRule) {\n            newRule.count += rule.count;\n          } else {\n            facet.categorialTransform.rules.add(rule.toJSON());\n          }\n        });\n      } else if (subFacet.isDatetime) {\n        var expressions = timeUtil.timeParts.get(subFacet.datetimeTransform.transformedFormat, 'description').groups;\n        expressions.forEach(function (expression) {\n          var newRule = facet.categorialTransform.rules.get(expression, 'expression');\n          if (newRule) {\n            // no-op: category exist and we don't have a proper count\n          } else {\n            facet.categorialTransform.rules.add({\n              expression: expression,\n              count: 0,\n              group: expression\n            });\n          }\n        });\n      }\n    }\n  });\n}\n\nmodule.exports = BaseModel.extend({\n  type: 'user',\n  props: {\n    /**\n     * Is there a connection with a spot sever?\n     * @memberof! Spot\n     * @type {boolean}\n     */\n    isConnected: ['boolean', true, false],\n    /**\n     * When the app in locked down, facets and datasets cannot be edited\n     * @memberof! Spot\n     * @type {boolean}\n     */\n    isLockedDown: ['boolean', true, false],\n    /**\n     * Type of spot session. Must be 'client' or 'server'\n     * @memberof! Spot\n     * @type {string}\n     */\n    sessionType: {\n      type: 'string',\n      required: true,\n      default: 'client',\n      values: ['client', 'server'],\n      setOnce: true\n    }\n  },\n  children: {\n    /**\n     * A union of all active datasets\n     * @memberof! Spot\n     * @type {Dataview}\n     */\n    dataview: Dataview\n  },\n  collections: {\n    /**\n     * Collection of all datasets\n     * @memberof! Spot\n     * @type {Dataset[]}\n     */\n    datasets: Datasets\n  },\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    // default to client side (crossfilter) sessions\n    this.driver = driverClient;\n\n    // assign backend driver\n    if (arguments && arguments[0] && arguments[0].sessionType) {\n      if (arguments[0].sessionType === 'client') {\n        this.driver = driverClient;\n      } else if (arguments[0].sessionType === 'server') {\n        this.driver = driverServer;\n      } else {\n        console.error('No driver for type', arguments[0].sessionType);\n      }\n    }\n  },\n  resetDataview: resetDataview,\n  connectToServer: connectToServer,\n  disconnectFromServer: disconnectFromServer,\n  getDatasets: getDatasets,\n  setFacetMinMax: setFacetMinMax,\n  setFacetCategories: setFacetCategories,\n  toggleDataset: toggleDataset\n});\n\nmodule.exports.util = {\n  dx: utildx,\n  misval: __webpack_require__(/*! ./util/misval */ \"bff6\"),\n  time: timeUtil\n};\n\nmodule.exports.transforms = {\n  categorial: __webpack_require__(/*! ./facet/categorial-transform */ \"9b75\"),\n  continuous: __webpack_require__(/*! ./facet/continuous-transform */ \"5a80\"),\n  datetime: __webpack_require__(/*! ./facet/datetime-transform */ \"a0ca\"),\n  duration: __webpack_require__(/*! ./facet/duration-transform */ \"b123\")\n};\n\nmodule.exports.constructors = {\n  Dataview: Dataview,\n  Dataset: __webpack_require__(/*! ./dataset */ \"545a\"),\n  Datasets: Datasets\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiM2IwNy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvbWUuanM/Y2NmYSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1haW4gc3BvdCBvYmplY3QuXG4gKlxuICogQGNsYXNzIFNwb3RcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG52YXIgRGF0YXZpZXcgPSByZXF1aXJlKCcuL2RhdGF2aWV3Jyk7XG52YXIgRGF0YXNldHMgPSByZXF1aXJlKCcuL2RhdGFzZXQvY29sbGVjdGlvbicpO1xudmFyIGRyaXZlckNsaWVudCA9IHJlcXVpcmUoJy4vZHJpdmVyL2NsaWVudCcpO1xudmFyIGRyaXZlclNlcnZlciA9IHJlcXVpcmUoJy4vZHJpdmVyL3NlcnZlcicpO1xudmFyIHV0aWxkeCA9IHJlcXVpcmUoJy4vdXRpbC9jcm9zc2ZpbHRlcicpO1xudmFyIHRpbWVVdGlsID0gcmVxdWlyZSgnLi91dGlsL3RpbWUnKTtcbnZhciBpbyA9IHJlcXVpcmUoJ3NvY2tldC5pby1jbGllbnQnKTtcblxuLyoqXG4gKiBDb25uZWN0IHRvIHRoZSBzcG90LXNlcnZlciB1c2luZyBhIHdlYnNvY2tldCBhbmQgc2V0dXAgY2FsbGJhY2tzXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge2FkZHJlc3N9IE9wdGlvbmFsLiBJUCBhZGRyZXNzIGFuZCBwb3J0IG51bWJlciB0byBjb25uZWN0IHRvLiBmaS4gICdodHRwOi8vbG9jYWxob3N0OjMwMDAnXG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIGNvbm5lY3RUb1NlcnZlciAoYWRkcmVzcykge1xuICB2YXIgbWUgPSB0aGlzO1xuICB2YXIgc29ja2V0O1xuXG4gIGlmIChhZGRyZXNzKSB7XG4gICAgLy8gY29ubmVjdCB0byBzcGVjaWZpZWQgYWRkcmVzc1xuICAgIC8vIG5lY2Vzc2FyeSBmb3Igd2hlbiB3aW5kb3cubG9jYXRpb24gaXMgbm90IGF2YWlsYmxlIChub2RlLmpzKVxuICAgIHNvY2tldCA9IGlvLmNvbm5lY3QoYWRkcmVzcyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gVXNlIHNvY2tldC5pbyBmYWxsYmFjayB0byBhdXRvZGV0ZWN0IGFkZHJlc3NcbiAgICAvLyBpZS4gd2hlbiBhIHdlYnNpdGUgd2FudHMgdG8gY29ubmVjdCwgdXNlIHRoZSB3aW5kb3cubG9jYXRpb25cbiAgICBzb2NrZXQgPSBpby5jb25uZWN0KCk7XG4gIH1cblxuICBzb2NrZXQub24oJ2Nvbm5lY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgbWUuaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgIGNvbnNvbGUubG9nKCdDb25uZWN0ZWQgdG8gc2VydmVyJyk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignZGlzY29ubmVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBtZS5pc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICB9KTtcblxuICBzb2NrZXQub24oJ3N5bmNEYXRhc2V0cycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAvLyBkbyBhbiBpbmNyZW1lbnRhbCB1cGRhdGUsIGFzIHdlIHR5cGljYWxseSBzdGFydCB3aXRob3V0IGRhdGFzZXRzXG4gICAgbWUuZGF0YXNldHMuYWRkKHJlcS5kYXRhLCB7IG1lcmdlOiB0cnVlIH0pO1xuICB9KTtcblxuICBzb2NrZXQub24oJ3N5bmNEYXRhdmlldycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICBtZS5kYXRhdmlldy5yZXNldChyZXEuZGF0YSk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignc3luY0ZhY2V0cycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAvLyBkbyBhbiBpbmNyZW1lbnRhbCB1cGRhdGUsIGFzIHdlIHR5cGljYWxseSB1cGRhdGUgb25seSBhIGZldyBwcm9wZXJ0aWVzIG9mIGEgZmFjZXRcbiAgICAvLyBBbHNvLCBhIGZ1bGwgcmVzZXQgd2lsbCBvcnBoYW4gdGhlIHZpZXcubW9kZWwgb2JqZWN0cyBpbiBzcG90LWFwcCAoaWUuIGNyYXNoZXMpXG4gICAgdmFyIGRhdGFzZXQgPSBtZS5kYXRhc2V0cy5nZXQocmVxLmRhdGFzZXRJZCk7XG4gICAgZGF0YXNldC5mYWNldHMuYWRkKHJlcS5kYXRhLCB7IG1lcmdlOiB0cnVlIH0pO1xuXG4gICAgbWUucmVzZXREYXRhdmlldygpOyAvLyBOT1RFOiB0aGUgY2FjaGVkIChzZXJpYWxpemVkKSBkYXRhc2V0cyBuZWVkIHRvIGJlIHVwZGF0ZWQsIHRvb1xuXG4gICAgZGF0YXNldC50cmlnZ2VyKCdzeW5jRmFjZXRzJyk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignbmV3RGF0YScsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICB2YXIgZmlsdGVyID0gbWUuZGF0YXZpZXcuZmlsdGVycy5nZXQocmVxLmZpbHRlcklkKTtcbiAgICBpZiAocmVxLmRhdGEpIHtcbiAgICAgIGZpbHRlci5kYXRhID0gcmVxLmRhdGE7XG5cbiAgICAgIC8vIGZvciB0ZXh0IGZpbHRlcnMsIHJlYnVpbGQgcGFydGl0aW9uIGFuZCBjb3VudFxuICAgICAgZmlsdGVyLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uLCBwKSB7XG4gICAgICAgIHZhciBjb2x1bW5Ub05hbWUgPSB7MTogJ2EnLCAyOiAnYicsIDM6ICdjJywgNDogJ2QnfTtcblxuICAgICAgICBpZiAocGFydGl0aW9uLmlzVGV4dCkge1xuICAgICAgICAgIHBhcnRpdGlvbi5ncm91cHMucmVzZXQobnVsbCwge3NpbGVudDogdHJ1ZX0pO1xuICAgICAgICAgIGZpbHRlci5kYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHZhciBjb3VudCA9IChwYXJzZUZsb2F0KGQuYWEpIHx8IHBhcnNlSW50KGQuY291bnQpKSB8fCAwO1xuXG4gICAgICAgICAgICBpZiAoY291bnQpIHtcbiAgICAgICAgICAgICAgcGFydGl0aW9uLmdyb3Vwcy5hZGQoe1xuICAgICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgICBtYXg6IDEwMCxcbiAgICAgICAgICAgICAgICBjb3VudDogY291bnQsXG4gICAgICAgICAgICAgICAgbGFiZWw6IGRbY29sdW1uVG9OYW1lWyhwICsgMSldXSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogZFtjb2x1bW5Ub05hbWVbKHAgKyAxKV1dXG4gICAgICAgICAgICAgIH0sIHtzaWxlbnQ6IHRydWV9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwYXJ0aXRpb24uZ3JvdXBzLnNvcnQoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBmaWx0ZXIudHJpZ2dlcignbmV3RGF0YScpO1xuICAgIH1cbiAgfSk7XG5cbiAgc29ja2V0Lm9uKCduZXdNZXRhRGF0YScsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICBtZS5kYXRhdmlldy5kYXRhVG90YWwgPSBwYXJzZUludChyZXEuZGF0YVRvdGFsKTtcbiAgICBtZS5kYXRhdmlldy5kYXRhU2VsZWN0ZWQgPSBwYXJzZUludChyZXEuZGF0YVNlbGVjdGVkKTtcbiAgICBjb25zb2xlLnRpbWVFbmQoJ0dldCBkYXRhJyk7XG4gICAgbWUuZGF0YXZpZXcudHJpZ2dlcignbmV3TWV0YURhdGEnKTtcbiAgfSk7XG5cbiAgc29ja2V0LmNvbm5lY3QoKTtcbiAgbWUuc29ja2V0ID0gc29ja2V0O1xufVxuXG4vKipcbiAqIERpc2Nvbm5lY3QgZnJvbSB0aGUgc3BvdC1zZXJ2ZXJcbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiEgU3BvdFxuICovXG5mdW5jdGlvbiBkaXNjb25uZWN0RnJvbVNlcnZlciAoKSB7XG4gIHRoaXMuc29ja2V0LmRpc2Nvbm5lY3QoKTtcbn1cblxuLyoqXG4gKiBSZXF1ZXN0IGEgbGlzdCBvZiBhdmFpbGFibGUgZGF0YXNldHMgZnJvbSB0aGUgc2VydmVyXG4gKlxuICogRGVwZW5kaW5nIG9uIHRoZSBkcml2ZXIsIHRoaXMgY2FuIGJlIGFuIGFzeW5jcmhvbm91cyBmdW5jdGlvbi5cbiAqIEl0IHJldHVybnMgYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGRhdGFzZXQgY29sbGVjdGlvblxuICpcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2V9XG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIGdldERhdGFzZXRzICgpIHtcbiAgdmFyIG1lID0gdGhpcztcblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIG1lLnNvY2tldC5lbWl0KCdnZXREYXRhc2V0cycpO1xuXG4gICAgbWUuZGF0YXNldHMub25jZSgncmVzZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXNvbHZlKG1lLmRhdGFzZXRzKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmVzZXQgbWluLCBtYXgsIGFuZCBjYXRlZ29yaWVzIGZvciBhbGwgZmFjZXRzIGluIHRoZSBkYXRhdmlld1xuICpcbiAqIEBwYXJhbSB7U3BvdH0gbWUgTWFpbiBzcG90IGluc3RhbmNlXG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIHJlc2V0RGF0YXZpZXcgKCkge1xuICB2YXIgdG9TZXJpYWxpemUgPSBbXTtcblxuICAvLyBVcGRhdGUgbGlzdCBvZiBhY3RpdmUgZGF0YXNldHMsIGFuZCBzZXJpYWxpemUgdGhlIGRhdGFzZXRzIHBhcnRzIHdlIG5lZWQgdG8gc2VuZCBvbiBnZXREYXRhIHJlcXVlc3RzXG4gIHRoaXMuZGF0YXZpZXcuZGF0YXNldElkcyA9IFtdO1xuICB0aGlzLmRhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24gKGRhdGFzZXQpIHtcbiAgICBpZiAoZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgICAgLy8gQlVHRklYOiB0aGUgbGlzdCBvZiBkYXRhc2V0SWRzIGNhbiBnZXQgb3V0IG9mIHN5bmMgd2hlbiB1c2luZyBzcG90LXNlcnZlci4gSnVzdCByZWNyZWF0ZSBpdCBhbHdheXMuXG4gICAgICB0aGlzLmRhdGF2aWV3LmRhdGFzZXRJZHMucHVzaChkYXRhc2V0LmdldElkKCkpO1xuICAgICAgdG9TZXJpYWxpemUucHVzaChkYXRhc2V0LnRvSlNPTigpKTsgLy8gVE9ETzogb25seSBzZXJpYWxpemUgdXNlZCBmYWNldHM/XG4gICAgfVxuICB9LCB0aGlzKTtcbiAgdGhpcy5jYWNoZWREYXRhc2V0cyA9IEpTT04uc3RyaW5naWZ5KHRvU2VyaWFsaXplKTtcblxuICAvLyByZXNjYW4gbWluL21heCB2YWx1ZXMgYW5kIGNhdGVnb3JpZXMgZm9yIHRoZSBuZXdseSBhZGRlZCBmYWNldHNcbiAgdGhpcy5kYXRhdmlldy5mYWNldHMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICB2YXIgbmV3RmFjZXQgPSB0aGlzLmRhdGF2aWV3LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcblxuICAgIGlmIChuZXdGYWNldC5pc0NvbnRpbnVvdXMgfHwgbmV3RmFjZXQuaXNEYXRldGltZSB8fCBuZXdGYWNldC5pc0R1cmF0aW9uKSB7XG4gICAgICB0aGlzLnNldEZhY2V0TWluTWF4KGZhY2V0KTtcbiAgICB9IGVsc2UgaWYgKG5ld0ZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgdGhpcy5zZXRGYWNldENhdGVnb3JpZXMoZmFjZXQpO1xuICAgIH1cbiAgfSwgdGhpcyk7XG59XG5cbi8qXG4gKiBBZGQgb3IgcmVtb3ZlIGZhY2V0cyBmcm9tIGEgZGF0YXNldCB0byB0aGUgZ2xvYmFsIChtZXJnZWQpIGRhdGFzZXRcbiAqXG4gKiBAbWVtYmVyb2YhIFNwb3RcbiAqIEBwYXJhbSB7U3BvdH0gbWUgTWFpbiBzcG90IGluc3RhbmNlXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXQgRGF0YXNldCBzZXQgYWRkIG9yIHJlbW92ZVxuICovXG5mdW5jdGlvbiB0b2dnbGVEYXRhc2V0RmFjZXRzIChtZSwgZGF0YXNldCkge1xuICBpZiAoZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIHJlbW92ZSBhY3RpdmUgZmFjZXRzIGluIGRhdGFzZXQgZnJvbSB0aGUgZ2xvYmFsIGRhdGFzZXQuLi5cbiAgICBkYXRhc2V0LmZhY2V0cy5mb3JFYWNoKGZ1bmN0aW9uIChmYWNldCkge1xuICAgICAgaWYgKCFmYWNldC5pc0FjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIC4uLmJ1dCBvbmx5IHdoZW4gbm8gb3RoZXIgYWN0aXZlIGRhdGFzZXQgY29udGFpbnMgaXRcbiAgICAgIHZhciBmYWNldElzVW5pcXVlID0gdHJ1ZTtcbiAgICAgIG1lLmRhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24gKG90aGVyRGF0YXNldCkge1xuICAgICAgICBpZiAoIW90aGVyRGF0YXNldC5pc0FjdGl2ZSB8fCBvdGhlckRhdGFzZXQgPT09IGRhdGFzZXQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG90aGVyRGF0YXNldC5mYWNldHMuZ2V0KGZhY2V0Lm5hbWUsICduYW1lJykpIHtcbiAgICAgICAgICBmYWNldElzVW5pcXVlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKGZhY2V0SXNVbmlxdWUpIHtcbiAgICAgICAgdmFyIHRvUmVtb3ZlID0gbWUuZGF0YXZpZXcuZmFjZXRzLmdldChmYWNldC5uYW1lLCAnbmFtZScpO1xuICAgICAgICBtZS5kYXRhdmlldy5mYWNldHMucmVtb3ZlKHRvUmVtb3ZlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIGlmICghZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIGNvcHkgZmFjZXRzXG4gICAgZGF0YXNldC5mYWNldHMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICAgIC8vIGRvIG5vdGhpbmcgaWYgZmFjZXQgaXMgbm90IGFjdGl2ZVxuICAgICAgaWYgKCFmYWNldC5pc0FjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGRlZmF1bHQgb3B0aW9ucyBmb3IgYWxsIGZhY2V0IHR5cGVzXG4gICAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgbmFtZTogZmFjZXQubmFtZSxcbiAgICAgICAgYWNjZXNzb3I6IGZhY2V0Lm5hbWUsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBmYWNldC5kZXNjcmlwdGlvbixcbiAgICAgICAgdHlwZTogZmFjZXQudHJhbnNmb3JtLnRyYW5zZm9ybWVkVHlwZSxcbiAgICAgICAgdW5pdHM6IGZhY2V0LnVuaXRzLCAvLyBUT0RPOiB0cmFuc2Zvcm1lZCB1bml0cz9cbiAgICAgICAgaXNBY3RpdmU6IHRydWVcbiAgICAgIH07XG5cbiAgICAgIC8vIGRvIG5vdCBhZGQgaWYgYSBzaW1pbGFyIGZhY2V0IGFscmVhZHkgZXhpc3RzXG4gICAgICBpZiAoIW1lLmRhdGF2aWV3LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKSkge1xuICAgICAgICBtZS5kYXRhdmlldy5mYWNldHMuYWRkKG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbi8qXG4gKiBBZGQgb3IgcmVtb3ZlIGRhdGEgZnJvbSBhIGRhdGFzZXQgdG8gdGhlIGdsb2JhbCAobWVyZ2VkKSBkYXRhc2V0XG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKiBAcGFyYW0ge1Nwb3R9IG1lIE1haW4gc3BvdCBpbnN0YW5jZVxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0IERhdGFzZXQgc2V0IGFkZCBvciByZW1vdmVcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlRGF0YXNldERhdGEgKG1lLCBkYXRhc2V0KSB7XG4gIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgLy8gaWYgZGF0YXNldCBpcyBhY3RpdmUsIHJlbW92ZSBpdDpcbiAgICAvLyAuLi5jbGVhciBhbGwgY3Jvc3NmaWx0ZXIgZmlsdGVyc1xuICAgIG1lLmRhdGF2aWV3LmZpbHRlcnMuZm9yRWFjaChmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgICAvLyBCVUdGSVg6IHdoZW4gbG9hZGluZyBzZXNzaW9ucywgdGhlIGRhdGFzZXQgaXMgbm90IGluaXRpYWxpemVkIHByb3Blcmx5XG4gICAgICAvLyBzbyBjaGVjayBmb3IgaXQgdG8gYmUgc3VyZVxuICAgICAgaWYgKGZpbHRlci5kaW1lbnNpb24pIHtcbiAgICAgICAgZmlsdGVyLmRpbWVuc2lvbi5maWx0ZXJBbGwoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIC4uLmZpbHRlciBhbGwgZGF0YSwgb3JpZ2luYXRpbmcgZnJvbSB0aGUgZGF0YXNldCBmcm9tIHRoZSBkYXRhc2V0XG4gICAgdmFyIGRpbWVuc2lvbiA9IG1lLmRhdGF2aWV3LmNyb3NzZmlsdGVyLmRpbWVuc2lvbihmdW5jdGlvbiAoZCkge1xuICAgICAgcmV0dXJuIGQuX09yaWdpbmFsRGF0YXNldElkO1xuICAgIH0pO1xuICAgIGRpbWVuc2lvbi5maWx0ZXIoZGF0YXNldC5nZXRJZCgpKTtcblxuICAgIC8vIC4uLnJlbW92ZSBtYXRjaGluZyBkYXRhXG4gICAgbWUuZGF0YXZpZXcuY3Jvc3NmaWx0ZXIucmVtb3ZlKCk7XG5cbiAgICAvLyAuLi5yZXN0b3JlIG9yaWdpbmFsIGZpbHRlcnNcbiAgICBkaW1lbnNpb24uZmlsdGVyQWxsKCk7XG4gICAgZGltZW5zaW9uLmRpc3Bvc2UoKTtcbiAgICBtZS5kYXRhdmlldy5maWx0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpbHRlcikge1xuICAgICAgZmlsdGVyLnVwZGF0ZURhdGFGaWx0ZXIoKTtcbiAgICB9KTtcbiAgfSBlbHNlIGlmICghZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIGlmIGRhdGFzZXQgaXMgbm90IGFjdGl2ZSwgYWRkIGl0XG4gICAgLy8gLi4uZmluZCBmYWNldHMgdG8gY29weVxuICAgIHZhciBkYXRhVHJhbnNmb3JtcyA9IFtdO1xuICAgIGRhdGFzZXQuZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgICAvLyBkbyBub3RoaW5nIGlmIGZhY2V0IGlzIG5vdCBhY3RpdmVcbiAgICAgIGlmICghZmFjZXQuaXNBY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZGF0YVRyYW5zZm9ybXMucHVzaCh7XG4gICAgICAgIGtleTogZmFjZXQubmFtZSxcbiAgICAgICAgZm46IHV0aWxkeC52YWx1ZUZuKGZhY2V0KVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyAuLi50cmFuc2Zvcm0gZGF0YVxuICAgIHZhciBkYXRhID0gZGF0YXNldC5kYXRhO1xuICAgIHZhciB0cmFuc2Zvcm1lZERhdGEgPSBbXTtcblxuICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZGF0dW0pIHtcbiAgICAgIHZhciB0cmFuc2Zvcm1lZERhdHVtID0ge307XG4gICAgICBkYXRhVHJhbnNmb3Jtcy5mb3JFYWNoKGZ1bmN0aW9uICh0cmFuc2Zvcm0pIHtcbiAgICAgICAgdHJhbnNmb3JtZWREYXR1bVt0cmFuc2Zvcm0ua2V5XSA9IHRyYW5zZm9ybS5mbihkYXR1bSk7XG4gICAgICB9KTtcbiAgICAgIHRyYW5zZm9ybWVkRGF0dW0uX09yaWdpbmFsRGF0YXNldElkID0gZGF0YXNldC5nZXRJZCgpO1xuICAgICAgdHJhbnNmb3JtZWREYXRhLnB1c2godHJhbnNmb3JtZWREYXR1bSk7XG4gICAgfSk7XG5cbiAgICAvLyAuLi5hZGQgdG8gbWVyZ2VkIGRhdGFzZXRcbiAgICBtZS5kYXRhdmlldy5jcm9zc2ZpbHRlci5hZGQodHJhbnNmb3JtZWREYXRhKTtcbiAgfVxuXG4gIC8vIHVwZGF0ZSBjb3VudHNcbiAgbWUuZGF0YXZpZXcuZGF0YVRvdGFsID0gbWUuZGF0YXZpZXcuY3Jvc3NmaWx0ZXIuc2l6ZSgpO1xuICBtZS5kYXRhdmlldy5kYXRhU2VsZWN0ZWQgPSBtZS5kYXRhdmlldy5jb3VudEdyb3VwLnZhbHVlKCk7XG59XG5cbi8qKlxuICogQWRkIG9yIHJlbW92ZSBhIGRhdGFzZXQgZnJvbSB0aGUgZGF0YXZpZXdcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldCBEYXRhc2V0IHNldCBhZGQgb3IgcmVtb3ZlXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2YhIFNwb3RcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlRGF0YXNldCAoZGF0YXNldCkge1xuICBpZiAodGhpcy5zZXNzaW9uVHlwZSA9PT0gJ3NlcnZlcicpIHtcbiAgICB0b2dnbGVEYXRhc2V0RmFjZXRzKHRoaXMsIGRhdGFzZXQpO1xuICB9IGVsc2UgaWYgKHRoaXMuc2Vzc2lvblR5cGUgPT09ICdjbGllbnQnKSB7XG4gICAgLy8gcmVsZWFzZSBhbGwgZmlsdGVyc1xuICAgIHRoaXMuZGF0YXZpZXcuZmlsdGVycy5mb3JFYWNoKGZ1bmN0aW9uIChmaWx0ZXIpIHtcbiAgICAgIGZpbHRlci5yZWxlYXNlRGF0YUZpbHRlcigpO1xuICAgIH0pO1xuXG4gICAgLy8gbWFudWFsbHkgbWVyZ2UgdGhlIGRhdGFzZXRzXG4gICAgdG9nZ2xlRGF0YXNldEZhY2V0cyh0aGlzLCBkYXRhc2V0KTtcbiAgICB0b2dnbGVEYXRhc2V0RGF0YSh0aGlzLCBkYXRhc2V0KTtcbiAgfVxuXG4gIGRhdGFzZXQuaXNBY3RpdmUgPSAhZGF0YXNldC5pc0FjdGl2ZTtcblxuICB0aGlzLnJlc2V0RGF0YXZpZXcoKTtcbn1cblxuZnVuY3Rpb24gc2V0RmFjZXRNaW5NYXggKGZhY2V0KSB7XG4gIC8vIFRoaXMgc2hvdWxkIHdvcmsgZm9yIGFsbCBraW5kcyBvZiBmYWNldHM6XG4gIC8vIG51bWJlcnMsIGR1cmF0aW9ucywgYW5kIGRhdGF0aW1lcyBhbGwgaW1wbGVtZW50IHRoZSByZWxldmFudCBvcGVyYXRpb25zXG4gIHZhciBkYXRhc2V0cyA9IHRoaXMuZGF0YXNldHM7XG5cbiAgdmFyIGZpcnN0ID0gdHJ1ZTtcbiAgZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZGF0YXNldCkge1xuICAgIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgICB2YXIgc3ViRmFjZXQgPSBkYXRhc2V0LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcbiAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICBmYWNldC5taW52YWxBc1RleHQgPSBzdWJGYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW5Bc1RleHQ7XG4gICAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IHN1YkZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZE1heEFzVGV4dDtcbiAgICAgICAgZmlyc3QgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChzdWJGYWNldC5taW52YWwgPCBmYWNldC5taW52YWwpIHtcbiAgICAgICAgICBmYWNldC5taW52YWxBc1RleHQgPSBzdWJGYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW5Bc1RleHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN1YkZhY2V0Lm1heHZhbCA+IGZhY2V0Lm1heHZhbCkge1xuICAgICAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IHN1YkZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZE1heEFzVGV4dDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHNldEZhY2V0Q2F0ZWdvcmllcyAoZmFjZXQpIHtcbiAgdmFyIGRhdGFzZXRzID0gdGhpcy5kYXRhc2V0cztcblxuICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJlc2V0KCk7XG5cbiAgLy8gZ2V0IGNhdGVnb3JpZXMgYnkgY29tYmluaW5nIHRoZSBzZXRzIGZvciB0aGUgc2VwYXJhdGUgZGF0YXNldHNcbiAgZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZGF0YXNldCkge1xuICAgIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgICB2YXIgc3ViRmFjZXQgPSBkYXRhc2V0LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcblxuICAgICAgaWYgKHN1YkZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgICAvLyBtZXJnZSBydWxlcyBmcm9tIHN1YkZhY2V0IGludG8gdGhvc2Ugb2YgRmFjZXRcbiAgICAgICAgc3ViRmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChydWxlKSB7XG4gICAgICAgICAgdmFyIG5ld1J1bGUgPSBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLmdldChydWxlLmV4cHJlc3Npb24sICdleHByZXNzaW9uJyk7XG4gICAgICAgICAgaWYgKG5ld1J1bGUpIHtcbiAgICAgICAgICAgIG5ld1J1bGUuY291bnQgKz0gcnVsZS5jb3VudDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5hZGQocnVsZS50b0pTT04oKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoc3ViRmFjZXQuaXNEYXRldGltZSkge1xuICAgICAgICB2YXIgZXhwcmVzc2lvbnMgPSB0aW1lVXRpbC50aW1lUGFydHMuZ2V0KHN1YkZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKS5ncm91cHM7XG4gICAgICAgIGV4cHJlc3Npb25zLmZvckVhY2goZnVuY3Rpb24gKGV4cHJlc3Npb24pIHtcbiAgICAgICAgICB2YXIgbmV3UnVsZSA9IGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuZ2V0KGV4cHJlc3Npb24sICdleHByZXNzaW9uJyk7XG4gICAgICAgICAgaWYgKG5ld1J1bGUpIHtcbiAgICAgICAgICAgIC8vIG5vLW9wOiBjYXRlZ29yeSBleGlzdCBhbmQgd2UgZG9uJ3QgaGF2ZSBhIHByb3BlciBjb3VudFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLmFkZCh7XG4gICAgICAgICAgICAgIGV4cHJlc3Npb246IGV4cHJlc3Npb24sXG4gICAgICAgICAgICAgIGNvdW50OiAwLFxuICAgICAgICAgICAgICBncm91cDogZXhwcmVzc2lvblxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VNb2RlbC5leHRlbmQoe1xuICB0eXBlOiAndXNlcicsXG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogSXMgdGhlcmUgYSBjb25uZWN0aW9uIHdpdGggYSBzcG90IHNldmVyP1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIGlzQ29ubmVjdGVkOiBbJ2Jvb2xlYW4nLCB0cnVlLCBmYWxzZV0sXG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgYXBwIGluIGxvY2tlZCBkb3duLCBmYWNldHMgYW5kIGRhdGFzZXRzIGNhbm5vdCBiZSBlZGl0ZWRcbiAgICAgKiBAbWVtYmVyb2YhIFNwb3RcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0xvY2tlZERvd246IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXSxcbiAgICAvKipcbiAgICAgKiBUeXBlIG9mIHNwb3Qgc2Vzc2lvbi4gTXVzdCBiZSAnY2xpZW50JyBvciAnc2VydmVyJ1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgc2Vzc2lvblR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnY2xpZW50JyxcbiAgICAgIHZhbHVlczogWydjbGllbnQnLCAnc2VydmVyJ10sXG4gICAgICBzZXRPbmNlOiB0cnVlXG4gICAgfVxuICB9LFxuICBjaGlsZHJlbjoge1xuICAgIC8qKlxuICAgICAqIEEgdW5pb24gb2YgYWxsIGFjdGl2ZSBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtEYXRhdmlld31cbiAgICAgKi9cbiAgICBkYXRhdmlldzogRGF0YXZpZXdcbiAgfSxcbiAgY29sbGVjdGlvbnM6IHtcbiAgICAvKipcbiAgICAgKiBDb2xsZWN0aW9uIG9mIGFsbCBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtEYXRhc2V0W119XG4gICAgICovXG4gICAgZGF0YXNldHM6IERhdGFzZXRzXG4gIH0sXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBmaXJzdCBkbyBwYXJlbnQgY2xhc3MgaW5pdGlhbGl6YXRpb25cbiAgICBCYXNlTW9kZWwucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIC8vIGRlZmF1bHQgdG8gY2xpZW50IHNpZGUgKGNyb3NzZmlsdGVyKSBzZXNzaW9uc1xuICAgIHRoaXMuZHJpdmVyID0gZHJpdmVyQ2xpZW50O1xuXG4gICAgLy8gYXNzaWduIGJhY2tlbmQgZHJpdmVyXG4gICAgaWYgKGFyZ3VtZW50cyAmJiBhcmd1bWVudHNbMF0gJiYgYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlKSB7XG4gICAgICBpZiAoYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlID09PSAnY2xpZW50Jykge1xuICAgICAgICB0aGlzLmRyaXZlciA9IGRyaXZlckNsaWVudDtcbiAgICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlID09PSAnc2VydmVyJykge1xuICAgICAgICB0aGlzLmRyaXZlciA9IGRyaXZlclNlcnZlcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ05vIGRyaXZlciBmb3IgdHlwZScsIGFyZ3VtZW50c1swXS5zZXNzaW9uVHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICByZXNldERhdGF2aWV3OiByZXNldERhdGF2aWV3LFxuICBjb25uZWN0VG9TZXJ2ZXI6IGNvbm5lY3RUb1NlcnZlcixcbiAgZGlzY29ubmVjdEZyb21TZXJ2ZXI6IGRpc2Nvbm5lY3RGcm9tU2VydmVyLFxuICBnZXREYXRhc2V0czogZ2V0RGF0YXNldHMsXG4gIHNldEZhY2V0TWluTWF4OiBzZXRGYWNldE1pbk1heCxcbiAgc2V0RmFjZXRDYXRlZ29yaWVzOiBzZXRGYWNldENhdGVnb3JpZXMsXG4gIHRvZ2dsZURhdGFzZXQ6IHRvZ2dsZURhdGFzZXRcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cy51dGlsID0ge1xuICBkeDogdXRpbGR4LFxuICBtaXN2YWw6IHJlcXVpcmUoJy4vdXRpbC9taXN2YWwnKSxcbiAgdGltZTogdGltZVV0aWxcbn07XG5cbm1vZHVsZS5leHBvcnRzLnRyYW5zZm9ybXMgPSB7XG4gIGNhdGVnb3JpYWw6IHJlcXVpcmUoJy4vZmFjZXQvY2F0ZWdvcmlhbC10cmFuc2Zvcm0nKSxcbiAgY29udGludW91czogcmVxdWlyZSgnLi9mYWNldC9jb250aW51b3VzLXRyYW5zZm9ybScpLFxuICBkYXRldGltZTogcmVxdWlyZSgnLi9mYWNldC9kYXRldGltZS10cmFuc2Zvcm0nKSxcbiAgZHVyYXRpb246IHJlcXVpcmUoJy4vZmFjZXQvZHVyYXRpb24tdHJhbnNmb3JtJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNvbnN0cnVjdG9ycyA9IHtcbiAgRGF0YXZpZXc6IERhdGF2aWV3LFxuICBEYXRhc2V0OiByZXF1aXJlKCcuL2RhdGFzZXQnKSxcbiAgRGF0YXNldHM6IERhdGFzZXRzXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3b07\n")},"419b":function(module,exports,__webpack_require__){eval('/* WEBPACK VAR INJECTION */(function(global) {\nmodule.exports = isBuf;\n\n/**\n * Returns true if obj is a buffer or an arraybuffer.\n *\n * @api private\n */\n\nfunction isBuf(obj) {\n  return (global.Buffer && global.Buffer.isBuffer(obj)) ||\n         (global.ArrayBuffer && obj instanceof ArrayBuffer);\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ "698d")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE5Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9pcy1idWZmZXIuanM/MGJlNiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbm1vZHVsZS5leHBvcnRzID0gaXNCdWY7XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIG9iaiBpcyBhIGJ1ZmZlciBvciBhbiBhcnJheWJ1ZmZlci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0J1ZihvYmopIHtcbiAgcmV0dXJuIChnbG9iYWwuQnVmZmVyICYmIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIob2JqKSkgfHxcbiAgICAgICAgIChnbG9iYWwuQXJyYXlCdWZmZXIgJiYgb2JqIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpO1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///419b\n')},"433b":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(process) {\n/**\n * This is the web browser implementation of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = __webpack_require__(/*! ./debug */ \"23b1\");\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = 'undefined' != typeof chrome\n               && 'undefined' != typeof chrome.storage\n                  ? chrome.storage.local\n                  : localstorage();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n  'lightseagreen',\n  'forestgreen',\n  'goldenrod',\n  'dodgerblue',\n  'darkorchid',\n  'crimson'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\nfunction useColors() {\n  // is webkit? http://stackoverflow.com/a/16459606/376773\n  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n  return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) ||\n    // is firebug? http://stackoverflow.com/a/398120/376773\n    (window.console && (console.firebug || (console.exception && console.table))) ||\n    // is firefox >= v31?\n    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n    (navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31);\n}\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nexports.formatters.j = function(v) {\n  try {\n    return JSON.stringify(v);\n  } catch (err) {\n    return '[UnexpectedJSONParseError]: ' + err.message;\n  }\n};\n\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs() {\n  var args = arguments;\n  var useColors = this.useColors;\n\n  args[0] = (useColors ? '%c' : '')\n    + this.namespace\n    + (useColors ? ' %c' : ' ')\n    + args[0]\n    + (useColors ? '%c ' : ' ')\n    + '+' + exports.humanize(this.diff);\n\n  if (!useColors) return args;\n\n  var c = 'color: ' + this.color;\n  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));\n\n  // the final \"%c\" is somewhat tricky, because there could be other\n  // arguments passed either before or after the %c, so we need to\n  // figure out the correct index to insert the CSS into\n  var index = 0;\n  var lastC = 0;\n  args[0].replace(/%[a-z%]/g, function(match) {\n    if ('%%' === match) return;\n    index++;\n    if ('%c' === match) {\n      // we only are interested in the *last* %c\n      // (the user may have provided their own)\n      lastC = index;\n    }\n  });\n\n  args.splice(lastC, 0, c);\n  return args;\n}\n\n/**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\nfunction log() {\n  // this hackery is required for IE8/9, where\n  // the `console.log` function doesn't have 'apply'\n  return 'object' === typeof console\n    && console.log\n    && Function.prototype.apply.call(console.log, console, arguments);\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\nfunction save(namespaces) {\n  try {\n    if (null == namespaces) {\n      exports.storage.removeItem('debug');\n    } else {\n      exports.storage.debug = namespaces;\n    }\n  } catch(e) {}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n  var r;\n  try {\n    return exports.storage.debug;\n  } catch(e) {}\n\n  // If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n  if (typeof process !== 'undefined' && 'env' in process) {\n    return process.env.DEBUG;\n  }\n}\n\n/**\n * Enable namespaces listed in `localStorage.debug` initially.\n */\n\nexports.enable(load());\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage(){\n  try {\n    return window.localStorage;\n  } catch (e) {}\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../process/browser.js */ \"26d5\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMzYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZGVidWcvYnJvd3Nlci5qcz82NDdhIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSB3ZWIgYnJvd3NlciBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gKlxuICogRXhwb3NlIGBkZWJ1ZygpYCBhcyB0aGUgbW9kdWxlLlxuICovXG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZGVidWcnKTtcbmV4cG9ydHMubG9nID0gbG9nO1xuZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbmV4cG9ydHMuc2F2ZSA9IHNhdmU7XG5leHBvcnRzLmxvYWQgPSBsb2FkO1xuZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG5leHBvcnRzLnN0b3JhZ2UgPSAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lXG4gICAgICAgICAgICAgICAmJiAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lLnN0b3JhZ2VcbiAgICAgICAgICAgICAgICAgID8gY2hyb21lLnN0b3JhZ2UubG9jYWxcbiAgICAgICAgICAgICAgICAgIDogbG9jYWxzdG9yYWdlKCk7XG5cbi8qKlxuICogQ29sb3JzLlxuICovXG5cbmV4cG9ydHMuY29sb3JzID0gW1xuICAnbGlnaHRzZWFncmVlbicsXG4gICdmb3Jlc3RncmVlbicsXG4gICdnb2xkZW5yb2QnLFxuICAnZG9kZ2VyYmx1ZScsXG4gICdkYXJrb3JjaGlkJyxcbiAgJ2NyaW1zb24nXG5dO1xuXG4vKipcbiAqIEN1cnJlbnRseSBvbmx5IFdlYktpdC1iYXNlZCBXZWIgSW5zcGVjdG9ycywgRmlyZWZveCA+PSB2MzEsXG4gKiBhbmQgdGhlIEZpcmVidWcgZXh0ZW5zaW9uIChhbnkgRmlyZWZveCB2ZXJzaW9uKSBhcmUga25vd25cbiAqIHRvIHN1cHBvcnQgXCIlY1wiIENTUyBjdXN0b21pemF0aW9ucy5cbiAqXG4gKiBUT0RPOiBhZGQgYSBgbG9jYWxTdG9yYWdlYCB2YXJpYWJsZSB0byBleHBsaWNpdGx5IGVuYWJsZS9kaXNhYmxlIGNvbG9yc1xuICovXG5cbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcbiAgLy8gaXMgd2Via2l0PyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNjQ1OTYwNi8zNzY3NzNcbiAgLy8gZG9jdW1lbnQgaXMgdW5kZWZpbmVkIGluIHJlYWN0LW5hdGl2ZTogaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0LW5hdGl2ZS9wdWxsLzE2MzJcbiAgcmV0dXJuICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmICdXZWJraXRBcHBlYXJhbmNlJyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUpIHx8XG4gICAgLy8gaXMgZmlyZWJ1Zz8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzk4MTIwLzM3Njc3M1xuICAgICh3aW5kb3cuY29uc29sZSAmJiAoY29uc29sZS5maXJlYnVnIHx8IChjb25zb2xlLmV4Y2VwdGlvbiAmJiBjb25zb2xlLnRhYmxlKSkpIHx8XG4gICAgLy8gaXMgZmlyZWZveCA+PSB2MzE/XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9Ub29scy9XZWJfQ29uc29sZSNTdHlsaW5nX21lc3NhZ2VzXG4gICAgKG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5tYXRjaCgvZmlyZWZveFxcLyhcXGQrKS8pICYmIHBhcnNlSW50KFJlZ0V4cC4kMSwgMTApID49IDMxKTtcbn1cblxuLyoqXG4gKiBNYXAgJWogdG8gYEpTT04uc3RyaW5naWZ5KClgLCBzaW5jZSBubyBXZWIgSW5zcGVjdG9ycyBkbyB0aGF0IGJ5IGRlZmF1bHQuXG4gKi9cblxuZXhwb3J0cy5mb3JtYXR0ZXJzLmogPSBmdW5jdGlvbih2KSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHYpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gJ1tVbmV4cGVjdGVkSlNPTlBhcnNlRXJyb3JdOiAnICsgZXJyLm1lc3NhZ2U7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBDb2xvcml6ZSBsb2cgYXJndW1lbnRzIGlmIGVuYWJsZWQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBmb3JtYXRBcmdzKCkge1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIHVzZUNvbG9ycyA9IHRoaXMudXNlQ29sb3JzO1xuXG4gIGFyZ3NbMF0gPSAodXNlQ29sb3JzID8gJyVjJyA6ICcnKVxuICAgICsgdGhpcy5uYW1lc3BhY2VcbiAgICArICh1c2VDb2xvcnMgPyAnICVjJyA6ICcgJylcbiAgICArIGFyZ3NbMF1cbiAgICArICh1c2VDb2xvcnMgPyAnJWMgJyA6ICcgJylcbiAgICArICcrJyArIGV4cG9ydHMuaHVtYW5pemUodGhpcy5kaWZmKTtcblxuICBpZiAoIXVzZUNvbG9ycykgcmV0dXJuIGFyZ3M7XG5cbiAgdmFyIGMgPSAnY29sb3I6ICcgKyB0aGlzLmNvbG9yO1xuICBhcmdzID0gW2FyZ3NbMF0sIGMsICdjb2xvcjogaW5oZXJpdCddLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmdzLCAxKSk7XG5cbiAgLy8gdGhlIGZpbmFsIFwiJWNcIiBpcyBzb21ld2hhdCB0cmlja3ksIGJlY2F1c2UgdGhlcmUgY291bGQgYmUgb3RoZXJcbiAgLy8gYXJndW1lbnRzIHBhc3NlZCBlaXRoZXIgYmVmb3JlIG9yIGFmdGVyIHRoZSAlYywgc28gd2UgbmVlZCB0b1xuICAvLyBmaWd1cmUgb3V0IHRoZSBjb3JyZWN0IGluZGV4IHRvIGluc2VydCB0aGUgQ1NTIGludG9cbiAgdmFyIGluZGV4ID0gMDtcbiAgdmFyIGxhc3RDID0gMDtcbiAgYXJnc1swXS5yZXBsYWNlKC8lW2EteiVdL2csIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgaWYgKCclJScgPT09IG1hdGNoKSByZXR1cm47XG4gICAgaW5kZXgrKztcbiAgICBpZiAoJyVjJyA9PT0gbWF0Y2gpIHtcbiAgICAgIC8vIHdlIG9ubHkgYXJlIGludGVyZXN0ZWQgaW4gdGhlICpsYXN0KiAlY1xuICAgICAgLy8gKHRoZSB1c2VyIG1heSBoYXZlIHByb3ZpZGVkIHRoZWlyIG93bilcbiAgICAgIGxhc3RDID0gaW5kZXg7XG4gICAgfVxuICB9KTtcblxuICBhcmdzLnNwbGljZShsYXN0QywgMCwgYyk7XG4gIHJldHVybiBhcmdzO1xufVxuXG4vKipcbiAqIEludm9rZXMgYGNvbnNvbGUubG9nKClgIHdoZW4gYXZhaWxhYmxlLlxuICogTm8tb3Agd2hlbiBgY29uc29sZS5sb2dgIGlzIG5vdCBhIFwiZnVuY3Rpb25cIi5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGxvZygpIHtcbiAgLy8gdGhpcyBoYWNrZXJ5IGlzIHJlcXVpcmVkIGZvciBJRTgvOSwgd2hlcmVcbiAgLy8gdGhlIGBjb25zb2xlLmxvZ2AgZnVuY3Rpb24gZG9lc24ndCBoYXZlICdhcHBseSdcbiAgcmV0dXJuICdvYmplY3QnID09PSB0eXBlb2YgY29uc29sZVxuICAgICYmIGNvbnNvbGUubG9nXG4gICAgJiYgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoY29uc29sZS5sb2csIGNvbnNvbGUsIGFyZ3VtZW50cyk7XG59XG5cbi8qKlxuICogU2F2ZSBgbmFtZXNwYWNlc2AuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNhdmUobmFtZXNwYWNlcykge1xuICB0cnkge1xuICAgIGlmIChudWxsID09IG5hbWVzcGFjZXMpIHtcbiAgICAgIGV4cG9ydHMuc3RvcmFnZS5yZW1vdmVJdGVtKCdkZWJ1ZycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLnN0b3JhZ2UuZGVidWcgPSBuYW1lc3BhY2VzO1xuICAgIH1cbiAgfSBjYXRjaChlKSB7fVxufVxuXG4vKipcbiAqIExvYWQgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gcmV0dXJucyB0aGUgcHJldmlvdXNseSBwZXJzaXN0ZWQgZGVidWcgbW9kZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvYWQoKSB7XG4gIHZhciByO1xuICB0cnkge1xuICAgIHJldHVybiBleHBvcnRzLnN0b3JhZ2UuZGVidWc7XG4gIH0gY2F0Y2goZSkge31cblxuICAvLyBJZiBkZWJ1ZyBpc24ndCBzZXQgaW4gTFMsIGFuZCB3ZSdyZSBpbiBFbGVjdHJvbiwgdHJ5IHRvIGxvYWQgJERFQlVHXG4gIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ2VudicgaW4gcHJvY2Vzcykge1xuICAgIHJldHVybiBwcm9jZXNzLmVudi5ERUJVRztcbiAgfVxufVxuXG4vKipcbiAqIEVuYWJsZSBuYW1lc3BhY2VzIGxpc3RlZCBpbiBgbG9jYWxTdG9yYWdlLmRlYnVnYCBpbml0aWFsbHkuXG4gKi9cblxuZXhwb3J0cy5lbmFibGUobG9hZCgpKTtcblxuLyoqXG4gKiBMb2NhbHN0b3JhZ2UgYXR0ZW1wdHMgdG8gcmV0dXJuIHRoZSBsb2NhbHN0b3JhZ2UuXG4gKlxuICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBzYWZhcmkgdGhyb3dzXG4gKiB3aGVuIGEgdXNlciBkaXNhYmxlcyBjb29raWVzL2xvY2Fsc3RvcmFnZVxuICogYW5kIHlvdSBhdHRlbXB0IHRvIGFjY2VzcyBpdC5cbiAqXG4gKiBAcmV0dXJuIHtMb2NhbFN0b3JhZ2V9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2NhbHN0b3JhZ2UoKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZTtcbiAgfSBjYXRjaCAoZSkge31cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///433b\n")},"4c13":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar toArray = __webpack_require__(/*! to-array */ \"7de3\");\nvar on = __webpack_require__(/*! ./on */ \"faaa\");\nvar bind = __webpack_require__(/*! component-bind */ \"b6f6\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:socket');\nvar hasBin = __webpack_require__(/*! has-binary */ \"d304\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = exports = Socket;\n\n/**\n * Internal events (blacklisted).\n * These events can't be emitted by the user.\n *\n * @api private\n */\n\nvar events = {\n  connect: 1,\n  connect_error: 1,\n  connect_timeout: 1,\n  connecting: 1,\n  disconnect: 1,\n  error: 1,\n  reconnect: 1,\n  reconnect_attempt: 1,\n  reconnect_failed: 1,\n  reconnect_error: 1,\n  reconnecting: 1,\n  ping: 1,\n  pong: 1\n};\n\n/**\n * Shortcut to `Emitter#emit`.\n */\n\nvar emit = Emitter.prototype.emit;\n\n/**\n * `Socket` constructor.\n *\n * @api public\n */\n\nfunction Socket (io, nsp, opts) {\n  this.io = io;\n  this.nsp = nsp;\n  this.json = this; // compat\n  this.ids = 0;\n  this.acks = {};\n  this.receiveBuffer = [];\n  this.sendBuffer = [];\n  this.connected = false;\n  this.disconnected = true;\n  if (opts && opts.query) {\n    this.query = opts.query;\n  }\n  if (this.io.autoConnect) this.open();\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Socket.prototype);\n\n/**\n * Subscribe to open, close and packet events\n *\n * @api private\n */\n\nSocket.prototype.subEvents = function () {\n  if (this.subs) return;\n\n  var io = this.io;\n  this.subs = [\n    on(io, 'open', bind(this, 'onopen')),\n    on(io, 'packet', bind(this, 'onpacket')),\n    on(io, 'close', bind(this, 'onclose'))\n  ];\n};\n\n/**\n * \"Opens\" the socket.\n *\n * @api public\n */\n\nSocket.prototype.open =\nSocket.prototype.connect = function () {\n  if (this.connected) return this;\n\n  this.subEvents();\n  this.io.open(); // ensure open\n  if ('open' === this.io.readyState) this.onopen();\n  this.emit('connecting');\n  return this;\n};\n\n/**\n * Sends a `message` event.\n *\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.send = function () {\n  var args = toArray(arguments);\n  args.unshift('message');\n  this.emit.apply(this, args);\n  return this;\n};\n\n/**\n * Override `emit`.\n * If the event is in `events`, it's emitted normally.\n *\n * @param {String} event name\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.emit = function (ev) {\n  if (events.hasOwnProperty(ev)) {\n    emit.apply(this, arguments);\n    return this;\n  }\n\n  var args = toArray(arguments);\n  var parserType = parser.EVENT; // default\n  if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary\n  var packet = { type: parserType, data: args };\n\n  packet.options = {};\n  packet.options.compress = !this.flags || false !== this.flags.compress;\n\n  // event ack callback\n  if ('function' === typeof args[args.length - 1]) {\n    debug('emitting packet with ack id %d', this.ids);\n    this.acks[this.ids] = args.pop();\n    packet.id = this.ids++;\n  }\n\n  if (this.connected) {\n    this.packet(packet);\n  } else {\n    this.sendBuffer.push(packet);\n  }\n\n  delete this.flags;\n\n  return this;\n};\n\n/**\n * Sends a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.packet = function (packet) {\n  packet.nsp = this.nsp;\n  this.io.packet(packet);\n};\n\n/**\n * Called upon engine `open`.\n *\n * @api private\n */\n\nSocket.prototype.onopen = function () {\n  debug('transport is open - connecting');\n\n  // write connect packet if necessary\n  if ('/' !== this.nsp) {\n    if (this.query) {\n      this.packet({type: parser.CONNECT, query: this.query});\n    } else {\n      this.packet({type: parser.CONNECT});\n    }\n  }\n};\n\n/**\n * Called upon engine `close`.\n *\n * @param {String} reason\n * @api private\n */\n\nSocket.prototype.onclose = function (reason) {\n  debug('close (%s)', reason);\n  this.connected = false;\n  this.disconnected = true;\n  delete this.id;\n  this.emit('disconnect', reason);\n};\n\n/**\n * Called with socket packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onpacket = function (packet) {\n  if (packet.nsp !== this.nsp) return;\n\n  switch (packet.type) {\n    case parser.CONNECT:\n      this.onconnect();\n      break;\n\n    case parser.EVENT:\n      this.onevent(packet);\n      break;\n\n    case parser.BINARY_EVENT:\n      this.onevent(packet);\n      break;\n\n    case parser.ACK:\n      this.onack(packet);\n      break;\n\n    case parser.BINARY_ACK:\n      this.onack(packet);\n      break;\n\n    case parser.DISCONNECT:\n      this.ondisconnect();\n      break;\n\n    case parser.ERROR:\n      this.emit('error', packet.data);\n      break;\n  }\n};\n\n/**\n * Called upon a server event.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onevent = function (packet) {\n  var args = packet.data || [];\n  debug('emitting event %j', args);\n\n  if (null != packet.id) {\n    debug('attaching ack callback to event');\n    args.push(this.ack(packet.id));\n  }\n\n  if (this.connected) {\n    emit.apply(this, args);\n  } else {\n    this.receiveBuffer.push(args);\n  }\n};\n\n/**\n * Produces an ack callback to emit with an event.\n *\n * @api private\n */\n\nSocket.prototype.ack = function (id) {\n  var self = this;\n  var sent = false;\n  return function () {\n    // prevent double callbacks\n    if (sent) return;\n    sent = true;\n    var args = toArray(arguments);\n    debug('sending ack %j', args);\n\n    var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;\n    self.packet({\n      type: type,\n      id: id,\n      data: args\n    });\n  };\n};\n\n/**\n * Called upon a server acknowlegement.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onack = function (packet) {\n  var ack = this.acks[packet.id];\n  if ('function' === typeof ack) {\n    debug('calling ack %s with %j', packet.id, packet.data);\n    ack.apply(this, packet.data);\n    delete this.acks[packet.id];\n  } else {\n    debug('bad ack %s', packet.id);\n  }\n};\n\n/**\n * Called upon server connect.\n *\n * @api private\n */\n\nSocket.prototype.onconnect = function () {\n  this.connected = true;\n  this.disconnected = false;\n  this.emit('connect');\n  this.emitBuffered();\n};\n\n/**\n * Emit buffered events (received and emitted).\n *\n * @api private\n */\n\nSocket.prototype.emitBuffered = function () {\n  var i;\n  for (i = 0; i < this.receiveBuffer.length; i++) {\n    emit.apply(this, this.receiveBuffer[i]);\n  }\n  this.receiveBuffer = [];\n\n  for (i = 0; i < this.sendBuffer.length; i++) {\n    this.packet(this.sendBuffer[i]);\n  }\n  this.sendBuffer = [];\n};\n\n/**\n * Called upon server disconnect.\n *\n * @api private\n */\n\nSocket.prototype.ondisconnect = function () {\n  debug('server disconnect (%s)', this.nsp);\n  this.destroy();\n  this.onclose('io server disconnect');\n};\n\n/**\n * Called upon forced client/server side disconnections,\n * this method ensures the manager stops tracking us and\n * that reconnections don't get triggered for this.\n *\n * @api private.\n */\n\nSocket.prototype.destroy = function () {\n  if (this.subs) {\n    // clean subscriptions to avoid reconnections\n    for (var i = 0; i < this.subs.length; i++) {\n      this.subs[i].destroy();\n    }\n    this.subs = null;\n  }\n\n  this.io.destroy(this);\n};\n\n/**\n * Disconnects the socket manually.\n *\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.close =\nSocket.prototype.disconnect = function () {\n  if (this.connected) {\n    debug('performing disconnect (%s)', this.nsp);\n    this.packet({ type: parser.DISCONNECT });\n  }\n\n  // remove socket from pool\n  this.destroy();\n\n  if (this.connected) {\n    // fire events\n    this.onclose('io client disconnect');\n  }\n  return this;\n};\n\n/**\n * Sets the compress flag.\n *\n * @param {Boolean} if `true`, compresses the sending data\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.compress = function (compress) {\n  this.flags = this.flags || {};\n  this.flags.compress = compress;\n  return this;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNGMxMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvc29ja2V0LmpzPzg3ZDEiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNlciA9IHJlcXVpcmUoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciB0b0FycmF5ID0gcmVxdWlyZSgndG8tYXJyYXknKTtcbnZhciBvbiA9IHJlcXVpcmUoJy4vb24nKTtcbnZhciBiaW5kID0gcmVxdWlyZSgnY29tcG9uZW50LWJpbmQnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6c29ja2V0Jyk7XG52YXIgaGFzQmluID0gcmVxdWlyZSgnaGFzLWJpbmFyeScpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IFNvY2tldDtcblxuLyoqXG4gKiBJbnRlcm5hbCBldmVudHMgKGJsYWNrbGlzdGVkKS5cbiAqIFRoZXNlIGV2ZW50cyBjYW4ndCBiZSBlbWl0dGVkIGJ5IHRoZSB1c2VyLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbnZhciBldmVudHMgPSB7XG4gIGNvbm5lY3Q6IDEsXG4gIGNvbm5lY3RfZXJyb3I6IDEsXG4gIGNvbm5lY3RfdGltZW91dDogMSxcbiAgY29ubmVjdGluZzogMSxcbiAgZGlzY29ubmVjdDogMSxcbiAgZXJyb3I6IDEsXG4gIHJlY29ubmVjdDogMSxcbiAgcmVjb25uZWN0X2F0dGVtcHQ6IDEsXG4gIHJlY29ubmVjdF9mYWlsZWQ6IDEsXG4gIHJlY29ubmVjdF9lcnJvcjogMSxcbiAgcmVjb25uZWN0aW5nOiAxLFxuICBwaW5nOiAxLFxuICBwb25nOiAxXG59O1xuXG4vKipcbiAqIFNob3J0Y3V0IHRvIGBFbWl0dGVyI2VtaXRgLlxuICovXG5cbnZhciBlbWl0ID0gRW1pdHRlci5wcm90b3R5cGUuZW1pdDtcblxuLyoqXG4gKiBgU29ja2V0YCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFNvY2tldCAoaW8sIG5zcCwgb3B0cykge1xuICB0aGlzLmlvID0gaW87XG4gIHRoaXMubnNwID0gbnNwO1xuICB0aGlzLmpzb24gPSB0aGlzOyAvLyBjb21wYXRcbiAgdGhpcy5pZHMgPSAwO1xuICB0aGlzLmFja3MgPSB7fTtcbiAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG4gIHRoaXMuc2VuZEJ1ZmZlciA9IFtdO1xuICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICB0aGlzLmRpc2Nvbm5lY3RlZCA9IHRydWU7XG4gIGlmIChvcHRzICYmIG9wdHMucXVlcnkpIHtcbiAgICB0aGlzLnF1ZXJ5ID0gb3B0cy5xdWVyeTtcbiAgfVxuICBpZiAodGhpcy5pby5hdXRvQ29ubmVjdCkgdGhpcy5vcGVuKCk7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFNvY2tldC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIFN1YnNjcmliZSB0byBvcGVuLCBjbG9zZSBhbmQgcGFja2V0IGV2ZW50c1xuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc3ViRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zdWJzKSByZXR1cm47XG5cbiAgdmFyIGlvID0gdGhpcy5pbztcbiAgdGhpcy5zdWJzID0gW1xuICAgIG9uKGlvLCAnb3BlbicsIGJpbmQodGhpcywgJ29ub3BlbicpKSxcbiAgICBvbihpbywgJ3BhY2tldCcsIGJpbmQodGhpcywgJ29ucGFja2V0JykpLFxuICAgIG9uKGlvLCAnY2xvc2UnLCBiaW5kKHRoaXMsICdvbmNsb3NlJykpXG4gIF07XG59O1xuXG4vKipcbiAqIFwiT3BlbnNcIiB0aGUgc29ja2V0LlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vcGVuID1cblNvY2tldC5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY29ubmVjdGVkKSByZXR1cm4gdGhpcztcblxuICB0aGlzLnN1YkV2ZW50cygpO1xuICB0aGlzLmlvLm9wZW4oKTsgLy8gZW5zdXJlIG9wZW5cbiAgaWYgKCdvcGVuJyA9PT0gdGhpcy5pby5yZWFkeVN0YXRlKSB0aGlzLm9ub3BlbigpO1xuICB0aGlzLmVtaXQoJ2Nvbm5lY3RpbmcnKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIGEgYG1lc3NhZ2VgIGV2ZW50LlxuICpcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMpO1xuICBhcmdzLnVuc2hpZnQoJ21lc3NhZ2UnKTtcbiAgdGhpcy5lbWl0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgYGVtaXRgLlxuICogSWYgdGhlIGV2ZW50IGlzIGluIGBldmVudHNgLCBpdCdzIGVtaXR0ZWQgbm9ybWFsbHkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IG5hbWVcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShldikpIHtcbiAgICBlbWl0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgdmFyIHBhcnNlclR5cGUgPSBwYXJzZXIuRVZFTlQ7IC8vIGRlZmF1bHRcbiAgaWYgKGhhc0JpbihhcmdzKSkgeyBwYXJzZXJUeXBlID0gcGFyc2VyLkJJTkFSWV9FVkVOVDsgfSAvLyBiaW5hcnlcbiAgdmFyIHBhY2tldCA9IHsgdHlwZTogcGFyc2VyVHlwZSwgZGF0YTogYXJncyB9O1xuXG4gIHBhY2tldC5vcHRpb25zID0ge307XG4gIHBhY2tldC5vcHRpb25zLmNvbXByZXNzID0gIXRoaXMuZmxhZ3MgfHwgZmFsc2UgIT09IHRoaXMuZmxhZ3MuY29tcHJlc3M7XG5cbiAgLy8gZXZlbnQgYWNrIGNhbGxiYWNrXG4gIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgYXJnc1thcmdzLmxlbmd0aCAtIDFdKSB7XG4gICAgZGVidWcoJ2VtaXR0aW5nIHBhY2tldCB3aXRoIGFjayBpZCAlZCcsIHRoaXMuaWRzKTtcbiAgICB0aGlzLmFja3NbdGhpcy5pZHNdID0gYXJncy5wb3AoKTtcbiAgICBwYWNrZXQuaWQgPSB0aGlzLmlkcysrO1xuICB9XG5cbiAgaWYgKHRoaXMuY29ubmVjdGVkKSB7XG4gICAgdGhpcy5wYWNrZXQocGFja2V0KTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnNlbmRCdWZmZXIucHVzaChwYWNrZXQpO1xuICB9XG5cbiAgZGVsZXRlIHRoaXMuZmxhZ3M7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIGEgcGFja2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUucGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICBwYWNrZXQubnNwID0gdGhpcy5uc3A7XG4gIHRoaXMuaW8ucGFja2V0KHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGVuZ2luZSBgb3BlbmAuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCd0cmFuc3BvcnQgaXMgb3BlbiAtIGNvbm5lY3RpbmcnKTtcblxuICAvLyB3cml0ZSBjb25uZWN0IHBhY2tldCBpZiBuZWNlc3NhcnlcbiAgaWYgKCcvJyAhPT0gdGhpcy5uc3ApIHtcbiAgICBpZiAodGhpcy5xdWVyeSkge1xuICAgICAgdGhpcy5wYWNrZXQoe3R5cGU6IHBhcnNlci5DT05ORUNULCBxdWVyeTogdGhpcy5xdWVyeX0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBhY2tldCh7dHlwZTogcGFyc2VyLkNPTk5FQ1R9KTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZW5naW5lIGBjbG9zZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJlYXNvblxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICBkZWJ1ZygnY2xvc2UgKCVzKScsIHJlYXNvbik7XG4gIHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG4gIHRoaXMuZGlzY29ubmVjdGVkID0gdHJ1ZTtcbiAgZGVsZXRlIHRoaXMuaWQ7XG4gIHRoaXMuZW1pdCgnZGlzY29ubmVjdCcsIHJlYXNvbik7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIHNvY2tldCBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbnBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgaWYgKHBhY2tldC5uc3AgIT09IHRoaXMubnNwKSByZXR1cm47XG5cbiAgc3dpdGNoIChwYWNrZXQudHlwZSkge1xuICAgIGNhc2UgcGFyc2VyLkNPTk5FQ1Q6XG4gICAgICB0aGlzLm9uY29ubmVjdCgpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5FVkVOVDpcbiAgICAgIHRoaXMub25ldmVudChwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfRVZFTlQ6XG4gICAgICB0aGlzLm9uZXZlbnQocGFja2V0KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5ESVNDT05ORUNUOlxuICAgICAgdGhpcy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuRVJST1I6XG4gICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgcGFja2V0LmRhdGEpO1xuICAgICAgYnJlYWs7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gYSBzZXJ2ZXIgZXZlbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmV2ZW50ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICB2YXIgYXJncyA9IHBhY2tldC5kYXRhIHx8IFtdO1xuICBkZWJ1ZygnZW1pdHRpbmcgZXZlbnQgJWonLCBhcmdzKTtcblxuICBpZiAobnVsbCAhPSBwYWNrZXQuaWQpIHtcbiAgICBkZWJ1ZygnYXR0YWNoaW5nIGFjayBjYWxsYmFjayB0byBldmVudCcpO1xuICAgIGFyZ3MucHVzaCh0aGlzLmFjayhwYWNrZXQuaWQpKTtcbiAgfVxuXG4gIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgIGVtaXQuYXBwbHkodGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yZWNlaXZlQnVmZmVyLnB1c2goYXJncyk7XG4gIH1cbn07XG5cbi8qKlxuICogUHJvZHVjZXMgYW4gYWNrIGNhbGxiYWNrIHRvIGVtaXQgd2l0aCBhbiBldmVudC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmFjayA9IGZ1bmN0aW9uIChpZCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBzZW50ID0gZmFsc2U7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gcHJldmVudCBkb3VibGUgY2FsbGJhY2tzXG4gICAgaWYgKHNlbnQpIHJldHVybjtcbiAgICBzZW50ID0gdHJ1ZTtcbiAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICBkZWJ1Zygnc2VuZGluZyBhY2sgJWonLCBhcmdzKTtcblxuICAgIHZhciB0eXBlID0gaGFzQmluKGFyZ3MpID8gcGFyc2VyLkJJTkFSWV9BQ0sgOiBwYXJzZXIuQUNLO1xuICAgIHNlbGYucGFja2V0KHtcbiAgICAgIHR5cGU6IHR5cGUsXG4gICAgICBpZDogaWQsXG4gICAgICBkYXRhOiBhcmdzXG4gICAgfSk7XG4gIH07XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgc2VydmVyIGFja25vd2xlZ2VtZW50LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25hY2sgPSBmdW5jdGlvbiAocGFja2V0KSB7XG4gIHZhciBhY2sgPSB0aGlzLmFja3NbcGFja2V0LmlkXTtcbiAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBhY2spIHtcbiAgICBkZWJ1ZygnY2FsbGluZyBhY2sgJXMgd2l0aCAlaicsIHBhY2tldC5pZCwgcGFja2V0LmRhdGEpO1xuICAgIGFjay5hcHBseSh0aGlzLCBwYWNrZXQuZGF0YSk7XG4gICAgZGVsZXRlIHRoaXMuYWNrc1twYWNrZXQuaWRdO1xuICB9IGVsc2Uge1xuICAgIGRlYnVnKCdiYWQgYWNrICVzJywgcGFja2V0LmlkKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzZXJ2ZXIgY29ubmVjdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuICB0aGlzLmRpc2Nvbm5lY3RlZCA9IGZhbHNlO1xuICB0aGlzLmVtaXQoJ2Nvbm5lY3QnKTtcbiAgdGhpcy5lbWl0QnVmZmVyZWQoKTtcbn07XG5cbi8qKlxuICogRW1pdCBidWZmZXJlZCBldmVudHMgKHJlY2VpdmVkIGFuZCBlbWl0dGVkKS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmVtaXRCdWZmZXJlZCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnJlY2VpdmVCdWZmZXIubGVuZ3RoOyBpKyspIHtcbiAgICBlbWl0LmFwcGx5KHRoaXMsIHRoaXMucmVjZWl2ZUJ1ZmZlcltpXSk7XG4gIH1cbiAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMuc2VuZEJ1ZmZlci5sZW5ndGg7IGkrKykge1xuICAgIHRoaXMucGFja2V0KHRoaXMuc2VuZEJ1ZmZlcltpXSk7XG4gIH1cbiAgdGhpcy5zZW5kQnVmZmVyID0gW107XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHNlcnZlciBkaXNjb25uZWN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25kaXNjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1Zygnc2VydmVyIGRpc2Nvbm5lY3QgKCVzKScsIHRoaXMubnNwKTtcbiAgdGhpcy5kZXN0cm95KCk7XG4gIHRoaXMub25jbG9zZSgnaW8gc2VydmVyIGRpc2Nvbm5lY3QnKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZm9yY2VkIGNsaWVudC9zZXJ2ZXIgc2lkZSBkaXNjb25uZWN0aW9ucyxcbiAqIHRoaXMgbWV0aG9kIGVuc3VyZXMgdGhlIG1hbmFnZXIgc3RvcHMgdHJhY2tpbmcgdXMgYW5kXG4gKiB0aGF0IHJlY29ubmVjdGlvbnMgZG9uJ3QgZ2V0IHRyaWdnZXJlZCBmb3IgdGhpcy5cbiAqXG4gKiBAYXBpIHByaXZhdGUuXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zdWJzKSB7XG4gICAgLy8gY2xlYW4gc3Vic2NyaXB0aW9ucyB0byBhdm9pZCByZWNvbm5lY3Rpb25zXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuc3Vic1tpXS5kZXN0cm95KCk7XG4gICAgfVxuICAgIHRoaXMuc3VicyA9IG51bGw7XG4gIH1cblxuICB0aGlzLmlvLmRlc3Ryb3kodGhpcyk7XG59O1xuXG4vKipcbiAqIERpc2Nvbm5lY3RzIHRoZSBzb2NrZXQgbWFudWFsbHkuXG4gKlxuICogQHJldHVybiB7U29ja2V0fSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPVxuU29ja2V0LnByb3RvdHlwZS5kaXNjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jb25uZWN0ZWQpIHtcbiAgICBkZWJ1ZygncGVyZm9ybWluZyBkaXNjb25uZWN0ICglcyknLCB0aGlzLm5zcCk7XG4gICAgdGhpcy5wYWNrZXQoeyB0eXBlOiBwYXJzZXIuRElTQ09OTkVDVCB9KTtcbiAgfVxuXG4gIC8vIHJlbW92ZSBzb2NrZXQgZnJvbSBwb29sXG4gIHRoaXMuZGVzdHJveSgpO1xuXG4gIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgIC8vIGZpcmUgZXZlbnRzXG4gICAgdGhpcy5vbmNsb3NlKCdpbyBjbGllbnQgZGlzY29ubmVjdCcpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBjb21wcmVzcyBmbGFnLlxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaWYgYHRydWVgLCBjb21wcmVzc2VzIHRoZSBzZW5kaW5nIGRhdGFcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNvbXByZXNzID0gZnVuY3Rpb24gKGNvbXByZXNzKSB7XG4gIHRoaXMuZmxhZ3MgPSB0aGlzLmZsYWdzIHx8IHt9O1xuICB0aGlzLmZsYWdzLmNvbXByZXNzID0gY29tcHJlc3M7XG4gIHJldHVybiB0aGlzO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4c13\n")},"4d50":function(module,exports,__webpack_require__){eval("/**\n * Facets are the main abstraction over the data.\n *\n * A `Dataset` is a collection of (similar) items, with each item having a certain set of properties, ie. `Facet`s.\n * The `Facet` class defines the property: It can be a continuous value, a set of labels or tags,\n * or it can be result of some transformation or equation.\n *\n * @class Facet\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar CategorialTransform = __webpack_require__(/*! ./facet/categorial-transform */ \"9b75\");\nvar ContinuousTransform = __webpack_require__(/*! ./facet/continuous-transform */ \"5a80\");\nvar datetimeTransform = __webpack_require__(/*! ./facet/datetime-transform */ \"a0ca\");\nvar durationTransform = __webpack_require__(/*! ./facet/duration-transform */ \"b123\");\nvar textTransform = __webpack_require__(/*! ./facet/text-transform */ \"e810\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    this.on('change:type', function (facet, newval) {\n      // reset transformations on type change\n      this.continuousTransform.reset();\n      this.categorialTransform.reset();\n      this.datetimeTransform.reset();\n      this.durationTransform.reset();\n    });\n  },\n  props: {\n    /**\n     * Show in facet lists (used for interactive searching on Facets page)\n     * @memberof! Facet\n     * @type {boolean}\n     */\n    show: ['boolean', false, true],\n\n    /**\n     * Show facet bar (on Analyze page)\n     * @memberof! Facet\n     * @type {boolean}\n     */\n    isActive: ['boolean', false, false],\n\n    // general facet properties\n    /**\n     * Description of this facet, for displaying purposes\n     * @memberof! Facet\n     * @type {string}\n     */\n    description: ['string', true, ''],\n\n    /**\n     * For continuous facets, its units for displaying purposes\n     * @memberof! Facet\n     * @type {string}\n     */\n    units: ['string', true, ''],\n\n    /**\n     * Short name (human readable) for this facet, must be unique.\n     * @memberof! Facet\n     * @type {string}\n     */\n    name: ['string', true, ''],\n\n    /**\n     * Type of this facet:\n     *  * `constant`        A constant value of \"1\" for all data items\n     *  * `continuous`      The facet takes on real numbers\n     *  * `categorial`      The facet is a string, or an array of strings (for a well defined set of labels and tags)\n     *  * `datetime`        The facet is a datetime (using momentjs.tz)\n     *  * `duration`        The facet is a duration (using momentjs.duration)\n     *  * `text`            Freeform text.\n     * Check for facet type using isConstant, isContinuous, isCategorial, isDatetime, isDuration, or isText  properties.\n     * @memberof! Facet\n     * @type {string}\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['constant', 'continuous', 'categorial', 'datetime', 'duration', 'text']\n    },\n\n    /**\n     * The accessor for this facet.\n     * For nested properties use dot notation: For a dataset `[ {name: {first: \"Santa\", last: \"Claus\"}}, ...]`\n     * you can use `name.first` and `name.last` to get Santa and Claus, respectively.\n     *\n     * @memberof! Facet\n     * @type {string}\n     */\n    accessor: ['string', false, null],\n\n    /**\n     * Missing or invalid data indicator; for multiple values, use a comma separated, quoted list\n     * Numbers, strings, booleans, and the special value null are allowed.\n     * Use single or double quotes for strings \"missing\".\n     * The parsed values are available in the misval property.\n     *\n     * @memberof! Facet\n     * @type {string}\n     */\n    misvalAsText: 'string',\n\n    /**\n     * For continuous or datetime Facets, the minimum value as text.\n     * Parsed value available in the `minval` property\n     * @memberof! Facet\n     * @type {string}\n     */\n    minvalAsText: 'string',\n\n    /**\n     * For continuous or datetime Facets, the maximum value as text.\n     * Parsed value available in the `maxval` property\n     * @memberof! Facet\n     * @type {string}\n     */\n    maxvalAsText: 'string'\n  },\n  children: {\n    /**\n     * A categorial transformation to apply to the data\n     * @memberof! Facet\n     * @type {CategorialTransform}\n     */\n    categorialTransform: CategorialTransform,\n    /**\n     * A datetime transformation to apply to the data\n     * @memberof! Facet\n     * @type {dateimeTransform}\n     */\n    datetimeTransform: datetimeTransform,\n    /**\n     * A duration transformation to apply to the data\n     * @memberof! Facet\n     * @type {dateimeTransform}\n     */\n    durationTransform: durationTransform,\n    /**\n     * A continuous transformation to apply to the data\n     * @memberof! Facet\n     * @type {ContinuousTransform}\n     */\n    continuousTransform: ContinuousTransform,\n    /**\n     * A text transform\n     * @memberof! Facet\n     * @type {TextTransform}\n     */\n    textTransform: textTransform\n  },\n\n  derived: {\n    // properties for: type\n    isConstant: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'constant';\n      }\n    },\n    isContinuous: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'continuous';\n      }\n    },\n    isCategorial: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'categorial';\n      }\n    },\n    isDatetime: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'datetime';\n      }\n    },\n    isDuration: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'duration';\n      }\n    },\n    isText: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'text';\n      }\n    },\n\n    /**\n     * Array of missing data indicators\n     * @memberof! Facet\n     * @type {Object[]}\n     * @readonly\n     */\n    misval: {\n      deps: ['misvalAsText'],\n      fn: function () {\n        // Parse the text content as a JSON array:\n        //  - strings should be quoted\n        //  - numbers unquoated\n        //  - special numbers not allowed: NaN, Infinity\n        try {\n          if (this.misvalAsText !== null) {\n            return JSON.parse('[' + this.misvalAsText + ']');\n          } else {\n            return [];\n          }\n        } catch (e) {\n          return [];\n        }\n      },\n      cache: false\n    },\n\n    /**\n     * For continuous or datetime Facets, the minimum value.\n     * @memberof! Facet\n     * @type {number|datetime}\n     * @readonly\n     */\n    minval: {\n      deps: ['minvalAsText', 'type'],\n      fn: function () {\n        var min;\n        if (this.isContinuous) {\n          min = parseFloat(this.minvalAsText);\n          if (isNaN(min)) {\n            min = 0;\n          }\n        } else if (this.isDatetime) {\n          min = moment(this.minvalAsText, moment.ISO_8601);\n          if (!min.isValid()) {\n            min = moment('2010-01-01 00:00', moment.ISO_8601);\n          }\n        } else if (this.isDuration) {\n          min = moment.duration(this.minvalAsText);\n          if (!moment.isDuration(min)) {\n            min = moment.duration(1, 'seconds');\n          }\n        }\n        return min;\n      },\n      cache: false\n    },\n    /**\n     * For continuous or datetime Facets, the maximum value.\n     * @memberof! Facet\n     * @type {number|datetime}\n     * @readonly\n     */\n    maxval: {\n      deps: ['maxvalAsText', 'type'],\n      fn: function () {\n        var max;\n        if (this.isContinuous) {\n          max = parseFloat(this.maxvalAsText);\n          if (isNaN(max)) {\n            max = 100;\n          }\n        } else if (this.isDatetime) {\n          max = moment(this.maxvalAsText, moment.ISO_8601);\n          if (!max.isValid()) {\n            max = moment('2020-01-01 00:00', moment.ISO_8601);\n          }\n        } else if (this.isDuration) {\n          max = moment.duration(this.maxvalAsText);\n          if (!moment.isDuration(max)) {\n            max = moment.duration(100, 'seconds');\n          }\n        }\n        return max;\n      },\n      cache: false\n    },\n    transform: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isContinuous) {\n          return this.continuousTransform;\n        } else if (this.isCategorial) {\n          return this.categorialTransform;\n        } else if (this.isDatetime) {\n          return this.datetimeTransform;\n        } else if (this.isDuration) {\n          return this.durationTransform;\n        } else if (this.isText) {\n          return this.textTransform;\n        }\n        console.error('Invalid facet');\n      },\n      cache: false\n    }\n  },\n  /**\n   * setMinMax sets the range of a continuous or time facet\n   * For facets in a dataview, the minimum is just the minimum of the facet over all active datasets,\n   * and the same for the maximum.\n   * For facets in a datset, the actual implementation is in the dataset driver.\n   *\n   * @memberof! Facet\n   */\n  setMinMax: function () {\n    var Dataset = __webpack_require__(/*! ./dataset */ \"545a\");\n    var Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\n\n    var ancestor = this.collection.parent;\n    var spot;\n\n    if (ancestor instanceof Dataview) {\n      // Facet -> Facets -> Dataview -> Spot\n      spot = this.collection.parent.parent;\n      spot.setFacetMinMax(this);\n    } else if (ancestor instanceof Dataset) {\n      // Dataset -> Datasets -> Spot\n      spot = ancestor.collection.parent;\n      spot.driver.setMinMax(ancestor, this);\n    }\n  },\n  /**\n   * setCategories finds finds all values on an ordinal (categorial) axis\n   * Updates the categorialTransform of the facet\n   * For facets in a dataview, this is the union of the categories of facet over all active datasets.\n   * For facets in a dataset, the actual implementation is in the dataset driver.\n   *\n   * @memberof! Facet\n   */\n  setCategories: function () {\n    var Dataset = __webpack_require__(/*! ./dataset */ \"545a\");\n    var Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\n\n    var ancestor = this.collection.parent;\n    var spot;\n\n    if (ancestor instanceof Dataview) {\n      // Facet -> Facets -> Dataview -> Spot\n      spot = this.collection.parent.parent;\n      spot.setFacetCategories(this);\n    } else if (ancestor instanceof Dataset) {\n      // Facet -> Facets -> Dataset -> Datasets -> Spot\n      spot = ancestor.collection.parent;\n      spot.driver.setCategories(ancestor, this);\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNGQ1MC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQuanM/ZDdlYiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEZhY2V0cyBhcmUgdGhlIG1haW4gYWJzdHJhY3Rpb24gb3ZlciB0aGUgZGF0YS5cbiAqXG4gKiBBIGBEYXRhc2V0YCBpcyBhIGNvbGxlY3Rpb24gb2YgKHNpbWlsYXIpIGl0ZW1zLCB3aXRoIGVhY2ggaXRlbSBoYXZpbmcgYSBjZXJ0YWluIHNldCBvZiBwcm9wZXJ0aWVzLCBpZS4gYEZhY2V0YHMuXG4gKiBUaGUgYEZhY2V0YCBjbGFzcyBkZWZpbmVzIHRoZSBwcm9wZXJ0eTogSXQgY2FuIGJlIGEgY29udGludW91cyB2YWx1ZSwgYSBzZXQgb2YgbGFiZWxzIG9yIHRhZ3MsXG4gKiBvciBpdCBjYW4gYmUgcmVzdWx0IG9mIHNvbWUgdHJhbnNmb3JtYXRpb24gb3IgZXF1YXRpb24uXG4gKlxuICogQGNsYXNzIEZhY2V0XG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBCYXNlTW9kZWwgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIENhdGVnb3JpYWxUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L2NhdGVnb3JpYWwtdHJhbnNmb3JtJyk7XG52YXIgQ29udGludW91c1RyYW5zZm9ybSA9IHJlcXVpcmUoJy4vZmFjZXQvY29udGludW91cy10cmFuc2Zvcm0nKTtcbnZhciBkYXRldGltZVRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vZmFjZXQvZGF0ZXRpbWUtdHJhbnNmb3JtJyk7XG52YXIgZHVyYXRpb25UcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L2R1cmF0aW9uLXRyYW5zZm9ybScpO1xudmFyIHRleHRUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L3RleHQtdHJhbnNmb3JtJyk7XG52YXIgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50LXRpbWV6b25lJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLm9uKCdjaGFuZ2U6dHlwZScsIGZ1bmN0aW9uIChmYWNldCwgbmV3dmFsKSB7XG4gICAgICAvLyByZXNldCB0cmFuc2Zvcm1hdGlvbnMgb24gdHlwZSBjaGFuZ2VcbiAgICAgIHRoaXMuY29udGludW91c1RyYW5zZm9ybS5yZXNldCgpO1xuICAgICAgdGhpcy5jYXRlZ29yaWFsVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgICB0aGlzLmRhdGV0aW1lVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgICB0aGlzLmR1cmF0aW9uVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgfSk7XG4gIH0sXG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogU2hvdyBpbiBmYWNldCBsaXN0cyAodXNlZCBmb3IgaW50ZXJhY3RpdmUgc2VhcmNoaW5nIG9uIEZhY2V0cyBwYWdlKVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBzaG93OiBbJ2Jvb2xlYW4nLCBmYWxzZSwgdHJ1ZV0sXG5cbiAgICAvKipcbiAgICAgKiBTaG93IGZhY2V0IGJhciAob24gQW5hbHl6ZSBwYWdlKVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0FjdGl2ZTogWydib29sZWFuJywgZmFsc2UsIGZhbHNlXSxcblxuICAgIC8vIGdlbmVyYWwgZmFjZXQgcHJvcGVydGllc1xuICAgIC8qKlxuICAgICAqIERlc2NyaXB0aW9uIG9mIHRoaXMgZmFjZXQsIGZvciBkaXNwbGF5aW5nIHB1cnBvc2VzXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgZGVzY3JpcHRpb246IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgZmFjZXRzLCBpdHMgdW5pdHMgZm9yIGRpc3BsYXlpbmcgcHVycG9zZXNcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB1bml0czogWydzdHJpbmcnLCB0cnVlLCAnJ10sXG5cbiAgICAvKipcbiAgICAgKiBTaG9ydCBuYW1lIChodW1hbiByZWFkYWJsZSkgZm9yIHRoaXMgZmFjZXQsIG11c3QgYmUgdW5pcXVlLlxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG5hbWU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiB0aGlzIGZhY2V0OlxuICAgICAqICAqIGBjb25zdGFudGAgICAgICAgIEEgY29uc3RhbnQgdmFsdWUgb2YgXCIxXCIgZm9yIGFsbCBkYXRhIGl0ZW1zXG4gICAgICogICogYGNvbnRpbnVvdXNgICAgICAgVGhlIGZhY2V0IHRha2VzIG9uIHJlYWwgbnVtYmVyc1xuICAgICAqICAqIGBjYXRlZ29yaWFsYCAgICAgIFRoZSBmYWNldCBpcyBhIHN0cmluZywgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncyAoZm9yIGEgd2VsbCBkZWZpbmVkIHNldCBvZiBsYWJlbHMgYW5kIHRhZ3MpXG4gICAgICogICogYGRhdGV0aW1lYCAgICAgICAgVGhlIGZhY2V0IGlzIGEgZGF0ZXRpbWUgKHVzaW5nIG1vbWVudGpzLnR6KVxuICAgICAqICAqIGBkdXJhdGlvbmAgICAgICAgIFRoZSBmYWNldCBpcyBhIGR1cmF0aW9uICh1c2luZyBtb21lbnRqcy5kdXJhdGlvbilcbiAgICAgKiAgKiBgdGV4dGAgICAgICAgICAgICBGcmVlZm9ybSB0ZXh0LlxuICAgICAqIENoZWNrIGZvciBmYWNldCB0eXBlIHVzaW5nIGlzQ29uc3RhbnQsIGlzQ29udGludW91cywgaXNDYXRlZ29yaWFsLCBpc0RhdGV0aW1lLCBpc0R1cmF0aW9uLCBvciBpc1RleHQgIHByb3BlcnRpZXMuXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHlwZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICdjYXRlZ29yaWFsJyxcbiAgICAgIHZhbHVlczogWydjb25zdGFudCcsICdjb250aW51b3VzJywgJ2NhdGVnb3JpYWwnLCAnZGF0ZXRpbWUnLCAnZHVyYXRpb24nLCAndGV4dCddXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBhY2Nlc3NvciBmb3IgdGhpcyBmYWNldC5cbiAgICAgKiBGb3IgbmVzdGVkIHByb3BlcnRpZXMgdXNlIGRvdCBub3RhdGlvbjogRm9yIGEgZGF0YXNldCBgWyB7bmFtZToge2ZpcnN0OiBcIlNhbnRhXCIsIGxhc3Q6IFwiQ2xhdXNcIn19LCAuLi5dYFxuICAgICAqIHlvdSBjYW4gdXNlIGBuYW1lLmZpcnN0YCBhbmQgYG5hbWUubGFzdGAgdG8gZ2V0IFNhbnRhIGFuZCBDbGF1cywgcmVzcGVjdGl2ZWx5LlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgYWNjZXNzb3I6IFsnc3RyaW5nJywgZmFsc2UsIG51bGxdLFxuXG4gICAgLyoqXG4gICAgICogTWlzc2luZyBvciBpbnZhbGlkIGRhdGEgaW5kaWNhdG9yOyBmb3IgbXVsdGlwbGUgdmFsdWVzLCB1c2UgYSBjb21tYSBzZXBhcmF0ZWQsIHF1b3RlZCBsaXN0XG4gICAgICogTnVtYmVycywgc3RyaW5ncywgYm9vbGVhbnMsIGFuZCB0aGUgc3BlY2lhbCB2YWx1ZSBudWxsIGFyZSBhbGxvd2VkLlxuICAgICAqIFVzZSBzaW5nbGUgb3IgZG91YmxlIHF1b3RlcyBmb3Igc3RyaW5ncyBcIm1pc3NpbmdcIi5cbiAgICAgKiBUaGUgcGFyc2VkIHZhbHVlcyBhcmUgYXZhaWxhYmxlIGluIHRoZSBtaXN2YWwgcHJvcGVydHkuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBtaXN2YWxBc1RleHQ6ICdzdHJpbmcnLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgb3IgZGF0ZXRpbWUgRmFjZXRzLCB0aGUgbWluaW11bSB2YWx1ZSBhcyB0ZXh0LlxuICAgICAqIFBhcnNlZCB2YWx1ZSBhdmFpbGFibGUgaW4gdGhlIGBtaW52YWxgIHByb3BlcnR5XG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgbWludmFsQXNUZXh0OiAnc3RyaW5nJyxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1heGltdW0gdmFsdWUgYXMgdGV4dC5cbiAgICAgKiBQYXJzZWQgdmFsdWUgYXZhaWxhYmxlIGluIHRoZSBgbWF4dmFsYCBwcm9wZXJ0eVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG1heHZhbEFzVGV4dDogJ3N0cmluZydcbiAgfSxcbiAgY2hpbGRyZW46IHtcbiAgICAvKipcbiAgICAgKiBBIGNhdGVnb3JpYWwgdHJhbnNmb3JtYXRpb24gdG8gYXBwbHkgdG8gdGhlIGRhdGFcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge0NhdGVnb3JpYWxUcmFuc2Zvcm19XG4gICAgICovXG4gICAgY2F0ZWdvcmlhbFRyYW5zZm9ybTogQ2F0ZWdvcmlhbFRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGRhdGV0aW1lIHRyYW5zZm9ybWF0aW9uIHRvIGFwcGx5IHRvIHRoZSBkYXRhXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtkYXRlaW1lVHJhbnNmb3JtfVxuICAgICAqL1xuICAgIGRhdGV0aW1lVHJhbnNmb3JtOiBkYXRldGltZVRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGR1cmF0aW9uIHRyYW5zZm9ybWF0aW9uIHRvIGFwcGx5IHRvIHRoZSBkYXRhXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtkYXRlaW1lVHJhbnNmb3JtfVxuICAgICAqL1xuICAgIGR1cmF0aW9uVHJhbnNmb3JtOiBkdXJhdGlvblRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGNvbnRpbnVvdXMgdHJhbnNmb3JtYXRpb24gdG8gYXBwbHkgdG8gdGhlIGRhdGFcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge0NvbnRpbnVvdXNUcmFuc2Zvcm19XG4gICAgICovXG4gICAgY29udGludW91c1RyYW5zZm9ybTogQ29udGludW91c1RyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIHRleHQgdHJhbnNmb3JtXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtUZXh0VHJhbnNmb3JtfVxuICAgICAqL1xuICAgIHRleHRUcmFuc2Zvcm06IHRleHRUcmFuc2Zvcm1cbiAgfSxcblxuICBkZXJpdmVkOiB7XG4gICAgLy8gcHJvcGVydGllcyBmb3I6IHR5cGVcbiAgICBpc0NvbnN0YW50OiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjb25zdGFudCc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0NvbnRpbnVvdXM6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2NvbnRpbnVvdXMnO1xuICAgICAgfVxuICAgIH0sXG4gICAgaXNDYXRlZ29yaWFsOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjYXRlZ29yaWFsJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzRGF0ZXRpbWU6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2RhdGV0aW1lJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzRHVyYXRpb246IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2R1cmF0aW9uJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzVGV4dDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAndGV4dCc7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEFycmF5IG9mIG1pc3NpbmcgZGF0YSBpbmRpY2F0b3JzXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtPYmplY3RbXX1cbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKi9cbiAgICBtaXN2YWw6IHtcbiAgICAgIGRlcHM6IFsnbWlzdmFsQXNUZXh0J10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBQYXJzZSB0aGUgdGV4dCBjb250ZW50IGFzIGEgSlNPTiBhcnJheTpcbiAgICAgICAgLy8gIC0gc3RyaW5ncyBzaG91bGQgYmUgcXVvdGVkXG4gICAgICAgIC8vICAtIG51bWJlcnMgdW5xdW9hdGVkXG4gICAgICAgIC8vICAtIHNwZWNpYWwgbnVtYmVycyBub3QgYWxsb3dlZDogTmFOLCBJbmZpbml0eVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICh0aGlzLm1pc3ZhbEFzVGV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoJ1snICsgdGhpcy5taXN2YWxBc1RleHQgKyAnXScpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1pbmltdW0gdmFsdWUuXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtudW1iZXJ8ZGF0ZXRpbWV9XG4gICAgICogQHJlYWRvbmx5XG4gICAgICovXG4gICAgbWludmFsOiB7XG4gICAgICBkZXBzOiBbJ21pbnZhbEFzVGV4dCcsICd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWluO1xuICAgICAgICBpZiAodGhpcy5pc0NvbnRpbnVvdXMpIHtcbiAgICAgICAgICBtaW4gPSBwYXJzZUZsb2F0KHRoaXMubWludmFsQXNUZXh0KTtcbiAgICAgICAgICBpZiAoaXNOYU4obWluKSkge1xuICAgICAgICAgICAgbWluID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0RhdGV0aW1lKSB7XG4gICAgICAgICAgbWluID0gbW9tZW50KHRoaXMubWludmFsQXNUZXh0LCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICAgIGlmICghbWluLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgbWluID0gbW9tZW50KCcyMDEwLTAxLTAxIDAwOjAwJywgbW9tZW50LklTT184NjAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0R1cmF0aW9uKSB7XG4gICAgICAgICAgbWluID0gbW9tZW50LmR1cmF0aW9uKHRoaXMubWludmFsQXNUZXh0KTtcbiAgICAgICAgICBpZiAoIW1vbWVudC5pc0R1cmF0aW9uKG1pbikpIHtcbiAgICAgICAgICAgIG1pbiA9IG1vbWVudC5kdXJhdGlvbigxLCAnc2Vjb25kcycpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWluO1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgb3IgZGF0ZXRpbWUgRmFjZXRzLCB0aGUgbWF4aW11bSB2YWx1ZS5cbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge251bWJlcnxkYXRldGltZX1cbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKi9cbiAgICBtYXh2YWw6IHtcbiAgICAgIGRlcHM6IFsnbWF4dmFsQXNUZXh0JywgJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXg7XG4gICAgICAgIGlmICh0aGlzLmlzQ29udGludW91cykge1xuICAgICAgICAgIG1heCA9IHBhcnNlRmxvYXQodGhpcy5tYXh2YWxBc1RleHQpO1xuICAgICAgICAgIGlmIChpc05hTihtYXgpKSB7XG4gICAgICAgICAgICBtYXggPSAxMDA7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEYXRldGltZSkge1xuICAgICAgICAgIG1heCA9IG1vbWVudCh0aGlzLm1heHZhbEFzVGV4dCwgbW9tZW50LklTT184NjAxKTtcbiAgICAgICAgICBpZiAoIW1heC5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIG1heCA9IG1vbWVudCgnMjAyMC0wMS0wMSAwMDowMCcsIG1vbWVudC5JU09fODYwMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEdXJhdGlvbikge1xuICAgICAgICAgIG1heCA9IG1vbWVudC5kdXJhdGlvbih0aGlzLm1heHZhbEFzVGV4dCk7XG4gICAgICAgICAgaWYgKCFtb21lbnQuaXNEdXJhdGlvbihtYXgpKSB7XG4gICAgICAgICAgICBtYXggPSBtb21lbnQuZHVyYXRpb24oMTAwLCAnc2Vjb25kcycpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWF4O1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgdHJhbnNmb3JtOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzQ29udGludW91cykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRpbnVvdXNUcmFuc2Zvcm07XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0NhdGVnb3JpYWwpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jYXRlZ29yaWFsVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEYXRldGltZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmRhdGV0aW1lVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEdXJhdGlvbikge1xuICAgICAgICAgIHJldHVybiB0aGlzLmR1cmF0aW9uVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNUZXh0KSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudGV4dFRyYW5zZm9ybTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmVycm9yKCdJbnZhbGlkIGZhY2V0Jyk7XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfVxuICB9LFxuICAvKipcbiAgICogc2V0TWluTWF4IHNldHMgdGhlIHJhbmdlIG9mIGEgY29udGludW91cyBvciB0aW1lIGZhY2V0XG4gICAqIEZvciBmYWNldHMgaW4gYSBkYXRhdmlldywgdGhlIG1pbmltdW0gaXMganVzdCB0aGUgbWluaW11bSBvZiB0aGUgZmFjZXQgb3ZlciBhbGwgYWN0aXZlIGRhdGFzZXRzLFxuICAgKiBhbmQgdGhlIHNhbWUgZm9yIHRoZSBtYXhpbXVtLlxuICAgKiBGb3IgZmFjZXRzIGluIGEgZGF0c2V0LCB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIGlzIGluIHRoZSBkYXRhc2V0IGRyaXZlci5cbiAgICpcbiAgICogQG1lbWJlcm9mISBGYWNldFxuICAgKi9cbiAgc2V0TWluTWF4OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIERhdGFzZXQgPSByZXF1aXJlKCcuL2RhdGFzZXQnKTtcbiAgICB2YXIgRGF0YXZpZXcgPSByZXF1aXJlKCcuL2RhdGF2aWV3Jyk7XG5cbiAgICB2YXIgYW5jZXN0b3IgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90O1xuXG4gICAgaWYgKGFuY2VzdG9yIGluc3RhbmNlb2YgRGF0YXZpZXcpIHtcbiAgICAgIC8vIEZhY2V0IC0+IEZhY2V0cyAtPiBEYXRhdmlldyAtPiBTcG90XG4gICAgICBzcG90ID0gdGhpcy5jb2xsZWN0aW9uLnBhcmVudC5wYXJlbnQ7XG4gICAgICBzcG90LnNldEZhY2V0TWluTWF4KHRoaXMpO1xuICAgIH0gZWxzZSBpZiAoYW5jZXN0b3IgaW5zdGFuY2VvZiBEYXRhc2V0KSB7XG4gICAgICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgICAgIHNwb3QgPSBhbmNlc3Rvci5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICAgIHNwb3QuZHJpdmVyLnNldE1pbk1heChhbmNlc3RvciwgdGhpcyk7XG4gICAgfVxuICB9LFxuICAvKipcbiAgICogc2V0Q2F0ZWdvcmllcyBmaW5kcyBmaW5kcyBhbGwgdmFsdWVzIG9uIGFuIG9yZGluYWwgKGNhdGVnb3JpYWwpIGF4aXNcbiAgICogVXBkYXRlcyB0aGUgY2F0ZWdvcmlhbFRyYW5zZm9ybSBvZiB0aGUgZmFjZXRcbiAgICogRm9yIGZhY2V0cyBpbiBhIGRhdGF2aWV3LCB0aGlzIGlzIHRoZSB1bmlvbiBvZiB0aGUgY2F0ZWdvcmllcyBvZiBmYWNldCBvdmVyIGFsbCBhY3RpdmUgZGF0YXNldHMuXG4gICAqIEZvciBmYWNldHMgaW4gYSBkYXRhc2V0LCB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIGlzIGluIHRoZSBkYXRhc2V0IGRyaXZlci5cbiAgICpcbiAgICogQG1lbWJlcm9mISBGYWNldFxuICAgKi9cbiAgc2V0Q2F0ZWdvcmllczogZnVuY3Rpb24gKCkge1xuICAgIHZhciBEYXRhc2V0ID0gcmVxdWlyZSgnLi9kYXRhc2V0Jyk7XG4gICAgdmFyIERhdGF2aWV3ID0gcmVxdWlyZSgnLi9kYXRhdmlldycpO1xuXG4gICAgdmFyIGFuY2VzdG9yID0gdGhpcy5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICB2YXIgc3BvdDtcblxuICAgIGlmIChhbmNlc3RvciBpbnN0YW5jZW9mIERhdGF2aWV3KSB7XG4gICAgICAvLyBGYWNldCAtPiBGYWNldHMgLT4gRGF0YXZpZXcgLT4gU3BvdFxuICAgICAgc3BvdCA9IHRoaXMuY29sbGVjdGlvbi5wYXJlbnQucGFyZW50O1xuICAgICAgc3BvdC5zZXRGYWNldENhdGVnb3JpZXModGhpcyk7XG4gICAgfSBlbHNlIGlmIChhbmNlc3RvciBpbnN0YW5jZW9mIERhdGFzZXQpIHtcbiAgICAgIC8vIEZhY2V0IC0+IEZhY2V0cyAtPiBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgICAgIHNwb3QgPSBhbmNlc3Rvci5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICAgIHNwb3QuZHJpdmVyLnNldENhdGVnb3JpZXMoYW5jZXN0b3IsIHRoaXMpO1xuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4d50\n")},5066:function(module,exports,__webpack_require__){eval("/**\n * A Dataview is a join of Datasets\n *\n * @class Dataview\n * @extends Base\n */\nvar Crossfilter = __webpack_require__(/*! crossfilter2 */ \"0352\"); // TODO: only for client side datasets\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Filters = __webpack_require__(/*! ./filter/collection */ \"7fa4\");\nvar Facets = __webpack_require__(/*! ./facet/collection */ \"51fb\");\n\nfunction getData () {\n  if (this.isPaused) {\n    return;\n  }\n  console.time('Get data');\n\n  var spot = this.parent;\n\n  return spot.driver.getData(this);\n}\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    /**\n     * Crossfilter instance, see [here](http://square.github.io/crossfilter/)\n     * used for client side data handling.\n     *\n     * @memberof! Dataset\n     */\n    this.crossfilter = new Crossfilter([]);\n    this.countGroup = this.crossfilter.groupAll().reduceCount();\n  },\n  props: {\n    /**\n     * Total number of datapoints in the current dataview\n     *\n     * @memberof! Dataview\n     * @readonly\n     * @type {number}\n     */\n    dataTotal: ['number', true, 0],\n    /**\n     * Number of datapoints that are currently selected\n     *\n     * @memberof! Dataview\n     * @readonly\n     * @type {number}\n     */\n    dataSelected: ['number', true, 0],\n    /**\n     * DatasetId's of active datasets\n     *\n     * @memberof! Dataview\n     * @type {String[]}\n     */\n    datasetIds: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    }\n  },\n  session: {\n    /**\n     * isPaused when true, calls to getAllData are ignored.\n     * This is useful to suppres calls to getData\n     * when adding and removing a number of filters at once.\n     * @memberof! Dataview\n     * @type {boolean}\n     */\n    isPaused: ['boolean', true, false]\n  },\n  collections: {\n    /**\n     * A Facet collection holding pre defined facets\n     *\n     * @memberof! Dataview\n     * @type {Facet[]}\n     */\n    facets: Facets,\n    /**\n     * A Filter collection holding all active filters on the dataview\n     *\n     * @memberof! Dataview\n     * @type {Filter[]}\n     */\n    filters: Filters\n  },\n  /**\n   * Pause the dataview. This means calls to getData are blocked.\n   * Useful when updating a lot of filters and you are not interested in the intermediate state.\n   *\n   * @memberof! Dataview\n   */\n  pause: function () {\n    this.isPaused = true;\n  },\n  /**\n   * Unpause the dataview.\n   *\n   * @memberof! Dataview\n   */\n  play: function () {\n    this.isPaused = false;\n  },\n\n  /**\n   * Get data for all filters linked to this dataview.\n   * When data has become available for a filter, a `newData` event is triggered on that filter.\n   *\n   * @memberof! Dataview\n   * @function\n   */\n  getData: getData\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTA2Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXZpZXcuanM/NGQ0YSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEEgRGF0YXZpZXcgaXMgYSBqb2luIG9mIERhdGFzZXRzXG4gKlxuICogQGNsYXNzIERhdGF2aWV3XG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBDcm9zc2ZpbHRlciA9IHJlcXVpcmUoJ2Nyb3NzZmlsdGVyMicpOyAvLyBUT0RPOiBvbmx5IGZvciBjbGllbnQgc2lkZSBkYXRhc2V0c1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG52YXIgRmlsdGVycyA9IHJlcXVpcmUoJy4vZmlsdGVyL2NvbGxlY3Rpb24nKTtcbnZhciBGYWNldHMgPSByZXF1aXJlKCcuL2ZhY2V0L2NvbGxlY3Rpb24nKTtcblxuZnVuY3Rpb24gZ2V0RGF0YSAoKSB7XG4gIGlmICh0aGlzLmlzUGF1c2VkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnNvbGUudGltZSgnR2V0IGRhdGEnKTtcblxuICB2YXIgc3BvdCA9IHRoaXMucGFyZW50O1xuXG4gIHJldHVybiBzcG90LmRyaXZlci5nZXREYXRhKHRoaXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VNb2RlbC5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gZmlyc3QgZG8gcGFyZW50IGNsYXNzIGluaXRpYWxpemF0aW9uXG4gICAgQmFzZU1vZGVsLnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICAvKipcbiAgICAgKiBDcm9zc2ZpbHRlciBpbnN0YW5jZSwgc2VlIFtoZXJlXShodHRwOi8vc3F1YXJlLmdpdGh1Yi5pby9jcm9zc2ZpbHRlci8pXG4gICAgICogdXNlZCBmb3IgY2xpZW50IHNpZGUgZGF0YSBoYW5kbGluZy5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqL1xuICAgIHRoaXMuY3Jvc3NmaWx0ZXIgPSBuZXcgQ3Jvc3NmaWx0ZXIoW10pO1xuICAgIHRoaXMuY291bnRHcm91cCA9IHRoaXMuY3Jvc3NmaWx0ZXIuZ3JvdXBBbGwoKS5yZWR1Y2VDb3VudCgpO1xuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRvdGFsIG51bWJlciBvZiBkYXRhcG9pbnRzIGluIHRoZSBjdXJyZW50IGRhdGF2aWV3XG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHJlYWRvbmx5XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBkYXRhVG90YWw6IFsnbnVtYmVyJywgdHJ1ZSwgMF0sXG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIGRhdGFwb2ludHMgdGhhdCBhcmUgY3VycmVudGx5IHNlbGVjdGVkXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHJlYWRvbmx5XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBkYXRhU2VsZWN0ZWQ6IFsnbnVtYmVyJywgdHJ1ZSwgMF0sXG4gICAgLyoqXG4gICAgICogRGF0YXNldElkJ3Mgb2YgYWN0aXZlIGRhdGFzZXRzXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge1N0cmluZ1tdfVxuICAgICAqL1xuICAgIGRhdGFzZXRJZHM6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBkZWZhdWx0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHNlc3Npb246IHtcbiAgICAvKipcbiAgICAgKiBpc1BhdXNlZCB3aGVuIHRydWUsIGNhbGxzIHRvIGdldEFsbERhdGEgYXJlIGlnbm9yZWQuXG4gICAgICogVGhpcyBpcyB1c2VmdWwgdG8gc3VwcHJlcyBjYWxscyB0byBnZXREYXRhXG4gICAgICogd2hlbiBhZGRpbmcgYW5kIHJlbW92aW5nIGEgbnVtYmVyIG9mIGZpbHRlcnMgYXQgb25jZS5cbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNQYXVzZWQ6IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXVxuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEEgRmFjZXQgY29sbGVjdGlvbiBob2xkaW5nIHByZSBkZWZpbmVkIGZhY2V0c1xuICAgICAqXG4gICAgICogQG1lbWJlcm9mISBEYXRhdmlld1xuICAgICAqIEB0eXBlIHtGYWNldFtdfVxuICAgICAqL1xuICAgIGZhY2V0czogRmFjZXRzLFxuICAgIC8qKlxuICAgICAqIEEgRmlsdGVyIGNvbGxlY3Rpb24gaG9sZGluZyBhbGwgYWN0aXZlIGZpbHRlcnMgb24gdGhlIGRhdGF2aWV3XG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge0ZpbHRlcltdfVxuICAgICAqL1xuICAgIGZpbHRlcnM6IEZpbHRlcnNcbiAgfSxcbiAgLyoqXG4gICAqIFBhdXNlIHRoZSBkYXRhdmlldy4gVGhpcyBtZWFucyBjYWxscyB0byBnZXREYXRhIGFyZSBibG9ja2VkLlxuICAgKiBVc2VmdWwgd2hlbiB1cGRhdGluZyBhIGxvdCBvZiBmaWx0ZXJzIGFuZCB5b3UgYXJlIG5vdCBpbnRlcmVzdGVkIGluIHRoZSBpbnRlcm1lZGlhdGUgc3RhdGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiEgRGF0YXZpZXdcbiAgICovXG4gIHBhdXNlOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5pc1BhdXNlZCA9IHRydWU7XG4gIH0sXG4gIC8qKlxuICAgKiBVbnBhdXNlIHRoZSBkYXRhdmlldy5cbiAgICpcbiAgICogQG1lbWJlcm9mISBEYXRhdmlld1xuICAgKi9cbiAgcGxheTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuaXNQYXVzZWQgPSBmYWxzZTtcbiAgfSxcblxuICAvKipcbiAgICogR2V0IGRhdGEgZm9yIGFsbCBmaWx0ZXJzIGxpbmtlZCB0byB0aGlzIGRhdGF2aWV3LlxuICAgKiBXaGVuIGRhdGEgaGFzIGJlY29tZSBhdmFpbGFibGUgZm9yIGEgZmlsdGVyLCBhIGBuZXdEYXRhYCBldmVudCBpcyB0cmlnZ2VyZWQgb24gdGhhdCBmaWx0ZXIuXG4gICAqXG4gICAqIEBtZW1iZXJvZiEgRGF0YXZpZXdcbiAgICogQGZ1bmN0aW9uXG4gICAqL1xuICBnZXREYXRhOiBnZXREYXRhXG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5066\n")},"51fb":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Facet = __webpack_require__(/*! ../facet */ \"4d50\");\n\nmodule.exports = Collection.extend({\n  model: Facet,\n  mainIndex: 'id',\n  indexes: ['name'],\n  session: {\n    needle: ['string', true, ''], // search string used on the Facet page\n    showSearch: ['boolean', true, false] // show/hide the search bar on the Facet page\n  },\n  comparator: function (left, right) {\n    return left.name.localeCompare(right.name);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTFmYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29sbGVjdGlvbi5qcz84ZWU5Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBDb2xsZWN0aW9uID0gcmVxdWlyZSgnYW1wZXJzYW5kLWNvbGxlY3Rpb24nKTtcbnZhciBGYWNldCA9IHJlcXVpcmUoJy4uL2ZhY2V0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogRmFjZXQsXG4gIG1haW5JbmRleDogJ2lkJyxcbiAgaW5kZXhlczogWyduYW1lJ10sXG4gIHNlc3Npb246IHtcbiAgICBuZWVkbGU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLCAvLyBzZWFyY2ggc3RyaW5nIHVzZWQgb24gdGhlIEZhY2V0IHBhZ2VcbiAgICBzaG93U2VhcmNoOiBbJ2Jvb2xlYW4nLCB0cnVlLCBmYWxzZV0gLy8gc2hvdy9oaWRlIHRoZSBzZWFyY2ggYmFyIG9uIHRoZSBGYWNldCBwYWdlXG4gIH0sXG4gIGNvbXBhcmF0b3I6IGZ1bmN0aW9uIChsZWZ0LCByaWdodCkge1xuICAgIHJldHVybiBsZWZ0Lm5hbWUubG9jYWxlQ29tcGFyZShyaWdodC5uYW1lKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///51fb\n")},"544d":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Dataset = __webpack_require__(/*! ../dataset */ \"545a\");\n\nmodule.exports = Collection.extend({\n  mainIndex: 'id',\n  indexes: ['name'],\n  model: Dataset\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQ0ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXNldC9jb2xsZWN0aW9uLmpzPzkxZDkiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIENvbGxlY3Rpb24gPSByZXF1aXJlKCdhbXBlcnNhbmQtY29sbGVjdGlvbicpO1xudmFyIERhdGFzZXQgPSByZXF1aXJlKCcuLi9kYXRhc2V0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtYWluSW5kZXg6ICdpZCcsXG4gIGluZGV4ZXM6IFsnbmFtZSddLFxuICBtb2RlbDogRGF0YXNldFxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///544d\n")},"545a":function(module,exports,__webpack_require__){eval("/**\n * @class Dataset\n * @extends Base\n */\nvar Crossfilter = __webpack_require__(/*! crossfilter2 */ \"0352\"); // TODO: only for client side datasets\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Facets = __webpack_require__(/*! ./facet/collection */ \"51fb\");\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    /**\n     * Crossfilter instance, see [here](http://square.github.io/crossfilter/)\n     * used for client side data handling.\n     *\n     * @memberof! Dataset\n     */\n    this.crossfilter = new Crossfilter([]);\n    this.countGroup = this.crossfilter.groupAll().reduceCount();\n  },\n  props: {\n    /**\n     * Name of the dataset\n     * @memberof! Dataset\n     * @type {string}\n     */\n    name: {\n      type: 'string',\n      required: true,\n      default: 'Name'\n    },\n    /**\n     * URL, fi. to paper, dataset owner, etc.\n     * @memberof! Dataset\n     * @type {string}\n     */\n    URL: {\n      type: 'string',\n      required: true,\n      default: 'URL'\n    },\n    /**\n     * Database table name for server datasets\n     * @memberof! Dataset\n     * @type {string}\n     */\n    databaseTable: {\n      type: 'string',\n      default: ''\n    },\n    /**\n     * Short description of the dataset\n     * @memberof! Dataset\n     * @type {string}\n     */\n    description: {\n      type: 'string',\n      required: true,\n      default: 'Description'\n    },\n    /**\n     * If dataset is part of the current session\n     * @memberof! Dataset\n     * @type {boolean}\n     */\n    isActive: {\n      type: 'boolean',\n      required: true,\n      default: false\n    }\n  },\n  session: {\n    /**\n     * For searching through datasets URL and description.\n     * True if this dataset matches the search paramters.\n     */\n    show: {\n      type: 'boolean',\n      required: true,\n      default: true\n    },\n    data: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    }\n  },\n  collections: {\n    /**\n     * A Facet collection holding pre defined facets\n     * @memberof! Dataset\n     * @type {Facet[]}\n     */\n    facets: Facets\n  },\n  scan: function () {\n    // Dataset -> Datasets -> spot\n    var spot = this.collection.parent;\n\n    // clear all existing facets\n    this.facets.reset();\n\n    spot.driver.scan(this);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQ1YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXNldC5qcz9lYTcwIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGNsYXNzIERhdGFzZXRcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xudmFyIENyb3NzZmlsdGVyID0gcmVxdWlyZSgnY3Jvc3NmaWx0ZXIyJyk7IC8vIFRPRE86IG9ubHkgZm9yIGNsaWVudCBzaWRlIGRhdGFzZXRzXG52YXIgQmFzZU1vZGVsID0gcmVxdWlyZSgnLi91dGlsL2Jhc2UnKTtcbnZhciBGYWNldHMgPSByZXF1aXJlKCcuL2ZhY2V0L2NvbGxlY3Rpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlTW9kZWwuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIC8vIGZpcnN0IGRvIHBhcmVudCBjbGFzcyBpbml0aWFsaXphdGlvblxuICAgIEJhc2VNb2RlbC5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgLyoqXG4gICAgICogQ3Jvc3NmaWx0ZXIgaW5zdGFuY2UsIHNlZSBbaGVyZV0oaHR0cDovL3NxdWFyZS5naXRodWIuaW8vY3Jvc3NmaWx0ZXIvKVxuICAgICAqIHVzZWQgZm9yIGNsaWVudCBzaWRlIGRhdGEgaGFuZGxpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKi9cbiAgICB0aGlzLmNyb3NzZmlsdGVyID0gbmV3IENyb3NzZmlsdGVyKFtdKTtcbiAgICB0aGlzLmNvdW50R3JvdXAgPSB0aGlzLmNyb3NzZmlsdGVyLmdyb3VwQWxsKCkucmVkdWNlQ291bnQoKTtcbiAgfSxcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBOYW1lIG9mIHRoZSBkYXRhc2V0XG4gICAgICogQG1lbWJlcm9mISBEYXRhc2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBuYW1lOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ05hbWUnXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBVUkwsIGZpLiB0byBwYXBlciwgZGF0YXNldCBvd25lciwgZXRjLlxuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgVVJMOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ1VSTCdcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIERhdGFiYXNlIHRhYmxlIG5hbWUgZm9yIHNlcnZlciBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgZGF0YWJhc2VUYWJsZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZWZhdWx0OiAnJ1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogU2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIGRhdGFzZXRcbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRlc2NyaXB0aW9uOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ0Rlc2NyaXB0aW9uJ1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogSWYgZGF0YXNldCBpcyBwYXJ0IG9mIHRoZSBjdXJyZW50IHNlc3Npb25cbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0FjdGl2ZToge1xuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiBmYWxzZVxuICAgIH1cbiAgfSxcbiAgc2Vzc2lvbjoge1xuICAgIC8qKlxuICAgICAqIEZvciBzZWFyY2hpbmcgdGhyb3VnaCBkYXRhc2V0cyBVUkwgYW5kIGRlc2NyaXB0aW9uLlxuICAgICAqIFRydWUgaWYgdGhpcyBkYXRhc2V0IG1hdGNoZXMgdGhlIHNlYXJjaCBwYXJhbXRlcnMuXG4gICAgICovXG4gICAgc2hvdzoge1xuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiB0cnVlXG4gICAgfSxcbiAgICBkYXRhOiB7XG4gICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEEgRmFjZXQgY29sbGVjdGlvbiBob2xkaW5nIHByZSBkZWZpbmVkIGZhY2V0c1xuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtGYWNldFtdfVxuICAgICAqL1xuICAgIGZhY2V0czogRmFjZXRzXG4gIH0sXG4gIHNjYW46IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IHNwb3RcbiAgICB2YXIgc3BvdCA9IHRoaXMuY29sbGVjdGlvbi5wYXJlbnQ7XG5cbiAgICAvLyBjbGVhciBhbGwgZXhpc3RpbmcgZmFjZXRzXG4gICAgdGhpcy5mYWNldHMucmVzZXQoKTtcblxuICAgIHNwb3QuZHJpdmVyLnNjYW4odGhpcyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///545a\n")},"58ab":function(module,exports,__webpack_require__){eval('\nmodule.exports = __webpack_require__(/*! ./socket */ "0112");\n\n/**\n * Exports parser\n *\n * @api public\n *\n */\nmodule.exports.parser = __webpack_require__(/*! engine.io-parser */ "aa6c");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNThhYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvaW5kZXguanM/ZWViYiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9zb2NrZXQnKTtcblxuLyoqXG4gKiBFeHBvcnRzIHBhcnNlclxuICpcbiAqIEBhcGkgcHVibGljXG4gKlxuICovXG5tb2R1bGUuZXhwb3J0cy5wYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///58ab\n')},"5a80":function(module,exports,__webpack_require__){eval("/**\n * ContinuousTransfrom defines a transformation on continuous (nummerical) data.\n * Currently linear interpolation between a set of control points is implemented.\n *\n * @class ContinuousTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nvar ControlPoint = __webpack_require__(/*! ./control-point */ \"09c5\");\nvar ControlPoints = Collection.extend({\n  model: ControlPoint\n});\n\n/**\n * Apply piecewise linear transformation\n * The function is constant outside the range spanned by the control points;\n * there it is set to value of the first, or the last, control points.\n *\n * @function\n * @memberof! ContinuousTransform\n * @param {number} x\n * @returns {number} fx\n */\nfunction transform (cps, x) {\n  if (x === misval) {\n    return misval;\n  }\n\n  var ncps = cps.models.length;\n  if (x <= cps.models[0].x) {\n    // outside range on left side\n    return cps.models[0].fx;\n  } else if (x >= cps.models[ncps - 1].x) {\n    // outside range on right side\n    return cps.models[ncps - 1].fx;\n  } else {\n    // inside range\n    var i = 0;\n    while (x > cps.models[i].x) {\n      i = i + 1;\n    }\n\n    // linear interpolate between fx_i and fx_(i+1)\n    var xm = cps.models[i].x;\n    var xp = cps.models[i + 1].x;\n    var fxm = cps.models[i].fx;\n    var fxp = cps.models[i + 1].fx;\n    if (xp === xm) {\n      return 0.5 * (fxm + fxp);\n    } else {\n      return fxm + (x - xm) * (fxp - fxm) / (xp - xm);\n    }\n  }\n}\n\n/**\n * The inverse of the transform\n *\n * @function\n * @memberof! ContinuousTransform\n * @param {number} fx\n * @returns {number} x\n */\nfunction inverse (cps, fx) {\n  if (fx === misval) {\n    return misval;\n  }\n\n  var ncps = cps.models.length;\n  if (fx <= cps.models[0].fx) {\n    // outside range on left side\n    return cps.models[0].x;\n  } else if (fx >= cps.models[ncps - 1].fx) {\n    // outside range on right side\n    return cps.models[ncps - 1].x;\n  } else {\n    // inside range\n    var i = 0;\n    while (fx > cps.models[i].fx) {\n      i = i + 1;\n    }\n\n    // linear interpolate between fx_i and fx_(i+1)\n    var xm = cps.models[i].x;\n    var xp = cps.models[i + 1].x;\n    var fxm = cps.models[i].fx;\n    var fxp = cps.models[i + 1].fx;\n    if (fxp === fxm) {\n      return 0.5 * (xm + xp);\n    } else {\n      return xm + (fx - fxm) * (xp - xm) / (fxp - fxm);\n    }\n  }\n}\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * The type of continuous transform, can be none, or percentiles\n     * Use isNone, or isPercentiles, check for transform type\n     * @memberof! ContinuousTransform\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'none',\n      values: ['none', 'percentiles']\n    },\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'continuous',\n      values: ['continuous']\n    }\n  },\n  derived: {\n    isNone: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'none';\n      }\n    },\n    isPercentiles: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'percentiles';\n      }\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! ContinuousTransform\n     */\n    transformedMin: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isPercentiles) {\n          return 0;\n        } else if (this.isNone) {\n          return this.parent.minval;\n        } else {\n          console.error('Invalid continuous transform');\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! ContinuousTransform\n     */\n    transformedMax: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isPercentiles) {\n          return 100;\n        } else if (this.isNone) {\n          return this.parent.maxval;\n        } else {\n          console.error('Invalid continuous transform');\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! ContinuousTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! ContinuousTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n  collections: {\n    cps: ControlPoints\n  },\n  transform: function (x) {\n    return transform(this.cps, x);\n  },\n  inverse: function (fx) {\n    return inverse(this.cps, fx);\n  },\n  reset: function () {\n    this.type = 'none';\n    this.cps.reset();\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNWE4MC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29udGludW91cy10cmFuc2Zvcm0uanM/YzgwOSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbnRpbnVvdXNUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNvbnRpbnVvdXMgKG51bW1lcmljYWwpIGRhdGEuXG4gKiBDdXJyZW50bHkgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiBhIHNldCBvZiBjb250cm9sIHBvaW50cyBpcyBpbXBsZW1lbnRlZC5cbiAqXG4gKiBAY2xhc3MgQ29udGludW91c1RyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBDb2xsZWN0aW9uID0gcmVxdWlyZSgnYW1wZXJzYW5kLWNvbGxlY3Rpb24nKTtcbnZhciBtaXN2YWwgPSByZXF1aXJlKCcuLi91dGlsL21pc3ZhbCcpO1xuXG52YXIgQ29udHJvbFBvaW50ID0gcmVxdWlyZSgnLi9jb250cm9sLXBvaW50Jyk7XG52YXIgQ29udHJvbFBvaW50cyA9IENvbGxlY3Rpb24uZXh0ZW5kKHtcbiAgbW9kZWw6IENvbnRyb2xQb2ludFxufSk7XG5cbi8qKlxuICogQXBwbHkgcGllY2V3aXNlIGxpbmVhciB0cmFuc2Zvcm1hdGlvblxuICogVGhlIGZ1bmN0aW9uIGlzIGNvbnN0YW50IG91dHNpZGUgdGhlIHJhbmdlIHNwYW5uZWQgYnkgdGhlIGNvbnRyb2wgcG9pbnRzO1xuICogdGhlcmUgaXQgaXMgc2V0IHRvIHZhbHVlIG9mIHRoZSBmaXJzdCwgb3IgdGhlIGxhc3QsIGNvbnRyb2wgcG9pbnRzLlxuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mISBDb250aW51b3VzVHJhbnNmb3JtXG4gKiBAcGFyYW0ge251bWJlcn0geFxuICogQHJldHVybnMge251bWJlcn0gZnhcbiAqL1xuZnVuY3Rpb24gdHJhbnNmb3JtIChjcHMsIHgpIHtcbiAgaWYgKHggPT09IG1pc3ZhbCkge1xuICAgIHJldHVybiBtaXN2YWw7XG4gIH1cblxuICB2YXIgbmNwcyA9IGNwcy5tb2RlbHMubGVuZ3RoO1xuICBpZiAoeCA8PSBjcHMubW9kZWxzWzBdLngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIGxlZnQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzWzBdLmZ4O1xuICB9IGVsc2UgaWYgKHggPj0gY3BzLm1vZGVsc1tuY3BzIC0gMV0ueCkge1xuICAgIC8vIG91dHNpZGUgcmFuZ2Ugb24gcmlnaHQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzW25jcHMgLSAxXS5meDtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbnNpZGUgcmFuZ2VcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKHggPiBjcHMubW9kZWxzW2ldLngpIHtcbiAgICAgIGkgPSBpICsgMTtcbiAgICB9XG5cbiAgICAvLyBsaW5lYXIgaW50ZXJwb2xhdGUgYmV0d2VlbiBmeF9pIGFuZCBmeF8oaSsxKVxuICAgIHZhciB4bSA9IGNwcy5tb2RlbHNbaV0ueDtcbiAgICB2YXIgeHAgPSBjcHMubW9kZWxzW2kgKyAxXS54O1xuICAgIHZhciBmeG0gPSBjcHMubW9kZWxzW2ldLmZ4O1xuICAgIHZhciBmeHAgPSBjcHMubW9kZWxzW2kgKyAxXS5meDtcbiAgICBpZiAoeHAgPT09IHhtKSB7XG4gICAgICByZXR1cm4gMC41ICogKGZ4bSArIGZ4cCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmeG0gKyAoeCAtIHhtKSAqIChmeHAgLSBmeG0pIC8gKHhwIC0geG0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoZSBpbnZlcnNlIG9mIHRoZSB0cmFuc2Zvcm1cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICogQHBhcmFtIHtudW1iZXJ9IGZ4XG4gKiBAcmV0dXJucyB7bnVtYmVyfSB4XG4gKi9cbmZ1bmN0aW9uIGludmVyc2UgKGNwcywgZngpIHtcbiAgaWYgKGZ4ID09PSBtaXN2YWwpIHtcbiAgICByZXR1cm4gbWlzdmFsO1xuICB9XG5cbiAgdmFyIG5jcHMgPSBjcHMubW9kZWxzLmxlbmd0aDtcbiAgaWYgKGZ4IDw9IGNwcy5tb2RlbHNbMF0uZngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIGxlZnQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzWzBdLng7XG4gIH0gZWxzZSBpZiAoZnggPj0gY3BzLm1vZGVsc1tuY3BzIC0gMV0uZngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIHJpZ2h0IHNpZGVcbiAgICByZXR1cm4gY3BzLm1vZGVsc1tuY3BzIC0gMV0ueDtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbnNpZGUgcmFuZ2VcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKGZ4ID4gY3BzLm1vZGVsc1tpXS5meCkge1xuICAgICAgaSA9IGkgKyAxO1xuICAgIH1cblxuICAgIC8vIGxpbmVhciBpbnRlcnBvbGF0ZSBiZXR3ZWVuIGZ4X2kgYW5kIGZ4XyhpKzEpXG4gICAgdmFyIHhtID0gY3BzLm1vZGVsc1tpXS54O1xuICAgIHZhciB4cCA9IGNwcy5tb2RlbHNbaSArIDFdLng7XG4gICAgdmFyIGZ4bSA9IGNwcy5tb2RlbHNbaV0uZng7XG4gICAgdmFyIGZ4cCA9IGNwcy5tb2RlbHNbaSArIDFdLmZ4O1xuICAgIGlmIChmeHAgPT09IGZ4bSkge1xuICAgICAgcmV0dXJuIDAuNSAqICh4bSArIHhwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHhtICsgKGZ4IC0gZnhtKSAqICh4cCAtIHhtKSAvIChmeHAgLSBmeG0pO1xuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEFtcGVyc2FuZE1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgY29udGludW91cyB0cmFuc2Zvcm0sIGNhbiBiZSBub25lLCBvciBwZXJjZW50aWxlc1xuICAgICAqIFVzZSBpc05vbmUsIG9yIGlzUGVyY2VudGlsZXMsIGNoZWNrIGZvciB0cmFuc2Zvcm0gdHlwZVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnbm9uZScsXG4gICAgICB2YWx1ZXM6IFsnbm9uZScsICdwZXJjZW50aWxlcyddXG4gICAgfSxcbiAgICB0cmFuc2Zvcm1lZFR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnY29udGludW91cycsXG4gICAgICB2YWx1ZXM6IFsnY29udGludW91cyddXG4gICAgfVxuICB9LFxuICBkZXJpdmVkOiB7XG4gICAgaXNOb25lOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdub25lJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzUGVyY2VudGlsZXM6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ3BlcmNlbnRpbGVzJztcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1pbjoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5pc1BlcmNlbnRpbGVzKSB7XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc05vbmUpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQubWludmFsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgY29udGludW91cyB0cmFuc2Zvcm0nKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWF4OiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUGVyY2VudGlsZXMpIHtcbiAgICAgICAgICByZXR1cm4gMTAwO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNOb25lKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50Lm1heHZhbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdJbnZhbGlkIGNvbnRpbnVvdXMgdHJhbnNmb3JtJyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkTWluJywgJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1pbnZhbCA9IHRoaXMudHJhbnNmb3JtZWRNaW47XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiBtaW52YWwuZm9ybWF0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1heEFzVGV4dDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZE1heCcsICd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXh2YWwgPSB0aGlzLnRyYW5zZm9ybWVkTWF4O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLmZvcm1hdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH1cbiAgfSxcbiAgY29sbGVjdGlvbnM6IHtcbiAgICBjcHM6IENvbnRyb2xQb2ludHNcbiAgfSxcbiAgdHJhbnNmb3JtOiBmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiB0cmFuc2Zvcm0odGhpcy5jcHMsIHgpO1xuICB9LFxuICBpbnZlcnNlOiBmdW5jdGlvbiAoZngpIHtcbiAgICByZXR1cm4gaW52ZXJzZSh0aGlzLmNwcywgZngpO1xuICB9LFxuICByZXNldDogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMudHlwZSA9ICdub25lJztcbiAgICB0aGlzLmNwcy5yZXNldCgpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5a80\n")},6176:function(module,exports){eval("module.exports = Array.isArray || function (arr) {\n  return Object.prototype.toString.call(arr) == '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjE3Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcz8xYjA4Il0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6176\n")},"636d":function(module,exports){eval("\n/**\n * Expose `Emitter`.\n */\n\nmodule.exports = Emitter;\n\n/**\n * Initialize a new `Emitter`.\n *\n * @api public\n */\n\nfunction Emitter(obj) {\n  if (obj) return mixin(obj);\n};\n\n/**\n * Mixin the emitter properties.\n *\n * @param {Object} obj\n * @return {Object}\n * @api private\n */\n\nfunction mixin(obj) {\n  for (var key in Emitter.prototype) {\n    obj[key] = Emitter.prototype[key];\n  }\n  return obj;\n}\n\n/**\n * Listen on the given `event` with `fn`.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.on =\nEmitter.prototype.addEventListener = function(event, fn){\n  this._callbacks = this._callbacks || {};\n  (this._callbacks[event] = this._callbacks[event] || [])\n    .push(fn);\n  return this;\n};\n\n/**\n * Adds an `event` listener that will be invoked a single\n * time then automatically removed.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.once = function(event, fn){\n  var self = this;\n  this._callbacks = this._callbacks || {};\n\n  function on() {\n    self.off(event, on);\n    fn.apply(this, arguments);\n  }\n\n  on.fn = fn;\n  this.on(event, on);\n  return this;\n};\n\n/**\n * Remove the given callback for `event` or all\n * registered callbacks.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.off =\nEmitter.prototype.removeListener =\nEmitter.prototype.removeAllListeners =\nEmitter.prototype.removeEventListener = function(event, fn){\n  this._callbacks = this._callbacks || {};\n\n  // all\n  if (0 == arguments.length) {\n    this._callbacks = {};\n    return this;\n  }\n\n  // specific event\n  var callbacks = this._callbacks[event];\n  if (!callbacks) return this;\n\n  // remove all handlers\n  if (1 == arguments.length) {\n    delete this._callbacks[event];\n    return this;\n  }\n\n  // remove specific handler\n  var cb;\n  for (var i = 0; i < callbacks.length; i++) {\n    cb = callbacks[i];\n    if (cb === fn || cb.fn === fn) {\n      callbacks.splice(i, 1);\n      break;\n    }\n  }\n  return this;\n};\n\n/**\n * Emit `event` with the given args.\n *\n * @param {String} event\n * @param {Mixed} ...\n * @return {Emitter}\n */\n\nEmitter.prototype.emit = function(event){\n  this._callbacks = this._callbacks || {};\n  var args = [].slice.call(arguments, 1)\n    , callbacks = this._callbacks[event];\n\n  if (callbacks) {\n    callbacks = callbacks.slice(0);\n    for (var i = 0, len = callbacks.length; i < len; ++i) {\n      callbacks[i].apply(this, args);\n    }\n  }\n\n  return this;\n};\n\n/**\n * Return array of callbacks for `event`.\n *\n * @param {String} event\n * @return {Array}\n * @api public\n */\n\nEmitter.prototype.listeners = function(event){\n  this._callbacks = this._callbacks || {};\n  return this._callbacks[event] || [];\n};\n\n/**\n * Check if this emitter has `event` handlers.\n *\n * @param {String} event\n * @return {Boolean}\n * @api public\n */\n\nEmitter.prototype.hasListeners = function(event){\n  return !! this.listeners(event).length;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjM2ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanM/ZWVlMiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogRXhwb3NlIGBFbWl0dGVyYC5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVtaXR0ZXI7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgRW1pdHRlcmAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBFbWl0dGVyKG9iaikge1xuICBpZiAob2JqKSByZXR1cm4gbWl4aW4ob2JqKTtcbn07XG5cbi8qKlxuICogTWl4aW4gdGhlIGVtaXR0ZXIgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBtaXhpbihvYmopIHtcbiAgZm9yICh2YXIga2V5IGluIEVtaXR0ZXIucHJvdG90eXBlKSB7XG4gICAgb2JqW2tleV0gPSBFbWl0dGVyLnByb3RvdHlwZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbiA9XG5FbWl0dGVyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICAodGhpcy5fY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuX2NhbGxiYWNrc1tldmVudF0gfHwgW10pXG4gICAgLnB1c2goZm4pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXG4gKiB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICBmdW5jdGlvbiBvbigpIHtcbiAgICBzZWxmLm9mZihldmVudCwgb24pO1xuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBvbi5mbiA9IGZuO1xuICB0aGlzLm9uKGV2ZW50LCBvbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICogcmVnaXN0ZXJlZCBjYWxsYmFja3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub2ZmID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuXG4gIC8vIGFsbFxuICBpZiAoMCA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgdGhpcy5fY2FsbGJhY2tzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzcGVjaWZpYyBldmVudFxuICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcbiAgaWYgKCFjYWxsYmFja3MpIHJldHVybiB0aGlzO1xuXG4gIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcbiAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcbiAgdmFyIGNiO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgIGNiID0gY2FsbGJhY2tzW2ldO1xuICAgIGlmIChjYiA9PT0gZm4gfHwgY2IuZm4gPT09IGZuKSB7XG4gICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7TWl4ZWR9IC4uLlxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oZXZlbnQpe1xuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG4gIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpXG4gICAgLCBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuXG4gIGlmIChjYWxsYmFja3MpIHtcbiAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgY2FsbGJhY2tzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYXJyYXkgb2YgY2FsbGJhY2tzIGZvciBgZXZlbnRgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7QXJyYXl9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XSB8fCBbXTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhpcyBlbWl0dGVyIGhhcyBgZXZlbnRgIGhhbmRsZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuaGFzTGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xuICByZXR1cm4gISEgdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///636d\n")},"6b20":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar Transport = __webpack_require__(/*! ../transport */ \"0d97\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar yeast = __webpack_require__(/*! yeast */ \"c16d\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:websocket');\nvar BrowserWebSocket = global.WebSocket || global.MozWebSocket;\nvar NodeWebSocket;\nif (typeof window === 'undefined') {\n  try {\n    NodeWebSocket = __webpack_require__(/*! ws */ 1);\n  } catch (e) { }\n}\n\n/**\n * Get either the `WebSocket` or `MozWebSocket` globals\n * in the browser or try to resolve WebSocket-compatible\n * interface exposed by `ws` for Node-like environment.\n */\n\nvar WebSocket = BrowserWebSocket;\nif (!WebSocket && typeof window === 'undefined') {\n  WebSocket = NodeWebSocket;\n}\n\n/**\n * Module exports.\n */\n\nmodule.exports = WS;\n\n/**\n * WebSocket transport constructor.\n *\n * @api {Object} connection options\n * @api public\n */\n\nfunction WS (opts) {\n  var forceBase64 = (opts && opts.forceBase64);\n  if (forceBase64) {\n    this.supportsBinary = false;\n  }\n  this.perMessageDeflate = opts.perMessageDeflate;\n  this.usingBrowserWebSocket = BrowserWebSocket && !opts.forceNode;\n  if (!this.usingBrowserWebSocket) {\n    WebSocket = NodeWebSocket;\n  }\n  Transport.call(this, opts);\n}\n\n/**\n * Inherits from Transport.\n */\n\ninherit(WS, Transport);\n\n/**\n * Transport name.\n *\n * @api public\n */\n\nWS.prototype.name = 'websocket';\n\n/*\n * WebSockets support binary\n */\n\nWS.prototype.supportsBinary = true;\n\n/**\n * Opens socket.\n *\n * @api private\n */\n\nWS.prototype.doOpen = function () {\n  if (!this.check()) {\n    // let probe timeout\n    return;\n  }\n\n  var uri = this.uri();\n  var protocols = void (0);\n  var opts = {\n    agent: this.agent,\n    perMessageDeflate: this.perMessageDeflate\n  };\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n  if (this.extraHeaders) {\n    opts.headers = this.extraHeaders;\n  }\n  if (this.localAddress) {\n    opts.localAddress = this.localAddress;\n  }\n\n  try {\n    this.ws = this.usingBrowserWebSocket ? new WebSocket(uri) : new WebSocket(uri, protocols, opts);\n  } catch (err) {\n    return this.emit('error', err);\n  }\n\n  if (this.ws.binaryType === undefined) {\n    this.supportsBinary = false;\n  }\n\n  if (this.ws.supports && this.ws.supports.binary) {\n    this.supportsBinary = true;\n    this.ws.binaryType = 'nodebuffer';\n  } else {\n    this.ws.binaryType = 'arraybuffer';\n  }\n\n  this.addEventListeners();\n};\n\n/**\n * Adds event listeners to the socket\n *\n * @api private\n */\n\nWS.prototype.addEventListeners = function () {\n  var self = this;\n\n  this.ws.onopen = function () {\n    self.onOpen();\n  };\n  this.ws.onclose = function () {\n    self.onClose();\n  };\n  this.ws.onmessage = function (ev) {\n    self.onData(ev.data);\n  };\n  this.ws.onerror = function (e) {\n    self.onError('websocket error', e);\n  };\n};\n\n/**\n * Writes data to socket.\n *\n * @param {Array} array of packets.\n * @api private\n */\n\nWS.prototype.write = function (packets) {\n  var self = this;\n  this.writable = false;\n\n  // encodePacket efficient as it uses WS framing\n  // no need for encodePayload\n  var total = packets.length;\n  for (var i = 0, l = total; i < l; i++) {\n    (function (packet) {\n      parser.encodePacket(packet, self.supportsBinary, function (data) {\n        if (!self.usingBrowserWebSocket) {\n          // always create a new object (GH-437)\n          var opts = {};\n          if (packet.options) {\n            opts.compress = packet.options.compress;\n          }\n\n          if (self.perMessageDeflate) {\n            var len = 'string' === typeof data ? global.Buffer.byteLength(data) : data.length;\n            if (len < self.perMessageDeflate.threshold) {\n              opts.compress = false;\n            }\n          }\n        }\n\n        // Sometimes the websocket has already been closed but the browser didn't\n        // have a chance of informing us about it yet, in that case send will\n        // throw an error\n        try {\n          if (self.usingBrowserWebSocket) {\n            // TypeError is thrown when passing the second argument on Safari\n            self.ws.send(data);\n          } else {\n            self.ws.send(data, opts);\n          }\n        } catch (e) {\n          debug('websocket closed before onclose event');\n        }\n\n        --total || done();\n      });\n    })(packets[i]);\n  }\n\n  function done () {\n    self.emit('flush');\n\n    // fake drain\n    // defer to next tick to allow Socket to clear writeBuffer\n    setTimeout(function () {\n      self.writable = true;\n      self.emit('drain');\n    }, 0);\n  }\n};\n\n/**\n * Called upon close\n *\n * @api private\n */\n\nWS.prototype.onClose = function () {\n  Transport.prototype.onClose.call(this);\n};\n\n/**\n * Closes socket.\n *\n * @api private\n */\n\nWS.prototype.doClose = function () {\n  if (typeof this.ws !== 'undefined') {\n    this.ws.close();\n  }\n};\n\n/**\n * Generates uri for connection.\n *\n * @api private\n */\n\nWS.prototype.uri = function () {\n  var query = this.query || {};\n  var schema = this.secure ? 'wss' : 'ws';\n  var port = '';\n\n  // avoid port if default for schema\n  if (this.port && (('wss' === schema && Number(this.port) !== 443) ||\n    ('ws' === schema && Number(this.port) !== 80))) {\n    port = ':' + this.port;\n  }\n\n  // append timestamp to URI\n  if (this.timestampRequests) {\n    query[this.timestampParam] = yeast();\n  }\n\n  // communicate binary support capabilities\n  if (!this.supportsBinary) {\n    query.b64 = 1;\n  }\n\n  query = parseqs.encode(query);\n\n  // prepend ? to query\n  if (query.length) {\n    query = '?' + query;\n  }\n\n  var ipv6 = this.hostname.indexOf(':') !== -1;\n  return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;\n};\n\n/**\n * Feature detection for WebSocket.\n *\n * @return {Boolean} whether this transport is available.\n * @api public\n */\n\nWS.prototype.check = function () {\n  return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNmIyMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy93ZWJzb2NrZXQuanM/ZGI4MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIFRyYW5zcG9ydCA9IHJlcXVpcmUoJy4uL3RyYW5zcG9ydCcpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBwYXJzZXFzID0gcmVxdWlyZSgncGFyc2VxcycpO1xudmFyIGluaGVyaXQgPSByZXF1aXJlKCdjb21wb25lbnQtaW5oZXJpdCcpO1xudmFyIHllYXN0ID0gcmVxdWlyZSgneWVhc3QnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ2VuZ2luZS5pby1jbGllbnQ6d2Vic29ja2V0Jyk7XG52YXIgQnJvd3NlcldlYlNvY2tldCA9IGdsb2JhbC5XZWJTb2NrZXQgfHwgZ2xvYmFsLk1veldlYlNvY2tldDtcbnZhciBOb2RlV2ViU29ja2V0O1xuaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gIHRyeSB7XG4gICAgTm9kZVdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG4gIH0gY2F0Y2ggKGUpIHsgfVxufVxuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxudmFyIFdlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQ7XG5pZiAoIVdlYlNvY2tldCAmJiB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICBXZWJTb2NrZXQgPSBOb2RlV2ViU29ja2V0O1xufVxuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gV1M7XG5cbi8qKlxuICogV2ViU29ja2V0IHRyYW5zcG9ydCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHtPYmplY3R9IGNvbm5lY3Rpb24gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBXUyAob3B0cykge1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIHRoaXMucGVyTWVzc2FnZURlZmxhdGUgPSBvcHRzLnBlck1lc3NhZ2VEZWZsYXRlO1xuICB0aGlzLnVzaW5nQnJvd3NlcldlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQgJiYgIW9wdHMuZm9yY2VOb2RlO1xuICBpZiAoIXRoaXMudXNpbmdCcm93c2VyV2ViU29ja2V0KSB7XG4gICAgV2ViU29ja2V0ID0gTm9kZVdlYlNvY2tldDtcbiAgfVxuICBUcmFuc3BvcnQuY2FsbCh0aGlzLCBvcHRzKTtcbn1cblxuLyoqXG4gKiBJbmhlcml0cyBmcm9tIFRyYW5zcG9ydC5cbiAqL1xuXG5pbmhlcml0KFdTLCBUcmFuc3BvcnQpO1xuXG4vKipcbiAqIFRyYW5zcG9ydCBuYW1lLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuV1MucHJvdG90eXBlLm5hbWUgPSAnd2Vic29ja2V0JztcblxuLypcbiAqIFdlYlNvY2tldHMgc3VwcG9ydCBiaW5hcnlcbiAqL1xuXG5XUy5wcm90b3R5cGUuc3VwcG9ydHNCaW5hcnkgPSB0cnVlO1xuXG4vKipcbiAqIE9wZW5zIHNvY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5XUy5wcm90b3R5cGUuZG9PcGVuID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuY2hlY2soKSkge1xuICAgIC8vIGxldCBwcm9iZSB0aW1lb3V0XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHVyaSA9IHRoaXMudXJpKCk7XG4gIHZhciBwcm90b2NvbHMgPSB2b2lkICgwKTtcbiAgdmFyIG9wdHMgPSB7XG4gICAgYWdlbnQ6IHRoaXMuYWdlbnQsXG4gICAgcGVyTWVzc2FnZURlZmxhdGU6IHRoaXMucGVyTWVzc2FnZURlZmxhdGVcbiAgfTtcblxuICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgb3B0cy5wZnggPSB0aGlzLnBmeDtcbiAgb3B0cy5rZXkgPSB0aGlzLmtleTtcbiAgb3B0cy5wYXNzcGhyYXNlID0gdGhpcy5wYXNzcGhyYXNlO1xuICBvcHRzLmNlcnQgPSB0aGlzLmNlcnQ7XG4gIG9wdHMuY2EgPSB0aGlzLmNhO1xuICBvcHRzLmNpcGhlcnMgPSB0aGlzLmNpcGhlcnM7XG4gIG9wdHMucmVqZWN0VW5hdXRob3JpemVkID0gdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQ7XG4gIGlmICh0aGlzLmV4dHJhSGVhZGVycykge1xuICAgIG9wdHMuaGVhZGVycyA9IHRoaXMuZXh0cmFIZWFkZXJzO1xuICB9XG4gIGlmICh0aGlzLmxvY2FsQWRkcmVzcykge1xuICAgIG9wdHMubG9jYWxBZGRyZXNzID0gdGhpcy5sb2NhbEFkZHJlc3M7XG4gIH1cblxuICB0cnkge1xuICAgIHRoaXMud3MgPSB0aGlzLnVzaW5nQnJvd3NlcldlYlNvY2tldCA/IG5ldyBXZWJTb2NrZXQodXJpKSA6IG5ldyBXZWJTb2NrZXQodXJpLCBwcm90b2NvbHMsIG9wdHMpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gIH1cblxuICBpZiAodGhpcy53cy5iaW5hcnlUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG4gIH1cblxuICBpZiAodGhpcy53cy5zdXBwb3J0cyAmJiB0aGlzLndzLnN1cHBvcnRzLmJpbmFyeSkge1xuICAgIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSB0cnVlO1xuICAgIHRoaXMud3MuYmluYXJ5VHlwZSA9ICdub2RlYnVmZmVyJztcbiAgfSBlbHNlIHtcbiAgICB0aGlzLndzLmJpbmFyeVR5cGUgPSAnYXJyYXlidWZmZXInO1xuICB9XG5cbiAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xufTtcblxuLyoqXG4gKiBBZGRzIGV2ZW50IGxpc3RlbmVycyB0byB0aGUgc29ja2V0XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXJzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy53cy5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5vbk9wZW4oKTtcbiAgfTtcbiAgdGhpcy53cy5vbmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgIHNlbGYub25DbG9zZSgpO1xuICB9O1xuICB0aGlzLndzLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChldikge1xuICAgIHNlbGYub25EYXRhKGV2LmRhdGEpO1xuICB9O1xuICB0aGlzLndzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZSkge1xuICAgIHNlbGYub25FcnJvcignd2Vic29ja2V0IGVycm9yJywgZSk7XG4gIH07XG59O1xuXG4vKipcbiAqIFdyaXRlcyBkYXRhIHRvIHNvY2tldC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBvZiBwYWNrZXRzLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKHBhY2tldHMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG5cbiAgLy8gZW5jb2RlUGFja2V0IGVmZmljaWVudCBhcyBpdCB1c2VzIFdTIGZyYW1pbmdcbiAgLy8gbm8gbmVlZCBmb3IgZW5jb2RlUGF5bG9hZFxuICB2YXIgdG90YWwgPSBwYWNrZXRzLmxlbmd0aDtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB0b3RhbDsgaSA8IGw7IGkrKykge1xuICAgIChmdW5jdGlvbiAocGFja2V0KSB7XG4gICAgICBwYXJzZXIuZW5jb2RlUGFja2V0KHBhY2tldCwgc2VsZi5zdXBwb3J0c0JpbmFyeSwgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgaWYgKCFzZWxmLnVzaW5nQnJvd3NlcldlYlNvY2tldCkge1xuICAgICAgICAgIC8vIGFsd2F5cyBjcmVhdGUgYSBuZXcgb2JqZWN0IChHSC00MzcpXG4gICAgICAgICAgdmFyIG9wdHMgPSB7fTtcbiAgICAgICAgICBpZiAocGFja2V0Lm9wdGlvbnMpIHtcbiAgICAgICAgICAgIG9wdHMuY29tcHJlc3MgPSBwYWNrZXQub3B0aW9ucy5jb21wcmVzcztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc2VsZi5wZXJNZXNzYWdlRGVmbGF0ZSkge1xuICAgICAgICAgICAgdmFyIGxlbiA9ICdzdHJpbmcnID09PSB0eXBlb2YgZGF0YSA/IGdsb2JhbC5CdWZmZXIuYnl0ZUxlbmd0aChkYXRhKSA6IGRhdGEubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKGxlbiA8IHNlbGYucGVyTWVzc2FnZURlZmxhdGUudGhyZXNob2xkKSB7XG4gICAgICAgICAgICAgIG9wdHMuY29tcHJlc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTb21ldGltZXMgdGhlIHdlYnNvY2tldCBoYXMgYWxyZWFkeSBiZWVuIGNsb3NlZCBidXQgdGhlIGJyb3dzZXIgZGlkbid0XG4gICAgICAgIC8vIGhhdmUgYSBjaGFuY2Ugb2YgaW5mb3JtaW5nIHVzIGFib3V0IGl0IHlldCwgaW4gdGhhdCBjYXNlIHNlbmQgd2lsbFxuICAgICAgICAvLyB0aHJvdyBhbiBlcnJvclxuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChzZWxmLnVzaW5nQnJvd3NlcldlYlNvY2tldCkge1xuICAgICAgICAgICAgLy8gVHlwZUVycm9yIGlzIHRocm93biB3aGVuIHBhc3NpbmcgdGhlIHNlY29uZCBhcmd1bWVudCBvbiBTYWZhcmlcbiAgICAgICAgICAgIHNlbGYud3Muc2VuZChkYXRhKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi53cy5zZW5kKGRhdGEsIG9wdHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGRlYnVnKCd3ZWJzb2NrZXQgY2xvc2VkIGJlZm9yZSBvbmNsb3NlIGV2ZW50Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAtLXRvdGFsIHx8IGRvbmUoKTtcbiAgICAgIH0pO1xuICAgIH0pKHBhY2tldHNbaV0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZG9uZSAoKSB7XG4gICAgc2VsZi5lbWl0KCdmbHVzaCcpO1xuXG4gICAgLy8gZmFrZSBkcmFpblxuICAgIC8vIGRlZmVyIHRvIG5leHQgdGljayB0byBhbGxvdyBTb2NrZXQgdG8gY2xlYXIgd3JpdGVCdWZmZXJcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYud3JpdGFibGUgPSB0cnVlO1xuICAgICAgc2VsZi5lbWl0KCdkcmFpbicpO1xuICAgIH0sIDApO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGNsb3NlXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLm9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIFRyYW5zcG9ydC5wcm90b3R5cGUub25DbG9zZS5jYWxsKHRoaXMpO1xufTtcblxuLyoqXG4gKiBDbG9zZXMgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbldTLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIHRoaXMud3MgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhpcy53cy5jbG9zZSgpO1xuICB9XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyB1cmkgZm9yIGNvbm5lY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLnVyaSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHF1ZXJ5ID0gdGhpcy5xdWVyeSB8fCB7fTtcbiAgdmFyIHNjaGVtYSA9IHRoaXMuc2VjdXJlID8gJ3dzcycgOiAnd3MnO1xuICB2YXIgcG9ydCA9ICcnO1xuXG4gIC8vIGF2b2lkIHBvcnQgaWYgZGVmYXVsdCBmb3Igc2NoZW1hXG4gIGlmICh0aGlzLnBvcnQgJiYgKCgnd3NzJyA9PT0gc2NoZW1hICYmIE51bWJlcih0aGlzLnBvcnQpICE9PSA0NDMpIHx8XG4gICAgKCd3cycgPT09IHNjaGVtYSAmJiBOdW1iZXIodGhpcy5wb3J0KSAhPT0gODApKSkge1xuICAgIHBvcnQgPSAnOicgKyB0aGlzLnBvcnQ7XG4gIH1cblxuICAvLyBhcHBlbmQgdGltZXN0YW1wIHRvIFVSSVxuICBpZiAodGhpcy50aW1lc3RhbXBSZXF1ZXN0cykge1xuICAgIHF1ZXJ5W3RoaXMudGltZXN0YW1wUGFyYW1dID0geWVhc3QoKTtcbiAgfVxuXG4gIC8vIGNvbW11bmljYXRlIGJpbmFyeSBzdXBwb3J0IGNhcGFiaWxpdGllc1xuICBpZiAoIXRoaXMuc3VwcG9ydHNCaW5hcnkpIHtcbiAgICBxdWVyeS5iNjQgPSAxO1xuICB9XG5cbiAgcXVlcnkgPSBwYXJzZXFzLmVuY29kZShxdWVyeSk7XG5cbiAgLy8gcHJlcGVuZCA/IHRvIHF1ZXJ5XG4gIGlmIChxdWVyeS5sZW5ndGgpIHtcbiAgICBxdWVyeSA9ICc/JyArIHF1ZXJ5O1xuICB9XG5cbiAgdmFyIGlwdjYgPSB0aGlzLmhvc3RuYW1lLmluZGV4T2YoJzonKSAhPT0gLTE7XG4gIHJldHVybiBzY2hlbWEgKyAnOi8vJyArIChpcHY2ID8gJ1snICsgdGhpcy5ob3N0bmFtZSArICddJyA6IHRoaXMuaG9zdG5hbWUpICsgcG9ydCArIHRoaXMucGF0aCArIHF1ZXJ5O1xufTtcblxuLyoqXG4gKiBGZWF0dXJlIGRldGVjdGlvbiBmb3IgV2ViU29ja2V0LlxuICpcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHdoZXRoZXIgdGhpcyB0cmFuc3BvcnQgaXMgYXZhaWxhYmxlLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5XUy5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhIVdlYlNvY2tldCAmJiAhKCdfX2luaXRpYWxpemUnIGluIFdlYlNvY2tldCAmJiB0aGlzLm5hbWUgPT09IFdTLnByb3RvdHlwZS5uYW1lKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6b20\n")},"6fba":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar debug = __webpack_require__(/*! debug */ \"8233\")('socket.io-parser');\nvar json = __webpack_require__(/*! json3 */ \"3b17\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"636d\");\nvar binary = __webpack_require__(/*! ./binary */ \"ea82\");\nvar isBuf = __webpack_require__(/*! ./is-buffer */ \"419b\");\n\n/**\n * Protocol version.\n *\n * @api public\n */\n\nexports.protocol = 4;\n\n/**\n * Packet types.\n *\n * @api public\n */\n\nexports.types = [\n  'CONNECT',\n  'DISCONNECT',\n  'EVENT',\n  'ACK',\n  'ERROR',\n  'BINARY_EVENT',\n  'BINARY_ACK'\n];\n\n/**\n * Packet type `connect`.\n *\n * @api public\n */\n\nexports.CONNECT = 0;\n\n/**\n * Packet type `disconnect`.\n *\n * @api public\n */\n\nexports.DISCONNECT = 1;\n\n/**\n * Packet type `event`.\n *\n * @api public\n */\n\nexports.EVENT = 2;\n\n/**\n * Packet type `ack`.\n *\n * @api public\n */\n\nexports.ACK = 3;\n\n/**\n * Packet type `error`.\n *\n * @api public\n */\n\nexports.ERROR = 4;\n\n/**\n * Packet type 'binary event'\n *\n * @api public\n */\n\nexports.BINARY_EVENT = 5;\n\n/**\n * Packet type `binary ack`. For acks with binary arguments.\n *\n * @api public\n */\n\nexports.BINARY_ACK = 6;\n\n/**\n * Encoder constructor.\n *\n * @api public\n */\n\nexports.Encoder = Encoder;\n\n/**\n * Decoder constructor.\n *\n * @api public\n */\n\nexports.Decoder = Decoder;\n\n/**\n * A socket.io Encoder instance\n *\n * @api public\n */\n\nfunction Encoder() {}\n\n/**\n * Encode a packet as a single string if non-binary, or as a\n * buffer sequence, depending on packet type.\n *\n * @param {Object} obj - packet object\n * @param {Function} callback - function to handle encodings (likely engine.write)\n * @return Calls callback with Array of encodings\n * @api public\n */\n\nEncoder.prototype.encode = function(obj, callback){\n  debug('encoding packet %j', obj);\n\n  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n    encodeAsBinary(obj, callback);\n  }\n  else {\n    var encoding = encodeAsString(obj);\n    callback([encoding]);\n  }\n};\n\n/**\n * Encode packet as string.\n *\n * @param {Object} packet\n * @return {String} encoded\n * @api private\n */\n\nfunction encodeAsString(obj) {\n  var str = '';\n  var nsp = false;\n\n  // first is type\n  str += obj.type;\n\n  // attachments if we have them\n  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n    str += obj.attachments;\n    str += '-';\n  }\n\n  // if we have a namespace other than `/`\n  // we append it followed by a comma `,`\n  if (obj.nsp && '/' != obj.nsp) {\n    nsp = true;\n    str += obj.nsp;\n  }\n\n  // immediately followed by the id\n  if (null != obj.id) {\n    if (nsp) {\n      str += ',';\n      nsp = false;\n    }\n    str += obj.id;\n  }\n\n  // json data\n  if (null != obj.data) {\n    if (nsp) str += ',';\n    str += json.stringify(obj.data);\n  }\n\n  debug('encoded %j as %s', obj, str);\n  return str;\n}\n\n/**\n * Encode packet as 'buffer sequence' by removing blobs, and\n * deconstructing packet into object with placeholders and\n * a list of buffers.\n *\n * @param {Object} packet\n * @return {Buffer} encoded\n * @api private\n */\n\nfunction encodeAsBinary(obj, callback) {\n\n  function writeEncoding(bloblessData) {\n    var deconstruction = binary.deconstructPacket(bloblessData);\n    var pack = encodeAsString(deconstruction.packet);\n    var buffers = deconstruction.buffers;\n\n    buffers.unshift(pack); // add packet info to beginning of data list\n    callback(buffers); // write all the buffers\n  }\n\n  binary.removeBlobs(obj, writeEncoding);\n}\n\n/**\n * A socket.io Decoder instance\n *\n * @return {Object} decoder\n * @api public\n */\n\nfunction Decoder() {\n  this.reconstructor = null;\n}\n\n/**\n * Mix in `Emitter` with Decoder.\n */\n\nEmitter(Decoder.prototype);\n\n/**\n * Decodes an ecoded packet string into packet JSON.\n *\n * @param {String} obj - encoded packet\n * @return {Object} packet\n * @api public\n */\n\nDecoder.prototype.add = function(obj) {\n  var packet;\n  if ('string' == typeof obj) {\n    packet = decodeString(obj);\n    if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) { // binary packet's json\n      this.reconstructor = new BinaryReconstructor(packet);\n\n      // no attachments, labeled binary but no binary data to follow\n      if (this.reconstructor.reconPack.attachments === 0) {\n        this.emit('decoded', packet);\n      }\n    } else { // non-binary full packet\n      this.emit('decoded', packet);\n    }\n  }\n  else if (isBuf(obj) || obj.base64) { // raw binary data\n    if (!this.reconstructor) {\n      throw new Error('got binary data when not reconstructing a packet');\n    } else {\n      packet = this.reconstructor.takeBinaryData(obj);\n      if (packet) { // received final buffer\n        this.reconstructor = null;\n        this.emit('decoded', packet);\n      }\n    }\n  }\n  else {\n    throw new Error('Unknown type: ' + obj);\n  }\n};\n\n/**\n * Decode a packet String (JSON data)\n *\n * @param {String} str\n * @return {Object} packet\n * @api private\n */\n\nfunction decodeString(str) {\n  var p = {};\n  var i = 0;\n\n  // look up type\n  p.type = Number(str.charAt(0));\n  if (null == exports.types[p.type]) return error();\n\n  // look up attachments if type binary\n  if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) {\n    var buf = '';\n    while (str.charAt(++i) != '-') {\n      buf += str.charAt(i);\n      if (i == str.length) break;\n    }\n    if (buf != Number(buf) || str.charAt(i) != '-') {\n      throw new Error('Illegal attachments');\n    }\n    p.attachments = Number(buf);\n  }\n\n  // look up namespace (if any)\n  if ('/' == str.charAt(i + 1)) {\n    p.nsp = '';\n    while (++i) {\n      var c = str.charAt(i);\n      if (',' == c) break;\n      p.nsp += c;\n      if (i == str.length) break;\n    }\n  } else {\n    p.nsp = '/';\n  }\n\n  // look up id\n  var next = str.charAt(i + 1);\n  if ('' !== next && Number(next) == next) {\n    p.id = '';\n    while (++i) {\n      var c = str.charAt(i);\n      if (null == c || Number(c) != c) {\n        --i;\n        break;\n      }\n      p.id += str.charAt(i);\n      if (i == str.length) break;\n    }\n    p.id = Number(p.id);\n  }\n\n  // look up json data\n  if (str.charAt(++i)) {\n    p = tryParse(p, str.substr(i));\n  }\n\n  debug('decoded %s as %j', str, p);\n  return p;\n}\n\nfunction tryParse(p, str) {\n  try {\n    p.data = json.parse(str);\n  } catch(e){\n    return error();\n  }\n  return p; \n};\n\n/**\n * Deallocates a parser's resources\n *\n * @api public\n */\n\nDecoder.prototype.destroy = function() {\n  if (this.reconstructor) {\n    this.reconstructor.finishedReconstruction();\n  }\n};\n\n/**\n * A manager of a binary event's 'buffer sequence'. Should\n * be constructed whenever a packet of type BINARY_EVENT is\n * decoded.\n *\n * @param {Object} packet\n * @return {BinaryReconstructor} initialized reconstructor\n * @api private\n */\n\nfunction BinaryReconstructor(packet) {\n  this.reconPack = packet;\n  this.buffers = [];\n}\n\n/**\n * Method to be called when binary data received from connection\n * after a BINARY_EVENT packet.\n *\n * @param {Buffer | ArrayBuffer} binData - the raw binary data received\n * @return {null | Object} returns null if more binary data is expected or\n *   a reconstructed packet object if all buffers have been received.\n * @api private\n */\n\nBinaryReconstructor.prototype.takeBinaryData = function(binData) {\n  this.buffers.push(binData);\n  if (this.buffers.length == this.reconPack.attachments) { // done with buffer list\n    var packet = binary.reconstructPacket(this.reconPack, this.buffers);\n    this.finishedReconstruction();\n    return packet;\n  }\n  return null;\n};\n\n/**\n * Cleans up binary packet reconstruction variables.\n *\n * @api private\n */\n\nBinaryReconstructor.prototype.finishedReconstruction = function() {\n  this.reconPack = null;\n  this.buffers = [];\n};\n\nfunction error(data){\n  return {\n    type: exports.ERROR,\n    data: 'parser error'\n  };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNmZiYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9pbmRleC5qcz84ZjQzIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBqc29uID0gcmVxdWlyZSgnanNvbjMnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciBiaW5hcnkgPSByZXF1aXJlKCcuL2JpbmFyeScpO1xudmFyIGlzQnVmID0gcmVxdWlyZSgnLi9pcy1idWZmZXInKTtcblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5wcm90b2NvbCA9IDQ7XG5cbi8qKlxuICogUGFja2V0IHR5cGVzLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy50eXBlcyA9IFtcbiAgJ0NPTk5FQ1QnLFxuICAnRElTQ09OTkVDVCcsXG4gICdFVkVOVCcsXG4gICdBQ0snLFxuICAnRVJST1InLFxuICAnQklOQVJZX0VWRU5UJyxcbiAgJ0JJTkFSWV9BQ0snXG5dO1xuXG4vKipcbiAqIFBhY2tldCB0eXBlIGBjb25uZWN0YC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuQ09OTkVDVCA9IDA7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGRpc2Nvbm5lY3RgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5ESVNDT05ORUNUID0gMTtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgZXZlbnRgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5FVkVOVCA9IDI7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGFja2AuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkFDSyA9IDM7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGVycm9yYC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuRVJST1IgPSA0O1xuXG4vKipcbiAqIFBhY2tldCB0eXBlICdiaW5hcnkgZXZlbnQnXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkJJTkFSWV9FVkVOVCA9IDU7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGJpbmFyeSBhY2tgLiBGb3IgYWNrcyB3aXRoIGJpbmFyeSBhcmd1bWVudHMuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkJJTkFSWV9BQ0sgPSA2O1xuXG4vKipcbiAqIEVuY29kZXIgY29uc3RydWN0b3IuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkVuY29kZXIgPSBFbmNvZGVyO1xuXG4vKipcbiAqIERlY29kZXIgY29uc3RydWN0b3IuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkRlY29kZXIgPSBEZWNvZGVyO1xuXG4vKipcbiAqIEEgc29ja2V0LmlvIEVuY29kZXIgaW5zdGFuY2VcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIEVuY29kZXIoKSB7fVxuXG4vKipcbiAqIEVuY29kZSBhIHBhY2tldCBhcyBhIHNpbmdsZSBzdHJpbmcgaWYgbm9uLWJpbmFyeSwgb3IgYXMgYVxuICogYnVmZmVyIHNlcXVlbmNlLCBkZXBlbmRpbmcgb24gcGFja2V0IHR5cGUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiAtIHBhY2tldCBvYmplY3RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIC0gZnVuY3Rpb24gdG8gaGFuZGxlIGVuY29kaW5ncyAobGlrZWx5IGVuZ2luZS53cml0ZSlcbiAqIEByZXR1cm4gQ2FsbHMgY2FsbGJhY2sgd2l0aCBBcnJheSBvZiBlbmNvZGluZ3NcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW5jb2Rlci5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24ob2JqLCBjYWxsYmFjayl7XG4gIGRlYnVnKCdlbmNvZGluZyBwYWNrZXQgJWonLCBvYmopO1xuXG4gIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBvYmoudHlwZSB8fCBleHBvcnRzLkJJTkFSWV9BQ0sgPT0gb2JqLnR5cGUpIHtcbiAgICBlbmNvZGVBc0JpbmFyeShvYmosIGNhbGxiYWNrKTtcbiAgfVxuICBlbHNlIHtcbiAgICB2YXIgZW5jb2RpbmcgPSBlbmNvZGVBc1N0cmluZyhvYmopO1xuICAgIGNhbGxiYWNrKFtlbmNvZGluZ10pO1xuICB9XG59O1xuXG4vKipcbiAqIEVuY29kZSBwYWNrZXQgYXMgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEByZXR1cm4ge1N0cmluZ30gZW5jb2RlZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gZW5jb2RlQXNTdHJpbmcob2JqKSB7XG4gIHZhciBzdHIgPSAnJztcbiAgdmFyIG5zcCA9IGZhbHNlO1xuXG4gIC8vIGZpcnN0IGlzIHR5cGVcbiAgc3RyICs9IG9iai50eXBlO1xuXG4gIC8vIGF0dGFjaG1lbnRzIGlmIHdlIGhhdmUgdGhlbVxuICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gb2JqLnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IG9iai50eXBlKSB7XG4gICAgc3RyICs9IG9iai5hdHRhY2htZW50cztcbiAgICBzdHIgKz0gJy0nO1xuICB9XG5cbiAgLy8gaWYgd2UgaGF2ZSBhIG5hbWVzcGFjZSBvdGhlciB0aGFuIGAvYFxuICAvLyB3ZSBhcHBlbmQgaXQgZm9sbG93ZWQgYnkgYSBjb21tYSBgLGBcbiAgaWYgKG9iai5uc3AgJiYgJy8nICE9IG9iai5uc3ApIHtcbiAgICBuc3AgPSB0cnVlO1xuICAgIHN0ciArPSBvYmoubnNwO1xuICB9XG5cbiAgLy8gaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgdGhlIGlkXG4gIGlmIChudWxsICE9IG9iai5pZCkge1xuICAgIGlmIChuc3ApIHtcbiAgICAgIHN0ciArPSAnLCc7XG4gICAgICBuc3AgPSBmYWxzZTtcbiAgICB9XG4gICAgc3RyICs9IG9iai5pZDtcbiAgfVxuXG4gIC8vIGpzb24gZGF0YVxuICBpZiAobnVsbCAhPSBvYmouZGF0YSkge1xuICAgIGlmIChuc3ApIHN0ciArPSAnLCc7XG4gICAgc3RyICs9IGpzb24uc3RyaW5naWZ5KG9iai5kYXRhKTtcbiAgfVxuXG4gIGRlYnVnKCdlbmNvZGVkICVqIGFzICVzJywgb2JqLCBzdHIpO1xuICByZXR1cm4gc3RyO1xufVxuXG4vKipcbiAqIEVuY29kZSBwYWNrZXQgYXMgJ2J1ZmZlciBzZXF1ZW5jZScgYnkgcmVtb3ZpbmcgYmxvYnMsIGFuZFxuICogZGVjb25zdHJ1Y3RpbmcgcGFja2V0IGludG8gb2JqZWN0IHdpdGggcGxhY2Vob2xkZXJzIGFuZFxuICogYSBsaXN0IG9mIGJ1ZmZlcnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQHJldHVybiB7QnVmZmVyfSBlbmNvZGVkXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBlbmNvZGVBc0JpbmFyeShvYmosIGNhbGxiYWNrKSB7XG5cbiAgZnVuY3Rpb24gd3JpdGVFbmNvZGluZyhibG9ibGVzc0RhdGEpIHtcbiAgICB2YXIgZGVjb25zdHJ1Y3Rpb24gPSBiaW5hcnkuZGVjb25zdHJ1Y3RQYWNrZXQoYmxvYmxlc3NEYXRhKTtcbiAgICB2YXIgcGFjayA9IGVuY29kZUFzU3RyaW5nKGRlY29uc3RydWN0aW9uLnBhY2tldCk7XG4gICAgdmFyIGJ1ZmZlcnMgPSBkZWNvbnN0cnVjdGlvbi5idWZmZXJzO1xuXG4gICAgYnVmZmVycy51bnNoaWZ0KHBhY2spOyAvLyBhZGQgcGFja2V0IGluZm8gdG8gYmVnaW5uaW5nIG9mIGRhdGEgbGlzdFxuICAgIGNhbGxiYWNrKGJ1ZmZlcnMpOyAvLyB3cml0ZSBhbGwgdGhlIGJ1ZmZlcnNcbiAgfVxuXG4gIGJpbmFyeS5yZW1vdmVCbG9icyhvYmosIHdyaXRlRW5jb2RpbmcpO1xufVxuXG4vKipcbiAqIEEgc29ja2V0LmlvIERlY29kZXIgaW5zdGFuY2VcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGRlY29kZXJcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRGVjb2RlcigpIHtcbiAgdGhpcy5yZWNvbnN0cnVjdG9yID0gbnVsbDtcbn1cblxuLyoqXG4gKiBNaXggaW4gYEVtaXR0ZXJgIHdpdGggRGVjb2Rlci5cbiAqL1xuXG5FbWl0dGVyKERlY29kZXIucHJvdG90eXBlKTtcblxuLyoqXG4gKiBEZWNvZGVzIGFuIGVjb2RlZCBwYWNrZXQgc3RyaW5nIGludG8gcGFja2V0IEpTT04uXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG9iaiAtIGVuY29kZWQgcGFja2V0XG4gKiBAcmV0dXJuIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5EZWNvZGVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbihvYmopIHtcbiAgdmFyIHBhY2tldDtcbiAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBvYmopIHtcbiAgICBwYWNrZXQgPSBkZWNvZGVTdHJpbmcob2JqKTtcbiAgICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gcGFja2V0LnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IHBhY2tldC50eXBlKSB7IC8vIGJpbmFyeSBwYWNrZXQncyBqc29uXG4gICAgICB0aGlzLnJlY29uc3RydWN0b3IgPSBuZXcgQmluYXJ5UmVjb25zdHJ1Y3RvcihwYWNrZXQpO1xuXG4gICAgICAvLyBubyBhdHRhY2htZW50cywgbGFiZWxlZCBiaW5hcnkgYnV0IG5vIGJpbmFyeSBkYXRhIHRvIGZvbGxvd1xuICAgICAgaWYgKHRoaXMucmVjb25zdHJ1Y3Rvci5yZWNvblBhY2suYXR0YWNobWVudHMgPT09IDApIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkZWNvZGVkJywgcGFja2V0KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgeyAvLyBub24tYmluYXJ5IGZ1bGwgcGFja2V0XG4gICAgICB0aGlzLmVtaXQoJ2RlY29kZWQnLCBwYWNrZXQpO1xuICAgIH1cbiAgfVxuICBlbHNlIGlmIChpc0J1ZihvYmopIHx8IG9iai5iYXNlNjQpIHsgLy8gcmF3IGJpbmFyeSBkYXRhXG4gICAgaWYgKCF0aGlzLnJlY29uc3RydWN0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ290IGJpbmFyeSBkYXRhIHdoZW4gbm90IHJlY29uc3RydWN0aW5nIGEgcGFja2V0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhY2tldCA9IHRoaXMucmVjb25zdHJ1Y3Rvci50YWtlQmluYXJ5RGF0YShvYmopO1xuICAgICAgaWYgKHBhY2tldCkgeyAvLyByZWNlaXZlZCBmaW5hbCBidWZmZXJcbiAgICAgICAgdGhpcy5yZWNvbnN0cnVjdG9yID0gbnVsbDtcbiAgICAgICAgdGhpcy5lbWl0KCdkZWNvZGVkJywgcGFja2V0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHR5cGU6ICcgKyBvYmopO1xuICB9XG59O1xuXG4vKipcbiAqIERlY29kZSBhIHBhY2tldCBTdHJpbmcgKEpTT04gZGF0YSlcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gZGVjb2RlU3RyaW5nKHN0cikge1xuICB2YXIgcCA9IHt9O1xuICB2YXIgaSA9IDA7XG5cbiAgLy8gbG9vayB1cCB0eXBlXG4gIHAudHlwZSA9IE51bWJlcihzdHIuY2hhckF0KDApKTtcbiAgaWYgKG51bGwgPT0gZXhwb3J0cy50eXBlc1twLnR5cGVdKSByZXR1cm4gZXJyb3IoKTtcblxuICAvLyBsb29rIHVwIGF0dGFjaG1lbnRzIGlmIHR5cGUgYmluYXJ5XG4gIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBwLnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IHAudHlwZSkge1xuICAgIHZhciBidWYgPSAnJztcbiAgICB3aGlsZSAoc3RyLmNoYXJBdCgrK2kpICE9ICctJykge1xuICAgICAgYnVmICs9IHN0ci5jaGFyQXQoaSk7XG4gICAgICBpZiAoaSA9PSBzdHIubGVuZ3RoKSBicmVhaztcbiAgICB9XG4gICAgaWYgKGJ1ZiAhPSBOdW1iZXIoYnVmKSB8fCBzdHIuY2hhckF0KGkpICE9ICctJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbGxlZ2FsIGF0dGFjaG1lbnRzJyk7XG4gICAgfVxuICAgIHAuYXR0YWNobWVudHMgPSBOdW1iZXIoYnVmKTtcbiAgfVxuXG4gIC8vIGxvb2sgdXAgbmFtZXNwYWNlIChpZiBhbnkpXG4gIGlmICgnLycgPT0gc3RyLmNoYXJBdChpICsgMSkpIHtcbiAgICBwLm5zcCA9ICcnO1xuICAgIHdoaWxlICgrK2kpIHtcbiAgICAgIHZhciBjID0gc3RyLmNoYXJBdChpKTtcbiAgICAgIGlmICgnLCcgPT0gYykgYnJlYWs7XG4gICAgICBwLm5zcCArPSBjO1xuICAgICAgaWYgKGkgPT0gc3RyLmxlbmd0aCkgYnJlYWs7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHAubnNwID0gJy8nO1xuICB9XG5cbiAgLy8gbG9vayB1cCBpZFxuICB2YXIgbmV4dCA9IHN0ci5jaGFyQXQoaSArIDEpO1xuICBpZiAoJycgIT09IG5leHQgJiYgTnVtYmVyKG5leHQpID09IG5leHQpIHtcbiAgICBwLmlkID0gJyc7XG4gICAgd2hpbGUgKCsraSkge1xuICAgICAgdmFyIGMgPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKG51bGwgPT0gYyB8fCBOdW1iZXIoYykgIT0gYykge1xuICAgICAgICAtLWk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgcC5pZCArPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKGkgPT0gc3RyLmxlbmd0aCkgYnJlYWs7XG4gICAgfVxuICAgIHAuaWQgPSBOdW1iZXIocC5pZCk7XG4gIH1cblxuICAvLyBsb29rIHVwIGpzb24gZGF0YVxuICBpZiAoc3RyLmNoYXJBdCgrK2kpKSB7XG4gICAgcCA9IHRyeVBhcnNlKHAsIHN0ci5zdWJzdHIoaSkpO1xuICB9XG5cbiAgZGVidWcoJ2RlY29kZWQgJXMgYXMgJWonLCBzdHIsIHApO1xuICByZXR1cm4gcDtcbn1cblxuZnVuY3Rpb24gdHJ5UGFyc2UocCwgc3RyKSB7XG4gIHRyeSB7XG4gICAgcC5kYXRhID0ganNvbi5wYXJzZShzdHIpO1xuICB9IGNhdGNoKGUpe1xuICAgIHJldHVybiBlcnJvcigpO1xuICB9XG4gIHJldHVybiBwOyBcbn07XG5cbi8qKlxuICogRGVhbGxvY2F0ZXMgYSBwYXJzZXIncyByZXNvdXJjZXNcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkRlY29kZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMucmVjb25zdHJ1Y3Rvcikge1xuICAgIHRoaXMucmVjb25zdHJ1Y3Rvci5maW5pc2hlZFJlY29uc3RydWN0aW9uKCk7XG4gIH1cbn07XG5cbi8qKlxuICogQSBtYW5hZ2VyIG9mIGEgYmluYXJ5IGV2ZW50J3MgJ2J1ZmZlciBzZXF1ZW5jZScuIFNob3VsZFxuICogYmUgY29uc3RydWN0ZWQgd2hlbmV2ZXIgYSBwYWNrZXQgb2YgdHlwZSBCSU5BUllfRVZFTlQgaXNcbiAqIGRlY29kZWQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQHJldHVybiB7QmluYXJ5UmVjb25zdHJ1Y3Rvcn0gaW5pdGlhbGl6ZWQgcmVjb25zdHJ1Y3RvclxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gQmluYXJ5UmVjb25zdHJ1Y3RvcihwYWNrZXQpIHtcbiAgdGhpcy5yZWNvblBhY2sgPSBwYWNrZXQ7XG4gIHRoaXMuYnVmZmVycyA9IFtdO1xufVxuXG4vKipcbiAqIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBiaW5hcnkgZGF0YSByZWNlaXZlZCBmcm9tIGNvbm5lY3Rpb25cbiAqIGFmdGVyIGEgQklOQVJZX0VWRU5UIHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge0J1ZmZlciB8IEFycmF5QnVmZmVyfSBiaW5EYXRhIC0gdGhlIHJhdyBiaW5hcnkgZGF0YSByZWNlaXZlZFxuICogQHJldHVybiB7bnVsbCB8IE9iamVjdH0gcmV0dXJucyBudWxsIGlmIG1vcmUgYmluYXJ5IGRhdGEgaXMgZXhwZWN0ZWQgb3JcbiAqICAgYSByZWNvbnN0cnVjdGVkIHBhY2tldCBvYmplY3QgaWYgYWxsIGJ1ZmZlcnMgaGF2ZSBiZWVuIHJlY2VpdmVkLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuQmluYXJ5UmVjb25zdHJ1Y3Rvci5wcm90b3R5cGUudGFrZUJpbmFyeURhdGEgPSBmdW5jdGlvbihiaW5EYXRhKSB7XG4gIHRoaXMuYnVmZmVycy5wdXNoKGJpbkRhdGEpO1xuICBpZiAodGhpcy5idWZmZXJzLmxlbmd0aCA9PSB0aGlzLnJlY29uUGFjay5hdHRhY2htZW50cykgeyAvLyBkb25lIHdpdGggYnVmZmVyIGxpc3RcbiAgICB2YXIgcGFja2V0ID0gYmluYXJ5LnJlY29uc3RydWN0UGFja2V0KHRoaXMucmVjb25QYWNrLCB0aGlzLmJ1ZmZlcnMpO1xuICAgIHRoaXMuZmluaXNoZWRSZWNvbnN0cnVjdGlvbigpO1xuICAgIHJldHVybiBwYWNrZXQ7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIENsZWFucyB1cCBiaW5hcnkgcGFja2V0IHJlY29uc3RydWN0aW9uIHZhcmlhYmxlcy5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5CaW5hcnlSZWNvbnN0cnVjdG9yLnByb3RvdHlwZS5maW5pc2hlZFJlY29uc3RydWN0aW9uID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMucmVjb25QYWNrID0gbnVsbDtcbiAgdGhpcy5idWZmZXJzID0gW107XG59O1xuXG5mdW5jdGlvbiBlcnJvcihkYXRhKXtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBleHBvcnRzLkVSUk9SLFxuICAgIGRhdGE6ICdwYXJzZXIgZXJyb3InXG4gIH07XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6fba\n")},"720c":function(module,exports,__webpack_require__){eval("/**\n * Client side filtering using crossfilter\n * Due to limitation of crossfilter with array (or data that has no natrual ordering), this will not work as expected:\n * * dimension: `function (d) {return [d.x, d.y, d.z]}`\n * * group: `function (d) {return [d.x / 10 , d.y / 10, d.z / 10]}`\n *\n * Therefore, we preform grouping already in the dimension itself, and join the array to a string.\n * Strings have a natural ordering and thus can be used as dimension value.\n * * dimension: `function (d) -> \"d.x/10|d.y/10|d.z/10\"`\n * * group: `function (d) {return d;}`\n *\n * @module driver/client\n */\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nvar utildx = __webpack_require__(/*! ../util/crossfilter */ \"adfa\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nvar grpIdxToName = {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'};\nvar aggRankToName = {1: 'aa', 2: 'bb', 3: 'cc', 4: 'dd', 5: 'ee'};\n\n/**\n * setMinMax sets the range of a continuous or time facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setMinMax (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var valFn = utildx.baseValueFn(facet);\n\n  // to be able to mark the value as missing we need it unprocessed, so rawValueFn\n  var rawValFn = utildx.rawValueFn(facet);\n\n  var lessFn;\n  var moreFn;\n  if (facet.isDatetime) {\n    lessFn = function (a, b) { return (b === misval || a.isBefore(b)); };\n    moreFn = function (a, b) { return (b === misval || b.isBefore(a)); };\n  } else {\n    lessFn = function (a, b) { return (b === misval || a < b); };\n    moreFn = function (a, b) { return (b === misval || a > b); };\n  }\n\n  var minval = misval;\n  var rawMin = misval;\n\n  var maxval = misval;\n  var rawMax = misval;\n\n  dataset.data.forEach(function (d) {\n    var rawV = rawValFn(d);\n    var v = valFn(d);\n\n    if (v !== misval) {\n      if (lessFn(v, minval)) {\n        minval = v;\n        rawMin = rawV;\n      }\n      if (moreFn(v, maxval)) {\n        maxval = v;\n        rawMax = rawV;\n      }\n    }\n  });\n\n  if (minval !== misval) {\n    if (facet.isContinuous) {\n      facet.minvalAsText = minval.toString();\n    } else if (facet.isDatetime) {\n      facet.minvalAsText = minval.toISOString();\n    } else if (facet.isDuration) {\n      facet.minvalAsText = minval.toISOString();\n    }\n    facet.rawMinval = rawMin;\n  } else {\n    facet.minvalAsText = '';\n    facet.rawMinval = misval;\n  }\n\n  if (maxval !== misval) {\n    if (facet.isContinuous) {\n      facet.maxvalAsText = maxval.toString();\n    } else if (facet.isDatetime) {\n      facet.maxvalAsText = maxval.toISOString();\n    } else if (facet.isDuration) {\n      facet.maxvalAsText = maxval.toISOString();\n    }\n    facet.rawMaxval = rawMax;\n  } else {\n    facet.maxvalAsText = '';\n    facet.rawMaxval = misval;\n  }\n}\n\n/**\n * setCategories finds finds all values on an ordinal (categorial) axis\n * Updates the categorialTransform of the facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setCategories (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var valFn = utildx.baseValueFn(facet);\n\n  var p = {};\n  var Plength = 0;\n  dataset.data.forEach(function (d, i) {\n    var vals = valFn(d);\n    if (vals instanceof Array) {\n      vals.forEach(function (val) {\n        if (p.hasOwnProperty(val)) {\n          p[val]++;\n        } else {\n          if (Plength < 75) { // NOTE: limit to maximally 75 categories\n            p[val] = 1;\n            Plength++;\n          }\n        }\n      });\n    } else {\n      if (p.hasOwnProperty(vals)) {\n        p[vals]++;\n      } else {\n        if (Plength < 75) { // NOTE: limit to maximally 75 categories\n          p[vals] = 1;\n          Plength++;\n        }\n      }\n    }\n  });\n\n  facet.categorialTransform.reset();\n\n  Object.keys(p).forEach(function (key) {\n    // TODO: missing data should be mapped to a misval from misvalAsText\n    var keyAsString = key.toString();\n    var groupAsString = keyAsString;\n\n    facet.categorialTransform.rules.add({expression: keyAsString, count: p[key], group: groupAsString});\n  });\n}\n\n/**\n * Calculate 100 percentiles (ie. 1,2,3,4 etc.), and initialize the `facet.continuousTransform`\n * to an approximate percentile mapping.\n * Use the recommended method from [NIST](http://www.itl.nist.gov/div898/handbook/prc/section2/prc262.htm)\n * See also the discussion on [Wikipedia](https://en.wikipedia.org/wiki/Percentile)\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setPercentiles (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var basevalueFn = utildx.baseValueFn(facet);\n  var data = dataset.data;\n\n  data.sort(function (a, b) {\n    var valA = basevalueFn(a);\n    var valB = basevalueFn(b);\n\n    if (valA === valB) {\n      return 0;\n    }\n    if (valA === misval) {\n      return -1;\n    }\n    if (valB === misval) {\n      return 1;\n    }\n\n    if (valA < valB) {\n      return -1;\n    } else {\n      return 1;\n    }\n  });\n\n  var tf = facet.continuousTransform;\n  var x, i;\n\n  // drop missing values, which should be sorted at the start of the array\n  i = 0;\n  while (basevalueFn(data[i]) === misval && i < data.length) {\n    i++;\n  }\n  data.splice(0, i);\n\n  // start clean\n  tf.reset();\n\n  // add minimum value as control points p0 and p1\n  tf.cps.add({x: basevalueFn(data[0]), fx: 0});\n  tf.cps.add({x: basevalueFn(data[0]), fx: 0});\n\n  var p, value;\n  for (p = 1; p < 100; p++) {\n    x = (p * 0.01) * (data.length + 1) - 1; // indexing starts at zero, not at one\n    i = Math.trunc(x);\n    value = (1 - x + i) * basevalueFn(data[i]) + (x - i) * basevalueFn(data[i + 1]);\n    tf.cps.add({x: value, fx: p});\n  }\n\n  // add maximum value as p101 and p102\n  tf.cps.add({x: basevalueFn(data[data.length - 1]), fx: 100});\n  tf.cps.add({x: basevalueFn(data[data.length - 1]), fx: 100});\n\n  tf.type = 'percentiles';\n}\n\n/**\n * Autoconfigure a dataset:\n * 1. pick 10 random elements\n * 2. create facets for their properties\n * 3. add facets' values over the sample to the facet.description\n * 4. set range or categories\n *\n * @param {Dataset} dataset\n */\nfunction scan (dataset) {\n  function facetExists (facets, path) {\n    var exists = false;\n    facets.forEach(function (f) {\n      if (f.accessor === path || f.accessor === path + '[]') {\n        exists = true;\n      }\n    });\n    return exists;\n  }\n\n  function addValue (values, v, missing) {\n    if (v === misval) {\n      v = missing;\n    }\n    if (values.indexOf(v) === -1) {\n      values.push(v);\n    }\n  }\n\n  function guessType (values) {\n    var mytype = {\n      continuous: 0,\n      text: 0,\n      datetime: 0,\n      duration: 0,\n      categorial: 0\n    };\n    values.forEach(function (value) {\n      if (moment(value, moment.ISO_8601).isValid()) {\n        // \"2016-08-17 17:25:00+01\"\n        mytype.datetime++;\n      } else if (\n          (moment.duration(value).asMilliseconds() !== 0) &&\n          (typeof value === 'string') &&\n          (value[0].toLowerCase() === 'p')) {\n        // \"P10Y\"\n        mytype.duration++;\n      } else if (value == +value) {  // eslint-disable-line eqeqeq\n        // \"10\" or 10\n        mytype.continuous++;\n      } else {\n        // \"hello world\"\n        mytype.categorial++;\n      }\n    });\n\n    // get facetType with highest count\n    var max = -1;\n    var facetType;\n    Object.keys(mytype).forEach(function (key) {\n      if (mytype[key] > max) {\n        facetType = key;\n        max = mytype[key];\n      }\n    });\n\n    return facetType;\n  }\n\n  function tryFacet (facets, data, path, value) {\n    // Check for existence\n    if (facetExists(facets, path)) {\n      return;\n    }\n\n    // Create a new facet\n    var facet = facets.add({\n      name: path,\n      accessor: path,\n      type: 'text'\n    });\n\n    // Sample values\n    var baseValueFn = utildx.baseValueFn(facet);\n    var values = [];\n    var isArray = false;\n\n    data.forEach(function (d) {\n      var value = baseValueFn(d);\n      if (value instanceof Array) {\n        isArray = true;\n        value.forEach(function (v) {\n          addValue(values, v, facet.misval[0]);\n        });\n      } else {\n        addValue(values, value, facet.misval[0]);\n      }\n    });\n\n    // Reconfigure facet\n    facet.accessor = isArray ? facet.accessor + '[]' : facet.accessor;\n    facet.type = guessType(values);\n    facet.description = values.join(', ').match('^.{0,40}') + '...';\n    facet.isActive = true;\n  }\n\n  function recurse (facets, data, path, tree) {\n    var props = Object.getOwnPropertyNames(tree);\n    props.forEach(function (name) {\n      var subpath;\n      if (path) {\n        subpath = path + '##' + name;\n      } else {\n        subpath = name;\n      }\n\n      if (tree[name] instanceof Array) {\n        // add an array as a itself as a facet, ie. labelset, to prevent adding each element as separate facet\n        // also add the array length as facet\n        tryFacet(facets, data, subpath, tree[name]);\n        tryFacet(facets, data, subpath + '.length', tree[name].length);\n      } else if (tree[name] instanceof Object) {\n        // recurse into objects\n        recurse(facets, data, subpath, tree[name]);\n      } else {\n        // add strings and numbers as facets\n        tryFacet(facets, data, subpath, tree[name]);\n      }\n    });\n  }\n\n  // Add facets\n  var data = dataset.data.slice(0, 10);\n  data.forEach(function (d) {\n    recurse(dataset.facets, data, '', d);\n  });\n\n  dataset.facets.forEach(function (facet) {\n    if (facet.isCategorial) {\n      setCategories(dataset, facet);\n    } else if (facet.isContinuous || facet.isDatetime) {\n      setMinMax(dataset, facet);\n    }\n  });\n  dataset.trigger('syncFacets');\n}\n\n/**\n * Initialize the data filter, and construct the getData callback function on the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction initDataFilter (dataview, filter) {\n  var facet;\n\n  // use the partitions as groups:\n  var groupFns = [];\n  filter.partitions.forEach(function (partition) {\n    facet = dataview.facets.get(partition.facetName, 'name');\n    var valueFn = utildx.valueFn(facet);\n    var groupFn = utildx.groupFn(partition);\n\n    var rank = partition.rank;\n    groupFns[rank - 1] = function (d) {\n      return groupFn(valueFn(d));\n    };\n  });\n\n  // and then create keys from the group values\n  var groupsKeys = function (d) {\n    var keys = [];\n\n    groupFns.forEach(function (groupFn) {\n      var result = groupFn(d);\n      var newKeys = [];\n      if (keys.length === 0) {\n        if (result instanceof Array) {\n          newKeys = result;\n        } else {\n          newKeys = [result];\n        }\n      } else {\n        if (result instanceof Array) {\n          keys.forEach(function (oldKey) {\n            result.forEach(function (key) {\n              newKeys.push(oldKey + '|' + key);\n            });\n          });\n        } else {\n          keys.forEach(function (oldKey) {\n            newKeys.push(oldKey + '|' + result);\n          });\n        }\n      }\n      keys = newKeys;\n    });\n    return keys;\n  };\n\n  // set up the facet valueFns to aggregate over\n  // and the reduction functions for them\n  var aggregateFns = [];\n  var aggregateRanks = [];\n  var reduceFns = [];\n  filter.aggregates.forEach(function (aggregate) {\n    facet = dataview.facets.get(aggregate.facetName, 'name');\n    aggregateRanks.push(aggregate.rank);\n    aggregateFns.push(utildx.valueFn(facet));\n    reduceFns.push(utildx.reduceFn(aggregate));\n  });\n\n  // setup the crossfilter dimensions and groups\n  filter.dimension = dataview.crossfilter.dimension(function (d) {\n    return groupsKeys(d);\n  }, true);\n  var crossfilterGroup = filter.dimension.group(function (d) { return d; });\n\n  crossfilterGroup.reduce(\n    // add\n    function (p, d) {\n      if (aggregateFns.length === 0) {\n        p[0] = p[0] ? p[0] : {count: 0};\n        p[0].count += 1;\n      }\n\n      aggregateFns.forEach(function (aggregateFn, i) {\n        var val = aggregateFn(d);\n        if (val !== misval) {\n          val = parseFloat(val);\n          p[i] = p[i] || {count: 0, sum: 0, sumsquares: 0};\n          p[i].count += 1;\n          p[i].sum += val;\n          p[i].sumsquares += val * val;\n        }\n      });\n      return p;\n    },\n    // subtract\n    function (p, d) {\n      if (aggregateFns.length === 0) {\n        p[0] = p[0] ? p[0] : {count: 0};\n        p[0].count -= 1;\n      }\n\n      aggregateFns.forEach(function (aggregateFn, i) {\n        var val = aggregateFn(d);\n        if (val !== misval) {\n          val = parseFloat(val);\n          p[i] = p[i] || {count: 0, sum: 0, sumsquares: 0};\n          p[i].count -= 1;\n          p[i].sum -= val;\n          p[i].sumsquares -= val * val;\n        }\n      });\n      return p;\n    },\n    // initialize\n    function () {\n      return [];\n    }\n  );\n\n  filter.getData = function () {\n    filter.data = [];\n\n    // Get data from crossfilter\n    var groups = crossfilterGroup.all();\n\n    // { key: \"group1|group2|...\",\n    //   value: [ {count: agg1, sum: agg1}\n    //            {count: agg2, sum: agg2}\n    //            {count: agg3, sum: agg3}\n    //                    ...             ]}\n    groups.forEach(function (group) {\n      var item = {};\n\n      // turn the string back into individual group values\n      var groupsKeys;\n      if (typeof group.key === 'string') {\n        groupsKeys = group.key.split('|');\n      } else {\n        // shortcut for numeric non-partitioned case\n        groupsKeys = [group.key];\n      }\n\n      // add paritioning data to the item\n      groupsKeys.forEach(function (subkey, i) {\n        item[grpIdxToName[i]] = subkey;\n      });\n\n      // add aggregated data to the item\n      reduceFns.forEach(function (reduceFn, i) {\n        var name = aggRankToName[aggregateRanks[i]];\n        item[name] = reduceFn(group.value[i]);\n      });\n\n      // add an overall count\n      // becuase the filtering removes missing data points, this is the same as\n      // the count for any one of the aggregates\n      item.count = group.value[0] ? group.value[0].count : 0;\n\n      filter.data.push(item);\n    });\n  };\n}\n\n/**\n * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n * related to the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction releaseDataFilter (dataview, filter) {\n  if (filter.dimension) {\n    filter.dimension.filterAll();\n    filter.dimension.dispose();\n    delete filter.dimension;\n    delete filter.getData;\n  }\n}\n\n/**\n * Change the filter parameters for an initialized filter\n * @param {Filter} filter\n */\nfunction updateDataFilter (filter) {\n  if (filter.dimension) {\n    filter.dimension.filterFunction(filter.filterFunction());\n  }\n}\n\n/**\n * Get data for every filter, and trigger a 'newData' event\n *\n * Returns a Promise that resolves to the dataview when all data and metadata has been updated\n *\n * @param {Dataview} dataview\n * @returns {Promise}\n */\nfunction getData (dataview) {\n  dataview.filters.forEach(function (filter) {\n    if (filter.isInitialized) {\n      filter.getData();\n      filter.trigger('newData');\n    }\n  });\n\n  // update counts\n  dataview.dataTotal = dataview.crossfilter.size();\n  dataview.dataSelected = dataview.countGroup.value();\n  dataview.trigger('newMetaData');\n\n  return Promise.resolve(dataview);\n}\n\nmodule.exports = {\n  driverType: 'client',\n  scan: scan,\n  setMinMax: setMinMax,\n  setCategories: setCategories,\n  setPercentiles: setPercentiles,\n  initDataFilter: initDataFilter,\n  releaseDataFilter: releaseDataFilter,\n  updateDataFilter: updateDataFilter,\n  getData: getData\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwYy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZHJpdmVyL2NsaWVudC5qcz9kZjc3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2xpZW50IHNpZGUgZmlsdGVyaW5nIHVzaW5nIGNyb3NzZmlsdGVyXG4gKiBEdWUgdG8gbGltaXRhdGlvbiBvZiBjcm9zc2ZpbHRlciB3aXRoIGFycmF5IChvciBkYXRhIHRoYXQgaGFzIG5vIG5hdHJ1YWwgb3JkZXJpbmcpLCB0aGlzIHdpbGwgbm90IHdvcmsgYXMgZXhwZWN0ZWQ6XG4gKiAqIGRpbWVuc2lvbjogYGZ1bmN0aW9uIChkKSB7cmV0dXJuIFtkLngsIGQueSwgZC56XX1gXG4gKiAqIGdyb3VwOiBgZnVuY3Rpb24gKGQpIHtyZXR1cm4gW2QueCAvIDEwICwgZC55IC8gMTAsIGQueiAvIDEwXX1gXG4gKlxuICogVGhlcmVmb3JlLCB3ZSBwcmVmb3JtIGdyb3VwaW5nIGFscmVhZHkgaW4gdGhlIGRpbWVuc2lvbiBpdHNlbGYsIGFuZCBqb2luIHRoZSBhcnJheSB0byBhIHN0cmluZy5cbiAqIFN0cmluZ3MgaGF2ZSBhIG5hdHVyYWwgb3JkZXJpbmcgYW5kIHRodXMgY2FuIGJlIHVzZWQgYXMgZGltZW5zaW9uIHZhbHVlLlxuICogKiBkaW1lbnNpb246IGBmdW5jdGlvbiAoZCkgLT4gXCJkLngvMTB8ZC55LzEwfGQuei8xMFwiYFxuICogKiBncm91cDogYGZ1bmN0aW9uIChkKSB7cmV0dXJuIGQ7fWBcbiAqXG4gKiBAbW9kdWxlIGRyaXZlci9jbGllbnRcbiAqL1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xuXG52YXIgdXRpbGR4ID0gcmVxdWlyZSgnLi4vdXRpbC9jcm9zc2ZpbHRlcicpO1xudmFyIG1pc3ZhbCA9IHJlcXVpcmUoJy4uL3V0aWwvbWlzdmFsJyk7XG5cbnZhciBncnBJZHhUb05hbWUgPSB7MDogJ2EnLCAxOiAnYicsIDI6ICdjJywgMzogJ2QnLCA0OiAnZSd9O1xudmFyIGFnZ1JhbmtUb05hbWUgPSB7MTogJ2FhJywgMjogJ2JiJywgMzogJ2NjJywgNDogJ2RkJywgNTogJ2VlJ307XG5cbi8qKlxuICogc2V0TWluTWF4IHNldHMgdGhlIHJhbmdlIG9mIGEgY29udGludW91cyBvciB0aW1lIGZhY2V0XG4gKlxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0XG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICovXG5mdW5jdGlvbiBzZXRNaW5NYXggKGRhdGFzZXQsIGZhY2V0KSB7XG4gIC8vIHdlIG5lZWQgdGhlIHZhbHVlIGp1c3QgYmVmb3JlIGEgdHJhbnNmb3JtYXRpb24sIHNvIGJhc2VWYWx1ZUZuXG4gIHZhciB2YWxGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG5cbiAgLy8gdG8gYmUgYWJsZSB0byBtYXJrIHRoZSB2YWx1ZSBhcyBtaXNzaW5nIHdlIG5lZWQgaXQgdW5wcm9jZXNzZWQsIHNvIHJhd1ZhbHVlRm5cbiAgdmFyIHJhd1ZhbEZuID0gdXRpbGR4LnJhd1ZhbHVlRm4oZmFjZXQpO1xuXG4gIHZhciBsZXNzRm47XG4gIHZhciBtb3JlRm47XG4gIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgbGVzc0ZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYS5pc0JlZm9yZShiKSk7IH07XG4gICAgbW9yZUZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYi5pc0JlZm9yZShhKSk7IH07XG4gIH0gZWxzZSB7XG4gICAgbGVzc0ZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYSA8IGIpOyB9O1xuICAgIG1vcmVGbiA9IGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiAoYiA9PT0gbWlzdmFsIHx8IGEgPiBiKTsgfTtcbiAgfVxuXG4gIHZhciBtaW52YWwgPSBtaXN2YWw7XG4gIHZhciByYXdNaW4gPSBtaXN2YWw7XG5cbiAgdmFyIG1heHZhbCA9IG1pc3ZhbDtcbiAgdmFyIHJhd01heCA9IG1pc3ZhbDtcblxuICBkYXRhc2V0LmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgIHZhciByYXdWID0gcmF3VmFsRm4oZCk7XG4gICAgdmFyIHYgPSB2YWxGbihkKTtcblxuICAgIGlmICh2ICE9PSBtaXN2YWwpIHtcbiAgICAgIGlmIChsZXNzRm4odiwgbWludmFsKSkge1xuICAgICAgICBtaW52YWwgPSB2O1xuICAgICAgICByYXdNaW4gPSByYXdWO1xuICAgICAgfVxuICAgICAgaWYgKG1vcmVGbih2LCBtYXh2YWwpKSB7XG4gICAgICAgIG1heHZhbCA9IHY7XG4gICAgICAgIHJhd01heCA9IHJhd1Y7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBpZiAobWludmFsICE9PSBtaXN2YWwpIHtcbiAgICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgICBmYWNldC5taW52YWxBc1RleHQgPSBtaW52YWwudG9TdHJpbmcoKTtcbiAgICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICAgIGZhY2V0Lm1pbnZhbEFzVGV4dCA9IG1pbnZhbC50b0lTT1N0cmluZygpO1xuICAgIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgICAgZmFjZXQubWludmFsQXNUZXh0ID0gbWludmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGZhY2V0LnJhd01pbnZhbCA9IHJhd01pbjtcbiAgfSBlbHNlIHtcbiAgICBmYWNldC5taW52YWxBc1RleHQgPSAnJztcbiAgICBmYWNldC5yYXdNaW52YWwgPSBtaXN2YWw7XG4gIH1cblxuICBpZiAobWF4dmFsICE9PSBtaXN2YWwpIHtcbiAgICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgICBmYWNldC5tYXh2YWxBc1RleHQgPSBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IG1heHZhbC50b0lTT1N0cmluZygpO1xuICAgIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgICAgZmFjZXQubWF4dmFsQXNUZXh0ID0gbWF4dmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGZhY2V0LnJhd01heHZhbCA9IHJhd01heDtcbiAgfSBlbHNlIHtcbiAgICBmYWNldC5tYXh2YWxBc1RleHQgPSAnJztcbiAgICBmYWNldC5yYXdNYXh2YWwgPSBtaXN2YWw7XG4gIH1cbn1cblxuLyoqXG4gKiBzZXRDYXRlZ29yaWVzIGZpbmRzIGZpbmRzIGFsbCB2YWx1ZXMgb24gYW4gb3JkaW5hbCAoY2F0ZWdvcmlhbCkgYXhpc1xuICogVXBkYXRlcyB0aGUgY2F0ZWdvcmlhbFRyYW5zZm9ybSBvZiB0aGUgZmFjZXRcbiAqXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXRcbiAqIEBwYXJhbSB7RmFjZXR9IGZhY2V0XG4gKi9cbmZ1bmN0aW9uIHNldENhdGVnb3JpZXMgKGRhdGFzZXQsIGZhY2V0KSB7XG4gIC8vIHdlIG5lZWQgdGhlIHZhbHVlIGp1c3QgYmVmb3JlIGEgdHJhbnNmb3JtYXRpb24sIHNvIGJhc2VWYWx1ZUZuXG4gIHZhciB2YWxGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG5cbiAgdmFyIHAgPSB7fTtcbiAgdmFyIFBsZW5ndGggPSAwO1xuICBkYXRhc2V0LmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZCwgaSkge1xuICAgIHZhciB2YWxzID0gdmFsRm4oZCk7XG4gICAgaWYgKHZhbHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgdmFscy5mb3JFYWNoKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgaWYgKHAuaGFzT3duUHJvcGVydHkodmFsKSkge1xuICAgICAgICAgIHBbdmFsXSsrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChQbGVuZ3RoIDwgNzUpIHsgLy8gTk9URTogbGltaXQgdG8gbWF4aW1hbGx5IDc1IGNhdGVnb3JpZXNcbiAgICAgICAgICAgIHBbdmFsXSA9IDE7XG4gICAgICAgICAgICBQbGVuZ3RoKys7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHAuaGFzT3duUHJvcGVydHkodmFscykpIHtcbiAgICAgICAgcFt2YWxzXSsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKFBsZW5ndGggPCA3NSkgeyAvLyBOT1RFOiBsaW1pdCB0byBtYXhpbWFsbHkgNzUgY2F0ZWdvcmllc1xuICAgICAgICAgIHBbdmFsc10gPSAxO1xuICAgICAgICAgIFBsZW5ndGgrKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5yZXNldCgpO1xuXG4gIE9iamVjdC5rZXlzKHApLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIC8vIFRPRE86IG1pc3NpbmcgZGF0YSBzaG91bGQgYmUgbWFwcGVkIHRvIGEgbWlzdmFsIGZyb20gbWlzdmFsQXNUZXh0XG4gICAgdmFyIGtleUFzU3RyaW5nID0ga2V5LnRvU3RyaW5nKCk7XG4gICAgdmFyIGdyb3VwQXNTdHJpbmcgPSBrZXlBc1N0cmluZztcblxuICAgIGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuYWRkKHtleHByZXNzaW9uOiBrZXlBc1N0cmluZywgY291bnQ6IHBba2V5XSwgZ3JvdXA6IGdyb3VwQXNTdHJpbmd9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIDEwMCBwZXJjZW50aWxlcyAoaWUuIDEsMiwzLDQgZXRjLiksIGFuZCBpbml0aWFsaXplIHRoZSBgZmFjZXQuY29udGludW91c1RyYW5zZm9ybWBcbiAqIHRvIGFuIGFwcHJveGltYXRlIHBlcmNlbnRpbGUgbWFwcGluZy5cbiAqIFVzZSB0aGUgcmVjb21tZW5kZWQgbWV0aG9kIGZyb20gW05JU1RdKGh0dHA6Ly93d3cuaXRsLm5pc3QuZ292L2Rpdjg5OC9oYW5kYm9vay9wcmMvc2VjdGlvbjIvcHJjMjYyLmh0bSlcbiAqIFNlZSBhbHNvIHRoZSBkaXNjdXNzaW9uIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1BlcmNlbnRpbGUpXG4gKlxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0XG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICovXG5mdW5jdGlvbiBzZXRQZXJjZW50aWxlcyAoZGF0YXNldCwgZmFjZXQpIHtcbiAgLy8gd2UgbmVlZCB0aGUgdmFsdWUganVzdCBiZWZvcmUgYSB0cmFuc2Zvcm1hdGlvbiwgc28gYmFzZVZhbHVlRm5cbiAgdmFyIGJhc2V2YWx1ZUZuID0gdXRpbGR4LmJhc2VWYWx1ZUZuKGZhY2V0KTtcbiAgdmFyIGRhdGEgPSBkYXRhc2V0LmRhdGE7XG5cbiAgZGF0YS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgdmFyIHZhbEEgPSBiYXNldmFsdWVGbihhKTtcbiAgICB2YXIgdmFsQiA9IGJhc2V2YWx1ZUZuKGIpO1xuXG4gICAgaWYgKHZhbEEgPT09IHZhbEIpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpZiAodmFsQSA9PT0gbWlzdmFsKSB7XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIGlmICh2YWxCID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIGlmICh2YWxBIDwgdmFsQikge1xuICAgICAgcmV0dXJuIC0xO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH0pO1xuXG4gIHZhciB0ZiA9IGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm07XG4gIHZhciB4LCBpO1xuXG4gIC8vIGRyb3AgbWlzc2luZyB2YWx1ZXMsIHdoaWNoIHNob3VsZCBiZSBzb3J0ZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZSBhcnJheVxuICBpID0gMDtcbiAgd2hpbGUgKGJhc2V2YWx1ZUZuKGRhdGFbaV0pID09PSBtaXN2YWwgJiYgaSA8IGRhdGEubGVuZ3RoKSB7XG4gICAgaSsrO1xuICB9XG4gIGRhdGEuc3BsaWNlKDAsIGkpO1xuXG4gIC8vIHN0YXJ0IGNsZWFuXG4gIHRmLnJlc2V0KCk7XG5cbiAgLy8gYWRkIG1pbmltdW0gdmFsdWUgYXMgY29udHJvbCBwb2ludHMgcDAgYW5kIHAxXG4gIHRmLmNwcy5hZGQoe3g6IGJhc2V2YWx1ZUZuKGRhdGFbMF0pLCBmeDogMH0pO1xuICB0Zi5jcHMuYWRkKHt4OiBiYXNldmFsdWVGbihkYXRhWzBdKSwgZng6IDB9KTtcblxuICB2YXIgcCwgdmFsdWU7XG4gIGZvciAocCA9IDE7IHAgPCAxMDA7IHArKykge1xuICAgIHggPSAocCAqIDAuMDEpICogKGRhdGEubGVuZ3RoICsgMSkgLSAxOyAvLyBpbmRleGluZyBzdGFydHMgYXQgemVybywgbm90IGF0IG9uZVxuICAgIGkgPSBNYXRoLnRydW5jKHgpO1xuICAgIHZhbHVlID0gKDEgLSB4ICsgaSkgKiBiYXNldmFsdWVGbihkYXRhW2ldKSArICh4IC0gaSkgKiBiYXNldmFsdWVGbihkYXRhW2kgKyAxXSk7XG4gICAgdGYuY3BzLmFkZCh7eDogdmFsdWUsIGZ4OiBwfSk7XG4gIH1cblxuICAvLyBhZGQgbWF4aW11bSB2YWx1ZSBhcyBwMTAxIGFuZCBwMTAyXG4gIHRmLmNwcy5hZGQoe3g6IGJhc2V2YWx1ZUZuKGRhdGFbZGF0YS5sZW5ndGggLSAxXSksIGZ4OiAxMDB9KTtcbiAgdGYuY3BzLmFkZCh7eDogYmFzZXZhbHVlRm4oZGF0YVtkYXRhLmxlbmd0aCAtIDFdKSwgZng6IDEwMH0pO1xuXG4gIHRmLnR5cGUgPSAncGVyY2VudGlsZXMnO1xufVxuXG4vKipcbiAqIEF1dG9jb25maWd1cmUgYSBkYXRhc2V0OlxuICogMS4gcGljayAxMCByYW5kb20gZWxlbWVudHNcbiAqIDIuIGNyZWF0ZSBmYWNldHMgZm9yIHRoZWlyIHByb3BlcnRpZXNcbiAqIDMuIGFkZCBmYWNldHMnIHZhbHVlcyBvdmVyIHRoZSBzYW1wbGUgdG8gdGhlIGZhY2V0LmRlc2NyaXB0aW9uXG4gKiA0LiBzZXQgcmFuZ2Ugb3IgY2F0ZWdvcmllc1xuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICovXG5mdW5jdGlvbiBzY2FuIChkYXRhc2V0KSB7XG4gIGZ1bmN0aW9uIGZhY2V0RXhpc3RzIChmYWNldHMsIHBhdGgpIHtcbiAgICB2YXIgZXhpc3RzID0gZmFsc2U7XG4gICAgZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgIGlmIChmLmFjY2Vzc29yID09PSBwYXRoIHx8IGYuYWNjZXNzb3IgPT09IHBhdGggKyAnW10nKSB7XG4gICAgICAgIGV4aXN0cyA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGV4aXN0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFZhbHVlICh2YWx1ZXMsIHYsIG1pc3NpbmcpIHtcbiAgICBpZiAodiA9PT0gbWlzdmFsKSB7XG4gICAgICB2ID0gbWlzc2luZztcbiAgICB9XG4gICAgaWYgKHZhbHVlcy5pbmRleE9mKHYpID09PSAtMSkge1xuICAgICAgdmFsdWVzLnB1c2godik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZ3Vlc3NUeXBlICh2YWx1ZXMpIHtcbiAgICB2YXIgbXl0eXBlID0ge1xuICAgICAgY29udGludW91czogMCxcbiAgICAgIHRleHQ6IDAsXG4gICAgICBkYXRldGltZTogMCxcbiAgICAgIGR1cmF0aW9uOiAwLFxuICAgICAgY2F0ZWdvcmlhbDogMFxuICAgIH07XG4gICAgdmFsdWVzLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBpZiAobW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpLmlzVmFsaWQoKSkge1xuICAgICAgICAvLyBcIjIwMTYtMDgtMTcgMTc6MjU6MDArMDFcIlxuICAgICAgICBteXR5cGUuZGF0ZXRpbWUrKztcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgKG1vbWVudC5kdXJhdGlvbih2YWx1ZSkuYXNNaWxsaXNlY29uZHMoKSAhPT0gMCkgJiZcbiAgICAgICAgICAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgJiZcbiAgICAgICAgICAodmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSkge1xuICAgICAgICAvLyBcIlAxMFlcIlxuICAgICAgICBteXR5cGUuZHVyYXRpb24rKztcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gK3ZhbHVlKSB7ICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgICAgICAvLyBcIjEwXCIgb3IgMTBcbiAgICAgICAgbXl0eXBlLmNvbnRpbnVvdXMrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFwiaGVsbG8gd29ybGRcIlxuICAgICAgICBteXR5cGUuY2F0ZWdvcmlhbCsrO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gZ2V0IGZhY2V0VHlwZSB3aXRoIGhpZ2hlc3QgY291bnRcbiAgICB2YXIgbWF4ID0gLTE7XG4gICAgdmFyIGZhY2V0VHlwZTtcbiAgICBPYmplY3Qua2V5cyhteXR5cGUpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgaWYgKG15dHlwZVtrZXldID4gbWF4KSB7XG4gICAgICAgIGZhY2V0VHlwZSA9IGtleTtcbiAgICAgICAgbWF4ID0gbXl0eXBlW2tleV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZmFjZXRUeXBlO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJ5RmFjZXQgKGZhY2V0cywgZGF0YSwgcGF0aCwgdmFsdWUpIHtcbiAgICAvLyBDaGVjayBmb3IgZXhpc3RlbmNlXG4gICAgaWYgKGZhY2V0RXhpc3RzKGZhY2V0cywgcGF0aCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYSBuZXcgZmFjZXRcbiAgICB2YXIgZmFjZXQgPSBmYWNldHMuYWRkKHtcbiAgICAgIG5hbWU6IHBhdGgsXG4gICAgICBhY2Nlc3NvcjogcGF0aCxcbiAgICAgIHR5cGU6ICd0ZXh0J1xuICAgIH0pO1xuXG4gICAgLy8gU2FtcGxlIHZhbHVlc1xuICAgIHZhciBiYXNlVmFsdWVGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIHZhciBpc0FycmF5ID0gZmFsc2U7XG5cbiAgICBkYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGJhc2VWYWx1ZUZuKGQpO1xuICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgaXNBcnJheSA9IHRydWU7XG4gICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICBhZGRWYWx1ZSh2YWx1ZXMsIHYsIGZhY2V0Lm1pc3ZhbFswXSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWRkVmFsdWUodmFsdWVzLCB2YWx1ZSwgZmFjZXQubWlzdmFsWzBdKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFJlY29uZmlndXJlIGZhY2V0XG4gICAgZmFjZXQuYWNjZXNzb3IgPSBpc0FycmF5ID8gZmFjZXQuYWNjZXNzb3IgKyAnW10nIDogZmFjZXQuYWNjZXNzb3I7XG4gICAgZmFjZXQudHlwZSA9IGd1ZXNzVHlwZSh2YWx1ZXMpO1xuICAgIGZhY2V0LmRlc2NyaXB0aW9uID0gdmFsdWVzLmpvaW4oJywgJykubWF0Y2goJ14uezAsNDB9JykgKyAnLi4uJztcbiAgICBmYWNldC5pc0FjdGl2ZSA9IHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiByZWN1cnNlIChmYWNldHMsIGRhdGEsIHBhdGgsIHRyZWUpIHtcbiAgICB2YXIgcHJvcHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0cmVlKTtcbiAgICBwcm9wcy5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICB2YXIgc3VicGF0aDtcbiAgICAgIGlmIChwYXRoKSB7XG4gICAgICAgIHN1YnBhdGggPSBwYXRoICsgJyMjJyArIG5hbWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdWJwYXRoID0gbmFtZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRyZWVbbmFtZV0gaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAvLyBhZGQgYW4gYXJyYXkgYXMgYSBpdHNlbGYgYXMgYSBmYWNldCwgaWUuIGxhYmVsc2V0LCB0byBwcmV2ZW50IGFkZGluZyBlYWNoIGVsZW1lbnQgYXMgc2VwYXJhdGUgZmFjZXRcbiAgICAgICAgLy8gYWxzbyBhZGQgdGhlIGFycmF5IGxlbmd0aCBhcyBmYWNldFxuICAgICAgICB0cnlGYWNldChmYWNldHMsIGRhdGEsIHN1YnBhdGgsIHRyZWVbbmFtZV0pO1xuICAgICAgICB0cnlGYWNldChmYWNldHMsIGRhdGEsIHN1YnBhdGggKyAnLmxlbmd0aCcsIHRyZWVbbmFtZV0ubGVuZ3RoKTtcbiAgICAgIH0gZWxzZSBpZiAodHJlZVtuYW1lXSBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgICAgICAvLyByZWN1cnNlIGludG8gb2JqZWN0c1xuICAgICAgICByZWN1cnNlKGZhY2V0cywgZGF0YSwgc3VicGF0aCwgdHJlZVtuYW1lXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBhZGQgc3RyaW5ncyBhbmQgbnVtYmVycyBhcyBmYWNldHNcbiAgICAgICAgdHJ5RmFjZXQoZmFjZXRzLCBkYXRhLCBzdWJwYXRoLCB0cmVlW25hbWVdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIEFkZCBmYWNldHNcbiAgdmFyIGRhdGEgPSBkYXRhc2V0LmRhdGEuc2xpY2UoMCwgMTApO1xuICBkYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICByZWN1cnNlKGRhdGFzZXQuZmFjZXRzLCBkYXRhLCAnJywgZCk7XG4gIH0pO1xuXG4gIGRhdGFzZXQuZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgaWYgKGZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgc2V0Q2F0ZWdvcmllcyhkYXRhc2V0LCBmYWNldCk7XG4gICAgfSBlbHNlIGlmIChmYWNldC5pc0NvbnRpbnVvdXMgfHwgZmFjZXQuaXNEYXRldGltZSkge1xuICAgICAgc2V0TWluTWF4KGRhdGFzZXQsIGZhY2V0KTtcbiAgICB9XG4gIH0pO1xuICBkYXRhc2V0LnRyaWdnZXIoJ3N5bmNGYWNldHMnKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gaW5pdERhdGFGaWx0ZXIgKGRhdGF2aWV3LCBmaWx0ZXIpIHtcbiAgdmFyIGZhY2V0O1xuXG4gIC8vIHVzZSB0aGUgcGFydGl0aW9ucyBhcyBncm91cHM6XG4gIHZhciBncm91cEZucyA9IFtdO1xuICBmaWx0ZXIucGFydGl0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgICBmYWNldCA9IGRhdGF2aWV3LmZhY2V0cy5nZXQocGFydGl0aW9uLmZhY2V0TmFtZSwgJ25hbWUnKTtcbiAgICB2YXIgdmFsdWVGbiA9IHV0aWxkeC52YWx1ZUZuKGZhY2V0KTtcbiAgICB2YXIgZ3JvdXBGbiA9IHV0aWxkeC5ncm91cEZuKHBhcnRpdGlvbik7XG5cbiAgICB2YXIgcmFuayA9IHBhcnRpdGlvbi5yYW5rO1xuICAgIGdyb3VwRm5zW3JhbmsgLSAxXSA9IGZ1bmN0aW9uIChkKSB7XG4gICAgICByZXR1cm4gZ3JvdXBGbih2YWx1ZUZuKGQpKTtcbiAgICB9O1xuICB9KTtcblxuICAvLyBhbmQgdGhlbiBjcmVhdGUga2V5cyBmcm9tIHRoZSBncm91cCB2YWx1ZXNcbiAgdmFyIGdyb3Vwc0tleXMgPSBmdW5jdGlvbiAoZCkge1xuICAgIHZhciBrZXlzID0gW107XG5cbiAgICBncm91cEZucy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cEZuKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gZ3JvdXBGbihkKTtcbiAgICAgIHZhciBuZXdLZXlzID0gW107XG4gICAgICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgbmV3S2V5cyA9IHJlc3VsdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdLZXlzID0gW3Jlc3VsdF07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAob2xkS2V5KSB7XG4gICAgICAgICAgICByZXN1bHQuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgIG5ld0tleXMucHVzaChvbGRLZXkgKyAnfCcgKyBrZXkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChvbGRLZXkpIHtcbiAgICAgICAgICAgIG5ld0tleXMucHVzaChvbGRLZXkgKyAnfCcgKyByZXN1bHQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBrZXlzID0gbmV3S2V5cztcbiAgICB9KTtcbiAgICByZXR1cm4ga2V5cztcbiAgfTtcblxuICAvLyBzZXQgdXAgdGhlIGZhY2V0IHZhbHVlRm5zIHRvIGFnZ3JlZ2F0ZSBvdmVyXG4gIC8vIGFuZCB0aGUgcmVkdWN0aW9uIGZ1bmN0aW9ucyBmb3IgdGhlbVxuICB2YXIgYWdncmVnYXRlRm5zID0gW107XG4gIHZhciBhZ2dyZWdhdGVSYW5rcyA9IFtdO1xuICB2YXIgcmVkdWNlRm5zID0gW107XG4gIGZpbHRlci5hZ2dyZWdhdGVzLmZvckVhY2goZnVuY3Rpb24gKGFnZ3JlZ2F0ZSkge1xuICAgIGZhY2V0ID0gZGF0YXZpZXcuZmFjZXRzLmdldChhZ2dyZWdhdGUuZmFjZXROYW1lLCAnbmFtZScpO1xuICAgIGFnZ3JlZ2F0ZVJhbmtzLnB1c2goYWdncmVnYXRlLnJhbmspO1xuICAgIGFnZ3JlZ2F0ZUZucy5wdXNoKHV0aWxkeC52YWx1ZUZuKGZhY2V0KSk7XG4gICAgcmVkdWNlRm5zLnB1c2godXRpbGR4LnJlZHVjZUZuKGFnZ3JlZ2F0ZSkpO1xuICB9KTtcblxuICAvLyBzZXR1cCB0aGUgY3Jvc3NmaWx0ZXIgZGltZW5zaW9ucyBhbmQgZ3JvdXBzXG4gIGZpbHRlci5kaW1lbnNpb24gPSBkYXRhdmlldy5jcm9zc2ZpbHRlci5kaW1lbnNpb24oZnVuY3Rpb24gKGQpIHtcbiAgICByZXR1cm4gZ3JvdXBzS2V5cyhkKTtcbiAgfSwgdHJ1ZSk7XG4gIHZhciBjcm9zc2ZpbHRlckdyb3VwID0gZmlsdGVyLmRpbWVuc2lvbi5ncm91cChmdW5jdGlvbiAoZCkgeyByZXR1cm4gZDsgfSk7XG5cbiAgY3Jvc3NmaWx0ZXJHcm91cC5yZWR1Y2UoXG4gICAgLy8gYWRkXG4gICAgZnVuY3Rpb24gKHAsIGQpIHtcbiAgICAgIGlmIChhZ2dyZWdhdGVGbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHBbMF0gPSBwWzBdID8gcFswXSA6IHtjb3VudDogMH07XG4gICAgICAgIHBbMF0uY291bnQgKz0gMTtcbiAgICAgIH1cblxuICAgICAgYWdncmVnYXRlRm5zLmZvckVhY2goZnVuY3Rpb24gKGFnZ3JlZ2F0ZUZuLCBpKSB7XG4gICAgICAgIHZhciB2YWwgPSBhZ2dyZWdhdGVGbihkKTtcbiAgICAgICAgaWYgKHZhbCAhPT0gbWlzdmFsKSB7XG4gICAgICAgICAgdmFsID0gcGFyc2VGbG9hdCh2YWwpO1xuICAgICAgICAgIHBbaV0gPSBwW2ldIHx8IHtjb3VudDogMCwgc3VtOiAwLCBzdW1zcXVhcmVzOiAwfTtcbiAgICAgICAgICBwW2ldLmNvdW50ICs9IDE7XG4gICAgICAgICAgcFtpXS5zdW0gKz0gdmFsO1xuICAgICAgICAgIHBbaV0uc3Vtc3F1YXJlcyArPSB2YWwgKiB2YWw7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHA7XG4gICAgfSxcbiAgICAvLyBzdWJ0cmFjdFxuICAgIGZ1bmN0aW9uIChwLCBkKSB7XG4gICAgICBpZiAoYWdncmVnYXRlRm5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBwWzBdID0gcFswXSA/IHBbMF0gOiB7Y291bnQ6IDB9O1xuICAgICAgICBwWzBdLmNvdW50IC09IDE7XG4gICAgICB9XG5cbiAgICAgIGFnZ3JlZ2F0ZUZucy5mb3JFYWNoKGZ1bmN0aW9uIChhZ2dyZWdhdGVGbiwgaSkge1xuICAgICAgICB2YXIgdmFsID0gYWdncmVnYXRlRm4oZCk7XG4gICAgICAgIGlmICh2YWwgIT09IG1pc3ZhbCkge1xuICAgICAgICAgIHZhbCA9IHBhcnNlRmxvYXQodmFsKTtcbiAgICAgICAgICBwW2ldID0gcFtpXSB8fCB7Y291bnQ6IDAsIHN1bTogMCwgc3Vtc3F1YXJlczogMH07XG4gICAgICAgICAgcFtpXS5jb3VudCAtPSAxO1xuICAgICAgICAgIHBbaV0uc3VtIC09IHZhbDtcbiAgICAgICAgICBwW2ldLnN1bXNxdWFyZXMgLT0gdmFsICogdmFsO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBwO1xuICAgIH0sXG4gICAgLy8gaW5pdGlhbGl6ZVxuICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICk7XG5cbiAgZmlsdGVyLmdldERhdGEgPSBmdW5jdGlvbiAoKSB7XG4gICAgZmlsdGVyLmRhdGEgPSBbXTtcblxuICAgIC8vIEdldCBkYXRhIGZyb20gY3Jvc3NmaWx0ZXJcbiAgICB2YXIgZ3JvdXBzID0gY3Jvc3NmaWx0ZXJHcm91cC5hbGwoKTtcblxuICAgIC8vIHsga2V5OiBcImdyb3VwMXxncm91cDJ8Li4uXCIsXG4gICAgLy8gICB2YWx1ZTogWyB7Y291bnQ6IGFnZzEsIHN1bTogYWdnMX1cbiAgICAvLyAgICAgICAgICAgIHtjb3VudDogYWdnMiwgc3VtOiBhZ2cyfVxuICAgIC8vICAgICAgICAgICAge2NvdW50OiBhZ2czLCBzdW06IGFnZzN9XG4gICAgLy8gICAgICAgICAgICAgICAgICAgIC4uLiAgICAgICAgICAgICBdfVxuICAgIGdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgdmFyIGl0ZW0gPSB7fTtcblxuICAgICAgLy8gdHVybiB0aGUgc3RyaW5nIGJhY2sgaW50byBpbmRpdmlkdWFsIGdyb3VwIHZhbHVlc1xuICAgICAgdmFyIGdyb3Vwc0tleXM7XG4gICAgICBpZiAodHlwZW9mIGdyb3VwLmtleSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZ3JvdXBzS2V5cyA9IGdyb3VwLmtleS5zcGxpdCgnfCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gc2hvcnRjdXQgZm9yIG51bWVyaWMgbm9uLXBhcnRpdGlvbmVkIGNhc2VcbiAgICAgICAgZ3JvdXBzS2V5cyA9IFtncm91cC5rZXldO1xuICAgICAgfVxuXG4gICAgICAvLyBhZGQgcGFyaXRpb25pbmcgZGF0YSB0byB0aGUgaXRlbVxuICAgICAgZ3JvdXBzS2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChzdWJrZXksIGkpIHtcbiAgICAgICAgaXRlbVtncnBJZHhUb05hbWVbaV1dID0gc3Via2V5O1xuICAgICAgfSk7XG5cbiAgICAgIC8vIGFkZCBhZ2dyZWdhdGVkIGRhdGEgdG8gdGhlIGl0ZW1cbiAgICAgIHJlZHVjZUZucy5mb3JFYWNoKGZ1bmN0aW9uIChyZWR1Y2VGbiwgaSkge1xuICAgICAgICB2YXIgbmFtZSA9IGFnZ1JhbmtUb05hbWVbYWdncmVnYXRlUmFua3NbaV1dO1xuICAgICAgICBpdGVtW25hbWVdID0gcmVkdWNlRm4oZ3JvdXAudmFsdWVbaV0pO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIGFkZCBhbiBvdmVyYWxsIGNvdW50XG4gICAgICAvLyBiZWN1YXNlIHRoZSBmaWx0ZXJpbmcgcmVtb3ZlcyBtaXNzaW5nIGRhdGEgcG9pbnRzLCB0aGlzIGlzIHRoZSBzYW1lIGFzXG4gICAgICAvLyB0aGUgY291bnQgZm9yIGFueSBvbmUgb2YgdGhlIGFnZ3JlZ2F0ZXNcbiAgICAgIGl0ZW0uY291bnQgPSBncm91cC52YWx1ZVswXSA/IGdyb3VwLnZhbHVlWzBdLmNvdW50IDogMDtcblxuICAgICAgZmlsdGVyLmRhdGEucHVzaChpdGVtKTtcbiAgICB9KTtcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGUgb3Bwb3NpdGUgb3IgaW5pdERhdGFGaWx0ZXIsIGl0IHNob3VsZCByZW1vdmUgdGhlIGZpbHRlciBhbmQgZGVhbGxvY2F0ZSBvdGhlciBjb25maWd1cmF0aW9uXG4gKiByZWxhdGVkIHRvIHRoZSBmaWx0ZXIuXG4gKiBAcGFyYW0ge0RhdGF2aWV3fSBkYXRhdmlld1xuICogQHBhcmFtIHtGaWx0ZXJ9IGZpbHRlclxuICovXG5mdW5jdGlvbiByZWxlYXNlRGF0YUZpbHRlciAoZGF0YXZpZXcsIGZpbHRlcikge1xuICBpZiAoZmlsdGVyLmRpbWVuc2lvbikge1xuICAgIGZpbHRlci5kaW1lbnNpb24uZmlsdGVyQWxsKCk7XG4gICAgZmlsdGVyLmRpbWVuc2lvbi5kaXNwb3NlKCk7XG4gICAgZGVsZXRlIGZpbHRlci5kaW1lbnNpb247XG4gICAgZGVsZXRlIGZpbHRlci5nZXREYXRhO1xuICB9XG59XG5cbi8qKlxuICogQ2hhbmdlIHRoZSBmaWx0ZXIgcGFyYW1ldGVycyBmb3IgYW4gaW5pdGlhbGl6ZWQgZmlsdGVyXG4gKiBAcGFyYW0ge0ZpbHRlcn0gZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZURhdGFGaWx0ZXIgKGZpbHRlcikge1xuICBpZiAoZmlsdGVyLmRpbWVuc2lvbikge1xuICAgIGZpbHRlci5kaW1lbnNpb24uZmlsdGVyRnVuY3Rpb24oZmlsdGVyLmZpbHRlckZ1bmN0aW9uKCkpO1xuICB9XG59XG5cbi8qKlxuICogR2V0IGRhdGEgZm9yIGV2ZXJ5IGZpbHRlciwgYW5kIHRyaWdnZXIgYSAnbmV3RGF0YScgZXZlbnRcbiAqXG4gKiBSZXR1cm5zIGEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkYXRhdmlldyB3aGVuIGFsbCBkYXRhIGFuZCBtZXRhZGF0YSBoYXMgYmVlbiB1cGRhdGVkXG4gKlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEByZXR1cm5zIHtQcm9taXNlfVxuICovXG5mdW5jdGlvbiBnZXREYXRhIChkYXRhdmlldykge1xuICBkYXRhdmlldy5maWx0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpbHRlcikge1xuICAgIGlmIChmaWx0ZXIuaXNJbml0aWFsaXplZCkge1xuICAgICAgZmlsdGVyLmdldERhdGEoKTtcbiAgICAgIGZpbHRlci50cmlnZ2VyKCduZXdEYXRhJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyB1cGRhdGUgY291bnRzXG4gIGRhdGF2aWV3LmRhdGFUb3RhbCA9IGRhdGF2aWV3LmNyb3NzZmlsdGVyLnNpemUoKTtcbiAgZGF0YXZpZXcuZGF0YVNlbGVjdGVkID0gZGF0YXZpZXcuY291bnRHcm91cC52YWx1ZSgpO1xuICBkYXRhdmlldy50cmlnZ2VyKCduZXdNZXRhRGF0YScpO1xuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoZGF0YXZpZXcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZHJpdmVyVHlwZTogJ2NsaWVudCcsXG4gIHNjYW46IHNjYW4sXG4gIHNldE1pbk1heDogc2V0TWluTWF4LFxuICBzZXRDYXRlZ29yaWVzOiBzZXRDYXRlZ29yaWVzLFxuICBzZXRQZXJjZW50aWxlczogc2V0UGVyY2VudGlsZXMsXG4gIGluaXREYXRhRmlsdGVyOiBpbml0RGF0YUZpbHRlcixcbiAgcmVsZWFzZURhdGFGaWx0ZXI6IHJlbGVhc2VEYXRhRmlsdGVyLFxuICB1cGRhdGVEYXRhRmlsdGVyOiB1cGRhdGVEYXRhRmlsdGVyLFxuICBnZXREYXRhOiBnZXREYXRhXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///720c\n")},"780f":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {\n/**\n * Module dependencies.\n */\n\nvar parseuri = __webpack_require__(/*! parseuri */ \"64a0\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:url');\n\n/**\n * Module exports.\n */\n\nmodule.exports = url;\n\n/**\n * URL parser.\n *\n * @param {String} url\n * @param {Object} An object meant to mimic window.location.\n *                 Defaults to window.location.\n * @api public\n */\n\nfunction url (uri, loc) {\n  var obj = uri;\n\n  // default to window.location\n  loc = loc || global.location;\n  if (null == uri) uri = loc.protocol + '//' + loc.host;\n\n  // relative path support\n  if ('string' === typeof uri) {\n    if ('/' === uri.charAt(0)) {\n      if ('/' === uri.charAt(1)) {\n        uri = loc.protocol + uri;\n      } else {\n        uri = loc.host + uri;\n      }\n    }\n\n    if (!/^(https?|wss?):\\/\\//.test(uri)) {\n      debug('protocol-less url %s', uri);\n      if ('undefined' !== typeof loc) {\n        uri = loc.protocol + '//' + uri;\n      } else {\n        uri = 'https://' + uri;\n      }\n    }\n\n    // parse\n    debug('parse %s', uri);\n    obj = parseuri(uri);\n  }\n\n  // make sure we treat `localhost:80` and `localhost` equally\n  if (!obj.port) {\n    if (/^(http|ws)$/.test(obj.protocol)) {\n      obj.port = '80';\n    } else if (/^(http|ws)s$/.test(obj.protocol)) {\n      obj.port = '443';\n    }\n  }\n\n  obj.path = obj.path || '/';\n\n  var ipv6 = obj.host.indexOf(':') !== -1;\n  var host = ipv6 ? '[' + obj.host + ']' : obj.host;\n\n  // define unique id\n  obj.id = obj.protocol + '://' + host + ':' + obj.port;\n  // define href\n  obj.href = obj.protocol + '://' + host + (loc && loc.port === obj.port ? '' : (':' + obj.port));\n\n  return obj;\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzgwZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvdXJsLmpzPzAwMGMiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNldXJpID0gcmVxdWlyZSgncGFyc2V1cmknKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6dXJsJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSB1cmw7XG5cbi8qKlxuICogVVJMIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge09iamVjdH0gQW4gb2JqZWN0IG1lYW50IHRvIG1pbWljIHdpbmRvdy5sb2NhdGlvbi5cbiAqICAgICAgICAgICAgICAgICBEZWZhdWx0cyB0byB3aW5kb3cubG9jYXRpb24uXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIHVybCAodXJpLCBsb2MpIHtcbiAgdmFyIG9iaiA9IHVyaTtcblxuICAvLyBkZWZhdWx0IHRvIHdpbmRvdy5sb2NhdGlvblxuICBsb2MgPSBsb2MgfHwgZ2xvYmFsLmxvY2F0aW9uO1xuICBpZiAobnVsbCA9PSB1cmkpIHVyaSA9IGxvYy5wcm90b2NvbCArICcvLycgKyBsb2MuaG9zdDtcblxuICAvLyByZWxhdGl2ZSBwYXRoIHN1cHBvcnRcbiAgaWYgKCdzdHJpbmcnID09PSB0eXBlb2YgdXJpKSB7XG4gICAgaWYgKCcvJyA9PT0gdXJpLmNoYXJBdCgwKSkge1xuICAgICAgaWYgKCcvJyA9PT0gdXJpLmNoYXJBdCgxKSkge1xuICAgICAgICB1cmkgPSBsb2MucHJvdG9jb2wgKyB1cmk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cmkgPSBsb2MuaG9zdCArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIS9eKGh0dHBzP3x3c3M/KTpcXC9cXC8vLnRlc3QodXJpKSkge1xuICAgICAgZGVidWcoJ3Byb3RvY29sLWxlc3MgdXJsICVzJywgdXJpKTtcbiAgICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGxvYykge1xuICAgICAgICB1cmkgPSBsb2MucHJvdG9jb2wgKyAnLy8nICsgdXJpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdXJpID0gJ2h0dHBzOi8vJyArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBwYXJzZVxuICAgIGRlYnVnKCdwYXJzZSAlcycsIHVyaSk7XG4gICAgb2JqID0gcGFyc2V1cmkodXJpKTtcbiAgfVxuXG4gIC8vIG1ha2Ugc3VyZSB3ZSB0cmVhdCBgbG9jYWxob3N0OjgwYCBhbmQgYGxvY2FsaG9zdGAgZXF1YWxseVxuICBpZiAoIW9iai5wb3J0KSB7XG4gICAgaWYgKC9eKGh0dHB8d3MpJC8udGVzdChvYmoucHJvdG9jb2wpKSB7XG4gICAgICBvYmoucG9ydCA9ICc4MCc7XG4gICAgfSBlbHNlIGlmICgvXihodHRwfHdzKXMkLy50ZXN0KG9iai5wcm90b2NvbCkpIHtcbiAgICAgIG9iai5wb3J0ID0gJzQ0Myc7XG4gICAgfVxuICB9XG5cbiAgb2JqLnBhdGggPSBvYmoucGF0aCB8fCAnLyc7XG5cbiAgdmFyIGlwdjYgPSBvYmouaG9zdC5pbmRleE9mKCc6JykgIT09IC0xO1xuICB2YXIgaG9zdCA9IGlwdjYgPyAnWycgKyBvYmouaG9zdCArICddJyA6IG9iai5ob3N0O1xuXG4gIC8vIGRlZmluZSB1bmlxdWUgaWRcbiAgb2JqLmlkID0gb2JqLnByb3RvY29sICsgJzovLycgKyBob3N0ICsgJzonICsgb2JqLnBvcnQ7XG4gIC8vIGRlZmluZSBocmVmXG4gIG9iai5ocmVmID0gb2JqLnByb3RvY29sICsgJzovLycgKyBob3N0ICsgKGxvYyAmJiBsb2MucG9ydCA9PT0gb2JqLnBvcnQgPyAnJyA6ICgnOicgKyBvYmoucG9ydCkpO1xuXG4gIHJldHVybiBvYmo7XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///780f\n")},"7d91":function(module,exports){eval("\n/**\n * Gets the keys for an object.\n *\n * @return {Array} keys\n * @api private\n */\n\nmodule.exports = Object.keys || function keys (obj){\n  var arr = [];\n  var has = Object.prototype.hasOwnProperty;\n\n  for (var i in obj) {\n    if (has.call(obj, i)) {\n      arr.push(i);\n    }\n  }\n  return arr;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2Q5MS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIva2V5cy5qcz83NTljIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBHZXRzIHRoZSBrZXlzIGZvciBhbiBvYmplY3QuXG4gKlxuICogQHJldHVybiB7QXJyYXl9IGtleXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ga2V5cyAob2JqKXtcbiAgdmFyIGFyciA9IFtdO1xuICB2YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGkpKSB7XG4gICAgICBhcnIucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycjtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7d91\n")},"7fa4":function(module,exports,__webpack_require__){eval('var Collection = __webpack_require__(/*! ampersand-collection */ "7bd3");\nvar Filter = __webpack_require__(/*! ../filter */ "9476");\n\nmodule.exports = Collection.extend({\n  mainIndex: \'id\',\n  model: Filter,\n  comparator: function (a, b) {\n    if (a.row > b.row || a.row === b.row && a.col > b.col) {\n      return 1;\n    }\n    if (a.col === b.col) {\n      return 0;\n    }\n    return -1;\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2ZhNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmlsdGVyL2NvbGxlY3Rpb24uanM/ODgyYyJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgRmlsdGVyID0gcmVxdWlyZSgnLi4vZmlsdGVyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtYWluSW5kZXg6ICdpZCcsXG4gIG1vZGVsOiBGaWx0ZXIsXG4gIGNvbXBhcmF0b3I6IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgaWYgKGEucm93ID4gYi5yb3cgfHwgYS5yb3cgPT09IGIucm93ICYmIGEuY29sID4gYi5jb2wpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICBpZiAoYS5jb2wgPT09IGIuY29sKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7fa4\n')},8191:function(module,exports,__webpack_require__){eval("/**\n * Partition\n *\n * Describes a partitioning of the data, based on the values a Facet can take.\n *\n * @class Partition\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Groups = __webpack_require__(/*! ./partition/group-collection */ \"0056\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar selection = __webpack_require__(/*! ./util/selection */ \"1278\");\nvar util = __webpack_require__(/*! ./util/time */ \"d45b\");\n\n/*\n * @param {Partition} partition\n * @param {Group[]} groups\n * @memberof! Partition\n */\nfunction setDatetimeGroups (partition, groups) {\n  var timeStart = partition.minval;\n  var timeEnd = partition.maxval;\n  var timeRes = util.getDatetimeResolution(timeStart, timeEnd);\n  var timeZone = partition.zone;\n\n  var current = moment(timeStart);\n  while ((!current.isAfter(timeEnd)) && groups.length < 500) {\n    groups.add({\n      min: moment(current).tz(timeZone).startOf(timeRes),\n      max: moment(current).tz(timeZone).endOf(timeRes),\n      value: moment(current).tz(timeZone).startOf(timeRes).format(),\n      label: moment(current).tz(timeZone).startOf(timeRes).format()\n    });\n    current.add(1, timeRes);\n  }\n}\n\n/*\n * @param {Partition} partition\n * @param {Group[]} groups\n * @memberof! Partition\n */\nfunction setDurationGroups (partition, groups) {\n  var dStart = partition.minval;\n  var dEnd = partition.maxval;\n  var dRes = util.getDurationResolution(dStart, dEnd);\n\n  var current = Math.floor(parseFloat(dStart.as(dRes)));\n  var last = Math.floor(parseFloat(dEnd.as(dRes)));\n\n  while (current < last) {\n    groups.add({\n      min: moment.duration(current, dRes),\n      max: moment.duration(current + 1, dRes),\n      value: moment.duration(current, dRes).toISOString(),\n      label: moment.duration(current, dRes).toISOString()\n    });\n\n    current = current + 1;\n  }\n}\n\n/*\n * Setup a grouping based on the `partition.groupingContinuous`, `partition.minval`,\n * `partition.maxval`, and the `partition.groupingParam`.\n * @memberof! Partition\n * @param {Partition} partition\n * @param {Group[]} groups\n */\nfunction setContinuousGroups (partition, groups) {\n  var param = partition.groupingParam;\n  var x0, x1, size, nbins;\n\n  if (partition.groupFixedN) {\n    // A fixed number of equally sized bins\n    nbins = param;\n    x0 = partition.minval;\n    x1 = partition.maxval;\n    size = (x1 - x0) / nbins;\n  } else if (partition.groupFixedS) {\n    // A fixed bin size\n    size = param;\n    x0 = Math.floor(partition.minval / size) * size;\n    x1 = Math.ceil(partition.maxval / size) * size;\n    nbins = (x1 - x0) / size;\n  } else if (partition.groupFixedSC) {\n    // A fixed bin size, centered on 0\n    size = param;\n    x0 = (Math.floor(partition.minval / size) - 0.5) * size;\n    x1 = (Math.ceil(partition.maxval / size) + 0.5) * size;\n    nbins = (x1 - x0) / size;\n  } else if (partition.groupLog) {\n    // Fixed number of logarithmically (base 10) sized bins\n    nbins = param;\n    x0 = Math.log(partition.minval) / Math.log(10.0);\n    x1 = Math.log(partition.maxval) / Math.log(10.0);\n    size = (x1 - x0) / nbins;\n  }\n\n  function unlog (x) {\n    return Math.exp(x * Math.log(10));\n  }\n\n  var i;\n  for (i = 0; i < nbins; i++) {\n    var start = x0 + i * size;\n    var end = x0 + (i + 1) * size;\n    var mid = 0.5 * (start + end);\n\n    if (partition.groupLog) {\n      groups.add({\n        min: unlog(start),\n        max: unlog(end),\n        value: unlog(start),\n        label: unlog(end).toPrecision(5)\n      });\n    } else {\n      groups.add({\n        min: start,\n        max: end,\n        value: mid,\n        label: mid.toPrecision(5)\n      });\n    }\n  }\n}\n\n/*\n * Setup a grouping based on the `partition.categorialTransform`\n * @memberof! Partition\n * @param {Partition} partition\n * @param {Group[]} groups\n */\nfunction setCategorialGroups (partition, groups) {\n  // dataview -> filters -> filter -> partitions -> partition\n  //          -> facets\n\n  var dataview;\n  var facet;\n  try {\n    dataview = partition.collection.parent.collection.parent;\n    facet = dataview.facets.get(partition.facetName, 'name');\n  } catch (e) {\n    console.error('setCategorialGroups: cannot locate facet for this partition');\n    return;\n  }\n\n  if (facet.isCategorial) {\n    // default: a categorial facet, with a categorial parittion\n    facet.categorialTransform.rules.forEach(function (rule, i) {\n      groups.add({\n        value: rule.group,\n        label: rule.group,\n        count: rule.count\n      });\n    });\n  } else if (facet.isDatetime) {\n    var format = facet.datetimeTransform.transformedFormat;\n    var timePart = util.timeParts.get(format, 'description');\n\n    timePart.groups.forEach(function (g, i) {\n      groups.add({\n        value: g,\n        label: g,\n        count: 0\n      });\n    });\n  } else {\n    console.warn('Not implemented');\n  }\n}\n\n/**\n * Reset type, minimum and maximum values\n * @params {Partition} partition\n * @params {Object} Options - silent do not trigger change events\n * @memberof! Partition\n */\nfunction reset (options) {\n  var partition = this;\n  // partition -> partitions -> filter -> filters -> dataview\n  var filter = partition.collection.parent;\n  var dataview = filter.collection.parent;\n  var facet = dataview.facets.get(partition.facetName, 'name');\n  options = options || {};\n\n  partition.set({\n    type: facet.transform.transformedType,\n    minval: facet.transform.transformedMin,\n    maxval: facet.transform.transformedMax\n  }, options);\n}\n\nmodule.exports = BaseModel.extend({\n  dataTypes: {\n    'numberDatetimeOrDuration': {\n      set: function (value) {\n        var newValue;\n\n        // check for momentjs objects\n        if (moment.isDuration(value)) {\n          return {\n            val: moment.duration(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (moment.isMoment(value)) {\n          return {\n            val: value.clone(),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to create momentjs objects\n        newValue = moment(value, moment.ISO_8601);\n        if (newValue.isValid()) {\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          newValue = moment.duration(value);\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to set a number\n        if (value === +value) {\n          return {\n            val: +value,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // failed..\n        return {\n          val: value,\n          type: typeof value\n        };\n      },\n      compare: function (currentVal, newVal) {\n        if (currentVal instanceof moment) {\n          return currentVal.isSame(newVal);\n        } else {\n          return +currentVal === +newVal;\n        }\n      }\n    }\n  },\n  props: {\n    /**\n     * Label for displaying on plots\n     * @memberof! Partition\n     * @type {string}\n     */\n    label: {\n      type: 'string',\n      required: true,\n      default: ''\n    },\n    /**\n     * Show a legend for this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    showLegend: {\n      type: 'boolean',\n      required: false,\n      default: true\n    },\n    /**\n     * Show an axis label for this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    showLabel: {\n      type: 'boolean',\n      required: false,\n      default: true\n    },\n\n    /**\n     * Timezone for partitioning\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    zone: {\n      type: 'string',\n      required: 'true',\n      default: function () {\n        return moment.tz.guess();\n      }\n    },\n\n    /**\n     * Type of this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['constant', 'continuous', 'categorial', 'datetime', 'duration', 'text']\n    },\n\n    /**\n     * The name of the facet to partition over\n     * @memberof! Partition\n     * @type {string}\n     */\n    facetName: 'string',\n\n    /**\n     * When part of a partitioning, this deterimines the ordering\n     * @memberof! Partition\n     * @type {number}\n     */\n    rank: {\n      type: 'number',\n      required: true\n    },\n\n    /**\n     * For categorial and text Facets, the ordering can be alfabetical or by count\n     * @memberof! Partition\n     */\n    ordering: {\n      type: 'string',\n      values: ['count', 'value'],\n      required: true,\n      default: 'value'\n    },\n\n    /**\n     * For continuous or datetime Facets, the minimum value. Values lower than this are grouped to 'missing'\n     * @memberof! Partition\n     * @type {number|moment}\n     */\n    minval: 'numberDatetimeOrDuration',\n\n    /**\n     * For continuous or datetime Facets, the maximum value. Values higher than this are grouped to 'missing'\n     * @memberof! Partition\n     * @type {number|moment}\n     */\n    maxval: 'numberDatetimeOrDuration',\n\n    /**\n     * Extra parameter used in the grouping strategy: either the number of bins, or the bin size.\n     * @memberof! Partition\n     * @type {number}\n     */\n    groupingParam: ['number', true, 20],\n\n    /**\n     * Grouping strategy:\n     *  * `fixedn`  fixed number of bins in the interval [minval, maxval]\n     *  * `fixedsc` a fixed binsize, centered on zero\n     *  * `fixeds`  a fixed binsize, starting at zero\n     *  * `log`     fixed number of bins but on a logarithmic scale\n     * Don't use directly but check grouping via the groupFixedN, groupFixedSC,\n     * groupFixedS, and groupLog properties\n     * @memberof! Partition\n     * @type {number}\n     */\n    groupingContinuous: {\n      type: 'string',\n      required: true,\n      default: 'fixedn',\n      values: ['fixedn', 'fixedsc', 'fixeds', 'log']\n    },\n\n    /**\n     * Depending on the type of partition, this can be an array of the selected groups,\n     * or a numberic interval [start, end]\n     * @memberof! Partition\n     * @type {array}\n     */\n    // NOTE: for categorial facets, contains rule.group\n    selected: {\n      type: 'array',\n      required: true,\n      default: function () {\n        return [];\n      }\n    }\n  },\n  derived: {\n    // properties for: type\n    isConstant: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'constant';\n      }\n    },\n    isContinuous: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'continuous';\n      }\n    },\n    isCategorial: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'categorial';\n      }\n    },\n    isDatetime: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'datetime';\n      }\n    },\n    isDuration: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'duration';\n      }\n    },\n    isText: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'text';\n      }\n    },\n    // properties for grouping-continuous\n    groupFixedN: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixedn';\n      }\n    },\n    groupFixedSC: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixedsc';\n      }\n    },\n    groupFixedS: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixeds';\n      }\n    },\n    groupLog: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'log';\n      }\n    },\n    /**\n     * The (ordered) set of groups this Partition can take, making up this partition.\n     * The list is recalculated when any of the partition's properties change:\n     * 'groupingContinuous', 'groupingParam', 'minval', 'maxval', 'type', 'zone' change\n     * The list keeps itself sorted according to the partition.ordering\n     *\n     * Can be used for plotting etc.\n     * @memberof! Partition\n     * @type {Group[]}\n     */\n    groups: {\n      deps: ['groupingContinuous', 'groupingParam', 'minval', 'maxval', 'type', 'zone'],\n      fn: function () {\n        var partition = this;\n        var groups = new Groups([], {\n          parent: partition\n        });\n\n        if (partition.isCategorial) {\n          setCategorialGroups(partition, groups);\n        } else if (partition.isContinuous) {\n          setContinuousGroups(partition, groups);\n        } else if (partition.isDatetime) {\n          setDatetimeGroups(partition, groups);\n        } else if (partition.isDuration) {\n          setDurationGroups(partition, groups);\n        } else if (partition.isText) {\n          // no-op\n        } else {\n          console.error('Cannot set groups for partition', partition.getId());\n        }\n\n        return groups;\n      }\n    }\n  },\n  updateSelection: function (group) {\n    selection.updateSelection(this, group);\n  },\n  filterFunction: function () {\n    return selection.filterFunction(this);\n  },\n  reset: reset\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODE5MS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uLmpzPzUzODciXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQYXJ0aXRpb25cbiAqXG4gKiBEZXNjcmliZXMgYSBwYXJ0aXRpb25pbmcgb2YgdGhlIGRhdGEsIGJhc2VkIG9uIHRoZSB2YWx1ZXMgYSBGYWNldCBjYW4gdGFrZS5cbiAqXG4gKiBAY2xhc3MgUGFydGl0aW9uXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBCYXNlTW9kZWwgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIEdyb3VwcyA9IHJlcXVpcmUoJy4vcGFydGl0aW9uL2dyb3VwLWNvbGxlY3Rpb24nKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciBzZWxlY3Rpb24gPSByZXF1aXJlKCcuL3V0aWwvc2VsZWN0aW9uJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbC90aW1lJyk7XG5cbi8qXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKiBAcGFyYW0ge0dyb3VwW119IGdyb3Vwc1xuICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAqL1xuZnVuY3Rpb24gc2V0RGF0ZXRpbWVHcm91cHMgKHBhcnRpdGlvbiwgZ3JvdXBzKSB7XG4gIHZhciB0aW1lU3RhcnQgPSBwYXJ0aXRpb24ubWludmFsO1xuICB2YXIgdGltZUVuZCA9IHBhcnRpdGlvbi5tYXh2YWw7XG4gIHZhciB0aW1lUmVzID0gdXRpbC5nZXREYXRldGltZVJlc29sdXRpb24odGltZVN0YXJ0LCB0aW1lRW5kKTtcbiAgdmFyIHRpbWVab25lID0gcGFydGl0aW9uLnpvbmU7XG5cbiAgdmFyIGN1cnJlbnQgPSBtb21lbnQodGltZVN0YXJ0KTtcbiAgd2hpbGUgKCghY3VycmVudC5pc0FmdGVyKHRpbWVFbmQpKSAmJiBncm91cHMubGVuZ3RoIDwgNTAwKSB7XG4gICAgZ3JvdXBzLmFkZCh7XG4gICAgICBtaW46IG1vbWVudChjdXJyZW50KS50eih0aW1lWm9uZSkuc3RhcnRPZih0aW1lUmVzKSxcbiAgICAgIG1heDogbW9tZW50KGN1cnJlbnQpLnR6KHRpbWVab25lKS5lbmRPZih0aW1lUmVzKSxcbiAgICAgIHZhbHVlOiBtb21lbnQoY3VycmVudCkudHoodGltZVpvbmUpLnN0YXJ0T2YodGltZVJlcykuZm9ybWF0KCksXG4gICAgICBsYWJlbDogbW9tZW50KGN1cnJlbnQpLnR6KHRpbWVab25lKS5zdGFydE9mKHRpbWVSZXMpLmZvcm1hdCgpXG4gICAgfSk7XG4gICAgY3VycmVudC5hZGQoMSwgdGltZVJlcyk7XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7R3JvdXBbXX0gZ3JvdXBzXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBzZXREdXJhdGlvbkdyb3VwcyAocGFydGl0aW9uLCBncm91cHMpIHtcbiAgdmFyIGRTdGFydCA9IHBhcnRpdGlvbi5taW52YWw7XG4gIHZhciBkRW5kID0gcGFydGl0aW9uLm1heHZhbDtcbiAgdmFyIGRSZXMgPSB1dGlsLmdldER1cmF0aW9uUmVzb2x1dGlvbihkU3RhcnQsIGRFbmQpO1xuXG4gIHZhciBjdXJyZW50ID0gTWF0aC5mbG9vcihwYXJzZUZsb2F0KGRTdGFydC5hcyhkUmVzKSkpO1xuICB2YXIgbGFzdCA9IE1hdGguZmxvb3IocGFyc2VGbG9hdChkRW5kLmFzKGRSZXMpKSk7XG5cbiAgd2hpbGUgKGN1cnJlbnQgPCBsYXN0KSB7XG4gICAgZ3JvdXBzLmFkZCh7XG4gICAgICBtaW46IG1vbWVudC5kdXJhdGlvbihjdXJyZW50LCBkUmVzKSxcbiAgICAgIG1heDogbW9tZW50LmR1cmF0aW9uKGN1cnJlbnQgKyAxLCBkUmVzKSxcbiAgICAgIHZhbHVlOiBtb21lbnQuZHVyYXRpb24oY3VycmVudCwgZFJlcykudG9JU09TdHJpbmcoKSxcbiAgICAgIGxhYmVsOiBtb21lbnQuZHVyYXRpb24oY3VycmVudCwgZFJlcykudG9JU09TdHJpbmcoKVxuICAgIH0pO1xuXG4gICAgY3VycmVudCA9IGN1cnJlbnQgKyAxO1xuICB9XG59XG5cbi8qXG4gKiBTZXR1cCBhIGdyb3VwaW5nIGJhc2VkIG9uIHRoZSBgcGFydGl0aW9uLmdyb3VwaW5nQ29udGludW91c2AsIGBwYXJ0aXRpb24ubWludmFsYCxcbiAqIGBwYXJ0aXRpb24ubWF4dmFsYCwgYW5kIHRoZSBgcGFydGl0aW9uLmdyb3VwaW5nUGFyYW1gLlxuICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7R3JvdXBbXX0gZ3JvdXBzXG4gKi9cbmZ1bmN0aW9uIHNldENvbnRpbnVvdXNHcm91cHMgKHBhcnRpdGlvbiwgZ3JvdXBzKSB7XG4gIHZhciBwYXJhbSA9IHBhcnRpdGlvbi5ncm91cGluZ1BhcmFtO1xuICB2YXIgeDAsIHgxLCBzaXplLCBuYmlucztcblxuICBpZiAocGFydGl0aW9uLmdyb3VwRml4ZWROKSB7XG4gICAgLy8gQSBmaXhlZCBudW1iZXIgb2YgZXF1YWxseSBzaXplZCBiaW5zXG4gICAgbmJpbnMgPSBwYXJhbTtcbiAgICB4MCA9IHBhcnRpdGlvbi5taW52YWw7XG4gICAgeDEgPSBwYXJ0aXRpb24ubWF4dmFsO1xuICAgIHNpemUgPSAoeDEgLSB4MCkgLyBuYmlucztcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uZ3JvdXBGaXhlZFMpIHtcbiAgICAvLyBBIGZpeGVkIGJpbiBzaXplXG4gICAgc2l6ZSA9IHBhcmFtO1xuICAgIHgwID0gTWF0aC5mbG9vcihwYXJ0aXRpb24ubWludmFsIC8gc2l6ZSkgKiBzaXplO1xuICAgIHgxID0gTWF0aC5jZWlsKHBhcnRpdGlvbi5tYXh2YWwgLyBzaXplKSAqIHNpemU7XG4gICAgbmJpbnMgPSAoeDEgLSB4MCkgLyBzaXplO1xuICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5ncm91cEZpeGVkU0MpIHtcbiAgICAvLyBBIGZpeGVkIGJpbiBzaXplLCBjZW50ZXJlZCBvbiAwXG4gICAgc2l6ZSA9IHBhcmFtO1xuICAgIHgwID0gKE1hdGguZmxvb3IocGFydGl0aW9uLm1pbnZhbCAvIHNpemUpIC0gMC41KSAqIHNpemU7XG4gICAgeDEgPSAoTWF0aC5jZWlsKHBhcnRpdGlvbi5tYXh2YWwgLyBzaXplKSArIDAuNSkgKiBzaXplO1xuICAgIG5iaW5zID0gKHgxIC0geDApIC8gc2l6ZTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAvLyBGaXhlZCBudW1iZXIgb2YgbG9nYXJpdGhtaWNhbGx5IChiYXNlIDEwKSBzaXplZCBiaW5zXG4gICAgbmJpbnMgPSBwYXJhbTtcbiAgICB4MCA9IE1hdGgubG9nKHBhcnRpdGlvbi5taW52YWwpIC8gTWF0aC5sb2coMTAuMCk7XG4gICAgeDEgPSBNYXRoLmxvZyhwYXJ0aXRpb24ubWF4dmFsKSAvIE1hdGgubG9nKDEwLjApO1xuICAgIHNpemUgPSAoeDEgLSB4MCkgLyBuYmlucztcbiAgfVxuXG4gIGZ1bmN0aW9uIHVubG9nICh4KSB7XG4gICAgcmV0dXJuIE1hdGguZXhwKHggKiBNYXRoLmxvZygxMCkpO1xuICB9XG5cbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBuYmluczsgaSsrKSB7XG4gICAgdmFyIHN0YXJ0ID0geDAgKyBpICogc2l6ZTtcbiAgICB2YXIgZW5kID0geDAgKyAoaSArIDEpICogc2l6ZTtcbiAgICB2YXIgbWlkID0gMC41ICogKHN0YXJ0ICsgZW5kKTtcblxuICAgIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAgIGdyb3Vwcy5hZGQoe1xuICAgICAgICBtaW46IHVubG9nKHN0YXJ0KSxcbiAgICAgICAgbWF4OiB1bmxvZyhlbmQpLFxuICAgICAgICB2YWx1ZTogdW5sb2coc3RhcnQpLFxuICAgICAgICBsYWJlbDogdW5sb2coZW5kKS50b1ByZWNpc2lvbig1KVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdyb3Vwcy5hZGQoe1xuICAgICAgICBtaW46IHN0YXJ0LFxuICAgICAgICBtYXg6IGVuZCxcbiAgICAgICAgdmFsdWU6IG1pZCxcbiAgICAgICAgbGFiZWw6IG1pZC50b1ByZWNpc2lvbig1KVxuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qXG4gKiBTZXR1cCBhIGdyb3VwaW5nIGJhc2VkIG9uIHRoZSBgcGFydGl0aW9uLmNhdGVnb3JpYWxUcmFuc2Zvcm1gXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICogQHBhcmFtIHtHcm91cFtdfSBncm91cHNcbiAqL1xuZnVuY3Rpb24gc2V0Q2F0ZWdvcmlhbEdyb3VwcyAocGFydGl0aW9uLCBncm91cHMpIHtcbiAgLy8gZGF0YXZpZXcgLT4gZmlsdGVycyAtPiBmaWx0ZXIgLT4gcGFydGl0aW9ucyAtPiBwYXJ0aXRpb25cbiAgLy8gICAgICAgICAgLT4gZmFjZXRzXG5cbiAgdmFyIGRhdGF2aWV3O1xuICB2YXIgZmFjZXQ7XG4gIHRyeSB7XG4gICAgZGF0YXZpZXcgPSBwYXJ0aXRpb24uY29sbGVjdGlvbi5wYXJlbnQuY29sbGVjdGlvbi5wYXJlbnQ7XG4gICAgZmFjZXQgPSBkYXRhdmlldy5mYWNldHMuZ2V0KHBhcnRpdGlvbi5mYWNldE5hbWUsICduYW1lJyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKCdzZXRDYXRlZ29yaWFsR3JvdXBzOiBjYW5ub3QgbG9jYXRlIGZhY2V0IGZvciB0aGlzIHBhcnRpdGlvbicpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmYWNldC5pc0NhdGVnb3JpYWwpIHtcbiAgICAvLyBkZWZhdWx0OiBhIGNhdGVnb3JpYWwgZmFjZXQsIHdpdGggYSBjYXRlZ29yaWFsIHBhcml0dGlvblxuICAgIGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuZm9yRWFjaChmdW5jdGlvbiAocnVsZSwgaSkge1xuICAgICAgZ3JvdXBzLmFkZCh7XG4gICAgICAgIHZhbHVlOiBydWxlLmdyb3VwLFxuICAgICAgICBsYWJlbDogcnVsZS5ncm91cCxcbiAgICAgICAgY291bnQ6IHJ1bGUuY291bnRcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICB2YXIgZm9ybWF0ID0gZmFjZXQuZGF0ZXRpbWVUcmFuc2Zvcm0udHJhbnNmb3JtZWRGb3JtYXQ7XG4gICAgdmFyIHRpbWVQYXJ0ID0gdXRpbC50aW1lUGFydHMuZ2V0KGZvcm1hdCwgJ2Rlc2NyaXB0aW9uJyk7XG5cbiAgICB0aW1lUGFydC5ncm91cHMuZm9yRWFjaChmdW5jdGlvbiAoZywgaSkge1xuICAgICAgZ3JvdXBzLmFkZCh7XG4gICAgICAgIHZhbHVlOiBnLFxuICAgICAgICBsYWJlbDogZyxcbiAgICAgICAgY291bnQ6IDBcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUud2FybignTm90IGltcGxlbWVudGVkJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNldCB0eXBlLCBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlc1xuICogQHBhcmFtcyB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbXMge09iamVjdH0gT3B0aW9ucyAtIHNpbGVudCBkbyBub3QgdHJpZ2dlciBjaGFuZ2UgZXZlbnRzXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICovXG5mdW5jdGlvbiByZXNldCAob3B0aW9ucykge1xuICB2YXIgcGFydGl0aW9uID0gdGhpcztcbiAgLy8gcGFydGl0aW9uIC0+IHBhcnRpdGlvbnMgLT4gZmlsdGVyIC0+IGZpbHRlcnMgLT4gZGF0YXZpZXdcbiAgdmFyIGZpbHRlciA9IHBhcnRpdGlvbi5jb2xsZWN0aW9uLnBhcmVudDtcbiAgdmFyIGRhdGF2aWV3ID0gZmlsdGVyLmNvbGxlY3Rpb24ucGFyZW50O1xuICB2YXIgZmFjZXQgPSBkYXRhdmlldy5mYWNldHMuZ2V0KHBhcnRpdGlvbi5mYWNldE5hbWUsICduYW1lJyk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHBhcnRpdGlvbi5zZXQoe1xuICAgIHR5cGU6IGZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZFR5cGUsXG4gICAgbWludmFsOiBmYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW4sXG4gICAgbWF4dmFsOiBmYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNYXhcbiAgfSwgb3B0aW9ucyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIGRhdGFUeXBlczoge1xuICAgICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nOiB7XG4gICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIG1vbWVudGpzIG9iamVjdHNcbiAgICAgICAgaWYgKG1vbWVudC5pc0R1cmF0aW9uKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG1vbWVudC5kdXJhdGlvbih2YWx1ZSksXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vbWVudC5pc01vbWVudCh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsOiB2YWx1ZS5jbG9uZSgpLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIGNyZWF0ZSBtb21lbnRqcyBvYmplY3RzXG4gICAgICAgIG5ld1ZhbHVlID0gbW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICBpZiAobmV3VmFsdWUuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbDogbmV3VmFsdWUsXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSB7XG4gICAgICAgICAgbmV3VmFsdWUgPSBtb21lbnQuZHVyYXRpb24odmFsdWUpO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG5ld1ZhbHVlLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIHNldCBhIG51bWJlclxuICAgICAgICBpZiAodmFsdWUgPT09ICt2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6ICt2YWx1ZSxcbiAgICAgICAgICAgIHR5cGU6ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZhaWxlZC4uXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsOiB2YWx1ZSxcbiAgICAgICAgICB0eXBlOiB0eXBlb2YgdmFsdWVcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBjb21wYXJlOiBmdW5jdGlvbiAoY3VycmVudFZhbCwgbmV3VmFsKSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsIGluc3RhbmNlb2YgbW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuIGN1cnJlbnRWYWwuaXNTYW1lKG5ld1ZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICtjdXJyZW50VmFsID09PSArbmV3VmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIExhYmVsIGZvciBkaXNwbGF5aW5nIG9uIHBsb3RzXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGxhYmVsOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJydcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFNob3cgYSBsZWdlbmQgZm9yIHRoaXMgcGFydGl0aW9uXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHNob3dMZWdlbmQ6IHtcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgIGRlZmF1bHQ6IHRydWVcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFNob3cgYW4gYXhpcyBsYWJlbCBmb3IgdGhpcyBwYXJ0aXRpb25cbiAgICAgKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgc2hvd0xhYmVsOiB7XG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICBkZWZhdWx0OiB0cnVlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRpbWV6b25lIGZvciBwYXJ0aXRpb25pbmdcbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB6b25lOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiAndHJ1ZScsXG4gICAgICBkZWZhdWx0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiB0aGlzIHBhcnRpdGlvblxuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0eXBlOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ2NhdGVnb3JpYWwnLFxuICAgICAgdmFsdWVzOiBbJ2NvbnN0YW50JywgJ2NvbnRpbnVvdXMnLCAnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICd0ZXh0J11cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGZhY2V0IHRvIHBhcnRpdGlvbiBvdmVyXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZhY2V0TmFtZTogJ3N0cmluZycsXG5cbiAgICAvKipcbiAgICAgKiBXaGVuIHBhcnQgb2YgYSBwYXJ0aXRpb25pbmcsIHRoaXMgZGV0ZXJpbWluZXMgdGhlIG9yZGVyaW5nXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHJhbms6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNhdGVnb3JpYWwgYW5kIHRleHQgRmFjZXRzLCB0aGUgb3JkZXJpbmcgY2FuIGJlIGFsZmFiZXRpY2FsIG9yIGJ5IGNvdW50XG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKi9cbiAgICBvcmRlcmluZzoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICB2YWx1ZXM6IFsnY291bnQnLCAndmFsdWUnXSxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ3ZhbHVlJ1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBGb3IgY29udGludW91cyBvciBkYXRldGltZSBGYWNldHMsIHRoZSBtaW5pbXVtIHZhbHVlLiBWYWx1ZXMgbG93ZXIgdGhhbiB0aGlzIGFyZSBncm91cGVkIHRvICdtaXNzaW5nJ1xuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICovXG4gICAgbWludmFsOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJyxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1heGltdW0gdmFsdWUuIFZhbHVlcyBoaWdoZXIgdGhhbiB0aGlzIGFyZSBncm91cGVkIHRvICdtaXNzaW5nJ1xuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICovXG4gICAgbWF4dmFsOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJyxcblxuICAgIC8qKlxuICAgICAqIEV4dHJhIHBhcmFtZXRlciB1c2VkIGluIHRoZSBncm91cGluZyBzdHJhdGVneTogZWl0aGVyIHRoZSBudW1iZXIgb2YgYmlucywgb3IgdGhlIGJpbiBzaXplLlxuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBncm91cGluZ1BhcmFtOiBbJ251bWJlcicsIHRydWUsIDIwXSxcblxuICAgIC8qKlxuICAgICAqIEdyb3VwaW5nIHN0cmF0ZWd5OlxuICAgICAqICAqIGBmaXhlZG5gICBmaXhlZCBudW1iZXIgb2YgYmlucyBpbiB0aGUgaW50ZXJ2YWwgW21pbnZhbCwgbWF4dmFsXVxuICAgICAqICAqIGBmaXhlZHNjYCBhIGZpeGVkIGJpbnNpemUsIGNlbnRlcmVkIG9uIHplcm9cbiAgICAgKiAgKiBgZml4ZWRzYCAgYSBmaXhlZCBiaW5zaXplLCBzdGFydGluZyBhdCB6ZXJvXG4gICAgICogICogYGxvZ2AgICAgIGZpeGVkIG51bWJlciBvZiBiaW5zIGJ1dCBvbiBhIGxvZ2FyaXRobWljIHNjYWxlXG4gICAgICogRG9uJ3QgdXNlIGRpcmVjdGx5IGJ1dCBjaGVjayBncm91cGluZyB2aWEgdGhlIGdyb3VwRml4ZWROLCBncm91cEZpeGVkU0MsXG4gICAgICogZ3JvdXBGaXhlZFMsIGFuZCBncm91cExvZyBwcm9wZXJ0aWVzXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdyb3VwaW5nQ29udGludW91czoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICdmaXhlZG4nLFxuICAgICAgdmFsdWVzOiBbJ2ZpeGVkbicsICdmaXhlZHNjJywgJ2ZpeGVkcycsICdsb2cnXVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBEZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgcGFydGl0aW9uLCB0aGlzIGNhbiBiZSBhbiBhcnJheSBvZiB0aGUgc2VsZWN0ZWQgZ3JvdXBzLFxuICAgICAqIG9yIGEgbnVtYmVyaWMgaW50ZXJ2YWwgW3N0YXJ0LCBlbmRdXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7YXJyYXl9XG4gICAgICovXG4gICAgLy8gTk9URTogZm9yIGNhdGVnb3JpYWwgZmFjZXRzLCBjb250YWlucyBydWxlLmdyb3VwXG4gICAgc2VsZWN0ZWQ6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgZGVyaXZlZDoge1xuICAgIC8vIHByb3BlcnRpZXMgZm9yOiB0eXBlXG4gICAgaXNDb25zdGFudDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAnY29uc3RhbnQnO1xuICAgICAgfVxuICAgIH0sXG4gICAgaXNDb250aW51b3VzOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjb250aW51b3VzJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzQ2F0ZWdvcmlhbDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAnY2F0ZWdvcmlhbCc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0RhdGV0aW1lOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdkYXRldGltZSc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0R1cmF0aW9uOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdkdXJhdGlvbic7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ3RleHQnO1xuICAgICAgfVxuICAgIH0sXG4gICAgLy8gcHJvcGVydGllcyBmb3IgZ3JvdXBpbmctY29udGludW91c1xuICAgIGdyb3VwRml4ZWROOiB7XG4gICAgICBkZXBzOiBbJ2dyb3VwaW5nQ29udGludW91cyddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JvdXBpbmdDb250aW51b3VzID09PSAnZml4ZWRuJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGdyb3VwRml4ZWRTQzoge1xuICAgICAgZGVwczogWydncm91cGluZ0NvbnRpbnVvdXMnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyb3VwaW5nQ29udGludW91cyA9PT0gJ2ZpeGVkc2MnO1xuICAgICAgfVxuICAgIH0sXG4gICAgZ3JvdXBGaXhlZFM6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cGluZ0NvbnRpbnVvdXMgPT09ICdmaXhlZHMnO1xuICAgICAgfVxuICAgIH0sXG4gICAgZ3JvdXBMb2c6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cGluZ0NvbnRpbnVvdXMgPT09ICdsb2cnO1xuICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIChvcmRlcmVkKSBzZXQgb2YgZ3JvdXBzIHRoaXMgUGFydGl0aW9uIGNhbiB0YWtlLCBtYWtpbmcgdXAgdGhpcyBwYXJ0aXRpb24uXG4gICAgICogVGhlIGxpc3QgaXMgcmVjYWxjdWxhdGVkIHdoZW4gYW55IG9mIHRoZSBwYXJ0aXRpb24ncyBwcm9wZXJ0aWVzIGNoYW5nZTpcbiAgICAgKiAnZ3JvdXBpbmdDb250aW51b3VzJywgJ2dyb3VwaW5nUGFyYW0nLCAnbWludmFsJywgJ21heHZhbCcsICd0eXBlJywgJ3pvbmUnIGNoYW5nZVxuICAgICAqIFRoZSBsaXN0IGtlZXBzIGl0c2VsZiBzb3J0ZWQgYWNjb3JkaW5nIHRvIHRoZSBwYXJ0aXRpb24ub3JkZXJpbmdcbiAgICAgKlxuICAgICAqIENhbiBiZSB1c2VkIGZvciBwbG90dGluZyBldGMuXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7R3JvdXBbXX1cbiAgICAgKi9cbiAgICBncm91cHM6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJywgJ2dyb3VwaW5nUGFyYW0nLCAnbWludmFsJywgJ21heHZhbCcsICd0eXBlJywgJ3pvbmUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwYXJ0aXRpb24gPSB0aGlzO1xuICAgICAgICB2YXIgZ3JvdXBzID0gbmV3IEdyb3VwcyhbXSwge1xuICAgICAgICAgIHBhcmVudDogcGFydGl0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChwYXJ0aXRpb24uaXNDYXRlZ29yaWFsKSB7XG4gICAgICAgICAgc2V0Q2F0ZWdvcmlhbEdyb3VwcyhwYXJ0aXRpb24sIGdyb3Vwcyk7XG4gICAgICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzQ29udGludW91cykge1xuICAgICAgICAgIHNldENvbnRpbnVvdXNHcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0RhdGV0aW1lKSB7XG4gICAgICAgICAgc2V0RGF0ZXRpbWVHcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0R1cmF0aW9uKSB7XG4gICAgICAgICAgc2V0RHVyYXRpb25Hcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc1RleHQpIHtcbiAgICAgICAgICAvLyBuby1vcFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Nhbm5vdCBzZXQgZ3JvdXBzIGZvciBwYXJ0aXRpb24nLCBwYXJ0aXRpb24uZ2V0SWQoKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ3JvdXBzO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgdXBkYXRlU2VsZWN0aW9uOiBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICBzZWxlY3Rpb24udXBkYXRlU2VsZWN0aW9uKHRoaXMsIGdyb3VwKTtcbiAgfSxcbiAgZmlsdGVyRnVuY3Rpb246IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gc2VsZWN0aW9uLmZpbHRlckZ1bmN0aW9uKHRoaXMpO1xuICB9LFxuICByZXNldDogcmVzZXRcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8191\n")},8233:function(module,exports,__webpack_require__){eval("\n/**\n * This is the web browser implementation of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = __webpack_require__(/*! ./debug */ \"bb16\");\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = 'undefined' != typeof chrome\n               && 'undefined' != typeof chrome.storage\n                  ? chrome.storage.local\n                  : localstorage();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n  'lightseagreen',\n  'forestgreen',\n  'goldenrod',\n  'dodgerblue',\n  'darkorchid',\n  'crimson'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\nfunction useColors() {\n  // is webkit? http://stackoverflow.com/a/16459606/376773\n  return ('WebkitAppearance' in document.documentElement.style) ||\n    // is firebug? http://stackoverflow.com/a/398120/376773\n    (window.console && (console.firebug || (console.exception && console.table))) ||\n    // is firefox >= v31?\n    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n    (navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31);\n}\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nexports.formatters.j = function(v) {\n  return JSON.stringify(v);\n};\n\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs() {\n  var args = arguments;\n  var useColors = this.useColors;\n\n  args[0] = (useColors ? '%c' : '')\n    + this.namespace\n    + (useColors ? ' %c' : ' ')\n    + args[0]\n    + (useColors ? '%c ' : ' ')\n    + '+' + exports.humanize(this.diff);\n\n  if (!useColors) return args;\n\n  var c = 'color: ' + this.color;\n  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));\n\n  // the final \"%c\" is somewhat tricky, because there could be other\n  // arguments passed either before or after the %c, so we need to\n  // figure out the correct index to insert the CSS into\n  var index = 0;\n  var lastC = 0;\n  args[0].replace(/%[a-z%]/g, function(match) {\n    if ('%%' === match) return;\n    index++;\n    if ('%c' === match) {\n      // we only are interested in the *last* %c\n      // (the user may have provided their own)\n      lastC = index;\n    }\n  });\n\n  args.splice(lastC, 0, c);\n  return args;\n}\n\n/**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\nfunction log() {\n  // this hackery is required for IE8/9, where\n  // the `console.log` function doesn't have 'apply'\n  return 'object' === typeof console\n    && console.log\n    && Function.prototype.apply.call(console.log, console, arguments);\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\nfunction save(namespaces) {\n  try {\n    if (null == namespaces) {\n      exports.storage.removeItem('debug');\n    } else {\n      exports.storage.debug = namespaces;\n    }\n  } catch(e) {}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n  var r;\n  try {\n    r = exports.storage.debug;\n  } catch(e) {}\n  return r;\n}\n\n/**\n * Enable namespaces listed in `localStorage.debug` initially.\n */\n\nexports.enable(load());\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage(){\n  try {\n    return window.localStorage;\n  } catch (e) {}\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvZGVidWcvYnJvd3Nlci5qcz80ZDVhIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSB3ZWIgYnJvd3NlciBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gKlxuICogRXhwb3NlIGBkZWJ1ZygpYCBhcyB0aGUgbW9kdWxlLlxuICovXG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZGVidWcnKTtcbmV4cG9ydHMubG9nID0gbG9nO1xuZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbmV4cG9ydHMuc2F2ZSA9IHNhdmU7XG5leHBvcnRzLmxvYWQgPSBsb2FkO1xuZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG5leHBvcnRzLnN0b3JhZ2UgPSAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lXG4gICAgICAgICAgICAgICAmJiAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lLnN0b3JhZ2VcbiAgICAgICAgICAgICAgICAgID8gY2hyb21lLnN0b3JhZ2UubG9jYWxcbiAgICAgICAgICAgICAgICAgIDogbG9jYWxzdG9yYWdlKCk7XG5cbi8qKlxuICogQ29sb3JzLlxuICovXG5cbmV4cG9ydHMuY29sb3JzID0gW1xuICAnbGlnaHRzZWFncmVlbicsXG4gICdmb3Jlc3RncmVlbicsXG4gICdnb2xkZW5yb2QnLFxuICAnZG9kZ2VyYmx1ZScsXG4gICdkYXJrb3JjaGlkJyxcbiAgJ2NyaW1zb24nXG5dO1xuXG4vKipcbiAqIEN1cnJlbnRseSBvbmx5IFdlYktpdC1iYXNlZCBXZWIgSW5zcGVjdG9ycywgRmlyZWZveCA+PSB2MzEsXG4gKiBhbmQgdGhlIEZpcmVidWcgZXh0ZW5zaW9uIChhbnkgRmlyZWZveCB2ZXJzaW9uKSBhcmUga25vd25cbiAqIHRvIHN1cHBvcnQgXCIlY1wiIENTUyBjdXN0b21pemF0aW9ucy5cbiAqXG4gKiBUT0RPOiBhZGQgYSBgbG9jYWxTdG9yYWdlYCB2YXJpYWJsZSB0byBleHBsaWNpdGx5IGVuYWJsZS9kaXNhYmxlIGNvbG9yc1xuICovXG5cbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcbiAgLy8gaXMgd2Via2l0PyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNjQ1OTYwNi8zNzY3NzNcbiAgcmV0dXJuICgnV2Via2l0QXBwZWFyYW5jZScgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlKSB8fFxuICAgIC8vIGlzIGZpcmVidWc/IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM5ODEyMC8zNzY3NzNcbiAgICAod2luZG93LmNvbnNvbGUgJiYgKGNvbnNvbGUuZmlyZWJ1ZyB8fCAoY29uc29sZS5leGNlcHRpb24gJiYgY29uc29sZS50YWJsZSkpKSB8fFxuICAgIC8vIGlzIGZpcmVmb3ggPj0gdjMxP1xuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvVG9vbHMvV2ViX0NvbnNvbGUjU3R5bGluZ19tZXNzYWdlc1xuICAgIChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkubWF0Y2goL2ZpcmVmb3hcXC8oXFxkKykvKSAmJiBwYXJzZUludChSZWdFeHAuJDEsIDEwKSA+PSAzMSk7XG59XG5cbi8qKlxuICogTWFwICVqIHRvIGBKU09OLnN0cmluZ2lmeSgpYCwgc2luY2Ugbm8gV2ViIEluc3BlY3RvcnMgZG8gdGhhdCBieSBkZWZhdWx0LlxuICovXG5cbmV4cG9ydHMuZm9ybWF0dGVycy5qID0gZnVuY3Rpb24odikge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodik7XG59O1xuXG5cbi8qKlxuICogQ29sb3JpemUgbG9nIGFyZ3VtZW50cyBpZiBlbmFibGVkLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZm9ybWF0QXJncygpIHtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciB1c2VDb2xvcnMgPSB0aGlzLnVzZUNvbG9ycztcblxuICBhcmdzWzBdID0gKHVzZUNvbG9ycyA/ICclYycgOiAnJylcbiAgICArIHRoaXMubmFtZXNwYWNlXG4gICAgKyAodXNlQ29sb3JzID8gJyAlYycgOiAnICcpXG4gICAgKyBhcmdzWzBdXG4gICAgKyAodXNlQ29sb3JzID8gJyVjICcgOiAnICcpXG4gICAgKyAnKycgKyBleHBvcnRzLmh1bWFuaXplKHRoaXMuZGlmZik7XG5cbiAgaWYgKCF1c2VDb2xvcnMpIHJldHVybiBhcmdzO1xuXG4gIHZhciBjID0gJ2NvbG9yOiAnICsgdGhpcy5jb2xvcjtcbiAgYXJncyA9IFthcmdzWzBdLCBjLCAnY29sb3I6IGluaGVyaXQnXS5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncywgMSkpO1xuXG4gIC8vIHRoZSBmaW5hbCBcIiVjXCIgaXMgc29tZXdoYXQgdHJpY2t5LCBiZWNhdXNlIHRoZXJlIGNvdWxkIGJlIG90aGVyXG4gIC8vIGFyZ3VtZW50cyBwYXNzZWQgZWl0aGVyIGJlZm9yZSBvciBhZnRlciB0aGUgJWMsIHNvIHdlIG5lZWQgdG9cbiAgLy8gZmlndXJlIG91dCB0aGUgY29ycmVjdCBpbmRleCB0byBpbnNlcnQgdGhlIENTUyBpbnRvXG4gIHZhciBpbmRleCA9IDA7XG4gIHZhciBsYXN0QyA9IDA7XG4gIGFyZ3NbMF0ucmVwbGFjZSgvJVthLXolXS9nLCBmdW5jdGlvbihtYXRjaCkge1xuICAgIGlmICgnJSUnID09PSBtYXRjaCkgcmV0dXJuO1xuICAgIGluZGV4Kys7XG4gICAgaWYgKCclYycgPT09IG1hdGNoKSB7XG4gICAgICAvLyB3ZSBvbmx5IGFyZSBpbnRlcmVzdGVkIGluIHRoZSAqbGFzdCogJWNcbiAgICAgIC8vICh0aGUgdXNlciBtYXkgaGF2ZSBwcm92aWRlZCB0aGVpciBvd24pXG4gICAgICBsYXN0QyA9IGluZGV4O1xuICAgIH1cbiAgfSk7XG5cbiAgYXJncy5zcGxpY2UobGFzdEMsIDAsIGMpO1xuICByZXR1cm4gYXJncztcbn1cblxuLyoqXG4gKiBJbnZva2VzIGBjb25zb2xlLmxvZygpYCB3aGVuIGF2YWlsYWJsZS5cbiAqIE5vLW9wIHdoZW4gYGNvbnNvbGUubG9nYCBpcyBub3QgYSBcImZ1bmN0aW9uXCIuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBsb2coKSB7XG4gIC8vIHRoaXMgaGFja2VyeSBpcyByZXF1aXJlZCBmb3IgSUU4LzksIHdoZXJlXG4gIC8vIHRoZSBgY29uc29sZS5sb2dgIGZ1bmN0aW9uIGRvZXNuJ3QgaGF2ZSAnYXBwbHknXG4gIHJldHVybiAnb2JqZWN0JyA9PT0gdHlwZW9mIGNvbnNvbGVcbiAgICAmJiBjb25zb2xlLmxvZ1xuICAgICYmIEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKGNvbnNvbGUubG9nLCBjb25zb2xlLCBhcmd1bWVudHMpO1xufVxuXG4vKipcbiAqIFNhdmUgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lc3BhY2VzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzYXZlKG5hbWVzcGFjZXMpIHtcbiAgdHJ5IHtcbiAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2VzKSB7XG4gICAgICBleHBvcnRzLnN0b3JhZ2UucmVtb3ZlSXRlbSgnZGVidWcnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhwb3J0cy5zdG9yYWdlLmRlYnVnID0gbmFtZXNwYWNlcztcbiAgICB9XG4gIH0gY2F0Y2goZSkge31cbn1cblxuLyoqXG4gKiBMb2FkIGBuYW1lc3BhY2VzYC5cbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHJldHVybnMgdGhlIHByZXZpb3VzbHkgcGVyc2lzdGVkIGRlYnVnIG1vZGVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2FkKCkge1xuICB2YXIgcjtcbiAgdHJ5IHtcbiAgICByID0gZXhwb3J0cy5zdG9yYWdlLmRlYnVnO1xuICB9IGNhdGNoKGUpIHt9XG4gIHJldHVybiByO1xufVxuXG4vKipcbiAqIEVuYWJsZSBuYW1lc3BhY2VzIGxpc3RlZCBpbiBgbG9jYWxTdG9yYWdlLmRlYnVnYCBpbml0aWFsbHkuXG4gKi9cblxuZXhwb3J0cy5lbmFibGUobG9hZCgpKTtcblxuLyoqXG4gKiBMb2NhbHN0b3JhZ2UgYXR0ZW1wdHMgdG8gcmV0dXJuIHRoZSBsb2NhbHN0b3JhZ2UuXG4gKlxuICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBzYWZhcmkgdGhyb3dzXG4gKiB3aGVuIGEgdXNlciBkaXNhYmxlcyBjb29raWVzL2xvY2Fsc3RvcmFnZVxuICogYW5kIHlvdSBhdHRlbXB0IHRvIGFjY2VzcyBpdC5cbiAqXG4gKiBAcmV0dXJuIHtMb2NhbFN0b3JhZ2V9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2NhbHN0b3JhZ2UoKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZTtcbiAgfSBjYXRjaCAoZSkge31cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8233\n")},"834b":function(module,exports,__webpack_require__){eval('/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies\n */\n\nvar XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ "86e3");\nvar XHR = __webpack_require__(/*! ./polling-xhr */ "108d");\nvar JSONP = __webpack_require__(/*! ./polling-jsonp */ "2dce");\nvar websocket = __webpack_require__(/*! ./websocket */ "6b20");\n\n/**\n * Export transports.\n */\n\nexports.polling = polling;\nexports.websocket = websocket;\n\n/**\n * Polling transport polymorphic constructor.\n * Decides on xhr vs jsonp based on feature detection.\n *\n * @api private\n */\n\nfunction polling (opts) {\n  var xhr;\n  var xd = false;\n  var xs = false;\n  var jsonp = false !== opts.jsonp;\n\n  if (global.location) {\n    var isSSL = \'https:\' === location.protocol;\n    var port = location.port;\n\n    // some user agents have empty `location.port`\n    if (!port) {\n      port = isSSL ? 443 : 80;\n    }\n\n    xd = opts.hostname !== location.hostname || port !== opts.port;\n    xs = opts.secure !== isSSL;\n  }\n\n  opts.xdomain = xd;\n  opts.xscheme = xs;\n  xhr = new XMLHttpRequest(opts);\n\n  if (\'open\' in xhr && !opts.forceJSONP) {\n    return new XHR(opts);\n  } else {\n    if (!jsonp) throw new Error(\'JSONP disabled\');\n    return new JSONP(opts);\n  }\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ "698d")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODM0Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9pbmRleC5qcz84OTk2Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llc1xuICovXG5cbnZhciBYTUxIdHRwUmVxdWVzdCA9IHJlcXVpcmUoJ3htbGh0dHByZXF1ZXN0LXNzbCcpO1xudmFyIFhIUiA9IHJlcXVpcmUoJy4vcG9sbGluZy14aHInKTtcbnZhciBKU09OUCA9IHJlcXVpcmUoJy4vcG9sbGluZy1qc29ucCcpO1xudmFyIHdlYnNvY2tldCA9IHJlcXVpcmUoJy4vd2Vic29ja2V0Jyk7XG5cbi8qKlxuICogRXhwb3J0IHRyYW5zcG9ydHMuXG4gKi9cblxuZXhwb3J0cy5wb2xsaW5nID0gcG9sbGluZztcbmV4cG9ydHMud2Vic29ja2V0ID0gd2Vic29ja2V0O1xuXG4vKipcbiAqIFBvbGxpbmcgdHJhbnNwb3J0IHBvbHltb3JwaGljIGNvbnN0cnVjdG9yLlxuICogRGVjaWRlcyBvbiB4aHIgdnMganNvbnAgYmFzZWQgb24gZmVhdHVyZSBkZXRlY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcG9sbGluZyAob3B0cykge1xuICB2YXIgeGhyO1xuICB2YXIgeGQgPSBmYWxzZTtcbiAgdmFyIHhzID0gZmFsc2U7XG4gIHZhciBqc29ucCA9IGZhbHNlICE9PSBvcHRzLmpzb25wO1xuXG4gIGlmIChnbG9iYWwubG9jYXRpb24pIHtcbiAgICB2YXIgaXNTU0wgPSAnaHR0cHM6JyA9PT0gbG9jYXRpb24ucHJvdG9jb2w7XG4gICAgdmFyIHBvcnQgPSBsb2NhdGlvbi5wb3J0O1xuXG4gICAgLy8gc29tZSB1c2VyIGFnZW50cyBoYXZlIGVtcHR5IGBsb2NhdGlvbi5wb3J0YFxuICAgIGlmICghcG9ydCkge1xuICAgICAgcG9ydCA9IGlzU1NMID8gNDQzIDogODA7XG4gICAgfVxuXG4gICAgeGQgPSBvcHRzLmhvc3RuYW1lICE9PSBsb2NhdGlvbi5ob3N0bmFtZSB8fCBwb3J0ICE9PSBvcHRzLnBvcnQ7XG4gICAgeHMgPSBvcHRzLnNlY3VyZSAhPT0gaXNTU0w7XG4gIH1cblxuICBvcHRzLnhkb21haW4gPSB4ZDtcbiAgb3B0cy54c2NoZW1lID0geHM7XG4gIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdChvcHRzKTtcblxuICBpZiAoJ29wZW4nIGluIHhociAmJiAhb3B0cy5mb3JjZUpTT05QKSB7XG4gICAgcmV0dXJuIG5ldyBYSFIob3B0cyk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFqc29ucCkgdGhyb3cgbmV3IEVycm9yKCdKU09OUCBkaXNhYmxlZCcpO1xuICAgIHJldHVybiBuZXcgSlNPTlAob3B0cyk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///834b\n')},"86e3":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {// browser shim for xmlhttprequest module\n\nvar hasCORS = __webpack_require__(/*! has-cors */ \"0392\");\n\nmodule.exports = function (opts) {\n  var xdomain = opts.xdomain;\n\n  // scheme must be same when usign XDomainRequest\n  // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx\n  var xscheme = opts.xscheme;\n\n  // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.\n  // https://github.com/Automattic/engine.io-client/pull/217\n  var enablesXDR = opts.enablesXDR;\n\n  // XMLHttpRequest can be disabled on IE\n  try {\n    if ('undefined' !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {\n      return new XMLHttpRequest();\n    }\n  } catch (e) { }\n\n  // Use XDomainRequest for IE8 if enablesXDR is true\n  // because loading bar keeps flashing when using jsonp-polling\n  // https://github.com/yujiosaka/socke.io-ie8-loading-example\n  try {\n    if ('undefined' !== typeof XDomainRequest && !xscheme && enablesXDR) {\n      return new XDomainRequest();\n    }\n  } catch (e) { }\n\n  if (!xdomain) {\n    try {\n      return new global[['Active'].concat('Object').join('X')]('Microsoft.XMLHTTP');\n    } catch (e) { }\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODZlMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIveG1saHR0cHJlcXVlc3QuanM/NzY2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBicm93c2VyIHNoaW0gZm9yIHhtbGh0dHByZXF1ZXN0IG1vZHVsZVxuXG52YXIgaGFzQ09SUyA9IHJlcXVpcmUoJ2hhcy1jb3JzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgdmFyIHhkb21haW4gPSBvcHRzLnhkb21haW47XG5cbiAgLy8gc2NoZW1lIG11c3QgYmUgc2FtZSB3aGVuIHVzaWduIFhEb21haW5SZXF1ZXN0XG4gIC8vIGh0dHA6Ly9ibG9ncy5tc2RuLmNvbS9iL2llaW50ZXJuYWxzL2FyY2hpdmUvMjAxMC8wNS8xMy94ZG9tYWlucmVxdWVzdC1yZXN0cmljdGlvbnMtbGltaXRhdGlvbnMtYW5kLXdvcmthcm91bmRzLmFzcHhcbiAgdmFyIHhzY2hlbWUgPSBvcHRzLnhzY2hlbWU7XG5cbiAgLy8gWERvbWFpblJlcXVlc3QgaGFzIGEgZmxvdyBvZiBub3Qgc2VuZGluZyBjb29raWUsIHRoZXJlZm9yZSBpdCBzaG91bGQgYmUgZGlzYWJsZWQgYXMgYSBkZWZhdWx0LlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vQXV0b21hdHRpYy9lbmdpbmUuaW8tY2xpZW50L3B1bGwvMjE3XG4gIHZhciBlbmFibGVzWERSID0gb3B0cy5lbmFibGVzWERSO1xuXG4gIC8vIFhNTEh0dHBSZXF1ZXN0IGNhbiBiZSBkaXNhYmxlZCBvbiBJRVxuICB0cnkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIFhNTEh0dHBSZXF1ZXN0ICYmICgheGRvbWFpbiB8fCBoYXNDT1JTKSkge1xuICAgICAgcmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkgeyB9XG5cbiAgLy8gVXNlIFhEb21haW5SZXF1ZXN0IGZvciBJRTggaWYgZW5hYmxlc1hEUiBpcyB0cnVlXG4gIC8vIGJlY2F1c2UgbG9hZGluZyBiYXIga2VlcHMgZmxhc2hpbmcgd2hlbiB1c2luZyBqc29ucC1wb2xsaW5nXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS95dWppb3Nha2Evc29ja2UuaW8taWU4LWxvYWRpbmctZXhhbXBsZVxuICB0cnkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIFhEb21haW5SZXF1ZXN0ICYmICF4c2NoZW1lICYmIGVuYWJsZXNYRFIpIHtcbiAgICAgIHJldHVybiBuZXcgWERvbWFpblJlcXVlc3QoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHsgfVxuXG4gIGlmICgheGRvbWFpbikge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbmV3IGdsb2JhbFtbJ0FjdGl2ZSddLmNvbmNhdCgnT2JqZWN0Jykuam9pbignWCcpXSgnTWljcm9zb2Z0LlhNTEhUVFAnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbiAgfVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///86e3\n")},9083:function(module,exports,__webpack_require__){eval("/**\n * A `Group` represents a value a `Facet` can take using a partitioning.\n * For continuous or time facets, it represents an interval.\n * For categorial facets, it is a single label.\n *\n * The `Facet.groups` collection is used for plotting, to deterime the postion along the axis.\n * Selections can be updated using a `Group`.\n *\n * @extends Base\n * @class Group\n */\nvar Base = __webpack_require__(/*! ../util/base */ \"3902\");\nvar moment = __webpack_require__(/*! moment */ \"da01\");\n\nmodule.exports = Base.extend({\n  dataTypes: {\n    'numberDatetimeOrDuration': {\n      set: function (value) {\n        var newValue;\n\n        // check for momentjs objects\n        if (moment.isDuration(value)) {\n          return {\n            val: moment.duration(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (moment.isMoment(value)) {\n          return {\n            val: moment(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to create momentjs objects\n        newValue = moment(value, moment.ISO_8601);\n        if (newValue.isValid()) {\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          newValue = moment.duration(value);\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to set a number\n        if (value === +value) {\n          return {\n            val: +value,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // failed..\n        return {\n          val: value,\n          type: typeof value\n        };\n      },\n      compare: function (currentVal, newVal) {\n        if (currentVal instanceof moment) {\n          return currentVal.isSame(newVal);\n        } else {\n          return +currentVal === +newVal;\n        }\n      }\n    }\n  },\n  props: {\n    /**\n     * For continuous, datetime, or duration facets. Lower limit of interval\n     * @type {number|moment}\n     * @memberof! Group\n     */\n    min: 'numberDatetimeOrDuration',\n\n    /**\n     * For continuous, datetime, or duration facets. Upper limit of interval\n     * @type {number|moment}\n     * @memberof! Group\n     */\n    max: 'numberDatetimeOrDuration',\n\n    /**\n     * Number of times this transform is used\n     * @type {number}\n     * @memberof! Group\n     */\n    count: ['number', true, 0],\n\n    /**\n     * Label for display\n     * @type {string}\n     * @memberof! Group\n     */\n    label: ['string', true, 'label'],\n\n    /**\n     * A value guaranteed to be in this group, used to check if this group is currently selected.\n     * moments and durations should be stored as moment.format() and duration.toISOString()\n     * @type {string|number}\n     * @memberof! Group\n     */\n    value: 'any',\n\n    /**\n     * Index, cached version of groups.models.indexOf(group)\n     * @type {number}\n     * @memberof! Group\n     */\n    groupIndex: 'number'\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2dyb3VwLmpzPzEwNGMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBIGBHcm91cGAgcmVwcmVzZW50cyBhIHZhbHVlIGEgYEZhY2V0YCBjYW4gdGFrZSB1c2luZyBhIHBhcnRpdGlvbmluZy5cbiAqIEZvciBjb250aW51b3VzIG9yIHRpbWUgZmFjZXRzLCBpdCByZXByZXNlbnRzIGFuIGludGVydmFsLlxuICogRm9yIGNhdGVnb3JpYWwgZmFjZXRzLCBpdCBpcyBhIHNpbmdsZSBsYWJlbC5cbiAqXG4gKiBUaGUgYEZhY2V0Lmdyb3Vwc2AgY29sbGVjdGlvbiBpcyB1c2VkIGZvciBwbG90dGluZywgdG8gZGV0ZXJpbWUgdGhlIHBvc3Rpb24gYWxvbmcgdGhlIGF4aXMuXG4gKiBTZWxlY3Rpb25zIGNhbiBiZSB1cGRhdGVkIHVzaW5nIGEgYEdyb3VwYC5cbiAqXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKiBAY2xhc3MgR3JvdXBcbiAqL1xudmFyIEJhc2UgPSByZXF1aXJlKCcuLi91dGlsL2Jhc2UnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlLmV4dGVuZCh7XG4gIGRhdGFUeXBlczoge1xuICAgICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nOiB7XG4gICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIG1vbWVudGpzIG9iamVjdHNcbiAgICAgICAgaWYgKG1vbWVudC5pc0R1cmF0aW9uKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG1vbWVudC5kdXJhdGlvbih2YWx1ZSksXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vbWVudC5pc01vbWVudCh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsOiBtb21lbnQodmFsdWUpLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIGNyZWF0ZSBtb21lbnRqcyBvYmplY3RzXG4gICAgICAgIG5ld1ZhbHVlID0gbW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICBpZiAobmV3VmFsdWUuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbDogbmV3VmFsdWUsXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSB7XG4gICAgICAgICAgbmV3VmFsdWUgPSBtb21lbnQuZHVyYXRpb24odmFsdWUpO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG5ld1ZhbHVlLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIHNldCBhIG51bWJlclxuICAgICAgICBpZiAodmFsdWUgPT09ICt2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6ICt2YWx1ZSxcbiAgICAgICAgICAgIHR5cGU6ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZhaWxlZC4uXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsOiB2YWx1ZSxcbiAgICAgICAgICB0eXBlOiB0eXBlb2YgdmFsdWVcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBjb21wYXJlOiBmdW5jdGlvbiAoY3VycmVudFZhbCwgbmV3VmFsKSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsIGluc3RhbmNlb2YgbW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuIGN1cnJlbnRWYWwuaXNTYW1lKG5ld1ZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICtjdXJyZW50VmFsID09PSArbmV3VmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzLCBkYXRldGltZSwgb3IgZHVyYXRpb24gZmFjZXRzLiBMb3dlciBsaW1pdCBvZiBpbnRlcnZhbFxuICAgICAqIEB0eXBlIHtudW1iZXJ8bW9tZW50fVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICBtaW46ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMsIGRhdGV0aW1lLCBvciBkdXJhdGlvbiBmYWNldHMuIFVwcGVyIGxpbWl0IG9mIGludGVydmFsXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIG1heDogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbicsXG5cbiAgICAvKipcbiAgICAgKiBOdW1iZXIgb2YgdGltZXMgdGhpcyB0cmFuc2Zvcm0gaXMgdXNlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIGNvdW50OiBbJ251bWJlcicsIHRydWUsIDBdLFxuXG4gICAgLyoqXG4gICAgICogTGFiZWwgZm9yIGRpc3BsYXlcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICBsYWJlbDogWydzdHJpbmcnLCB0cnVlLCAnbGFiZWwnXSxcblxuICAgIC8qKlxuICAgICAqIEEgdmFsdWUgZ3VhcmFudGVlZCB0byBiZSBpbiB0aGlzIGdyb3VwLCB1c2VkIHRvIGNoZWNrIGlmIHRoaXMgZ3JvdXAgaXMgY3VycmVudGx5IHNlbGVjdGVkLlxuICAgICAqIG1vbWVudHMgYW5kIGR1cmF0aW9ucyBzaG91bGQgYmUgc3RvcmVkIGFzIG1vbWVudC5mb3JtYXQoKSBhbmQgZHVyYXRpb24udG9JU09TdHJpbmcoKVxuICAgICAqIEB0eXBlIHtzdHJpbmd8bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICB2YWx1ZTogJ2FueScsXG5cbiAgICAvKipcbiAgICAgKiBJbmRleCwgY2FjaGVkIHZlcnNpb24gb2YgZ3JvdXBzLm1vZGVscy5pbmRleE9mKGdyb3VwKVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIGdyb3VwSW5kZXg6ICdudW1iZXInXG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9083\n")},"939f":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Create a blob builder even when vendor prefixes exist\n */\n\nvar BlobBuilder = global.BlobBuilder\n  || global.WebKitBlobBuilder\n  || global.MSBlobBuilder\n  || global.MozBlobBuilder;\n\n/**\n * Check if Blob constructor is supported\n */\n\nvar blobSupported = (function() {\n  try {\n    var a = new Blob(['hi']);\n    return a.size === 2;\n  } catch(e) {\n    return false;\n  }\n})();\n\n/**\n * Check if Blob constructor supports ArrayBufferViews\n * Fails in Safari 6, so we need to map to ArrayBuffers there.\n */\n\nvar blobSupportsArrayBufferView = blobSupported && (function() {\n  try {\n    var b = new Blob([new Uint8Array([1,2])]);\n    return b.size === 2;\n  } catch(e) {\n    return false;\n  }\n})();\n\n/**\n * Check if BlobBuilder is supported\n */\n\nvar blobBuilderSupported = BlobBuilder\n  && BlobBuilder.prototype.append\n  && BlobBuilder.prototype.getBlob;\n\n/**\n * Helper function that maps ArrayBufferViews to ArrayBuffers\n * Used by BlobBuilder constructor and old browsers that didn't\n * support it in the Blob constructor.\n */\n\nfunction mapArrayBufferViews(ary) {\n  for (var i = 0; i < ary.length; i++) {\n    var chunk = ary[i];\n    if (chunk.buffer instanceof ArrayBuffer) {\n      var buf = chunk.buffer;\n\n      // if this is a subarray, make a copy so we only\n      // include the subarray region from the underlying buffer\n      if (chunk.byteLength !== buf.byteLength) {\n        var copy = new Uint8Array(chunk.byteLength);\n        copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength));\n        buf = copy.buffer;\n      }\n\n      ary[i] = buf;\n    }\n  }\n}\n\nfunction BlobBuilderConstructor(ary, options) {\n  options = options || {};\n\n  var bb = new BlobBuilder();\n  mapArrayBufferViews(ary);\n\n  for (var i = 0; i < ary.length; i++) {\n    bb.append(ary[i]);\n  }\n\n  return (options.type) ? bb.getBlob(options.type) : bb.getBlob();\n};\n\nfunction BlobConstructor(ary, options) {\n  mapArrayBufferViews(ary);\n  return new Blob(ary, options || {});\n};\n\nmodule.exports = (function() {\n  if (blobSupported) {\n    return blobSupportsArrayBufferView ? global.Blob : BlobConstructor;\n  } else if (blobBuilderSupported) {\n    return BlobBuilderConstructor;\n  } else {\n    return undefined;\n  }\n})();\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM5Zi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvYmxvYi9pbmRleC5qcz8yMTA3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ3JlYXRlIGEgYmxvYiBidWlsZGVyIGV2ZW4gd2hlbiB2ZW5kb3IgcHJlZml4ZXMgZXhpc3RcbiAqL1xuXG52YXIgQmxvYkJ1aWxkZXIgPSBnbG9iYWwuQmxvYkJ1aWxkZXJcbiAgfHwgZ2xvYmFsLldlYktpdEJsb2JCdWlsZGVyXG4gIHx8IGdsb2JhbC5NU0Jsb2JCdWlsZGVyXG4gIHx8IGdsb2JhbC5Nb3pCbG9iQnVpbGRlcjtcblxuLyoqXG4gKiBDaGVjayBpZiBCbG9iIGNvbnN0cnVjdG9yIGlzIHN1cHBvcnRlZFxuICovXG5cbnZhciBibG9iU3VwcG9ydGVkID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIHZhciBhID0gbmV3IEJsb2IoWydoaSddKTtcbiAgICByZXR1cm4gYS5zaXplID09PSAyO1xuICB9IGNhdGNoKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8qKlxuICogQ2hlY2sgaWYgQmxvYiBjb25zdHJ1Y3RvciBzdXBwb3J0cyBBcnJheUJ1ZmZlclZpZXdzXG4gKiBGYWlscyBpbiBTYWZhcmkgNiwgc28gd2UgbmVlZCB0byBtYXAgdG8gQXJyYXlCdWZmZXJzIHRoZXJlLlxuICovXG5cbnZhciBibG9iU3VwcG9ydHNBcnJheUJ1ZmZlclZpZXcgPSBibG9iU3VwcG9ydGVkICYmIChmdW5jdGlvbigpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYiA9IG5ldyBCbG9iKFtuZXcgVWludDhBcnJheShbMSwyXSldKTtcbiAgICByZXR1cm4gYi5zaXplID09PSAyO1xuICB9IGNhdGNoKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8qKlxuICogQ2hlY2sgaWYgQmxvYkJ1aWxkZXIgaXMgc3VwcG9ydGVkXG4gKi9cblxudmFyIGJsb2JCdWlsZGVyU3VwcG9ydGVkID0gQmxvYkJ1aWxkZXJcbiAgJiYgQmxvYkJ1aWxkZXIucHJvdG90eXBlLmFwcGVuZFxuICAmJiBCbG9iQnVpbGRlci5wcm90b3R5cGUuZ2V0QmxvYjtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBtYXBzIEFycmF5QnVmZmVyVmlld3MgdG8gQXJyYXlCdWZmZXJzXG4gKiBVc2VkIGJ5IEJsb2JCdWlsZGVyIGNvbnN0cnVjdG9yIGFuZCBvbGQgYnJvd3NlcnMgdGhhdCBkaWRuJ3RcbiAqIHN1cHBvcnQgaXQgaW4gdGhlIEJsb2IgY29uc3RydWN0b3IuXG4gKi9cblxuZnVuY3Rpb24gbWFwQXJyYXlCdWZmZXJWaWV3cyhhcnkpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnkubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgY2h1bmsgPSBhcnlbaV07XG4gICAgaWYgKGNodW5rLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICB2YXIgYnVmID0gY2h1bmsuYnVmZmVyO1xuXG4gICAgICAvLyBpZiB0aGlzIGlzIGEgc3ViYXJyYXksIG1ha2UgYSBjb3B5IHNvIHdlIG9ubHlcbiAgICAgIC8vIGluY2x1ZGUgdGhlIHN1YmFycmF5IHJlZ2lvbiBmcm9tIHRoZSB1bmRlcmx5aW5nIGJ1ZmZlclxuICAgICAgaWYgKGNodW5rLmJ5dGVMZW5ndGggIT09IGJ1Zi5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHZhciBjb3B5ID0gbmV3IFVpbnQ4QXJyYXkoY2h1bmsuYnl0ZUxlbmd0aCk7XG4gICAgICAgIGNvcHkuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZiwgY2h1bmsuYnl0ZU9mZnNldCwgY2h1bmsuYnl0ZUxlbmd0aCkpO1xuICAgICAgICBidWYgPSBjb3B5LmJ1ZmZlcjtcbiAgICAgIH1cblxuICAgICAgYXJ5W2ldID0gYnVmO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBCbG9iQnVpbGRlckNvbnN0cnVjdG9yKGFyeSwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgYmIgPSBuZXcgQmxvYkJ1aWxkZXIoKTtcbiAgbWFwQXJyYXlCdWZmZXJWaWV3cyhhcnkpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgYmIuYXBwZW5kKGFyeVtpXSk7XG4gIH1cblxuICByZXR1cm4gKG9wdGlvbnMudHlwZSkgPyBiYi5nZXRCbG9iKG9wdGlvbnMudHlwZSkgOiBiYi5nZXRCbG9iKCk7XG59O1xuXG5mdW5jdGlvbiBCbG9iQ29uc3RydWN0b3IoYXJ5LCBvcHRpb25zKSB7XG4gIG1hcEFycmF5QnVmZmVyVmlld3MoYXJ5KTtcbiAgcmV0dXJuIG5ldyBCbG9iKGFyeSwgb3B0aW9ucyB8fCB7fSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IChmdW5jdGlvbigpIHtcbiAgaWYgKGJsb2JTdXBwb3J0ZWQpIHtcbiAgICByZXR1cm4gYmxvYlN1cHBvcnRzQXJyYXlCdWZmZXJWaWV3ID8gZ2xvYmFsLkJsb2IgOiBCbG9iQ29uc3RydWN0b3I7XG4gIH0gZWxzZSBpZiAoYmxvYkJ1aWxkZXJTdXBwb3J0ZWQpIHtcbiAgICByZXR1cm4gQmxvYkJ1aWxkZXJDb25zdHJ1Y3RvcjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59KSgpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///939f\n")},9476:function(module,exports,__webpack_require__){eval("/**\n * A filter provides a chart with an interface to the data.\n * The filter contains a number of `Partition`s and `Aggregate`s.\n * It takes care of calling the relevant functions provided by a `Dataset`.\n *\n * @class Filter\n * @extends Base\n */\n\n/**\n * @typedef {Object} DataRecord - Object holding the plot data, partitions are labelled with a single small letter, aggregates with a double small letter\n * @property {string} DataRecord.a Value of first partition\n * @property {string} DataRecord.b Value of second partition\n * @property {string} DataRecord.c Value of third partition, etc.\n * @property {string} DataRecord.aa Value of first aggregate\n * @property {string} DataRecord.bb Value of second aggregate, etc.\n */\n\n/**\n * @typedef {DataRecord[]} Data - Array of DataRecords\n */\n\nvar Base = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Aggregates = __webpack_require__(/*! ./aggregate/collection */ \"fbef\");\nvar Partitions = __webpack_require__(/*! ./partition/collection */ \"e59a\");\n\nmodule.exports = Base.extend({\n  props: {\n    /**\n     * Hint for the client (website) how to visualize this filter\n     * @memberof! Filter\n     * @type {string}\n     */\n    chartType: {\n      type: 'string',\n      required: true,\n      default: 'barchart',\n      values: ['piechart', 'horizontalbarchart', 'barchart', 'linechart', 'radarchart', 'polarareachart', 'bubbleplot', 'scatterchart', 'networkchart']\n    },\n    /**\n     * Title for displaying purposes\n     * @memberof! Filter\n     * @type {string}\n     */\n    title: ['string', true, ''],\n    /**\n     * Hint for the client (website) how to position the chart for this filter\n     * position (col, row) and size (size_x, size_y) of chart\n     */\n    col: 'number',\n    row: 'number',\n    size_x: 'number',\n    size_y: 'number'\n  },\n  collections: {\n    /**\n     * @memberof! Filter\n     * @type {Partitions[]}\n     */\n    partitions: Partitions,\n    /**\n     * @memberof! Filter\n     * @type {Aggregate[]}\n     */\n    aggregates: Aggregates\n  },\n  // Session properties are not typically persisted to the server,\n  // and are not returned by calls to toJSON() or serialize().\n  session: {\n    /**\n     * Array containing the data to plot\n     * @memberof! Filter\n     * @type {Data}\n     */\n    data: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    },\n    /*\n     * Call this function to request new data.\n     * The dataset backing the facet will copy the data to Filter.data.\n     * A newData event is fired when the data is ready to be plotted.\n     *\n     * @function\n     * @virtual\n     * @private\n     * @memberof! Filter\n     * @emits newData\n     */\n    getData: {\n      type: 'any'\n    },\n    /**\n     * A history of the current drill-down (ie. partitions.toJSON())\n     */\n    zoomHistory: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    },\n    /**\n     * Boolean indicating if the filter is initialized\n     */\n    isInitialized: {\n      type: 'boolean',\n      required: true,\n      default: false\n    }\n  },\n  initialize: function () {\n    // set up callback to free internal state on remove\n    this.on('remove', function () {\n      this.releaseDataFilter();\n    });\n  },\n  zoomIn: function () {\n    this.releaseDataFilter();\n\n    // save current state\n    this.zoomHistory.push(JSON.stringify(this.partitions.toJSON()));\n\n    this.partitions.forEach(function (partition) {\n      if ((partition.selected.length === 2) && (partition.isDatetime || partition.isContinuous)) {\n        if (partition.groupFixedS || partition.groupFixedSC) {\n          // scale down binsize\n          var newSize = partition.selected[1] - partition.selected[0];\n          var oldSize = partition.maxval - partition.minval;\n          partition.groupingParam = partition.groupingParam * newSize / oldSize;\n        }\n        // zoom to selected range, if possible\n        partition.set({\n          minval: partition.selected[0],\n          maxval: partition.selected[1]\n        });\n      } else if (partition.selected.length > 0 && (partition.isCategorial)) {\n        // zoom to selected categories, if possible\n        partition.groups.reset();\n        partition.selected.forEach(function (value) {\n          partition.groups.add({\n            value: value,\n            label: value,\n            count: 0,\n            isSelected: true\n          });\n        });\n      }\n      // select all\n      partition.updateSelection();\n    });\n    this.initDataFilter();\n    this.updateDataFilter(); // also triggers a getAllData()\n  },\n  zoomOut: function () {\n    var doReset = true;\n\n    // clear current selection\n    this.partitions.forEach(function (partition) {\n      if (partition.selected.length > 0) {\n        partition.updateSelection();\n        doReset = false;\n      }\n    });\n\n    if (doReset) {\n      this.releaseDataFilter();\n      if (this.zoomHistory.length > 0) {\n        // nothing was selected and we have drilled down: go up\n        var state = JSON.parse(this.zoomHistory.pop());\n        this.partitions.reset(state);\n      } else {\n        // nothing was selected and no drill down: reset partitioning\n        this.partitions.forEach(function (partition) {\n          if (partition.isDatetime || partition.isContinuous) {\n            partition.reset();\n          }\n        });\n      }\n      this.initDataFilter();\n    }\n    this.updateDataFilter(); // also triggers a getAllData()\n  },\n  // Apply the separate filterFunctions from each partition in a single function\n  filterFunction: function () {\n    var fs = [];\n    this.partitions.forEach(function (partition) {\n      fs.push(partition.filterFunction());\n    });\n    return function (d) {\n      if (typeof d === 'string') {\n        var groups = d.split('|');\n        return fs.every(function (f, i) { return f(groups[i]); });\n      } else {\n        // shortcut for non-partitioned numeric data\n        return fs[0](d);\n      }\n    };\n  },\n  /**\n   * Initialize the data filter, and construct the getData callback function on the filter.\n   *\n   * @memberof! Filter\n   */\n  initDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.releaseDataFilter(dataview, this);\n    spot.driver.initDataFilter(dataview, this);\n    spot.driver.updateDataFilter(this);\n\n    this.isInitialized = true;\n  },\n  /**\n   * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n   * related to the filter.\n   *\n   * @memberof! Filter\n   */\n  releaseDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.releaseDataFilter(dataview, this);\n\n    this.isInitialized = false;\n  },\n  /**\n   * Apply changes to the filter (like selecting groups)\n   *\n   * @memberof! Filter\n   */\n  updateDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.updateDataFilter(this);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ3Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmlsdGVyLmpzPzM4ZmYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBIGZpbHRlciBwcm92aWRlcyBhIGNoYXJ0IHdpdGggYW4gaW50ZXJmYWNlIHRvIHRoZSBkYXRhLlxuICogVGhlIGZpbHRlciBjb250YWlucyBhIG51bWJlciBvZiBgUGFydGl0aW9uYHMgYW5kIGBBZ2dyZWdhdGVgcy5cbiAqIEl0IHRha2VzIGNhcmUgb2YgY2FsbGluZyB0aGUgcmVsZXZhbnQgZnVuY3Rpb25zIHByb3ZpZGVkIGJ5IGEgYERhdGFzZXRgLlxuICpcbiAqIEBjbGFzcyBGaWx0ZXJcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IERhdGFSZWNvcmQgLSBPYmplY3QgaG9sZGluZyB0aGUgcGxvdCBkYXRhLCBwYXJ0aXRpb25zIGFyZSBsYWJlbGxlZCB3aXRoIGEgc2luZ2xlIHNtYWxsIGxldHRlciwgYWdncmVnYXRlcyB3aXRoIGEgZG91YmxlIHNtYWxsIGxldHRlclxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYSBWYWx1ZSBvZiBmaXJzdCBwYXJ0aXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEYXRhUmVjb3JkLmIgVmFsdWUgb2Ygc2Vjb25kIHBhcnRpdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYyBWYWx1ZSBvZiB0aGlyZCBwYXJ0aXRpb24sIGV0Yy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEYXRhUmVjb3JkLmFhIFZhbHVlIG9mIGZpcnN0IGFnZ3JlZ2F0ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYmIgVmFsdWUgb2Ygc2Vjb25kIGFnZ3JlZ2F0ZSwgZXRjLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge0RhdGFSZWNvcmRbXX0gRGF0YSAtIEFycmF5IG9mIERhdGFSZWNvcmRzXG4gKi9cblxudmFyIEJhc2UgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIEFnZ3JlZ2F0ZXMgPSByZXF1aXJlKCcuL2FnZ3JlZ2F0ZS9jb2xsZWN0aW9uJyk7XG52YXIgUGFydGl0aW9ucyA9IHJlcXVpcmUoJy4vcGFydGl0aW9uL2NvbGxlY3Rpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogSGludCBmb3IgdGhlIGNsaWVudCAod2Vic2l0ZSkgaG93IHRvIHZpc3VhbGl6ZSB0aGlzIGZpbHRlclxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBjaGFydFR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnYmFyY2hhcnQnLFxuICAgICAgdmFsdWVzOiBbJ3BpZWNoYXJ0JywgJ2hvcml6b250YWxiYXJjaGFydCcsICdiYXJjaGFydCcsICdsaW5lY2hhcnQnLCAncmFkYXJjaGFydCcsICdwb2xhcmFyZWFjaGFydCcsICdidWJibGVwbG90JywgJ3NjYXR0ZXJjaGFydCcsICduZXR3b3JrY2hhcnQnXVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGl0bGUgZm9yIGRpc3BsYXlpbmcgcHVycG9zZXNcbiAgICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGl0bGU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuICAgIC8qKlxuICAgICAqIEhpbnQgZm9yIHRoZSBjbGllbnQgKHdlYnNpdGUpIGhvdyB0byBwb3NpdGlvbiB0aGUgY2hhcnQgZm9yIHRoaXMgZmlsdGVyXG4gICAgICogcG9zaXRpb24gKGNvbCwgcm93KSBhbmQgc2l6ZSAoc2l6ZV94LCBzaXplX3kpIG9mIGNoYXJ0XG4gICAgICovXG4gICAgY29sOiAnbnVtYmVyJyxcbiAgICByb3c6ICdudW1iZXInLFxuICAgIHNpemVfeDogJ251bWJlcicsXG4gICAgc2l6ZV95OiAnbnVtYmVyJ1xuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge1BhcnRpdGlvbnNbXX1cbiAgICAgKi9cbiAgICBwYXJ0aXRpb25zOiBQYXJ0aXRpb25zLFxuICAgIC8qKlxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge0FnZ3JlZ2F0ZVtdfVxuICAgICAqL1xuICAgIGFnZ3JlZ2F0ZXM6IEFnZ3JlZ2F0ZXNcbiAgfSxcbiAgLy8gU2Vzc2lvbiBwcm9wZXJ0aWVzIGFyZSBub3QgdHlwaWNhbGx5IHBlcnNpc3RlZCB0byB0aGUgc2VydmVyLFxuICAvLyBhbmQgYXJlIG5vdCByZXR1cm5lZCBieSBjYWxscyB0byB0b0pTT04oKSBvciBzZXJpYWxpemUoKS5cbiAgc2Vzc2lvbjoge1xuICAgIC8qKlxuICAgICAqIEFycmF5IGNvbnRhaW5pbmcgdGhlIGRhdGEgdG8gcGxvdFxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge0RhdGF9XG4gICAgICovXG4gICAgZGF0YToge1xuICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0sXG4gICAgLypcbiAgICAgKiBDYWxsIHRoaXMgZnVuY3Rpb24gdG8gcmVxdWVzdCBuZXcgZGF0YS5cbiAgICAgKiBUaGUgZGF0YXNldCBiYWNraW5nIHRoZSBmYWNldCB3aWxsIGNvcHkgdGhlIGRhdGEgdG8gRmlsdGVyLmRhdGEuXG4gICAgICogQSBuZXdEYXRhIGV2ZW50IGlzIGZpcmVkIHdoZW4gdGhlIGRhdGEgaXMgcmVhZHkgdG8gYmUgcGxvdHRlZC5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEB2aXJ0dWFsXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgICAqIEBlbWl0cyBuZXdEYXRhXG4gICAgICovXG4gICAgZ2V0RGF0YToge1xuICAgICAgdHlwZTogJ2FueSdcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIEEgaGlzdG9yeSBvZiB0aGUgY3VycmVudCBkcmlsbC1kb3duIChpZS4gcGFydGl0aW9ucy50b0pTT04oKSlcbiAgICAgKi9cbiAgICB6b29tSGlzdG9yeToge1xuICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogQm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSBmaWx0ZXIgaXMgaW5pdGlhbGl6ZWRcbiAgICAgKi9cbiAgICBpc0luaXRpYWxpemVkOiB7XG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IGZhbHNlXG4gICAgfVxuICB9LFxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gc2V0IHVwIGNhbGxiYWNrIHRvIGZyZWUgaW50ZXJuYWwgc3RhdGUgb24gcmVtb3ZlXG4gICAgdGhpcy5vbigncmVtb3ZlJywgZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5yZWxlYXNlRGF0YUZpbHRlcigpO1xuICAgIH0pO1xuICB9LFxuICB6b29tSW46IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlbGVhc2VEYXRhRmlsdGVyKCk7XG5cbiAgICAvLyBzYXZlIGN1cnJlbnQgc3RhdGVcbiAgICB0aGlzLnpvb21IaXN0b3J5LnB1c2goSlNPTi5zdHJpbmdpZnkodGhpcy5wYXJ0aXRpb25zLnRvSlNPTigpKSk7XG5cbiAgICB0aGlzLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uKSB7XG4gICAgICBpZiAoKHBhcnRpdGlvbi5zZWxlY3RlZC5sZW5ndGggPT09IDIpICYmIChwYXJ0aXRpb24uaXNEYXRldGltZSB8fCBwYXJ0aXRpb24uaXNDb250aW51b3VzKSkge1xuICAgICAgICBpZiAocGFydGl0aW9uLmdyb3VwRml4ZWRTIHx8IHBhcnRpdGlvbi5ncm91cEZpeGVkU0MpIHtcbiAgICAgICAgICAvLyBzY2FsZSBkb3duIGJpbnNpemVcbiAgICAgICAgICB2YXIgbmV3U2l6ZSA9IHBhcnRpdGlvbi5zZWxlY3RlZFsxXSAtIHBhcnRpdGlvbi5zZWxlY3RlZFswXTtcbiAgICAgICAgICB2YXIgb2xkU2l6ZSA9IHBhcnRpdGlvbi5tYXh2YWwgLSBwYXJ0aXRpb24ubWludmFsO1xuICAgICAgICAgIHBhcnRpdGlvbi5ncm91cGluZ1BhcmFtID0gcGFydGl0aW9uLmdyb3VwaW5nUGFyYW0gKiBuZXdTaXplIC8gb2xkU2l6ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyB6b29tIHRvIHNlbGVjdGVkIHJhbmdlLCBpZiBwb3NzaWJsZVxuICAgICAgICBwYXJ0aXRpb24uc2V0KHtcbiAgICAgICAgICBtaW52YWw6IHBhcnRpdGlvbi5zZWxlY3RlZFswXSxcbiAgICAgICAgICBtYXh2YWw6IHBhcnRpdGlvbi5zZWxlY3RlZFsxXVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCA+IDAgJiYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwpKSB7XG4gICAgICAgIC8vIHpvb20gdG8gc2VsZWN0ZWQgY2F0ZWdvcmllcywgaWYgcG9zc2libGVcbiAgICAgICAgcGFydGl0aW9uLmdyb3Vwcy5yZXNldCgpO1xuICAgICAgICBwYXJ0aXRpb24uc2VsZWN0ZWQuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICBwYXJ0aXRpb24uZ3JvdXBzLmFkZCh7XG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICBsYWJlbDogdmFsdWUsXG4gICAgICAgICAgICBjb3VudDogMCxcbiAgICAgICAgICAgIGlzU2VsZWN0ZWQ6IHRydWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyBzZWxlY3QgYWxsXG4gICAgICBwYXJ0aXRpb24udXBkYXRlU2VsZWN0aW9uKCk7XG4gICAgfSk7XG4gICAgdGhpcy5pbml0RGF0YUZpbHRlcigpO1xuICAgIHRoaXMudXBkYXRlRGF0YUZpbHRlcigpOyAvLyBhbHNvIHRyaWdnZXJzIGEgZ2V0QWxsRGF0YSgpXG4gIH0sXG4gIHpvb21PdXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZG9SZXNldCA9IHRydWU7XG5cbiAgICAvLyBjbGVhciBjdXJyZW50IHNlbGVjdGlvblxuICAgIHRoaXMucGFydGl0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgICAgIGlmIChwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoID4gMCkge1xuICAgICAgICBwYXJ0aXRpb24udXBkYXRlU2VsZWN0aW9uKCk7XG4gICAgICAgIGRvUmVzZXQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChkb1Jlc2V0KSB7XG4gICAgICB0aGlzLnJlbGVhc2VEYXRhRmlsdGVyKCk7XG4gICAgICBpZiAodGhpcy56b29tSGlzdG9yeS5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIG5vdGhpbmcgd2FzIHNlbGVjdGVkIGFuZCB3ZSBoYXZlIGRyaWxsZWQgZG93bjogZ28gdXBcbiAgICAgICAgdmFyIHN0YXRlID0gSlNPTi5wYXJzZSh0aGlzLnpvb21IaXN0b3J5LnBvcCgpKTtcbiAgICAgICAgdGhpcy5wYXJ0aXRpb25zLnJlc2V0KHN0YXRlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG5vdGhpbmcgd2FzIHNlbGVjdGVkIGFuZCBubyBkcmlsbCBkb3duOiByZXNldCBwYXJ0aXRpb25pbmdcbiAgICAgICAgdGhpcy5wYXJ0aXRpb25zLmZvckVhY2goZnVuY3Rpb24gKHBhcnRpdGlvbikge1xuICAgICAgICAgIGlmIChwYXJ0aXRpb24uaXNEYXRldGltZSB8fCBwYXJ0aXRpb24uaXNDb250aW51b3VzKSB7XG4gICAgICAgICAgICBwYXJ0aXRpb24ucmVzZXQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgdGhpcy5pbml0RGF0YUZpbHRlcigpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZURhdGFGaWx0ZXIoKTsgLy8gYWxzbyB0cmlnZ2VycyBhIGdldEFsbERhdGEoKVxuICB9LFxuICAvLyBBcHBseSB0aGUgc2VwYXJhdGUgZmlsdGVyRnVuY3Rpb25zIGZyb20gZWFjaCBwYXJ0aXRpb24gaW4gYSBzaW5nbGUgZnVuY3Rpb25cbiAgZmlsdGVyRnVuY3Rpb246IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZnMgPSBbXTtcbiAgICB0aGlzLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uKSB7XG4gICAgICBmcy5wdXNoKHBhcnRpdGlvbi5maWx0ZXJGdW5jdGlvbigpKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmICh0eXBlb2YgZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdmFyIGdyb3VwcyA9IGQuc3BsaXQoJ3wnKTtcbiAgICAgICAgcmV0dXJuIGZzLmV2ZXJ5KGZ1bmN0aW9uIChmLCBpKSB7IHJldHVybiBmKGdyb3Vwc1tpXSk7IH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gc2hvcnRjdXQgZm9yIG5vbi1wYXJ0aXRpb25lZCBudW1lcmljIGRhdGFcbiAgICAgICAgcmV0dXJuIGZzWzBdKGQpO1xuICAgICAgfVxuICAgIH07XG4gIH0sXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICAgKlxuICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgKi9cbiAgaW5pdERhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIucmVsZWFzZURhdGFGaWx0ZXIoZGF0YXZpZXcsIHRoaXMpO1xuICAgIHNwb3QuZHJpdmVyLmluaXREYXRhRmlsdGVyKGRhdGF2aWV3LCB0aGlzKTtcbiAgICBzcG90LmRyaXZlci51cGRhdGVEYXRhRmlsdGVyKHRoaXMpO1xuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgfSxcbiAgLyoqXG4gICAqIFRoZSBvcHBvc2l0ZSBvciBpbml0RGF0YUZpbHRlciwgaXQgc2hvdWxkIHJlbW92ZSB0aGUgZmlsdGVyIGFuZCBkZWFsbG9jYXRlIG90aGVyIGNvbmZpZ3VyYXRpb25cbiAgICogcmVsYXRlZCB0byB0aGUgZmlsdGVyLlxuICAgKlxuICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgKi9cbiAgcmVsZWFzZURhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIucmVsZWFzZURhdGFGaWx0ZXIoZGF0YXZpZXcsIHRoaXMpO1xuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gZmFsc2U7XG4gIH0sXG4gIC8qKlxuICAgKiBBcHBseSBjaGFuZ2VzIHRvIHRoZSBmaWx0ZXIgKGxpa2Ugc2VsZWN0aW5nIGdyb3VwcylcbiAgICpcbiAgICogQG1lbWJlcm9mISBGaWx0ZXJcbiAgICovXG4gIHVwZGF0ZURhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIudXBkYXRlRGF0YUZpbHRlcih0aGlzKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9476\n")},"9b75":function(module,exports,__webpack_require__){eval("/**\n * CategorialTransfrom defines a transformation on categorial and textual data,\n * and is implemented as a collection of rules.\n *\n * @class CategorialTransform\n */\nvar Model = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\n\nvar Rule = __webpack_require__(/*! ./categorial-rule */ \"ba23\");\nvar Rules = Collection.extend({\n  indexes: ['expression'],\n  model: Rule\n});\n\n/**\n * Apply the first applicable transformation rule.\n * When no matching rule is found, return 'Other'\n *\n * @function\n * @memberof! CategorialTransform\n * @param {string} text\n * @returns {string} text The transformed text\n */\nfunction transform (rules, text) {\n  var i;\n  for (i = 0; i < rules.length; i++) {\n    var group = rules.models[i].match(text);\n    if (group) {\n      return group;\n    }\n  }\n  return 'Other';\n}\n\nmodule.exports = Model.extend({\n  props: {\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['categorial']\n    },\n    transformedMin: {\n      type: 'number',\n      required: true,\n      default: 0\n    },\n    transformedMax: {\n      type: 'number',\n      required: true,\n      default: 100\n    },\n    transformedMinAsText: {\n      type: 'string',\n      required: true,\n      default: '0'\n    },\n    transformedMaxAsText: {\n      type: 'string',\n      required: true,\n      default: '100'\n    }\n  },\n  collections: {\n    rules: Rules\n  },\n  transform: function (labels) {\n    if (!this.rules) {\n      return labels;\n    }\n    if (labels instanceof Array) {\n      labels.forEach(function (label, i) {\n        labels[i] = transform(this.rules, label);\n      }, this);\n    } else {\n      labels = transform(this.rules, labels);\n    }\n    return labels;\n  },\n  reset: function () {\n    this.rules.reset();\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWI3NS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY2F0ZWdvcmlhbC10cmFuc2Zvcm0uanM/MzBlYiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENhdGVnb3JpYWxUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNhdGVnb3JpYWwgYW5kIHRleHR1YWwgZGF0YSxcbiAqIGFuZCBpcyBpbXBsZW1lbnRlZCBhcyBhIGNvbGxlY3Rpb24gb2YgcnVsZXMuXG4gKlxuICogQGNsYXNzIENhdGVnb3JpYWxUcmFuc2Zvcm1cbiAqL1xudmFyIE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG52YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG5cbnZhciBSdWxlID0gcmVxdWlyZSgnLi9jYXRlZ29yaWFsLXJ1bGUnKTtcbnZhciBSdWxlcyA9IENvbGxlY3Rpb24uZXh0ZW5kKHtcbiAgaW5kZXhlczogWydleHByZXNzaW9uJ10sXG4gIG1vZGVsOiBSdWxlXG59KTtcblxuLyoqXG4gKiBBcHBseSB0aGUgZmlyc3QgYXBwbGljYWJsZSB0cmFuc2Zvcm1hdGlvbiBydWxlLlxuICogV2hlbiBubyBtYXRjaGluZyBydWxlIGlzIGZvdW5kLCByZXR1cm4gJ090aGVyJ1xuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mISBDYXRlZ29yaWFsVHJhbnNmb3JtXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICogQHJldHVybnMge3N0cmluZ30gdGV4dCBUaGUgdHJhbnNmb3JtZWQgdGV4dFxuICovXG5mdW5jdGlvbiB0cmFuc2Zvcm0gKHJ1bGVzLCB0ZXh0KSB7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgcnVsZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZ3JvdXAgPSBydWxlcy5tb2RlbHNbaV0ubWF0Y2godGV4dCk7XG4gICAgaWYgKGdyb3VwKSB7XG4gICAgICByZXR1cm4gZ3JvdXA7XG4gICAgfVxuICB9XG4gIHJldHVybiAnT3RoZXInO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IE1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgdHJhbnNmb3JtZWRUeXBlOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ2NhdGVnb3JpYWwnLFxuICAgICAgdmFsdWVzOiBbJ2NhdGVnb3JpYWwnXVxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNaW46IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAwXG4gICAgfSxcbiAgICB0cmFuc2Zvcm1lZE1heDoge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IDEwMFxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNaW5Bc1RleHQ6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnMCdcbiAgICB9LFxuICAgIHRyYW5zZm9ybWVkTWF4QXNUZXh0OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJzEwMCdcbiAgICB9XG4gIH0sXG4gIGNvbGxlY3Rpb25zOiB7XG4gICAgcnVsZXM6IFJ1bGVzXG4gIH0sXG4gIHRyYW5zZm9ybTogZnVuY3Rpb24gKGxhYmVscykge1xuICAgIGlmICghdGhpcy5ydWxlcykge1xuICAgICAgcmV0dXJuIGxhYmVscztcbiAgICB9XG4gICAgaWYgKGxhYmVscyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBsYWJlbHMuZm9yRWFjaChmdW5jdGlvbiAobGFiZWwsIGkpIHtcbiAgICAgICAgbGFiZWxzW2ldID0gdHJhbnNmb3JtKHRoaXMucnVsZXMsIGxhYmVsKTtcbiAgICAgIH0sIHRoaXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYWJlbHMgPSB0cmFuc2Zvcm0odGhpcy5ydWxlcywgbGFiZWxzKTtcbiAgICB9XG4gICAgcmV0dXJuIGxhYmVscztcbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJ1bGVzLnJlc2V0KCk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9b75\n")},"9d63":function(module,exports,__webpack_require__){eval("/**\n * The Aggregate class describes how to aggregate data, as described by a `Facet` into a single value.\n * For example, you can sum or average over numbers, or count the number of different labels.\n *\n * @class Aggregate\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\n\nmodule.exports = BaseModel.extend({\n  props: {\n    /**\n     * The name of the facet to aggregate over\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    facetName: 'string',\n\n    /**\n     * Label for displaying on plots\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    label: {\n      type: 'string',\n      required: true,\n      default: ''\n    },\n\n    /**\n     * When part of a aggregates, this deterimines the ordering\n     * @memberof! Aggregate\n     * @type {number}\n     */\n    rank: {\n      type: 'number',\n      required: true\n    },\n\n    /**\n     * Operation:\n     *  * `count`  count the number of elements in the group\n     *  * `sum`    sum the elements in the group\n     *  * `avg`    take the average of the elements in the group\n     *  * `stddev`  take the sample\n     *  * `min`    minum value of the elements in the group\n     *  * `max`    maximum value of the elements in the group\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    operation: {\n      type: 'string',\n      required: true,\n      default: 'avg',\n      values: ['count', 'avg', 'sum', 'stddev', 'min', 'max']\n    },\n    // NOTE: properties for reduction, should be a valid SQL aggregation function\n\n    /**\n     * Normalization: TODO\n     *  * `none`      data in same units as the original data\n     *  * `relative`  data is in percentages of the total; for subgroups in percentage of the parent group\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    normalization: {\n      type: 'string',\n      required: true,\n      default: 'none',\n      values: ['none', 'percentage']\n    }\n  },\n  derived: {\n    // operation values\n    doSum: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'sum';\n      }\n    },\n    doCount: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'count';\n      }\n    },\n    doAverage: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'avg';\n      }\n    },\n    doStddev: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'stddev';\n      }\n    },\n    doMin: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'min';\n      }\n    },\n    doMax: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'max';\n      }\n    },\n\n    // normalization values\n    normalizeNone: {\n      deps: ['normalization'],\n      fn: function () {\n        return this.normalization === 'absolute';\n      }\n    },\n    normalizePercentage: {\n      deps: ['normalization'],\n      fn: function () {\n        return this.normalization === 'percentage';\n      }\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWQ2My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvYWdncmVnYXRlLmpzP2JkNmEiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgQWdncmVnYXRlIGNsYXNzIGRlc2NyaWJlcyBob3cgdG8gYWdncmVnYXRlIGRhdGEsIGFzIGRlc2NyaWJlZCBieSBhIGBGYWNldGAgaW50byBhIHNpbmdsZSB2YWx1ZS5cbiAqIEZvciBleGFtcGxlLCB5b3UgY2FuIHN1bSBvciBhdmVyYWdlIG92ZXIgbnVtYmVycywgb3IgY291bnQgdGhlIG51bWJlciBvZiBkaWZmZXJlbnQgbGFiZWxzLlxuICpcbiAqIEBjbGFzcyBBZ2dyZWdhdGVcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGZhY2V0IHRvIGFnZ3JlZ2F0ZSBvdmVyXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZhY2V0TmFtZTogJ3N0cmluZycsXG5cbiAgICAvKipcbiAgICAgKiBMYWJlbCBmb3IgZGlzcGxheWluZyBvbiBwbG90c1xuICAgICAqIEBtZW1iZXJvZiEgQWdncmVnYXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBsYWJlbDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICcnXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFdoZW4gcGFydCBvZiBhIGFnZ3JlZ2F0ZXMsIHRoaXMgZGV0ZXJpbWluZXMgdGhlIG9yZGVyaW5nXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHJhbms6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogT3BlcmF0aW9uOlxuICAgICAqICAqIGBjb3VudGAgIGNvdW50IHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGdyb3VwXG4gICAgICogICogYHN1bWAgICAgc3VtIHRoZSBlbGVtZW50cyBpbiB0aGUgZ3JvdXBcbiAgICAgKiAgKiBgYXZnYCAgICB0YWtlIHRoZSBhdmVyYWdlIG9mIHRoZSBlbGVtZW50cyBpbiB0aGUgZ3JvdXBcbiAgICAgKiAgKiBgc3RkZGV2YCAgdGFrZSB0aGUgc2FtcGxlXG4gICAgICogICogYG1pbmAgICAgbWludW0gdmFsdWUgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBncm91cFxuICAgICAqICAqIGBtYXhgICAgIG1heGltdW0gdmFsdWUgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBncm91cFxuICAgICAqIEBtZW1iZXJvZiEgQWdncmVnYXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBvcGVyYXRpb246IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnYXZnJyxcbiAgICAgIHZhbHVlczogWydjb3VudCcsICdhdmcnLCAnc3VtJywgJ3N0ZGRldicsICdtaW4nLCAnbWF4J11cbiAgICB9LFxuICAgIC8vIE5PVEU6IHByb3BlcnRpZXMgZm9yIHJlZHVjdGlvbiwgc2hvdWxkIGJlIGEgdmFsaWQgU1FMIGFnZ3JlZ2F0aW9uIGZ1bmN0aW9uXG5cbiAgICAvKipcbiAgICAgKiBOb3JtYWxpemF0aW9uOiBUT0RPXG4gICAgICogICogYG5vbmVgICAgICAgZGF0YSBpbiBzYW1lIHVuaXRzIGFzIHRoZSBvcmlnaW5hbCBkYXRhXG4gICAgICogICogYHJlbGF0aXZlYCAgZGF0YSBpcyBpbiBwZXJjZW50YWdlcyBvZiB0aGUgdG90YWw7IGZvciBzdWJncm91cHMgaW4gcGVyY2VudGFnZSBvZiB0aGUgcGFyZW50IGdyb3VwXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG5vcm1hbGl6YXRpb246IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnbm9uZScsXG4gICAgICB2YWx1ZXM6IFsnbm9uZScsICdwZXJjZW50YWdlJ11cbiAgICB9XG4gIH0sXG4gIGRlcml2ZWQ6IHtcbiAgICAvLyBvcGVyYXRpb24gdmFsdWVzXG4gICAgZG9TdW06IHtcbiAgICAgIGRlcHM6IFsnb3BlcmF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vcGVyYXRpb24gPT09ICdzdW0nO1xuICAgICAgfVxuICAgIH0sXG4gICAgZG9Db3VudDoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ2NvdW50JztcbiAgICAgIH1cbiAgICB9LFxuICAgIGRvQXZlcmFnZToge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ2F2Zyc7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb1N0ZGRldjoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ3N0ZGRldic7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb01pbjoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ21pbic7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb01heDoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ21heCc7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8vIG5vcm1hbGl6YXRpb24gdmFsdWVzXG4gICAgbm9ybWFsaXplTm9uZToge1xuICAgICAgZGVwczogWydub3JtYWxpemF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxpemF0aW9uID09PSAnYWJzb2x1dGUnO1xuICAgICAgfVxuICAgIH0sXG4gICAgbm9ybWFsaXplUGVyY2VudGFnZToge1xuICAgICAgZGVwczogWydub3JtYWxpemF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxpemF0aW9uID09PSAncGVyY2VudGFnZSc7XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9d63\n")},a0ca:function(module,exports,__webpack_require__){eval("/**\n * DatetimeTransform defines a transformation on time or dates with timezones\n *\n * @class DatetimeTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Timezone to use when parsing, for when timezone information is absent or incorrect.\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    zone: ['string', true, 'ISO8601'],\n\n    /**\n     * Format indentifier to use when parsing, when not in ISO8601 format\n     * Mappings are defined in util/time.js => timeParts.description\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    format: ['string', true, 'ISO8601'],\n\n    /**\n     * Reformats to a string using the momentjs or postgreSQL format specifiers.\n     * This allows a transformation to day of the year, or day of week etc.\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedFormat: ['string', true, 'ISO8601'],\n\n    /**\n     * Controls conversion to duration by subtracting this date\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedReference: 'string',\n\n    /**\n     * Reference timezone for conversion from datetime to duration\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedZone: ['string', true, 'ISO8601']\n\n  },\n  derived: {\n    // reference momentjs for duration <-> datetime conversion\n    referenceMoment: {\n      deps: ['transformedReference', 'transformedZone'],\n      fn: function () {\n        var tz;\n        if (this.transformedZone === 'ISO8601') {\n          tz = moment.tz.guess();\n        } else {\n          var timeZone = util.timeZones.get(this.transformedZone, 'description');\n          if (timeZone && timeZone.format) {\n            tz = timeZone.format;\n          } else {\n            tz = moment.tz.guess();\n          }\n        }\n        if (this.transformedReference) {\n          return moment.tz(this.transformedReference, tz);\n        }\n        return null;\n      }\n    },\n    /**\n     * The type of the facet after the transformation has been applied\n     * @memberof! DatetimeTransform\n     */\n    transformedType: {\n      deps: ['transformedFormat', 'transformedReference'],\n      fn: function () {\n        if (this.transformedReference) {\n          // datetime -> duration\n          return 'duration';\n        } else if (this.transformedFormat === 'ISO8601') {\n          // datetime -> datetime\n          return 'datetime';\n        } else {\n          // datetime -> time part\n          var timePart = util.timeParts.get(this.transformedFormat, 'description');\n          if (timePart && timePart.type) {\n            return timePart.type;\n          }\n        }\n        return 'datetime';\n      },\n      cache: false\n    },\n    /**\n     * The minium value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! DatetimeTransform\n     */\n    transformedMin: {\n      deps: ['transformedType'],\n      fn: function () {\n        var timePart;\n        if (this.transformedType === 'datetime' || this.transformedType === 'duration') {\n          return this.transform(this.parent.minval);\n        }\n        timePart = util.timeParts.get(this.transformedFormat, 'description');\n        if (timePart.calcualte) {\n          return this.transform(this.parent.minval);\n        } else {\n          return timePart.min;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! DatetimeTransform\n     */\n    transformedMax: {\n      deps: ['transformedType'],\n      fn: function () {\n        var timePart;\n        if (this.transformedType === 'datetime' || this.transformedType === 'duration') {\n          return this.transform(this.parent.maxval);\n        }\n        timePart = util.timeParts.get(this.transformedFormat, 'description');\n        if (timePart.calcualte) {\n          return this.transform(this.parent.maxval);\n        } else {\n          return timePart.max;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DatetimeTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DatetimeTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n\n  /**\n   * @function\n   * @memberof! DatetimeTransform\n   * @param {Object} momentjs\n   * @returns {Object} momentjs\n   */\n  transform: function transform (inval) {\n    if (typeof inval === 'undefined') {\n      return misval;\n    }\n\n    var d = inval.clone();\n    var timePart;\n\n    if (this.referenceMoment) {\n      // datetime -> duration\n      return moment.duration(d.diff(this.referenceMoment, 'milliseconds', true), 'milliseconds');\n    } else if (this.transformedFormat !== 'ISO8601') {\n      timePart = util.timeParts.get(this.transformedFormat, 'description');\n      if (timePart && timePart.momentFormat) {\n        return d.format(timePart.momentFormat);\n      }\n      return d;\n    } else {\n      return d;\n    }\n  },\n  reset: function () {\n    this.unset(['zone', 'transformedFormat', 'transformedZone', 'transformedReference']);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYTBjYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvZGF0ZXRpbWUtdHJhbnNmb3JtLmpzPzM1YTIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEYXRldGltZVRyYW5zZm9ybSBkZWZpbmVzIGEgdHJhbnNmb3JtYXRpb24gb24gdGltZSBvciBkYXRlcyB3aXRoIHRpbWV6b25lc1xuICpcbiAqIEBjbGFzcyBEYXRldGltZVRyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC90aW1lJyk7XG52YXIgbWlzdmFsID0gcmVxdWlyZSgnLi4vdXRpbC9taXN2YWwnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRpbWV6b25lIHRvIHVzZSB3aGVuIHBhcnNpbmcsIGZvciB3aGVuIHRpbWV6b25lIGluZm9ybWF0aW9uIGlzIGFic2VudCBvciBpbmNvcnJlY3QuXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgem9uZTogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogRm9ybWF0IGluZGVudGlmaWVyIHRvIHVzZSB3aGVuIHBhcnNpbmcsIHdoZW4gbm90IGluIElTTzg2MDEgZm9ybWF0XG4gICAgICogTWFwcGluZ3MgYXJlIGRlZmluZWQgaW4gdXRpbC90aW1lLmpzID0+IHRpbWVQYXJ0cy5kZXNjcmlwdGlvblxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZvcm1hdDogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogUmVmb3JtYXRzIHRvIGEgc3RyaW5nIHVzaW5nIHRoZSBtb21lbnRqcyBvciBwb3N0Z3JlU1FMIGZvcm1hdCBzcGVjaWZpZXJzLlxuICAgICAqIFRoaXMgYWxsb3dzIGEgdHJhbnNmb3JtYXRpb24gdG8gZGF5IG9mIHRoZSB5ZWFyLCBvciBkYXkgb2Ygd2VlayBldGMuXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRGb3JtYXQ6IFsnc3RyaW5nJywgdHJ1ZSwgJ0lTTzg2MDEnXSxcblxuICAgIC8qKlxuICAgICAqIENvbnRyb2xzIGNvbnZlcnNpb24gdG8gZHVyYXRpb24gYnkgc3VidHJhY3RpbmcgdGhpcyBkYXRlXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRSZWZlcmVuY2U6ICdzdHJpbmcnLFxuXG4gICAgLyoqXG4gICAgICogUmVmZXJlbmNlIHRpbWV6b25lIGZvciBjb252ZXJzaW9uIGZyb20gZGF0ZXRpbWUgdG8gZHVyYXRpb25cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFpvbmU6IFsnc3RyaW5nJywgdHJ1ZSwgJ0lTTzg2MDEnXVxuXG4gIH0sXG4gIGRlcml2ZWQ6IHtcbiAgICAvLyByZWZlcmVuY2UgbW9tZW50anMgZm9yIGR1cmF0aW9uIDwtPiBkYXRldGltZSBjb252ZXJzaW9uXG4gICAgcmVmZXJlbmNlTW9tZW50OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkUmVmZXJlbmNlJywgJ3RyYW5zZm9ybWVkWm9uZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHR6O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFpvbmUgPT09ICdJU084NjAxJykge1xuICAgICAgICAgIHR6ID0gbW9tZW50LnR6Lmd1ZXNzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHRpbWVab25lID0gdXRpbC50aW1lWm9uZXMuZ2V0KHRoaXMudHJhbnNmb3JtZWRab25lLCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgICBpZiAodGltZVpvbmUgJiYgdGltZVpvbmUuZm9ybWF0KSB7XG4gICAgICAgICAgICB0eiA9IHRpbWVab25lLmZvcm1hdDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHogPSBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXR1cm4gbW9tZW50LnR6KHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UsIHR6KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBmYWNldCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFR5cGU6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRGb3JtYXQnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkUmVmZXJlbmNlKSB7XG4gICAgICAgICAgLy8gZGF0ZXRpbWUgLT4gZHVyYXRpb25cbiAgICAgICAgICByZXR1cm4gJ2R1cmF0aW9uJztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0ID09PSAnSVNPODYwMScpIHtcbiAgICAgICAgICAvLyBkYXRldGltZSAtPiBkYXRldGltZVxuICAgICAgICAgIHJldHVybiAnZGF0ZXRpbWUnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGRhdGV0aW1lIC0+IHRpbWUgcGFydFxuICAgICAgICAgIHZhciB0aW1lUGFydCA9IHV0aWwudGltZVBhcnRzLmdldCh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgICBpZiAodGltZVBhcnQgJiYgdGltZVBhcnQudHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRpbWVQYXJ0LnR5cGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnZGF0ZXRpbWUnO1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1pbml1bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluOiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRpbWVQYXJ0O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScgfHwgdGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkdXJhdGlvbicpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0odGhpcy5wYXJlbnQubWludmFsKTtcbiAgICAgICAgfVxuICAgICAgICB0aW1lUGFydCA9IHV0aWwudGltZVBhcnRzLmdldCh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgaWYgKHRpbWVQYXJ0LmNhbGN1YWx0ZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybSh0aGlzLnBhcmVudC5taW52YWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aW1lUGFydC5taW47XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNYXg6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGltZVBhcnQ7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJyB8fCB0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2R1cmF0aW9uJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybSh0aGlzLnBhcmVudC5tYXh2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHRpbWVQYXJ0ID0gdXRpbC50aW1lUGFydHMuZ2V0KHRoaXMudHJhbnNmb3JtZWRGb3JtYXQsICdkZXNjcmlwdGlvbicpO1xuICAgICAgICBpZiAodGltZVBhcnQuY2FsY3VhbHRlKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKHRoaXMucGFyZW50Lm1heHZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRpbWVQYXJ0Lm1heDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKlxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkTWluJywgJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1pbnZhbCA9IHRoaXMudHJhbnNmb3JtZWRNaW47XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiBtaW52YWwuZm9ybWF0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNYXhBc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRNYXgnLCAndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWF4dmFsID0gdGhpcy50cmFuc2Zvcm1lZE1heDtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnZGF0ZXRpbWUnKSB7XG4gICAgICAgICAgcmV0dXJuIG1heHZhbC5mb3JtYXQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIEBmdW5jdGlvblxuICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtb21lbnRqc1xuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBtb21lbnRqc1xuICAgKi9cbiAgdHJhbnNmb3JtOiBmdW5jdGlvbiB0cmFuc2Zvcm0gKGludmFsKSB7XG4gICAgaWYgKHR5cGVvZiBpbnZhbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfVxuXG4gICAgdmFyIGQgPSBpbnZhbC5jbG9uZSgpO1xuICAgIHZhciB0aW1lUGFydDtcblxuICAgIGlmICh0aGlzLnJlZmVyZW5jZU1vbWVudCkge1xuICAgICAgLy8gZGF0ZXRpbWUgLT4gZHVyYXRpb25cbiAgICAgIHJldHVybiBtb21lbnQuZHVyYXRpb24oZC5kaWZmKHRoaXMucmVmZXJlbmNlTW9tZW50LCAnbWlsbGlzZWNvbmRzJywgdHJ1ZSksICdtaWxsaXNlY29uZHMnKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudHJhbnNmb3JtZWRGb3JtYXQgIT09ICdJU084NjAxJykge1xuICAgICAgdGltZVBhcnQgPSB1dGlsLnRpbWVQYXJ0cy5nZXQodGhpcy50cmFuc2Zvcm1lZEZvcm1hdCwgJ2Rlc2NyaXB0aW9uJyk7XG4gICAgICBpZiAodGltZVBhcnQgJiYgdGltZVBhcnQubW9tZW50Rm9ybWF0KSB7XG4gICAgICAgIHJldHVybiBkLmZvcm1hdCh0aW1lUGFydC5tb21lbnRGb3JtYXQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBkO1xuICAgIH1cbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVuc2V0KFsnem9uZScsICd0cmFuc2Zvcm1lZEZvcm1hdCcsICd0cmFuc2Zvcm1lZFpvbmUnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///a0ca\n")},aa6c:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar keys = __webpack_require__(/*! ./keys */ \"7d91\");\nvar hasBinary = __webpack_require__(/*! has-binary */ \"d304\");\nvar sliceBuffer = __webpack_require__(/*! arraybuffer.slice */ \"ef13\");\nvar after = __webpack_require__(/*! after */ \"4aa5\");\nvar utf8 = __webpack_require__(/*! wtf-8 */ \"943e\");\n\nvar base64encoder;\nif (global && global.ArrayBuffer) {\n  base64encoder = __webpack_require__(/*! base64-arraybuffer */ \"21de\");\n}\n\n/**\n * Check if we are running an android browser. That requires us to use\n * ArrayBuffer with polling transports...\n *\n * http://ghinda.net/jpeg-blob-ajax-android/\n */\n\nvar isAndroid = typeof navigator !== 'undefined' && /Android/i.test(navigator.userAgent);\n\n/**\n * Check if we are running in PhantomJS.\n * Uploading a Blob with PhantomJS does not work correctly, as reported here:\n * https://github.com/ariya/phantomjs/issues/11395\n * @type boolean\n */\nvar isPhantomJS = typeof navigator !== 'undefined' && /PhantomJS/i.test(navigator.userAgent);\n\n/**\n * When true, avoids using Blobs to encode payloads.\n * @type boolean\n */\nvar dontSendBlobs = isAndroid || isPhantomJS;\n\n/**\n * Current protocol version.\n */\n\nexports.protocol = 3;\n\n/**\n * Packet types.\n */\n\nvar packets = exports.packets = {\n    open:     0    // non-ws\n  , close:    1    // non-ws\n  , ping:     2\n  , pong:     3\n  , message:  4\n  , upgrade:  5\n  , noop:     6\n};\n\nvar packetslist = keys(packets);\n\n/**\n * Premade error packet.\n */\n\nvar err = { type: 'error', data: 'parser error' };\n\n/**\n * Create a blob api even for blob builder when vendor prefixes exist\n */\n\nvar Blob = __webpack_require__(/*! blob */ \"939f\");\n\n/**\n * Encodes a packet.\n *\n *     <packet type id> [ <data> ]\n *\n * Example:\n *\n *     5hello world\n *     3\n *     4\n *\n * Binary is encoded in an identical principle\n *\n * @api private\n */\n\nexports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {\n  if ('function' == typeof supportsBinary) {\n    callback = supportsBinary;\n    supportsBinary = false;\n  }\n\n  if ('function' == typeof utf8encode) {\n    callback = utf8encode;\n    utf8encode = null;\n  }\n\n  var data = (packet.data === undefined)\n    ? undefined\n    : packet.data.buffer || packet.data;\n\n  if (global.ArrayBuffer && data instanceof ArrayBuffer) {\n    return encodeArrayBuffer(packet, supportsBinary, callback);\n  } else if (Blob && data instanceof global.Blob) {\n    return encodeBlob(packet, supportsBinary, callback);\n  }\n\n  // might be an object with { base64: true, data: dataAsBase64String }\n  if (data && data.base64) {\n    return encodeBase64Object(packet, callback);\n  }\n\n  // Sending data as a utf-8 string\n  var encoded = packets[packet.type];\n\n  // data fragment is optional\n  if (undefined !== packet.data) {\n    encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data);\n  }\n\n  return callback('' + encoded);\n\n};\n\nfunction encodeBase64Object(packet, callback) {\n  // packet data is an object { base64: true, data: dataAsBase64String }\n  var message = 'b' + exports.packets[packet.type] + packet.data.data;\n  return callback(message);\n}\n\n/**\n * Encode packet helpers for binary types\n */\n\nfunction encodeArrayBuffer(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  var data = packet.data;\n  var contentArray = new Uint8Array(data);\n  var resultBuffer = new Uint8Array(1 + data.byteLength);\n\n  resultBuffer[0] = packets[packet.type];\n  for (var i = 0; i < contentArray.length; i++) {\n    resultBuffer[i+1] = contentArray[i];\n  }\n\n  return callback(resultBuffer.buffer);\n}\n\nfunction encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  var fr = new FileReader();\n  fr.onload = function() {\n    packet.data = fr.result;\n    exports.encodePacket(packet, supportsBinary, true, callback);\n  };\n  return fr.readAsArrayBuffer(packet.data);\n}\n\nfunction encodeBlob(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  if (dontSendBlobs) {\n    return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);\n  }\n\n  var length = new Uint8Array(1);\n  length[0] = packets[packet.type];\n  var blob = new Blob([length.buffer, packet.data]);\n\n  return callback(blob);\n}\n\n/**\n * Encodes a packet with binary data in a base64 string\n *\n * @param {Object} packet, has `type` and `data`\n * @return {String} base64 encoded message\n */\n\nexports.encodeBase64Packet = function(packet, callback) {\n  var message = 'b' + exports.packets[packet.type];\n  if (Blob && packet.data instanceof global.Blob) {\n    var fr = new FileReader();\n    fr.onload = function() {\n      var b64 = fr.result.split(',')[1];\n      callback(message + b64);\n    };\n    return fr.readAsDataURL(packet.data);\n  }\n\n  var b64data;\n  try {\n    b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));\n  } catch (e) {\n    // iPhone Safari doesn't let you apply with typed arrays\n    var typed = new Uint8Array(packet.data);\n    var basic = new Array(typed.length);\n    for (var i = 0; i < typed.length; i++) {\n      basic[i] = typed[i];\n    }\n    b64data = String.fromCharCode.apply(null, basic);\n  }\n  message += global.btoa(b64data);\n  return callback(message);\n};\n\n/**\n * Decodes a packet. Changes format to Blob if requested.\n *\n * @return {Object} with `type` and `data` (if any)\n * @api private\n */\n\nexports.decodePacket = function (data, binaryType, utf8decode) {\n  if (data === undefined) {\n    return err;\n  }\n  // String data\n  if (typeof data == 'string') {\n    if (data.charAt(0) == 'b') {\n      return exports.decodeBase64Packet(data.substr(1), binaryType);\n    }\n\n    if (utf8decode) {\n      data = tryDecode(data);\n      if (data === false) {\n        return err;\n      }\n    }\n    var type = data.charAt(0);\n\n    if (Number(type) != type || !packetslist[type]) {\n      return err;\n    }\n\n    if (data.length > 1) {\n      return { type: packetslist[type], data: data.substring(1) };\n    } else {\n      return { type: packetslist[type] };\n    }\n  }\n\n  var asArray = new Uint8Array(data);\n  var type = asArray[0];\n  var rest = sliceBuffer(data, 1);\n  if (Blob && binaryType === 'blob') {\n    rest = new Blob([rest]);\n  }\n  return { type: packetslist[type], data: rest };\n};\n\nfunction tryDecode(data) {\n  try {\n    data = utf8.decode(data);\n  } catch (e) {\n    return false;\n  }\n  return data;\n}\n\n/**\n * Decodes a packet encoded in a base64 string\n *\n * @param {String} base64 encoded message\n * @return {Object} with `type` and `data` (if any)\n */\n\nexports.decodeBase64Packet = function(msg, binaryType) {\n  var type = packetslist[msg.charAt(0)];\n  if (!base64encoder) {\n    return { type: type, data: { base64: true, data: msg.substr(1) } };\n  }\n\n  var data = base64encoder.decode(msg.substr(1));\n\n  if (binaryType === 'blob' && Blob) {\n    data = new Blob([data]);\n  }\n\n  return { type: type, data: data };\n};\n\n/**\n * Encodes multiple messages (payload).\n *\n *     <length>:data\n *\n * Example:\n *\n *     11:hello world2:hi\n *\n * If any contents are binary, they will be encoded as base64 strings. Base64\n * encoded strings are marked with a b before the length specifier\n *\n * @param {Array} packets\n * @api private\n */\n\nexports.encodePayload = function (packets, supportsBinary, callback) {\n  if (typeof supportsBinary == 'function') {\n    callback = supportsBinary;\n    supportsBinary = null;\n  }\n\n  var isBinary = hasBinary(packets);\n\n  if (supportsBinary && isBinary) {\n    if (Blob && !dontSendBlobs) {\n      return exports.encodePayloadAsBlob(packets, callback);\n    }\n\n    return exports.encodePayloadAsArrayBuffer(packets, callback);\n  }\n\n  if (!packets.length) {\n    return callback('0:');\n  }\n\n  function setLengthHeader(message) {\n    return message.length + ':' + message;\n  }\n\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function(message) {\n      doneCallback(null, setLengthHeader(message));\n    });\n  }\n\n  map(packets, encodeOne, function(err, results) {\n    return callback(results.join(''));\n  });\n};\n\n/**\n * Async array map using after\n */\n\nfunction map(ary, each, done) {\n  var result = new Array(ary.length);\n  var next = after(ary.length, done);\n\n  var eachWithIndex = function(i, el, cb) {\n    each(el, function(error, msg) {\n      result[i] = msg;\n      cb(error, result);\n    });\n  };\n\n  for (var i = 0; i < ary.length; i++) {\n    eachWithIndex(i, ary[i], next);\n  }\n}\n\n/*\n * Decodes data when a payload is maybe expected. Possible binary contents are\n * decoded from their base64 representation\n *\n * @param {String} data, callback method\n * @api public\n */\n\nexports.decodePayload = function (data, binaryType, callback) {\n  if (typeof data != 'string') {\n    return exports.decodePayloadAsBinary(data, binaryType, callback);\n  }\n\n  if (typeof binaryType === 'function') {\n    callback = binaryType;\n    binaryType = null;\n  }\n\n  var packet;\n  if (data == '') {\n    // parser error - ignoring payload\n    return callback(err, 0, 1);\n  }\n\n  var length = ''\n    , n, msg;\n\n  for (var i = 0, l = data.length; i < l; i++) {\n    var chr = data.charAt(i);\n\n    if (':' != chr) {\n      length += chr;\n    } else {\n      if ('' == length || (length != (n = Number(length)))) {\n        // parser error - ignoring payload\n        return callback(err, 0, 1);\n      }\n\n      msg = data.substr(i + 1, n);\n\n      if (length != msg.length) {\n        // parser error - ignoring payload\n        return callback(err, 0, 1);\n      }\n\n      if (msg.length) {\n        packet = exports.decodePacket(msg, binaryType, true);\n\n        if (err.type == packet.type && err.data == packet.data) {\n          // parser error in individual packet - ignoring payload\n          return callback(err, 0, 1);\n        }\n\n        var ret = callback(packet, i + n, l);\n        if (false === ret) return;\n      }\n\n      // advance cursor\n      i += n;\n      length = '';\n    }\n  }\n\n  if (length != '') {\n    // parser error - ignoring payload\n    return callback(err, 0, 1);\n  }\n\n};\n\n/**\n * Encodes multiple messages (payload) as binary.\n *\n * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number\n * 255><data>\n *\n * Example:\n * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers\n *\n * @param {Array} packets\n * @return {ArrayBuffer} encoded payload\n * @api private\n */\n\nexports.encodePayloadAsArrayBuffer = function(packets, callback) {\n  if (!packets.length) {\n    return callback(new ArrayBuffer(0));\n  }\n\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, true, true, function(data) {\n      return doneCallback(null, data);\n    });\n  }\n\n  map(packets, encodeOne, function(err, encodedPackets) {\n    var totalLength = encodedPackets.reduce(function(acc, p) {\n      var len;\n      if (typeof p === 'string'){\n        len = p.length;\n      } else {\n        len = p.byteLength;\n      }\n      return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2\n    }, 0);\n\n    var resultArray = new Uint8Array(totalLength);\n\n    var bufferIndex = 0;\n    encodedPackets.forEach(function(p) {\n      var isString = typeof p === 'string';\n      var ab = p;\n      if (isString) {\n        var view = new Uint8Array(p.length);\n        for (var i = 0; i < p.length; i++) {\n          view[i] = p.charCodeAt(i);\n        }\n        ab = view.buffer;\n      }\n\n      if (isString) { // not true binary\n        resultArray[bufferIndex++] = 0;\n      } else { // true binary\n        resultArray[bufferIndex++] = 1;\n      }\n\n      var lenStr = ab.byteLength.toString();\n      for (var i = 0; i < lenStr.length; i++) {\n        resultArray[bufferIndex++] = parseInt(lenStr[i]);\n      }\n      resultArray[bufferIndex++] = 255;\n\n      var view = new Uint8Array(ab);\n      for (var i = 0; i < view.length; i++) {\n        resultArray[bufferIndex++] = view[i];\n      }\n    });\n\n    return callback(resultArray.buffer);\n  });\n};\n\n/**\n * Encode as Blob\n */\n\nexports.encodePayloadAsBlob = function(packets, callback) {\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, true, true, function(encoded) {\n      var binaryIdentifier = new Uint8Array(1);\n      binaryIdentifier[0] = 1;\n      if (typeof encoded === 'string') {\n        var view = new Uint8Array(encoded.length);\n        for (var i = 0; i < encoded.length; i++) {\n          view[i] = encoded.charCodeAt(i);\n        }\n        encoded = view.buffer;\n        binaryIdentifier[0] = 0;\n      }\n\n      var len = (encoded instanceof ArrayBuffer)\n        ? encoded.byteLength\n        : encoded.size;\n\n      var lenStr = len.toString();\n      var lengthAry = new Uint8Array(lenStr.length + 1);\n      for (var i = 0; i < lenStr.length; i++) {\n        lengthAry[i] = parseInt(lenStr[i]);\n      }\n      lengthAry[lenStr.length] = 255;\n\n      if (Blob) {\n        var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);\n        doneCallback(null, blob);\n      }\n    });\n  }\n\n  map(packets, encodeOne, function(err, results) {\n    return callback(new Blob(results));\n  });\n};\n\n/*\n * Decodes data when a payload is maybe expected. Strings are decoded by\n * interpreting each byte as a key code for entries marked to start with 0. See\n * description of encodePayloadAsBinary\n *\n * @param {ArrayBuffer} data, callback method\n * @api public\n */\n\nexports.decodePayloadAsBinary = function (data, binaryType, callback) {\n  if (typeof binaryType === 'function') {\n    callback = binaryType;\n    binaryType = null;\n  }\n\n  var bufferTail = data;\n  var buffers = [];\n\n  var numberTooLong = false;\n  while (bufferTail.byteLength > 0) {\n    var tailArray = new Uint8Array(bufferTail);\n    var isString = tailArray[0] === 0;\n    var msgLength = '';\n\n    for (var i = 1; ; i++) {\n      if (tailArray[i] == 255) break;\n\n      if (msgLength.length > 310) {\n        numberTooLong = true;\n        break;\n      }\n\n      msgLength += tailArray[i];\n    }\n\n    if(numberTooLong) return callback(err, 0, 1);\n\n    bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);\n    msgLength = parseInt(msgLength);\n\n    var msg = sliceBuffer(bufferTail, 0, msgLength);\n    if (isString) {\n      try {\n        msg = String.fromCharCode.apply(null, new Uint8Array(msg));\n      } catch (e) {\n        // iPhone Safari doesn't let you apply to typed arrays\n        var typed = new Uint8Array(msg);\n        msg = '';\n        for (var i = 0; i < typed.length; i++) {\n          msg += String.fromCharCode(typed[i]);\n        }\n      }\n    }\n\n    buffers.push(msg);\n    bufferTail = sliceBuffer(bufferTail, msgLength);\n  }\n\n  var total = buffers.length;\n  buffers.forEach(function(buffer, i) {\n    callback(exports.decodePacket(buffer, binaryType, true), i, total);\n  });\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWE2Yy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIvYnJvd3Nlci5qcz9hZjAyIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIga2V5cyA9IHJlcXVpcmUoJy4va2V5cycpO1xudmFyIGhhc0JpbmFyeSA9IHJlcXVpcmUoJ2hhcy1iaW5hcnknKTtcbnZhciBzbGljZUJ1ZmZlciA9IHJlcXVpcmUoJ2FycmF5YnVmZmVyLnNsaWNlJyk7XG52YXIgYWZ0ZXIgPSByZXF1aXJlKCdhZnRlcicpO1xudmFyIHV0ZjggPSByZXF1aXJlKCd3dGYtOCcpO1xuXG52YXIgYmFzZTY0ZW5jb2RlcjtcbmlmIChnbG9iYWwgJiYgZ2xvYmFsLkFycmF5QnVmZmVyKSB7XG4gIGJhc2U2NGVuY29kZXIgPSByZXF1aXJlKCdiYXNlNjQtYXJyYXlidWZmZXInKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgcnVubmluZyBhbiBhbmRyb2lkIGJyb3dzZXIuIFRoYXQgcmVxdWlyZXMgdXMgdG8gdXNlXG4gKiBBcnJheUJ1ZmZlciB3aXRoIHBvbGxpbmcgdHJhbnNwb3J0cy4uLlxuICpcbiAqIGh0dHA6Ly9naGluZGEubmV0L2pwZWctYmxvYi1hamF4LWFuZHJvaWQvXG4gKi9cblxudmFyIGlzQW5kcm9pZCA9IHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmIC9BbmRyb2lkL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgcnVubmluZyBpbiBQaGFudG9tSlMuXG4gKiBVcGxvYWRpbmcgYSBCbG9iIHdpdGggUGhhbnRvbUpTIGRvZXMgbm90IHdvcmsgY29ycmVjdGx5LCBhcyByZXBvcnRlZCBoZXJlOlxuICogaHR0cHM6Ly9naXRodWIuY29tL2FyaXlhL3BoYW50b21qcy9pc3N1ZXMvMTEzOTVcbiAqIEB0eXBlIGJvb2xlYW5cbiAqL1xudmFyIGlzUGhhbnRvbUpTID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgL1BoYW50b21KUy9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG5cbi8qKlxuICogV2hlbiB0cnVlLCBhdm9pZHMgdXNpbmcgQmxvYnMgdG8gZW5jb2RlIHBheWxvYWRzLlxuICogQHR5cGUgYm9vbGVhblxuICovXG52YXIgZG9udFNlbmRCbG9icyA9IGlzQW5kcm9pZCB8fCBpc1BoYW50b21KUztcblxuLyoqXG4gKiBDdXJyZW50IHByb3RvY29sIHZlcnNpb24uXG4gKi9cblxuZXhwb3J0cy5wcm90b2NvbCA9IDM7XG5cbi8qKlxuICogUGFja2V0IHR5cGVzLlxuICovXG5cbnZhciBwYWNrZXRzID0gZXhwb3J0cy5wYWNrZXRzID0ge1xuICAgIG9wZW46ICAgICAwICAgIC8vIG5vbi13c1xuICAsIGNsb3NlOiAgICAxICAgIC8vIG5vbi13c1xuICAsIHBpbmc6ICAgICAyXG4gICwgcG9uZzogICAgIDNcbiAgLCBtZXNzYWdlOiAgNFxuICAsIHVwZ3JhZGU6ICA1XG4gICwgbm9vcDogICAgIDZcbn07XG5cbnZhciBwYWNrZXRzbGlzdCA9IGtleXMocGFja2V0cyk7XG5cbi8qKlxuICogUHJlbWFkZSBlcnJvciBwYWNrZXQuXG4gKi9cblxudmFyIGVyciA9IHsgdHlwZTogJ2Vycm9yJywgZGF0YTogJ3BhcnNlciBlcnJvcicgfTtcblxuLyoqXG4gKiBDcmVhdGUgYSBibG9iIGFwaSBldmVuIGZvciBibG9iIGJ1aWxkZXIgd2hlbiB2ZW5kb3IgcHJlZml4ZXMgZXhpc3RcbiAqL1xuXG52YXIgQmxvYiA9IHJlcXVpcmUoJ2Jsb2InKTtcblxuLyoqXG4gKiBFbmNvZGVzIGEgcGFja2V0LlxuICpcbiAqICAgICA8cGFja2V0IHR5cGUgaWQ+IFsgPGRhdGE+IF1cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICA1aGVsbG8gd29ybGRcbiAqICAgICAzXG4gKiAgICAgNFxuICpcbiAqIEJpbmFyeSBpcyBlbmNvZGVkIGluIGFuIGlkZW50aWNhbCBwcmluY2lwbGVcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLmVuY29kZVBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCB1dGY4ZW5jb2RlLCBjYWxsYmFjaykge1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2Ygc3VwcG9ydHNCaW5hcnkpIHtcbiAgICBjYWxsYmFjayA9IHN1cHBvcnRzQmluYXJ5O1xuICAgIHN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG4gIH1cblxuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgdXRmOGVuY29kZSkge1xuICAgIGNhbGxiYWNrID0gdXRmOGVuY29kZTtcbiAgICB1dGY4ZW5jb2RlID0gbnVsbDtcbiAgfVxuXG4gIHZhciBkYXRhID0gKHBhY2tldC5kYXRhID09PSB1bmRlZmluZWQpXG4gICAgPyB1bmRlZmluZWRcbiAgICA6IHBhY2tldC5kYXRhLmJ1ZmZlciB8fCBwYWNrZXQuZGF0YTtcblxuICBpZiAoZ2xvYmFsLkFycmF5QnVmZmVyICYmIGRhdGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiBlbmNvZGVBcnJheUJ1ZmZlcihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjayk7XG4gIH0gZWxzZSBpZiAoQmxvYiAmJiBkYXRhIGluc3RhbmNlb2YgZ2xvYmFsLkJsb2IpIHtcbiAgICByZXR1cm4gZW5jb2RlQmxvYihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjayk7XG4gIH1cblxuICAvLyBtaWdodCBiZSBhbiBvYmplY3Qgd2l0aCB7IGJhc2U2NDogdHJ1ZSwgZGF0YTogZGF0YUFzQmFzZTY0U3RyaW5nIH1cbiAgaWYgKGRhdGEgJiYgZGF0YS5iYXNlNjQpIHtcbiAgICByZXR1cm4gZW5jb2RlQmFzZTY0T2JqZWN0KHBhY2tldCwgY2FsbGJhY2spO1xuICB9XG5cbiAgLy8gU2VuZGluZyBkYXRhIGFzIGEgdXRmLTggc3RyaW5nXG4gIHZhciBlbmNvZGVkID0gcGFja2V0c1twYWNrZXQudHlwZV07XG5cbiAgLy8gZGF0YSBmcmFnbWVudCBpcyBvcHRpb25hbFxuICBpZiAodW5kZWZpbmVkICE9PSBwYWNrZXQuZGF0YSkge1xuICAgIGVuY29kZWQgKz0gdXRmOGVuY29kZSA/IHV0ZjguZW5jb2RlKFN0cmluZyhwYWNrZXQuZGF0YSkpIDogU3RyaW5nKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHJldHVybiBjYWxsYmFjaygnJyArIGVuY29kZWQpO1xuXG59O1xuXG5mdW5jdGlvbiBlbmNvZGVCYXNlNjRPYmplY3QocGFja2V0LCBjYWxsYmFjaykge1xuICAvLyBwYWNrZXQgZGF0YSBpcyBhbiBvYmplY3QgeyBiYXNlNjQ6IHRydWUsIGRhdGE6IGRhdGFBc0Jhc2U2NFN0cmluZyB9XG4gIHZhciBtZXNzYWdlID0gJ2InICsgZXhwb3J0cy5wYWNrZXRzW3BhY2tldC50eXBlXSArIHBhY2tldC5kYXRhLmRhdGE7XG4gIHJldHVybiBjYWxsYmFjayhtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBFbmNvZGUgcGFja2V0IGhlbHBlcnMgZm9yIGJpbmFyeSB0eXBlc1xuICovXG5cbmZ1bmN0aW9uIGVuY29kZUFycmF5QnVmZmVyKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKSB7XG4gIGlmICghc3VwcG9ydHNCaW5hcnkpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQocGFja2V0LCBjYWxsYmFjayk7XG4gIH1cblxuICB2YXIgZGF0YSA9IHBhY2tldC5kYXRhO1xuICB2YXIgY29udGVudEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gIHZhciByZXN1bHRCdWZmZXIgPSBuZXcgVWludDhBcnJheSgxICsgZGF0YS5ieXRlTGVuZ3RoKTtcblxuICByZXN1bHRCdWZmZXJbMF0gPSBwYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb250ZW50QXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICByZXN1bHRCdWZmZXJbaSsxXSA9IGNvbnRlbnRBcnJheVtpXTtcbiAgfVxuXG4gIHJldHVybiBjYWxsYmFjayhyZXN1bHRCdWZmZXIuYnVmZmVyKTtcbn1cblxuZnVuY3Rpb24gZW5jb2RlQmxvYkFzQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgaWYgKCFzdXBwb3J0c0JpbmFyeSkge1xuICAgIHJldHVybiBleHBvcnRzLmVuY29kZUJhc2U2NFBhY2tldChwYWNrZXQsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHZhciBmciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gIGZyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgIHBhY2tldC5kYXRhID0gZnIucmVzdWx0O1xuICAgIGV4cG9ydHMuZW5jb2RlUGFja2V0KHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIHRydWUsIGNhbGxiYWNrKTtcbiAgfTtcbiAgcmV0dXJuIGZyLnJlYWRBc0FycmF5QnVmZmVyKHBhY2tldC5kYXRhKTtcbn1cblxuZnVuY3Rpb24gZW5jb2RlQmxvYihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjaykge1xuICBpZiAoIXN1cHBvcnRzQmluYXJ5KSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuZW5jb2RlQmFzZTY0UGFja2V0KHBhY2tldCwgY2FsbGJhY2spO1xuICB9XG5cbiAgaWYgKGRvbnRTZW5kQmxvYnMpIHtcbiAgICByZXR1cm4gZW5jb2RlQmxvYkFzQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spO1xuICB9XG5cbiAgdmFyIGxlbmd0aCA9IG5ldyBVaW50OEFycmF5KDEpO1xuICBsZW5ndGhbMF0gPSBwYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgdmFyIGJsb2IgPSBuZXcgQmxvYihbbGVuZ3RoLmJ1ZmZlciwgcGFja2V0LmRhdGFdKTtcblxuICByZXR1cm4gY2FsbGJhY2soYmxvYik7XG59XG5cbi8qKlxuICogRW5jb2RlcyBhIHBhY2tldCB3aXRoIGJpbmFyeSBkYXRhIGluIGEgYmFzZTY0IHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQsIGhhcyBgdHlwZWAgYW5kIGBkYXRhYFxuICogQHJldHVybiB7U3RyaW5nfSBiYXNlNjQgZW5jb2RlZCBtZXNzYWdlXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQsIGNhbGxiYWNrKSB7XG4gIHZhciBtZXNzYWdlID0gJ2InICsgZXhwb3J0cy5wYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgaWYgKEJsb2IgJiYgcGFja2V0LmRhdGEgaW5zdGFuY2VvZiBnbG9iYWwuQmxvYikge1xuICAgIHZhciBmciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgZnIub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYjY0ID0gZnIucmVzdWx0LnNwbGl0KCcsJylbMV07XG4gICAgICBjYWxsYmFjayhtZXNzYWdlICsgYjY0KTtcbiAgICB9O1xuICAgIHJldHVybiBmci5yZWFkQXNEYXRhVVJMKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHZhciBiNjRkYXRhO1xuICB0cnkge1xuICAgIGI2NGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBpUGhvbmUgU2FmYXJpIGRvZXNuJ3QgbGV0IHlvdSBhcHBseSB3aXRoIHR5cGVkIGFycmF5c1xuICAgIHZhciB0eXBlZCA9IG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKTtcbiAgICB2YXIgYmFzaWMgPSBuZXcgQXJyYXkodHlwZWQubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICBiYXNpY1tpXSA9IHR5cGVkW2ldO1xuICAgIH1cbiAgICBiNjRkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBiYXNpYyk7XG4gIH1cbiAgbWVzc2FnZSArPSBnbG9iYWwuYnRvYShiNjRkYXRhKTtcbiAgcmV0dXJuIGNhbGxiYWNrKG1lc3NhZ2UpO1xufTtcblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0LiBDaGFuZ2VzIGZvcm1hdCB0byBCbG9iIGlmIHJlcXVlc3RlZC5cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHdpdGggYHR5cGVgIGFuZCBgZGF0YWAgKGlmIGFueSlcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZGVjb2RlUGFja2V0ID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIHV0ZjhkZWNvZGUpIHtcbiAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBlcnI7XG4gIH1cbiAgLy8gU3RyaW5nIGRhdGFcbiAgaWYgKHR5cGVvZiBkYXRhID09ICdzdHJpbmcnKSB7XG4gICAgaWYgKGRhdGEuY2hhckF0KDApID09ICdiJykge1xuICAgICAgcmV0dXJuIGV4cG9ydHMuZGVjb2RlQmFzZTY0UGFja2V0KGRhdGEuc3Vic3RyKDEpLCBiaW5hcnlUeXBlKTtcbiAgICB9XG5cbiAgICBpZiAodXRmOGRlY29kZSkge1xuICAgICAgZGF0YSA9IHRyeURlY29kZShkYXRhKTtcbiAgICAgIGlmIChkYXRhID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gZXJyO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgdHlwZSA9IGRhdGEuY2hhckF0KDApO1xuXG4gICAgaWYgKE51bWJlcih0eXBlKSAhPSB0eXBlIHx8ICFwYWNrZXRzbGlzdFt0eXBlXSkge1xuICAgICAgcmV0dXJuIGVycjtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS5sZW5ndGggPiAxKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBwYWNrZXRzbGlzdFt0eXBlXSwgZGF0YTogZGF0YS5zdWJzdHJpbmcoMSkgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHsgdHlwZTogcGFja2V0c2xpc3RbdHlwZV0gfTtcbiAgICB9XG4gIH1cblxuICB2YXIgYXNBcnJheSA9IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICB2YXIgdHlwZSA9IGFzQXJyYXlbMF07XG4gIHZhciByZXN0ID0gc2xpY2VCdWZmZXIoZGF0YSwgMSk7XG4gIGlmIChCbG9iICYmIGJpbmFyeVR5cGUgPT09ICdibG9iJykge1xuICAgIHJlc3QgPSBuZXcgQmxvYihbcmVzdF0pO1xuICB9XG4gIHJldHVybiB7IHR5cGU6IHBhY2tldHNsaXN0W3R5cGVdLCBkYXRhOiByZXN0IH07XG59O1xuXG5mdW5jdGlvbiB0cnlEZWNvZGUoZGF0YSkge1xuICB0cnkge1xuICAgIGRhdGEgPSB1dGY4LmRlY29kZShkYXRhKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gZGF0YTtcbn1cblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0IGVuY29kZWQgaW4gYSBiYXNlNjQgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGJhc2U2NCBlbmNvZGVkIG1lc3NhZ2VcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBgdHlwZWAgYW5kIGBkYXRhYCAoaWYgYW55KVxuICovXG5cbmV4cG9ydHMuZGVjb2RlQmFzZTY0UGFja2V0ID0gZnVuY3Rpb24obXNnLCBiaW5hcnlUeXBlKSB7XG4gIHZhciB0eXBlID0gcGFja2V0c2xpc3RbbXNnLmNoYXJBdCgwKV07XG4gIGlmICghYmFzZTY0ZW5jb2Rlcikge1xuICAgIHJldHVybiB7IHR5cGU6IHR5cGUsIGRhdGE6IHsgYmFzZTY0OiB0cnVlLCBkYXRhOiBtc2cuc3Vic3RyKDEpIH0gfTtcbiAgfVxuXG4gIHZhciBkYXRhID0gYmFzZTY0ZW5jb2Rlci5kZWNvZGUobXNnLnN1YnN0cigxKSk7XG5cbiAgaWYgKGJpbmFyeVR5cGUgPT09ICdibG9iJyAmJiBCbG9iKSB7XG4gICAgZGF0YSA9IG5ldyBCbG9iKFtkYXRhXSk7XG4gIH1cblxuICByZXR1cm4geyB0eXBlOiB0eXBlLCBkYXRhOiBkYXRhIH07XG59O1xuXG4vKipcbiAqIEVuY29kZXMgbXVsdGlwbGUgbWVzc2FnZXMgKHBheWxvYWQpLlxuICpcbiAqICAgICA8bGVuZ3RoPjpkYXRhXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgMTE6aGVsbG8gd29ybGQyOmhpXG4gKlxuICogSWYgYW55IGNvbnRlbnRzIGFyZSBiaW5hcnksIHRoZXkgd2lsbCBiZSBlbmNvZGVkIGFzIGJhc2U2NCBzdHJpbmdzLiBCYXNlNjRcbiAqIGVuY29kZWQgc3RyaW5ncyBhcmUgbWFya2VkIHdpdGggYSBiIGJlZm9yZSB0aGUgbGVuZ3RoIHNwZWNpZmllclxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHBhY2tldHNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGF5bG9hZCA9IGZ1bmN0aW9uIChwYWNrZXRzLCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBzdXBwb3J0c0JpbmFyeSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBzdXBwb3J0c0JpbmFyeTtcbiAgICBzdXBwb3J0c0JpbmFyeSA9IG51bGw7XG4gIH1cblxuICB2YXIgaXNCaW5hcnkgPSBoYXNCaW5hcnkocGFja2V0cyk7XG5cbiAgaWYgKHN1cHBvcnRzQmluYXJ5ICYmIGlzQmluYXJ5KSB7XG4gICAgaWYgKEJsb2IgJiYgIWRvbnRTZW5kQmxvYnMpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0Jsb2IocGFja2V0cywgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0FycmF5QnVmZmVyKHBhY2tldHMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIGlmICghcGFja2V0cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gY2FsbGJhY2soJzA6Jyk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkge1xuICAgIHJldHVybiBtZXNzYWdlLmxlbmd0aCArICc6JyArIG1lc3NhZ2U7XG4gIH1cblxuICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICBleHBvcnRzLmVuY29kZVBhY2tldChwYWNrZXQsICFpc0JpbmFyeSA/IGZhbHNlIDogc3VwcG9ydHNCaW5hcnksIHRydWUsIGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgIGRvbmVDYWxsYmFjayhudWxsLCBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkpO1xuICAgIH0pO1xuICB9XG5cbiAgbWFwKHBhY2tldHMsIGVuY29kZU9uZSwgZnVuY3Rpb24oZXJyLCByZXN1bHRzKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdHMuam9pbignJykpO1xuICB9KTtcbn07XG5cbi8qKlxuICogQXN5bmMgYXJyYXkgbWFwIHVzaW5nIGFmdGVyXG4gKi9cblxuZnVuY3Rpb24gbWFwKGFyeSwgZWFjaCwgZG9uZSkge1xuICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KGFyeS5sZW5ndGgpO1xuICB2YXIgbmV4dCA9IGFmdGVyKGFyeS5sZW5ndGgsIGRvbmUpO1xuXG4gIHZhciBlYWNoV2l0aEluZGV4ID0gZnVuY3Rpb24oaSwgZWwsIGNiKSB7XG4gICAgZWFjaChlbCwgZnVuY3Rpb24oZXJyb3IsIG1zZykge1xuICAgICAgcmVzdWx0W2ldID0gbXNnO1xuICAgICAgY2IoZXJyb3IsIHJlc3VsdCk7XG4gICAgfSk7XG4gIH07XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnkubGVuZ3RoOyBpKyspIHtcbiAgICBlYWNoV2l0aEluZGV4KGksIGFyeVtpXSwgbmV4dCk7XG4gIH1cbn1cblxuLypcbiAqIERlY29kZXMgZGF0YSB3aGVuIGEgcGF5bG9hZCBpcyBtYXliZSBleHBlY3RlZC4gUG9zc2libGUgYmluYXJ5IGNvbnRlbnRzIGFyZVxuICogZGVjb2RlZCBmcm9tIHRoZWlyIGJhc2U2NCByZXByZXNlbnRhdGlvblxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhLCBjYWxsYmFjayBtZXRob2RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5kZWNvZGVQYXlsb2FkID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgZGF0YSAhPSAnc3RyaW5nJykge1xuICAgIHJldHVybiBleHBvcnRzLmRlY29kZVBheWxvYWRBc0JpbmFyeShkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjayk7XG4gIH1cblxuICBpZiAodHlwZW9mIGJpbmFyeVR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IGJpbmFyeVR5cGU7XG4gICAgYmluYXJ5VHlwZSA9IG51bGw7XG4gIH1cblxuICB2YXIgcGFja2V0O1xuICBpZiAoZGF0YSA9PSAnJykge1xuICAgIC8vIHBhcnNlciBlcnJvciAtIGlnbm9yaW5nIHBheWxvYWRcbiAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgfVxuXG4gIHZhciBsZW5ndGggPSAnJ1xuICAgICwgbiwgbXNnO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gZGF0YS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIgY2hyID0gZGF0YS5jaGFyQXQoaSk7XG5cbiAgICBpZiAoJzonICE9IGNocikge1xuICAgICAgbGVuZ3RoICs9IGNocjtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCcnID09IGxlbmd0aCB8fCAobGVuZ3RoICE9IChuID0gTnVtYmVyKGxlbmd0aCkpKSkge1xuICAgICAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICAgICAgfVxuXG4gICAgICBtc2cgPSBkYXRhLnN1YnN0cihpICsgMSwgbik7XG5cbiAgICAgIGlmIChsZW5ndGggIT0gbXNnLmxlbmd0aCkge1xuICAgICAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICAgICAgfVxuXG4gICAgICBpZiAobXNnLmxlbmd0aCkge1xuICAgICAgICBwYWNrZXQgPSBleHBvcnRzLmRlY29kZVBhY2tldChtc2csIGJpbmFyeVR5cGUsIHRydWUpO1xuXG4gICAgICAgIGlmIChlcnIudHlwZSA9PSBwYWNrZXQudHlwZSAmJiBlcnIuZGF0YSA9PSBwYWNrZXQuZGF0YSkge1xuICAgICAgICAgIC8vIHBhcnNlciBlcnJvciBpbiBpbmRpdmlkdWFsIHBhY2tldCAtIGlnbm9yaW5nIHBheWxvYWRcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXQgPSBjYWxsYmFjayhwYWNrZXQsIGkgKyBuLCBsKTtcbiAgICAgICAgaWYgKGZhbHNlID09PSByZXQpIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gYWR2YW5jZSBjdXJzb3JcbiAgICAgIGkgKz0gbjtcbiAgICAgIGxlbmd0aCA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIGlmIChsZW5ndGggIT0gJycpIHtcbiAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG4gIH1cblxufTtcblxuLyoqXG4gKiBFbmNvZGVzIG11bHRpcGxlIG1lc3NhZ2VzIChwYXlsb2FkKSBhcyBiaW5hcnkuXG4gKlxuICogPDEgPSBiaW5hcnksIDAgPSBzdHJpbmc+PG51bWJlciBmcm9tIDAtOT48bnVtYmVyIGZyb20gMC05PlsuLi5dPG51bWJlclxuICogMjU1PjxkYXRhPlxuICpcbiAqIEV4YW1wbGU6XG4gKiAxIDMgMjU1IDEgMiAzLCBpZiB0aGUgYmluYXJ5IGNvbnRlbnRzIGFyZSBpbnRlcnByZXRlZCBhcyA4IGJpdCBpbnRlZ2Vyc1xuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHBhY2tldHNcbiAqIEByZXR1cm4ge0FycmF5QnVmZmVyfSBlbmNvZGVkIHBheWxvYWRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGF5bG9hZEFzQXJyYXlCdWZmZXIgPSBmdW5jdGlvbihwYWNrZXRzLCBjYWxsYmFjaykge1xuICBpZiAoIXBhY2tldHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBBcnJheUJ1ZmZlcigwKSk7XG4gIH1cblxuICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICBleHBvcnRzLmVuY29kZVBhY2tldChwYWNrZXQsIHRydWUsIHRydWUsIGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHJldHVybiBkb25lQ2FsbGJhY2sobnVsbCwgZGF0YSk7XG4gICAgfSk7XG4gIH1cblxuICBtYXAocGFja2V0cywgZW5jb2RlT25lLCBmdW5jdGlvbihlcnIsIGVuY29kZWRQYWNrZXRzKSB7XG4gICAgdmFyIHRvdGFsTGVuZ3RoID0gZW5jb2RlZFBhY2tldHMucmVkdWNlKGZ1bmN0aW9uKGFjYywgcCkge1xuICAgICAgdmFyIGxlbjtcbiAgICAgIGlmICh0eXBlb2YgcCA9PT0gJ3N0cmluZycpe1xuICAgICAgICBsZW4gPSBwLmxlbmd0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxlbiA9IHAuYnl0ZUxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2MgKyBsZW4udG9TdHJpbmcoKS5sZW5ndGggKyBsZW4gKyAyOyAvLyBzdHJpbmcvYmluYXJ5IGlkZW50aWZpZXIgKyBzZXBhcmF0b3IgPSAyXG4gICAgfSwgMCk7XG5cbiAgICB2YXIgcmVzdWx0QXJyYXkgPSBuZXcgVWludDhBcnJheSh0b3RhbExlbmd0aCk7XG5cbiAgICB2YXIgYnVmZmVySW5kZXggPSAwO1xuICAgIGVuY29kZWRQYWNrZXRzLmZvckVhY2goZnVuY3Rpb24ocCkge1xuICAgICAgdmFyIGlzU3RyaW5nID0gdHlwZW9mIHAgPT09ICdzdHJpbmcnO1xuICAgICAgdmFyIGFiID0gcDtcbiAgICAgIGlmIChpc1N0cmluZykge1xuICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KHAubGVuZ3RoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmlld1tpXSA9IHAuY2hhckNvZGVBdChpKTtcbiAgICAgICAgfVxuICAgICAgICBhYiA9IHZpZXcuYnVmZmVyO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNTdHJpbmcpIHsgLy8gbm90IHRydWUgYmluYXJ5XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMDtcbiAgICAgIH0gZWxzZSB7IC8vIHRydWUgYmluYXJ5XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMTtcbiAgICAgIH1cblxuICAgICAgdmFyIGxlblN0ciA9IGFiLmJ5dGVMZW5ndGgudG9TdHJpbmcoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuU3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gcGFyc2VJbnQobGVuU3RyW2ldKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMjU1O1xuXG4gICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGFiKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IHZpZXdbaV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY2FsbGJhY2socmVzdWx0QXJyYXkuYnVmZmVyKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEVuY29kZSBhcyBCbG9iXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVQYXlsb2FkQXNCbG9iID0gZnVuY3Rpb24ocGFja2V0cywgY2FsbGJhY2spIHtcbiAgZnVuY3Rpb24gZW5jb2RlT25lKHBhY2tldCwgZG9uZUNhbGxiYWNrKSB7XG4gICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCB0cnVlLCB0cnVlLCBmdW5jdGlvbihlbmNvZGVkKSB7XG4gICAgICB2YXIgYmluYXJ5SWRlbnRpZmllciA9IG5ldyBVaW50OEFycmF5KDEpO1xuICAgICAgYmluYXJ5SWRlbnRpZmllclswXSA9IDE7XG4gICAgICBpZiAodHlwZW9mIGVuY29kZWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoZW5jb2RlZC5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVuY29kZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2aWV3W2ldID0gZW5jb2RlZC5jaGFyQ29kZUF0KGkpO1xuICAgICAgICB9XG4gICAgICAgIGVuY29kZWQgPSB2aWV3LmJ1ZmZlcjtcbiAgICAgICAgYmluYXJ5SWRlbnRpZmllclswXSA9IDA7XG4gICAgICB9XG5cbiAgICAgIHZhciBsZW4gPSAoZW5jb2RlZCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKVxuICAgICAgICA/IGVuY29kZWQuYnl0ZUxlbmd0aFxuICAgICAgICA6IGVuY29kZWQuc2l6ZTtcblxuICAgICAgdmFyIGxlblN0ciA9IGxlbi50b1N0cmluZygpO1xuICAgICAgdmFyIGxlbmd0aEFyeSA9IG5ldyBVaW50OEFycmF5KGxlblN0ci5sZW5ndGggKyAxKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuU3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxlbmd0aEFyeVtpXSA9IHBhcnNlSW50KGxlblN0cltpXSk7XG4gICAgICB9XG4gICAgICBsZW5ndGhBcnlbbGVuU3RyLmxlbmd0aF0gPSAyNTU7XG5cbiAgICAgIGlmIChCbG9iKSB7XG4gICAgICAgIHZhciBibG9iID0gbmV3IEJsb2IoW2JpbmFyeUlkZW50aWZpZXIuYnVmZmVyLCBsZW5ndGhBcnkuYnVmZmVyLCBlbmNvZGVkXSk7XG4gICAgICAgIGRvbmVDYWxsYmFjayhudWxsLCBibG9iKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG1hcChwYWNrZXRzLCBlbmNvZGVPbmUsIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICAgIHJldHVybiBjYWxsYmFjayhuZXcgQmxvYihyZXN1bHRzKSk7XG4gIH0pO1xufTtcblxuLypcbiAqIERlY29kZXMgZGF0YSB3aGVuIGEgcGF5bG9hZCBpcyBtYXliZSBleHBlY3RlZC4gU3RyaW5ncyBhcmUgZGVjb2RlZCBieVxuICogaW50ZXJwcmV0aW5nIGVhY2ggYnl0ZSBhcyBhIGtleSBjb2RlIGZvciBlbnRyaWVzIG1hcmtlZCB0byBzdGFydCB3aXRoIDAuIFNlZVxuICogZGVzY3JpcHRpb24gb2YgZW5jb2RlUGF5bG9hZEFzQmluYXJ5XG4gKlxuICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gZGF0YSwgY2FsbGJhY2sgbWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb2RlUGF5bG9hZEFzQmluYXJ5ID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgYmluYXJ5VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gYmluYXJ5VHlwZTtcbiAgICBiaW5hcnlUeXBlID0gbnVsbDtcbiAgfVxuXG4gIHZhciBidWZmZXJUYWlsID0gZGF0YTtcbiAgdmFyIGJ1ZmZlcnMgPSBbXTtcblxuICB2YXIgbnVtYmVyVG9vTG9uZyA9IGZhbHNlO1xuICB3aGlsZSAoYnVmZmVyVGFpbC5ieXRlTGVuZ3RoID4gMCkge1xuICAgIHZhciB0YWlsQXJyYXkgPSBuZXcgVWludDhBcnJheShidWZmZXJUYWlsKTtcbiAgICB2YXIgaXNTdHJpbmcgPSB0YWlsQXJyYXlbMF0gPT09IDA7XG4gICAgdmFyIG1zZ0xlbmd0aCA9ICcnO1xuXG4gICAgZm9yICh2YXIgaSA9IDE7IDsgaSsrKSB7XG4gICAgICBpZiAodGFpbEFycmF5W2ldID09IDI1NSkgYnJlYWs7XG5cbiAgICAgIGlmIChtc2dMZW5ndGgubGVuZ3RoID4gMzEwKSB7XG4gICAgICAgIG51bWJlclRvb0xvbmcgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgbXNnTGVuZ3RoICs9IHRhaWxBcnJheVtpXTtcbiAgICB9XG5cbiAgICBpZihudW1iZXJUb29Mb25nKSByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcblxuICAgIGJ1ZmZlclRhaWwgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCAyICsgbXNnTGVuZ3RoLmxlbmd0aCk7XG4gICAgbXNnTGVuZ3RoID0gcGFyc2VJbnQobXNnTGVuZ3RoKTtcblxuICAgIHZhciBtc2cgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCAwLCBtc2dMZW5ndGgpO1xuICAgIGlmIChpc1N0cmluZykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbXNnID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDhBcnJheShtc2cpKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gaVBob25lIFNhZmFyaSBkb2Vzbid0IGxldCB5b3UgYXBwbHkgdG8gdHlwZWQgYXJyYXlzXG4gICAgICAgIHZhciB0eXBlZCA9IG5ldyBVaW50OEFycmF5KG1zZyk7XG4gICAgICAgIG1zZyA9ICcnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgbXNnICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodHlwZWRbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgYnVmZmVycy5wdXNoKG1zZyk7XG4gICAgYnVmZmVyVGFpbCA9IHNsaWNlQnVmZmVyKGJ1ZmZlclRhaWwsIG1zZ0xlbmd0aCk7XG4gIH1cblxuICB2YXIgdG90YWwgPSBidWZmZXJzLmxlbmd0aDtcbiAgYnVmZmVycy5mb3JFYWNoKGZ1bmN0aW9uKGJ1ZmZlciwgaSkge1xuICAgIGNhbGxiYWNrKGV4cG9ydHMuZGVjb2RlUGFja2V0KGJ1ZmZlciwgYmluYXJ5VHlwZSwgdHJ1ZSksIGksIHRvdGFsKTtcbiAgfSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///aa6c\n")},adfa:function(module,exports,__webpack_require__){eval("/**\n * Utility functions for crossfilter datasets\n * We roughly follow the crossfilter design of dimensions and groups, but we\n * add extra steps to allow transformations on the data.\n * 1. a datum is turned into a raw value, ie. string or number etc. by rawValueFn\n * 2. it is then cast to the correct type value using baseValFn\n * 3. a further transfrom can be applied with valueFn\n * 4. a value is grouped using groupFn; this value must be either a number or a string.\n *\n * @module client/util-crossfilter\n * @see rawValueFn, baseValueFn, valueFn, groupFn\n */\nvar misval = __webpack_require__(/*! ./misval */ \"bff6\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\n\n/**\n * @typedef {Object} SubgroupValue\n * @property {number} count The count of the number of elements in this subgroup\n * @property {number} sum The sum of all elements in this subgroup\n */\n\n/**\n * Reduce a SubgroupValue to a single number\n *\n * @callback reduceCB\n * @param {SubgroupValue} d SubgroupValue\n * @returns {number} Reduced value\n */\n/**\n\n/**\n * Returns a function for further reducing the crossfilter group\n * to a single value, depending on sum/count/average settings of\n * the Aggregate class.\n * @param {Aggregate} facet - The Aggregate class for which to create the reduction function\n * @returns {cb} The required reduction function\n */\nfunction reduceFn (aggregate) {\n  if (aggregate.doSum) {\n    /**\n     * @callback subgroupSum\n     * @param {SubgroupValue} d\n     * @returns {number} sum\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n      if (d.count > 0) {\n        return d.sum;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doCount) {\n    /**\n     * @callback subgroupCount\n     * @param {SubgroupValue} d\n     * @returns {number} count\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n      if (d.count > 0) {\n        return d.count;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doAverage) {\n    /**\n     * @callback subgroupAverage\n     * @param {SubgroupValue} d\n     * @returns {number} d.sum/d.count\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n\n      if (d.count > 0) {\n        return d.sum / d.count;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doStddev) {\n    /**\n     * @callback subgroupStddev\n     * @param {SubgroupValue} d\n     * @returns {number} stddev(d)\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n\n      // \\sum_i (x_i - \\bar x)^2 =\n      //   \\sum_i (x_i^2 - 2x_i\\bar x + (\\bar x)^2) =\n      //   \\sum_i (x_i^2) - 2 N (\\bar x)^2 + N(\\bar x)^2 =\n      //   \\sum_i (x_i^2) - N (\\bar x)^2\n      if (d.count > 1) {\n        return Math.sqrt((d.sumsquares - (d.sum * d.sum / d.count)) / (d.count - 1));\n      } else {\n        return misval;\n      }\n    };\n  }\n\n  console.error('Operation not implemented for this Aggregate', aggregate);\n  return function (d) {\n    if (d === misval || d == null) {\n      return misval;\n    }\n    if (d.count > 0) {\n      return d.count;\n    } else {\n      return misval;\n    }\n  };\n}\n\n// ********************************************************\n// Facet transform utility function\n// ********************************************************\n\n/**\n * Returns the base value for a datum\n *\n * @callback baseValueCB\n * @param {Object} d Raw data record\n * @returns {Object} base value\n */\n\n/**\n * Raw value for given facet\n * @param {Facet} facet\n * @returns {rawValueCB} Raw value function for this facet\n */\nfunction rawValueFn (facet) {\n  var accessor;\n\n  // Array dimensions have a [] appended to the accessor,\n  // remove it to get to the actual accessor\n  var path = facet.accessor;\n  if (path.match(/\\[]$/)) {\n    path = path.substring(0, path.length - 2);\n  }\n\n  var misvals = {};\n  facet.misval.forEach(function (val) {\n    misvals[val] = true;\n  });\n\n  // Access nested properties via a double hash sign, this to prevent collision with regular keys; fi. 'person.name'\n  path = path.split('##');\n\n  if (path.length === 1) {\n    // Use a simple direct accessor, as it is probably faster than the more general case\n    // and it was implemented already\n    if (facet.misval.length > 0) {\n      accessor = function (d) {\n        var value = d[path[0]];\n        if (value === undefined || value === null || value in misvals) {\n          return misval;\n        }\n        return value;\n      };\n    } else {\n      accessor = function (d) {\n        var value = d[path[0]];\n        if (value === undefined || value === null) {\n          return misval;\n        }\n        return value;\n      };\n    }\n  } else {\n    // Recursively follow the crumbs to the desired property\n    accessor = function (d) {\n      var i = 0;\n      var value = d;\n\n      for (i = 0; i < path.length; i++) {\n        if (value && value[path[i]] !== undefined) {\n          value = value[path[i]];\n        } else {\n          return misval;\n        }\n      }\n\n      if (value === null || value in misvals) {\n        value = misval;\n      }\n      return value;\n    };\n  }\n\n  return accessor;\n}\n\n/**\n * Base value for given facet, ie. cast to correct type or object.\n * @param {Facet} facet\n * @returns {vaseValueCB} Base value function for this facet\n */\nfunction baseValueFn (facet) {\n  var rawValFn = rawValueFn(facet);\n\n  if (facet.isContinuous) {\n    /*\n     * Continuous facets:\n     * Parse numeric value from base value\n     */\n    return function (d) {\n      var val = parseFloat(rawValFn(d));\n      if (isNaN(val) || val === Infinity || val === -Infinity) {\n        return misval;\n      }\n      return val;\n    };\n  } else if (facet.isCategorial) {\n    return function (d) {\n      var vals = rawValFn(d);\n      if (vals !== misval) {\n        if (vals instanceof Array) {\n          vals.forEach(function (val, i) {\n            vals[i] = val.toString();\n          });\n        } else {\n          vals = vals.toString();\n        }\n        return vals;\n      }\n      return misval;\n    };\n  } else if (facet.isDatetime) {\n    /*\n     * Time parsing:\n     * 1. moment parses the string using the given format, but defaults to\n     *    the [ISO 8601 standard](https://en.wikipedia.org/wiki/ISO_8601)\n     * 2. Note that if the string contains timezone information, that is parsed too.\n     * 3. The time is transformed to requested timezone, defaulting the locale default\n     *    when no zone is set\n    */\n    var timeFormat = facet.datetimeTransform.format;\n    if (timeFormat === 'ISO8601') {\n      // use default ISO formatting\n      timeFormat = moment.ISO_8601;\n    }\n\n    var timeZone = facet.datetimeTransform.zone;\n    if (timeZone === 'ISO8601') {\n      // use default locale timezone, get overridden if a string contains a timezone\n      timeZone = moment.tz.guess();\n    } else {\n      timeZone = util.timeZones.get(timeZone, 'description').format;\n    }\n\n    return function (d) {\n      var value = rawValFn(d);\n      if (value !== misval) {\n        var m = moment.tz(value, timeFormat, timeZone);\n        if (m.isValid()) {\n          return m;\n        }\n      }\n      return misval;\n    };\n  } else if (facet.isDuration) {\n    /*\n     * Duration parsing:\n     * 1. If no format is given, the string parsed using\n     *    the [ISO 8601 standard](https://en.wikipedia.org/wiki/ISO_8601)\n     * 2. If a format is given, the string is parsed as float and interpreted in the given units\n     */\n    var units = facet.durationTransform.units;\n    if (units === 'ISO8601') {\n      return function (d) {\n        var value = rawValFn(d);\n\n        // parse string if necessary\n        if (value !== misval && typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          value = moment.duration(value);\n        }\n\n        // check for valid duration\n        if (moment.isDuration(value)) {\n          return value;\n        }\n\n        return misval;\n      };\n    } else {\n      units = util.durationUnits.get(units, 'description').momentFormat;\n      return function (d) {\n        var value = rawValFn(d);\n\n        // parse string if necessary\n        if (value !== misval && !isNaN(value)) {\n          // NOTE: isNaN('0') is false, if that gives problems, we could use:\n          // value == +value) { // eslint-disable-line eqeqeq\n          value = moment.duration(parseFloat(value), units);\n        }\n\n        // check for valid duration\n        if (moment.isDuration(value)) {\n          return value;\n        }\n\n        return misval;\n      };\n    }\n  }\n\n  // isCategorial, isText\n  // no casting or constructing necessary, return the raw value\n  return rawValFn;\n}\n\n/**\n * Returns the transformed value from a base value\n *\n * @callback valueCB\n * @param {Object} d Base value\n * @returns {Object} Transformed value\n */\n\n/**\n * Create a function that returns the transformed value for this facet\n * @param {Facet} facet\n * @returns {valueCB} Value function for this facet\n */\nfunction valueFn (facet) {\n  // get base value function\n  var baseValFn = baseValueFn(facet);\n\n  if (facet.isConstant) {\n    return function () { return '1'; };\n  } else if (facet.isContinuous) {\n    // do we have a continuous transform?\n    if (facet.continuousTransform && facet.continuousTransform.type !== 'none') {\n      // yes, use it\n      return function (d) {\n        var val = facet.continuousTransform.transform(parseFloat(baseValFn(d)));\n        if (isNaN(val) || val === Infinity || val === -Infinity) {\n          return misval;\n        }\n        return val;\n      };\n    }\n  } else if (facet.isCategorial) {\n    // do we have a categorial transform?\n    if (facet.categorialTransform && facet.categorialTransform.rules.length > 0) {\n      // yes, use it\n      return function (d) {\n        var val = baseValFn(d);\n        return val === misval ? misval : facet.categorialTransform.transform(baseValFn(d));\n      };\n    }\n  } else if (facet.isDatetime) {\n    // always use the transform, so we do not have to repeat the yes/no transfrom logic here\n    return function (d) {\n      var val = baseValFn(d);\n      return val === misval ? misval : facet.datetimeTransform.transform(val);\n    };\n  } else if (facet.isDuration) {\n    // always use the transform, so we do not have to repeat the yes/no transfrom logic here\n    return function (d) {\n      var val = baseValFn(d);\n      return val === misval ? misval : facet.durationTransform.transform(val);\n    };\n  }\n\n  // no transfrom, return base value\n  return baseValFn;\n}\n\nfunction continuousGroupFn (partition) {\n  return function (d) {\n    if (d === misval) {\n      return d;\n    }\n\n    var ngroups = partition.groups.length;\n    if (d < partition.minval || d > partition.maxval) {\n      return misval;\n    }\n\n    // bins include their lower bound, but not their upper bound\n    var i = 0;\n    while (i < ngroups && d >= partition.groups.models[i].max) {\n      i++;\n    }\n    // special case last bin includes also upperbound d === partition.maxval\n    if (i === ngroups) {\n      return partition.groups.models[i - 1].value;\n    }\n    return partition.groups.models[i].value;\n  };\n}\n\n/*\n * Round the datetime to the specified resolution\n * see:\n * http://momentjs.com/docs/#/manipulating/start-of/\n * http://momentjs.com/docs/#/displaying/as-javascript-date/\n */\nfunction datetimeGroupFn (partition) {\n  var timeStep = util.getDatetimeResolution(partition.minval, partition.maxval);\n  return function (d) {\n    if (d === misval) {\n      return misval;\n    }\n    if (d.isBefore(partition.minval) || d.isAfter(partition.maxval)) {\n      return misval;\n    }\n    var grouped = moment(d).startOf(timeStep).format();\n    return grouped;\n  };\n}\n\n/*\n * Round the duration to the specified resolution\n */\nfunction durationGroupFn (partition) {\n  var timeStep = util.getDurationResolution(partition.minval, partition.maxval);\n  return function (d) {\n    if (d === misval) {\n      return misval;\n    }\n    if (d < partition.minval || d > partition.maxval) {\n      return misval;\n    }\n    var rounded = Math.floor(parseFloat(d.as(timeStep)));\n    return moment.duration(rounded, timeStep).toISOString();\n  };\n}\n\n/*\n * Don't do any grouping; that is done in the step from base value to value.\n * Matching of facet value and group could lead to a different ordering,\n * which is not allowed by crossfilter\n */\nfunction categorialGroupFn (partition) {\n  return function (d) { return d; };\n}\n\n/**\n * Returns the grouped value for a transformed value\n *\n * @callback groupCB\n * @param {Object} d Transformed value\n * @returns {Object} Group\n */\n\n/**\n * Create a function that returns the group value for a partition\n * @param {Partition} partition\n * @returns {cb} Group function for this partition, taking a `Data`\n */\nfunction groupFn (partition) {\n  if (partition.isConstant) {\n    return function () { return '1'; };\n  } else if (partition.isContinuous) {\n    return continuousGroupFn(partition);\n  } else if (partition.isCategorial) {\n    return categorialGroupFn(partition);\n  } else if (partition.isDatetime) {\n    return datetimeGroupFn(partition);\n  } else if (partition.isDuration) {\n    return durationGroupFn(partition);\n  } else if (partition.isText) {\n    return function (d) { return d.toString(); };\n  } else {\n    console.error('Group function not implemented for partition', partition);\n  }\n}\n\nmodule.exports = {\n  rawValueFn: rawValueFn,\n  baseValueFn: baseValueFn,\n  valueFn: valueFn,\n  groupFn: groupFn,\n\n  reduceFn: reduceFn\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRmYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9jcm9zc2ZpbHRlci5qcz8xZjdhIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIGNyb3NzZmlsdGVyIGRhdGFzZXRzXG4gKiBXZSByb3VnaGx5IGZvbGxvdyB0aGUgY3Jvc3NmaWx0ZXIgZGVzaWduIG9mIGRpbWVuc2lvbnMgYW5kIGdyb3VwcywgYnV0IHdlXG4gKiBhZGQgZXh0cmEgc3RlcHMgdG8gYWxsb3cgdHJhbnNmb3JtYXRpb25zIG9uIHRoZSBkYXRhLlxuICogMS4gYSBkYXR1bSBpcyB0dXJuZWQgaW50byBhIHJhdyB2YWx1ZSwgaWUuIHN0cmluZyBvciBudW1iZXIgZXRjLiBieSByYXdWYWx1ZUZuXG4gKiAyLiBpdCBpcyB0aGVuIGNhc3QgdG8gdGhlIGNvcnJlY3QgdHlwZSB2YWx1ZSB1c2luZyBiYXNlVmFsRm5cbiAqIDMuIGEgZnVydGhlciB0cmFuc2Zyb20gY2FuIGJlIGFwcGxpZWQgd2l0aCB2YWx1ZUZuXG4gKiA0LiBhIHZhbHVlIGlzIGdyb3VwZWQgdXNpbmcgZ3JvdXBGbjsgdGhpcyB2YWx1ZSBtdXN0IGJlIGVpdGhlciBhIG51bWJlciBvciBhIHN0cmluZy5cbiAqXG4gKiBAbW9kdWxlIGNsaWVudC91dGlsLWNyb3NzZmlsdGVyXG4gKiBAc2VlIHJhd1ZhbHVlRm4sIGJhc2VWYWx1ZUZuLCB2YWx1ZUZuLCBncm91cEZuXG4gKi9cbnZhciBtaXN2YWwgPSByZXF1aXJlKCcuL21pc3ZhbCcpO1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsL3RpbWUnKTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTdWJncm91cFZhbHVlXG4gKiBAcHJvcGVydHkge251bWJlcn0gY291bnQgVGhlIGNvdW50IG9mIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBzdWJncm91cFxuICogQHByb3BlcnR5IHtudW1iZXJ9IHN1bSBUaGUgc3VtIG9mIGFsbCBlbGVtZW50cyBpbiB0aGlzIHN1Ymdyb3VwXG4gKi9cblxuLyoqXG4gKiBSZWR1Y2UgYSBTdWJncm91cFZhbHVlIHRvIGEgc2luZ2xlIG51bWJlclxuICpcbiAqIEBjYWxsYmFjayByZWR1Y2VDQlxuICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkIFN1Ymdyb3VwVmFsdWVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJlZHVjZWQgdmFsdWVcbiAqL1xuLyoqXG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIGZvciBmdXJ0aGVyIHJlZHVjaW5nIHRoZSBjcm9zc2ZpbHRlciBncm91cFxuICogdG8gYSBzaW5nbGUgdmFsdWUsIGRlcGVuZGluZyBvbiBzdW0vY291bnQvYXZlcmFnZSBzZXR0aW5ncyBvZlxuICogdGhlIEFnZ3JlZ2F0ZSBjbGFzcy5cbiAqIEBwYXJhbSB7QWdncmVnYXRlfSBmYWNldCAtIFRoZSBBZ2dyZWdhdGUgY2xhc3MgZm9yIHdoaWNoIHRvIGNyZWF0ZSB0aGUgcmVkdWN0aW9uIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7Y2J9IFRoZSByZXF1aXJlZCByZWR1Y3Rpb24gZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gcmVkdWNlRm4gKGFnZ3JlZ2F0ZSkge1xuICBpZiAoYWdncmVnYXRlLmRvU3VtKSB7XG4gICAgLyoqXG4gICAgICogQGNhbGxiYWNrIHN1Ymdyb3VwU3VtXG4gICAgICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkXG4gICAgICogQHJldHVybnMge251bWJlcn0gc3VtXG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICBpZiAoZCA9PT0gbWlzdmFsIHx8IGQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgICAgaWYgKGQuY291bnQgPiAwKSB7XG4gICAgICAgIHJldHVybiBkLnN1bTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIGlmIChhZ2dyZWdhdGUuZG9Db3VudCkge1xuICAgIC8qKlxuICAgICAqIEBjYWxsYmFjayBzdWJncm91cENvdW50XG4gICAgICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkXG4gICAgICogQHJldHVybnMge251bWJlcn0gY291bnRcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGQuY291bnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgIH07XG4gIH0gZWxzZSBpZiAoYWdncmVnYXRlLmRvQXZlcmFnZSkge1xuICAgIC8qKlxuICAgICAqIEBjYWxsYmFjayBzdWJncm91cEF2ZXJhZ2VcbiAgICAgKiBAcGFyYW0ge1N1Ymdyb3VwVmFsdWV9IGRcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBkLnN1bS9kLmNvdW50XG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICBpZiAoZCA9PT0gbWlzdmFsIHx8IGQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuXG4gICAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGQuc3VtIC8gZC5jb3VudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIGlmIChhZ2dyZWdhdGUuZG9TdGRkZXYpIHtcbiAgICAvKipcbiAgICAgKiBAY2FsbGJhY2sgc3ViZ3JvdXBTdGRkZXZcbiAgICAgKiBAcGFyYW0ge1N1Ymdyb3VwVmFsdWV9IGRcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBzdGRkZXYoZClcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG5cbiAgICAgIC8vIFxcc3VtX2kgKHhfaSAtIFxcYmFyIHgpXjIgPVxuICAgICAgLy8gICBcXHN1bV9pICh4X2leMiAtIDJ4X2lcXGJhciB4ICsgKFxcYmFyIHgpXjIpID1cbiAgICAgIC8vICAgXFxzdW1faSAoeF9pXjIpIC0gMiBOIChcXGJhciB4KV4yICsgTihcXGJhciB4KV4yID1cbiAgICAgIC8vICAgXFxzdW1faSAoeF9pXjIpIC0gTiAoXFxiYXIgeCleMlxuICAgICAgaWYgKGQuY291bnQgPiAxKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnNxcnQoKGQuc3Vtc3F1YXJlcyAtIChkLnN1bSAqIGQuc3VtIC8gZC5jb3VudCkpIC8gKGQuY291bnQgLSAxKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBjb25zb2xlLmVycm9yKCdPcGVyYXRpb24gbm90IGltcGxlbWVudGVkIGZvciB0aGlzIEFnZ3JlZ2F0ZScsIGFnZ3JlZ2F0ZSk7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgIHJldHVybiBkLmNvdW50O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgfTtcbn1cblxuLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbi8vIEZhY2V0IHRyYW5zZm9ybSB1dGlsaXR5IGZ1bmN0aW9uXG4vLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG4vKipcbiAqIFJldHVybnMgdGhlIGJhc2UgdmFsdWUgZm9yIGEgZGF0dW1cbiAqXG4gKiBAY2FsbGJhY2sgYmFzZVZhbHVlQ0JcbiAqIEBwYXJhbSB7T2JqZWN0fSBkIFJhdyBkYXRhIHJlY29yZFxuICogQHJldHVybnMge09iamVjdH0gYmFzZSB2YWx1ZVxuICovXG5cbi8qKlxuICogUmF3IHZhbHVlIGZvciBnaXZlbiBmYWNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqIEByZXR1cm5zIHtyYXdWYWx1ZUNCfSBSYXcgdmFsdWUgZnVuY3Rpb24gZm9yIHRoaXMgZmFjZXRcbiAqL1xuZnVuY3Rpb24gcmF3VmFsdWVGbiAoZmFjZXQpIHtcbiAgdmFyIGFjY2Vzc29yO1xuXG4gIC8vIEFycmF5IGRpbWVuc2lvbnMgaGF2ZSBhIFtdIGFwcGVuZGVkIHRvIHRoZSBhY2Nlc3NvcixcbiAgLy8gcmVtb3ZlIGl0IHRvIGdldCB0byB0aGUgYWN0dWFsIGFjY2Vzc29yXG4gIHZhciBwYXRoID0gZmFjZXQuYWNjZXNzb3I7XG4gIGlmIChwYXRoLm1hdGNoKC9cXFtdJC8pKSB7XG4gICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoIC0gMik7XG4gIH1cblxuICB2YXIgbWlzdmFscyA9IHt9O1xuICBmYWNldC5taXN2YWwuZm9yRWFjaChmdW5jdGlvbiAodmFsKSB7XG4gICAgbWlzdmFsc1t2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgLy8gQWNjZXNzIG5lc3RlZCBwcm9wZXJ0aWVzIHZpYSBhIGRvdWJsZSBoYXNoIHNpZ24sIHRoaXMgdG8gcHJldmVudCBjb2xsaXNpb24gd2l0aCByZWd1bGFyIGtleXM7IGZpLiAncGVyc29uLm5hbWUnXG4gIHBhdGggPSBwYXRoLnNwbGl0KCcjIycpO1xuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMSkge1xuICAgIC8vIFVzZSBhIHNpbXBsZSBkaXJlY3QgYWNjZXNzb3IsIGFzIGl0IGlzIHByb2JhYmx5IGZhc3RlciB0aGFuIHRoZSBtb3JlIGdlbmVyYWwgY2FzZVxuICAgIC8vIGFuZCBpdCB3YXMgaW1wbGVtZW50ZWQgYWxyZWFkeVxuICAgIGlmIChmYWNldC5taXN2YWwubGVuZ3RoID4gMCkge1xuICAgICAgYWNjZXNzb3IgPSBmdW5jdGlvbiAoZCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBkW3BhdGhbMF1dO1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSBpbiBtaXN2YWxzKSB7XG4gICAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBhY2Nlc3NvciA9IGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGRbcGF0aFswXV07XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBSZWN1cnNpdmVseSBmb2xsb3cgdGhlIGNydW1icyB0byB0aGUgZGVzaXJlZCBwcm9wZXJ0eVxuICAgIGFjY2Vzc29yID0gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciBpID0gMDtcbiAgICAgIHZhciB2YWx1ZSA9IGQ7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh2YWx1ZSAmJiB2YWx1ZVtwYXRoW2ldXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZVtwYXRoW2ldXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSBpbiBtaXN2YWxzKSB7XG4gICAgICAgIHZhbHVlID0gbWlzdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gYWNjZXNzb3I7XG59XG5cbi8qKlxuICogQmFzZSB2YWx1ZSBmb3IgZ2l2ZW4gZmFjZXQsIGllLiBjYXN0IHRvIGNvcnJlY3QgdHlwZSBvciBvYmplY3QuXG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICogQHJldHVybnMge3Zhc2VWYWx1ZUNCfSBCYXNlIHZhbHVlIGZ1bmN0aW9uIGZvciB0aGlzIGZhY2V0XG4gKi9cbmZ1bmN0aW9uIGJhc2VWYWx1ZUZuIChmYWNldCkge1xuICB2YXIgcmF3VmFsRm4gPSByYXdWYWx1ZUZuKGZhY2V0KTtcblxuICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgLypcbiAgICAgKiBDb250aW51b3VzIGZhY2V0czpcbiAgICAgKiBQYXJzZSBudW1lcmljIHZhbHVlIGZyb20gYmFzZSB2YWx1ZVxuICAgICAqL1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbCA9IHBhcnNlRmxvYXQocmF3VmFsRm4oZCkpO1xuICAgICAgaWYgKGlzTmFOKHZhbCkgfHwgdmFsID09PSBJbmZpbml0eSB8fCB2YWwgPT09IC1JbmZpbml0eSkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbDtcbiAgICB9O1xuICB9IGVsc2UgaWYgKGZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbHMgPSByYXdWYWxGbihkKTtcbiAgICAgIGlmICh2YWxzICE9PSBtaXN2YWwpIHtcbiAgICAgICAgaWYgKHZhbHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgIHZhbHMuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBpKSB7XG4gICAgICAgICAgICB2YWxzW2ldID0gdmFsLnRvU3RyaW5nKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFscyA9IHZhbHMudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFscztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgLypcbiAgICAgKiBUaW1lIHBhcnNpbmc6XG4gICAgICogMS4gbW9tZW50IHBhcnNlcyB0aGUgc3RyaW5nIHVzaW5nIHRoZSBnaXZlbiBmb3JtYXQsIGJ1dCBkZWZhdWx0cyB0b1xuICAgICAqICAgIHRoZSBbSVNPIDg2MDEgc3RhbmRhcmRdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT184NjAxKVxuICAgICAqIDIuIE5vdGUgdGhhdCBpZiB0aGUgc3RyaW5nIGNvbnRhaW5zIHRpbWV6b25lIGluZm9ybWF0aW9uLCB0aGF0IGlzIHBhcnNlZCB0b28uXG4gICAgICogMy4gVGhlIHRpbWUgaXMgdHJhbnNmb3JtZWQgdG8gcmVxdWVzdGVkIHRpbWV6b25lLCBkZWZhdWx0aW5nIHRoZSBsb2NhbGUgZGVmYXVsdFxuICAgICAqICAgIHdoZW4gbm8gem9uZSBpcyBzZXRcbiAgICAqL1xuICAgIHZhciB0aW1lRm9ybWF0ID0gZmFjZXQuZGF0ZXRpbWVUcmFuc2Zvcm0uZm9ybWF0O1xuICAgIGlmICh0aW1lRm9ybWF0ID09PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIHVzZSBkZWZhdWx0IElTTyBmb3JtYXR0aW5nXG4gICAgICB0aW1lRm9ybWF0ID0gbW9tZW50LklTT184NjAxO1xuICAgIH1cblxuICAgIHZhciB0aW1lWm9uZSA9IGZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnpvbmU7XG4gICAgaWYgKHRpbWVab25lID09PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIHVzZSBkZWZhdWx0IGxvY2FsZSB0aW1lem9uZSwgZ2V0IG92ZXJyaWRkZW4gaWYgYSBzdHJpbmcgY29udGFpbnMgYSB0aW1lem9uZVxuICAgICAgdGltZVpvbmUgPSBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGltZVpvbmUgPSB1dGlsLnRpbWVab25lcy5nZXQodGltZVpvbmUsICdkZXNjcmlwdGlvbicpLmZvcm1hdDtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWx1ZSA9IHJhd1ZhbEZuKGQpO1xuICAgICAgaWYgKHZhbHVlICE9PSBtaXN2YWwpIHtcbiAgICAgICAgdmFyIG0gPSBtb21lbnQudHoodmFsdWUsIHRpbWVGb3JtYXQsIHRpbWVab25lKTtcbiAgICAgICAgaWYgKG0uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIG07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0R1cmF0aW9uKSB7XG4gICAgLypcbiAgICAgKiBEdXJhdGlvbiBwYXJzaW5nOlxuICAgICAqIDEuIElmIG5vIGZvcm1hdCBpcyBnaXZlbiwgdGhlIHN0cmluZyBwYXJzZWQgdXNpbmdcbiAgICAgKiAgICB0aGUgW0lTTyA4NjAxIHN0YW5kYXJkXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSlcbiAgICAgKiAyLiBJZiBhIGZvcm1hdCBpcyBnaXZlbiwgdGhlIHN0cmluZyBpcyBwYXJzZWQgYXMgZmxvYXQgYW5kIGludGVycHJldGVkIGluIHRoZSBnaXZlbiB1bml0c1xuICAgICAqL1xuICAgIHZhciB1bml0cyA9IGZhY2V0LmR1cmF0aW9uVHJhbnNmb3JtLnVuaXRzO1xuICAgIGlmICh1bml0cyA9PT0gJ0lTTzg2MDEnKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gcmF3VmFsRm4oZCk7XG5cbiAgICAgICAgLy8gcGFyc2Ugc3RyaW5nIGlmIG5lY2Vzc2FyeVxuICAgICAgICBpZiAodmFsdWUgIT09IG1pc3ZhbCAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlWzBdLnRvTG93ZXJDYXNlKCkgPT09ICdwJykge1xuICAgICAgICAgIHZhbHVlID0gbW9tZW50LmR1cmF0aW9uKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGZvciB2YWxpZCBkdXJhdGlvblxuICAgICAgICBpZiAobW9tZW50LmlzRHVyYXRpb24odmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuaXRzID0gdXRpbC5kdXJhdGlvblVuaXRzLmdldCh1bml0cywgJ2Rlc2NyaXB0aW9uJykubW9tZW50Rm9ybWF0O1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJhd1ZhbEZuKGQpO1xuXG4gICAgICAgIC8vIHBhcnNlIHN0cmluZyBpZiBuZWNlc3NhcnlcbiAgICAgICAgaWYgKHZhbHVlICE9PSBtaXN2YWwgJiYgIWlzTmFOKHZhbHVlKSkge1xuICAgICAgICAgIC8vIE5PVEU6IGlzTmFOKCcwJykgaXMgZmFsc2UsIGlmIHRoYXQgZ2l2ZXMgcHJvYmxlbXMsIHdlIGNvdWxkIHVzZTpcbiAgICAgICAgICAvLyB2YWx1ZSA9PSArdmFsdWUpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICAgICAgICB2YWx1ZSA9IG1vbWVudC5kdXJhdGlvbihwYXJzZUZsb2F0KHZhbHVlKSwgdW5pdHMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIHZhbGlkIGR1cmF0aW9uXG4gICAgICAgIGlmIChtb21lbnQuaXNEdXJhdGlvbih2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvLyBpc0NhdGVnb3JpYWwsIGlzVGV4dFxuICAvLyBubyBjYXN0aW5nIG9yIGNvbnN0cnVjdGluZyBuZWNlc3NhcnksIHJldHVybiB0aGUgcmF3IHZhbHVlXG4gIHJldHVybiByYXdWYWxGbjtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB0cmFuc2Zvcm1lZCB2YWx1ZSBmcm9tIGEgYmFzZSB2YWx1ZVxuICpcbiAqIEBjYWxsYmFjayB2YWx1ZUNCXG4gKiBAcGFyYW0ge09iamVjdH0gZCBCYXNlIHZhbHVlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBUcmFuc2Zvcm1lZCB2YWx1ZVxuICovXG5cbi8qKlxuICogQ3JlYXRlIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB0cmFuc2Zvcm1lZCB2YWx1ZSBmb3IgdGhpcyBmYWNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqIEByZXR1cm5zIHt2YWx1ZUNCfSBWYWx1ZSBmdW5jdGlvbiBmb3IgdGhpcyBmYWNldFxuICovXG5mdW5jdGlvbiB2YWx1ZUZuIChmYWNldCkge1xuICAvLyBnZXQgYmFzZSB2YWx1ZSBmdW5jdGlvblxuICB2YXIgYmFzZVZhbEZuID0gYmFzZVZhbHVlRm4oZmFjZXQpO1xuXG4gIGlmIChmYWNldC5pc0NvbnN0YW50KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsgcmV0dXJuICcxJzsgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0NvbnRpbnVvdXMpIHtcbiAgICAvLyBkbyB3ZSBoYXZlIGEgY29udGludW91cyB0cmFuc2Zvcm0/XG4gICAgaWYgKGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm0gJiYgZmFjZXQuY29udGludW91c1RyYW5zZm9ybS50eXBlICE9PSAnbm9uZScpIHtcbiAgICAgIC8vIHllcywgdXNlIGl0XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgdmFyIHZhbCA9IGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm0udHJhbnNmb3JtKHBhcnNlRmxvYXQoYmFzZVZhbEZuKGQpKSk7XG4gICAgICAgIGlmIChpc05hTih2YWwpIHx8IHZhbCA9PT0gSW5maW5pdHkgfHwgdmFsID09PSAtSW5maW5pdHkpIHtcbiAgICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIGlmIChmYWNldC5pc0NhdGVnb3JpYWwpIHtcbiAgICAvLyBkbyB3ZSBoYXZlIGEgY2F0ZWdvcmlhbCB0cmFuc2Zvcm0/XG4gICAgaWYgKGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0gJiYgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyB5ZXMsIHVzZSBpdFxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWwgPSBiYXNlVmFsRm4oZCk7XG4gICAgICAgIHJldHVybiB2YWwgPT09IG1pc3ZhbCA/IG1pc3ZhbCA6IGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0udHJhbnNmb3JtKGJhc2VWYWxGbihkKSk7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgLy8gYWx3YXlzIHVzZSB0aGUgdHJhbnNmb3JtLCBzbyB3ZSBkbyBub3QgaGF2ZSB0byByZXBlYXQgdGhlIHllcy9ubyB0cmFuc2Zyb20gbG9naWMgaGVyZVxuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbCA9IGJhc2VWYWxGbihkKTtcbiAgICAgIHJldHVybiB2YWwgPT09IG1pc3ZhbCA/IG1pc3ZhbCA6IGZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnRyYW5zZm9ybSh2YWwpO1xuICAgIH07XG4gIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgIC8vIGFsd2F5cyB1c2UgdGhlIHRyYW5zZm9ybSwgc28gd2UgZG8gbm90IGhhdmUgdG8gcmVwZWF0IHRoZSB5ZXMvbm8gdHJhbnNmcm9tIGxvZ2ljIGhlcmVcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWwgPSBiYXNlVmFsRm4oZCk7XG4gICAgICByZXR1cm4gdmFsID09PSBtaXN2YWwgPyBtaXN2YWwgOiBmYWNldC5kdXJhdGlvblRyYW5zZm9ybS50cmFuc2Zvcm0odmFsKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gbm8gdHJhbnNmcm9tLCByZXR1cm4gYmFzZSB2YWx1ZVxuICByZXR1cm4gYmFzZVZhbEZuO1xufVxuXG5mdW5jdGlvbiBjb250aW51b3VzR3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiBkO1xuICAgIH1cblxuICAgIHZhciBuZ3JvdXBzID0gcGFydGl0aW9uLmdyb3Vwcy5sZW5ndGg7XG4gICAgaWYgKGQgPCBwYXJ0aXRpb24ubWludmFsIHx8IGQgPiBwYXJ0aXRpb24ubWF4dmFsKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cblxuICAgIC8vIGJpbnMgaW5jbHVkZSB0aGVpciBsb3dlciBib3VuZCwgYnV0IG5vdCB0aGVpciB1cHBlciBib3VuZFxuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoaSA8IG5ncm91cHMgJiYgZCA+PSBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpXS5tYXgpIHtcbiAgICAgIGkrKztcbiAgICB9XG4gICAgLy8gc3BlY2lhbCBjYXNlIGxhc3QgYmluIGluY2x1ZGVzIGFsc28gdXBwZXJib3VuZCBkID09PSBwYXJ0aXRpb24ubWF4dmFsXG4gICAgaWYgKGkgPT09IG5ncm91cHMpIHtcbiAgICAgIHJldHVybiBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpIC0gMV0udmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpXS52YWx1ZTtcbiAgfTtcbn1cblxuLypcbiAqIFJvdW5kIHRoZSBkYXRldGltZSB0byB0aGUgc3BlY2lmaWVkIHJlc29sdXRpb25cbiAqIHNlZTpcbiAqIGh0dHA6Ly9tb21lbnRqcy5jb20vZG9jcy8jL21hbmlwdWxhdGluZy9zdGFydC1vZi9cbiAqIGh0dHA6Ly9tb21lbnRqcy5jb20vZG9jcy8jL2Rpc3BsYXlpbmcvYXMtamF2YXNjcmlwdC1kYXRlL1xuICovXG5mdW5jdGlvbiBkYXRldGltZUdyb3VwRm4gKHBhcnRpdGlvbikge1xuICB2YXIgdGltZVN0ZXAgPSB1dGlsLmdldERhdGV0aW1lUmVzb2x1dGlvbihwYXJ0aXRpb24ubWludmFsLCBwYXJ0aXRpb24ubWF4dmFsKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgaWYgKGQgPT09IG1pc3ZhbCkge1xuICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICB9XG4gICAgaWYgKGQuaXNCZWZvcmUocGFydGl0aW9uLm1pbnZhbCkgfHwgZC5pc0FmdGVyKHBhcnRpdGlvbi5tYXh2YWwpKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgICB2YXIgZ3JvdXBlZCA9IG1vbWVudChkKS5zdGFydE9mKHRpbWVTdGVwKS5mb3JtYXQoKTtcbiAgICByZXR1cm4gZ3JvdXBlZDtcbiAgfTtcbn1cblxuLypcbiAqIFJvdW5kIHRoZSBkdXJhdGlvbiB0byB0aGUgc3BlY2lmaWVkIHJlc29sdXRpb25cbiAqL1xuZnVuY3Rpb24gZHVyYXRpb25Hcm91cEZuIChwYXJ0aXRpb24pIHtcbiAgdmFyIHRpbWVTdGVwID0gdXRpbC5nZXREdXJhdGlvblJlc29sdXRpb24ocGFydGl0aW9uLm1pbnZhbCwgcGFydGl0aW9uLm1heHZhbCk7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfVxuICAgIGlmIChkIDwgcGFydGl0aW9uLm1pbnZhbCB8fCBkID4gcGFydGl0aW9uLm1heHZhbCkge1xuICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICB9XG4gICAgdmFyIHJvdW5kZWQgPSBNYXRoLmZsb29yKHBhcnNlRmxvYXQoZC5hcyh0aW1lU3RlcCkpKTtcbiAgICByZXR1cm4gbW9tZW50LmR1cmF0aW9uKHJvdW5kZWQsIHRpbWVTdGVwKS50b0lTT1N0cmluZygpO1xuICB9O1xufVxuXG4vKlxuICogRG9uJ3QgZG8gYW55IGdyb3VwaW5nOyB0aGF0IGlzIGRvbmUgaW4gdGhlIHN0ZXAgZnJvbSBiYXNlIHZhbHVlIHRvIHZhbHVlLlxuICogTWF0Y2hpbmcgb2YgZmFjZXQgdmFsdWUgYW5kIGdyb3VwIGNvdWxkIGxlYWQgdG8gYSBkaWZmZXJlbnQgb3JkZXJpbmcsXG4gKiB3aGljaCBpcyBub3QgYWxsb3dlZCBieSBjcm9zc2ZpbHRlclxuICovXG5mdW5jdGlvbiBjYXRlZ29yaWFsR3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkgeyByZXR1cm4gZDsgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBncm91cGVkIHZhbHVlIGZvciBhIHRyYW5zZm9ybWVkIHZhbHVlXG4gKlxuICogQGNhbGxiYWNrIGdyb3VwQ0JcbiAqIEBwYXJhbSB7T2JqZWN0fSBkIFRyYW5zZm9ybWVkIHZhbHVlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBHcm91cFxuICovXG5cbi8qKlxuICogQ3JlYXRlIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBncm91cCB2YWx1ZSBmb3IgYSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEByZXR1cm5zIHtjYn0gR3JvdXAgZnVuY3Rpb24gZm9yIHRoaXMgcGFydGl0aW9uLCB0YWtpbmcgYSBgRGF0YWBcbiAqL1xuZnVuY3Rpb24gZ3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIGlmIChwYXJ0aXRpb24uaXNDb25zdGFudCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7IHJldHVybiAnMSc7IH07XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzQ29udGludW91cykge1xuICAgIHJldHVybiBjb250aW51b3VzR3JvdXBGbihwYXJ0aXRpb24pO1xuICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwpIHtcbiAgICByZXR1cm4gY2F0ZWdvcmlhbEdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNEYXRldGltZSkge1xuICAgIHJldHVybiBkYXRldGltZUdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNEdXJhdGlvbikge1xuICAgIHJldHVybiBkdXJhdGlvbkdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNUZXh0KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7IHJldHVybiBkLnRvU3RyaW5nKCk7IH07XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS5lcnJvcignR3JvdXAgZnVuY3Rpb24gbm90IGltcGxlbWVudGVkIGZvciBwYXJ0aXRpb24nLCBwYXJ0aXRpb24pO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICByYXdWYWx1ZUZuOiByYXdWYWx1ZUZuLFxuICBiYXNlVmFsdWVGbjogYmFzZVZhbHVlRm4sXG4gIHZhbHVlRm46IHZhbHVlRm4sXG4gIGdyb3VwRm46IGdyb3VwRm4sXG5cbiAgcmVkdWNlRm46IHJlZHVjZUZuXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///adfa\n")},b123:function(module,exports,__webpack_require__){eval("/**\n * DurationTransfrom defines a transformation on duration data\n *\n * @class DurationTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Units of the duration\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    units: ['string', true, 'ISO8601'],\n\n    /**\n     * For durations, transforms duration to these units\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    transformedUnits: ['string', true, 'ISO8601'],\n\n    /**\n     * Transform the date to this timezone.\n     *\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedZone: ['string', true, 'ISO8601'],\n\n    /**\n     * Controls conversion to datetime by adding this date\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    transformedReference: 'string'\n  },\n  derived: {\n    /**\n     * Reference momentjs for duration <-> datetime conversion\n     *\n     * @type {moment}\n     * @memberof! DurationTransform\n     */\n    referenceMoment: {\n      deps: ['transformedReference', 'transformedZone'],\n      fn: function () {\n        var tz;\n        if (this.transformedZone === 'ISO8601') {\n          tz = moment.tz.guess();\n        } else {\n          var timeZone = util.timeZones.get(this.transformedZone, 'description');\n          if (timeZone && timeZone.format) {\n            tz = timeZone.format;\n          } else {\n            tz = moment.tz.guess();\n          }\n        }\n\n        if (this.transformedReference) {\n          return moment.tz(this.transformedReference, tz);\n        }\n        return null;\n      }\n    },\n    /**\n     * The type of the facet after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DurationTransform\n     */\n    transformedType: {\n      deps: ['transformedFormat', 'transformedReference', 'transformedZone'],\n      fn: function () {\n        if (this.referenceMoment) {\n          return 'datetime';\n        } else if (this.transformedUnits !== 'ISO8601') {\n          return 'continuous';\n        } else {\n          return 'duration';\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minium value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMin: {\n      deps: ['transformedType'],\n      fn: function () {\n        var facet = this.parent;\n        if (this.transformedType === 'datetime') {\n          return this.transform(facet.minval);\n        } else if (this.transformedType === 'continuous') {\n          return this.transform(facet.minval);\n        } else {\n          return facet.minval;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMax: {\n      deps: ['transformedType'],\n      fn: function () {\n        var facet = this.parent;\n        if (this.transformedType === 'datetime') {\n          return this.transform(facet.maxval);\n        } else if (this.transformedType === 'continuous') {\n          return this.transform(facet.maxval);\n        } else {\n          return facet.maxval;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n\n  /**\n   * Apply the configured transformation to this Facet's value\n   *\n   * @function\n   * @memberof! DurationTransform\n   * @param {Object} inval momentjs duration\n   * @returns {Object} outval momentjs duration or datetime\n   */\n  transform: function transform (inval) {\n    var units;\n    if (this.referenceMoment) {\n      // duration -> datetime\n      return this.referenceMoment.clone().add(inval);\n    } else if (this.transformedUnits !== 'ISO8601') {\n      // duration -> continuous\n      units = util.durationUnits.get(this.transformedUnits, 'description').momentFormat;\n      return inval.as(units);\n    } else {\n      // no change\n      return inval;\n    }\n  },\n  reset: function () {\n    this.unset(['zone', 'transformedFormat', 'transformedZone', 'transformedReference']);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjEyMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvZHVyYXRpb24tdHJhbnNmb3JtLmpzPzJkZjUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEdXJhdGlvblRyYW5zZnJvbSBkZWZpbmVzIGEgdHJhbnNmb3JtYXRpb24gb24gZHVyYXRpb24gZGF0YVxuICpcbiAqIEBjbGFzcyBEdXJhdGlvblRyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC90aW1lJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBVbml0cyBvZiB0aGUgZHVyYXRpb25cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHVuaXRzOiBbJ3N0cmluZycsIHRydWUsICdJU084NjAxJ10sXG5cbiAgICAvKipcbiAgICAgKiBGb3IgZHVyYXRpb25zLCB0cmFuc2Zvcm1zIGR1cmF0aW9uIHRvIHRoZXNlIHVuaXRzXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFVuaXRzOiBbJ3N0cmluZycsIHRydWUsICdJU084NjAxJ10sXG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm0gdGhlIGRhdGUgdG8gdGhpcyB0aW1lem9uZS5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkWm9uZTogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogQ29udHJvbHMgY29udmVyc2lvbiB0byBkYXRldGltZSBieSBhZGRpbmcgdGhpcyBkYXRlXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFJlZmVyZW5jZTogJ3N0cmluZydcbiAgfSxcbiAgZGVyaXZlZDoge1xuICAgIC8qKlxuICAgICAqIFJlZmVyZW5jZSBtb21lbnRqcyBmb3IgZHVyYXRpb24gPC0+IGRhdGV0aW1lIGNvbnZlcnNpb25cbiAgICAgKlxuICAgICAqIEB0eXBlIHttb21lbnR9XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblRyYW5zZm9ybVxuICAgICAqL1xuICAgIHJlZmVyZW5jZU1vbWVudDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZFJlZmVyZW5jZScsICd0cmFuc2Zvcm1lZFpvbmUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0ejtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRab25lID09PSAnSVNPODYwMScpIHtcbiAgICAgICAgICB0eiA9IG1vbWVudC50ei5ndWVzcygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciB0aW1lWm9uZSA9IHV0aWwudGltZVpvbmVzLmdldCh0aGlzLnRyYW5zZm9ybWVkWm9uZSwgJ2Rlc2NyaXB0aW9uJyk7XG4gICAgICAgICAgaWYgKHRpbWVab25lICYmIHRpbWVab25lLmZvcm1hdCkge1xuICAgICAgICAgICAgdHogPSB0aW1lWm9uZS5mb3JtYXQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHR6ID0gbW9tZW50LnR6Lmd1ZXNzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXR1cm4gbW9tZW50LnR6KHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UsIHR6KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBmYWNldCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRUeXBlOiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkRm9ybWF0JywgJ3RyYW5zZm9ybWVkUmVmZXJlbmNlJywgJ3RyYW5zZm9ybWVkWm9uZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMucmVmZXJlbmNlTW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuICdkYXRldGltZSc7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy50cmFuc2Zvcm1lZFVuaXRzICE9PSAnSVNPODYwMScpIHtcbiAgICAgICAgICByZXR1cm4gJ2NvbnRpbnVvdXMnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiAnZHVyYXRpb24nO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWluaXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1pbjoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmYWNldCA9IHRoaXMucGFyZW50O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0oZmFjZXQubWludmFsKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2NvbnRpbnVvdXMnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKGZhY2V0Lm1pbnZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGZhY2V0Lm1pbnZhbDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWF4OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZhY2V0ID0gdGhpcy5wYXJlbnQ7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybShmYWNldC5tYXh2YWwpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnY29udGludW91cycpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0oZmFjZXQubWF4dmFsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZmFjZXQubWF4dmFsO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWluaW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNaW5Bc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRNaW4nLCAndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWludmFsID0gdGhpcy50cmFuc2Zvcm1lZE1pbjtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnZGF0ZXRpbWUnKSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC5mb3JtYXQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWludmFsLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1heEFzVGV4dDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZE1heCcsICd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXh2YWwgPSB0aGlzLnRyYW5zZm9ybWVkTWF4O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLmZvcm1hdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogQXBwbHkgdGhlIGNvbmZpZ3VyZWQgdHJhbnNmb3JtYXRpb24gdG8gdGhpcyBGYWNldCdzIHZhbHVlXG4gICAqXG4gICAqIEBmdW5jdGlvblxuICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBpbnZhbCBtb21lbnRqcyBkdXJhdGlvblxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBvdXR2YWwgbW9tZW50anMgZHVyYXRpb24gb3IgZGF0ZXRpbWVcbiAgICovXG4gIHRyYW5zZm9ybTogZnVuY3Rpb24gdHJhbnNmb3JtIChpbnZhbCkge1xuICAgIHZhciB1bml0cztcbiAgICBpZiAodGhpcy5yZWZlcmVuY2VNb21lbnQpIHtcbiAgICAgIC8vIGR1cmF0aW9uIC0+IGRhdGV0aW1lXG4gICAgICByZXR1cm4gdGhpcy5yZWZlcmVuY2VNb21lbnQuY2xvbmUoKS5hZGQoaW52YWwpO1xuICAgIH0gZWxzZSBpZiAodGhpcy50cmFuc2Zvcm1lZFVuaXRzICE9PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIGR1cmF0aW9uIC0+IGNvbnRpbnVvdXNcbiAgICAgIHVuaXRzID0gdXRpbC5kdXJhdGlvblVuaXRzLmdldCh0aGlzLnRyYW5zZm9ybWVkVW5pdHMsICdkZXNjcmlwdGlvbicpLm1vbWVudEZvcm1hdDtcbiAgICAgIHJldHVybiBpbnZhbC5hcyh1bml0cyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG5vIGNoYW5nZVxuICAgICAgcmV0dXJuIGludmFsO1xuICAgIH1cbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVuc2V0KFsnem9uZScsICd0cmFuc2Zvcm1lZEZvcm1hdCcsICd0cmFuc2Zvcm1lZFpvbmUnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///b123\n")},b452:function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar url = __webpack_require__(/*! ./url */ \"780f\");\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar Manager = __webpack_require__(/*! ./manager */ \"1e1f\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client');\n\n/**\n * Module exports.\n */\n\nmodule.exports = exports = lookup;\n\n/**\n * Managers cache.\n */\n\nvar cache = exports.managers = {};\n\n/**\n * Looks up an existing `Manager` for multiplexing.\n * If the user summons:\n *\n *   `io('http://localhost/a');`\n *   `io('http://localhost/b');`\n *\n * We reuse the existing instance based on same scheme/port/host,\n * and we initialize sockets for each namespace.\n *\n * @api public\n */\n\nfunction lookup (uri, opts) {\n  if (typeof uri === 'object') {\n    opts = uri;\n    uri = undefined;\n  }\n\n  opts = opts || {};\n\n  var parsed = url(uri);\n  var source = parsed.source;\n  var id = parsed.id;\n  var path = parsed.path;\n  var sameNamespace = cache[id] && path in cache[id].nsps;\n  var newConnection = opts.forceNew || opts['force new connection'] ||\n                      false === opts.multiplex || sameNamespace;\n\n  var io;\n\n  if (newConnection) {\n    debug('ignoring socket cache for %s', source);\n    io = Manager(source, opts);\n  } else {\n    if (!cache[id]) {\n      debug('new io instance for %s', source);\n      cache[id] = Manager(source, opts);\n    }\n    io = cache[id];\n  }\n  if (parsed.query && !opts.query) {\n    opts.query = parsed.query;\n  } else if (opts && 'object' === typeof opts.query) {\n    opts.query = encodeQueryString(opts.query);\n  }\n  return io.socket(parsed.path, opts);\n}\n/**\n *  Helper method to parse query objects to string.\n * @param {object} query\n * @returns {string}\n */\nfunction encodeQueryString (obj) {\n  var str = [];\n  for (var p in obj) {\n    if (obj.hasOwnProperty(p)) {\n      str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));\n    }\n  }\n  return str.join('&');\n}\n/**\n * Protocol version.\n *\n * @api public\n */\n\nexports.protocol = parser.protocol;\n\n/**\n * `connect`.\n *\n * @param {String} uri\n * @api public\n */\n\nexports.connect = lookup;\n\n/**\n * Expose constructors for standalone build.\n *\n * @api public\n */\n\nexports.Manager = __webpack_require__(/*! ./manager */ \"1e1f\");\nexports.Socket = __webpack_require__(/*! ./socket */ \"4c13\");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjQ1Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvaW5kZXguanM/ZjQyZiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgdXJsID0gcmVxdWlyZSgnLi91cmwnKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgTWFuYWdlciA9IHJlcXVpcmUoJy4vbWFuYWdlcicpO1xudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnc29ja2V0LmlvLWNsaWVudCcpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGxvb2t1cDtcblxuLyoqXG4gKiBNYW5hZ2VycyBjYWNoZS5cbiAqL1xuXG52YXIgY2FjaGUgPSBleHBvcnRzLm1hbmFnZXJzID0ge307XG5cbi8qKlxuICogTG9va3MgdXAgYW4gZXhpc3RpbmcgYE1hbmFnZXJgIGZvciBtdWx0aXBsZXhpbmcuXG4gKiBJZiB0aGUgdXNlciBzdW1tb25zOlxuICpcbiAqICAgYGlvKCdodHRwOi8vbG9jYWxob3N0L2EnKTtgXG4gKiAgIGBpbygnaHR0cDovL2xvY2FsaG9zdC9iJyk7YFxuICpcbiAqIFdlIHJldXNlIHRoZSBleGlzdGluZyBpbnN0YW5jZSBiYXNlZCBvbiBzYW1lIHNjaGVtZS9wb3J0L2hvc3QsXG4gKiBhbmQgd2UgaW5pdGlhbGl6ZSBzb2NrZXRzIGZvciBlYWNoIG5hbWVzcGFjZS5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGxvb2t1cCAodXJpLCBvcHRzKSB7XG4gIGlmICh0eXBlb2YgdXJpID09PSAnb2JqZWN0Jykge1xuICAgIG9wdHMgPSB1cmk7XG4gICAgdXJpID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgdmFyIHBhcnNlZCA9IHVybCh1cmkpO1xuICB2YXIgc291cmNlID0gcGFyc2VkLnNvdXJjZTtcbiAgdmFyIGlkID0gcGFyc2VkLmlkO1xuICB2YXIgcGF0aCA9IHBhcnNlZC5wYXRoO1xuICB2YXIgc2FtZU5hbWVzcGFjZSA9IGNhY2hlW2lkXSAmJiBwYXRoIGluIGNhY2hlW2lkXS5uc3BzO1xuICB2YXIgbmV3Q29ubmVjdGlvbiA9IG9wdHMuZm9yY2VOZXcgfHwgb3B0c1snZm9yY2UgbmV3IGNvbm5lY3Rpb24nXSB8fFxuICAgICAgICAgICAgICAgICAgICAgIGZhbHNlID09PSBvcHRzLm11bHRpcGxleCB8fCBzYW1lTmFtZXNwYWNlO1xuXG4gIHZhciBpbztcblxuICBpZiAobmV3Q29ubmVjdGlvbikge1xuICAgIGRlYnVnKCdpZ25vcmluZyBzb2NrZXQgY2FjaGUgZm9yICVzJywgc291cmNlKTtcbiAgICBpbyA9IE1hbmFnZXIoc291cmNlLCBvcHRzKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoIWNhY2hlW2lkXSkge1xuICAgICAgZGVidWcoJ25ldyBpbyBpbnN0YW5jZSBmb3IgJXMnLCBzb3VyY2UpO1xuICAgICAgY2FjaGVbaWRdID0gTWFuYWdlcihzb3VyY2UsIG9wdHMpO1xuICAgIH1cbiAgICBpbyA9IGNhY2hlW2lkXTtcbiAgfVxuICBpZiAocGFyc2VkLnF1ZXJ5ICYmICFvcHRzLnF1ZXJ5KSB7XG4gICAgb3B0cy5xdWVyeSA9IHBhcnNlZC5xdWVyeTtcbiAgfSBlbHNlIGlmIChvcHRzICYmICdvYmplY3QnID09PSB0eXBlb2Ygb3B0cy5xdWVyeSkge1xuICAgIG9wdHMucXVlcnkgPSBlbmNvZGVRdWVyeVN0cmluZyhvcHRzLnF1ZXJ5KTtcbiAgfVxuICByZXR1cm4gaW8uc29ja2V0KHBhcnNlZC5wYXRoLCBvcHRzKTtcbn1cbi8qKlxuICogIEhlbHBlciBtZXRob2QgdG8gcGFyc2UgcXVlcnkgb2JqZWN0cyB0byBzdHJpbmcuXG4gKiBAcGFyYW0ge29iamVjdH0gcXVlcnlcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGVuY29kZVF1ZXJ5U3RyaW5nIChvYmopIHtcbiAgdmFyIHN0ciA9IFtdO1xuICBmb3IgKHZhciBwIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkocCkpIHtcbiAgICAgIHN0ci5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChwKSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChvYmpbcF0pKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0ci5qb2luKCcmJyk7XG59XG4vKipcbiAqIFByb3RvY29sIHZlcnNpb24uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sO1xuXG4vKipcbiAqIGBjb25uZWN0YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJpXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuY29ubmVjdCA9IGxvb2t1cDtcblxuLyoqXG4gKiBFeHBvc2UgY29uc3RydWN0b3JzIGZvciBzdGFuZGFsb25lIGJ1aWxkLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5NYW5hZ2VyID0gcmVxdWlyZSgnLi9tYW5hZ2VyJyk7XG5leHBvcnRzLlNvY2tldCA9IHJlcXVpcmUoJy4vc29ja2V0Jyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///b452\n")},ba23:function(module,exports,__webpack_require__){eval("/**\n * Categorial Rule abstracts a single matching rule\n *\n * @class CategorialRule\n */\nvar Base = __webpack_require__(/*! ../util/base */ \"3902\");\n\n// Data structure for mapping categorial (and textual) data on groups\nmodule.exports = Base.extend({\n  props: {\n    /**\n     * string or string format of regexp to match data against.\n     * To use a regular expression, start and end the string with a slash, '/'.\n     * Options can be appedended, notably 'i' for case insensitive matching.\n     * The first captured group can be used in the group, see below.\n     * Examples\n     * 1. 'hello' matches 'hello', not 'hello world'\n     * 2. '/hello/' matches 'hello world', but not 'Hello world'\n     * 3. '/hello/i' matches 'I say Hello'\n     * @type {string}\n     * @memberof! CategorialRule\n     */\n    expression: ['string', true, 'Missing'],\n\n    /**\n     * Number of items this transform is used\n     * @type {number}\n     * @memberof! CategorialRule\n     */\n    count: ['number', true, 0],\n\n    /**\n     * Name of the group this is mapped to. The special substring $1 is replaced by the first captured group,\n     * in example 4 above, with group set to 'He says $1', the match results in 'He says goodbye'\n     * @type {string}\n     * @memberof! CategorialRule\n     */\n    group: ['string', true, 'Missing']\n  },\n  derived: {\n\n    /**\n     * Match function\n     * @memberof! CategorialRule\n     * @function\n     * @param {string} text The text to match\n     * @returns {string|false} group The group label if matching, else false\n     */\n    match: {\n      deps: ['expression', 'group'],\n      fn: function () {\n        var that = this;\n\n        var reFormat = new RegExp(/^\\/(.*)\\/([gimuy]*)$/);\n        var match = reFormat.exec(that.expression);\n\n        if (match) {\n          // if the expression is in the form of /<text>/<flags>, it is a regular expression, compile it\n          var exp = RegExp(match[1], match[2]);\n          return function (text) {\n            var m = exp.exec(text);\n            if (m) {\n              return that.group;\n              // return that.group.replace('$1', m[1]);\n            } else {\n              return false;\n            }\n          };\n        } else {\n          // otherwise do matching using '==='\n          return function (text) {\n            if (text === that.expression) {\n              return that.group;\n            } else {\n              return false;\n            }\n          };\n        }\n      }\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmEyMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY2F0ZWdvcmlhbC1ydWxlLmpzP2UxNzMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDYXRlZ29yaWFsIFJ1bGUgYWJzdHJhY3RzIGEgc2luZ2xlIG1hdGNoaW5nIHJ1bGVcbiAqXG4gKiBAY2xhc3MgQ2F0ZWdvcmlhbFJ1bGVcbiAqL1xudmFyIEJhc2UgPSByZXF1aXJlKCcuLi91dGlsL2Jhc2UnKTtcblxuLy8gRGF0YSBzdHJ1Y3R1cmUgZm9yIG1hcHBpbmcgY2F0ZWdvcmlhbCAoYW5kIHRleHR1YWwpIGRhdGEgb24gZ3JvdXBzXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2UuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBzdHJpbmcgb3Igc3RyaW5nIGZvcm1hdCBvZiByZWdleHAgdG8gbWF0Y2ggZGF0YSBhZ2FpbnN0LlxuICAgICAqIFRvIHVzZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbiwgc3RhcnQgYW5kIGVuZCB0aGUgc3RyaW5nIHdpdGggYSBzbGFzaCwgJy8nLlxuICAgICAqIE9wdGlvbnMgY2FuIGJlIGFwcGVkZW5kZWQsIG5vdGFibHkgJ2knIGZvciBjYXNlIGluc2Vuc2l0aXZlIG1hdGNoaW5nLlxuICAgICAqIFRoZSBmaXJzdCBjYXB0dXJlZCBncm91cCBjYW4gYmUgdXNlZCBpbiB0aGUgZ3JvdXAsIHNlZSBiZWxvdy5cbiAgICAgKiBFeGFtcGxlc1xuICAgICAqIDEuICdoZWxsbycgbWF0Y2hlcyAnaGVsbG8nLCBub3QgJ2hlbGxvIHdvcmxkJ1xuICAgICAqIDIuICcvaGVsbG8vJyBtYXRjaGVzICdoZWxsbyB3b3JsZCcsIGJ1dCBub3QgJ0hlbGxvIHdvcmxkJ1xuICAgICAqIDMuICcvaGVsbG8vaScgbWF0Y2hlcyAnSSBzYXkgSGVsbG8nXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIENhdGVnb3JpYWxSdWxlXG4gICAgICovXG4gICAgZXhwcmVzc2lvbjogWydzdHJpbmcnLCB0cnVlLCAnTWlzc2luZyddLFxuXG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIGl0ZW1zIHRoaXMgdHJhbnNmb3JtIGlzIHVzZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ2F0ZWdvcmlhbFJ1bGVcbiAgICAgKi9cbiAgICBjb3VudDogWydudW1iZXInLCB0cnVlLCAwXSxcblxuICAgIC8qKlxuICAgICAqIE5hbWUgb2YgdGhlIGdyb3VwIHRoaXMgaXMgbWFwcGVkIHRvLiBUaGUgc3BlY2lhbCBzdWJzdHJpbmcgJDEgaXMgcmVwbGFjZWQgYnkgdGhlIGZpcnN0IGNhcHR1cmVkIGdyb3VwLFxuICAgICAqIGluIGV4YW1wbGUgNCBhYm92ZSwgd2l0aCBncm91cCBzZXQgdG8gJ0hlIHNheXMgJDEnLCB0aGUgbWF0Y2ggcmVzdWx0cyBpbiAnSGUgc2F5cyBnb29kYnllJ1xuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQG1lbWJlcm9mISBDYXRlZ29yaWFsUnVsZVxuICAgICAqL1xuICAgIGdyb3VwOiBbJ3N0cmluZycsIHRydWUsICdNaXNzaW5nJ11cbiAgfSxcbiAgZGVyaXZlZDoge1xuXG4gICAgLyoqXG4gICAgICogTWF0Y2ggZnVuY3Rpb25cbiAgICAgKiBAbWVtYmVyb2YhIENhdGVnb3JpYWxSdWxlXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgVGhlIHRleHQgdG8gbWF0Y2hcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfGZhbHNlfSBncm91cCBUaGUgZ3JvdXAgbGFiZWwgaWYgbWF0Y2hpbmcsIGVsc2UgZmFsc2VcbiAgICAgKi9cbiAgICBtYXRjaDoge1xuICAgICAgZGVwczogWydleHByZXNzaW9uJywgJ2dyb3VwJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHJlRm9ybWF0ID0gbmV3IFJlZ0V4cCgvXlxcLyguKilcXC8oW2dpbXV5XSopJC8pO1xuICAgICAgICB2YXIgbWF0Y2ggPSByZUZvcm1hdC5leGVjKHRoYXQuZXhwcmVzc2lvbik7XG5cbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgLy8gaWYgdGhlIGV4cHJlc3Npb24gaXMgaW4gdGhlIGZvcm0gb2YgLzx0ZXh0Pi88ZmxhZ3M+LCBpdCBpcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiwgY29tcGlsZSBpdFxuICAgICAgICAgIHZhciBleHAgPSBSZWdFeHAobWF0Y2hbMV0sIG1hdGNoWzJdKTtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHRleHQpIHtcbiAgICAgICAgICAgIHZhciBtID0gZXhwLmV4ZWModGV4dCk7XG4gICAgICAgICAgICBpZiAobSkge1xuICAgICAgICAgICAgICByZXR1cm4gdGhhdC5ncm91cDtcbiAgICAgICAgICAgICAgLy8gcmV0dXJuIHRoYXQuZ3JvdXAucmVwbGFjZSgnJDEnLCBtWzFdKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG90aGVyd2lzZSBkbyBtYXRjaGluZyB1c2luZyAnPT09J1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICAgICAgaWYgKHRleHQgPT09IHRoYXQuZXhwcmVzc2lvbikge1xuICAgICAgICAgICAgICByZXR1cm4gdGhhdC5ncm91cDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///ba23\n")},bb16:function(module,exports,__webpack_require__){eval("\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = debug;\nexports.coerce = coerce;\nexports.disable = disable;\nexports.enable = enable;\nexports.enabled = enabled;\nexports.humanize = __webpack_require__(/*! ms */ \"1ed2\");\n\n/**\n * The currently active debug mode names, and names to skip.\n */\n\nexports.names = [];\nexports.skips = [];\n\n/**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lowercased letter, i.e. \"n\".\n */\n\nexports.formatters = {};\n\n/**\n * Previously assigned color.\n */\n\nvar prevColor = 0;\n\n/**\n * Previous log timestamp.\n */\n\nvar prevTime;\n\n/**\n * Select a color.\n *\n * @return {Number}\n * @api private\n */\n\nfunction selectColor() {\n  return exports.colors[prevColor++ % exports.colors.length];\n}\n\n/**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\nfunction debug(namespace) {\n\n  // define the `disabled` version\n  function disabled() {\n  }\n  disabled.enabled = false;\n\n  // define the `enabled` version\n  function enabled() {\n\n    var self = enabled;\n\n    // set `diff` timestamp\n    var curr = +new Date();\n    var ms = curr - (prevTime || curr);\n    self.diff = ms;\n    self.prev = prevTime;\n    self.curr = curr;\n    prevTime = curr;\n\n    // add the `color` if not set\n    if (null == self.useColors) self.useColors = exports.useColors();\n    if (null == self.color && self.useColors) self.color = selectColor();\n\n    var args = Array.prototype.slice.call(arguments);\n\n    args[0] = exports.coerce(args[0]);\n\n    if ('string' !== typeof args[0]) {\n      // anything else let's inspect with %o\n      args = ['%o'].concat(args);\n    }\n\n    // apply any `formatters` transformations\n    var index = 0;\n    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {\n      // if we encounter an escaped % then don't increase the array index\n      if (match === '%%') return match;\n      index++;\n      var formatter = exports.formatters[format];\n      if ('function' === typeof formatter) {\n        var val = args[index];\n        match = formatter.call(self, val);\n\n        // now we need to remove `args[index]` since it's inlined in the `format`\n        args.splice(index, 1);\n        index--;\n      }\n      return match;\n    });\n\n    if ('function' === typeof exports.formatArgs) {\n      args = exports.formatArgs.apply(self, args);\n    }\n    var logFn = enabled.log || exports.log || console.log.bind(console);\n    logFn.apply(self, args);\n  }\n  enabled.enabled = true;\n\n  var fn = exports.enabled(namespace) ? enabled : disabled;\n\n  fn.namespace = namespace;\n\n  return fn;\n}\n\n/**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\nfunction enable(namespaces) {\n  exports.save(namespaces);\n\n  var split = (namespaces || '').split(/[\\s,]+/);\n  var len = split.length;\n\n  for (var i = 0; i < len; i++) {\n    if (!split[i]) continue; // ignore empty strings\n    namespaces = split[i].replace(/\\*/g, '.*?');\n    if (namespaces[0] === '-') {\n      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n    } else {\n      exports.names.push(new RegExp('^' + namespaces + '$'));\n    }\n  }\n}\n\n/**\n * Disable debug output.\n *\n * @api public\n */\n\nfunction disable() {\n  exports.enable('');\n}\n\n/**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\nfunction enabled(name) {\n  var i, len;\n  for (i = 0, len = exports.skips.length; i < len; i++) {\n    if (exports.skips[i].test(name)) {\n      return false;\n    }\n  }\n  for (i = 0, len = exports.names.length; i < len; i++) {\n    if (exports.names[i].test(name)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\nfunction coerce(val) {\n  if (val instanceof Error) return val.stack || val.message;\n  return val;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmIxNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvZGVidWcvZGVidWcuanM/NTJhNyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogVGhpcyBpcyB0aGUgY29tbW9uIGxvZ2ljIGZvciBib3RoIHRoZSBOb2RlLmpzIGFuZCB3ZWIgYnJvd3NlclxuICogaW1wbGVtZW50YXRpb25zIG9mIGBkZWJ1ZygpYC5cbiAqXG4gKiBFeHBvc2UgYGRlYnVnKClgIGFzIHRoZSBtb2R1bGUuXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZGVidWc7XG5leHBvcnRzLmNvZXJjZSA9IGNvZXJjZTtcbmV4cG9ydHMuZGlzYWJsZSA9IGRpc2FibGU7XG5leHBvcnRzLmVuYWJsZSA9IGVuYWJsZTtcbmV4cG9ydHMuZW5hYmxlZCA9IGVuYWJsZWQ7XG5leHBvcnRzLmh1bWFuaXplID0gcmVxdWlyZSgnbXMnKTtcblxuLyoqXG4gKiBUaGUgY3VycmVudGx5IGFjdGl2ZSBkZWJ1ZyBtb2RlIG5hbWVzLCBhbmQgbmFtZXMgdG8gc2tpcC5cbiAqL1xuXG5leHBvcnRzLm5hbWVzID0gW107XG5leHBvcnRzLnNraXBzID0gW107XG5cbi8qKlxuICogTWFwIG9mIHNwZWNpYWwgXCIlblwiIGhhbmRsaW5nIGZ1bmN0aW9ucywgZm9yIHRoZSBkZWJ1ZyBcImZvcm1hdFwiIGFyZ3VtZW50LlxuICpcbiAqIFZhbGlkIGtleSBuYW1lcyBhcmUgYSBzaW5nbGUsIGxvd2VyY2FzZWQgbGV0dGVyLCBpLmUuIFwiblwiLlxuICovXG5cbmV4cG9ydHMuZm9ybWF0dGVycyA9IHt9O1xuXG4vKipcbiAqIFByZXZpb3VzbHkgYXNzaWduZWQgY29sb3IuXG4gKi9cblxudmFyIHByZXZDb2xvciA9IDA7XG5cbi8qKlxuICogUHJldmlvdXMgbG9nIHRpbWVzdGFtcC5cbiAqL1xuXG52YXIgcHJldlRpbWU7XG5cbi8qKlxuICogU2VsZWN0IGEgY29sb3IuXG4gKlxuICogQHJldHVybiB7TnVtYmVyfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2VsZWN0Q29sb3IoKSB7XG4gIHJldHVybiBleHBvcnRzLmNvbG9yc1twcmV2Q29sb3IrKyAlIGV4cG9ydHMuY29sb3JzLmxlbmd0aF07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgZGVidWdnZXIgd2l0aCB0aGUgZ2l2ZW4gYG5hbWVzcGFjZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlYnVnKG5hbWVzcGFjZSkge1xuXG4gIC8vIGRlZmluZSB0aGUgYGRpc2FibGVkYCB2ZXJzaW9uXG4gIGZ1bmN0aW9uIGRpc2FibGVkKCkge1xuICB9XG4gIGRpc2FibGVkLmVuYWJsZWQgPSBmYWxzZTtcblxuICAvLyBkZWZpbmUgdGhlIGBlbmFibGVkYCB2ZXJzaW9uXG4gIGZ1bmN0aW9uIGVuYWJsZWQoKSB7XG5cbiAgICB2YXIgc2VsZiA9IGVuYWJsZWQ7XG5cbiAgICAvLyBzZXQgYGRpZmZgIHRpbWVzdGFtcFxuICAgIHZhciBjdXJyID0gK25ldyBEYXRlKCk7XG4gICAgdmFyIG1zID0gY3VyciAtIChwcmV2VGltZSB8fCBjdXJyKTtcbiAgICBzZWxmLmRpZmYgPSBtcztcbiAgICBzZWxmLnByZXYgPSBwcmV2VGltZTtcbiAgICBzZWxmLmN1cnIgPSBjdXJyO1xuICAgIHByZXZUaW1lID0gY3VycjtcblxuICAgIC8vIGFkZCB0aGUgYGNvbG9yYCBpZiBub3Qgc2V0XG4gICAgaWYgKG51bGwgPT0gc2VsZi51c2VDb2xvcnMpIHNlbGYudXNlQ29sb3JzID0gZXhwb3J0cy51c2VDb2xvcnMoKTtcbiAgICBpZiAobnVsbCA9PSBzZWxmLmNvbG9yICYmIHNlbGYudXNlQ29sb3JzKSBzZWxmLmNvbG9yID0gc2VsZWN0Q29sb3IoKTtcblxuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgIGFyZ3NbMF0gPSBleHBvcnRzLmNvZXJjZShhcmdzWzBdKTtcblxuICAgIGlmICgnc3RyaW5nJyAhPT0gdHlwZW9mIGFyZ3NbMF0pIHtcbiAgICAgIC8vIGFueXRoaW5nIGVsc2UgbGV0J3MgaW5zcGVjdCB3aXRoICVvXG4gICAgICBhcmdzID0gWyclbyddLmNvbmNhdChhcmdzKTtcbiAgICB9XG5cbiAgICAvLyBhcHBseSBhbnkgYGZvcm1hdHRlcnNgIHRyYW5zZm9ybWF0aW9uc1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgYXJnc1swXSA9IGFyZ3NbMF0ucmVwbGFjZSgvJShbYS16JV0pL2csIGZ1bmN0aW9uKG1hdGNoLCBmb3JtYXQpIHtcbiAgICAgIC8vIGlmIHdlIGVuY291bnRlciBhbiBlc2NhcGVkICUgdGhlbiBkb24ndCBpbmNyZWFzZSB0aGUgYXJyYXkgaW5kZXhcbiAgICAgIGlmIChtYXRjaCA9PT0gJyUlJykgcmV0dXJuIG1hdGNoO1xuICAgICAgaW5kZXgrKztcbiAgICAgIHZhciBmb3JtYXR0ZXIgPSBleHBvcnRzLmZvcm1hdHRlcnNbZm9ybWF0XTtcbiAgICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgZm9ybWF0dGVyKSB7XG4gICAgICAgIHZhciB2YWwgPSBhcmdzW2luZGV4XTtcbiAgICAgICAgbWF0Y2ggPSBmb3JtYXR0ZXIuY2FsbChzZWxmLCB2YWwpO1xuXG4gICAgICAgIC8vIG5vdyB3ZSBuZWVkIHRvIHJlbW92ZSBgYXJnc1tpbmRleF1gIHNpbmNlIGl0J3MgaW5saW5lZCBpbiB0aGUgYGZvcm1hdGBcbiAgICAgICAgYXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBpbmRleC0tO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH0pO1xuXG4gICAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBleHBvcnRzLmZvcm1hdEFyZ3MpIHtcbiAgICAgIGFyZ3MgPSBleHBvcnRzLmZvcm1hdEFyZ3MuYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgfVxuICAgIHZhciBsb2dGbiA9IGVuYWJsZWQubG9nIHx8IGV4cG9ydHMubG9nIHx8IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSk7XG4gICAgbG9nRm4uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbiAgZW5hYmxlZC5lbmFibGVkID0gdHJ1ZTtcblxuICB2YXIgZm4gPSBleHBvcnRzLmVuYWJsZWQobmFtZXNwYWNlKSA/IGVuYWJsZWQgOiBkaXNhYmxlZDtcblxuICBmbi5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7XG5cbiAgcmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgYSBkZWJ1ZyBtb2RlIGJ5IG5hbWVzcGFjZXMuIFRoaXMgY2FuIGluY2x1ZGUgbW9kZXNcbiAqIHNlcGFyYXRlZCBieSBhIGNvbG9uIGFuZCB3aWxkY2FyZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZW5hYmxlKG5hbWVzcGFjZXMpIHtcbiAgZXhwb3J0cy5zYXZlKG5hbWVzcGFjZXMpO1xuXG4gIHZhciBzcGxpdCA9IChuYW1lc3BhY2VzIHx8ICcnKS5zcGxpdCgvW1xccyxdKy8pO1xuICB2YXIgbGVuID0gc3BsaXQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoIXNwbGl0W2ldKSBjb250aW51ZTsgLy8gaWdub3JlIGVtcHR5IHN0cmluZ3NcbiAgICBuYW1lc3BhY2VzID0gc3BsaXRbaV0ucmVwbGFjZSgvXFwqL2csICcuKj8nKTtcbiAgICBpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG4gICAgICBleHBvcnRzLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzLnN1YnN0cigxKSArICckJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzICsgJyQnKSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGlzYWJsZSBkZWJ1ZyBvdXRwdXQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkaXNhYmxlKCkge1xuICBleHBvcnRzLmVuYWJsZSgnJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RlIG5hbWUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGVkKG5hbWUpIHtcbiAgdmFyIGksIGxlbjtcbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLnNraXBzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5uYW1lcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLm5hbWVzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29lcmNlIGB2YWxgLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjb2VyY2UodmFsKSB7XG4gIGlmICh2YWwgaW5zdGFuY2VvZiBFcnJvcikgcmV0dXJuIHZhbC5zdGFjayB8fCB2YWwubWVzc2FnZTtcbiAgcmV0dXJuIHZhbDtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///bb16\n")},bff6:function(module,exports){eval("/**\n * This module defines a single unique missing value indicator.\n * All invalid, absent, or user-indicated missing value is internally set to this value.\n *\n * @example\n * var misval = require('./framework/misval');\n * if ( a === misval ) {\n *   ...\n * }\n * @module client/misval\n */\n\n// module.exports = -Number.MAX_VALUE;\nmodule.exports = 'missing';\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmZmNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9taXN2YWwuanM/YjI3OSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoaXMgbW9kdWxlIGRlZmluZXMgYSBzaW5nbGUgdW5pcXVlIG1pc3NpbmcgdmFsdWUgaW5kaWNhdG9yLlxuICogQWxsIGludmFsaWQsIGFic2VudCwgb3IgdXNlci1pbmRpY2F0ZWQgbWlzc2luZyB2YWx1ZSBpcyBpbnRlcm5hbGx5IHNldCB0byB0aGlzIHZhbHVlLlxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbWlzdmFsID0gcmVxdWlyZSgnLi9mcmFtZXdvcmsvbWlzdmFsJyk7XG4gKiBpZiAoIGEgPT09IG1pc3ZhbCApIHtcbiAqICAgLi4uXG4gKiB9XG4gKiBAbW9kdWxlIGNsaWVudC9taXN2YWxcbiAqL1xuXG4vLyBtb2R1bGUuZXhwb3J0cyA9IC1OdW1iZXIuTUFYX1ZBTFVFO1xubW9kdWxlLmV4cG9ydHMgPSAnbWlzc2luZyc7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///bff6\n")},c59b:function(module,exports,__webpack_require__){eval('\nmodule.exports = __webpack_require__(/*! ./lib/index */ "58ab");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYzU5Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9pbmRleC5qcz80NmEyIl0sInNvdXJjZXNDb250ZW50IjpbIlxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9pbmRleCcpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///c59b\n')},d45b:function(module,exports,__webpack_require__){eval("var AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar AmpersandColllection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\n/*\n * Time is grouped by truncating; the resolution is determined in util-time.getResolution()\n * See [this table](http://momentjs.com/docs/#/durations/creating/) for accpetable values\n * when using a crossfilter dataset.\n */\nfunction unitsForMilliseconds (milliseconds) {\n  var count = milliseconds;\n  if (count < 10000) { // 10 seconds\n    return 'milliseconds';\n  }\n  count = count / 1000;\n\n  if (count < 15 * 60) { // 15 minutes\n    return 'seconds';\n  }\n  count = count / 60;\n\n  if (count < 3 * 60) { // 3 hours\n    return 'minutes';\n  }\n  count = count / 60;\n\n  if (count < 3 * 24) { // 3 days\n    return 'hours';\n  }\n  count = count / 24;\n\n  if (count < 3 * 7) { // 3 weeks\n    return 'days';\n  }\n  if (count < 7 * 52) { // 52 weeks\n    return 'weeks';\n  }\n  if (count < 2 * 365) { // 2 years\n    return 'months';\n  }\n  return 'years';\n}\n\nfunction getFormat (units) {\n  var fmt;\n  if (units === 'seconds') {\n    fmt = 'mm:ss';\n  } else if (units === 'minutes') {\n    fmt = 'HH:mm';\n  } else if (units === 'hours') {\n    fmt = 'HH:00';\n  } else if (units === 'days') {\n    fmt = 'dddd do';\n  } else if (units === 'weeks') {\n    fmt = 'wo';\n  } else if (units === 'months') {\n    fmt = 'YY MMM';\n  } else if (units === 'years') {\n    fmt = 'YYYY';\n  }\n  return fmt;\n}\n\nfunction getDatetimeResolution (start, end) {\n  var difference = end.diff(start);\n  return unitsForMilliseconds(difference);\n}\n\nfunction getDurationResolution (min, max) {\n  var length = moment.duration(max.as('milliseconds') - min.as('milliseconds'), 'milliseconds');\n  return unitsForMilliseconds(length);\n}\n\nvar TimePart = AmpersandModel.extend({\n  props: {\n    /**\n     * The format string for momentjs\n     * @memberof! TimePart\n     * @type {string}\n     */\n    momentFormat: ['string', true],\n    /**\n     * The format string for postgresql\n     * @memberof! TimePart\n     * @type {string}\n     */\n    postgresFormat: ['string', true],\n    /**\n     * The human readable descprition of the datetime part\n     * @memberof! TimePart\n     * @type {string}\n     */\n    description: ['string', true],\n    /**\n     * Data type after conversion: 'continuous', or 'categorial'\n     * @memberof! TimePart\n     * @type {string}\n     */\n    type: ['string', true],\n    /**\n     * For continuous datetime parts (ie, day-of-year), the minimum value\n     * @memberof! TimePart\n     * @type {number}\n     */\n    min: ['number', true, 0],\n    /**\n     * For continuous datetime parts (ie, day-of-year), the maximum value\n     * @memberof! TimePart\n     * @type {number}\n     */\n    max: ['number', true, 1],\n    /**\n     * When true, calculate the minimum and maximum value from the\n     * original datetime limits. Used for continuous datetime parts (ie, year)\n     * @memberof! TimePart\n     * @type {boolean}\n     */\n    calculate: ['boolean', true, false],\n    /**\n     * For categorial datetime parts (Mon, Tue, ..), the array of possible values\n     * @memberof! TimePart\n     * @type {String[]}\n     */\n    groups: ['array']\n  }\n});\n\nvar TimeParts = AmpersandColllection.extend({\n  model: TimePart,\n  indexes: ['description']\n});\n\nvar timeParts = new TimeParts([\n  { description: 'ISO8601', type: 'datetime', calculate: true },\n  { postgresFormat: 'month', momentFormat: 'M', description: 'Month (1-12)', type: 'continuous', min: 1, max: 12 },\n  { postgresFormat: 'quarter', momentFormat: 'Q', description: 'Quarter (1-4)', type: 'continuous', min: 1, max: 4 },\n  { postgresFormat: 'day', momentFormat: 'D', description: 'Day of Month  (1-31)', type: 'continuous', min: 1, max: 31 },\n  { postgresFormat: 'doy', momentFormat: 'DDD', description: 'Day of Year (1-365)', type: 'continuous', min: 1, max: 365 },\n  { postgresFormat: 'dow', momentFormat: 'd', description: 'Day of Week (0-6)', type: 'continuous', min: 0, max: 6 },\n  { postgresFormat: 'isodow', momentFormat: 'E', description: 'Day of Week ISO (1-7)', type: 'continuous', min: 1, max: 7 },\n  { postgresFormat: 'week', momentFormat: 'W', description: 'Week of Year ISO  (1-53)', type: 'continuous', min: 1, max: 53 },\n  { postgresFormat: 'year', momentFormat: 'Y', description: 'Year', type: 'continuous', calculate: true },\n  { postgresFormat: 'hours', momentFormat: 'H', description: 'Hour (0-23)', type: 'continuous', min: 0, max: 23 },\n  { postgresFormat: 'minute', momentFormat: 'm', description: 'Minute (0-59)', type: 'continuous', min: 0, max: 59 },\n  { postgresFormat: 'second', momentFormat: 's', description: 'Second (0-59)', type: 'continuous', min: 0, max: 59 },\n  { postgresFormat: 'milliseconds', momentFormat: 'SSS', description: 'Milliseconds (0-999)', type: 'continuous', min: 0, max: 999 },\n  { postgresFormat: 'microseconds', momentFormat: 'SSSSSS', description: 'microseconds (0-999999)', type: 'continuous', min: 0, max: 999999 },\n  { postgresFormat: 'epoch', momentFormat: 'X', description: 'Unix Timestamp', type: 'continuous', calculate: true },\n  { postgresFormat: 'Mon', momentFormat: 'MMM', description: 'Month (Jan - Dec)', type: 'categorial', groups: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] },\n  { postgresFormat: 'Month', momentFormat: 'MMMM', description: 'Month (January - December)', type: 'categorial', groups: ['January', 'Feburary', 'March', 'April', 'May', 'June', 'July', 'August', 'Septebmer', 'October', 'November', 'December'] },\n  { postgresFormat: 'Dy', momentFormat: 'ddd', description: 'Day of Week (Sun-Sat)', type: 'categorial', groups: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] },\n  { postgresFormat: 'Day', momentFormat: 'dddd', description: 'Day of Week (Sunday-Saturday)', type: 'categorial', groups: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] },\n  { postgresFormat: 'AM', momentFormat: 'A', description: 'AM/PM', type: 'categorial', groups: ['AM', 'PM'] }\n]);\n\nvar DurationUnit = AmpersandModel.extend({\n  props: {\n    /**\n     * The descriptive name of the time unit\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    description: ['string'],\n    /**\n     * Momentjs parsing format\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    momentFormat: ['string'],\n    /**\n     * Postgres parsing format\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    postgresFormat: ['string'],\n    /**\n     * Conversion factor to seconds\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    seconds: ['number']\n  }\n});\n\nvar DurationUnits = AmpersandColllection.extend({\n  indexes: ['description'],\n  model: DurationUnit\n});\n\nvar durationUnits = new DurationUnits([\n  {\n    description: 'ISO8601',\n    seconds: 1\n  }, {\n    description: 'millenium',\n    momentFormat: 'millenium',\n    postgresFormat: 'millenium',\n    seconds: 100 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'century',\n    momentFormat: 'century',\n    postgresFormat: 'century',\n    seconds: 100 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'decades',\n    momentFormat: 'decades',\n    postgresFormat: 'decade',\n    seconds: 10 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'years',\n    momentFormat: 'years',\n    postgresFormat: 'year',\n    seconds: 365.25 * 24 * 60 * 60\n  }, {\n    description: 'quarters',\n    momentFormat: '',\n    postgresFormat: 'quarter',\n    seconds: 365.25 * 8 * 60 * 60\n  }, {\n    description: 'months',\n    momentFormat: 'months',\n    postgresFormat: 'month',\n    seconds: 30 * 24 * 60 * 60\n  }, {\n    description: 'weeks',\n    momentFormat: 'weeks',\n    postgresFormat: 'week',\n    seconds: 7 * 24 * 60 * 60\n  }, {\n    description: 'days',\n    momentFormat: 'days',\n    postgresFormat: 'day',\n    seconds: 24 * 60 * 60\n  }, {\n    description: 'hours',\n    momentFormat: 'hours',\n    postgresFormat: 'hour',\n    seconds: 60 * 60\n  }, {\n    description: 'minutes',\n    momentFormat: 'minutes',\n    postgresFormat: 'minute',\n    seconds: 60\n  }, {\n    description: 'seconds',\n    momentFormat: 'seconds',\n    postgresFormat: 'second',\n    seconds: 1\n  }, {\n    description: 'milliseconds',\n    momentFormat: 'milliseconds',\n    postgresFormat: 'milliseconds',\n    seconds: 0.001\n  }, {\n    description: 'microseconds',\n    momentFormat: 'microseconds',\n    postgresFormat: 'microseconds',\n    seconds: 0.000001\n  }\n]);\n\nvar TimeZone = AmpersandModel.extend({\n  props: {\n    /**\n     * The descriptive name of the time zone\n     * @memberof! TimeZone\n     * @type {string}\n     */\n    description: ['string'],\n    /**\n     * The time zone format\n     * @memberof! TimeZone\n     * @type {string}\n     */\n    format: ['string']\n  }\n});\n\nvar TimeZones = AmpersandColllection.extend({\n  indexes: ['description'],\n  model: TimeZone\n});\n\nvar timeZones = new TimeZones();\ntimeZones.add({\n  description: 'ISO8601',\n  format: 'ISO8601'\n});\n\nmoment.tz.names().forEach(function (tz) {\n  timeZones.add({\n    description: tz,\n    format: tz\n  });\n});\n\nmodule.exports = {\n  timeParts: timeParts,\n  timeZones: timeZones,\n  durationUnits: durationUnits,\n  getDatetimeResolution: getDatetimeResolution,\n  getDurationResolution: getDurationResolution,\n  getFormat: getFormat\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZDQ1Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC90aW1lLmpzP2ExMzkiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIEFtcGVyc2FuZE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG52YXIgQW1wZXJzYW5kQ29sbGxlY3Rpb24gPSByZXF1aXJlKCdhbXBlcnNhbmQtY29sbGVjdGlvbicpO1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xuXG4vKlxuICogVGltZSBpcyBncm91cGVkIGJ5IHRydW5jYXRpbmc7IHRoZSByZXNvbHV0aW9uIGlzIGRldGVybWluZWQgaW4gdXRpbC10aW1lLmdldFJlc29sdXRpb24oKVxuICogU2VlIFt0aGlzIHRhYmxlXShodHRwOi8vbW9tZW50anMuY29tL2RvY3MvIy9kdXJhdGlvbnMvY3JlYXRpbmcvKSBmb3IgYWNjcGV0YWJsZSB2YWx1ZXNcbiAqIHdoZW4gdXNpbmcgYSBjcm9zc2ZpbHRlciBkYXRhc2V0LlxuICovXG5mdW5jdGlvbiB1bml0c0Zvck1pbGxpc2Vjb25kcyAobWlsbGlzZWNvbmRzKSB7XG4gIHZhciBjb3VudCA9IG1pbGxpc2Vjb25kcztcbiAgaWYgKGNvdW50IDwgMTAwMDApIHsgLy8gMTAgc2Vjb25kc1xuICAgIHJldHVybiAnbWlsbGlzZWNvbmRzJztcbiAgfVxuICBjb3VudCA9IGNvdW50IC8gMTAwMDtcblxuICBpZiAoY291bnQgPCAxNSAqIDYwKSB7IC8vIDE1IG1pbnV0ZXNcbiAgICByZXR1cm4gJ3NlY29uZHMnO1xuICB9XG4gIGNvdW50ID0gY291bnQgLyA2MDtcblxuICBpZiAoY291bnQgPCAzICogNjApIHsgLy8gMyBob3Vyc1xuICAgIHJldHVybiAnbWludXRlcyc7XG4gIH1cbiAgY291bnQgPSBjb3VudCAvIDYwO1xuXG4gIGlmIChjb3VudCA8IDMgKiAyNCkgeyAvLyAzIGRheXNcbiAgICByZXR1cm4gJ2hvdXJzJztcbiAgfVxuICBjb3VudCA9IGNvdW50IC8gMjQ7XG5cbiAgaWYgKGNvdW50IDwgMyAqIDcpIHsgLy8gMyB3ZWVrc1xuICAgIHJldHVybiAnZGF5cyc7XG4gIH1cbiAgaWYgKGNvdW50IDwgNyAqIDUyKSB7IC8vIDUyIHdlZWtzXG4gICAgcmV0dXJuICd3ZWVrcyc7XG4gIH1cbiAgaWYgKGNvdW50IDwgMiAqIDM2NSkgeyAvLyAyIHllYXJzXG4gICAgcmV0dXJuICdtb250aHMnO1xuICB9XG4gIHJldHVybiAneWVhcnMnO1xufVxuXG5mdW5jdGlvbiBnZXRGb3JtYXQgKHVuaXRzKSB7XG4gIHZhciBmbXQ7XG4gIGlmICh1bml0cyA9PT0gJ3NlY29uZHMnKSB7XG4gICAgZm10ID0gJ21tOnNzJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ21pbnV0ZXMnKSB7XG4gICAgZm10ID0gJ0hIOm1tJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ2hvdXJzJykge1xuICAgIGZtdCA9ICdISDowMCc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICdkYXlzJykge1xuICAgIGZtdCA9ICdkZGRkIGRvJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ3dlZWtzJykge1xuICAgIGZtdCA9ICd3byc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICdtb250aHMnKSB7XG4gICAgZm10ID0gJ1lZIE1NTSc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICd5ZWFycycpIHtcbiAgICBmbXQgPSAnWVlZWSc7XG4gIH1cbiAgcmV0dXJuIGZtdDtcbn1cblxuZnVuY3Rpb24gZ2V0RGF0ZXRpbWVSZXNvbHV0aW9uIChzdGFydCwgZW5kKSB7XG4gIHZhciBkaWZmZXJlbmNlID0gZW5kLmRpZmYoc3RhcnQpO1xuICByZXR1cm4gdW5pdHNGb3JNaWxsaXNlY29uZHMoZGlmZmVyZW5jZSk7XG59XG5cbmZ1bmN0aW9uIGdldER1cmF0aW9uUmVzb2x1dGlvbiAobWluLCBtYXgpIHtcbiAgdmFyIGxlbmd0aCA9IG1vbWVudC5kdXJhdGlvbihtYXguYXMoJ21pbGxpc2Vjb25kcycpIC0gbWluLmFzKCdtaWxsaXNlY29uZHMnKSwgJ21pbGxpc2Vjb25kcycpO1xuICByZXR1cm4gdW5pdHNGb3JNaWxsaXNlY29uZHMobGVuZ3RoKTtcbn1cblxudmFyIFRpbWVQYXJ0ID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBUaGUgZm9ybWF0IHN0cmluZyBmb3IgbW9tZW50anNcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBtb21lbnRGb3JtYXQ6IFsnc3RyaW5nJywgdHJ1ZV0sXG4gICAgLyoqXG4gICAgICogVGhlIGZvcm1hdCBzdHJpbmcgZm9yIHBvc3RncmVzcWxcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBwb3N0Z3Jlc0Zvcm1hdDogWydzdHJpbmcnLCB0cnVlXSxcbiAgICAvKipcbiAgICAgKiBUaGUgaHVtYW4gcmVhZGFibGUgZGVzY3ByaXRpb24gb2YgdGhlIGRhdGV0aW1lIHBhcnRcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBkZXNjcmlwdGlvbjogWydzdHJpbmcnLCB0cnVlXSxcbiAgICAvKipcbiAgICAgKiBEYXRhIHR5cGUgYWZ0ZXIgY29udmVyc2lvbjogJ2NvbnRpbnVvdXMnLCBvciAnY2F0ZWdvcmlhbCdcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0eXBlOiBbJ3N0cmluZycsIHRydWVdLFxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIGRhdGV0aW1lIHBhcnRzIChpZSwgZGF5LW9mLXllYXIpLCB0aGUgbWluaW11bSB2YWx1ZVxuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIG1pbjogWydudW1iZXInLCB0cnVlLCAwXSxcbiAgICAvKipcbiAgICAgKiBGb3IgY29udGludW91cyBkYXRldGltZSBwYXJ0cyAoaWUsIGRheS1vZi15ZWFyKSwgdGhlIG1heGltdW0gdmFsdWVcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBtYXg6IFsnbnVtYmVyJywgdHJ1ZSwgMV0sXG4gICAgLyoqXG4gICAgICogV2hlbiB0cnVlLCBjYWxjdWxhdGUgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gdmFsdWUgZnJvbSB0aGVcbiAgICAgKiBvcmlnaW5hbCBkYXRldGltZSBsaW1pdHMuIFVzZWQgZm9yIGNvbnRpbnVvdXMgZGF0ZXRpbWUgcGFydHMgKGllLCB5ZWFyKVxuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBjYWxjdWxhdGU6IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXSxcbiAgICAvKipcbiAgICAgKiBGb3IgY2F0ZWdvcmlhbCBkYXRldGltZSBwYXJ0cyAoTW9uLCBUdWUsIC4uKSwgdGhlIGFycmF5IG9mIHBvc3NpYmxlIHZhbHVlc1xuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7U3RyaW5nW119XG4gICAgICovXG4gICAgZ3JvdXBzOiBbJ2FycmF5J11cbiAgfVxufSk7XG5cbnZhciBUaW1lUGFydHMgPSBBbXBlcnNhbmRDb2xsbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogVGltZVBhcnQsXG4gIGluZGV4ZXM6IFsnZGVzY3JpcHRpb24nXVxufSk7XG5cbnZhciB0aW1lUGFydHMgPSBuZXcgVGltZVBhcnRzKFtcbiAgeyBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLCB0eXBlOiAnZGF0ZXRpbWUnLCBjYWxjdWxhdGU6IHRydWUgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ21vbnRoJywgbW9tZW50Rm9ybWF0OiAnTScsIGRlc2NyaXB0aW9uOiAnTW9udGggKDEtMTIpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogMTIgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3F1YXJ0ZXInLCBtb21lbnRGb3JtYXQ6ICdRJywgZGVzY3JpcHRpb246ICdRdWFydGVyICgxLTQpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogNCB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZGF5JywgbW9tZW50Rm9ybWF0OiAnRCcsIGRlc2NyaXB0aW9uOiAnRGF5IG9mIE1vbnRoICAoMS0zMSknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMSwgbWF4OiAzMSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZG95JywgbW9tZW50Rm9ybWF0OiAnREREJywgZGVzY3JpcHRpb246ICdEYXkgb2YgWWVhciAoMS0zNjUpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogMzY1IH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdkb3cnLCBtb21lbnRGb3JtYXQ6ICdkJywgZGVzY3JpcHRpb246ICdEYXkgb2YgV2VlayAoMC02KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDYgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ2lzb2RvdycsIG1vbWVudEZvcm1hdDogJ0UnLCBkZXNjcmlwdGlvbjogJ0RheSBvZiBXZWVrIElTTyAoMS03KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAxLCBtYXg6IDcgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3dlZWsnLCBtb21lbnRGb3JtYXQ6ICdXJywgZGVzY3JpcHRpb246ICdXZWVrIG9mIFllYXIgSVNPICAoMS01MyknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMSwgbWF4OiA1MyB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAneWVhcicsIG1vbWVudEZvcm1hdDogJ1knLCBkZXNjcmlwdGlvbjogJ1llYXInLCB0eXBlOiAnY29udGludW91cycsIGNhbGN1bGF0ZTogdHJ1ZSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnaG91cnMnLCBtb21lbnRGb3JtYXQ6ICdIJywgZGVzY3JpcHRpb246ICdIb3VyICgwLTIzKScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDIzIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdtaW51dGUnLCBtb21lbnRGb3JtYXQ6ICdtJywgZGVzY3JpcHRpb246ICdNaW51dGUgKDAtNTkpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDAsIG1heDogNTkgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3NlY29uZCcsIG1vbWVudEZvcm1hdDogJ3MnLCBkZXNjcmlwdGlvbjogJ1NlY29uZCAoMC01OSknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMCwgbWF4OiA1OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnbWlsbGlzZWNvbmRzJywgbW9tZW50Rm9ybWF0OiAnU1NTJywgZGVzY3JpcHRpb246ICdNaWxsaXNlY29uZHMgKDAtOTk5KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDk5OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnbWljcm9zZWNvbmRzJywgbW9tZW50Rm9ybWF0OiAnU1NTU1NTJywgZGVzY3JpcHRpb246ICdtaWNyb3NlY29uZHMgKDAtOTk5OTk5KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDk5OTk5OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZXBvY2gnLCBtb21lbnRGb3JtYXQ6ICdYJywgZGVzY3JpcHRpb246ICdVbml4IFRpbWVzdGFtcCcsIHR5cGU6ICdjb250aW51b3VzJywgY2FsY3VsYXRlOiB0cnVlIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdNb24nLCBtb21lbnRGb3JtYXQ6ICdNTU0nLCBkZXNjcmlwdGlvbjogJ01vbnRoIChKYW4gLSBEZWMpJywgdHlwZTogJ2NhdGVnb3JpYWwnLCBncm91cHM6IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLCAnT2N0JywgJ05vdicsICdEZWMnXSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnTW9udGgnLCBtb21lbnRGb3JtYXQ6ICdNTU1NJywgZGVzY3JpcHRpb246ICdNb250aCAoSmFudWFyeSAtIERlY2VtYmVyKScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ0phbnVhcnknLCAnRmVidXJhcnknLCAnTWFyY2gnLCAnQXByaWwnLCAnTWF5JywgJ0p1bmUnLCAnSnVseScsICdBdWd1c3QnLCAnU2VwdGVibWVyJywgJ09jdG9iZXInLCAnTm92ZW1iZXInLCAnRGVjZW1iZXInXSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnRHknLCBtb21lbnRGb3JtYXQ6ICdkZGQnLCBkZXNjcmlwdGlvbjogJ0RheSBvZiBXZWVrIChTdW4tU2F0KScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ1N1bicsICdNb24nLCAnVHVlJywgJ1dlZCcsICdUaHUnLCAnRnJpJywgJ1NhdCddIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdEYXknLCBtb21lbnRGb3JtYXQ6ICdkZGRkJywgZGVzY3JpcHRpb246ICdEYXkgb2YgV2VlayAoU3VuZGF5LVNhdHVyZGF5KScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknLCAnU3VuZGF5J10gfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ0FNJywgbW9tZW50Rm9ybWF0OiAnQScsIGRlc2NyaXB0aW9uOiAnQU0vUE0nLCB0eXBlOiAnY2F0ZWdvcmlhbCcsIGdyb3VwczogWydBTScsICdQTSddIH1cbl0pO1xuXG52YXIgRHVyYXRpb25Vbml0ID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBUaGUgZGVzY3JpcHRpdmUgbmFtZSBvZiB0aGUgdGltZSB1bml0XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRlc2NyaXB0aW9uOiBbJ3N0cmluZyddLFxuICAgIC8qKlxuICAgICAqIE1vbWVudGpzIHBhcnNpbmcgZm9ybWF0XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG1vbWVudEZvcm1hdDogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBQb3N0Z3JlcyBwYXJzaW5nIGZvcm1hdFxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25Vbml0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBwb3N0Z3Jlc0Zvcm1hdDogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBDb252ZXJzaW9uIGZhY3RvciB0byBzZWNvbmRzXG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHNlY29uZHM6IFsnbnVtYmVyJ11cbiAgfVxufSk7XG5cbnZhciBEdXJhdGlvblVuaXRzID0gQW1wZXJzYW5kQ29sbGxlY3Rpb24uZXh0ZW5kKHtcbiAgaW5kZXhlczogWydkZXNjcmlwdGlvbiddLFxuICBtb2RlbDogRHVyYXRpb25Vbml0XG59KTtcblxudmFyIGR1cmF0aW9uVW5pdHMgPSBuZXcgRHVyYXRpb25Vbml0cyhbXG4gIHtcbiAgICBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLFxuICAgIHNlY29uZHM6IDFcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnbWlsbGVuaXVtJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaWxsZW5pdW0nLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnbWlsbGVuaXVtJyxcbiAgICBzZWNvbmRzOiAxMDAgKiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnY2VudHVyeScsXG4gICAgbW9tZW50Rm9ybWF0OiAnY2VudHVyeScsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdjZW50dXJ5JyxcbiAgICBzZWNvbmRzOiAxMDAgKiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnZGVjYWRlcycsXG4gICAgbW9tZW50Rm9ybWF0OiAnZGVjYWRlcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdkZWNhZGUnLFxuICAgIHNlY29uZHM6IDEwICogMzY1LjI1ICogMjQgKiA2MCAqIDYwXG4gIH0sIHtcbiAgICBkZXNjcmlwdGlvbjogJ3llYXJzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICd5ZWFycycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICd5ZWFyJyxcbiAgICBzZWNvbmRzOiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAncXVhcnRlcnMnLFxuICAgIG1vbWVudEZvcm1hdDogJycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdxdWFydGVyJyxcbiAgICBzZWNvbmRzOiAzNjUuMjUgKiA4ICogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtb250aHMnLFxuICAgIG1vbWVudEZvcm1hdDogJ21vbnRocycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdtb250aCcsXG4gICAgc2Vjb25kczogMzAgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnd2Vla3MnLFxuICAgIG1vbWVudEZvcm1hdDogJ3dlZWtzJyxcbiAgICBwb3N0Z3Jlc0Zvcm1hdDogJ3dlZWsnLFxuICAgIHNlY29uZHM6IDcgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnZGF5cycsXG4gICAgbW9tZW50Rm9ybWF0OiAnZGF5cycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdkYXknLFxuICAgIHNlY29uZHM6IDI0ICogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdob3VycycsXG4gICAgbW9tZW50Rm9ybWF0OiAnaG91cnMnLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnaG91cicsXG4gICAgc2Vjb25kczogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtaW51dGVzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaW51dGVzJyxcbiAgICBwb3N0Z3Jlc0Zvcm1hdDogJ21pbnV0ZScsXG4gICAgc2Vjb25kczogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnc2Vjb25kcycsXG4gICAgbW9tZW50Rm9ybWF0OiAnc2Vjb25kcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdzZWNvbmQnLFxuICAgIHNlY29uZHM6IDFcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnbWlsbGlzZWNvbmRzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaWxsaXNlY29uZHMnLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnbWlsbGlzZWNvbmRzJyxcbiAgICBzZWNvbmRzOiAwLjAwMVxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtaWNyb3NlY29uZHMnLFxuICAgIG1vbWVudEZvcm1hdDogJ21pY3Jvc2Vjb25kcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdtaWNyb3NlY29uZHMnLFxuICAgIHNlY29uZHM6IDAuMDAwMDAxXG4gIH1cbl0pO1xuXG52YXIgVGltZVpvbmUgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRoZSBkZXNjcmlwdGl2ZSBuYW1lIG9mIHRoZSB0aW1lIHpvbmVcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVab25lXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBkZXNjcmlwdGlvbjogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSB6b25lIGZvcm1hdFxuICAgICAqIEBtZW1iZXJvZiEgVGltZVpvbmVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZvcm1hdDogWydzdHJpbmcnXVxuICB9XG59KTtcblxudmFyIFRpbWVab25lcyA9IEFtcGVyc2FuZENvbGxsZWN0aW9uLmV4dGVuZCh7XG4gIGluZGV4ZXM6IFsnZGVzY3JpcHRpb24nXSxcbiAgbW9kZWw6IFRpbWVab25lXG59KTtcblxudmFyIHRpbWVab25lcyA9IG5ldyBUaW1lWm9uZXMoKTtcbnRpbWVab25lcy5hZGQoe1xuICBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLFxuICBmb3JtYXQ6ICdJU084NjAxJ1xufSk7XG5cbm1vbWVudC50ei5uYW1lcygpLmZvckVhY2goZnVuY3Rpb24gKHR6KSB7XG4gIHRpbWVab25lcy5hZGQoe1xuICAgIGRlc2NyaXB0aW9uOiB0eixcbiAgICBmb3JtYXQ6IHR6XG4gIH0pO1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB0aW1lUGFydHM6IHRpbWVQYXJ0cyxcbiAgdGltZVpvbmVzOiB0aW1lWm9uZXMsXG4gIGR1cmF0aW9uVW5pdHM6IGR1cmF0aW9uVW5pdHMsXG4gIGdldERhdGV0aW1lUmVzb2x1dGlvbjogZ2V0RGF0ZXRpbWVSZXNvbHV0aW9uLFxuICBnZXREdXJhdGlvblJlc29sdXRpb246IGdldER1cmF0aW9uUmVzb2x1dGlvbixcbiAgZ2V0Rm9ybWF0OiBnZXRGb3JtYXRcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///d45b\n")},e59a:function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Partition = __webpack_require__(/*! ../partition */ \"8191\");\n\nmodule.exports = Collection.extend({\n  model: Partition,\n  indexes: ['rank'],\n  comparator: 'rank',\n  initialize: function () {\n    this.on('add', function (newPartition) {\n      newPartition.reset();\n    });\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTU5YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2NvbGxlY3Rpb24uanM/YzRiOCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgUGFydGl0aW9uID0gcmVxdWlyZSgnLi4vcGFydGl0aW9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogUGFydGl0aW9uLFxuICBpbmRleGVzOiBbJ3JhbmsnXSxcbiAgY29tcGFyYXRvcjogJ3JhbmsnLFxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5vbignYWRkJywgZnVuY3Rpb24gKG5ld1BhcnRpdGlvbikge1xuICAgICAgbmV3UGFydGl0aW9uLnJlc2V0KCk7XG4gICAgfSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///e59a\n")},e810:function(module,exports,__webpack_require__){eval("/**\n * ContinuousTransfrom defines a transformation on continuous (nummerical) data.\n * Currently linear interpolation between a set of control points is implemented.\n *\n * @class ContinuousTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'text',\n      values: ['text']\n    },\n    transformedMin: {\n      type: 'number',\n      required: true,\n      default: 0\n    },\n    transformedMax: {\n      type: 'number',\n      required: true,\n      default: 100\n    }\n  },\n  reset: function () {\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTgxMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvdGV4dC10cmFuc2Zvcm0uanM/MzQ1MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbnRpbnVvdXNUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNvbnRpbnVvdXMgKG51bW1lcmljYWwpIGRhdGEuXG4gKiBDdXJyZW50bHkgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiBhIHNldCBvZiBjb250cm9sIHBvaW50cyBpcyBpbXBsZW1lbnRlZC5cbiAqXG4gKiBAY2xhc3MgQ29udGludW91c1RyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIHRyYW5zZm9ybWVkVHlwZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICd0ZXh0JyxcbiAgICAgIHZhbHVlczogWyd0ZXh0J11cbiAgICB9LFxuICAgIHRyYW5zZm9ybWVkTWluOiB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogMFxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNYXg6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAxMDBcbiAgICB9XG4gIH0sXG4gIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///e810\n")},ea82:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/*global Blob,File*/\n\n/**\n * Module requirements\n */\n\nvar isArray = __webpack_require__(/*! isarray */ \"6176\");\nvar isBuf = __webpack_require__(/*! ./is-buffer */ \"419b\");\n\n/**\n * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.\n * Anything with blobs or files should be fed through removeBlobs before coming\n * here.\n *\n * @param {Object} packet - socket.io event packet\n * @return {Object} with deconstructed packet and list of buffers\n * @api public\n */\n\nexports.deconstructPacket = function(packet){\n  var buffers = [];\n  var packetData = packet.data;\n\n  function _deconstructPacket(data) {\n    if (!data) return data;\n\n    if (isBuf(data)) {\n      var placeholder = { _placeholder: true, num: buffers.length };\n      buffers.push(data);\n      return placeholder;\n    } else if (isArray(data)) {\n      var newData = new Array(data.length);\n      for (var i = 0; i < data.length; i++) {\n        newData[i] = _deconstructPacket(data[i]);\n      }\n      return newData;\n    } else if ('object' == typeof data && !(data instanceof Date)) {\n      var newData = {};\n      for (var key in data) {\n        newData[key] = _deconstructPacket(data[key]);\n      }\n      return newData;\n    }\n    return data;\n  }\n\n  var pack = packet;\n  pack.data = _deconstructPacket(packetData);\n  pack.attachments = buffers.length; // number of binary 'attachments'\n  return {packet: pack, buffers: buffers};\n};\n\n/**\n * Reconstructs a binary packet from its placeholder packet and buffers\n *\n * @param {Object} packet - event packet with placeholders\n * @param {Array} buffers - binary buffers to put in placeholder positions\n * @return {Object} reconstructed packet\n * @api public\n */\n\nexports.reconstructPacket = function(packet, buffers) {\n  var curPlaceHolder = 0;\n\n  function _reconstructPacket(data) {\n    if (data && data._placeholder) {\n      var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway)\n      return buf;\n    } else if (isArray(data)) {\n      for (var i = 0; i < data.length; i++) {\n        data[i] = _reconstructPacket(data[i]);\n      }\n      return data;\n    } else if (data && 'object' == typeof data) {\n      for (var key in data) {\n        data[key] = _reconstructPacket(data[key]);\n      }\n      return data;\n    }\n    return data;\n  }\n\n  packet.data = _reconstructPacket(packet.data);\n  packet.attachments = undefined; // no longer useful\n  return packet;\n};\n\n/**\n * Asynchronously removes Blobs or Files from data via\n * FileReader's readAsArrayBuffer method. Used before encoding\n * data as msgpack. Calls callback with the blobless data.\n *\n * @param {Object} data\n * @param {Function} callback\n * @api private\n */\n\nexports.removeBlobs = function(data, callback) {\n  function _removeBlobs(obj, curKey, containingObject) {\n    if (!obj) return obj;\n\n    // convert any blob\n    if ((global.Blob && obj instanceof Blob) ||\n        (global.File && obj instanceof File)) {\n      pendingBlobs++;\n\n      // async filereader\n      var fileReader = new FileReader();\n      fileReader.onload = function() { // this.result == arraybuffer\n        if (containingObject) {\n          containingObject[curKey] = this.result;\n        }\n        else {\n          bloblessData = this.result;\n        }\n\n        // if nothing pending its callback time\n        if(! --pendingBlobs) {\n          callback(bloblessData);\n        }\n      };\n\n      fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer\n    } else if (isArray(obj)) { // handle array\n      for (var i = 0; i < obj.length; i++) {\n        _removeBlobs(obj[i], i, obj);\n      }\n    } else if (obj && 'object' == typeof obj && !isBuf(obj)) { // and object\n      for (var key in obj) {\n        _removeBlobs(obj[key], key, obj);\n      }\n    }\n  }\n\n  var pendingBlobs = 0;\n  var bloblessData = data;\n  _removeBlobs(bloblessData);\n  if (!pendingBlobs) {\n    callback(bloblessData);\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWE4Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9iaW5hcnkuanM/ZGQwNyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKmdsb2JhbCBCbG9iLEZpbGUqL1xuXG4vKipcbiAqIE1vZHVsZSByZXF1aXJlbWVudHNcbiAqL1xuXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcbnZhciBpc0J1ZiA9IHJlcXVpcmUoJy4vaXMtYnVmZmVyJyk7XG5cbi8qKlxuICogUmVwbGFjZXMgZXZlcnkgQnVmZmVyIHwgQXJyYXlCdWZmZXIgaW4gcGFja2V0IHdpdGggYSBudW1iZXJlZCBwbGFjZWhvbGRlci5cbiAqIEFueXRoaW5nIHdpdGggYmxvYnMgb3IgZmlsZXMgc2hvdWxkIGJlIGZlZCB0aHJvdWdoIHJlbW92ZUJsb2JzIGJlZm9yZSBjb21pbmdcbiAqIGhlcmUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldCAtIHNvY2tldC5pbyBldmVudCBwYWNrZXRcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBkZWNvbnN0cnVjdGVkIHBhY2tldCBhbmQgbGlzdCBvZiBidWZmZXJzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb25zdHJ1Y3RQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQpe1xuICB2YXIgYnVmZmVycyA9IFtdO1xuICB2YXIgcGFja2V0RGF0YSA9IHBhY2tldC5kYXRhO1xuXG4gIGZ1bmN0aW9uIF9kZWNvbnN0cnVjdFBhY2tldChkYXRhKSB7XG4gICAgaWYgKCFkYXRhKSByZXR1cm4gZGF0YTtcblxuICAgIGlmIChpc0J1ZihkYXRhKSkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0geyBfcGxhY2Vob2xkZXI6IHRydWUsIG51bTogYnVmZmVycy5sZW5ndGggfTtcbiAgICAgIGJ1ZmZlcnMucHVzaChkYXRhKTtcbiAgICAgIHJldHVybiBwbGFjZWhvbGRlcjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIHZhciBuZXdEYXRhID0gbmV3IEFycmF5KGRhdGEubGVuZ3RoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBuZXdEYXRhW2ldID0gX2RlY29uc3RydWN0UGFja2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgfSBlbHNlIGlmICgnb2JqZWN0JyA9PSB0eXBlb2YgZGF0YSAmJiAhKGRhdGEgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgdmFyIG5ld0RhdGEgPSB7fTtcbiAgICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICAgIG5ld0RhdGFba2V5XSA9IF9kZWNvbnN0cnVjdFBhY2tldChkYXRhW2tleV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgdmFyIHBhY2sgPSBwYWNrZXQ7XG4gIHBhY2suZGF0YSA9IF9kZWNvbnN0cnVjdFBhY2tldChwYWNrZXREYXRhKTtcbiAgcGFjay5hdHRhY2htZW50cyA9IGJ1ZmZlcnMubGVuZ3RoOyAvLyBudW1iZXIgb2YgYmluYXJ5ICdhdHRhY2htZW50cydcbiAgcmV0dXJuIHtwYWNrZXQ6IHBhY2ssIGJ1ZmZlcnM6IGJ1ZmZlcnN9O1xufTtcblxuLyoqXG4gKiBSZWNvbnN0cnVjdHMgYSBiaW5hcnkgcGFja2V0IGZyb20gaXRzIHBsYWNlaG9sZGVyIHBhY2tldCBhbmQgYnVmZmVyc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQgLSBldmVudCBwYWNrZXQgd2l0aCBwbGFjZWhvbGRlcnNcbiAqIEBwYXJhbSB7QXJyYXl9IGJ1ZmZlcnMgLSBiaW5hcnkgYnVmZmVycyB0byBwdXQgaW4gcGxhY2Vob2xkZXIgcG9zaXRpb25zXG4gKiBAcmV0dXJuIHtPYmplY3R9IHJlY29uc3RydWN0ZWQgcGFja2V0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMucmVjb25zdHJ1Y3RQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQsIGJ1ZmZlcnMpIHtcbiAgdmFyIGN1clBsYWNlSG9sZGVyID0gMDtcblxuICBmdW5jdGlvbiBfcmVjb25zdHJ1Y3RQYWNrZXQoZGF0YSkge1xuICAgIGlmIChkYXRhICYmIGRhdGEuX3BsYWNlaG9sZGVyKSB7XG4gICAgICB2YXIgYnVmID0gYnVmZmVyc1tkYXRhLm51bV07IC8vIGFwcHJvcHJpYXRlIGJ1ZmZlciAoc2hvdWxkIGJlIG5hdHVyYWwgb3JkZXIgYW55d2F5KVxuICAgICAgcmV0dXJuIGJ1ZjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBkYXRhW2ldID0gX3JlY29uc3RydWN0UGFja2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSBlbHNlIGlmIChkYXRhICYmICdvYmplY3QnID09IHR5cGVvZiBkYXRhKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkge1xuICAgICAgICBkYXRhW2tleV0gPSBfcmVjb25zdHJ1Y3RQYWNrZXQoZGF0YVtrZXldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIHBhY2tldC5kYXRhID0gX3JlY29uc3RydWN0UGFja2V0KHBhY2tldC5kYXRhKTtcbiAgcGFja2V0LmF0dGFjaG1lbnRzID0gdW5kZWZpbmVkOyAvLyBubyBsb25nZXIgdXNlZnVsXG4gIHJldHVybiBwYWNrZXQ7XG59O1xuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IHJlbW92ZXMgQmxvYnMgb3IgRmlsZXMgZnJvbSBkYXRhIHZpYVxuICogRmlsZVJlYWRlcidzIHJlYWRBc0FycmF5QnVmZmVyIG1ldGhvZC4gVXNlZCBiZWZvcmUgZW5jb2RpbmdcbiAqIGRhdGEgYXMgbXNncGFjay4gQ2FsbHMgY2FsbGJhY2sgd2l0aCB0aGUgYmxvYmxlc3MgZGF0YS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMucmVtb3ZlQmxvYnMgPSBmdW5jdGlvbihkYXRhLCBjYWxsYmFjaykge1xuICBmdW5jdGlvbiBfcmVtb3ZlQmxvYnMob2JqLCBjdXJLZXksIGNvbnRhaW5pbmdPYmplY3QpIHtcbiAgICBpZiAoIW9iaikgcmV0dXJuIG9iajtcblxuICAgIC8vIGNvbnZlcnQgYW55IGJsb2JcbiAgICBpZiAoKGdsb2JhbC5CbG9iICYmIG9iaiBpbnN0YW5jZW9mIEJsb2IpIHx8XG4gICAgICAgIChnbG9iYWwuRmlsZSAmJiBvYmogaW5zdGFuY2VvZiBGaWxlKSkge1xuICAgICAgcGVuZGluZ0Jsb2JzKys7XG5cbiAgICAgIC8vIGFzeW5jIGZpbGVyZWFkZXJcbiAgICAgIHZhciBmaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gZnVuY3Rpb24oKSB7IC8vIHRoaXMucmVzdWx0ID09IGFycmF5YnVmZmVyXG4gICAgICAgIGlmIChjb250YWluaW5nT2JqZWN0KSB7XG4gICAgICAgICAgY29udGFpbmluZ09iamVjdFtjdXJLZXldID0gdGhpcy5yZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYmxvYmxlc3NEYXRhID0gdGhpcy5yZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBub3RoaW5nIHBlbmRpbmcgaXRzIGNhbGxiYWNrIHRpbWVcbiAgICAgICAgaWYoISAtLXBlbmRpbmdCbG9icykge1xuICAgICAgICAgIGNhbGxiYWNrKGJsb2JsZXNzRGF0YSk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIob2JqKTsgLy8gYmxvYiAtPiBhcnJheWJ1ZmZlclxuICAgIH0gZWxzZSBpZiAoaXNBcnJheShvYmopKSB7IC8vIGhhbmRsZSBhcnJheVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtpXSwgaSwgb2JqKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9iaiAmJiAnb2JqZWN0JyA9PSB0eXBlb2Ygb2JqICYmICFpc0J1ZihvYmopKSB7IC8vIGFuZCBvYmplY3RcbiAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHBlbmRpbmdCbG9icyA9IDA7XG4gIHZhciBibG9ibGVzc0RhdGEgPSBkYXRhO1xuICBfcmVtb3ZlQmxvYnMoYmxvYmxlc3NEYXRhKTtcbiAgaWYgKCFwZW5kaW5nQmxvYnMpIHtcbiAgICBjYWxsYmFjayhibG9ibGVzc0RhdGEpO1xuICB9XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///ea82\n")},ef13:function(module,exports){eval("/**\n * An abstraction for slicing an arraybuffer even when\n * ArrayBuffer.prototype.slice is not supported\n *\n * @api public\n */\n\nmodule.exports = function(arraybuffer, start, end) {\n  var bytes = arraybuffer.byteLength;\n  start = start || 0;\n  end = end || bytes;\n\n  if (arraybuffer.slice) { return arraybuffer.slice(start, end); }\n\n  if (start < 0) { start += bytes; }\n  if (end < 0) { end += bytes; }\n  if (end > bytes) { end = bytes; }\n\n  if (start >= bytes || start >= end || bytes === 0) {\n    return new ArrayBuffer(0);\n  }\n\n  var abv = new Uint8Array(arraybuffer);\n  var result = new Uint8Array(end - start);\n  for (var i = start, ii = 0; i < end; i++, ii++) {\n    result[ii] = abv[i];\n  }\n  return result.buffer;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWYxMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvYXJyYXlidWZmZXIuc2xpY2UvaW5kZXguanM/NTM3NCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFuIGFic3RyYWN0aW9uIGZvciBzbGljaW5nIGFuIGFycmF5YnVmZmVyIGV2ZW4gd2hlblxuICogQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlIGlzIG5vdCBzdXBwb3J0ZWRcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYXJyYXlidWZmZXIsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYXJyYXlidWZmZXIuYnl0ZUxlbmd0aDtcbiAgc3RhcnQgPSBzdGFydCB8fCAwO1xuICBlbmQgPSBlbmQgfHwgYnl0ZXM7XG5cbiAgaWYgKGFycmF5YnVmZmVyLnNsaWNlKSB7IHJldHVybiBhcnJheWJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTsgfVxuXG4gIGlmIChzdGFydCA8IDApIHsgc3RhcnQgKz0gYnl0ZXM7IH1cbiAgaWYgKGVuZCA8IDApIHsgZW5kICs9IGJ5dGVzOyB9XG4gIGlmIChlbmQgPiBieXRlcykgeyBlbmQgPSBieXRlczsgfVxuXG4gIGlmIChzdGFydCA+PSBieXRlcyB8fCBzdGFydCA+PSBlbmQgfHwgYnl0ZXMgPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xuICB9XG5cbiAgdmFyIGFidiA9IG5ldyBVaW50OEFycmF5KGFycmF5YnVmZmVyKTtcbiAgdmFyIHJlc3VsdCA9IG5ldyBVaW50OEFycmF5KGVuZCAtIHN0YXJ0KTtcbiAgZm9yICh2YXIgaSA9IHN0YXJ0LCBpaSA9IDA7IGkgPCBlbmQ7IGkrKywgaWkrKykge1xuICAgIHJlc3VsdFtpaV0gPSBhYnZbaV07XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5idWZmZXI7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///ef13\n")},faaa:function(module,exports){eval("\n/**\n * Module exports.\n */\n\nmodule.exports = on;\n\n/**\n * Helper for subscriptions.\n *\n * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`\n * @param {String} event name\n * @param {Function} callback\n * @api public\n */\n\nfunction on (obj, ev, fn) {\n  obj.on(ev, fn);\n  return {\n    destroy: function () {\n      obj.removeListener(ev, fn);\n    }\n  };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFhYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvb24uanM/MTBkYiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBvbjtcblxuLyoqXG4gKiBIZWxwZXIgZm9yIHN1YnNjcmlwdGlvbnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8RXZlbnRFbWl0dGVyfSBvYmogd2l0aCBgRW1pdHRlcmAgbWl4aW4gb3IgYEV2ZW50RW1pdHRlcmBcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBuYW1lXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBvbiAob2JqLCBldiwgZm4pIHtcbiAgb2JqLm9uKGV2LCBmbik7XG4gIHJldHVybiB7XG4gICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgb2JqLnJlbW92ZUxpc3RlbmVyKGV2LCBmbik7XG4gICAgfVxuICB9O1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///faaa\n")},fbef:function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Aggregate = __webpack_require__(/*! ../aggregate */ \"9d63\");\n\nmodule.exports = Collection.extend({\n  model: Aggregate,\n  indexes: ['rank'],\n  comparator: 'rank'\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmJlZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvYWdncmVnYXRlL2NvbGxlY3Rpb24uanM/YmJhNiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgQWdncmVnYXRlID0gcmVxdWlyZSgnLi4vYWdncmVnYXRlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogQWdncmVnYXRlLFxuICBpbmRleGVzOiBbJ3JhbmsnXSxcbiAgY29tcGFyYXRvcjogJ3JhbmsnXG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///fbef\n")}}]);

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.spot-framework"],{"0056":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Group = __webpack_require__(/*! ./group */ \"9083\");\n\nfunction setOrdering (groups, ordering) {\n  if (ordering === 'count') {\n    groups.comparator = function (a, b) {\n      if (a.count === b.count) {\n        return a.value < b.value ? -1 : 1;\n      } else {\n        return b.count - a.count;\n      }\n    };\n  } else if (ordering === 'value') {\n    groups.comparator = 'value';\n  } else {\n    console.error('Ordering not implemented for partition: ', ordering);\n  }\n  groups.sort();\n}\n\nmodule.exports = Collection.extend({\n  indexes: ['value', 'label', 'group', 'groupIndex'],\n  model: Group,\n  comparator: 'label',\n  initialize: function (models, options) {\n    var groups = this;\n    var partition = options.parent;\n\n    // update group index on resort\n    this.on('sort', function () {\n      this.forEach(function (group, i) {\n        group.groupIndex = i;\n      });\n    }, this);\n\n    // this.parent := partition\n    if (partition) {\n      setOrdering(groups, partition.ordering);\n\n      partition.on('change ordering', function () {\n        setOrdering(groups, partition.ordering);\n      });\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDA1Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2dyb3VwLWNvbGxlY3Rpb24uanM/OGM1ZiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgR3JvdXAgPSByZXF1aXJlKCcuL2dyb3VwJyk7XG5cbmZ1bmN0aW9uIHNldE9yZGVyaW5nIChncm91cHMsIG9yZGVyaW5nKSB7XG4gIGlmIChvcmRlcmluZyA9PT0gJ2NvdW50Jykge1xuICAgIGdyb3Vwcy5jb21wYXJhdG9yID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIGlmIChhLmNvdW50ID09PSBiLmNvdW50KSB7XG4gICAgICAgIHJldHVybiBhLnZhbHVlIDwgYi52YWx1ZSA/IC0xIDogMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBiLmNvdW50IC0gYS5jb3VudDtcbiAgICAgIH1cbiAgICB9O1xuICB9IGVsc2UgaWYgKG9yZGVyaW5nID09PSAndmFsdWUnKSB7XG4gICAgZ3JvdXBzLmNvbXBhcmF0b3IgPSAndmFsdWUnO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUuZXJyb3IoJ09yZGVyaW5nIG5vdCBpbXBsZW1lbnRlZCBmb3IgcGFydGl0aW9uOiAnLCBvcmRlcmluZyk7XG4gIH1cbiAgZ3JvdXBzLnNvcnQoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDb2xsZWN0aW9uLmV4dGVuZCh7XG4gIGluZGV4ZXM6IFsndmFsdWUnLCAnbGFiZWwnLCAnZ3JvdXAnLCAnZ3JvdXBJbmRleCddLFxuICBtb2RlbDogR3JvdXAsXG4gIGNvbXBhcmF0b3I6ICdsYWJlbCcsXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uIChtb2RlbHMsIG9wdGlvbnMpIHtcbiAgICB2YXIgZ3JvdXBzID0gdGhpcztcbiAgICB2YXIgcGFydGl0aW9uID0gb3B0aW9ucy5wYXJlbnQ7XG5cbiAgICAvLyB1cGRhdGUgZ3JvdXAgaW5kZXggb24gcmVzb3J0XG4gICAgdGhpcy5vbignc29ydCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZ3JvdXAsIGkpIHtcbiAgICAgICAgZ3JvdXAuZ3JvdXBJbmRleCA9IGk7XG4gICAgICB9KTtcbiAgICB9LCB0aGlzKTtcblxuICAgIC8vIHRoaXMucGFyZW50IDo9IHBhcnRpdGlvblxuICAgIGlmIChwYXJ0aXRpb24pIHtcbiAgICAgIHNldE9yZGVyaW5nKGdyb3VwcywgcGFydGl0aW9uLm9yZGVyaW5nKTtcblxuICAgICAgcGFydGl0aW9uLm9uKCdjaGFuZ2Ugb3JkZXJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNldE9yZGVyaW5nKGdyb3VwcywgcGFydGl0aW9uLm9yZGVyaW5nKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///0056\n")},"0112":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar transports = __webpack_require__(/*! ./transports/index */ \"834b\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:socket');\nvar index = __webpack_require__(/*! indexof */ \"3294\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar parseuri = __webpack_require__(/*! parseuri */ \"64a0\");\nvar parsejson = __webpack_require__(/*! parsejson */ \"185c\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = Socket;\n\n/**\n * Socket constructor.\n *\n * @param {String|Object} uri or options\n * @param {Object} options\n * @api public\n */\n\nfunction Socket (uri, opts) {\n  if (!(this instanceof Socket)) return new Socket(uri, opts);\n\n  opts = opts || {};\n\n  if (uri && 'object' === typeof uri) {\n    opts = uri;\n    uri = null;\n  }\n\n  if (uri) {\n    uri = parseuri(uri);\n    opts.hostname = uri.host;\n    opts.secure = uri.protocol === 'https' || uri.protocol === 'wss';\n    opts.port = uri.port;\n    if (uri.query) opts.query = uri.query;\n  } else if (opts.host) {\n    opts.hostname = parseuri(opts.host).host;\n  }\n\n  this.secure = null != opts.secure ? opts.secure\n    : (global.location && 'https:' === location.protocol);\n\n  if (opts.hostname && !opts.port) {\n    // if no port is specified manually, use the protocol default\n    opts.port = this.secure ? '443' : '80';\n  }\n\n  this.agent = opts.agent || false;\n  this.hostname = opts.hostname ||\n    (global.location ? location.hostname : 'localhost');\n  this.port = opts.port || (global.location && location.port\n      ? location.port\n      : (this.secure ? 443 : 80));\n  this.query = opts.query || {};\n  if ('string' === typeof this.query) this.query = parseqs.decode(this.query);\n  this.upgrade = false !== opts.upgrade;\n  this.path = (opts.path || '/engine.io').replace(/\\/$/, '') + '/';\n  this.forceJSONP = !!opts.forceJSONP;\n  this.jsonp = false !== opts.jsonp;\n  this.forceBase64 = !!opts.forceBase64;\n  this.enablesXDR = !!opts.enablesXDR;\n  this.timestampParam = opts.timestampParam || 't';\n  this.timestampRequests = opts.timestampRequests;\n  this.transports = opts.transports || ['polling', 'websocket'];\n  this.readyState = '';\n  this.writeBuffer = [];\n  this.prevBufferLen = 0;\n  this.policyPort = opts.policyPort || 843;\n  this.rememberUpgrade = opts.rememberUpgrade || false;\n  this.binaryType = null;\n  this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;\n  this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || {}) : false;\n\n  if (true === this.perMessageDeflate) this.perMessageDeflate = {};\n  if (this.perMessageDeflate && null == this.perMessageDeflate.threshold) {\n    this.perMessageDeflate.threshold = 1024;\n  }\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx || null;\n  this.key = opts.key || null;\n  this.passphrase = opts.passphrase || null;\n  this.cert = opts.cert || null;\n  this.ca = opts.ca || null;\n  this.ciphers = opts.ciphers || null;\n  this.rejectUnauthorized = opts.rejectUnauthorized === undefined ? null : opts.rejectUnauthorized;\n  this.forceNode = !!opts.forceNode;\n\n  // other options for Node.js client\n  var freeGlobal = typeof global === 'object' && global;\n  if (freeGlobal.global === freeGlobal) {\n    if (opts.extraHeaders && Object.keys(opts.extraHeaders).length > 0) {\n      this.extraHeaders = opts.extraHeaders;\n    }\n\n    if (opts.localAddress) {\n      this.localAddress = opts.localAddress;\n    }\n  }\n\n  // set on handshake\n  this.id = null;\n  this.upgrades = null;\n  this.pingInterval = null;\n  this.pingTimeout = null;\n\n  // set on heartbeat\n  this.pingIntervalTimer = null;\n  this.pingTimeoutTimer = null;\n\n  this.open();\n}\n\nSocket.priorWebsocketSuccess = false;\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Socket.prototype);\n\n/**\n * Protocol version.\n *\n * @api public\n */\n\nSocket.protocol = parser.protocol; // this is an int\n\n/**\n * Expose deps for legacy compatibility\n * and standalone browser access.\n */\n\nSocket.Socket = Socket;\nSocket.Transport = __webpack_require__(/*! ./transport */ \"0d97\");\nSocket.transports = __webpack_require__(/*! ./transports/index */ \"834b\");\nSocket.parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\n\n/**\n * Creates transport of the given type.\n *\n * @param {String} transport name\n * @return {Transport}\n * @api private\n */\n\nSocket.prototype.createTransport = function (name) {\n  debug('creating transport \"%s\"', name);\n  var query = clone(this.query);\n\n  // append engine.io protocol identifier\n  query.EIO = parser.protocol;\n\n  // transport name\n  query.transport = name;\n\n  // session id if we already have one\n  if (this.id) query.sid = this.id;\n\n  var transport = new transports[name]({\n    agent: this.agent,\n    hostname: this.hostname,\n    port: this.port,\n    secure: this.secure,\n    path: this.path,\n    query: query,\n    forceJSONP: this.forceJSONP,\n    jsonp: this.jsonp,\n    forceBase64: this.forceBase64,\n    enablesXDR: this.enablesXDR,\n    timestampRequests: this.timestampRequests,\n    timestampParam: this.timestampParam,\n    policyPort: this.policyPort,\n    socket: this,\n    pfx: this.pfx,\n    key: this.key,\n    passphrase: this.passphrase,\n    cert: this.cert,\n    ca: this.ca,\n    ciphers: this.ciphers,\n    rejectUnauthorized: this.rejectUnauthorized,\n    perMessageDeflate: this.perMessageDeflate,\n    extraHeaders: this.extraHeaders,\n    forceNode: this.forceNode,\n    localAddress: this.localAddress\n  });\n\n  return transport;\n};\n\nfunction clone (obj) {\n  var o = {};\n  for (var i in obj) {\n    if (obj.hasOwnProperty(i)) {\n      o[i] = obj[i];\n    }\n  }\n  return o;\n}\n\n/**\n * Initializes transport to use and starts probe.\n *\n * @api private\n */\nSocket.prototype.open = function () {\n  var transport;\n  if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') !== -1) {\n    transport = 'websocket';\n  } else if (0 === this.transports.length) {\n    // Emit error on next tick so it can be listened to\n    var self = this;\n    setTimeout(function () {\n      self.emit('error', 'No transports available');\n    }, 0);\n    return;\n  } else {\n    transport = this.transports[0];\n  }\n  this.readyState = 'opening';\n\n  // Retry with the next transport if the transport is disabled (jsonp: false)\n  try {\n    transport = this.createTransport(transport);\n  } catch (e) {\n    this.transports.shift();\n    this.open();\n    return;\n  }\n\n  transport.open();\n  this.setTransport(transport);\n};\n\n/**\n * Sets the current transport. Disables the existing one (if any).\n *\n * @api private\n */\n\nSocket.prototype.setTransport = function (transport) {\n  debug('setting transport %s', transport.name);\n  var self = this;\n\n  if (this.transport) {\n    debug('clearing existing transport %s', this.transport.name);\n    this.transport.removeAllListeners();\n  }\n\n  // set up transport\n  this.transport = transport;\n\n  // set up transport listeners\n  transport\n  .on('drain', function () {\n    self.onDrain();\n  })\n  .on('packet', function (packet) {\n    self.onPacket(packet);\n  })\n  .on('error', function (e) {\n    self.onError(e);\n  })\n  .on('close', function () {\n    self.onClose('transport close');\n  });\n};\n\n/**\n * Probes a transport.\n *\n * @param {String} transport name\n * @api private\n */\n\nSocket.prototype.probe = function (name) {\n  debug('probing transport \"%s\"', name);\n  var transport = this.createTransport(name, { probe: 1 });\n  var failed = false;\n  var self = this;\n\n  Socket.priorWebsocketSuccess = false;\n\n  function onTransportOpen () {\n    if (self.onlyBinaryUpgrades) {\n      var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;\n      failed = failed || upgradeLosesBinary;\n    }\n    if (failed) return;\n\n    debug('probe transport \"%s\" opened', name);\n    transport.send([{ type: 'ping', data: 'probe' }]);\n    transport.once('packet', function (msg) {\n      if (failed) return;\n      if ('pong' === msg.type && 'probe' === msg.data) {\n        debug('probe transport \"%s\" pong', name);\n        self.upgrading = true;\n        self.emit('upgrading', transport);\n        if (!transport) return;\n        Socket.priorWebsocketSuccess = 'websocket' === transport.name;\n\n        debug('pausing current transport \"%s\"', self.transport.name);\n        self.transport.pause(function () {\n          if (failed) return;\n          if ('closed' === self.readyState) return;\n          debug('changing transport and sending upgrade packet');\n\n          cleanup();\n\n          self.setTransport(transport);\n          transport.send([{ type: 'upgrade' }]);\n          self.emit('upgrade', transport);\n          transport = null;\n          self.upgrading = false;\n          self.flush();\n        });\n      } else {\n        debug('probe transport \"%s\" failed', name);\n        var err = new Error('probe error');\n        err.transport = transport.name;\n        self.emit('upgradeError', err);\n      }\n    });\n  }\n\n  function freezeTransport () {\n    if (failed) return;\n\n    // Any callback called by transport should be ignored since now\n    failed = true;\n\n    cleanup();\n\n    transport.close();\n    transport = null;\n  }\n\n  // Handle any error that happens while probing\n  function onerror (err) {\n    var error = new Error('probe error: ' + err);\n    error.transport = transport.name;\n\n    freezeTransport();\n\n    debug('probe transport \"%s\" failed because of error: %s', name, err);\n\n    self.emit('upgradeError', error);\n  }\n\n  function onTransportClose () {\n    onerror('transport closed');\n  }\n\n  // When the socket is closed while we're probing\n  function onclose () {\n    onerror('socket closed');\n  }\n\n  // When the socket is upgraded while we're probing\n  function onupgrade (to) {\n    if (transport && to.name !== transport.name) {\n      debug('\"%s\" works - aborting \"%s\"', to.name, transport.name);\n      freezeTransport();\n    }\n  }\n\n  // Remove all listeners on the transport and on self\n  function cleanup () {\n    transport.removeListener('open', onTransportOpen);\n    transport.removeListener('error', onerror);\n    transport.removeListener('close', onTransportClose);\n    self.removeListener('close', onclose);\n    self.removeListener('upgrading', onupgrade);\n  }\n\n  transport.once('open', onTransportOpen);\n  transport.once('error', onerror);\n  transport.once('close', onTransportClose);\n\n  this.once('close', onclose);\n  this.once('upgrading', onupgrade);\n\n  transport.open();\n};\n\n/**\n * Called when connection is deemed open.\n *\n * @api public\n */\n\nSocket.prototype.onOpen = function () {\n  debug('socket open');\n  this.readyState = 'open';\n  Socket.priorWebsocketSuccess = 'websocket' === this.transport.name;\n  this.emit('open');\n  this.flush();\n\n  // we check for `readyState` in case an `open`\n  // listener already closed the socket\n  if ('open' === this.readyState && this.upgrade && this.transport.pause) {\n    debug('starting upgrade probes');\n    for (var i = 0, l = this.upgrades.length; i < l; i++) {\n      this.probe(this.upgrades[i]);\n    }\n  }\n};\n\n/**\n * Handles a packet.\n *\n * @api private\n */\n\nSocket.prototype.onPacket = function (packet) {\n  if ('opening' === this.readyState || 'open' === this.readyState ||\n      'closing' === this.readyState) {\n    debug('socket receive: type \"%s\", data \"%s\"', packet.type, packet.data);\n\n    this.emit('packet', packet);\n\n    // Socket is live - any packet counts\n    this.emit('heartbeat');\n\n    switch (packet.type) {\n      case 'open':\n        this.onHandshake(parsejson(packet.data));\n        break;\n\n      case 'pong':\n        this.setPing();\n        this.emit('pong');\n        break;\n\n      case 'error':\n        var err = new Error('server error');\n        err.code = packet.data;\n        this.onError(err);\n        break;\n\n      case 'message':\n        this.emit('data', packet.data);\n        this.emit('message', packet.data);\n        break;\n    }\n  } else {\n    debug('packet received with socket readyState \"%s\"', this.readyState);\n  }\n};\n\n/**\n * Called upon handshake completion.\n *\n * @param {Object} handshake obj\n * @api private\n */\n\nSocket.prototype.onHandshake = function (data) {\n  this.emit('handshake', data);\n  this.id = data.sid;\n  this.transport.query.sid = data.sid;\n  this.upgrades = this.filterUpgrades(data.upgrades);\n  this.pingInterval = data.pingInterval;\n  this.pingTimeout = data.pingTimeout;\n  this.onOpen();\n  // In case open handler closes socket\n  if ('closed' === this.readyState) return;\n  this.setPing();\n\n  // Prolong liveness of socket on heartbeat\n  this.removeListener('heartbeat', this.onHeartbeat);\n  this.on('heartbeat', this.onHeartbeat);\n};\n\n/**\n * Resets ping timeout.\n *\n * @api private\n */\n\nSocket.prototype.onHeartbeat = function (timeout) {\n  clearTimeout(this.pingTimeoutTimer);\n  var self = this;\n  self.pingTimeoutTimer = setTimeout(function () {\n    if ('closed' === self.readyState) return;\n    self.onClose('ping timeout');\n  }, timeout || (self.pingInterval + self.pingTimeout));\n};\n\n/**\n * Pings server every `this.pingInterval` and expects response\n * within `this.pingTimeout` or closes connection.\n *\n * @api private\n */\n\nSocket.prototype.setPing = function () {\n  var self = this;\n  clearTimeout(self.pingIntervalTimer);\n  self.pingIntervalTimer = setTimeout(function () {\n    debug('writing ping packet - expecting pong within %sms', self.pingTimeout);\n    self.ping();\n    self.onHeartbeat(self.pingTimeout);\n  }, self.pingInterval);\n};\n\n/**\n* Sends a ping packet.\n*\n* @api private\n*/\n\nSocket.prototype.ping = function () {\n  var self = this;\n  this.sendPacket('ping', function () {\n    self.emit('ping');\n  });\n};\n\n/**\n * Called on `drain` event\n *\n * @api private\n */\n\nSocket.prototype.onDrain = function () {\n  this.writeBuffer.splice(0, this.prevBufferLen);\n\n  // setting prevBufferLen = 0 is very important\n  // for example, when upgrading, upgrade packet is sent over,\n  // and a nonzero prevBufferLen could cause problems on `drain`\n  this.prevBufferLen = 0;\n\n  if (0 === this.writeBuffer.length) {\n    this.emit('drain');\n  } else {\n    this.flush();\n  }\n};\n\n/**\n * Flush write buffers.\n *\n * @api private\n */\n\nSocket.prototype.flush = function () {\n  if ('closed' !== this.readyState && this.transport.writable &&\n    !this.upgrading && this.writeBuffer.length) {\n    debug('flushing %d packets in socket', this.writeBuffer.length);\n    this.transport.send(this.writeBuffer);\n    // keep track of current length of writeBuffer\n    // splice writeBuffer and callbackBuffer on `drain`\n    this.prevBufferLen = this.writeBuffer.length;\n    this.emit('flush');\n  }\n};\n\n/**\n * Sends a message.\n *\n * @param {String} message.\n * @param {Function} callback function.\n * @param {Object} options.\n * @return {Socket} for chaining.\n * @api public\n */\n\nSocket.prototype.write =\nSocket.prototype.send = function (msg, options, fn) {\n  this.sendPacket('message', msg, options, fn);\n  return this;\n};\n\n/**\n * Sends a packet.\n *\n * @param {String} packet type.\n * @param {String} data.\n * @param {Object} options.\n * @param {Function} callback function.\n * @api private\n */\n\nSocket.prototype.sendPacket = function (type, data, options, fn) {\n  if ('function' === typeof data) {\n    fn = data;\n    data = undefined;\n  }\n\n  if ('function' === typeof options) {\n    fn = options;\n    options = null;\n  }\n\n  if ('closing' === this.readyState || 'closed' === this.readyState) {\n    return;\n  }\n\n  options = options || {};\n  options.compress = false !== options.compress;\n\n  var packet = {\n    type: type,\n    data: data,\n    options: options\n  };\n  this.emit('packetCreate', packet);\n  this.writeBuffer.push(packet);\n  if (fn) this.once('flush', fn);\n  this.flush();\n};\n\n/**\n * Closes the connection.\n *\n * @api private\n */\n\nSocket.prototype.close = function () {\n  if ('opening' === this.readyState || 'open' === this.readyState) {\n    this.readyState = 'closing';\n\n    var self = this;\n\n    if (this.writeBuffer.length) {\n      this.once('drain', function () {\n        if (this.upgrading) {\n          waitForUpgrade();\n        } else {\n          close();\n        }\n      });\n    } else if (this.upgrading) {\n      waitForUpgrade();\n    } else {\n      close();\n    }\n  }\n\n  function close () {\n    self.onClose('forced close');\n    debug('socket closing - telling transport to close');\n    self.transport.close();\n  }\n\n  function cleanupAndClose () {\n    self.removeListener('upgrade', cleanupAndClose);\n    self.removeListener('upgradeError', cleanupAndClose);\n    close();\n  }\n\n  function waitForUpgrade () {\n    // wait for upgrade to finish since we can't send packets while pausing a transport\n    self.once('upgrade', cleanupAndClose);\n    self.once('upgradeError', cleanupAndClose);\n  }\n\n  return this;\n};\n\n/**\n * Called upon transport error\n *\n * @api private\n */\n\nSocket.prototype.onError = function (err) {\n  debug('socket error %j', err);\n  Socket.priorWebsocketSuccess = false;\n  this.emit('error', err);\n  this.onClose('transport error', err);\n};\n\n/**\n * Called upon transport close.\n *\n * @api private\n */\n\nSocket.prototype.onClose = function (reason, desc) {\n  if ('opening' === this.readyState || 'open' === this.readyState || 'closing' === this.readyState) {\n    debug('socket close with reason: \"%s\"', reason);\n    var self = this;\n\n    // clear timers\n    clearTimeout(this.pingIntervalTimer);\n    clearTimeout(this.pingTimeoutTimer);\n\n    // stop event from firing again for transport\n    this.transport.removeAllListeners('close');\n\n    // ensure transport won't stay open\n    this.transport.close();\n\n    // ignore further transport communication\n    this.transport.removeAllListeners();\n\n    // set ready state\n    this.readyState = 'closed';\n\n    // clear session id\n    this.id = null;\n\n    // emit close event\n    this.emit('close', reason, desc);\n\n    // clean buffers after, so users can still\n    // grab the buffers on `close` event\n    self.writeBuffer = [];\n    self.prevBufferLen = 0;\n  }\n};\n\n/**\n * Filters upgrades, returning only those matching client transports.\n *\n * @param {Array} server upgrades\n * @api private\n *\n */\n\nSocket.prototype.filterUpgrades = function (upgrades) {\n  var filteredUpgrades = [];\n  for (var i = 0, j = upgrades.length; i < j; i++) {\n    if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);\n  }\n  return filteredUpgrades;\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDExMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvc29ja2V0LmpzPzM1YjUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL2luZGV4Jyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnNvY2tldCcpO1xudmFyIGluZGV4ID0gcmVxdWlyZSgnaW5kZXhvZicpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBwYXJzZXVyaSA9IHJlcXVpcmUoJ3BhcnNldXJpJyk7XG52YXIgcGFyc2Vqc29uID0gcmVxdWlyZSgncGFyc2Vqc29uJyk7XG52YXIgcGFyc2VxcyA9IHJlcXVpcmUoJ3BhcnNlcXMnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNvY2tldDtcblxuLyoqXG4gKiBTb2NrZXQgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSB1cmkgb3Igb3B0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gU29ja2V0ICh1cmksIG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNvY2tldCkpIHJldHVybiBuZXcgU29ja2V0KHVyaSwgb3B0cyk7XG5cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgaWYgKHVyaSAmJiAnb2JqZWN0JyA9PT0gdHlwZW9mIHVyaSkge1xuICAgIG9wdHMgPSB1cmk7XG4gICAgdXJpID0gbnVsbDtcbiAgfVxuXG4gIGlmICh1cmkpIHtcbiAgICB1cmkgPSBwYXJzZXVyaSh1cmkpO1xuICAgIG9wdHMuaG9zdG5hbWUgPSB1cmkuaG9zdDtcbiAgICBvcHRzLnNlY3VyZSA9IHVyaS5wcm90b2NvbCA9PT0gJ2h0dHBzJyB8fCB1cmkucHJvdG9jb2wgPT09ICd3c3MnO1xuICAgIG9wdHMucG9ydCA9IHVyaS5wb3J0O1xuICAgIGlmICh1cmkucXVlcnkpIG9wdHMucXVlcnkgPSB1cmkucXVlcnk7XG4gIH0gZWxzZSBpZiAob3B0cy5ob3N0KSB7XG4gICAgb3B0cy5ob3N0bmFtZSA9IHBhcnNldXJpKG9wdHMuaG9zdCkuaG9zdDtcbiAgfVxuXG4gIHRoaXMuc2VjdXJlID0gbnVsbCAhPSBvcHRzLnNlY3VyZSA/IG9wdHMuc2VjdXJlXG4gICAgOiAoZ2xvYmFsLmxvY2F0aW9uICYmICdodHRwczonID09PSBsb2NhdGlvbi5wcm90b2NvbCk7XG5cbiAgaWYgKG9wdHMuaG9zdG5hbWUgJiYgIW9wdHMucG9ydCkge1xuICAgIC8vIGlmIG5vIHBvcnQgaXMgc3BlY2lmaWVkIG1hbnVhbGx5LCB1c2UgdGhlIHByb3RvY29sIGRlZmF1bHRcbiAgICBvcHRzLnBvcnQgPSB0aGlzLnNlY3VyZSA/ICc0NDMnIDogJzgwJztcbiAgfVxuXG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50IHx8IGZhbHNlO1xuICB0aGlzLmhvc3RuYW1lID0gb3B0cy5ob3N0bmFtZSB8fFxuICAgIChnbG9iYWwubG9jYXRpb24gPyBsb2NhdGlvbi5ob3N0bmFtZSA6ICdsb2NhbGhvc3QnKTtcbiAgdGhpcy5wb3J0ID0gb3B0cy5wb3J0IHx8IChnbG9iYWwubG9jYXRpb24gJiYgbG9jYXRpb24ucG9ydFxuICAgICAgPyBsb2NhdGlvbi5wb3J0XG4gICAgICA6ICh0aGlzLnNlY3VyZSA/IDQ0MyA6IDgwKSk7XG4gIHRoaXMucXVlcnkgPSBvcHRzLnF1ZXJ5IHx8IHt9O1xuICBpZiAoJ3N0cmluZycgPT09IHR5cGVvZiB0aGlzLnF1ZXJ5KSB0aGlzLnF1ZXJ5ID0gcGFyc2Vxcy5kZWNvZGUodGhpcy5xdWVyeSk7XG4gIHRoaXMudXBncmFkZSA9IGZhbHNlICE9PSBvcHRzLnVwZ3JhZGU7XG4gIHRoaXMucGF0aCA9IChvcHRzLnBhdGggfHwgJy9lbmdpbmUuaW8nKS5yZXBsYWNlKC9cXC8kLywgJycpICsgJy8nO1xuICB0aGlzLmZvcmNlSlNPTlAgPSAhIW9wdHMuZm9yY2VKU09OUDtcbiAgdGhpcy5qc29ucCA9IGZhbHNlICE9PSBvcHRzLmpzb25wO1xuICB0aGlzLmZvcmNlQmFzZTY0ID0gISFvcHRzLmZvcmNlQmFzZTY0O1xuICB0aGlzLmVuYWJsZXNYRFIgPSAhIW9wdHMuZW5hYmxlc1hEUjtcbiAgdGhpcy50aW1lc3RhbXBQYXJhbSA9IG9wdHMudGltZXN0YW1wUGFyYW0gfHwgJ3QnO1xuICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgdGhpcy50cmFuc3BvcnRzID0gb3B0cy50cmFuc3BvcnRzIHx8IFsncG9sbGluZycsICd3ZWJzb2NrZXQnXTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gIHRoaXMud3JpdGVCdWZmZXIgPSBbXTtcbiAgdGhpcy5wcmV2QnVmZmVyTGVuID0gMDtcbiAgdGhpcy5wb2xpY3lQb3J0ID0gb3B0cy5wb2xpY3lQb3J0IHx8IDg0MztcbiAgdGhpcy5yZW1lbWJlclVwZ3JhZGUgPSBvcHRzLnJlbWVtYmVyVXBncmFkZSB8fCBmYWxzZTtcbiAgdGhpcy5iaW5hcnlUeXBlID0gbnVsbDtcbiAgdGhpcy5vbmx5QmluYXJ5VXBncmFkZXMgPSBvcHRzLm9ubHlCaW5hcnlVcGdyYWRlcztcbiAgdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZSA9IGZhbHNlICE9PSBvcHRzLnBlck1lc3NhZ2VEZWZsYXRlID8gKG9wdHMucGVyTWVzc2FnZURlZmxhdGUgfHwge30pIDogZmFsc2U7XG5cbiAgaWYgKHRydWUgPT09IHRoaXMucGVyTWVzc2FnZURlZmxhdGUpIHRoaXMucGVyTWVzc2FnZURlZmxhdGUgPSB7fTtcbiAgaWYgKHRoaXMucGVyTWVzc2FnZURlZmxhdGUgJiYgbnVsbCA9PSB0aGlzLnBlck1lc3NhZ2VEZWZsYXRlLnRocmVzaG9sZCkge1xuICAgIHRoaXMucGVyTWVzc2FnZURlZmxhdGUudGhyZXNob2xkID0gMTAyNDtcbiAgfVxuXG4gIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLnBmeCA9IG9wdHMucGZ4IHx8IG51bGw7XG4gIHRoaXMua2V5ID0gb3B0cy5rZXkgfHwgbnVsbDtcbiAgdGhpcy5wYXNzcGhyYXNlID0gb3B0cy5wYXNzcGhyYXNlIHx8IG51bGw7XG4gIHRoaXMuY2VydCA9IG9wdHMuY2VydCB8fCBudWxsO1xuICB0aGlzLmNhID0gb3B0cy5jYSB8fCBudWxsO1xuICB0aGlzLmNpcGhlcnMgPSBvcHRzLmNpcGhlcnMgfHwgbnVsbDtcbiAgdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQgPSBvcHRzLnJlamVjdFVuYXV0aG9yaXplZCA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IG9wdHMucmVqZWN0VW5hdXRob3JpemVkO1xuICB0aGlzLmZvcmNlTm9kZSA9ICEhb3B0cy5mb3JjZU5vZGU7XG5cbiAgLy8gb3RoZXIgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgdmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09PSAnb2JqZWN0JyAmJiBnbG9iYWw7XG4gIGlmIChmcmVlR2xvYmFsLmdsb2JhbCA9PT0gZnJlZUdsb2JhbCkge1xuICAgIGlmIChvcHRzLmV4dHJhSGVhZGVycyAmJiBPYmplY3Qua2V5cyhvcHRzLmV4dHJhSGVhZGVycykubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5leHRyYUhlYWRlcnMgPSBvcHRzLmV4dHJhSGVhZGVycztcbiAgICB9XG5cbiAgICBpZiAob3B0cy5sb2NhbEFkZHJlc3MpIHtcbiAgICAgIHRoaXMubG9jYWxBZGRyZXNzID0gb3B0cy5sb2NhbEFkZHJlc3M7XG4gICAgfVxuICB9XG5cbiAgLy8gc2V0IG9uIGhhbmRzaGFrZVxuICB0aGlzLmlkID0gbnVsbDtcbiAgdGhpcy51cGdyYWRlcyA9IG51bGw7XG4gIHRoaXMucGluZ0ludGVydmFsID0gbnVsbDtcbiAgdGhpcy5waW5nVGltZW91dCA9IG51bGw7XG5cbiAgLy8gc2V0IG9uIGhlYXJ0YmVhdFxuICB0aGlzLnBpbmdJbnRlcnZhbFRpbWVyID0gbnVsbDtcbiAgdGhpcy5waW5nVGltZW91dFRpbWVyID0gbnVsbDtcblxuICB0aGlzLm9wZW4oKTtcbn1cblxuU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuXG4vKipcbiAqIE1peCBpbiBgRW1pdHRlcmAuXG4gKi9cblxuRW1pdHRlcihTb2NrZXQucHJvdG90eXBlKTtcblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sOyAvLyB0aGlzIGlzIGFuIGludFxuXG4vKipcbiAqIEV4cG9zZSBkZXBzIGZvciBsZWdhY3kgY29tcGF0aWJpbGl0eVxuICogYW5kIHN0YW5kYWxvbmUgYnJvd3NlciBhY2Nlc3MuXG4gKi9cblxuU29ja2V0LlNvY2tldCA9IFNvY2tldDtcblNvY2tldC5UcmFuc3BvcnQgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpO1xuU29ja2V0LnRyYW5zcG9ydHMgPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMvaW5kZXgnKTtcblNvY2tldC5wYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyB0cmFuc3BvcnQgb2YgdGhlIGdpdmVuIHR5cGUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHRyYW5zcG9ydCBuYW1lXG4gKiBAcmV0dXJuIHtUcmFuc3BvcnR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNyZWF0ZVRyYW5zcG9ydCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlYnVnKCdjcmVhdGluZyB0cmFuc3BvcnQgXCIlc1wiJywgbmFtZSk7XG4gIHZhciBxdWVyeSA9IGNsb25lKHRoaXMucXVlcnkpO1xuXG4gIC8vIGFwcGVuZCBlbmdpbmUuaW8gcHJvdG9jb2wgaWRlbnRpZmllclxuICBxdWVyeS5FSU8gPSBwYXJzZXIucHJvdG9jb2w7XG5cbiAgLy8gdHJhbnNwb3J0IG5hbWVcbiAgcXVlcnkudHJhbnNwb3J0ID0gbmFtZTtcblxuICAvLyBzZXNzaW9uIGlkIGlmIHdlIGFscmVhZHkgaGF2ZSBvbmVcbiAgaWYgKHRoaXMuaWQpIHF1ZXJ5LnNpZCA9IHRoaXMuaWQ7XG5cbiAgdmFyIHRyYW5zcG9ydCA9IG5ldyB0cmFuc3BvcnRzW25hbWVdKHtcbiAgICBhZ2VudDogdGhpcy5hZ2VudCxcbiAgICBob3N0bmFtZTogdGhpcy5ob3N0bmFtZSxcbiAgICBwb3J0OiB0aGlzLnBvcnQsXG4gICAgc2VjdXJlOiB0aGlzLnNlY3VyZSxcbiAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgcXVlcnk6IHF1ZXJ5LFxuICAgIGZvcmNlSlNPTlA6IHRoaXMuZm9yY2VKU09OUCxcbiAgICBqc29ucDogdGhpcy5qc29ucCxcbiAgICBmb3JjZUJhc2U2NDogdGhpcy5mb3JjZUJhc2U2NCxcbiAgICBlbmFibGVzWERSOiB0aGlzLmVuYWJsZXNYRFIsXG4gICAgdGltZXN0YW1wUmVxdWVzdHM6IHRoaXMudGltZXN0YW1wUmVxdWVzdHMsXG4gICAgdGltZXN0YW1wUGFyYW06IHRoaXMudGltZXN0YW1wUGFyYW0sXG4gICAgcG9saWN5UG9ydDogdGhpcy5wb2xpY3lQb3J0LFxuICAgIHNvY2tldDogdGhpcyxcbiAgICBwZng6IHRoaXMucGZ4LFxuICAgIGtleTogdGhpcy5rZXksXG4gICAgcGFzc3BocmFzZTogdGhpcy5wYXNzcGhyYXNlLFxuICAgIGNlcnQ6IHRoaXMuY2VydCxcbiAgICBjYTogdGhpcy5jYSxcbiAgICBjaXBoZXJzOiB0aGlzLmNpcGhlcnMsXG4gICAgcmVqZWN0VW5hdXRob3JpemVkOiB0aGlzLnJlamVjdFVuYXV0aG9yaXplZCxcbiAgICBwZXJNZXNzYWdlRGVmbGF0ZTogdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZSxcbiAgICBleHRyYUhlYWRlcnM6IHRoaXMuZXh0cmFIZWFkZXJzLFxuICAgIGZvcmNlTm9kZTogdGhpcy5mb3JjZU5vZGUsXG4gICAgbG9jYWxBZGRyZXNzOiB0aGlzLmxvY2FsQWRkcmVzc1xuICB9KTtcblxuICByZXR1cm4gdHJhbnNwb3J0O1xufTtcblxuZnVuY3Rpb24gY2xvbmUgKG9iaikge1xuICB2YXIgbyA9IHt9O1xuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgIG9baV0gPSBvYmpbaV07XG4gICAgfVxuICB9XG4gIHJldHVybiBvO1xufVxuXG4vKipcbiAqIEluaXRpYWxpemVzIHRyYW5zcG9ydCB0byB1c2UgYW5kIHN0YXJ0cyBwcm9iZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuU29ja2V0LnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdHJhbnNwb3J0O1xuICBpZiAodGhpcy5yZW1lbWJlclVwZ3JhZGUgJiYgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyAmJiB0aGlzLnRyYW5zcG9ydHMuaW5kZXhPZignd2Vic29ja2V0JykgIT09IC0xKSB7XG4gICAgdHJhbnNwb3J0ID0gJ3dlYnNvY2tldCc7XG4gIH0gZWxzZSBpZiAoMCA9PT0gdGhpcy50cmFuc3BvcnRzLmxlbmd0aCkge1xuICAgIC8vIEVtaXQgZXJyb3Igb24gbmV4dCB0aWNrIHNvIGl0IGNhbiBiZSBsaXN0ZW5lZCB0b1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCAnTm8gdHJhbnNwb3J0cyBhdmFpbGFibGUnKTtcbiAgICB9LCAwKTtcbiAgICByZXR1cm47XG4gIH0gZWxzZSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy50cmFuc3BvcnRzWzBdO1xuICB9XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcblxuICAvLyBSZXRyeSB3aXRoIHRoZSBuZXh0IHRyYW5zcG9ydCBpZiB0aGUgdHJhbnNwb3J0IGlzIGRpc2FibGVkIChqc29ucDogZmFsc2UpXG4gIHRyeSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy5jcmVhdGVUcmFuc3BvcnQodHJhbnNwb3J0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRoaXMudHJhbnNwb3J0cy5zaGlmdCgpO1xuICAgIHRoaXMub3BlbigpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyYW5zcG9ydC5vcGVuKCk7XG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGN1cnJlbnQgdHJhbnNwb3J0LiBEaXNhYmxlcyB0aGUgZXhpc3Rpbmcgb25lIChpZiBhbnkpLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24gKHRyYW5zcG9ydCkge1xuICBkZWJ1Zygnc2V0dGluZyB0cmFuc3BvcnQgJXMnLCB0cmFuc3BvcnQubmFtZSk7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAodGhpcy50cmFuc3BvcnQpIHtcbiAgICBkZWJ1ZygnY2xlYXJpbmcgZXhpc3RpbmcgdHJhbnNwb3J0ICVzJywgdGhpcy50cmFuc3BvcnQubmFtZSk7XG4gICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gIH1cblxuICAvLyBzZXQgdXAgdHJhbnNwb3J0XG4gIHRoaXMudHJhbnNwb3J0ID0gdHJhbnNwb3J0O1xuXG4gIC8vIHNldCB1cCB0cmFuc3BvcnQgbGlzdGVuZXJzXG4gIHRyYW5zcG9ydFxuICAub24oJ2RyYWluJywgZnVuY3Rpb24gKCkge1xuICAgIHNlbGYub25EcmFpbigpO1xuICB9KVxuICAub24oJ3BhY2tldCcsIGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgICBzZWxmLm9uUGFja2V0KHBhY2tldCk7XG4gIH0pXG4gIC5vbignZXJyb3InLCBmdW5jdGlvbiAoZSkge1xuICAgIHNlbGYub25FcnJvcihlKTtcbiAgfSlcbiAgLm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtcbiAgICBzZWxmLm9uQ2xvc2UoJ3RyYW5zcG9ydCBjbG9zZScpO1xuICB9KTtcbn07XG5cbi8qKlxuICogUHJvYmVzIGEgdHJhbnNwb3J0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0cmFuc3BvcnQgbmFtZVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5wcm9iZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlYnVnKCdwcm9iaW5nIHRyYW5zcG9ydCBcIiVzXCInLCBuYW1lKTtcbiAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuY3JlYXRlVHJhbnNwb3J0KG5hbWUsIHsgcHJvYmU6IDEgfSk7XG4gIHZhciBmYWlsZWQgPSBmYWxzZTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIFNvY2tldC5wcmlvcldlYnNvY2tldFN1Y2Nlc3MgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBvblRyYW5zcG9ydE9wZW4gKCkge1xuICAgIGlmIChzZWxmLm9ubHlCaW5hcnlVcGdyYWRlcykge1xuICAgICAgdmFyIHVwZ3JhZGVMb3Nlc0JpbmFyeSA9ICF0aGlzLnN1cHBvcnRzQmluYXJ5ICYmIHNlbGYudHJhbnNwb3J0LnN1cHBvcnRzQmluYXJ5O1xuICAgICAgZmFpbGVkID0gZmFpbGVkIHx8IHVwZ3JhZGVMb3Nlc0JpbmFyeTtcbiAgICB9XG4gICAgaWYgKGZhaWxlZCkgcmV0dXJuO1xuXG4gICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgb3BlbmVkJywgbmFtZSk7XG4gICAgdHJhbnNwb3J0LnNlbmQoW3sgdHlwZTogJ3BpbmcnLCBkYXRhOiAncHJvYmUnIH1dKTtcbiAgICB0cmFuc3BvcnQub25jZSgncGFja2V0JywgZnVuY3Rpb24gKG1zZykge1xuICAgICAgaWYgKGZhaWxlZCkgcmV0dXJuO1xuICAgICAgaWYgKCdwb25nJyA9PT0gbXNnLnR5cGUgJiYgJ3Byb2JlJyA9PT0gbXNnLmRhdGEpIHtcbiAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgcG9uZycsIG5hbWUpO1xuICAgICAgICBzZWxmLnVwZ3JhZGluZyA9IHRydWU7XG4gICAgICAgIHNlbGYuZW1pdCgndXBncmFkaW5nJywgdHJhbnNwb3J0KTtcbiAgICAgICAgaWYgKCF0cmFuc3BvcnQpIHJldHVybjtcbiAgICAgICAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9ICd3ZWJzb2NrZXQnID09PSB0cmFuc3BvcnQubmFtZTtcblxuICAgICAgICBkZWJ1ZygncGF1c2luZyBjdXJyZW50IHRyYW5zcG9ydCBcIiVzXCInLCBzZWxmLnRyYW5zcG9ydC5uYW1lKTtcbiAgICAgICAgc2VsZi50cmFuc3BvcnQucGF1c2UoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmIChmYWlsZWQpIHJldHVybjtcbiAgICAgICAgICBpZiAoJ2Nsb3NlZCcgPT09IHNlbGYucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICAgIGRlYnVnKCdjaGFuZ2luZyB0cmFuc3BvcnQgYW5kIHNlbmRpbmcgdXBncmFkZSBwYWNrZXQnKTtcblxuICAgICAgICAgIGNsZWFudXAoKTtcblxuICAgICAgICAgIHNlbGYuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG4gICAgICAgICAgdHJhbnNwb3J0LnNlbmQoW3sgdHlwZTogJ3VwZ3JhZGUnIH1dKTtcbiAgICAgICAgICBzZWxmLmVtaXQoJ3VwZ3JhZGUnLCB0cmFuc3BvcnQpO1xuICAgICAgICAgIHRyYW5zcG9ydCA9IG51bGw7XG4gICAgICAgICAgc2VsZi51cGdyYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLmZsdXNoKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgZmFpbGVkJywgbmFtZSk7XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3Byb2JlIGVycm9yJyk7XG4gICAgICAgIGVyci50cmFuc3BvcnQgPSB0cmFuc3BvcnQubmFtZTtcbiAgICAgICAgc2VsZi5lbWl0KCd1cGdyYWRlRXJyb3InLCBlcnIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZnJlZXplVHJhbnNwb3J0ICgpIHtcbiAgICBpZiAoZmFpbGVkKSByZXR1cm47XG5cbiAgICAvLyBBbnkgY2FsbGJhY2sgY2FsbGVkIGJ5IHRyYW5zcG9ydCBzaG91bGQgYmUgaWdub3JlZCBzaW5jZSBub3dcbiAgICBmYWlsZWQgPSB0cnVlO1xuXG4gICAgY2xlYW51cCgpO1xuXG4gICAgdHJhbnNwb3J0LmNsb3NlKCk7XG4gICAgdHJhbnNwb3J0ID0gbnVsbDtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhbnkgZXJyb3IgdGhhdCBoYXBwZW5zIHdoaWxlIHByb2JpbmdcbiAgZnVuY3Rpb24gb25lcnJvciAoZXJyKSB7XG4gICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdwcm9iZSBlcnJvcjogJyArIGVycik7XG4gICAgZXJyb3IudHJhbnNwb3J0ID0gdHJhbnNwb3J0Lm5hbWU7XG5cbiAgICBmcmVlemVUcmFuc3BvcnQoKTtcblxuICAgIGRlYnVnKCdwcm9iZSB0cmFuc3BvcnQgXCIlc1wiIGZhaWxlZCBiZWNhdXNlIG9mIGVycm9yOiAlcycsIG5hbWUsIGVycik7XG5cbiAgICBzZWxmLmVtaXQoJ3VwZ3JhZGVFcnJvcicsIGVycm9yKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVHJhbnNwb3J0Q2xvc2UgKCkge1xuICAgIG9uZXJyb3IoJ3RyYW5zcG9ydCBjbG9zZWQnKTtcbiAgfVxuXG4gIC8vIFdoZW4gdGhlIHNvY2tldCBpcyBjbG9zZWQgd2hpbGUgd2UncmUgcHJvYmluZ1xuICBmdW5jdGlvbiBvbmNsb3NlICgpIHtcbiAgICBvbmVycm9yKCdzb2NrZXQgY2xvc2VkJyk7XG4gIH1cblxuICAvLyBXaGVuIHRoZSBzb2NrZXQgaXMgdXBncmFkZWQgd2hpbGUgd2UncmUgcHJvYmluZ1xuICBmdW5jdGlvbiBvbnVwZ3JhZGUgKHRvKSB7XG4gICAgaWYgKHRyYW5zcG9ydCAmJiB0by5uYW1lICE9PSB0cmFuc3BvcnQubmFtZSkge1xuICAgICAgZGVidWcoJ1wiJXNcIiB3b3JrcyAtIGFib3J0aW5nIFwiJXNcIicsIHRvLm5hbWUsIHRyYW5zcG9ydC5uYW1lKTtcbiAgICAgIGZyZWV6ZVRyYW5zcG9ydCgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIG9uIHRoZSB0cmFuc3BvcnQgYW5kIG9uIHNlbGZcbiAgZnVuY3Rpb24gY2xlYW51cCAoKSB7XG4gICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdvcGVuJywgb25UcmFuc3BvcnRPcGVuKTtcbiAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uVHJhbnNwb3J0Q2xvc2UpO1xuICAgIHNlbGYucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkaW5nJywgb251cGdyYWRlKTtcbiAgfVxuXG4gIHRyYW5zcG9ydC5vbmNlKCdvcGVuJywgb25UcmFuc3BvcnRPcGVuKTtcbiAgdHJhbnNwb3J0Lm9uY2UoJ2Vycm9yJywgb25lcnJvcik7XG4gIHRyYW5zcG9ydC5vbmNlKCdjbG9zZScsIG9uVHJhbnNwb3J0Q2xvc2UpO1xuXG4gIHRoaXMub25jZSgnY2xvc2UnLCBvbmNsb3NlKTtcbiAgdGhpcy5vbmNlKCd1cGdyYWRpbmcnLCBvbnVwZ3JhZGUpO1xuXG4gIHRyYW5zcG9ydC5vcGVuKCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aGVuIGNvbm5lY3Rpb24gaXMgZGVlbWVkIG9wZW4uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgZGVidWcoJ3NvY2tldCBvcGVuJyk7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuJztcbiAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9ICd3ZWJzb2NrZXQnID09PSB0aGlzLnRyYW5zcG9ydC5uYW1lO1xuICB0aGlzLmVtaXQoJ29wZW4nKTtcbiAgdGhpcy5mbHVzaCgpO1xuXG4gIC8vIHdlIGNoZWNrIGZvciBgcmVhZHlTdGF0ZWAgaW4gY2FzZSBhbiBgb3BlbmBcbiAgLy8gbGlzdGVuZXIgYWxyZWFkeSBjbG9zZWQgdGhlIHNvY2tldFxuICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgJiYgdGhpcy51cGdyYWRlICYmIHRoaXMudHJhbnNwb3J0LnBhdXNlKSB7XG4gICAgZGVidWcoJ3N0YXJ0aW5nIHVwZ3JhZGUgcHJvYmVzJyk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLnVwZ3JhZGVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdGhpcy5wcm9iZSh0aGlzLnVwZ3JhZGVzW2ldKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogSGFuZGxlcyBhIHBhY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uUGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICBpZiAoJ29wZW5pbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgfHxcbiAgICAgICdjbG9zaW5nJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgZGVidWcoJ3NvY2tldCByZWNlaXZlOiB0eXBlIFwiJXNcIiwgZGF0YSBcIiVzXCInLCBwYWNrZXQudHlwZSwgcGFja2V0LmRhdGEpO1xuXG4gICAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xuXG4gICAgLy8gU29ja2V0IGlzIGxpdmUgLSBhbnkgcGFja2V0IGNvdW50c1xuICAgIHRoaXMuZW1pdCgnaGVhcnRiZWF0Jyk7XG5cbiAgICBzd2l0Y2ggKHBhY2tldC50eXBlKSB7XG4gICAgICBjYXNlICdvcGVuJzpcbiAgICAgICAgdGhpcy5vbkhhbmRzaGFrZShwYXJzZWpzb24ocGFja2V0LmRhdGEpKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3BvbmcnOlxuICAgICAgICB0aGlzLnNldFBpbmcoKTtcbiAgICAgICAgdGhpcy5lbWl0KCdwb25nJyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3NlcnZlciBlcnJvcicpO1xuICAgICAgICBlcnIuY29kZSA9IHBhY2tldC5kYXRhO1xuICAgICAgICB0aGlzLm9uRXJyb3IoZXJyKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ21lc3NhZ2UnOlxuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBwYWNrZXQuZGF0YSk7XG4gICAgICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIHBhY2tldC5kYXRhKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGRlYnVnKCdwYWNrZXQgcmVjZWl2ZWQgd2l0aCBzb2NrZXQgcmVhZHlTdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGhhbmRzaGFrZSBjb21wbGV0aW9uLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBoYW5kc2hha2Ugb2JqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uSGFuZHNoYWtlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5lbWl0KCdoYW5kc2hha2UnLCBkYXRhKTtcbiAgdGhpcy5pZCA9IGRhdGEuc2lkO1xuICB0aGlzLnRyYW5zcG9ydC5xdWVyeS5zaWQgPSBkYXRhLnNpZDtcbiAgdGhpcy51cGdyYWRlcyA9IHRoaXMuZmlsdGVyVXBncmFkZXMoZGF0YS51cGdyYWRlcyk7XG4gIHRoaXMucGluZ0ludGVydmFsID0gZGF0YS5waW5nSW50ZXJ2YWw7XG4gIHRoaXMucGluZ1RpbWVvdXQgPSBkYXRhLnBpbmdUaW1lb3V0O1xuICB0aGlzLm9uT3BlbigpO1xuICAvLyBJbiBjYXNlIG9wZW4gaGFuZGxlciBjbG9zZXMgc29ja2V0XG4gIGlmICgnY2xvc2VkJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSByZXR1cm47XG4gIHRoaXMuc2V0UGluZygpO1xuXG4gIC8vIFByb2xvbmcgbGl2ZW5lc3Mgb2Ygc29ja2V0IG9uIGhlYXJ0YmVhdFxuICB0aGlzLnJlbW92ZUxpc3RlbmVyKCdoZWFydGJlYXQnLCB0aGlzLm9uSGVhcnRiZWF0KTtcbiAgdGhpcy5vbignaGVhcnRiZWF0JywgdGhpcy5vbkhlYXJ0YmVhdCk7XG59O1xuXG4vKipcbiAqIFJlc2V0cyBwaW5nIHRpbWVvdXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkhlYXJ0YmVhdCA9IGZ1bmN0aW9uICh0aW1lb3V0KSB7XG4gIGNsZWFyVGltZW91dCh0aGlzLnBpbmdUaW1lb3V0VGltZXIpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHNlbGYucGluZ1RpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGlmICgnY2xvc2VkJyA9PT0gc2VsZi5yZWFkeVN0YXRlKSByZXR1cm47XG4gICAgc2VsZi5vbkNsb3NlKCdwaW5nIHRpbWVvdXQnKTtcbiAgfSwgdGltZW91dCB8fCAoc2VsZi5waW5nSW50ZXJ2YWwgKyBzZWxmLnBpbmdUaW1lb3V0KSk7XG59O1xuXG4vKipcbiAqIFBpbmdzIHNlcnZlciBldmVyeSBgdGhpcy5waW5nSW50ZXJ2YWxgIGFuZCBleHBlY3RzIHJlc3BvbnNlXG4gKiB3aXRoaW4gYHRoaXMucGluZ1RpbWVvdXRgIG9yIGNsb3NlcyBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2V0UGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBjbGVhclRpbWVvdXQoc2VsZi5waW5nSW50ZXJ2YWxUaW1lcik7XG4gIHNlbGYucGluZ0ludGVydmFsVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JpdGluZyBwaW5nIHBhY2tldCAtIGV4cGVjdGluZyBwb25nIHdpdGhpbiAlc21zJywgc2VsZi5waW5nVGltZW91dCk7XG4gICAgc2VsZi5waW5nKCk7XG4gICAgc2VsZi5vbkhlYXJ0YmVhdChzZWxmLnBpbmdUaW1lb3V0KTtcbiAgfSwgc2VsZi5waW5nSW50ZXJ2YWwpO1xufTtcblxuLyoqXG4qIFNlbmRzIGEgcGluZyBwYWNrZXQuXG4qXG4qIEBhcGkgcHJpdmF0ZVxuKi9cblxuU29ja2V0LnByb3RvdHlwZS5waW5nID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuc2VuZFBhY2tldCgncGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBzZWxmLmVtaXQoJ3BpbmcnKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIENhbGxlZCBvbiBgZHJhaW5gIGV2ZW50XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkRyYWluID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLndyaXRlQnVmZmVyLnNwbGljZSgwLCB0aGlzLnByZXZCdWZmZXJMZW4pO1xuXG4gIC8vIHNldHRpbmcgcHJldkJ1ZmZlckxlbiA9IDAgaXMgdmVyeSBpbXBvcnRhbnRcbiAgLy8gZm9yIGV4YW1wbGUsIHdoZW4gdXBncmFkaW5nLCB1cGdyYWRlIHBhY2tldCBpcyBzZW50IG92ZXIsXG4gIC8vIGFuZCBhIG5vbnplcm8gcHJldkJ1ZmZlckxlbiBjb3VsZCBjYXVzZSBwcm9ibGVtcyBvbiBgZHJhaW5gXG4gIHRoaXMucHJldkJ1ZmZlckxlbiA9IDA7XG5cbiAgaWYgKDAgPT09IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgdGhpcy5lbWl0KCdkcmFpbicpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuZmx1c2goKTtcbiAgfVxufTtcblxuLyoqXG4gKiBGbHVzaCB3cml0ZSBidWZmZXJzLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnY2xvc2VkJyAhPT0gdGhpcy5yZWFkeVN0YXRlICYmIHRoaXMudHJhbnNwb3J0LndyaXRhYmxlICYmXG4gICAgIXRoaXMudXBncmFkaW5nICYmIHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgZGVidWcoJ2ZsdXNoaW5nICVkIHBhY2tldHMgaW4gc29ja2V0JywgdGhpcy53cml0ZUJ1ZmZlci5sZW5ndGgpO1xuICAgIHRoaXMudHJhbnNwb3J0LnNlbmQodGhpcy53cml0ZUJ1ZmZlcik7XG4gICAgLy8ga2VlcCB0cmFjayBvZiBjdXJyZW50IGxlbmd0aCBvZiB3cml0ZUJ1ZmZlclxuICAgIC8vIHNwbGljZSB3cml0ZUJ1ZmZlciBhbmQgY2FsbGJhY2tCdWZmZXIgb24gYGRyYWluYFxuICAgIHRoaXMucHJldkJ1ZmZlckxlbiA9IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoO1xuICAgIHRoaXMuZW1pdCgnZmx1c2gnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZW5kcyBhIG1lc3NhZ2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQHJldHVybiB7U29ja2V0fSBmb3IgY2hhaW5pbmcuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUud3JpdGUgPVxuU29ja2V0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKG1zZywgb3B0aW9ucywgZm4pIHtcbiAgdGhpcy5zZW5kUGFja2V0KCdtZXNzYWdlJywgbXNnLCBvcHRpb25zLCBmbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZW5kcyBhIHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFja2V0IHR5cGUuXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgZnVuY3Rpb24uXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNlbmRQYWNrZXQgPSBmdW5jdGlvbiAodHlwZSwgZGF0YSwgb3B0aW9ucywgZm4pIHtcbiAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBkYXRhKSB7XG4gICAgZm4gPSBkYXRhO1xuICAgIGRhdGEgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIG9wdGlvbnMpIHtcbiAgICBmbiA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9IG51bGw7XG4gIH1cblxuICBpZiAoJ2Nsb3NpbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ2Nsb3NlZCcgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBvcHRpb25zLmNvbXByZXNzID0gZmFsc2UgIT09IG9wdGlvbnMuY29tcHJlc3M7XG5cbiAgdmFyIHBhY2tldCA9IHtcbiAgICB0eXBlOiB0eXBlLFxuICAgIGRhdGE6IGRhdGEsXG4gICAgb3B0aW9uczogb3B0aW9uc1xuICB9O1xuICB0aGlzLmVtaXQoJ3BhY2tldENyZWF0ZScsIHBhY2tldCk7XG4gIHRoaXMud3JpdGVCdWZmZXIucHVzaChwYWNrZXQpO1xuICBpZiAoZm4pIHRoaXMub25jZSgnZmx1c2gnLCBmbik7XG4gIHRoaXMuZmx1c2goKTtcbn07XG5cbi8qKlxuICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zaW5nJztcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIGlmICh0aGlzLndyaXRlQnVmZmVyLmxlbmd0aCkge1xuICAgICAgdGhpcy5vbmNlKCdkcmFpbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMudXBncmFkaW5nKSB7XG4gICAgICAgICAgd2FpdEZvclVwZ3JhZGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudXBncmFkaW5nKSB7XG4gICAgICB3YWl0Rm9yVXBncmFkZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNsb3NlICgpIHtcbiAgICBzZWxmLm9uQ2xvc2UoJ2ZvcmNlZCBjbG9zZScpO1xuICAgIGRlYnVnKCdzb2NrZXQgY2xvc2luZyAtIHRlbGxpbmcgdHJhbnNwb3J0IHRvIGNsb3NlJyk7XG4gICAgc2VsZi50cmFuc3BvcnQuY2xvc2UoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsZWFudXBBbmRDbG9zZSAoKSB7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkZScsIGNsZWFudXBBbmRDbG9zZSk7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkZUVycm9yJywgY2xlYW51cEFuZENsb3NlKTtcbiAgICBjbG9zZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gd2FpdEZvclVwZ3JhZGUgKCkge1xuICAgIC8vIHdhaXQgZm9yIHVwZ3JhZGUgdG8gZmluaXNoIHNpbmNlIHdlIGNhbid0IHNlbmQgcGFja2V0cyB3aGlsZSBwYXVzaW5nIGEgdHJhbnNwb3J0XG4gICAgc2VsZi5vbmNlKCd1cGdyYWRlJywgY2xlYW51cEFuZENsb3NlKTtcbiAgICBzZWxmLm9uY2UoJ3VwZ3JhZGVFcnJvcicsIGNsZWFudXBBbmRDbG9zZSk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IGVycm9yXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKGVycikge1xuICBkZWJ1Zygnc29ja2V0IGVycm9yICVqJywgZXJyKTtcbiAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5vbkNsb3NlKCd0cmFuc3BvcnQgZXJyb3InLCBlcnIpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiB0cmFuc3BvcnQgY2xvc2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbiwgZGVzYykge1xuICBpZiAoJ29wZW5pbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ2Nsb3NpbmcnID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICBkZWJ1Zygnc29ja2V0IGNsb3NlIHdpdGggcmVhc29uOiBcIiVzXCInLCByZWFzb24pO1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIC8vIGNsZWFyIHRpbWVyc1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnBpbmdJbnRlcnZhbFRpbWVyKTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nVGltZW91dFRpbWVyKTtcblxuICAgIC8vIHN0b3AgZXZlbnQgZnJvbSBmaXJpbmcgYWdhaW4gZm9yIHRyYW5zcG9ydFxuICAgIHRoaXMudHJhbnNwb3J0LnJlbW92ZUFsbExpc3RlbmVycygnY2xvc2UnKTtcblxuICAgIC8vIGVuc3VyZSB0cmFuc3BvcnQgd29uJ3Qgc3RheSBvcGVuXG4gICAgdGhpcy50cmFuc3BvcnQuY2xvc2UoKTtcblxuICAgIC8vIGlnbm9yZSBmdXJ0aGVyIHRyYW5zcG9ydCBjb21tdW5pY2F0aW9uXG4gICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG5cbiAgICAvLyBzZXQgcmVhZHkgc3RhdGVcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcblxuICAgIC8vIGNsZWFyIHNlc3Npb24gaWRcbiAgICB0aGlzLmlkID0gbnVsbDtcblxuICAgIC8vIGVtaXQgY2xvc2UgZXZlbnRcbiAgICB0aGlzLmVtaXQoJ2Nsb3NlJywgcmVhc29uLCBkZXNjKTtcblxuICAgIC8vIGNsZWFuIGJ1ZmZlcnMgYWZ0ZXIsIHNvIHVzZXJzIGNhbiBzdGlsbFxuICAgIC8vIGdyYWIgdGhlIGJ1ZmZlcnMgb24gYGNsb3NlYCBldmVudFxuICAgIHNlbGYud3JpdGVCdWZmZXIgPSBbXTtcbiAgICBzZWxmLnByZXZCdWZmZXJMZW4gPSAwO1xuICB9XG59O1xuXG4vKipcbiAqIEZpbHRlcnMgdXBncmFkZXMsIHJldHVybmluZyBvbmx5IHRob3NlIG1hdGNoaW5nIGNsaWVudCB0cmFuc3BvcnRzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHNlcnZlciB1cGdyYWRlc1xuICogQGFwaSBwcml2YXRlXG4gKlxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZmlsdGVyVXBncmFkZXMgPSBmdW5jdGlvbiAodXBncmFkZXMpIHtcbiAgdmFyIGZpbHRlcmVkVXBncmFkZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGogPSB1cGdyYWRlcy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcbiAgICBpZiAofmluZGV4KHRoaXMudHJhbnNwb3J0cywgdXBncmFkZXNbaV0pKSBmaWx0ZXJlZFVwZ3JhZGVzLnB1c2godXBncmFkZXNbaV0pO1xuICB9XG4gIHJldHVybiBmaWx0ZXJlZFVwZ3JhZGVzO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0112\n")},"0352":function(module,exports,__webpack_require__){eval('// https://crossfilter.github.io/crossfilter/ v1.5.4 Copyright 2020 Mike Bostock\n!function(r,e){ true?module.exports=e():undefined}(this,(function(){"use strict";let r=o,e=o,n=o,t=f,u=i;function o(r){for(var e=new Array(r),n=-1;++n<r;)e[n]=0;return e}function f(r,e){for(var n=r.length;n<e;)r[n++]=0;return r}function i(r,e){if(e>32)throw new Error("invalid array width!");return r}function a(e){this.length=e,this.subarrays=1,this.width=8,this.masks={0:0},this[0]=r(e)}"undefined"!=typeof Uint8Array&&(r=function(r){return new Uint8Array(r)},e=function(r){return new Uint16Array(r)},n=function(r){return new Uint32Array(r)},t=function(r,e){if(r.length>=e)return r;var n=new r.constructor(e);return n.set(r),n},u=function(r,t){var u;switch(t){case 16:u=e(r.length);break;case 32:u=n(r.length);break;default:throw new Error("invalid array width!")}return u.set(r),u}),a.prototype.lengthen=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)this[e]=t(this[e],r);this.length=r},a.prototype.add=function(){var e,n,t,o,f;for(o=0,f=this.subarrays;o<f;++o)if(t=(~(e=this.masks[o])&e+1)>>>0,!((n=this.width-32*o)>=32)||t)return n<32&&t&1<<n&&(this[o]=u(this[o],n<<=1),this.width=32*o+n),this.masks[o]|=t,{offset:o,one:t};return this[this.subarrays]=r(this.length),this.masks[this.subarrays]=1,this.width+=8,{offset:this.subarrays++,one:1}},a.prototype.copy=function(r,e){var n,t;for(n=0,t=this.subarrays;n<t;++n)this[n][r]=this[n][e]},a.prototype.truncate=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)for(var t=this.length-1;t>=r;t--)this[e][t]=0;this.length=r},a.prototype.zero=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)if(this[e][r])return!1;return!0},a.prototype.zeroExcept=function(r,e,n){var t,u;for(t=0,u=this.subarrays;t<u;++t)if(t===e?this[t][r]&n:this[t][r])return!1;return!0},a.prototype.zeroExceptMask=function(r,e){var n,t;for(n=0,t=this.subarrays;n<t;++n)if(this[n][r]&e[n])return!1;return!0},a.prototype.only=function(r,e,n){var t,u;for(t=0,u=this.subarrays;t<u;++t)if(this[t][r]!=(t===e?n:0))return!1;return!0},a.prototype.onlyExcept=function(r,e,n,t,u){var o,f,i;for(f=0,i=this.subarrays;f<i;++f)if(o=this[f][r],f===e&&(o=(o&n)>>>0),o!=(f===t?u:0))return!1;return!0};var l={array8:o,array16:o,array32:o,arrayLengthen:f,arrayWiden:i,bitarray:a};var s={filterExact:(r,e)=>(function(n){var t=n.length;return[r.left(n,e,0,t),r.right(n,e,0,t)]}),filterRange:(r,e)=>{var n=e[0],t=e[1];return function(e){var u=e.length;return[r.left(e,n,0,u),r.left(e,t,0,u)]}},filterAll:r=>[0,r.length]},c=r=>r,h=()=>null,v=()=>0;function p(r){function e(r,e,t){for(var u=t-e,o=1+(u>>>1);--o>0;)n(r,o,u,e);return r}function n(e,n,t,u){for(var o,f=e[--u+n],i=r(f);(o=n<<1)<=t&&(o<t&&r(e[u+o])>r(e[u+o+1])&&o++,!(i<=r(e[u+o])));)e[u+n]=e[u+o],n=o;e[u+n]=f}return e.sort=function(r,e,t){for(var u,o=t-e;--o>0;)u=r[e],r[e]=r[e+o],r[e+o]=u,n(r,1,o,e);return r},e}const d=p(c);function g(r){var e=d.by(r);return function(n,t,u,o){var f,i,a,l=new Array(o=Math.min(u-t,o));for(i=0;i<o;++i)l[i]=n[t++];if(e(l,0,o),t<u){f=r(l[0]);do{r(a=n[t])>f&&(l[0]=a,f=r(e(l,0,o)[0]))}while(++t<u)}return l}}d.by=p;const y=g(c);function x(r){function e(e,n,t,u){for(;t<u;){var o=t+u>>>1;n<r(e[o])?u=o:t=o+1}return t}return e.right=e,e.left=function(e,n,t,u){for(;t<u;){var o=t+u>>>1;r(e[o])<n?t=o+1:u=o}return t},e}y.by=g;const b=x(c);b.by=x;var m=(r,e,n)=>{for(var t=0,u=e.length,o=n?JSON.parse(JSON.stringify(r)):new Array(u);t<u;++t)o[t]=r[e[t]];return o};var E={reduceIncrement:r=>r+1,reduceDecrement:r=>r-1,reduceAdd:r=>(function(e,n){return e+ +r(n)}),reduceSubtract:r=>(function(e,n){return e-r(n)})};const w=(r,e)=>{const n=r[e];return"function"==typeof n?n.call(r):n},A=/\\[([\\w\\d]+)\\]/g;var z=(r,e)=>(function(r,e,n,t,u){for(u in t=(n=n.split(".")).splice(-1,1),n)e=e[n[u]]=e[n[u]]||{};return r(e,t)})(w,r,e.replace(A,".$1")),k=-1;function O(){var r,e={add:a,remove:function(e){for(var o=new Array(t),i=[],a="function"==typeof e,l=0,s=0;l<t;++l)c=l,(a?e(n[c],c):r.zero(c))?(i.push(l),o[l]=k):o[l]=s++;var c;u.forEach((function(r){r(-1,-1,[],i,!0)})),f.forEach((function(r){r(o)}));for(var h=0,v=0;h<t;++h)o[h]!==k&&(h!==v&&(r.copy(v,h),n[v]=n[h]),++v);n.length=t=v,r.truncate(v),g("dataRemoved")},dimension:function(e,i){if("string"==typeof e){var a=e;e=function(r){return z(r,a)}}var p,x,w,A,O,F,N,R,U,D,I,L,W,J,j={filter:function(r){return null==r?er():Array.isArray(r)?rr(r):"function"==typeof r?nr(r):_(r)},filterExact:_,filterRange:rr,filterFunction:nr,filterAll:er,currentFilter:function(){return L},hasCurrentFilter:function(){return W},top:function(e,t){var u,o=[],f=P,a=0;t&&t>0&&(a=t);for(;--f>=K&&e>0;)r.zero(u=F[f])&&(a>0?--a:(o.push(n[u]),--e));if(i)for(f=0;f<$.length&&e>0;f++)r.zero(u=$[f])&&(a>0?--a:(o.push(n[u]),--e));return o},bottom:function(e,t){var u,o,f=[],a=0;t&&t>0&&(a=t);if(i)for(u=0;u<$.length&&e>0;u++)r.zero(o=$[u])&&(a>0?--a:(f.push(n[o]),--e));u=K;for(;u<P&&e>0;)r.zero(o=F[u])&&(a>0?--a:(f.push(n[o]),--e)),u++;return f},group:ur,groupAll:function(){var r=ur(h),e=r.all;return delete r.all,delete r.top,delete r.order,delete r.orderNatural,delete r.size,r.value=function(){return e()[0].value},r},dispose:or,remove:or,accessor:e,id:function(){return A}},$=[],q=function(r){return S(r).sort((function(r,e){var n=N[r],t=N[e];return n<t?-1:n>t?1:r-e}))},B=s.filterAll,G=[],H=[],K=0,P=0,Q=0;o.unshift(V),o.push(X),f.push(Y);var T=r.add();function V(n,u,o){var f,a;if(i){Q=0,G=0,J=[];for(var s=0;s<n.length;s++)for(G=0,J=e(n[s]);G<J.length;G++)Q++;N=[],f=S(n.length),a=M(Q,1);for(var c=S(Q),h=0,v=0;v<n.length;v++)if((J=e(n[v])).length)for(f[v]=J.length,G=0;G<J.length;G++)N.push(J[G]),c[h]=v,h++;else f[v]=0,$.push(v+u);var d=q(Q);N=m(N,d),R=m(c,d)}else N=n.map(e),R=q(o),N=m(N,R);var g,y,x,b=B(N),E=b[0],A=b[1];if(i)if(o=Q,I)for(g=0;g<o;++g)I(N[g],g)||(0==--f[R[g]]&&(r[w][R[g]+u]|=p),a[g]=1);else{for(y=0;y<E;++y)0==--f[R[y]]&&(r[w][R[y]+u]|=p),a[y]=1;for(x=A;x<o;++x)0==--f[R[x]]&&(r[w][R[x]+u]|=p),a[x]=1}else if(I)for(g=0;g<o;++g)I(N[g],g)||(r[w][R[g]+u]|=p);else{for(y=0;y<E;++y)r[w][R[y]+u]|=p;for(x=A;x<o;++x)r[w][R[x]+u]|=p}if(!u)return O=N,F=R,U=f,D=a,K=E,void(P=A);var z,k=O,C=F,L=D,W=0;if(s=0,i&&(z=u,u=k.length,o=Q),O=new Array(i?u+o:t),F=i?new Array(u+o):M(t,t),i&&(D=M(u+o,1)),i){var j=U.length;U=l.arrayLengthen(U,t);for(var G=0;G+j<t;G++)U[G+j]=f[G]}for(var H=0;s<u&&W<o;++H)k[s]<N[W]?(O[H]=k[s],i&&(D[H]=L[s]),F[H]=C[s++]):(O[H]=N[W],i&&(D[H]=a[W]),F[H]=R[W++]+(i?z:u));for(;s<u;++s,++H)O[H]=k[s],i&&(D[H]=L[s]),F[H]=C[s];for(;W<o;++W,++H)O[H]=N[W],i&&(D[H]=a[W]),F[H]=R[W]+(i?z:u);b=B(O),K=b[0],P=b[1]}function X(r,e,n){G.forEach((function(r){r(N,R,e,n)})),N=R=null}function Y(r){if(i){for(var e=0,n=0;e<$.length;e++)r[$[e]]!==k&&($[n]=r[$[e]],n++);for($.length=n,e=0,n=0;e<t;e++)r[e]!==k&&(n!==e&&(U[n]=U[e]),n++);U=U.slice(0,n)}for(var u,o=O.length,f=0,a=0;f<o;++f)r[u=F[f]]!==k&&(f!==a&&(O[a]=O[f]),F[a]=r[u],i&&(D[a]=D[f]),++a);for(O.length=a,i&&(D=D.slice(0,a));a<o;)F[a++]=0;var l=B(O);K=l[0],P=l[1]}function Z(e){var n=e[0],t=e[1];if(I)return I=null,tr((function(r,e){return n<=e&&e<t}),0===e[0]&&e[1]===O.length),K=n,P=t,j;var o,f,a,l=[],c=[],h=[],v=[];if(n<K)for(o=n,f=Math.min(K,t);o<f;++o)l.push(F[o]),h.push(o);else if(n>K)for(o=K,f=Math.min(n,P);o<f;++o)c.push(F[o]),v.push(o);if(t>P)for(o=Math.max(n,P),f=t;o<f;++o)l.push(F[o]),h.push(o);else if(t<P)for(o=Math.max(K,t),f=P;o<f;++o)c.push(F[o]),v.push(o);if(i){var d=[],y=[];for(o=0;o<l.length;o++)U[l[o]]++,D[h[o]]=0,1===U[l[o]]&&(r[w][l[o]]^=p,d.push(l[o]));for(o=0;o<c.length;o++)U[c[o]]--,D[v[o]]=1,0===U[c[o]]&&(r[w][c[o]]^=p,y.push(c[o]));if(l=d,c=y,B===s.filterAll)for(o=0;o<$.length;o++)r[w][a=$[o]]&p&&(r[w][a]^=p,l.push(a));else for(o=0;o<$.length;o++)r[w][a=$[o]]&p||(r[w][a]^=p,c.push(a))}else{for(o=0;o<l.length;o++)r[w][l[o]]^=p;for(o=0;o<c.length;o++)r[w][c[o]]^=p}return K=n,P=t,u.forEach((function(r){r(p,w,l,c)})),g("filtered"),j}function _(r){return L=r,W=!0,Z((B=s.filterExact(b,r))(O))}function rr(r){return L=r,W=!0,Z((B=s.filterRange(b,r))(O))}function er(){return L=void 0,W=!1,Z((B=s.filterAll)(O))}function nr(r){L=r,W=!0,I=r,B=s.filterAll,tr(r,!1);var e=B(O);return K=e[0],P=e[1],j}function tr(e,n){var t,o,f,a=[],l=[],s=[],c=[],h=O.length;if(!i)for(t=0;t<h;++t)!(r[w][o=F[t]]&p)^!!(f=e(O[t],t))&&(f?a.push(o):l.push(o));if(i)for(t=0;t<h;++t)e(O[t],t)?(a.push(F[t]),s.push(t)):(l.push(F[t]),c.push(t));if(i){var v=[],d=[];for(t=0;t<a.length;t++)1===D[s[t]]&&(U[a[t]]++,D[s[t]]=0,1===U[a[t]]&&(r[w][a[t]]^=p,v.push(a[t])));for(t=0;t<l.length;t++)0===D[c[t]]&&(U[l[t]]--,D[c[t]]=1,0===U[l[t]]&&(r[w][l[t]]^=p,d.push(l[t])));if(a=v,l=d,n)for(t=0;t<$.length;t++)r[w][o=$[t]]&p&&(r[w][o]^=p,a.push(o));else for(t=0;t<$.length;t++)r[w][o=$[t]]&p||(r[w][o]^=p,l.push(o))}else{for(t=0;t<a.length;t++)r[w][a[t]]&p&&(r[w][a[t]]&=x);for(t=0;t<l.length;t++)r[w][l[t]]&p||(r[w][l[t]]|=p)}u.forEach((function(r){r(p,w,a,l)})),g("filtered")}function ur(e){var o={top:function(r){var e=g(P(),0,a.length,r);return b.sort(e,0,e.length)},all:P,reduce:Q,reduceCount:T,reduceSum:function(r){return Q(E.reduceAdd(r),E.reduceSubtract(r),v)},order:V,orderNatural:function(){return V(c)},size:function(){return U},dispose:X,remove:X};H.push(o);var a,s,g,b,m,A,z,S,N=8,R=C(N),U=0,D=h,I=h,L=!0,W=e===h;function J(o,f,c,v){i&&(S=c,c=O.length-o.length,v=o.length);var p,d,g,y,b,E,k=a,F=i?[]:M(U,R),J=m,j=A,G=z,H=U,P=0,Q=0;for(L&&(J=G=h),L&&(j=G=h),a=new Array(U),U=0,s=i?H?s:[]:H>1?l.arrayLengthen(s,t):M(t,R),H&&(g=(d=k[0]).key);Q<v&&!((y=e(o[Q]))>=y);)++Q;for(;Q<v;){for(d&&g<=y?(b=d,E=g,F[P]=U,(d=k[++P])&&(g=d.key)):(b={key:y,value:G()},E=y),a[U]=b;y<=E&&(p=f[Q]+(i?S:c),i?s[p]?s[p].push(U):s[p]=[U]:s[p]=U,b.value=J(b.value,n[p],!0),r.zeroExcept(p,w,x)||(b.value=j(b.value,n[p],!1)),!(++Q>=v));)y=e(o[Q]);V()}for(;P<H;)a[F[P]=U]=k[P++],V();if(i)for(var T=0;T<t;T++)s[T]||(s[T]=[]);if(U>P)if(i)for(P=0;P<S;++P)for(T=0;T<s[P].length;T++)s[P][T]=F[s[P][T]];else for(P=0;P<c;++P)s[P]=F[s[P]];function V(){i?U++:++U===R&&(F=l.arrayWiden(F,N<<=1),s=l.arrayWiden(s,N),R=C(N))}p=u.indexOf(D),U>1||i?(D=$,I=B):(!U&&W&&(U=1,a=[{key:null,value:G()}]),1===U?(D=q,I=K):(D=h,I=h),s=null),u[p]=D}function j(r){if(U>1||i){var e,n,o,f=U,l=a,c=M(f,f);if(i){for(e=0,o=0;e<t;++e)if(r[e]!==k){for(s[o]=s[e],n=0;n<s[o].length;n++)c[s[o][n]]=1;++o}s=s.slice(0,o)}else for(e=0,o=0;e<t;++e)r[e]!==k&&(c[s[o]=s[e]]=1,++o);for(a=[],U=0,e=0;e<f;++e)c[e]&&(c[e]=U++,a.push(l[e]));if(U>1||i)if(i)for(e=0;e<o;++e)for(n=0;n<s[e].length;++n)s[e][n]=c[s[e][n]];else for(e=0;e<o;++e)s[e]=c[s[e]];else s=null;u[u.indexOf(D)]=U>1||i?(I=B,D=$):1===U?(I=K,D=q):I=D=h}else if(1===U){if(W)return;for(var v=0;v<t;++v)if(r[v]!==k)return;a=[],U=0,u[u.indexOf(D)]=D=I=h}}function $(e,t,u,o,f){var l,c,h,v,d;if(!(e===p&&t===w||L))if(i){for(l=0,v=u.length;l<v;++l)if(r.zeroExcept(h=u[l],w,x))for(c=0;c<s[h].length;c++)(d=a[s[h][c]]).value=m(d.value,n[h],!1,c);for(l=0,v=o.length;l<v;++l)if(r.onlyExcept(h=o[l],w,x,t,e))for(c=0;c<s[h].length;c++)(d=a[s[h][c]]).value=A(d.value,n[h],f,c)}else{for(l=0,v=u.length;l<v;++l)r.zeroExcept(h=u[l],w,x)&&((d=a[s[h]]).value=m(d.value,n[h],!1));for(l=0,v=o.length;l<v;++l)r.onlyExcept(h=o[l],w,x,t,e)&&((d=a[s[h]]).value=A(d.value,n[h],f))}}function q(e,t,u,o,f){if(!(e===p&&t===w||L)){var i,l,s,c=a[0];for(i=0,s=u.length;i<s;++i)r.zeroExcept(l=u[i],w,x)&&(c.value=m(c.value,n[l],!1));for(i=0,s=o.length;i<s;++i)r.onlyExcept(l=o[i],w,x,t,e)&&(c.value=A(c.value,n[l],f))}}function B(){var e,u,o;for(e=0;e<U;++e)a[e].value=z();if(i){for(e=0;e<t;++e)for(u=0;u<s[e].length;u++)(o=a[s[e][u]]).value=m(o.value,n[e],!0,u);for(e=0;e<t;++e)if(!r.zeroExcept(e,w,x))for(u=0;u<s[e].length;u++)(o=a[s[e][u]]).value=A(o.value,n[e],!1,u)}else{for(e=0;e<t;++e)(o=a[s[e]]).value=m(o.value,n[e],!0);for(e=0;e<t;++e)r.zeroExcept(e,w,x)||((o=a[s[e]]).value=A(o.value,n[e],!1))}}function K(){var e,u=a[0];for(u.value=z(),e=0;e<t;++e)u.value=m(u.value,n[e],!0);for(e=0;e<t;++e)r.zeroExcept(e,w,x)||(u.value=A(u.value,n[e],!1))}function P(){return L&&(I(),L=!1),a}function Q(r,e,n){return m=r,A=e,z=n,L=!0,o}function T(){return Q(E.reduceIncrement,E.reduceDecrement,v)}function V(r){function e(e){return r(e.value)}return g=y.by(e),b=d.by(e),o}function X(){var r=u.indexOf(D);return r>=0&&u.splice(r,1),(r=G.indexOf(J))>=0&&G.splice(r,1),(r=f.indexOf(j))>=0&&f.splice(r,1),(r=H.indexOf(o))>=0&&H.splice(r,1),o}return arguments.length<1&&(e=c),u.push(D),G.push(J),f.push(j),J(O,F,0,t),T().orderNatural()}function or(){H.forEach((function(r){r.dispose()}));var e=o.indexOf(V);return e>=0&&o.splice(e,1),(e=o.indexOf(X))>=0&&o.splice(e,1),(e=f.indexOf(Y))>=0&&f.splice(e,1),r.masks[w]&=x,er()}return w=T.offset,p=T.one,x=~p,A=w<<7|Math.log(p)/Math.log(2),V(n,0,t),X(n,0,t),j},groupAll:function(){var e,f,i,a,l={reduce:p,reduceCount:d,reduceSum:function(r){return p(E.reduceAdd(r),E.reduceSubtract(r),v)},value:function(){s&&(function(){var u;for(e=a(),u=0;u<t;++u)e=f(e,n[u],!0),r.zero(u)||(e=i(e,n[u],!1))}(),s=!1);return e},dispose:g,remove:g},s=!0;function c(u,o){var a;if(!s)for(a=o;a<t;++a)e=f(e,n[a],!0),r.zero(a)||(e=i(e,n[a],!1))}function h(t,u,o,a,l){var c,h,v;if(!s){for(c=0,v=o.length;c<v;++c)r.zero(h=o[c])&&(e=f(e,n[h],l));for(c=0,v=a.length;c<v;++c)r.only(h=a[c],u,t)&&(e=i(e,n[h],l))}}function p(r,e,n){return f=r,i=e,a=n,s=!0,l}function d(){return p(E.reduceIncrement,E.reduceDecrement,v)}function g(){var r=u.indexOf(h);return r>=0&&u.splice(r,1),(r=o.indexOf(c))>=0&&o.splice(r,1),l}return(u.push(h),o.push(c),c(n,0),d())},size:function(){return t},all:function(){return n},allFiltered:function(e){var u=[],o=0,f=p(e||[]);for(o=0;o<t;o++)r.zeroExceptMask(o,f)&&u.push(n[o]);return u},onChange:function(r){if("function"!=typeof r)return void console.warn("onChange callback parameter must be a function!");return i.push(r),function(){i.splice(i.indexOf(r),1)}},isElementFiltered:function(e,n){var t=p(n||[]);return r.zeroExceptMask(e,t)}},n=[],t=0,u=[],o=[],f=[],i=[];function a(u){var f=t,i=u.length;return i&&(n=n.concat(u),r.lengthen(t+=i),o.forEach((function(r){r(u,f,i)})),g("dataAdded")),e}function p(e){var n,t,u,o,f=Array(r.subarrays);for(n=0;n<r.subarrays;n++)f[n]=-1;for(t=0,u=e.length;t<u;t++)f[(o=e[t].id())>>7]&=~(1<<(63&o));return f}function g(r){for(var e=0;e<i.length;e++)i[e](r)}return r=new l.bitarray(0),arguments.length?a(arguments[0]):e}function M(r,e){return(e<257?l.array8:e<65537?l.array16:l.array32)(r)}function S(r){for(var e=M(r,r),n=-1;++n<r;)e[n]=n;return e}function C(r){return 8===r?256:16===r?65536:4294967296}O.heap=d,O.heapselect=y,O.bisect=b,O.permute=m;return O.version="1.5.4",O}));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDM1Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvY3Jvc3NmaWx0ZXIyL2Nyb3NzZmlsdGVyLm1pbi5qcz82ZTBjIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIGh0dHBzOi8vY3Jvc3NmaWx0ZXIuZ2l0aHViLmlvL2Nyb3NzZmlsdGVyLyB2MS41LjQgQ29weXJpZ2h0IDIwMjAgTWlrZSBCb3N0b2NrXG4hZnVuY3Rpb24ocixlKXtcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1lKCk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShlKToocj1yfHxzZWxmKS5jcm9zc2ZpbHRlcj1lKCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7bGV0IHI9byxlPW8sbj1vLHQ9Zix1PWk7ZnVuY3Rpb24gbyhyKXtmb3IodmFyIGU9bmV3IEFycmF5KHIpLG49LTE7KytuPHI7KWVbbl09MDtyZXR1cm4gZX1mdW5jdGlvbiBmKHIsZSl7Zm9yKHZhciBuPXIubGVuZ3RoO248ZTspcltuKytdPTA7cmV0dXJuIHJ9ZnVuY3Rpb24gaShyLGUpe2lmKGU+MzIpdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBhcnJheSB3aWR0aCFcIik7cmV0dXJuIHJ9ZnVuY3Rpb24gYShlKXt0aGlzLmxlbmd0aD1lLHRoaXMuc3ViYXJyYXlzPTEsdGhpcy53aWR0aD04LHRoaXMubWFza3M9ezA6MH0sdGhpc1swXT1yKGUpfVwidW5kZWZpbmVkXCIhPXR5cGVvZiBVaW50OEFycmF5JiYocj1mdW5jdGlvbihyKXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkocil9LGU9ZnVuY3Rpb24ocil7cmV0dXJuIG5ldyBVaW50MTZBcnJheShyKX0sbj1mdW5jdGlvbihyKXtyZXR1cm4gbmV3IFVpbnQzMkFycmF5KHIpfSx0PWZ1bmN0aW9uKHIsZSl7aWYoci5sZW5ndGg+PWUpcmV0dXJuIHI7dmFyIG49bmV3IHIuY29uc3RydWN0b3IoZSk7cmV0dXJuIG4uc2V0KHIpLG59LHU9ZnVuY3Rpb24ocix0KXt2YXIgdTtzd2l0Y2godCl7Y2FzZSAxNjp1PWUoci5sZW5ndGgpO2JyZWFrO2Nhc2UgMzI6dT1uKHIubGVuZ3RoKTticmVhaztkZWZhdWx0OnRocm93IG5ldyBFcnJvcihcImludmFsaWQgYXJyYXkgd2lkdGghXCIpfXJldHVybiB1LnNldChyKSx1fSksYS5wcm90b3R5cGUubGVuZ3RoZW49ZnVuY3Rpb24ocil7dmFyIGUsbjtmb3IoZT0wLG49dGhpcy5zdWJhcnJheXM7ZTxuOysrZSl0aGlzW2VdPXQodGhpc1tlXSxyKTt0aGlzLmxlbmd0aD1yfSxhLnByb3RvdHlwZS5hZGQ9ZnVuY3Rpb24oKXt2YXIgZSxuLHQsbyxmO2ZvcihvPTAsZj10aGlzLnN1YmFycmF5cztvPGY7KytvKWlmKHQ9KH4oZT10aGlzLm1hc2tzW29dKSZlKzEpPj4+MCwhKChuPXRoaXMud2lkdGgtMzIqbyk+PTMyKXx8dClyZXR1cm4gbjwzMiYmdCYxPDxuJiYodGhpc1tvXT11KHRoaXNbb10sbjw8PTEpLHRoaXMud2lkdGg9MzIqbytuKSx0aGlzLm1hc2tzW29dfD10LHtvZmZzZXQ6byxvbmU6dH07cmV0dXJuIHRoaXNbdGhpcy5zdWJhcnJheXNdPXIodGhpcy5sZW5ndGgpLHRoaXMubWFza3NbdGhpcy5zdWJhcnJheXNdPTEsdGhpcy53aWR0aCs9OCx7b2Zmc2V0OnRoaXMuc3ViYXJyYXlzKyssb25lOjF9fSxhLnByb3RvdHlwZS5jb3B5PWZ1bmN0aW9uKHIsZSl7dmFyIG4sdDtmb3Iobj0wLHQ9dGhpcy5zdWJhcnJheXM7bjx0Oysrbil0aGlzW25dW3JdPXRoaXNbbl1bZV19LGEucHJvdG90eXBlLnRydW5jYXRlPWZ1bmN0aW9uKHIpe3ZhciBlLG47Zm9yKGU9MCxuPXRoaXMuc3ViYXJyYXlzO2U8bjsrK2UpZm9yKHZhciB0PXRoaXMubGVuZ3RoLTE7dD49cjt0LS0pdGhpc1tlXVt0XT0wO3RoaXMubGVuZ3RoPXJ9LGEucHJvdG90eXBlLnplcm89ZnVuY3Rpb24ocil7dmFyIGUsbjtmb3IoZT0wLG49dGhpcy5zdWJhcnJheXM7ZTxuOysrZSlpZih0aGlzW2VdW3JdKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS56ZXJvRXhjZXB0PWZ1bmN0aW9uKHIsZSxuKXt2YXIgdCx1O2Zvcih0PTAsdT10aGlzLnN1YmFycmF5czt0PHU7Kyt0KWlmKHQ9PT1lP3RoaXNbdF1bcl0mbjp0aGlzW3RdW3JdKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS56ZXJvRXhjZXB0TWFzaz1mdW5jdGlvbihyLGUpe3ZhciBuLHQ7Zm9yKG49MCx0PXRoaXMuc3ViYXJyYXlzO248dDsrK24paWYodGhpc1tuXVtyXSZlW25dKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS5vbmx5PWZ1bmN0aW9uKHIsZSxuKXt2YXIgdCx1O2Zvcih0PTAsdT10aGlzLnN1YmFycmF5czt0PHU7Kyt0KWlmKHRoaXNbdF1bcl0hPSh0PT09ZT9uOjApKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS5vbmx5RXhjZXB0PWZ1bmN0aW9uKHIsZSxuLHQsdSl7dmFyIG8sZixpO2ZvcihmPTAsaT10aGlzLnN1YmFycmF5cztmPGk7KytmKWlmKG89dGhpc1tmXVtyXSxmPT09ZSYmKG89KG8mbik+Pj4wKSxvIT0oZj09PXQ/dTowKSlyZXR1cm4hMTtyZXR1cm4hMH07dmFyIGw9e2FycmF5ODpvLGFycmF5MTY6byxhcnJheTMyOm8sYXJyYXlMZW5ndGhlbjpmLGFycmF5V2lkZW46aSxiaXRhcnJheTphfTt2YXIgcz17ZmlsdGVyRXhhY3Q6KHIsZSk9PihmdW5jdGlvbihuKXt2YXIgdD1uLmxlbmd0aDtyZXR1cm5bci5sZWZ0KG4sZSwwLHQpLHIucmlnaHQobixlLDAsdCldfSksZmlsdGVyUmFuZ2U6KHIsZSk9Pnt2YXIgbj1lWzBdLHQ9ZVsxXTtyZXR1cm4gZnVuY3Rpb24oZSl7dmFyIHU9ZS5sZW5ndGg7cmV0dXJuW3IubGVmdChlLG4sMCx1KSxyLmxlZnQoZSx0LDAsdSldfX0sZmlsdGVyQWxsOnI9PlswLHIubGVuZ3RoXX0sYz1yPT5yLGg9KCk9Pm51bGwsdj0oKT0+MDtmdW5jdGlvbiBwKHIpe2Z1bmN0aW9uIGUocixlLHQpe2Zvcih2YXIgdT10LWUsbz0xKyh1Pj4+MSk7LS1vPjA7KW4ocixvLHUsZSk7cmV0dXJuIHJ9ZnVuY3Rpb24gbihlLG4sdCx1KXtmb3IodmFyIG8sZj1lWy0tdStuXSxpPXIoZik7KG89bjw8MSk8PXQmJihvPHQmJnIoZVt1K29dKT5yKGVbdStvKzFdKSYmbysrLCEoaTw9cihlW3Urb10pKSk7KWVbdStuXT1lW3Urb10sbj1vO2VbdStuXT1mfXJldHVybiBlLnNvcnQ9ZnVuY3Rpb24ocixlLHQpe2Zvcih2YXIgdSxvPXQtZTstLW8+MDspdT1yW2VdLHJbZV09cltlK29dLHJbZStvXT11LG4ociwxLG8sZSk7cmV0dXJuIHJ9LGV9Y29uc3QgZD1wKGMpO2Z1bmN0aW9uIGcocil7dmFyIGU9ZC5ieShyKTtyZXR1cm4gZnVuY3Rpb24obix0LHUsbyl7dmFyIGYsaSxhLGw9bmV3IEFycmF5KG89TWF0aC5taW4odS10LG8pKTtmb3IoaT0wO2k8bzsrK2kpbFtpXT1uW3QrK107aWYoZShsLDAsbyksdDx1KXtmPXIobFswXSk7ZG97cihhPW5bdF0pPmYmJihsWzBdPWEsZj1yKGUobCwwLG8pWzBdKSl9d2hpbGUoKyt0PHUpfXJldHVybiBsfX1kLmJ5PXA7Y29uc3QgeT1nKGMpO2Z1bmN0aW9uIHgocil7ZnVuY3Rpb24gZShlLG4sdCx1KXtmb3IoO3Q8dTspe3ZhciBvPXQrdT4+PjE7bjxyKGVbb10pP3U9bzp0PW8rMX1yZXR1cm4gdH1yZXR1cm4gZS5yaWdodD1lLGUubGVmdD1mdW5jdGlvbihlLG4sdCx1KXtmb3IoO3Q8dTspe3ZhciBvPXQrdT4+PjE7cihlW29dKTxuP3Q9bysxOnU9b31yZXR1cm4gdH0sZX15LmJ5PWc7Y29uc3QgYj14KGMpO2IuYnk9eDt2YXIgbT0ocixlLG4pPT57Zm9yKHZhciB0PTAsdT1lLmxlbmd0aCxvPW4/SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyKSk6bmV3IEFycmF5KHUpO3Q8dTsrK3Qpb1t0XT1yW2VbdF1dO3JldHVybiBvfTt2YXIgRT17cmVkdWNlSW5jcmVtZW50OnI9PnIrMSxyZWR1Y2VEZWNyZW1lbnQ6cj0+ci0xLHJlZHVjZUFkZDpyPT4oZnVuY3Rpb24oZSxuKXtyZXR1cm4gZSsgK3Iobil9KSxyZWR1Y2VTdWJ0cmFjdDpyPT4oZnVuY3Rpb24oZSxuKXtyZXR1cm4gZS1yKG4pfSl9O2NvbnN0IHc9KHIsZSk9Pntjb25zdCBuPXJbZV07cmV0dXJuXCJmdW5jdGlvblwiPT10eXBlb2Ygbj9uLmNhbGwocik6bn0sQT0vXFxbKFtcXHdcXGRdKylcXF0vZzt2YXIgej0ocixlKT0+KGZ1bmN0aW9uKHIsZSxuLHQsdSl7Zm9yKHUgaW4gdD0obj1uLnNwbGl0KFwiLlwiKSkuc3BsaWNlKC0xLDEpLG4pZT1lW25bdV1dPWVbblt1XV18fHt9O3JldHVybiByKGUsdCl9KSh3LHIsZS5yZXBsYWNlKEEsXCIuJDFcIikpLGs9LTE7ZnVuY3Rpb24gTygpe3ZhciByLGU9e2FkZDphLHJlbW92ZTpmdW5jdGlvbihlKXtmb3IodmFyIG89bmV3IEFycmF5KHQpLGk9W10sYT1cImZ1bmN0aW9uXCI9PXR5cGVvZiBlLGw9MCxzPTA7bDx0OysrbCljPWwsKGE/ZShuW2NdLGMpOnIuemVybyhjKSk/KGkucHVzaChsKSxvW2xdPWspOm9bbF09cysrO3ZhciBjO3UuZm9yRWFjaCgoZnVuY3Rpb24ocil7cigtMSwtMSxbXSxpLCEwKX0pKSxmLmZvckVhY2goKGZ1bmN0aW9uKHIpe3Iobyl9KSk7Zm9yKHZhciBoPTAsdj0wO2g8dDsrK2gpb1toXSE9PWsmJihoIT09diYmKHIuY29weSh2LGgpLG5bdl09bltoXSksKyt2KTtuLmxlbmd0aD10PXYsci50cnVuY2F0ZSh2KSxnKFwiZGF0YVJlbW92ZWRcIil9LGRpbWVuc2lvbjpmdW5jdGlvbihlLGkpe2lmKFwic3RyaW5nXCI9PXR5cGVvZiBlKXt2YXIgYT1lO2U9ZnVuY3Rpb24ocil7cmV0dXJuIHoocixhKX19dmFyIHAseCx3LEEsTyxGLE4sUixVLEQsSSxMLFcsSixqPXtmaWx0ZXI6ZnVuY3Rpb24ocil7cmV0dXJuIG51bGw9PXI/ZXIoKTpBcnJheS5pc0FycmF5KHIpP3JyKHIpOlwiZnVuY3Rpb25cIj09dHlwZW9mIHI/bnIocik6XyhyKX0sZmlsdGVyRXhhY3Q6XyxmaWx0ZXJSYW5nZTpycixmaWx0ZXJGdW5jdGlvbjpucixmaWx0ZXJBbGw6ZXIsY3VycmVudEZpbHRlcjpmdW5jdGlvbigpe3JldHVybiBMfSxoYXNDdXJyZW50RmlsdGVyOmZ1bmN0aW9uKCl7cmV0dXJuIFd9LHRvcDpmdW5jdGlvbihlLHQpe3ZhciB1LG89W10sZj1QLGE9MDt0JiZ0PjAmJihhPXQpO2Zvcig7LS1mPj1LJiZlPjA7KXIuemVybyh1PUZbZl0pJiYoYT4wPy0tYTooby5wdXNoKG5bdV0pLC0tZSkpO2lmKGkpZm9yKGY9MDtmPCQubGVuZ3RoJiZlPjA7ZisrKXIuemVybyh1PSRbZl0pJiYoYT4wPy0tYTooby5wdXNoKG5bdV0pLC0tZSkpO3JldHVybiBvfSxib3R0b206ZnVuY3Rpb24oZSx0KXt2YXIgdSxvLGY9W10sYT0wO3QmJnQ+MCYmKGE9dCk7aWYoaSlmb3IodT0wO3U8JC5sZW5ndGgmJmU+MDt1Kyspci56ZXJvKG89JFt1XSkmJihhPjA/LS1hOihmLnB1c2gobltvXSksLS1lKSk7dT1LO2Zvcig7dTxQJiZlPjA7KXIuemVybyhvPUZbdV0pJiYoYT4wPy0tYTooZi5wdXNoKG5bb10pLC0tZSkpLHUrKztyZXR1cm4gZn0sZ3JvdXA6dXIsZ3JvdXBBbGw6ZnVuY3Rpb24oKXt2YXIgcj11cihoKSxlPXIuYWxsO3JldHVybiBkZWxldGUgci5hbGwsZGVsZXRlIHIudG9wLGRlbGV0ZSByLm9yZGVyLGRlbGV0ZSByLm9yZGVyTmF0dXJhbCxkZWxldGUgci5zaXplLHIudmFsdWU9ZnVuY3Rpb24oKXtyZXR1cm4gZSgpWzBdLnZhbHVlfSxyfSxkaXNwb3NlOm9yLHJlbW92ZTpvcixhY2Nlc3NvcjplLGlkOmZ1bmN0aW9uKCl7cmV0dXJuIEF9fSwkPVtdLHE9ZnVuY3Rpb24ocil7cmV0dXJuIFMocikuc29ydCgoZnVuY3Rpb24ocixlKXt2YXIgbj1OW3JdLHQ9TltlXTtyZXR1cm4gbjx0Py0xOm4+dD8xOnItZX0pKX0sQj1zLmZpbHRlckFsbCxHPVtdLEg9W10sSz0wLFA9MCxRPTA7by51bnNoaWZ0KFYpLG8ucHVzaChYKSxmLnB1c2goWSk7dmFyIFQ9ci5hZGQoKTtmdW5jdGlvbiBWKG4sdSxvKXt2YXIgZixhO2lmKGkpe1E9MCxHPTAsSj1bXTtmb3IodmFyIHM9MDtzPG4ubGVuZ3RoO3MrKylmb3IoRz0wLEo9ZShuW3NdKTtHPEoubGVuZ3RoO0crKylRKys7Tj1bXSxmPVMobi5sZW5ndGgpLGE9TShRLDEpO2Zvcih2YXIgYz1TKFEpLGg9MCx2PTA7djxuLmxlbmd0aDt2KyspaWYoKEo9ZShuW3ZdKSkubGVuZ3RoKWZvcihmW3ZdPUoubGVuZ3RoLEc9MDtHPEoubGVuZ3RoO0crKylOLnB1c2goSltHXSksY1toXT12LGgrKztlbHNlIGZbdl09MCwkLnB1c2godit1KTt2YXIgZD1xKFEpO049bShOLGQpLFI9bShjLGQpfWVsc2UgTj1uLm1hcChlKSxSPXEobyksTj1tKE4sUik7dmFyIGcseSx4LGI9QihOKSxFPWJbMF0sQT1iWzFdO2lmKGkpaWYobz1RLEkpZm9yKGc9MDtnPG87KytnKUkoTltnXSxnKXx8KDA9PS0tZltSW2ddXSYmKHJbd11bUltnXSt1XXw9cCksYVtnXT0xKTtlbHNle2Zvcih5PTA7eTxFOysreSkwPT0tLWZbUlt5XV0mJihyW3ddW1JbeV0rdV18PXApLGFbeV09MTtmb3IoeD1BO3g8bzsrK3gpMD09LS1mW1JbeF1dJiYoclt3XVtSW3hdK3VdfD1wKSxhW3hdPTF9ZWxzZSBpZihJKWZvcihnPTA7ZzxvOysrZylJKE5bZ10sZyl8fChyW3ddW1JbZ10rdV18PXApO2Vsc2V7Zm9yKHk9MDt5PEU7Kyt5KXJbd11bUlt5XSt1XXw9cDtmb3IoeD1BO3g8bzsrK3gpclt3XVtSW3hdK3VdfD1wfWlmKCF1KXJldHVybiBPPU4sRj1SLFU9ZixEPWEsSz1FLHZvaWQoUD1BKTt2YXIgeixrPU8sQz1GLEw9RCxXPTA7aWYocz0wLGkmJih6PXUsdT1rLmxlbmd0aCxvPVEpLE89bmV3IEFycmF5KGk/dStvOnQpLEY9aT9uZXcgQXJyYXkodStvKTpNKHQsdCksaSYmKEQ9TSh1K28sMSkpLGkpe3ZhciBqPVUubGVuZ3RoO1U9bC5hcnJheUxlbmd0aGVuKFUsdCk7Zm9yKHZhciBHPTA7RytqPHQ7RysrKVVbRytqXT1mW0ddfWZvcih2YXIgSD0wO3M8dSYmVzxvOysrSClrW3NdPE5bV10/KE9bSF09a1tzXSxpJiYoRFtIXT1MW3NdKSxGW0hdPUNbcysrXSk6KE9bSF09TltXXSxpJiYoRFtIXT1hW1ddKSxGW0hdPVJbVysrXSsoaT96OnUpKTtmb3IoO3M8dTsrK3MsKytIKU9bSF09a1tzXSxpJiYoRFtIXT1MW3NdKSxGW0hdPUNbc107Zm9yKDtXPG87KytXLCsrSClPW0hdPU5bV10saSYmKERbSF09YVtXXSksRltIXT1SW1ddKyhpP3o6dSk7Yj1CKE8pLEs9YlswXSxQPWJbMV19ZnVuY3Rpb24gWChyLGUsbil7Ry5mb3JFYWNoKChmdW5jdGlvbihyKXtyKE4sUixlLG4pfSkpLE49Uj1udWxsfWZ1bmN0aW9uIFkocil7aWYoaSl7Zm9yKHZhciBlPTAsbj0wO2U8JC5sZW5ndGg7ZSsrKXJbJFtlXV0hPT1rJiYoJFtuXT1yWyRbZV1dLG4rKyk7Zm9yKCQubGVuZ3RoPW4sZT0wLG49MDtlPHQ7ZSsrKXJbZV0hPT1rJiYobiE9PWUmJihVW25dPVVbZV0pLG4rKyk7VT1VLnNsaWNlKDAsbil9Zm9yKHZhciB1LG89Ty5sZW5ndGgsZj0wLGE9MDtmPG87KytmKXJbdT1GW2ZdXSE9PWsmJihmIT09YSYmKE9bYV09T1tmXSksRlthXT1yW3VdLGkmJihEW2FdPURbZl0pLCsrYSk7Zm9yKE8ubGVuZ3RoPWEsaSYmKEQ9RC5zbGljZSgwLGEpKTthPG87KUZbYSsrXT0wO3ZhciBsPUIoTyk7Sz1sWzBdLFA9bFsxXX1mdW5jdGlvbiBaKGUpe3ZhciBuPWVbMF0sdD1lWzFdO2lmKEkpcmV0dXJuIEk9bnVsbCx0cigoZnVuY3Rpb24ocixlKXtyZXR1cm4gbjw9ZSYmZTx0fSksMD09PWVbMF0mJmVbMV09PT1PLmxlbmd0aCksSz1uLFA9dCxqO3ZhciBvLGYsYSxsPVtdLGM9W10saD1bXSx2PVtdO2lmKG48Sylmb3Iobz1uLGY9TWF0aC5taW4oSyx0KTtvPGY7KytvKWwucHVzaChGW29dKSxoLnB1c2gobyk7ZWxzZSBpZihuPkspZm9yKG89SyxmPU1hdGgubWluKG4sUCk7bzxmOysrbyljLnB1c2goRltvXSksdi5wdXNoKG8pO2lmKHQ+UClmb3Iobz1NYXRoLm1heChuLFApLGY9dDtvPGY7KytvKWwucHVzaChGW29dKSxoLnB1c2gobyk7ZWxzZSBpZih0PFApZm9yKG89TWF0aC5tYXgoSyx0KSxmPVA7bzxmOysrbyljLnB1c2goRltvXSksdi5wdXNoKG8pO2lmKGkpe3ZhciBkPVtdLHk9W107Zm9yKG89MDtvPGwubGVuZ3RoO28rKylVW2xbb11dKyssRFtoW29dXT0wLDE9PT1VW2xbb11dJiYoclt3XVtsW29dXV49cCxkLnB1c2gobFtvXSkpO2ZvcihvPTA7bzxjLmxlbmd0aDtvKyspVVtjW29dXS0tLERbdltvXV09MSwwPT09VVtjW29dXSYmKHJbd11bY1tvXV1ePXAseS5wdXNoKGNbb10pKTtpZihsPWQsYz15LEI9PT1zLmZpbHRlckFsbClmb3Iobz0wO288JC5sZW5ndGg7bysrKXJbd11bYT0kW29dXSZwJiYoclt3XVthXV49cCxsLnB1c2goYSkpO2Vsc2UgZm9yKG89MDtvPCQubGVuZ3RoO28rKylyW3ddW2E9JFtvXV0mcHx8KHJbd11bYV1ePXAsYy5wdXNoKGEpKX1lbHNle2ZvcihvPTA7bzxsLmxlbmd0aDtvKyspclt3XVtsW29dXV49cDtmb3Iobz0wO288Yy5sZW5ndGg7bysrKXJbd11bY1tvXV1ePXB9cmV0dXJuIEs9bixQPXQsdS5mb3JFYWNoKChmdW5jdGlvbihyKXtyKHAsdyxsLGMpfSkpLGcoXCJmaWx0ZXJlZFwiKSxqfWZ1bmN0aW9uIF8ocil7cmV0dXJuIEw9cixXPSEwLFooKEI9cy5maWx0ZXJFeGFjdChiLHIpKShPKSl9ZnVuY3Rpb24gcnIocil7cmV0dXJuIEw9cixXPSEwLFooKEI9cy5maWx0ZXJSYW5nZShiLHIpKShPKSl9ZnVuY3Rpb24gZXIoKXtyZXR1cm4gTD12b2lkIDAsVz0hMSxaKChCPXMuZmlsdGVyQWxsKShPKSl9ZnVuY3Rpb24gbnIocil7TD1yLFc9ITAsST1yLEI9cy5maWx0ZXJBbGwsdHIociwhMSk7dmFyIGU9QihPKTtyZXR1cm4gSz1lWzBdLFA9ZVsxXSxqfWZ1bmN0aW9uIHRyKGUsbil7dmFyIHQsbyxmLGE9W10sbD1bXSxzPVtdLGM9W10saD1PLmxlbmd0aDtpZighaSlmb3IodD0wO3Q8aDsrK3QpIShyW3ddW289Rlt0XV0mcCleISEoZj1lKE9bdF0sdCkpJiYoZj9hLnB1c2gobyk6bC5wdXNoKG8pKTtpZihpKWZvcih0PTA7dDxoOysrdCllKE9bdF0sdCk/KGEucHVzaChGW3RdKSxzLnB1c2godCkpOihsLnB1c2goRlt0XSksYy5wdXNoKHQpKTtpZihpKXt2YXIgdj1bXSxkPVtdO2Zvcih0PTA7dDxhLmxlbmd0aDt0KyspMT09PURbc1t0XV0mJihVW2FbdF1dKyssRFtzW3RdXT0wLDE9PT1VW2FbdF1dJiYoclt3XVthW3RdXV49cCx2LnB1c2goYVt0XSkpKTtmb3IodD0wO3Q8bC5sZW5ndGg7dCsrKTA9PT1EW2NbdF1dJiYoVVtsW3RdXS0tLERbY1t0XV09MSwwPT09VVtsW3RdXSYmKHJbd11bbFt0XV1ePXAsZC5wdXNoKGxbdF0pKSk7aWYoYT12LGw9ZCxuKWZvcih0PTA7dDwkLmxlbmd0aDt0Kyspclt3XVtvPSRbdF1dJnAmJihyW3ddW29dXj1wLGEucHVzaChvKSk7ZWxzZSBmb3IodD0wO3Q8JC5sZW5ndGg7dCsrKXJbd11bbz0kW3RdXSZwfHwoclt3XVtvXV49cCxsLnB1c2gobykpfWVsc2V7Zm9yKHQ9MDt0PGEubGVuZ3RoO3QrKylyW3ddW2FbdF1dJnAmJihyW3ddW2FbdF1dJj14KTtmb3IodD0wO3Q8bC5sZW5ndGg7dCsrKXJbd11bbFt0XV0mcHx8KHJbd11bbFt0XV18PXApfXUuZm9yRWFjaCgoZnVuY3Rpb24ocil7cihwLHcsYSxsKX0pKSxnKFwiZmlsdGVyZWRcIil9ZnVuY3Rpb24gdXIoZSl7dmFyIG89e3RvcDpmdW5jdGlvbihyKXt2YXIgZT1nKFAoKSwwLGEubGVuZ3RoLHIpO3JldHVybiBiLnNvcnQoZSwwLGUubGVuZ3RoKX0sYWxsOlAscmVkdWNlOlEscmVkdWNlQ291bnQ6VCxyZWR1Y2VTdW06ZnVuY3Rpb24ocil7cmV0dXJuIFEoRS5yZWR1Y2VBZGQociksRS5yZWR1Y2VTdWJ0cmFjdChyKSx2KX0sb3JkZXI6VixvcmRlck5hdHVyYWw6ZnVuY3Rpb24oKXtyZXR1cm4gVihjKX0sc2l6ZTpmdW5jdGlvbigpe3JldHVybiBVfSxkaXNwb3NlOlgscmVtb3ZlOlh9O0gucHVzaChvKTt2YXIgYSxzLGcsYixtLEEseixTLE49OCxSPUMoTiksVT0wLEQ9aCxJPWgsTD0hMCxXPWU9PT1oO2Z1bmN0aW9uIEoobyxmLGMsdil7aSYmKFM9YyxjPU8ubGVuZ3RoLW8ubGVuZ3RoLHY9by5sZW5ndGgpO3ZhciBwLGQsZyx5LGIsRSxrPWEsRj1pP1tdOk0oVSxSKSxKPW0saj1BLEc9eixIPVUsUD0wLFE9MDtmb3IoTCYmKEo9Rz1oKSxMJiYoaj1HPWgpLGE9bmV3IEFycmF5KFUpLFU9MCxzPWk/SD9zOltdOkg+MT9sLmFycmF5TGVuZ3RoZW4ocyx0KTpNKHQsUiksSCYmKGc9KGQ9a1swXSkua2V5KTtRPHYmJiEoKHk9ZShvW1FdKSk+PXkpOykrK1E7Zm9yKDtRPHY7KXtmb3IoZCYmZzw9eT8oYj1kLEU9ZyxGW1BdPVUsKGQ9a1srK1BdKSYmKGc9ZC5rZXkpKTooYj17a2V5OnksdmFsdWU6RygpfSxFPXkpLGFbVV09Yjt5PD1FJiYocD1mW1FdKyhpP1M6YyksaT9zW3BdP3NbcF0ucHVzaChVKTpzW3BdPVtVXTpzW3BdPVUsYi52YWx1ZT1KKGIudmFsdWUsbltwXSwhMCksci56ZXJvRXhjZXB0KHAsdyx4KXx8KGIudmFsdWU9aihiLnZhbHVlLG5bcF0sITEpKSwhKCsrUT49dikpOyl5PWUob1tRXSk7VigpfWZvcig7UDxIOylhW0ZbUF09VV09a1tQKytdLFYoKTtpZihpKWZvcih2YXIgVD0wO1Q8dDtUKyspc1tUXXx8KHNbVF09W10pO2lmKFU+UClpZihpKWZvcihQPTA7UDxTOysrUClmb3IoVD0wO1Q8c1tQXS5sZW5ndGg7VCsrKXNbUF1bVF09RltzW1BdW1RdXTtlbHNlIGZvcihQPTA7UDxjOysrUClzW1BdPUZbc1tQXV07ZnVuY3Rpb24gVigpe2k/VSsrOisrVT09PVImJihGPWwuYXJyYXlXaWRlbihGLE48PD0xKSxzPWwuYXJyYXlXaWRlbihzLE4pLFI9QyhOKSl9cD11LmluZGV4T2YoRCksVT4xfHxpPyhEPSQsST1CKTooIVUmJlcmJihVPTEsYT1be2tleTpudWxsLHZhbHVlOkcoKX1dKSwxPT09VT8oRD1xLEk9Syk6KEQ9aCxJPWgpLHM9bnVsbCksdVtwXT1EfWZ1bmN0aW9uIGoocil7aWYoVT4xfHxpKXt2YXIgZSxuLG8sZj1VLGw9YSxjPU0oZixmKTtpZihpKXtmb3IoZT0wLG89MDtlPHQ7KytlKWlmKHJbZV0hPT1rKXtmb3Ioc1tvXT1zW2VdLG49MDtuPHNbb10ubGVuZ3RoO24rKyljW3Nbb11bbl1dPTE7KytvfXM9cy5zbGljZSgwLG8pfWVsc2UgZm9yKGU9MCxvPTA7ZTx0OysrZSlyW2VdIT09ayYmKGNbc1tvXT1zW2VdXT0xLCsrbyk7Zm9yKGE9W10sVT0wLGU9MDtlPGY7KytlKWNbZV0mJihjW2VdPVUrKyxhLnB1c2gobFtlXSkpO2lmKFU+MXx8aSlpZihpKWZvcihlPTA7ZTxvOysrZSlmb3Iobj0wO248c1tlXS5sZW5ndGg7KytuKXNbZV1bbl09Y1tzW2VdW25dXTtlbHNlIGZvcihlPTA7ZTxvOysrZSlzW2VdPWNbc1tlXV07ZWxzZSBzPW51bGw7dVt1LmluZGV4T2YoRCldPVU+MXx8aT8oST1CLEQ9JCk6MT09PVU/KEk9SyxEPXEpOkk9RD1ofWVsc2UgaWYoMT09PVUpe2lmKFcpcmV0dXJuO2Zvcih2YXIgdj0wO3Y8dDsrK3YpaWYoclt2XSE9PWspcmV0dXJuO2E9W10sVT0wLHVbdS5pbmRleE9mKEQpXT1EPUk9aH19ZnVuY3Rpb24gJChlLHQsdSxvLGYpe3ZhciBsLGMsaCx2LGQ7aWYoIShlPT09cCYmdD09PXd8fEwpKWlmKGkpe2ZvcihsPTAsdj11Lmxlbmd0aDtsPHY7KytsKWlmKHIuemVyb0V4Y2VwdChoPXVbbF0sdyx4KSlmb3IoYz0wO2M8c1toXS5sZW5ndGg7YysrKShkPWFbc1toXVtjXV0pLnZhbHVlPW0oZC52YWx1ZSxuW2hdLCExLGMpO2ZvcihsPTAsdj1vLmxlbmd0aDtsPHY7KytsKWlmKHIub25seUV4Y2VwdChoPW9bbF0sdyx4LHQsZSkpZm9yKGM9MDtjPHNbaF0ubGVuZ3RoO2MrKykoZD1hW3NbaF1bY11dKS52YWx1ZT1BKGQudmFsdWUsbltoXSxmLGMpfWVsc2V7Zm9yKGw9MCx2PXUubGVuZ3RoO2w8djsrK2wpci56ZXJvRXhjZXB0KGg9dVtsXSx3LHgpJiYoKGQ9YVtzW2hdXSkudmFsdWU9bShkLnZhbHVlLG5baF0sITEpKTtmb3IobD0wLHY9by5sZW5ndGg7bDx2OysrbClyLm9ubHlFeGNlcHQoaD1vW2xdLHcseCx0LGUpJiYoKGQ9YVtzW2hdXSkudmFsdWU9QShkLnZhbHVlLG5baF0sZikpfX1mdW5jdGlvbiBxKGUsdCx1LG8sZil7aWYoIShlPT09cCYmdD09PXd8fEwpKXt2YXIgaSxsLHMsYz1hWzBdO2ZvcihpPTAscz11Lmxlbmd0aDtpPHM7KytpKXIuemVyb0V4Y2VwdChsPXVbaV0sdyx4KSYmKGMudmFsdWU9bShjLnZhbHVlLG5bbF0sITEpKTtmb3IoaT0wLHM9by5sZW5ndGg7aTxzOysraSlyLm9ubHlFeGNlcHQobD1vW2ldLHcseCx0LGUpJiYoYy52YWx1ZT1BKGMudmFsdWUsbltsXSxmKSl9fWZ1bmN0aW9uIEIoKXt2YXIgZSx1LG87Zm9yKGU9MDtlPFU7KytlKWFbZV0udmFsdWU9eigpO2lmKGkpe2ZvcihlPTA7ZTx0OysrZSlmb3IodT0wO3U8c1tlXS5sZW5ndGg7dSsrKShvPWFbc1tlXVt1XV0pLnZhbHVlPW0oby52YWx1ZSxuW2VdLCEwLHUpO2ZvcihlPTA7ZTx0OysrZSlpZighci56ZXJvRXhjZXB0KGUsdyx4KSlmb3IodT0wO3U8c1tlXS5sZW5ndGg7dSsrKShvPWFbc1tlXVt1XV0pLnZhbHVlPUEoby52YWx1ZSxuW2VdLCExLHUpfWVsc2V7Zm9yKGU9MDtlPHQ7KytlKShvPWFbc1tlXV0pLnZhbHVlPW0oby52YWx1ZSxuW2VdLCEwKTtmb3IoZT0wO2U8dDsrK2Upci56ZXJvRXhjZXB0KGUsdyx4KXx8KChvPWFbc1tlXV0pLnZhbHVlPUEoby52YWx1ZSxuW2VdLCExKSl9fWZ1bmN0aW9uIEsoKXt2YXIgZSx1PWFbMF07Zm9yKHUudmFsdWU9eigpLGU9MDtlPHQ7KytlKXUudmFsdWU9bSh1LnZhbHVlLG5bZV0sITApO2ZvcihlPTA7ZTx0OysrZSlyLnplcm9FeGNlcHQoZSx3LHgpfHwodS52YWx1ZT1BKHUudmFsdWUsbltlXSwhMSkpfWZ1bmN0aW9uIFAoKXtyZXR1cm4gTCYmKEkoKSxMPSExKSxhfWZ1bmN0aW9uIFEocixlLG4pe3JldHVybiBtPXIsQT1lLHo9bixMPSEwLG99ZnVuY3Rpb24gVCgpe3JldHVybiBRKEUucmVkdWNlSW5jcmVtZW50LEUucmVkdWNlRGVjcmVtZW50LHYpfWZ1bmN0aW9uIFYocil7ZnVuY3Rpb24gZShlKXtyZXR1cm4gcihlLnZhbHVlKX1yZXR1cm4gZz15LmJ5KGUpLGI9ZC5ieShlKSxvfWZ1bmN0aW9uIFgoKXt2YXIgcj11LmluZGV4T2YoRCk7cmV0dXJuIHI+PTAmJnUuc3BsaWNlKHIsMSksKHI9Ry5pbmRleE9mKEopKT49MCYmRy5zcGxpY2UociwxKSwocj1mLmluZGV4T2YoaikpPj0wJiZmLnNwbGljZShyLDEpLChyPUguaW5kZXhPZihvKSk+PTAmJkguc3BsaWNlKHIsMSksb31yZXR1cm4gYXJndW1lbnRzLmxlbmd0aDwxJiYoZT1jKSx1LnB1c2goRCksRy5wdXNoKEopLGYucHVzaChqKSxKKE8sRiwwLHQpLFQoKS5vcmRlck5hdHVyYWwoKX1mdW5jdGlvbiBvcigpe0guZm9yRWFjaCgoZnVuY3Rpb24ocil7ci5kaXNwb3NlKCl9KSk7dmFyIGU9by5pbmRleE9mKFYpO3JldHVybiBlPj0wJiZvLnNwbGljZShlLDEpLChlPW8uaW5kZXhPZihYKSk+PTAmJm8uc3BsaWNlKGUsMSksKGU9Zi5pbmRleE9mKFkpKT49MCYmZi5zcGxpY2UoZSwxKSxyLm1hc2tzW3ddJj14LGVyKCl9cmV0dXJuIHc9VC5vZmZzZXQscD1ULm9uZSx4PX5wLEE9dzw8N3xNYXRoLmxvZyhwKS9NYXRoLmxvZygyKSxWKG4sMCx0KSxYKG4sMCx0KSxqfSxncm91cEFsbDpmdW5jdGlvbigpe3ZhciBlLGYsaSxhLGw9e3JlZHVjZTpwLHJlZHVjZUNvdW50OmQscmVkdWNlU3VtOmZ1bmN0aW9uKHIpe3JldHVybiBwKEUucmVkdWNlQWRkKHIpLEUucmVkdWNlU3VidHJhY3Qociksdil9LHZhbHVlOmZ1bmN0aW9uKCl7cyYmKGZ1bmN0aW9uKCl7dmFyIHU7Zm9yKGU9YSgpLHU9MDt1PHQ7Kyt1KWU9ZihlLG5bdV0sITApLHIuemVybyh1KXx8KGU9aShlLG5bdV0sITEpKX0oKSxzPSExKTtyZXR1cm4gZX0sZGlzcG9zZTpnLHJlbW92ZTpnfSxzPSEwO2Z1bmN0aW9uIGModSxvKXt2YXIgYTtpZighcylmb3IoYT1vO2E8dDsrK2EpZT1mKGUsblthXSwhMCksci56ZXJvKGEpfHwoZT1pKGUsblthXSwhMSkpfWZ1bmN0aW9uIGgodCx1LG8sYSxsKXt2YXIgYyxoLHY7aWYoIXMpe2ZvcihjPTAsdj1vLmxlbmd0aDtjPHY7KytjKXIuemVybyhoPW9bY10pJiYoZT1mKGUsbltoXSxsKSk7Zm9yKGM9MCx2PWEubGVuZ3RoO2M8djsrK2Mpci5vbmx5KGg9YVtjXSx1LHQpJiYoZT1pKGUsbltoXSxsKSl9fWZ1bmN0aW9uIHAocixlLG4pe3JldHVybiBmPXIsaT1lLGE9bixzPSEwLGx9ZnVuY3Rpb24gZCgpe3JldHVybiBwKEUucmVkdWNlSW5jcmVtZW50LEUucmVkdWNlRGVjcmVtZW50LHYpfWZ1bmN0aW9uIGcoKXt2YXIgcj11LmluZGV4T2YoaCk7cmV0dXJuIHI+PTAmJnUuc3BsaWNlKHIsMSksKHI9by5pbmRleE9mKGMpKT49MCYmby5zcGxpY2UociwxKSxsfXJldHVybih1LnB1c2goaCksby5wdXNoKGMpLGMobiwwKSxkKCkpfSxzaXplOmZ1bmN0aW9uKCl7cmV0dXJuIHR9LGFsbDpmdW5jdGlvbigpe3JldHVybiBufSxhbGxGaWx0ZXJlZDpmdW5jdGlvbihlKXt2YXIgdT1bXSxvPTAsZj1wKGV8fFtdKTtmb3Iobz0wO288dDtvKyspci56ZXJvRXhjZXB0TWFzayhvLGYpJiZ1LnB1c2gobltvXSk7cmV0dXJuIHV9LG9uQ2hhbmdlOmZ1bmN0aW9uKHIpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHIpcmV0dXJuIHZvaWQgY29uc29sZS53YXJuKFwib25DaGFuZ2UgY2FsbGJhY2sgcGFyYW1ldGVyIG11c3QgYmUgYSBmdW5jdGlvbiFcIik7cmV0dXJuIGkucHVzaChyKSxmdW5jdGlvbigpe2kuc3BsaWNlKGkuaW5kZXhPZihyKSwxKX19LGlzRWxlbWVudEZpbHRlcmVkOmZ1bmN0aW9uKGUsbil7dmFyIHQ9cChufHxbXSk7cmV0dXJuIHIuemVyb0V4Y2VwdE1hc2soZSx0KX19LG49W10sdD0wLHU9W10sbz1bXSxmPVtdLGk9W107ZnVuY3Rpb24gYSh1KXt2YXIgZj10LGk9dS5sZW5ndGg7cmV0dXJuIGkmJihuPW4uY29uY2F0KHUpLHIubGVuZ3RoZW4odCs9aSksby5mb3JFYWNoKChmdW5jdGlvbihyKXtyKHUsZixpKX0pKSxnKFwiZGF0YUFkZGVkXCIpKSxlfWZ1bmN0aW9uIHAoZSl7dmFyIG4sdCx1LG8sZj1BcnJheShyLnN1YmFycmF5cyk7Zm9yKG49MDtuPHIuc3ViYXJyYXlzO24rKylmW25dPS0xO2Zvcih0PTAsdT1lLmxlbmd0aDt0PHU7dCsrKWZbKG89ZVt0XS5pZCgpKT4+N10mPX4oMTw8KDYzJm8pKTtyZXR1cm4gZn1mdW5jdGlvbiBnKHIpe2Zvcih2YXIgZT0wO2U8aS5sZW5ndGg7ZSsrKWlbZV0ocil9cmV0dXJuIHI9bmV3IGwuYml0YXJyYXkoMCksYXJndW1lbnRzLmxlbmd0aD9hKGFyZ3VtZW50c1swXSk6ZX1mdW5jdGlvbiBNKHIsZSl7cmV0dXJuKGU8MjU3P2wuYXJyYXk4OmU8NjU1Mzc/bC5hcnJheTE2OmwuYXJyYXkzMikocil9ZnVuY3Rpb24gUyhyKXtmb3IodmFyIGU9TShyLHIpLG49LTE7KytuPHI7KWVbbl09bjtyZXR1cm4gZX1mdW5jdGlvbiBDKHIpe3JldHVybiA4PT09cj8yNTY6MTY9PT1yPzY1NTM2OjQyOTQ5NjcyOTZ9Ty5oZWFwPWQsTy5oZWFwc2VsZWN0PXksTy5iaXNlY3Q9YixPLnBlcm11dGU9bTtyZXR1cm4gTy52ZXJzaW9uPVwiMS41LjRcIixPfSkpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0352\n')},"072d":function(module,exports){eval("/**\n * Server side filtering\n *\n * Implementation of a dataset backed by a server, which in turn uses fi. postgreSQL\n * Fully asynchronous, based on socketIO.\n *\n * Most methods below result in a message with the methodName and a data object, containing:\n *  * `datasets` and `dataview`, or `dataset`\n *  * `filterId` or `facetId`\n *\n * Data can be requested using the dataview.getData() method\n * responds with a `newData` message containing `filterId` and `data`.\n *\n * @module driver/server\n */\n\n/**\n * Autoconfigure a dataset\n *\n * @param {Dataset} dataset\n */\nfunction scan (dataset) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    // spot-server will not respond so no use requesting a scan\n    return;\n  }\n\n  spot.socket.emit('scanData', {\n    dataset: dataset.toJSON()\n  });\n}\n\n/**\n * setMinMax sets the range of a continuous or time facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setMinMax (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    spot.socket.emit('setMinMax', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setMinMax', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * setCategories finds finds all values on an ordinal (categorial) axis\n * Updates the categorialTransform of the facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setCategories (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  facet.categorialTransform.rules.reset();\n  if (spot.isLockedDown) {\n    spot.socket.emit('setCategories', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setCategories', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * Calculate 100 percentiles (ie. 1,2,3,4 etc.), and initialize the `facet.continuousTransform`\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setPercentiles (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    spot.socket.emit('setPercentiles', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setPercentiles', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * Initialize the data filter, and construct the getData callback function on the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction initDataFilter (dataview, filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n * related to the filter.\n * @param {Filter} filter\n */\nfunction releaseDataFilter (filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * Change the filter parameters for an initialized filter\n * @param {Filter} filter\n */\nfunction updateDataFilter (filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * Get data for every filter, and trigger a 'newData' event\n *\n * Returns a Promise that resolves to the dataview when all data and metadata has been updated\n *\n * @param {Dataview} dataview\n * @returns {Promise}\n */\nfunction getData (dataview) {\n  var spot = dataview.parent;\n\n  return new Promise(function (resolve, reject) {\n    if (spot.isLockedDown) {\n      spot.socket.emit('getData', {\n        dataview: dataview.toJSON()\n      });\n    } else {\n      spot.socket.emit('getData', {\n        datasets: spot.cachedDatasets,\n        dataview: dataview.toJSON()\n      });\n    }\n\n    dataview.once('newMetaData', function () {\n      resolve(dataview);\n    });\n  });\n}\n\nmodule.exports = {\n  driverType: 'server',\n  scan: scan,\n  setMinMax: setMinMax,\n  setCategories: setCategories,\n  setPercentiles: setPercentiles,\n  initDataFilter: initDataFilter,\n  releaseDataFilter: releaseDataFilter,\n  updateDataFilter: updateDataFilter,\n  getData: getData\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDcyZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZHJpdmVyL3NlcnZlci5qcz9lMzc3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2VydmVyIHNpZGUgZmlsdGVyaW5nXG4gKlxuICogSW1wbGVtZW50YXRpb24gb2YgYSBkYXRhc2V0IGJhY2tlZCBieSBhIHNlcnZlciwgd2hpY2ggaW4gdHVybiB1c2VzIGZpLiBwb3N0Z3JlU1FMXG4gKiBGdWxseSBhc3luY2hyb25vdXMsIGJhc2VkIG9uIHNvY2tldElPLlxuICpcbiAqIE1vc3QgbWV0aG9kcyBiZWxvdyByZXN1bHQgaW4gYSBtZXNzYWdlIHdpdGggdGhlIG1ldGhvZE5hbWUgYW5kIGEgZGF0YSBvYmplY3QsIGNvbnRhaW5pbmc6XG4gKiAgKiBgZGF0YXNldHNgIGFuZCBgZGF0YXZpZXdgLCBvciBgZGF0YXNldGBcbiAqICAqIGBmaWx0ZXJJZGAgb3IgYGZhY2V0SWRgXG4gKlxuICogRGF0YSBjYW4gYmUgcmVxdWVzdGVkIHVzaW5nIHRoZSBkYXRhdmlldy5nZXREYXRhKCkgbWV0aG9kXG4gKiByZXNwb25kcyB3aXRoIGEgYG5ld0RhdGFgIG1lc3NhZ2UgY29udGFpbmluZyBgZmlsdGVySWRgIGFuZCBgZGF0YWAuXG4gKlxuICogQG1vZHVsZSBkcml2ZXIvc2VydmVyXG4gKi9cblxuLyoqXG4gKiBBdXRvY29uZmlndXJlIGEgZGF0YXNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICovXG5mdW5jdGlvbiBzY2FuIChkYXRhc2V0KSB7XG4gIC8vIERhdGFzZXQgLT4gRGF0YXNldHMgLT4gU3BvdFxuICB2YXIgc3BvdCA9IGRhdGFzZXQuY29sbGVjdGlvbi5wYXJlbnQ7XG5cbiAgaWYgKHNwb3QuaXNMb2NrZWREb3duKSB7XG4gICAgLy8gc3BvdC1zZXJ2ZXIgd2lsbCBub3QgcmVzcG9uZCBzbyBubyB1c2UgcmVxdWVzdGluZyBhIHNjYW5cbiAgICByZXR1cm47XG4gIH1cblxuICBzcG90LnNvY2tldC5lbWl0KCdzY2FuRGF0YScsIHtcbiAgICBkYXRhc2V0OiBkYXRhc2V0LnRvSlNPTigpXG4gIH0pO1xufVxuXG4vKipcbiAqIHNldE1pbk1heCBzZXRzIHRoZSByYW5nZSBvZiBhIGNvbnRpbnVvdXMgb3IgdGltZSBmYWNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqL1xuZnVuY3Rpb24gc2V0TWluTWF4IChkYXRhc2V0LCBmYWNldCkge1xuICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgdmFyIHNwb3QgPSBkYXRhc2V0LmNvbGxlY3Rpb24ucGFyZW50O1xuXG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldE1pbk1heCcsIHtcbiAgICAgIGRhdGFzZXRJZDogZGF0YXNldC5nZXRJZCgpLFxuICAgICAgZmFjZXRJZDogZmFjZXQuZ2V0SWQoKVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldE1pbk1heCcsIHtcbiAgICAgIGRhdGFzZXRJZDogZGF0YXNldC5nZXRJZCgpLFxuICAgICAgZGF0YXNldDogZGF0YXNldC50b0pTT04oKSxcbiAgICAgIGZhY2V0SWQ6IGZhY2V0LmdldElkKClcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIHNldENhdGVnb3JpZXMgZmluZHMgZmluZHMgYWxsIHZhbHVlcyBvbiBhbiBvcmRpbmFsIChjYXRlZ29yaWFsKSBheGlzXG4gKiBVcGRhdGVzIHRoZSBjYXRlZ29yaWFsVHJhbnNmb3JtIG9mIHRoZSBmYWNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqL1xuZnVuY3Rpb24gc2V0Q2F0ZWdvcmllcyAoZGF0YXNldCwgZmFjZXQpIHtcbiAgLy8gRGF0YXNldCAtPiBEYXRhc2V0cyAtPiBTcG90XG4gIHZhciBzcG90ID0gZGF0YXNldC5jb2xsZWN0aW9uLnBhcmVudDtcblxuICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLnJlc2V0KCk7XG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldENhdGVnb3JpZXMnLCB7XG4gICAgICBkYXRhc2V0SWQ6IGRhdGFzZXQuZ2V0SWQoKSxcbiAgICAgIGZhY2V0SWQ6IGZhY2V0LmdldElkKClcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBzcG90LnNvY2tldC5lbWl0KCdzZXRDYXRlZ29yaWVzJywge1xuICAgICAgZGF0YXNldElkOiBkYXRhc2V0LmdldElkKCksXG4gICAgICBkYXRhc2V0OiBkYXRhc2V0LnRvSlNPTigpLFxuICAgICAgZmFjZXRJZDogZmFjZXQuZ2V0SWQoKVxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIDEwMCBwZXJjZW50aWxlcyAoaWUuIDEsMiwzLDQgZXRjLiksIGFuZCBpbml0aWFsaXplIHRoZSBgZmFjZXQuY29udGludW91c1RyYW5zZm9ybWBcbiAqXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXRcbiAqIEBwYXJhbSB7RmFjZXR9IGZhY2V0XG4gKi9cbmZ1bmN0aW9uIHNldFBlcmNlbnRpbGVzIChkYXRhc2V0LCBmYWNldCkge1xuICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgdmFyIHNwb3QgPSBkYXRhc2V0LmNvbGxlY3Rpb24ucGFyZW50O1xuXG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldFBlcmNlbnRpbGVzJywge1xuICAgICAgZGF0YXNldElkOiBkYXRhc2V0LmdldElkKCksXG4gICAgICBmYWNldElkOiBmYWNldC5nZXRJZCgpXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgc3BvdC5zb2NrZXQuZW1pdCgnc2V0UGVyY2VudGlsZXMnLCB7XG4gICAgICBkYXRhc2V0SWQ6IGRhdGFzZXQuZ2V0SWQoKSxcbiAgICAgIGRhdGFzZXQ6IGRhdGFzZXQudG9KU09OKCksXG4gICAgICBmYWNldElkOiBmYWNldC5nZXRJZCgpXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gaW5pdERhdGFGaWx0ZXIgKGRhdGF2aWV3LCBmaWx0ZXIpIHtcbiAgLy8gYXMgdGhlIFNRTCBzZXJ2ZXIgaW1wbGVtZW50YXRpb24gaXMgc3RhdGVsZXNzLCBub3RoaW5nIHRvIGRvIGhlcmVcbn1cblxuLyoqXG4gKiBUaGUgb3Bwb3NpdGUgb3IgaW5pdERhdGFGaWx0ZXIsIGl0IHNob3VsZCByZW1vdmUgdGhlIGZpbHRlciBhbmQgZGVhbGxvY2F0ZSBvdGhlciBjb25maWd1cmF0aW9uXG4gKiByZWxhdGVkIHRvIHRoZSBmaWx0ZXIuXG4gKiBAcGFyYW0ge0ZpbHRlcn0gZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHJlbGVhc2VEYXRhRmlsdGVyIChmaWx0ZXIpIHtcbiAgLy8gYXMgdGhlIFNRTCBzZXJ2ZXIgaW1wbGVtZW50YXRpb24gaXMgc3RhdGVsZXNzLCBub3RoaW5nIHRvIGRvIGhlcmVcbn1cblxuLyoqXG4gKiBDaGFuZ2UgdGhlIGZpbHRlciBwYXJhbWV0ZXJzIGZvciBhbiBpbml0aWFsaXplZCBmaWx0ZXJcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGF0YUZpbHRlciAoZmlsdGVyKSB7XG4gIC8vIGFzIHRoZSBTUUwgc2VydmVyIGltcGxlbWVudGF0aW9uIGlzIHN0YXRlbGVzcywgbm90aGluZyB0byBkbyBoZXJlXG59XG5cbi8qKlxuICogR2V0IGRhdGEgZm9yIGV2ZXJ5IGZpbHRlciwgYW5kIHRyaWdnZXIgYSAnbmV3RGF0YScgZXZlbnRcbiAqXG4gKiBSZXR1cm5zIGEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkYXRhdmlldyB3aGVuIGFsbCBkYXRhIGFuZCBtZXRhZGF0YSBoYXMgYmVlbiB1cGRhdGVkXG4gKlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEByZXR1cm5zIHtQcm9taXNlfVxuICovXG5mdW5jdGlvbiBnZXREYXRhIChkYXRhdmlldykge1xuICB2YXIgc3BvdCA9IGRhdGF2aWV3LnBhcmVudDtcblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgICAgc3BvdC5zb2NrZXQuZW1pdCgnZ2V0RGF0YScsIHtcbiAgICAgICAgZGF0YXZpZXc6IGRhdGF2aWV3LnRvSlNPTigpXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3BvdC5zb2NrZXQuZW1pdCgnZ2V0RGF0YScsIHtcbiAgICAgICAgZGF0YXNldHM6IHNwb3QuY2FjaGVkRGF0YXNldHMsXG4gICAgICAgIGRhdGF2aWV3OiBkYXRhdmlldy50b0pTT04oKVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZGF0YXZpZXcub25jZSgnbmV3TWV0YURhdGEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXNvbHZlKGRhdGF2aWV3KTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBkcml2ZXJUeXBlOiAnc2VydmVyJyxcbiAgc2Nhbjogc2NhbixcbiAgc2V0TWluTWF4OiBzZXRNaW5NYXgsXG4gIHNldENhdGVnb3JpZXM6IHNldENhdGVnb3JpZXMsXG4gIHNldFBlcmNlbnRpbGVzOiBzZXRQZXJjZW50aWxlcyxcbiAgaW5pdERhdGFGaWx0ZXI6IGluaXREYXRhRmlsdGVyLFxuICByZWxlYXNlRGF0YUZpbHRlcjogcmVsZWFzZURhdGFGaWx0ZXIsXG4gIHVwZGF0ZURhdGFGaWx0ZXI6IHVwZGF0ZURhdGFGaWx0ZXIsXG4gIGdldERhdGE6IGdldERhdGFcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///072d\n")},"09c5":function(module,exports,__webpack_require__){eval("/**\n * A single control point for a continuous transform\n *\n * @class ControlPoint\n */\nvar BaseModel = __webpack_require__(/*! ../util/base */ \"3902\");\n\n// Data structure for mapping categorial (and textual) data on groups\nmodule.exports = BaseModel.extend({\n  props: {\n    /**\n     * Value\n     * @type {number}\n     * @memberof! ContinuousRule\n     */\n    x: 'number',\n\n    /**\n     * Transformed value\n     * @type {number}\n     * @memberof! ContinuousRule\n     */\n    fx: 'number'\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDljNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29udHJvbC1wb2ludC5qcz82OTJiIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQSBzaW5nbGUgY29udHJvbCBwb2ludCBmb3IgYSBjb250aW51b3VzIHRyYW5zZm9ybVxuICpcbiAqIEBjbGFzcyBDb250cm9sUG9pbnRcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4uL3V0aWwvYmFzZScpO1xuXG4vLyBEYXRhIHN0cnVjdHVyZSBmb3IgbWFwcGluZyBjYXRlZ29yaWFsIChhbmQgdGV4dHVhbCkgZGF0YSBvbiBncm91cHNcbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVmFsdWVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1J1bGVcbiAgICAgKi9cbiAgICB4OiAnbnVtYmVyJyxcblxuICAgIC8qKlxuICAgICAqIFRyYW5zZm9ybWVkIHZhbHVlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNSdWxlXG4gICAgICovXG4gICAgZng6ICdudW1iZXInXG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///09c5\n")},"0b10":function(module,exports){eval("/**\n * Helpers.\n */\n\nvar s = 1000\nvar m = s * 60\nvar h = m * 60\nvar d = h * 24\nvar y = d * 365.25\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function (val, options) {\n  options = options || {}\n  var type = typeof val\n  if (type === 'string' && val.length > 0) {\n    return parse(val)\n  } else if (type === 'number' && isNaN(val) === false) {\n    return options.long ?\n\t\t\tfmtLong(val) :\n\t\t\tfmtShort(val)\n  }\n  throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val))\n}\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n  str = String(str)\n  if (str.length > 10000) {\n    return\n  }\n  var match = /^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str)\n  if (!match) {\n    return\n  }\n  var n = parseFloat(match[1])\n  var type = (match[2] || 'ms').toLowerCase()\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'yrs':\n    case 'yr':\n    case 'y':\n      return n * y\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d\n    case 'hours':\n    case 'hour':\n    case 'hrs':\n    case 'hr':\n    case 'h':\n      return n * h\n    case 'minutes':\n    case 'minute':\n    case 'mins':\n    case 'min':\n    case 'm':\n      return n * m\n    case 'seconds':\n    case 'second':\n    case 'secs':\n    case 'sec':\n    case 's':\n      return n * s\n    case 'milliseconds':\n    case 'millisecond':\n    case 'msecs':\n    case 'msec':\n    case 'ms':\n      return n\n    default:\n      return undefined\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtShort(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd'\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h'\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm'\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's'\n  }\n  return ms + 'ms'\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtLong(ms) {\n  return plural(ms, d, 'day') ||\n    plural(ms, h, 'hour') ||\n    plural(ms, m, 'minute') ||\n    plural(ms, s, 'second') ||\n    ms + ' ms'\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's'\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMGIxMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvbXMvaW5kZXguanM/YjZlOCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhlbHBlcnMuXG4gKi9cblxudmFyIHMgPSAxMDAwXG52YXIgbSA9IHMgKiA2MFxudmFyIGggPSBtICogNjBcbnZhciBkID0gaCAqIDI0XG52YXIgeSA9IGQgKiAzNjUuMjVcblxuLyoqXG4gKiBQYXJzZSBvciBmb3JtYXQgdGhlIGdpdmVuIGB2YWxgLlxuICpcbiAqIE9wdGlvbnM6XG4gKlxuICogIC0gYGxvbmdgIHZlcmJvc2UgZm9ybWF0dGluZyBbZmFsc2VdXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSB2YWxcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhyb3cgYW4gZXJyb3IgaWYgdmFsIGlzIG5vdCBhIG5vbi1lbXB0eSBzdHJpbmcgb3IgYSBudW1iZXJcbiAqIEByZXR1cm4ge1N0cmluZ3xOdW1iZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHZhbCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWxcbiAgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIHZhbC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHBhcnNlKHZhbClcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBpc05hTih2YWwpID09PSBmYWxzZSkge1xuICAgIHJldHVybiBvcHRpb25zLmxvbmcgP1xuXHRcdFx0Zm10TG9uZyh2YWwpIDpcblx0XHRcdGZtdFNob3J0KHZhbClcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ3ZhbCBpcyBub3QgYSBub24tZW1wdHkgc3RyaW5nIG9yIGEgdmFsaWQgbnVtYmVyLiB2YWw9JyArIEpTT04uc3RyaW5naWZ5KHZhbCkpXG59XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGBzdHJgIGFuZCByZXR1cm4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlKHN0cikge1xuICBzdHIgPSBTdHJpbmcoc3RyKVxuICBpZiAoc3RyLmxlbmd0aCA+IDEwMDAwKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIG1hdGNoID0gL14oKD86XFxkKyk/XFwuP1xcZCspICoobWlsbGlzZWNvbmRzP3xtc2Vjcz98bXN8c2Vjb25kcz98c2Vjcz98c3xtaW51dGVzP3xtaW5zP3xtfGhvdXJzP3xocnM/fGh8ZGF5cz98ZHx5ZWFycz98eXJzP3x5KT8kL2kuZXhlYyhzdHIpXG4gIGlmICghbWF0Y2gpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgbiA9IHBhcnNlRmxvYXQobWF0Y2hbMV0pXG4gIHZhciB0eXBlID0gKG1hdGNoWzJdIHx8ICdtcycpLnRvTG93ZXJDYXNlKClcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAneWVhcnMnOlxuICAgIGNhc2UgJ3llYXInOlxuICAgIGNhc2UgJ3lycyc6XG4gICAgY2FzZSAneXInOlxuICAgIGNhc2UgJ3knOlxuICAgICAgcmV0dXJuIG4gKiB5XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZFxuICAgIGNhc2UgJ2hvdXJzJzpcbiAgICBjYXNlICdob3VyJzpcbiAgICBjYXNlICdocnMnOlxuICAgIGNhc2UgJ2hyJzpcbiAgICBjYXNlICdoJzpcbiAgICAgIHJldHVybiBuICogaFxuICAgIGNhc2UgJ21pbnV0ZXMnOlxuICAgIGNhc2UgJ21pbnV0ZSc6XG4gICAgY2FzZSAnbWlucyc6XG4gICAgY2FzZSAnbWluJzpcbiAgICBjYXNlICdtJzpcbiAgICAgIHJldHVybiBuICogbVxuICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgY2FzZSAnc2Vjcyc6XG4gICAgY2FzZSAnc2VjJzpcbiAgICBjYXNlICdzJzpcbiAgICAgIHJldHVybiBuICogc1xuICAgIGNhc2UgJ21pbGxpc2Vjb25kcyc6XG4gICAgY2FzZSAnbWlsbGlzZWNvbmQnOlxuICAgIGNhc2UgJ21zZWNzJzpcbiAgICBjYXNlICdtc2VjJzpcbiAgICBjYXNlICdtcyc6XG4gICAgICByZXR1cm4gblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuLyoqXG4gKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBmbXRTaG9ydChtcykge1xuICBpZiAobXMgPj0gZCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gZCkgKyAnZCdcbiAgfVxuICBpZiAobXMgPj0gaCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gaCkgKyAnaCdcbiAgfVxuICBpZiAobXMgPj0gbSkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gbSkgKyAnbSdcbiAgfVxuICBpZiAobXMgPj0gcykge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gcykgKyAncydcbiAgfVxuICByZXR1cm4gbXMgKyAnbXMnXG59XG5cbi8qKlxuICogTG9uZyBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBmbXRMb25nKG1zKSB7XG4gIHJldHVybiBwbHVyYWwobXMsIGQsICdkYXknKSB8fFxuICAgIHBsdXJhbChtcywgaCwgJ2hvdXInKSB8fFxuICAgIHBsdXJhbChtcywgbSwgJ21pbnV0ZScpIHx8XG4gICAgcGx1cmFsKG1zLCBzLCAnc2Vjb25kJykgfHxcbiAgICBtcyArICcgbXMnXG59XG5cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi9cblxuZnVuY3Rpb24gcGx1cmFsKG1zLCBuLCBuYW1lKSB7XG4gIGlmIChtcyA8IG4pIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAobXMgPCBuICogMS41KSB7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IobXMgLyBuKSArICcgJyArIG5hbWVcbiAgfVxuICByZXR1cm4gTWF0aC5jZWlsKG1zIC8gbikgKyAnICcgKyBuYW1lICsgJ3MnXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0b10\n")},"0d97":function(module,exports,__webpack_require__){eval("/**\n * Module dependencies.\n */\n\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = Transport;\n\n/**\n * Transport abstract constructor.\n *\n * @param {Object} options.\n * @api private\n */\n\nfunction Transport (opts) {\n  this.path = opts.path;\n  this.hostname = opts.hostname;\n  this.port = opts.port;\n  this.secure = opts.secure;\n  this.query = opts.query;\n  this.timestampParam = opts.timestampParam;\n  this.timestampRequests = opts.timestampRequests;\n  this.readyState = '';\n  this.agent = opts.agent || false;\n  this.socket = opts.socket;\n  this.enablesXDR = opts.enablesXDR;\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx;\n  this.key = opts.key;\n  this.passphrase = opts.passphrase;\n  this.cert = opts.cert;\n  this.ca = opts.ca;\n  this.ciphers = opts.ciphers;\n  this.rejectUnauthorized = opts.rejectUnauthorized;\n  this.forceNode = opts.forceNode;\n\n  // other options for Node.js client\n  this.extraHeaders = opts.extraHeaders;\n  this.localAddress = opts.localAddress;\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Transport.prototype);\n\n/**\n * Emits an error.\n *\n * @param {String} str\n * @return {Transport} for chaining\n * @api public\n */\n\nTransport.prototype.onError = function (msg, desc) {\n  var err = new Error(msg);\n  err.type = 'TransportError';\n  err.description = desc;\n  this.emit('error', err);\n  return this;\n};\n\n/**\n * Opens the transport.\n *\n * @api public\n */\n\nTransport.prototype.open = function () {\n  if ('closed' === this.readyState || '' === this.readyState) {\n    this.readyState = 'opening';\n    this.doOpen();\n  }\n\n  return this;\n};\n\n/**\n * Closes the transport.\n *\n * @api private\n */\n\nTransport.prototype.close = function () {\n  if ('opening' === this.readyState || 'open' === this.readyState) {\n    this.doClose();\n    this.onClose();\n  }\n\n  return this;\n};\n\n/**\n * Sends multiple packets.\n *\n * @param {Array} packets\n * @api private\n */\n\nTransport.prototype.send = function (packets) {\n  if ('open' === this.readyState) {\n    this.write(packets);\n  } else {\n    throw new Error('Transport not open');\n  }\n};\n\n/**\n * Called upon open\n *\n * @api private\n */\n\nTransport.prototype.onOpen = function () {\n  this.readyState = 'open';\n  this.writable = true;\n  this.emit('open');\n};\n\n/**\n * Called with data.\n *\n * @param {String} data\n * @api private\n */\n\nTransport.prototype.onData = function (data) {\n  var packet = parser.decodePacket(data, this.socket.binaryType);\n  this.onPacket(packet);\n};\n\n/**\n * Called with a decoded packet.\n */\n\nTransport.prototype.onPacket = function (packet) {\n  this.emit('packet', packet);\n};\n\n/**\n * Called upon close.\n *\n * @api private\n */\n\nTransport.prototype.onClose = function () {\n  this.readyState = 'closed';\n  this.emit('close');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMGQ5Ny5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0LmpzPzMxMmIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBwYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc3BvcnQ7XG5cbi8qKlxuICogVHJhbnNwb3J0IGFic3RyYWN0IGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gVHJhbnNwb3J0IChvcHRzKSB7XG4gIHRoaXMucGF0aCA9IG9wdHMucGF0aDtcbiAgdGhpcy5ob3N0bmFtZSA9IG9wdHMuaG9zdG5hbWU7XG4gIHRoaXMucG9ydCA9IG9wdHMucG9ydDtcbiAgdGhpcy5zZWN1cmUgPSBvcHRzLnNlY3VyZTtcbiAgdGhpcy5xdWVyeSA9IG9wdHMucXVlcnk7XG4gIHRoaXMudGltZXN0YW1wUGFyYW0gPSBvcHRzLnRpbWVzdGFtcFBhcmFtO1xuICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50IHx8IGZhbHNlO1xuICB0aGlzLnNvY2tldCA9IG9wdHMuc29ja2V0O1xuICB0aGlzLmVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG5cbiAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIHRoaXMucGZ4ID0gb3B0cy5wZng7XG4gIHRoaXMua2V5ID0gb3B0cy5rZXk7XG4gIHRoaXMucGFzc3BocmFzZSA9IG9wdHMucGFzc3BocmFzZTtcbiAgdGhpcy5jZXJ0ID0gb3B0cy5jZXJ0O1xuICB0aGlzLmNhID0gb3B0cy5jYTtcbiAgdGhpcy5jaXBoZXJzID0gb3B0cy5jaXBoZXJzO1xuICB0aGlzLnJlamVjdFVuYXV0aG9yaXplZCA9IG9wdHMucmVqZWN0VW5hdXRob3JpemVkO1xuICB0aGlzLmZvcmNlTm9kZSA9IG9wdHMuZm9yY2VOb2RlO1xuXG4gIC8vIG90aGVyIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIHRoaXMuZXh0cmFIZWFkZXJzID0gb3B0cy5leHRyYUhlYWRlcnM7XG4gIHRoaXMubG9jYWxBZGRyZXNzID0gb3B0cy5sb2NhbEFkZHJlc3M7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFRyYW5zcG9ydC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIEVtaXRzIGFuIGVycm9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge1RyYW5zcG9ydH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uIChtc2csIGRlc2MpIHtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcihtc2cpO1xuICBlcnIudHlwZSA9ICdUcmFuc3BvcnRFcnJvcic7XG4gIGVyci5kZXNjcmlwdGlvbiA9IGRlc2M7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3BlbnMgdGhlIHRyYW5zcG9ydC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCdjbG9zZWQnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJycgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcbiAgICB0aGlzLmRvT3BlbigpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENsb3NlcyB0aGUgdHJhbnNwb3J0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMuZG9DbG9zZSgpO1xuICAgIHRoaXMub25DbG9zZSgpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIG11bHRpcGxlIHBhY2tldHMuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFja2V0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuVHJhbnNwb3J0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKHBhY2tldHMpIHtcbiAgaWYgKCdvcGVuJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgdGhpcy53cml0ZShwYWNrZXRzKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zcG9ydCBub3Qgb3BlbicpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIG9wZW5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW4nO1xuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcbiAgdGhpcy5lbWl0KCdvcGVuJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIGRhdGEuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGFcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdmFyIHBhY2tldCA9IHBhcnNlci5kZWNvZGVQYWNrZXQoZGF0YSwgdGhpcy5zb2NrZXQuYmluYXJ5VHlwZSk7XG4gIHRoaXMub25QYWNrZXQocGFja2V0KTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHdpdGggYSBkZWNvZGVkIHBhY2tldC5cbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uUGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICB0aGlzLmVtaXQoJ3BhY2tldCcsIHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGNsb3NlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0d97\n")},"108d":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module requirements.\n */\n\nvar XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ \"86e3\");\nvar Polling = __webpack_require__(/*! ./polling */ \"181d\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:polling-xhr');\n\n/**\n * Module exports.\n */\n\nmodule.exports = XHR;\nmodule.exports.Request = Request;\n\n/**\n * Empty function\n */\n\nfunction empty () {}\n\n/**\n * XHR Polling constructor.\n *\n * @param {Object} opts\n * @api public\n */\n\nfunction XHR (opts) {\n  Polling.call(this, opts);\n  this.requestTimeout = opts.requestTimeout;\n\n  if (global.location) {\n    var isSSL = 'https:' === location.protocol;\n    var port = location.port;\n\n    // some user agents have empty `location.port`\n    if (!port) {\n      port = isSSL ? 443 : 80;\n    }\n\n    this.xd = opts.hostname !== global.location.hostname ||\n      port !== opts.port;\n    this.xs = opts.secure !== isSSL;\n  } else {\n    this.extraHeaders = opts.extraHeaders;\n  }\n}\n\n/**\n * Inherits from Polling.\n */\n\ninherit(XHR, Polling);\n\n/**\n * XHR supports binary\n */\n\nXHR.prototype.supportsBinary = true;\n\n/**\n * Creates a request.\n *\n * @param {String} method\n * @api private\n */\n\nXHR.prototype.request = function (opts) {\n  opts = opts || {};\n  opts.uri = this.uri();\n  opts.xd = this.xd;\n  opts.xs = this.xs;\n  opts.agent = this.agent || false;\n  opts.supportsBinary = this.supportsBinary;\n  opts.enablesXDR = this.enablesXDR;\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n  opts.requestTimeout = this.requestTimeout;\n\n  // other options for Node.js client\n  opts.extraHeaders = this.extraHeaders;\n\n  return new Request(opts);\n};\n\n/**\n * Sends data.\n *\n * @param {String} data to send.\n * @param {Function} called upon flush.\n * @api private\n */\n\nXHR.prototype.doWrite = function (data, fn) {\n  var isBinary = typeof data !== 'string' && data !== undefined;\n  var req = this.request({ method: 'POST', data: data, isBinary: isBinary });\n  var self = this;\n  req.on('success', fn);\n  req.on('error', function (err) {\n    self.onError('xhr post error', err);\n  });\n  this.sendXhr = req;\n};\n\n/**\n * Starts a poll cycle.\n *\n * @api private\n */\n\nXHR.prototype.doPoll = function () {\n  debug('xhr poll');\n  var req = this.request();\n  var self = this;\n  req.on('data', function (data) {\n    self.onData(data);\n  });\n  req.on('error', function (err) {\n    self.onError('xhr poll error', err);\n  });\n  this.pollXhr = req;\n};\n\n/**\n * Request constructor\n *\n * @param {Object} options\n * @api public\n */\n\nfunction Request (opts) {\n  this.method = opts.method || 'GET';\n  this.uri = opts.uri;\n  this.xd = !!opts.xd;\n  this.xs = !!opts.xs;\n  this.async = false !== opts.async;\n  this.data = undefined !== opts.data ? opts.data : null;\n  this.agent = opts.agent;\n  this.isBinary = opts.isBinary;\n  this.supportsBinary = opts.supportsBinary;\n  this.enablesXDR = opts.enablesXDR;\n  this.requestTimeout = opts.requestTimeout;\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx;\n  this.key = opts.key;\n  this.passphrase = opts.passphrase;\n  this.cert = opts.cert;\n  this.ca = opts.ca;\n  this.ciphers = opts.ciphers;\n  this.rejectUnauthorized = opts.rejectUnauthorized;\n\n  // other options for Node.js client\n  this.extraHeaders = opts.extraHeaders;\n\n  this.create();\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Request.prototype);\n\n/**\n * Creates the XHR object and sends the request.\n *\n * @api private\n */\n\nRequest.prototype.create = function () {\n  var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR };\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n\n  var xhr = this.xhr = new XMLHttpRequest(opts);\n  var self = this;\n\n  try {\n    debug('xhr open %s: %s', this.method, this.uri);\n    xhr.open(this.method, this.uri, this.async);\n    try {\n      if (this.extraHeaders) {\n        xhr.setDisableHeaderCheck(true);\n        for (var i in this.extraHeaders) {\n          if (this.extraHeaders.hasOwnProperty(i)) {\n            xhr.setRequestHeader(i, this.extraHeaders[i]);\n          }\n        }\n      }\n    } catch (e) {}\n    if (this.supportsBinary) {\n      // This has to be done after open because Firefox is stupid\n      // http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension\n      xhr.responseType = 'arraybuffer';\n    }\n\n    if ('POST' === this.method) {\n      try {\n        if (this.isBinary) {\n          xhr.setRequestHeader('Content-type', 'application/octet-stream');\n        } else {\n          xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');\n        }\n      } catch (e) {}\n    }\n\n    try {\n      xhr.setRequestHeader('Accept', '*/*');\n    } catch (e) {}\n\n    // ie6 check\n    if ('withCredentials' in xhr) {\n      xhr.withCredentials = true;\n    }\n\n    if (this.requestTimeout) {\n      xhr.timeout = this.requestTimeout;\n    }\n\n    if (this.hasXDR()) {\n      xhr.onload = function () {\n        self.onLoad();\n      };\n      xhr.onerror = function () {\n        self.onError(xhr.responseText);\n      };\n    } else {\n      xhr.onreadystatechange = function () {\n        if (4 !== xhr.readyState) return;\n        if (200 === xhr.status || 1223 === xhr.status) {\n          self.onLoad();\n        } else {\n          // make sure the `error` event handler that's user-set\n          // does not throw in the same tick and gets caught here\n          setTimeout(function () {\n            self.onError(xhr.status);\n          }, 0);\n        }\n      };\n    }\n\n    debug('xhr data %s', this.data);\n    xhr.send(this.data);\n  } catch (e) {\n    // Need to defer since .create() is called directly fhrom the constructor\n    // and thus the 'error' event can only be only bound *after* this exception\n    // occurs.  Therefore, also, we cannot throw here at all.\n    setTimeout(function () {\n      self.onError(e);\n    }, 0);\n    return;\n  }\n\n  if (global.document) {\n    this.index = Request.requestsCount++;\n    Request.requests[this.index] = this;\n  }\n};\n\n/**\n * Called upon successful response.\n *\n * @api private\n */\n\nRequest.prototype.onSuccess = function () {\n  this.emit('success');\n  this.cleanup();\n};\n\n/**\n * Called if we have data.\n *\n * @api private\n */\n\nRequest.prototype.onData = function (data) {\n  this.emit('data', data);\n  this.onSuccess();\n};\n\n/**\n * Called upon error.\n *\n * @api private\n */\n\nRequest.prototype.onError = function (err) {\n  this.emit('error', err);\n  this.cleanup(true);\n};\n\n/**\n * Cleans up house.\n *\n * @api private\n */\n\nRequest.prototype.cleanup = function (fromError) {\n  if ('undefined' === typeof this.xhr || null === this.xhr) {\n    return;\n  }\n  // xmlhttprequest\n  if (this.hasXDR()) {\n    this.xhr.onload = this.xhr.onerror = empty;\n  } else {\n    this.xhr.onreadystatechange = empty;\n  }\n\n  if (fromError) {\n    try {\n      this.xhr.abort();\n    } catch (e) {}\n  }\n\n  if (global.document) {\n    delete Request.requests[this.index];\n  }\n\n  this.xhr = null;\n};\n\n/**\n * Called upon load.\n *\n * @api private\n */\n\nRequest.prototype.onLoad = function () {\n  var data;\n  try {\n    var contentType;\n    try {\n      contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0];\n    } catch (e) {}\n    if (contentType === 'application/octet-stream') {\n      data = this.xhr.response || this.xhr.responseText;\n    } else {\n      if (!this.supportsBinary) {\n        data = this.xhr.responseText;\n      } else {\n        try {\n          data = String.fromCharCode.apply(null, new Uint8Array(this.xhr.response));\n        } catch (e) {\n          var ui8Arr = new Uint8Array(this.xhr.response);\n          var dataArray = [];\n          for (var idx = 0, length = ui8Arr.length; idx < length; idx++) {\n            dataArray.push(ui8Arr[idx]);\n          }\n\n          data = String.fromCharCode.apply(null, dataArray);\n        }\n      }\n    }\n  } catch (e) {\n    this.onError(e);\n  }\n  if (null != data) {\n    this.onData(data);\n  }\n};\n\n/**\n * Check if it has XDomainRequest.\n *\n * @api private\n */\n\nRequest.prototype.hasXDR = function () {\n  return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR;\n};\n\n/**\n * Aborts the request.\n *\n * @api public\n */\n\nRequest.prototype.abort = function () {\n  this.cleanup();\n};\n\n/**\n * Aborts pending requests when unloading the window. This is needed to prevent\n * memory leaks (e.g. when using IE) and to ensure that no spurious error is\n * emitted.\n */\n\nRequest.requestsCount = 0;\nRequest.requests = {};\n\nif (global.document) {\n  if (global.attachEvent) {\n    global.attachEvent('onunload', unloadHandler);\n  } else if (global.addEventListener) {\n    global.addEventListener('beforeunload', unloadHandler, false);\n  }\n}\n\nfunction unloadHandler () {\n  for (var i in Request.requests) {\n    if (Request.requests.hasOwnProperty(i)) {\n      Request.requests[i].abort();\n    }\n  }\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA4ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLXhoci5qcz9mYmY3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAqL1xuXG52YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdC1zc2wnKTtcbnZhciBQb2xsaW5nID0gcmVxdWlyZSgnLi9wb2xsaW5nJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgaW5oZXJpdCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1pbmhlcml0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnBvbGxpbmcteGhyJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBYSFI7XG5tb2R1bGUuZXhwb3J0cy5SZXF1ZXN0ID0gUmVxdWVzdDtcblxuLyoqXG4gKiBFbXB0eSBmdW5jdGlvblxuICovXG5cbmZ1bmN0aW9uIGVtcHR5ICgpIHt9XG5cbi8qKlxuICogWEhSIFBvbGxpbmcgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gWEhSIChvcHRzKSB7XG4gIFBvbGxpbmcuY2FsbCh0aGlzLCBvcHRzKTtcbiAgdGhpcy5yZXF1ZXN0VGltZW91dCA9IG9wdHMucmVxdWVzdFRpbWVvdXQ7XG5cbiAgaWYgKGdsb2JhbC5sb2NhdGlvbikge1xuICAgIHZhciBpc1NTTCA9ICdodHRwczonID09PSBsb2NhdGlvbi5wcm90b2NvbDtcbiAgICB2YXIgcG9ydCA9IGxvY2F0aW9uLnBvcnQ7XG5cbiAgICAvLyBzb21lIHVzZXIgYWdlbnRzIGhhdmUgZW1wdHkgYGxvY2F0aW9uLnBvcnRgXG4gICAgaWYgKCFwb3J0KSB7XG4gICAgICBwb3J0ID0gaXNTU0wgPyA0NDMgOiA4MDtcbiAgICB9XG5cbiAgICB0aGlzLnhkID0gb3B0cy5ob3N0bmFtZSAhPT0gZ2xvYmFsLmxvY2F0aW9uLmhvc3RuYW1lIHx8XG4gICAgICBwb3J0ICE9PSBvcHRzLnBvcnQ7XG4gICAgdGhpcy54cyA9IG9wdHMuc2VjdXJlICE9PSBpc1NTTDtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuICB9XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBQb2xsaW5nLlxuICovXG5cbmluaGVyaXQoWEhSLCBQb2xsaW5nKTtcblxuLyoqXG4gKiBYSFIgc3VwcG9ydHMgYmluYXJ5XG4gKi9cblxuWEhSLnByb3RvdHlwZS5zdXBwb3J0c0JpbmFyeSA9IHRydWU7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHJlcXVlc3QuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuWEhSLnByb3RvdHlwZS5yZXF1ZXN0ID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgb3B0cyA9IG9wdHMgfHwge307XG4gIG9wdHMudXJpID0gdGhpcy51cmkoKTtcbiAgb3B0cy54ZCA9IHRoaXMueGQ7XG4gIG9wdHMueHMgPSB0aGlzLnhzO1xuICBvcHRzLmFnZW50ID0gdGhpcy5hZ2VudCB8fCBmYWxzZTtcbiAgb3B0cy5zdXBwb3J0c0JpbmFyeSA9IHRoaXMuc3VwcG9ydHNCaW5hcnk7XG4gIG9wdHMuZW5hYmxlc1hEUiA9IHRoaXMuZW5hYmxlc1hEUjtcblxuICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgb3B0cy5wZnggPSB0aGlzLnBmeDtcbiAgb3B0cy5rZXkgPSB0aGlzLmtleTtcbiAgb3B0cy5wYXNzcGhyYXNlID0gdGhpcy5wYXNzcGhyYXNlO1xuICBvcHRzLmNlcnQgPSB0aGlzLmNlcnQ7XG4gIG9wdHMuY2EgPSB0aGlzLmNhO1xuICBvcHRzLmNpcGhlcnMgPSB0aGlzLmNpcGhlcnM7XG4gIG9wdHMucmVqZWN0VW5hdXRob3JpemVkID0gdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQ7XG4gIG9wdHMucmVxdWVzdFRpbWVvdXQgPSB0aGlzLnJlcXVlc3RUaW1lb3V0O1xuXG4gIC8vIG90aGVyIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIG9wdHMuZXh0cmFIZWFkZXJzID0gdGhpcy5leHRyYUhlYWRlcnM7XG5cbiAgcmV0dXJuIG5ldyBSZXF1ZXN0KG9wdHMpO1xufTtcblxuLyoqXG4gKiBTZW5kcyBkYXRhLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIHRvIHNlbmQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblhIUi5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uIChkYXRhLCBmbikge1xuICB2YXIgaXNCaW5hcnkgPSB0eXBlb2YgZGF0YSAhPT0gJ3N0cmluZycgJiYgZGF0YSAhPT0gdW5kZWZpbmVkO1xuICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KHsgbWV0aG9kOiAnUE9TVCcsIGRhdGE6IGRhdGEsIGlzQmluYXJ5OiBpc0JpbmFyeSB9KTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICByZXEub24oJ3N1Y2Nlc3MnLCBmbik7XG4gIHJlcS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgc2VsZi5vbkVycm9yKCd4aHIgcG9zdCBlcnJvcicsIGVycik7XG4gIH0pO1xuICB0aGlzLnNlbmRYaHIgPSByZXE7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuWEhSLnByb3RvdHlwZS5kb1BvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCd4aHIgcG9sbCcpO1xuICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KCk7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgcmVxLm9uKCdkYXRhJywgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBzZWxmLm9uRGF0YShkYXRhKTtcbiAgfSk7XG4gIHJlcS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgc2VsZi5vbkVycm9yKCd4aHIgcG9sbCBlcnJvcicsIGVycik7XG4gIH0pO1xuICB0aGlzLnBvbGxYaHIgPSByZXE7XG59O1xuXG4vKipcbiAqIFJlcXVlc3QgY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0IChvcHRzKSB7XG4gIHRoaXMubWV0aG9kID0gb3B0cy5tZXRob2QgfHwgJ0dFVCc7XG4gIHRoaXMudXJpID0gb3B0cy51cmk7XG4gIHRoaXMueGQgPSAhIW9wdHMueGQ7XG4gIHRoaXMueHMgPSAhIW9wdHMueHM7XG4gIHRoaXMuYXN5bmMgPSBmYWxzZSAhPT0gb3B0cy5hc3luYztcbiAgdGhpcy5kYXRhID0gdW5kZWZpbmVkICE9PSBvcHRzLmRhdGEgPyBvcHRzLmRhdGEgOiBudWxsO1xuICB0aGlzLmFnZW50ID0gb3B0cy5hZ2VudDtcbiAgdGhpcy5pc0JpbmFyeSA9IG9wdHMuaXNCaW5hcnk7XG4gIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSBvcHRzLnN1cHBvcnRzQmluYXJ5O1xuICB0aGlzLmVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG4gIHRoaXMucmVxdWVzdFRpbWVvdXQgPSBvcHRzLnJlcXVlc3RUaW1lb3V0O1xuXG4gIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLnBmeCA9IG9wdHMucGZ4O1xuICB0aGlzLmtleSA9IG9wdHMua2V5O1xuICB0aGlzLnBhc3NwaHJhc2UgPSBvcHRzLnBhc3NwaHJhc2U7XG4gIHRoaXMuY2VydCA9IG9wdHMuY2VydDtcbiAgdGhpcy5jYSA9IG9wdHMuY2E7XG4gIHRoaXMuY2lwaGVycyA9IG9wdHMuY2lwaGVycztcbiAgdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQgPSBvcHRzLnJlamVjdFVuYXV0aG9yaXplZDtcblxuICAvLyBvdGhlciBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuXG4gIHRoaXMuY3JlYXRlKCk7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFJlcXVlc3QucHJvdG90eXBlKTtcblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBYSFIgb2JqZWN0IGFuZCBzZW5kcyB0aGUgcmVxdWVzdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBvcHRzID0geyBhZ2VudDogdGhpcy5hZ2VudCwgeGRvbWFpbjogdGhpcy54ZCwgeHNjaGVtZTogdGhpcy54cywgZW5hYmxlc1hEUjogdGhpcy5lbmFibGVzWERSIH07XG5cbiAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIG9wdHMucGZ4ID0gdGhpcy5wZng7XG4gIG9wdHMua2V5ID0gdGhpcy5rZXk7XG4gIG9wdHMucGFzc3BocmFzZSA9IHRoaXMucGFzc3BocmFzZTtcbiAgb3B0cy5jZXJ0ID0gdGhpcy5jZXJ0O1xuICBvcHRzLmNhID0gdGhpcy5jYTtcbiAgb3B0cy5jaXBoZXJzID0gdGhpcy5jaXBoZXJzO1xuICBvcHRzLnJlamVjdFVuYXV0aG9yaXplZCA9IHRoaXMucmVqZWN0VW5hdXRob3JpemVkO1xuXG4gIHZhciB4aHIgPSB0aGlzLnhociA9IG5ldyBYTUxIdHRwUmVxdWVzdChvcHRzKTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRyeSB7XG4gICAgZGVidWcoJ3hociBvcGVuICVzOiAlcycsIHRoaXMubWV0aG9kLCB0aGlzLnVyaSk7XG4gICAgeGhyLm9wZW4odGhpcy5tZXRob2QsIHRoaXMudXJpLCB0aGlzLmFzeW5jKTtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuZXh0cmFIZWFkZXJzKSB7XG4gICAgICAgIHhoci5zZXREaXNhYmxlSGVhZGVyQ2hlY2sodHJ1ZSk7XG4gICAgICAgIGZvciAodmFyIGkgaW4gdGhpcy5leHRyYUhlYWRlcnMpIHtcbiAgICAgICAgICBpZiAodGhpcy5leHRyYUhlYWRlcnMuaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGksIHRoaXMuZXh0cmFIZWFkZXJzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIGlmICh0aGlzLnN1cHBvcnRzQmluYXJ5KSB7XG4gICAgICAvLyBUaGlzIGhhcyB0byBiZSBkb25lIGFmdGVyIG9wZW4gYmVjYXVzZSBGaXJlZm94IGlzIHN0dXBpZFxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMzIxNjkwMy9nZXQtYmluYXJ5LWRhdGEtd2l0aC14bWxodHRwcmVxdWVzdC1pbi1hLWZpcmVmb3gtZXh0ZW5zaW9uXG4gICAgICB4aHIucmVzcG9uc2VUeXBlID0gJ2FycmF5YnVmZmVyJztcbiAgICB9XG5cbiAgICBpZiAoJ1BPU1QnID09PSB0aGlzLm1ldGhvZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHRoaXMuaXNCaW5hcnkpIHtcbiAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdBY2NlcHQnLCAnKi8qJyk7XG4gICAgfSBjYXRjaCAoZSkge31cblxuICAgIC8vIGllNiBjaGVja1xuICAgIGlmICgnd2l0aENyZWRlbnRpYWxzJyBpbiB4aHIpIHtcbiAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnJlcXVlc3RUaW1lb3V0KSB7XG4gICAgICB4aHIudGltZW91dCA9IHRoaXMucmVxdWVzdFRpbWVvdXQ7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaGFzWERSKCkpIHtcbiAgICAgIHhoci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYub25Mb2FkKCk7XG4gICAgICB9O1xuICAgICAgeGhyLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYub25FcnJvcih4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICg0ICE9PSB4aHIucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICBpZiAoMjAwID09PSB4aHIuc3RhdHVzIHx8IDEyMjMgPT09IHhoci5zdGF0dXMpIHtcbiAgICAgICAgICBzZWxmLm9uTG9hZCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgYGVycm9yYCBldmVudCBoYW5kbGVyIHRoYXQncyB1c2VyLXNldFxuICAgICAgICAgIC8vIGRvZXMgbm90IHRocm93IGluIHRoZSBzYW1lIHRpY2sgYW5kIGdldHMgY2F1Z2h0IGhlcmVcbiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNlbGYub25FcnJvcih4aHIuc3RhdHVzKTtcbiAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBkZWJ1ZygneGhyIGRhdGEgJXMnLCB0aGlzLmRhdGEpO1xuICAgIHhoci5zZW5kKHRoaXMuZGF0YSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBOZWVkIHRvIGRlZmVyIHNpbmNlIC5jcmVhdGUoKSBpcyBjYWxsZWQgZGlyZWN0bHkgZmhyb20gdGhlIGNvbnN0cnVjdG9yXG4gICAgLy8gYW5kIHRodXMgdGhlICdlcnJvcicgZXZlbnQgY2FuIG9ubHkgYmUgb25seSBib3VuZCAqYWZ0ZXIqIHRoaXMgZXhjZXB0aW9uXG4gICAgLy8gb2NjdXJzLiAgVGhlcmVmb3JlLCBhbHNvLCB3ZSBjYW5ub3QgdGhyb3cgaGVyZSBhdCBhbGwuXG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBzZWxmLm9uRXJyb3IoZSk7XG4gICAgfSwgMCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGdsb2JhbC5kb2N1bWVudCkge1xuICAgIHRoaXMuaW5kZXggPSBSZXF1ZXN0LnJlcXVlc3RzQ291bnQrKztcbiAgICBSZXF1ZXN0LnJlcXVlc3RzW3RoaXMuaW5kZXhdID0gdGhpcztcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzdWNjZXNzZnVsIHJlc3BvbnNlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLm9uU3VjY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0KCdzdWNjZXNzJyk7XG4gIHRoaXMuY2xlYW51cCgpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgaWYgd2UgaGF2ZSBkYXRhLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuZW1pdCgnZGF0YScsIGRhdGEpO1xuICB0aGlzLm9uU3VjY2VzcygpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKGVycikge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5jbGVhbnVwKHRydWUpO1xufTtcblxuLyoqXG4gKiBDbGVhbnMgdXAgaG91c2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuY2xlYW51cCA9IGZ1bmN0aW9uIChmcm9tRXJyb3IpIHtcbiAgaWYgKCd1bmRlZmluZWQnID09PSB0eXBlb2YgdGhpcy54aHIgfHwgbnVsbCA9PT0gdGhpcy54aHIpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8geG1saHR0cHJlcXVlc3RcbiAgaWYgKHRoaXMuaGFzWERSKCkpIHtcbiAgICB0aGlzLnhoci5vbmxvYWQgPSB0aGlzLnhoci5vbmVycm9yID0gZW1wdHk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZW1wdHk7XG4gIH1cblxuICBpZiAoZnJvbUVycm9yKSB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMueGhyLmFib3J0KCk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfVxuXG4gIGlmIChnbG9iYWwuZG9jdW1lbnQpIHtcbiAgICBkZWxldGUgUmVxdWVzdC5yZXF1ZXN0c1t0aGlzLmluZGV4XTtcbiAgfVxuXG4gIHRoaXMueGhyID0gbnVsbDtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gbG9hZC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vbkxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBkYXRhO1xuICB0cnkge1xuICAgIHZhciBjb250ZW50VHlwZTtcbiAgICB0cnkge1xuICAgICAgY29udGVudFR5cGUgPSB0aGlzLnhoci5nZXRSZXNwb25zZUhlYWRlcignQ29udGVudC1UeXBlJykuc3BsaXQoJzsnKVswXTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIGlmIChjb250ZW50VHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpIHtcbiAgICAgIGRhdGEgPSB0aGlzLnhoci5yZXNwb25zZSB8fCB0aGlzLnhoci5yZXNwb25zZVRleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy5zdXBwb3J0c0JpbmFyeSkge1xuICAgICAgICBkYXRhID0gdGhpcy54aHIucmVzcG9uc2VUZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDhBcnJheSh0aGlzLnhoci5yZXNwb25zZSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdmFyIHVpOEFyciA9IG5ldyBVaW50OEFycmF5KHRoaXMueGhyLnJlc3BvbnNlKTtcbiAgICAgICAgICB2YXIgZGF0YUFycmF5ID0gW107XG4gICAgICAgICAgZm9yICh2YXIgaWR4ID0gMCwgbGVuZ3RoID0gdWk4QXJyLmxlbmd0aDsgaWR4IDwgbGVuZ3RoOyBpZHgrKykge1xuICAgICAgICAgICAgZGF0YUFycmF5LnB1c2godWk4QXJyW2lkeF0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGRhdGFBcnJheSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aGlzLm9uRXJyb3IoZSk7XG4gIH1cbiAgaWYgKG51bGwgIT0gZGF0YSkge1xuICAgIHRoaXMub25EYXRhKGRhdGEpO1xuICB9XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIGl0IGhhcyBYRG9tYWluUmVxdWVzdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5oYXNYRFIgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGdsb2JhbC5YRG9tYWluUmVxdWVzdCAmJiAhdGhpcy54cyAmJiB0aGlzLmVuYWJsZXNYRFI7XG59O1xuXG4vKipcbiAqIEFib3J0cyB0aGUgcmVxdWVzdC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmFib3J0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmNsZWFudXAoKTtcbn07XG5cbi8qKlxuICogQWJvcnRzIHBlbmRpbmcgcmVxdWVzdHMgd2hlbiB1bmxvYWRpbmcgdGhlIHdpbmRvdy4gVGhpcyBpcyBuZWVkZWQgdG8gcHJldmVudFxuICogbWVtb3J5IGxlYWtzIChlLmcuIHdoZW4gdXNpbmcgSUUpIGFuZCB0byBlbnN1cmUgdGhhdCBubyBzcHVyaW91cyBlcnJvciBpc1xuICogZW1pdHRlZC5cbiAqL1xuXG5SZXF1ZXN0LnJlcXVlc3RzQ291bnQgPSAwO1xuUmVxdWVzdC5yZXF1ZXN0cyA9IHt9O1xuXG5pZiAoZ2xvYmFsLmRvY3VtZW50KSB7XG4gIGlmIChnbG9iYWwuYXR0YWNoRXZlbnQpIHtcbiAgICBnbG9iYWwuYXR0YWNoRXZlbnQoJ29udW5sb2FkJywgdW5sb2FkSGFuZGxlcik7XG4gIH0gZWxzZSBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgdW5sb2FkSGFuZGxlciwgZmFsc2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVubG9hZEhhbmRsZXIgKCkge1xuICBmb3IgKHZhciBpIGluIFJlcXVlc3QucmVxdWVzdHMpIHtcbiAgICBpZiAoUmVxdWVzdC5yZXF1ZXN0cy5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgUmVxdWVzdC5yZXF1ZXN0c1tpXS5hYm9ydCgpO1xuICAgIH1cbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///108d\n")},1278:function(module,exports,__webpack_require__){eval("/**\n * Selection\n * @module client/util-selection\n */\nvar misval = __webpack_require__(/*! ./misval */ \"bff6\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\n/*\n * Set a categorial 1D filter function\n * @param {Partition} partition\n */\nfunction filterFunctionCategorial1D (partition) {\n  var haystack = {};\n\n  if (!partition.selected || !partition.selected.length) {\n    partition.groups.forEach(function (group) {\n      haystack[group.value] = true;\n    });\n  } else {\n    partition.selected.forEach(function (h) {\n      haystack[h] = true;\n    });\n  }\n\n  return function (d) {\n    var needle = d;\n    if (!(needle instanceof Array)) {\n      needle = [d];\n    }\n\n    var selected = false;\n    needle.forEach(function (s) {\n      selected = selected | haystack[s];\n    });\n    return !!selected;\n  };\n}\n\n/*\n * Set a text filter function\n * @param {Partition} partition\n */\nfunction filterFunctionText (partition) {\n  var haystack = {};\n\n  // nothing selected, so all selected\n  if (partition.selected.length === 0) {\n    return function () {\n      return true;\n    };\n  }\n\n  partition.selected.forEach(function (h) {\n    haystack[h] = true;\n  });\n\n  return function (d) {\n    var needle = d;\n    if (!(needle instanceof Array)) {\n      needle = [d];\n    }\n\n    var selected = false;\n    needle.forEach(function (s) {\n      selected = selected | haystack[s];\n    });\n    return !!selected;\n  };\n}\n\n/*\n * Set a continuous 1D filter function\n * @param {Partition} partition\n */\nfunction filterFunctionContinuous1D (partition) {\n  var edge = partition.maxval;\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = partition.minval;\n    max = partition.maxval;\n    return function (d) {\n      return ((d >= min && d <= max) && (d !== misval));\n    };\n  } else {\n    min = partition.selected[0];\n    max = partition.selected[1];\n    return function (d) {\n      return ((d >= min && d < max) || ((d === edge) && (max === edge))) && (d !== misval);\n    };\n  }\n}\n\n/*\n * Set a continuous 1D filter function on a datetime dimension\n * @param {Partition} partition\n */\nfunction filterFunctionDatetime1D (partition) {\n  var edge = moment(partition.maxval);\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = moment(partition.minval);\n    max = moment(partition.maxval);\n\n    return function (d) {\n      var m = moment(d);\n      return (m !== misval) && !m.isBefore(min) && !m.isAfter(max);\n    };\n  } else {\n    min = moment(partition.selected[0]);\n    max = moment(partition.selected[1]);\n    return function (d) {\n      var m = moment(d);\n      return (m !== misval) && !min.isAfter(m) && (m.isBefore(max) || (max.isSame(edge) && max.isSame(m)));\n    };\n  }\n}\n\n/*\n * Set a continuous 1D filter function on a duration dimension\n * @param {Partition} partition\n */\nfunction filterFunctionDuration1D (partition) {\n  var edge = partition.maxval;\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = partition.minval;\n    max = partition.maxval;\n\n    return function (d) {\n      if (d === misval) {\n        return false;\n      }\n      var m = moment.duration(d);\n      return moment.isDuration(m) && m >= min && m <= max;\n    };\n  } else {\n    min = moment.duration(partition.selected[0]);\n    max = moment.duration(partition.selected[1]);\n    return function (d) {\n      if (d === misval) {\n        return false;\n      }\n      var m = moment.duration(d);\n      return moment.isDuration(m) && m >= min && (m < max || (m <= max && max >= edge));\n    };\n  }\n}\n\n/**\n * A filter function based for a single partition\n * @function\n * @returns {boolean} selected True if the datapoint is currently selected\n * @param {Partition} partition\n * @param {Object} datapoint\n * @memberof! Selection\n */\nfunction filterFunction (partition) {\n  if (partition.isCategorial || partition.isConstant) {\n    return filterFunctionCategorial1D(partition);\n  } else if (partition.isContinuous) {\n    return filterFunctionContinuous1D(partition);\n  } else if (partition.isDatetime) {\n    return filterFunctionDatetime1D(partition);\n  } else if (partition.isDuration) {\n    return filterFunctionDuration1D(partition);\n  } else if (partition.isText) {\n    return filterFunctionText(partition);\n  } else {\n    console.error('Cannot make filterfunction for partition', partition);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateCategorial1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // 1. none selected:\n    selected.push(group.value);\n  } else if (selected.length === 1) {\n    if (selected[0] === group.value) {\n      // 2. one selected and the group is the same:\n      selected.splice(0, selected.length);\n      partition.groups.forEach(function (g) {\n        if (g.value !== group.value) {\n          selected.push(g.value);\n        }\n      });\n    } else {\n      // 3. one selected and the group is different:\n      selected.push(group.value);\n    }\n  } else {\n    var i;\n    i = selected.indexOf(group.value);\n    if (i > -1) {\n      // 4. more than one selected and the group is in the selection:\n      selected.splice(i, 1);\n    } else {\n      // 5. more than one selected and the group is not in the selection:\n      selected.push(group.value);\n    }\n  }\n\n  // after add: if filters == groups, reset and dont filter\n  if (selected.length === partition.groups.length) {\n    selected.splice(0, selected.length);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateText (partition, group) {\n  var selected = partition.selected;\n\n  var i;\n  i = selected.indexOf(group.value);\n  if (i > -1) {\n    // 1. in the selection, remove it\n    selected.splice(i, 1);\n  } else {\n    // 2. not in the selection, add it\n    selected.push(group.value);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateContinuous1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min;\n    selected[1] = group.max;\n  } else if (group.min >= selected[1]) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max;\n  } else if (group.max <= selected[0]) {\n    // clicked outside to the left of selection\n    selected[0] = group.min;\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    if (partition.groupLog) {\n      d1 = Math.abs(Math.log(selected[0]) - Math.log(group.min));\n      d2 = Math.abs(Math.log(selected[1]) - Math.log(group.max));\n    } else {\n      d1 = Math.abs(selected[0] - group.min);\n      d2 = Math.abs(selected[1] - group.max);\n    }\n    if (d1 < d2) {\n      selected[0] = group.min;\n    } else {\n      selected[1] = group.max;\n    }\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateDatetime1D (partition, group) {\n  var selected = partition.selected;\n\n  if (!selected || selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min.toISOString();\n    selected[1] = group.max.toISOString();\n    return;\n  }\n\n  var selectionStart = moment(selected[0]);\n  var selectionEnd = moment(selected[1]);\n\n  if (!group.min.isBefore(selectionEnd)) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max.toISOString();\n  } else if (!group.max.isAfter(selectionStart)) {\n    // clicked outside to the left of selection\n    selected[0] = group.min.toISOString();\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    d1 = Math.abs(selectionStart.diff(group.min));\n    d2 = Math.abs(selectionEnd.diff(group.max));\n\n    if (d1 < d2) {\n      selected[0] = group.max.toISOString();\n    } else {\n      selected[1] = group.min.toISOString();\n    }\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateDuration1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min.toISOString();\n    selected[1] = group.max.toISOString();\n    return;\n  }\n\n  var selectionStart = moment.duration(selected[0]);\n  var selectionEnd = moment.duration(selected[1]);\n\n  if (group.min >= selectionEnd) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max.toISOString();\n  } else if (group.max <= selectionStart) {\n    // clicked outside to the left of selection\n    selected[0] = group.min.toISOString();\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    d1 = Math.abs(selectionStart - group.min);\n    d2 = Math.abs(selectionEnd - group.max);\n\n    if (d1 < d2) {\n      selected[0] = group.max.toISOString();\n    } else {\n      selected[1] = group.min.toISOString();\n    }\n  }\n}\n\n/**\n * Update the selection with a given group or interval\n * or, if no group is given, clear the selection.\n *\n * For categorial selections the following rules are used:\n * 1. none selected:\n *    add the group to the selection\n * 2. one selected and the group is the same:\n *    invert the selection\n * 3. one selected and the group is different:\n *    add the group to the selection\n * 4. more than one selected and the group is in the selection:\n *    remove the group from the selection\n * 5. more than one selected and the group is not in the selection:\n *    add the group to the selection\n *\n * For continuous selections the following rules are used:\n * 1. no range selected\n *    set the range equal to that of the group\n * 2. a range selected and the group is outside the selection:\n *    extend the selection to include the group\n * 3. a range selected and the group is inside the selection:\n *    set the endpoint closest to the group to that of the group\n *\n * @function\n * @param {Partition} Partition to update\n * @param {(string|number[])} Group or interval\n */\nfunction updateSelection (partition, group) {\n  if (!group) {\n    // Clear the selection (ie. all points are selected)\n    partition.selected.splice(0, partition.selected.length);\n  } else {\n    // Update the selection\n    if (partition.type === 'categorial' || partition.type === 'constant') {\n      updateCategorial1D(partition, group);\n    } else if (partition.type === 'continuous') {\n      updateContinuous1D(partition, group);\n    } else if (partition.type === 'datetime') {\n      updateDatetime1D(partition, group);\n    } else if (partition.type === 'duration') {\n      updateDuration1D(partition, group);\n    } else if (partition.type === 'text') {\n      updateText(partition, group);\n    } else {\n      console.error('Cannot update selection', partition.type);\n    }\n  }\n}\n\nmodule.exports = {\n  filterFunction: filterFunction,\n  updateSelection: updateSelection\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTI3OC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9zZWxlY3Rpb24uanM/NGY5ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNlbGVjdGlvblxuICogQG1vZHVsZSBjbGllbnQvdXRpbC1zZWxlY3Rpb25cbiAqL1xudmFyIG1pc3ZhbCA9IHJlcXVpcmUoJy4vbWlzdmFsJyk7XG52YXIgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50LXRpbWV6b25lJyk7XG5cbi8qXG4gKiBTZXQgYSBjYXRlZ29yaWFsIDFEIGZpbHRlciBmdW5jdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkNhdGVnb3JpYWwxRCAocGFydGl0aW9uKSB7XG4gIHZhciBoYXlzdGFjayA9IHt9O1xuXG4gIGlmICghcGFydGl0aW9uLnNlbGVjdGVkIHx8ICFwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKSB7XG4gICAgcGFydGl0aW9uLmdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgaGF5c3RhY2tbZ3JvdXAudmFsdWVdID0gdHJ1ZTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBwYXJ0aXRpb24uc2VsZWN0ZWQuZm9yRWFjaChmdW5jdGlvbiAoaCkge1xuICAgICAgaGF5c3RhY2tbaF0gPSB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgdmFyIG5lZWRsZSA9IGQ7XG4gICAgaWYgKCEobmVlZGxlIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICBuZWVkbGUgPSBbZF07XG4gICAgfVxuXG4gICAgdmFyIHNlbGVjdGVkID0gZmFsc2U7XG4gICAgbmVlZGxlLmZvckVhY2goZnVuY3Rpb24gKHMpIHtcbiAgICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQgfCBoYXlzdGFja1tzXTtcbiAgICB9KTtcbiAgICByZXR1cm4gISFzZWxlY3RlZDtcbiAgfTtcbn1cblxuLypcbiAqIFNldCBhIHRleHQgZmlsdGVyIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uVGV4dCAocGFydGl0aW9uKSB7XG4gIHZhciBoYXlzdGFjayA9IHt9O1xuXG4gIC8vIG5vdGhpbmcgc2VsZWN0ZWQsIHNvIGFsbCBzZWxlY3RlZFxuICBpZiAocGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuICB9XG5cbiAgcGFydGl0aW9uLnNlbGVjdGVkLmZvckVhY2goZnVuY3Rpb24gKGgpIHtcbiAgICBoYXlzdGFja1toXSA9IHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIHZhciBuZWVkbGUgPSBkO1xuICAgIGlmICghKG5lZWRsZSBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgbmVlZGxlID0gW2RdO1xuICAgIH1cblxuICAgIHZhciBzZWxlY3RlZCA9IGZhbHNlO1xuICAgIG5lZWRsZS5mb3JFYWNoKGZ1bmN0aW9uIChzKSB7XG4gICAgICBzZWxlY3RlZCA9IHNlbGVjdGVkIHwgaGF5c3RhY2tbc107XG4gICAgfSk7XG4gICAgcmV0dXJuICEhc2VsZWN0ZWQ7XG4gIH07XG59XG5cbi8qXG4gKiBTZXQgYSBjb250aW51b3VzIDFEIGZpbHRlciBmdW5jdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkNvbnRpbnVvdXMxRCAocGFydGl0aW9uKSB7XG4gIHZhciBlZGdlID0gcGFydGl0aW9uLm1heHZhbDtcbiAgdmFyIG1pbjtcbiAgdmFyIG1heDtcblxuICBpZiAoIXBhcnRpdGlvbi5zZWxlY3RlZCB8fCAhcGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCkge1xuICAgIG1pbiA9IHBhcnRpdGlvbi5taW52YWw7XG4gICAgbWF4ID0gcGFydGl0aW9uLm1heHZhbDtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHJldHVybiAoKGQgPj0gbWluICYmIGQgPD0gbWF4KSAmJiAoZCAhPT0gbWlzdmFsKSk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBwYXJ0aXRpb24uc2VsZWN0ZWRbMF07XG4gICAgbWF4ID0gcGFydGl0aW9uLnNlbGVjdGVkWzFdO1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgcmV0dXJuICgoZCA+PSBtaW4gJiYgZCA8IG1heCkgfHwgKChkID09PSBlZGdlKSAmJiAobWF4ID09PSBlZGdlKSkpICYmIChkICE9PSBtaXN2YWwpO1xuICAgIH07XG4gIH1cbn1cblxuLypcbiAqIFNldCBhIGNvbnRpbnVvdXMgMUQgZmlsdGVyIGZ1bmN0aW9uIG9uIGEgZGF0ZXRpbWUgZGltZW5zaW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uRGF0ZXRpbWUxRCAocGFydGl0aW9uKSB7XG4gIHZhciBlZGdlID0gbW9tZW50KHBhcnRpdGlvbi5tYXh2YWwpO1xuICB2YXIgbWluO1xuICB2YXIgbWF4O1xuXG4gIGlmICghcGFydGl0aW9uLnNlbGVjdGVkIHx8ICFwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKSB7XG4gICAgbWluID0gbW9tZW50KHBhcnRpdGlvbi5taW52YWwpO1xuICAgIG1heCA9IG1vbWVudChwYXJ0aXRpb24ubWF4dmFsKTtcblxuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIG0gPSBtb21lbnQoZCk7XG4gICAgICByZXR1cm4gKG0gIT09IG1pc3ZhbCkgJiYgIW0uaXNCZWZvcmUobWluKSAmJiAhbS5pc0FmdGVyKG1heCk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBtb21lbnQocGFydGl0aW9uLnNlbGVjdGVkWzBdKTtcbiAgICBtYXggPSBtb21lbnQocGFydGl0aW9uLnNlbGVjdGVkWzFdKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciBtID0gbW9tZW50KGQpO1xuICAgICAgcmV0dXJuIChtICE9PSBtaXN2YWwpICYmICFtaW4uaXNBZnRlcihtKSAmJiAobS5pc0JlZm9yZShtYXgpIHx8IChtYXguaXNTYW1lKGVkZ2UpICYmIG1heC5pc1NhbWUobSkpKTtcbiAgICB9O1xuICB9XG59XG5cbi8qXG4gKiBTZXQgYSBjb250aW51b3VzIDFEIGZpbHRlciBmdW5jdGlvbiBvbiBhIGR1cmF0aW9uIGRpbWVuc2lvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkR1cmF0aW9uMUQgKHBhcnRpdGlvbikge1xuICB2YXIgZWRnZSA9IHBhcnRpdGlvbi5tYXh2YWw7XG4gIHZhciBtaW47XG4gIHZhciBtYXg7XG5cbiAgaWYgKCFwYXJ0aXRpb24uc2VsZWN0ZWQgfHwgIXBhcnRpdGlvbi5zZWxlY3RlZC5sZW5ndGgpIHtcbiAgICBtaW4gPSBwYXJ0aXRpb24ubWludmFsO1xuICAgIG1heCA9IHBhcnRpdGlvbi5tYXh2YWw7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIG0gPSBtb21lbnQuZHVyYXRpb24oZCk7XG4gICAgICByZXR1cm4gbW9tZW50LmlzRHVyYXRpb24obSkgJiYgbSA+PSBtaW4gJiYgbSA8PSBtYXg7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBtb21lbnQuZHVyYXRpb24ocGFydGl0aW9uLnNlbGVjdGVkWzBdKTtcbiAgICBtYXggPSBtb21lbnQuZHVyYXRpb24ocGFydGl0aW9uLnNlbGVjdGVkWzFdKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIG0gPSBtb21lbnQuZHVyYXRpb24oZCk7XG4gICAgICByZXR1cm4gbW9tZW50LmlzRHVyYXRpb24obSkgJiYgbSA+PSBtaW4gJiYgKG0gPCBtYXggfHwgKG0gPD0gbWF4ICYmIG1heCA+PSBlZGdlKSk7XG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIEEgZmlsdGVyIGZ1bmN0aW9uIGJhc2VkIGZvciBhIHNpbmdsZSBwYXJ0aXRpb25cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge2Jvb2xlYW59IHNlbGVjdGVkIFRydWUgaWYgdGhlIGRhdGFwb2ludCBpcyBjdXJyZW50bHkgc2VsZWN0ZWRcbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhcG9pbnRcbiAqIEBtZW1iZXJvZiEgU2VsZWN0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgaWYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwgfHwgcGFydGl0aW9uLmlzQ29uc3RhbnQpIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25DYXRlZ29yaWFsMUQocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNDb250aW51b3VzKSB7XG4gICAgcmV0dXJuIGZpbHRlckZ1bmN0aW9uQ29udGludW91czFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzRGF0ZXRpbWUpIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25EYXRldGltZTFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzRHVyYXRpb24pIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25EdXJhdGlvbjFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzVGV4dCkge1xuICAgIHJldHVybiBmaWx0ZXJGdW5jdGlvblRleHQocGFydGl0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zb2xlLmVycm9yKCdDYW5ub3QgbWFrZSBmaWx0ZXJmdW5jdGlvbiBmb3IgcGFydGl0aW9uJywgcGFydGl0aW9uKTtcbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlQ2F0ZWdvcmlhbDFEIChwYXJ0aXRpb24sIGdyb3VwKSB7XG4gIHZhciBzZWxlY3RlZCA9IHBhcnRpdGlvbi5zZWxlY3RlZDtcblxuICBpZiAoc2VsZWN0ZWQubGVuZ3RoID09PSAwKSB7XG4gICAgLy8gMS4gbm9uZSBzZWxlY3RlZDpcbiAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgfSBlbHNlIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDEpIHtcbiAgICBpZiAoc2VsZWN0ZWRbMF0gPT09IGdyb3VwLnZhbHVlKSB7XG4gICAgICAvLyAyLiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyB0aGUgc2FtZTpcbiAgICAgIHNlbGVjdGVkLnNwbGljZSgwLCBzZWxlY3RlZC5sZW5ndGgpO1xuICAgICAgcGFydGl0aW9uLmdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChnKSB7XG4gICAgICAgIGlmIChnLnZhbHVlICE9PSBncm91cC52YWx1ZSkge1xuICAgICAgICAgIHNlbGVjdGVkLnB1c2goZy52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyAzLiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyBkaWZmZXJlbnQ6XG4gICAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGk7XG4gICAgaSA9IHNlbGVjdGVkLmluZGV4T2YoZ3JvdXAudmFsdWUpO1xuICAgIGlmIChpID4gLTEpIHtcbiAgICAgIC8vIDQuIG1vcmUgdGhhbiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyBpbiB0aGUgc2VsZWN0aW9uOlxuICAgICAgc2VsZWN0ZWQuc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyA1LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgbm90IGluIHRoZSBzZWxlY3Rpb246XG4gICAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvLyBhZnRlciBhZGQ6IGlmIGZpbHRlcnMgPT0gZ3JvdXBzLCByZXNldCBhbmQgZG9udCBmaWx0ZXJcbiAgaWYgKHNlbGVjdGVkLmxlbmd0aCA9PT0gcGFydGl0aW9uLmdyb3Vwcy5sZW5ndGgpIHtcbiAgICBzZWxlY3RlZC5zcGxpY2UoMCwgc2VsZWN0ZWQubGVuZ3RoKTtcbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlVGV4dCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgdmFyIGk7XG4gIGkgPSBzZWxlY3RlZC5pbmRleE9mKGdyb3VwLnZhbHVlKTtcbiAgaWYgKGkgPiAtMSkge1xuICAgIC8vIDEuIGluIHRoZSBzZWxlY3Rpb24sIHJlbW92ZSBpdFxuICAgIHNlbGVjdGVkLnNwbGljZShpLCAxKTtcbiAgfSBlbHNlIHtcbiAgICAvLyAyLiBub3QgaW4gdGhlIHNlbGVjdGlvbiwgYWRkIGl0XG4gICAgc2VsZWN0ZWQucHVzaChncm91cC52YWx1ZSk7XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7R3JvdXB9IGdyb3VwIC0gVGhlIGdyb3VwIHRvIGFkZCBvciByZW1vdmUgZnJvbSB0aGUgZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZUNvbnRpbnVvdXMxRCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgaWYgKHNlbGVjdGVkLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIG5vdGhpbmcgc2VsZWN0ZWQsIHN0YXJ0IGEgcmFuZ2VcbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbjtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heDtcbiAgfSBlbHNlIGlmIChncm91cC5taW4gPj0gc2VsZWN0ZWRbMV0pIHtcbiAgICAvLyBjbGlja2VkIG91dHNpZGUgdG8gdGhlIHJpZ3RoIG9mIHNlbGVjdGlvblxuICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4O1xuICB9IGVsc2UgaWYgKGdyb3VwLm1heCA8PSBzZWxlY3RlZFswXSkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbjtcbiAgfSBlbHNlIHtcbiAgICAvLyBjbGlja2VkIGluc2lkZSBzZWxlY3Rpb25cbiAgICB2YXIgZDEsIGQyO1xuICAgIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAgIGQxID0gTWF0aC5hYnMoTWF0aC5sb2coc2VsZWN0ZWRbMF0pIC0gTWF0aC5sb2coZ3JvdXAubWluKSk7XG4gICAgICBkMiA9IE1hdGguYWJzKE1hdGgubG9nKHNlbGVjdGVkWzFdKSAtIE1hdGgubG9nKGdyb3VwLm1heCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkMSA9IE1hdGguYWJzKHNlbGVjdGVkWzBdIC0gZ3JvdXAubWluKTtcbiAgICAgIGQyID0gTWF0aC5hYnMoc2VsZWN0ZWRbMV0gLSBncm91cC5tYXgpO1xuICAgIH1cbiAgICBpZiAoZDEgPCBkMikge1xuICAgICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW47XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4O1xuICAgIH1cbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGF0ZXRpbWUxRCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgaWYgKCFzZWxlY3RlZCB8fCBzZWxlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICAvLyBub3RoaW5nIHNlbGVjdGVkLCBzdGFydCBhIHJhbmdlXG4gICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxlY3Rpb25TdGFydCA9IG1vbWVudChzZWxlY3RlZFswXSk7XG4gIHZhciBzZWxlY3Rpb25FbmQgPSBtb21lbnQoc2VsZWN0ZWRbMV0pO1xuXG4gIGlmICghZ3JvdXAubWluLmlzQmVmb3JlKHNlbGVjdGlvbkVuZCkpIHtcbiAgICAvLyBjbGlja2VkIG91dHNpZGUgdG8gdGhlIHJpZ3RoIG9mIHNlbGVjdGlvblxuICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4LnRvSVNPU3RyaW5nKCk7XG4gIH0gZWxzZSBpZiAoIWdyb3VwLm1heC5pc0FmdGVyKHNlbGVjdGlvblN0YXJ0KSkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbi50b0lTT1N0cmluZygpO1xuICB9IGVsc2Uge1xuICAgIC8vIGNsaWNrZWQgaW5zaWRlIHNlbGVjdGlvblxuICAgIHZhciBkMSwgZDI7XG4gICAgZDEgPSBNYXRoLmFicyhzZWxlY3Rpb25TdGFydC5kaWZmKGdyb3VwLm1pbikpO1xuICAgIGQyID0gTWF0aC5hYnMoc2VsZWN0aW9uRW5kLmRpZmYoZ3JvdXAubWF4KSk7XG5cbiAgICBpZiAoZDEgPCBkMikge1xuICAgICAgc2VsZWN0ZWRbMF0gPSBncm91cC5tYXgudG9JU09TdHJpbmcoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZWN0ZWRbMV0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICB9XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7R3JvdXB9IGdyb3VwIC0gVGhlIGdyb3VwIHRvIGFkZCBvciByZW1vdmUgZnJvbSB0aGUgZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZUR1cmF0aW9uMUQgKHBhcnRpdGlvbiwgZ3JvdXApIHtcbiAgdmFyIHNlbGVjdGVkID0gcGFydGl0aW9uLnNlbGVjdGVkO1xuXG4gIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICAvLyBub3RoaW5nIHNlbGVjdGVkLCBzdGFydCBhIHJhbmdlXG4gICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxlY3Rpb25TdGFydCA9IG1vbWVudC5kdXJhdGlvbihzZWxlY3RlZFswXSk7XG4gIHZhciBzZWxlY3Rpb25FbmQgPSBtb21lbnQuZHVyYXRpb24oc2VsZWN0ZWRbMV0pO1xuXG4gIGlmIChncm91cC5taW4gPj0gc2VsZWN0aW9uRW5kKSB7XG4gICAgLy8gY2xpY2tlZCBvdXRzaWRlIHRvIHRoZSByaWd0aCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICB9IGVsc2UgaWYgKGdyb3VwLm1heCA8PSBzZWxlY3Rpb25TdGFydCkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbi50b0lTT1N0cmluZygpO1xuICB9IGVsc2Uge1xuICAgIC8vIGNsaWNrZWQgaW5zaWRlIHNlbGVjdGlvblxuICAgIHZhciBkMSwgZDI7XG4gICAgZDEgPSBNYXRoLmFicyhzZWxlY3Rpb25TdGFydCAtIGdyb3VwLm1pbik7XG4gICAgZDIgPSBNYXRoLmFicyhzZWxlY3Rpb25FbmQgLSBncm91cC5tYXgpO1xuXG4gICAgaWYgKGQxIDwgZDIpIHtcbiAgICAgIHNlbGVjdGVkWzBdID0gZ3JvdXAubWF4LnRvSVNPU3RyaW5nKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWluLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVXBkYXRlIHRoZSBzZWxlY3Rpb24gd2l0aCBhIGdpdmVuIGdyb3VwIG9yIGludGVydmFsXG4gKiBvciwgaWYgbm8gZ3JvdXAgaXMgZ2l2ZW4sIGNsZWFyIHRoZSBzZWxlY3Rpb24uXG4gKlxuICogRm9yIGNhdGVnb3JpYWwgc2VsZWN0aW9ucyB0aGUgZm9sbG93aW5nIHJ1bGVzIGFyZSB1c2VkOlxuICogMS4gbm9uZSBzZWxlY3RlZDpcbiAqICAgIGFkZCB0aGUgZ3JvdXAgdG8gdGhlIHNlbGVjdGlvblxuICogMi4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgdGhlIHNhbWU6XG4gKiAgICBpbnZlcnQgdGhlIHNlbGVjdGlvblxuICogMy4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgZGlmZmVyZW50OlxuICogICAgYWRkIHRoZSBncm91cCB0byB0aGUgc2VsZWN0aW9uXG4gKiA0LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgaW4gdGhlIHNlbGVjdGlvbjpcbiAqICAgIHJlbW92ZSB0aGUgZ3JvdXAgZnJvbSB0aGUgc2VsZWN0aW9uXG4gKiA1LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgbm90IGluIHRoZSBzZWxlY3Rpb246XG4gKiAgICBhZGQgdGhlIGdyb3VwIHRvIHRoZSBzZWxlY3Rpb25cbiAqXG4gKiBGb3IgY29udGludW91cyBzZWxlY3Rpb25zIHRoZSBmb2xsb3dpbmcgcnVsZXMgYXJlIHVzZWQ6XG4gKiAxLiBubyByYW5nZSBzZWxlY3RlZFxuICogICAgc2V0IHRoZSByYW5nZSBlcXVhbCB0byB0aGF0IG9mIHRoZSBncm91cFxuICogMi4gYSByYW5nZSBzZWxlY3RlZCBhbmQgdGhlIGdyb3VwIGlzIG91dHNpZGUgdGhlIHNlbGVjdGlvbjpcbiAqICAgIGV4dGVuZCB0aGUgc2VsZWN0aW9uIHRvIGluY2x1ZGUgdGhlIGdyb3VwXG4gKiAzLiBhIHJhbmdlIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgaW5zaWRlIHRoZSBzZWxlY3Rpb246XG4gKiAgICBzZXQgdGhlIGVuZHBvaW50IGNsb3Nlc3QgdG8gdGhlIGdyb3VwIHRvIHRoYXQgb2YgdGhlIGdyb3VwXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gUGFydGl0aW9uIHRvIHVwZGF0ZVxuICogQHBhcmFtIHsoc3RyaW5nfG51bWJlcltdKX0gR3JvdXAgb3IgaW50ZXJ2YWxcbiAqL1xuZnVuY3Rpb24gdXBkYXRlU2VsZWN0aW9uIChwYXJ0aXRpb24sIGdyb3VwKSB7XG4gIGlmICghZ3JvdXApIHtcbiAgICAvLyBDbGVhciB0aGUgc2VsZWN0aW9uIChpZS4gYWxsIHBvaW50cyBhcmUgc2VsZWN0ZWQpXG4gICAgcGFydGl0aW9uLnNlbGVjdGVkLnNwbGljZSgwLCBwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBVcGRhdGUgdGhlIHNlbGVjdGlvblxuICAgIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2NhdGVnb3JpYWwnIHx8IHBhcnRpdGlvbi50eXBlID09PSAnY29uc3RhbnQnKSB7XG4gICAgICB1cGRhdGVDYXRlZ29yaWFsMUQocGFydGl0aW9uLCBncm91cCk7XG4gICAgfSBlbHNlIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2NvbnRpbnVvdXMnKSB7XG4gICAgICB1cGRhdGVDb250aW51b3VzMUQocGFydGl0aW9uLCBncm91cCk7XG4gICAgfSBlbHNlIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgdXBkYXRlRGF0ZXRpbWUxRChwYXJ0aXRpb24sIGdyb3VwKTtcbiAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi50eXBlID09PSAnZHVyYXRpb24nKSB7XG4gICAgICB1cGRhdGVEdXJhdGlvbjFEKHBhcnRpdGlvbiwgZ3JvdXApO1xuICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLnR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgdXBkYXRlVGV4dChwYXJ0aXRpb24sIGdyb3VwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcignQ2Fubm90IHVwZGF0ZSBzZWxlY3Rpb24nLCBwYXJ0aXRpb24udHlwZSk7XG4gICAgfVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBmaWx0ZXJGdW5jdGlvbjogZmlsdGVyRnVuY3Rpb24sXG4gIHVwZGF0ZVNlbGVjdGlvbjogdXBkYXRlU2VsZWN0aW9uXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1278\n")},"181d":function(module,exports,__webpack_require__){eval("/**\n * Module dependencies.\n */\n\nvar Transport = __webpack_require__(/*! ../transport */ \"0d97\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar yeast = __webpack_require__(/*! yeast */ \"c16d\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:polling');\n\n/**\n * Module exports.\n */\n\nmodule.exports = Polling;\n\n/**\n * Is XHR2 supported?\n */\n\nvar hasXHR2 = (function () {\n  var XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ \"86e3\");\n  var xhr = new XMLHttpRequest({ xdomain: false });\n  return null != xhr.responseType;\n})();\n\n/**\n * Polling interface.\n *\n * @param {Object} opts\n * @api private\n */\n\nfunction Polling (opts) {\n  var forceBase64 = (opts && opts.forceBase64);\n  if (!hasXHR2 || forceBase64) {\n    this.supportsBinary = false;\n  }\n  Transport.call(this, opts);\n}\n\n/**\n * Inherits from Transport.\n */\n\ninherit(Polling, Transport);\n\n/**\n * Transport name.\n */\n\nPolling.prototype.name = 'polling';\n\n/**\n * Opens the socket (triggers polling). We write a PING message to determine\n * when the transport is open.\n *\n * @api private\n */\n\nPolling.prototype.doOpen = function () {\n  this.poll();\n};\n\n/**\n * Pauses polling.\n *\n * @param {Function} callback upon buffers are flushed and transport is paused\n * @api private\n */\n\nPolling.prototype.pause = function (onPause) {\n  var self = this;\n\n  this.readyState = 'pausing';\n\n  function pause () {\n    debug('paused');\n    self.readyState = 'paused';\n    onPause();\n  }\n\n  if (this.polling || !this.writable) {\n    var total = 0;\n\n    if (this.polling) {\n      debug('we are currently polling - waiting to pause');\n      total++;\n      this.once('pollComplete', function () {\n        debug('pre-pause polling complete');\n        --total || pause();\n      });\n    }\n\n    if (!this.writable) {\n      debug('we are currently writing - waiting to pause');\n      total++;\n      this.once('drain', function () {\n        debug('pre-pause writing complete');\n        --total || pause();\n      });\n    }\n  } else {\n    pause();\n  }\n};\n\n/**\n * Starts polling cycle.\n *\n * @api public\n */\n\nPolling.prototype.poll = function () {\n  debug('polling');\n  this.polling = true;\n  this.doPoll();\n  this.emit('poll');\n};\n\n/**\n * Overloads onData to detect payloads.\n *\n * @api private\n */\n\nPolling.prototype.onData = function (data) {\n  var self = this;\n  debug('polling got data %s', data);\n  var callback = function (packet, index, total) {\n    // if its the first message we consider the transport open\n    if ('opening' === self.readyState) {\n      self.onOpen();\n    }\n\n    // if its a close packet, we close the ongoing requests\n    if ('close' === packet.type) {\n      self.onClose();\n      return false;\n    }\n\n    // otherwise bypass onData and handle the message\n    self.onPacket(packet);\n  };\n\n  // decode payload\n  parser.decodePayload(data, this.socket.binaryType, callback);\n\n  // if an event did not trigger closing\n  if ('closed' !== this.readyState) {\n    // if we got data we're not polling\n    this.polling = false;\n    this.emit('pollComplete');\n\n    if ('open' === this.readyState) {\n      this.poll();\n    } else {\n      debug('ignoring poll - transport state \"%s\"', this.readyState);\n    }\n  }\n};\n\n/**\n * For polling, send a close packet.\n *\n * @api private\n */\n\nPolling.prototype.doClose = function () {\n  var self = this;\n\n  function close () {\n    debug('writing close packet');\n    self.write([{ type: 'close' }]);\n  }\n\n  if ('open' === this.readyState) {\n    debug('transport open - closing');\n    close();\n  } else {\n    // in case we're trying to close while\n    // handshaking is in progress (GH-164)\n    debug('transport not open - deferring close');\n    this.once('open', close);\n  }\n};\n\n/**\n * Writes a packets payload.\n *\n * @param {Array} data packets\n * @param {Function} drain callback\n * @api private\n */\n\nPolling.prototype.write = function (packets) {\n  var self = this;\n  this.writable = false;\n  var callbackfn = function () {\n    self.writable = true;\n    self.emit('drain');\n  };\n\n  parser.encodePayload(packets, this.supportsBinary, function (data) {\n    self.doWrite(data, callbackfn);\n  });\n};\n\n/**\n * Generates uri for connection.\n *\n * @api private\n */\n\nPolling.prototype.uri = function () {\n  var query = this.query || {};\n  var schema = this.secure ? 'https' : 'http';\n  var port = '';\n\n  // cache busting is forced\n  if (false !== this.timestampRequests) {\n    query[this.timestampParam] = yeast();\n  }\n\n  if (!this.supportsBinary && !query.sid) {\n    query.b64 = 1;\n  }\n\n  query = parseqs.encode(query);\n\n  // avoid port if default for schema\n  if (this.port && (('https' === schema && Number(this.port) !== 443) ||\n     ('http' === schema && Number(this.port) !== 80))) {\n    port = ':' + this.port;\n  }\n\n  // prepend ? to query\n  if (query.length) {\n    query = '?' + query;\n  }\n\n  var ipv6 = this.hostname.indexOf(':') !== -1;\n  return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTgxZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLmpzP2U1ZjkiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBUcmFuc3BvcnQgPSByZXF1aXJlKCcuLi90cmFuc3BvcnQnKTtcbnZhciBwYXJzZXFzID0gcmVxdWlyZSgncGFyc2VxcycpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcbnZhciB5ZWFzdCA9IHJlcXVpcmUoJ3llYXN0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnBvbGxpbmcnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBvbGxpbmc7XG5cbi8qKlxuICogSXMgWEhSMiBzdXBwb3J0ZWQ/XG4gKi9cblxudmFyIGhhc1hIUjIgPSAoZnVuY3Rpb24gKCkge1xuICB2YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdC1zc2wnKTtcbiAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCh7IHhkb21haW46IGZhbHNlIH0pO1xuICByZXR1cm4gbnVsbCAhPSB4aHIucmVzcG9uc2VUeXBlO1xufSkoKTtcblxuLyoqXG4gKiBQb2xsaW5nIGludGVyZmFjZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gUG9sbGluZyAob3B0cykge1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKCFoYXNYSFIyIHx8IGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIFRyYW5zcG9ydC5jYWxsKHRoaXMsIG9wdHMpO1xufVxuXG4vKipcbiAqIEluaGVyaXRzIGZyb20gVHJhbnNwb3J0LlxuICovXG5cbmluaGVyaXQoUG9sbGluZywgVHJhbnNwb3J0KTtcblxuLyoqXG4gKiBUcmFuc3BvcnQgbmFtZS5cbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5uYW1lID0gJ3BvbGxpbmcnO1xuXG4vKipcbiAqIE9wZW5zIHRoZSBzb2NrZXQgKHRyaWdnZXJzIHBvbGxpbmcpLiBXZSB3cml0ZSBhIFBJTkcgbWVzc2FnZSB0byBkZXRlcm1pbmVcbiAqIHdoZW4gdGhlIHRyYW5zcG9ydCBpcyBvcGVuLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLmRvT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5wb2xsKCk7XG59O1xuXG4vKipcbiAqIFBhdXNlcyBwb2xsaW5nLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHVwb24gYnVmZmVycyBhcmUgZmx1c2hlZCBhbmQgdHJhbnNwb3J0IGlzIHBhdXNlZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAob25QYXVzZSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5yZWFkeVN0YXRlID0gJ3BhdXNpbmcnO1xuXG4gIGZ1bmN0aW9uIHBhdXNlICgpIHtcbiAgICBkZWJ1ZygncGF1c2VkJyk7XG4gICAgc2VsZi5yZWFkeVN0YXRlID0gJ3BhdXNlZCc7XG4gICAgb25QYXVzZSgpO1xuICB9XG5cbiAgaWYgKHRoaXMucG9sbGluZyB8fCAhdGhpcy53cml0YWJsZSkge1xuICAgIHZhciB0b3RhbCA9IDA7XG5cbiAgICBpZiAodGhpcy5wb2xsaW5nKSB7XG4gICAgICBkZWJ1Zygnd2UgYXJlIGN1cnJlbnRseSBwb2xsaW5nIC0gd2FpdGluZyB0byBwYXVzZScpO1xuICAgICAgdG90YWwrKztcbiAgICAgIHRoaXMub25jZSgncG9sbENvbXBsZXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZWJ1ZygncHJlLXBhdXNlIHBvbGxpbmcgY29tcGxldGUnKTtcbiAgICAgICAgLS10b3RhbCB8fCBwYXVzZSgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLndyaXRhYmxlKSB7XG4gICAgICBkZWJ1Zygnd2UgYXJlIGN1cnJlbnRseSB3cml0aW5nIC0gd2FpdGluZyB0byBwYXVzZScpO1xuICAgICAgdG90YWwrKztcbiAgICAgIHRoaXMub25jZSgnZHJhaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlYnVnKCdwcmUtcGF1c2Ugd3JpdGluZyBjb21wbGV0ZScpO1xuICAgICAgICAtLXRvdGFsIHx8IHBhdXNlKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcGF1c2UoKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTdGFydHMgcG9sbGluZyBjeWNsZS5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblBvbGxpbmcucHJvdG90eXBlLnBvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCdwb2xsaW5nJyk7XG4gIHRoaXMucG9sbGluZyA9IHRydWU7XG4gIHRoaXMuZG9Qb2xsKCk7XG4gIHRoaXMuZW1pdCgncG9sbCcpO1xufTtcblxuLyoqXG4gKiBPdmVybG9hZHMgb25EYXRhIHRvIGRldGVjdCBwYXlsb2Fkcy5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5vbkRhdGEgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGRlYnVnKCdwb2xsaW5nIGdvdCBkYXRhICVzJywgZGF0YSk7XG4gIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uIChwYWNrZXQsIGluZGV4LCB0b3RhbCkge1xuICAgIC8vIGlmIGl0cyB0aGUgZmlyc3QgbWVzc2FnZSB3ZSBjb25zaWRlciB0aGUgdHJhbnNwb3J0IG9wZW5cbiAgICBpZiAoJ29wZW5pbmcnID09PSBzZWxmLnJlYWR5U3RhdGUpIHtcbiAgICAgIHNlbGYub25PcGVuKCk7XG4gICAgfVxuXG4gICAgLy8gaWYgaXRzIGEgY2xvc2UgcGFja2V0LCB3ZSBjbG9zZSB0aGUgb25nb2luZyByZXF1ZXN0c1xuICAgIGlmICgnY2xvc2UnID09PSBwYWNrZXQudHlwZSkge1xuICAgICAgc2VsZi5vbkNsb3NlKCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gb3RoZXJ3aXNlIGJ5cGFzcyBvbkRhdGEgYW5kIGhhbmRsZSB0aGUgbWVzc2FnZVxuICAgIHNlbGYub25QYWNrZXQocGFja2V0KTtcbiAgfTtcblxuICAvLyBkZWNvZGUgcGF5bG9hZFxuICBwYXJzZXIuZGVjb2RlUGF5bG9hZChkYXRhLCB0aGlzLnNvY2tldC5iaW5hcnlUeXBlLCBjYWxsYmFjayk7XG5cbiAgLy8gaWYgYW4gZXZlbnQgZGlkIG5vdCB0cmlnZ2VyIGNsb3NpbmdcbiAgaWYgKCdjbG9zZWQnICE9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAvLyBpZiB3ZSBnb3QgZGF0YSB3ZSdyZSBub3QgcG9sbGluZ1xuICAgIHRoaXMucG9sbGluZyA9IGZhbHNlO1xuICAgIHRoaXMuZW1pdCgncG9sbENvbXBsZXRlJyk7XG5cbiAgICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAgIHRoaXMucG9sbCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1ZygnaWdub3JpbmcgcG9sbCAtIHRyYW5zcG9ydCBzdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBGb3IgcG9sbGluZywgc2VuZCBhIGNsb3NlIHBhY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gY2xvc2UgKCkge1xuICAgIGRlYnVnKCd3cml0aW5nIGNsb3NlIHBhY2tldCcpO1xuICAgIHNlbGYud3JpdGUoW3sgdHlwZTogJ2Nsb3NlJyB9XSk7XG4gIH1cblxuICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICBkZWJ1ZygndHJhbnNwb3J0IG9wZW4gLSBjbG9zaW5nJyk7XG4gICAgY2xvc2UoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbiBjYXNlIHdlJ3JlIHRyeWluZyB0byBjbG9zZSB3aGlsZVxuICAgIC8vIGhhbmRzaGFraW5nIGlzIGluIHByb2dyZXNzIChHSC0xNjQpXG4gICAgZGVidWcoJ3RyYW5zcG9ydCBub3Qgb3BlbiAtIGRlZmVycmluZyBjbG9zZScpO1xuICAgIHRoaXMub25jZSgnb3BlbicsIGNsb3NlKTtcbiAgfVxufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBwYWNrZXRzIHBheWxvYWQuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gZGF0YSBwYWNrZXRzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBkcmFpbiBjYWxsYmFja1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAocGFja2V0cykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcbiAgdmFyIGNhbGxiYWNrZm4gPSBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi53cml0YWJsZSA9IHRydWU7XG4gICAgc2VsZi5lbWl0KCdkcmFpbicpO1xuICB9O1xuXG4gIHBhcnNlci5lbmNvZGVQYXlsb2FkKHBhY2tldHMsIHRoaXMuc3VwcG9ydHNCaW5hcnksIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgc2VsZi5kb1dyaXRlKGRhdGEsIGNhbGxiYWNrZm4pO1xuICB9KTtcbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIHVyaSBmb3IgY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS51cmkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBxdWVyeSA9IHRoaXMucXVlcnkgfHwge307XG4gIHZhciBzY2hlbWEgPSB0aGlzLnNlY3VyZSA/ICdodHRwcycgOiAnaHR0cCc7XG4gIHZhciBwb3J0ID0gJyc7XG5cbiAgLy8gY2FjaGUgYnVzdGluZyBpcyBmb3JjZWRcbiAgaWYgKGZhbHNlICE9PSB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzKSB7XG4gICAgcXVlcnlbdGhpcy50aW1lc3RhbXBQYXJhbV0gPSB5ZWFzdCgpO1xuICB9XG5cbiAgaWYgKCF0aGlzLnN1cHBvcnRzQmluYXJ5ICYmICFxdWVyeS5zaWQpIHtcbiAgICBxdWVyeS5iNjQgPSAxO1xuICB9XG5cbiAgcXVlcnkgPSBwYXJzZXFzLmVuY29kZShxdWVyeSk7XG5cbiAgLy8gYXZvaWQgcG9ydCBpZiBkZWZhdWx0IGZvciBzY2hlbWFcbiAgaWYgKHRoaXMucG9ydCAmJiAoKCdodHRwcycgPT09IHNjaGVtYSAmJiBOdW1iZXIodGhpcy5wb3J0KSAhPT0gNDQzKSB8fFxuICAgICAoJ2h0dHAnID09PSBzY2hlbWEgJiYgTnVtYmVyKHRoaXMucG9ydCkgIT09IDgwKSkpIHtcbiAgICBwb3J0ID0gJzonICsgdGhpcy5wb3J0O1xuICB9XG5cbiAgLy8gcHJlcGVuZCA/IHRvIHF1ZXJ5XG4gIGlmIChxdWVyeS5sZW5ndGgpIHtcbiAgICBxdWVyeSA9ICc/JyArIHF1ZXJ5O1xuICB9XG5cbiAgdmFyIGlwdjYgPSB0aGlzLmhvc3RuYW1lLmluZGV4T2YoJzonKSAhPT0gLTE7XG4gIHJldHVybiBzY2hlbWEgKyAnOi8vJyArIChpcHY2ID8gJ1snICsgdGhpcy5ob3N0bmFtZSArICddJyA6IHRoaXMuaG9zdG5hbWUpICsgcG9ydCArIHRoaXMucGF0aCArIHF1ZXJ5O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///181d\n")},"1e1f":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar eio = __webpack_require__(/*! engine.io-client */ \"c59b\");\nvar Socket = __webpack_require__(/*! ./socket */ \"4c13\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar on = __webpack_require__(/*! ./on */ \"faaa\");\nvar bind = __webpack_require__(/*! component-bind */ \"b6f6\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:manager');\nvar indexOf = __webpack_require__(/*! indexof */ \"3294\");\nvar Backoff = __webpack_require__(/*! backo2 */ \"f942\");\n\n/**\n * IE6+ hasOwnProperty\n */\n\nvar has = Object.prototype.hasOwnProperty;\n\n/**\n * Module exports\n */\n\nmodule.exports = Manager;\n\n/**\n * `Manager` constructor.\n *\n * @param {String} engine instance or engine uri/opts\n * @param {Object} options\n * @api public\n */\n\nfunction Manager (uri, opts) {\n  if (!(this instanceof Manager)) return new Manager(uri, opts);\n  if (uri && ('object' === typeof uri)) {\n    opts = uri;\n    uri = undefined;\n  }\n  opts = opts || {};\n\n  opts.path = opts.path || '/socket.io';\n  this.nsps = {};\n  this.subs = [];\n  this.opts = opts;\n  this.reconnection(opts.reconnection !== false);\n  this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);\n  this.reconnectionDelay(opts.reconnectionDelay || 1000);\n  this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);\n  this.randomizationFactor(opts.randomizationFactor || 0.5);\n  this.backoff = new Backoff({\n    min: this.reconnectionDelay(),\n    max: this.reconnectionDelayMax(),\n    jitter: this.randomizationFactor()\n  });\n  this.timeout(null == opts.timeout ? 20000 : opts.timeout);\n  this.readyState = 'closed';\n  this.uri = uri;\n  this.connecting = [];\n  this.lastPing = null;\n  this.encoding = false;\n  this.packetBuffer = [];\n  this.encoder = new parser.Encoder();\n  this.decoder = new parser.Decoder();\n  this.autoConnect = opts.autoConnect !== false;\n  if (this.autoConnect) this.open();\n}\n\n/**\n * Propagate given event to sockets and emit on `this`\n *\n * @api private\n */\n\nManager.prototype.emitAll = function () {\n  this.emit.apply(this, arguments);\n  for (var nsp in this.nsps) {\n    if (has.call(this.nsps, nsp)) {\n      this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);\n    }\n  }\n};\n\n/**\n * Update `socket.id` of all sockets\n *\n * @api private\n */\n\nManager.prototype.updateSocketIds = function () {\n  for (var nsp in this.nsps) {\n    if (has.call(this.nsps, nsp)) {\n      this.nsps[nsp].id = this.engine.id;\n    }\n  }\n};\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Manager.prototype);\n\n/**\n * Sets the `reconnection` config.\n *\n * @param {Boolean} true/false if it should automatically reconnect\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnection = function (v) {\n  if (!arguments.length) return this._reconnection;\n  this._reconnection = !!v;\n  return this;\n};\n\n/**\n * Sets the reconnection attempts config.\n *\n * @param {Number} max reconnection attempts before giving up\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionAttempts = function (v) {\n  if (!arguments.length) return this._reconnectionAttempts;\n  this._reconnectionAttempts = v;\n  return this;\n};\n\n/**\n * Sets the delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionDelay = function (v) {\n  if (!arguments.length) return this._reconnectionDelay;\n  this._reconnectionDelay = v;\n  this.backoff && this.backoff.setMin(v);\n  return this;\n};\n\nManager.prototype.randomizationFactor = function (v) {\n  if (!arguments.length) return this._randomizationFactor;\n  this._randomizationFactor = v;\n  this.backoff && this.backoff.setJitter(v);\n  return this;\n};\n\n/**\n * Sets the maximum delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionDelayMax = function (v) {\n  if (!arguments.length) return this._reconnectionDelayMax;\n  this._reconnectionDelayMax = v;\n  this.backoff && this.backoff.setMax(v);\n  return this;\n};\n\n/**\n * Sets the connection timeout. `false` to disable\n *\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.timeout = function (v) {\n  if (!arguments.length) return this._timeout;\n  this._timeout = v;\n  return this;\n};\n\n/**\n * Starts trying to reconnect if reconnection is enabled and we have not\n * started reconnecting yet\n *\n * @api private\n */\n\nManager.prototype.maybeReconnectOnOpen = function () {\n  // Only try to reconnect if it's the first time we're connecting\n  if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) {\n    // keeps reconnection from firing twice for the same reconnection loop\n    this.reconnect();\n  }\n};\n\n/**\n * Sets the current transport `socket`.\n *\n * @param {Function} optional, callback\n * @return {Manager} self\n * @api public\n */\n\nManager.prototype.open =\nManager.prototype.connect = function (fn, opts) {\n  debug('readyState %s', this.readyState);\n  if (~this.readyState.indexOf('open')) return this;\n\n  debug('opening %s', this.uri);\n  this.engine = eio(this.uri, this.opts);\n  var socket = this.engine;\n  var self = this;\n  this.readyState = 'opening';\n  this.skipReconnect = false;\n\n  // emit `open`\n  var openSub = on(socket, 'open', function () {\n    self.onopen();\n    fn && fn();\n  });\n\n  // emit `connect_error`\n  var errorSub = on(socket, 'error', function (data) {\n    debug('connect_error');\n    self.cleanup();\n    self.readyState = 'closed';\n    self.emitAll('connect_error', data);\n    if (fn) {\n      var err = new Error('Connection error');\n      err.data = data;\n      fn(err);\n    } else {\n      // Only do this if there is no fn to handle the error\n      self.maybeReconnectOnOpen();\n    }\n  });\n\n  // emit `connect_timeout`\n  if (false !== this._timeout) {\n    var timeout = this._timeout;\n    debug('connect attempt will timeout after %d', timeout);\n\n    // set timer\n    var timer = setTimeout(function () {\n      debug('connect attempt timed out after %d', timeout);\n      openSub.destroy();\n      socket.close();\n      socket.emit('error', 'timeout');\n      self.emitAll('connect_timeout', timeout);\n    }, timeout);\n\n    this.subs.push({\n      destroy: function () {\n        clearTimeout(timer);\n      }\n    });\n  }\n\n  this.subs.push(openSub);\n  this.subs.push(errorSub);\n\n  return this;\n};\n\n/**\n * Called upon transport open.\n *\n * @api private\n */\n\nManager.prototype.onopen = function () {\n  debug('open');\n\n  // clear old subs\n  this.cleanup();\n\n  // mark as open\n  this.readyState = 'open';\n  this.emit('open');\n\n  // add new subs\n  var socket = this.engine;\n  this.subs.push(on(socket, 'data', bind(this, 'ondata')));\n  this.subs.push(on(socket, 'ping', bind(this, 'onping')));\n  this.subs.push(on(socket, 'pong', bind(this, 'onpong')));\n  this.subs.push(on(socket, 'error', bind(this, 'onerror')));\n  this.subs.push(on(socket, 'close', bind(this, 'onclose')));\n  this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));\n};\n\n/**\n * Called upon a ping.\n *\n * @api private\n */\n\nManager.prototype.onping = function () {\n  this.lastPing = new Date();\n  this.emitAll('ping');\n};\n\n/**\n * Called upon a packet.\n *\n * @api private\n */\n\nManager.prototype.onpong = function () {\n  this.emitAll('pong', new Date() - this.lastPing);\n};\n\n/**\n * Called with data.\n *\n * @api private\n */\n\nManager.prototype.ondata = function (data) {\n  this.decoder.add(data);\n};\n\n/**\n * Called when parser fully decodes a packet.\n *\n * @api private\n */\n\nManager.prototype.ondecoded = function (packet) {\n  this.emit('packet', packet);\n};\n\n/**\n * Called upon socket error.\n *\n * @api private\n */\n\nManager.prototype.onerror = function (err) {\n  debug('error', err);\n  this.emitAll('error', err);\n};\n\n/**\n * Creates a new socket for the given `nsp`.\n *\n * @return {Socket}\n * @api public\n */\n\nManager.prototype.socket = function (nsp, opts) {\n  var socket = this.nsps[nsp];\n  if (!socket) {\n    socket = new Socket(this, nsp, opts);\n    this.nsps[nsp] = socket;\n    var self = this;\n    socket.on('connecting', onConnecting);\n    socket.on('connect', function () {\n      socket.id = self.engine.id;\n    });\n\n    if (this.autoConnect) {\n      // manually call here since connecting evnet is fired before listening\n      onConnecting();\n    }\n  }\n\n  function onConnecting () {\n    if (!~indexOf(self.connecting, socket)) {\n      self.connecting.push(socket);\n    }\n  }\n\n  return socket;\n};\n\n/**\n * Called upon a socket close.\n *\n * @param {Socket} socket\n */\n\nManager.prototype.destroy = function (socket) {\n  var index = indexOf(this.connecting, socket);\n  if (~index) this.connecting.splice(index, 1);\n  if (this.connecting.length) return;\n\n  this.close();\n};\n\n/**\n * Writes a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nManager.prototype.packet = function (packet) {\n  debug('writing packet %j', packet);\n  var self = this;\n  if (packet.query && packet.type === 0) packet.nsp += '?' + packet.query;\n\n  if (!self.encoding) {\n    // encode, then write to engine with result\n    self.encoding = true;\n    this.encoder.encode(packet, function (encodedPackets) {\n      for (var i = 0; i < encodedPackets.length; i++) {\n        self.engine.write(encodedPackets[i], packet.options);\n      }\n      self.encoding = false;\n      self.processPacketQueue();\n    });\n  } else { // add packet to the queue\n    self.packetBuffer.push(packet);\n  }\n};\n\n/**\n * If packet buffer is non-empty, begins encoding the\n * next packet in line.\n *\n * @api private\n */\n\nManager.prototype.processPacketQueue = function () {\n  if (this.packetBuffer.length > 0 && !this.encoding) {\n    var pack = this.packetBuffer.shift();\n    this.packet(pack);\n  }\n};\n\n/**\n * Clean up transport subscriptions and packet buffer.\n *\n * @api private\n */\n\nManager.prototype.cleanup = function () {\n  debug('cleanup');\n\n  var subsLength = this.subs.length;\n  for (var i = 0; i < subsLength; i++) {\n    var sub = this.subs.shift();\n    sub.destroy();\n  }\n\n  this.packetBuffer = [];\n  this.encoding = false;\n  this.lastPing = null;\n\n  this.decoder.destroy();\n};\n\n/**\n * Close the current socket.\n *\n * @api private\n */\n\nManager.prototype.close =\nManager.prototype.disconnect = function () {\n  debug('disconnect');\n  this.skipReconnect = true;\n  this.reconnecting = false;\n  if ('opening' === this.readyState) {\n    // `onclose` will not fire because\n    // an open event never happened\n    this.cleanup();\n  }\n  this.backoff.reset();\n  this.readyState = 'closed';\n  if (this.engine) this.engine.close();\n};\n\n/**\n * Called upon engine close.\n *\n * @api private\n */\n\nManager.prototype.onclose = function (reason) {\n  debug('onclose');\n\n  this.cleanup();\n  this.backoff.reset();\n  this.readyState = 'closed';\n  this.emit('close', reason);\n\n  if (this._reconnection && !this.skipReconnect) {\n    this.reconnect();\n  }\n};\n\n/**\n * Attempt a reconnection.\n *\n * @api private\n */\n\nManager.prototype.reconnect = function () {\n  if (this.reconnecting || this.skipReconnect) return this;\n\n  var self = this;\n\n  if (this.backoff.attempts >= this._reconnectionAttempts) {\n    debug('reconnect failed');\n    this.backoff.reset();\n    this.emitAll('reconnect_failed');\n    this.reconnecting = false;\n  } else {\n    var delay = this.backoff.duration();\n    debug('will wait %dms before reconnect attempt', delay);\n\n    this.reconnecting = true;\n    var timer = setTimeout(function () {\n      if (self.skipReconnect) return;\n\n      debug('attempting reconnect');\n      self.emitAll('reconnect_attempt', self.backoff.attempts);\n      self.emitAll('reconnecting', self.backoff.attempts);\n\n      // check again for the case socket closed in above events\n      if (self.skipReconnect) return;\n\n      self.open(function (err) {\n        if (err) {\n          debug('reconnect attempt error');\n          self.reconnecting = false;\n          self.reconnect();\n          self.emitAll('reconnect_error', err.data);\n        } else {\n          debug('reconnect success');\n          self.onreconnect();\n        }\n      });\n    }, delay);\n\n    this.subs.push({\n      destroy: function () {\n        clearTimeout(timer);\n      }\n    });\n  }\n};\n\n/**\n * Called upon successful reconnect.\n *\n * @api private\n */\n\nManager.prototype.onreconnect = function () {\n  var attempt = this.backoff.attempts;\n  this.reconnecting = false;\n  this.backoff.reset();\n  this.updateSocketIds();\n  this.emitAll('reconnect', attempt);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMWUxZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvbWFuYWdlci5qcz9mMDk3Il0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBlaW8gPSByZXF1aXJlKCdlbmdpbmUuaW8tY2xpZW50Jyk7XG52YXIgU29ja2V0ID0gcmVxdWlyZSgnLi9zb2NrZXQnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgb24gPSByZXF1aXJlKCcuL29uJyk7XG52YXIgYmluZCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1iaW5kJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdzb2NrZXQuaW8tY2xpZW50Om1hbmFnZXInKTtcbnZhciBpbmRleE9mID0gcmVxdWlyZSgnaW5kZXhvZicpO1xudmFyIEJhY2tvZmYgPSByZXF1aXJlKCdiYWNrbzInKTtcblxuLyoqXG4gKiBJRTYrIGhhc093blByb3BlcnR5XG4gKi9cblxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hbmFnZXI7XG5cbi8qKlxuICogYE1hbmFnZXJgIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBlbmdpbmUgaW5zdGFuY2Ugb3IgZW5naW5lIHVyaS9vcHRzXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBNYW5hZ2VyICh1cmksIG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE1hbmFnZXIpKSByZXR1cm4gbmV3IE1hbmFnZXIodXJpLCBvcHRzKTtcbiAgaWYgKHVyaSAmJiAoJ29iamVjdCcgPT09IHR5cGVvZiB1cmkpKSB7XG4gICAgb3B0cyA9IHVyaTtcbiAgICB1cmkgPSB1bmRlZmluZWQ7XG4gIH1cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgb3B0cy5wYXRoID0gb3B0cy5wYXRoIHx8ICcvc29ja2V0LmlvJztcbiAgdGhpcy5uc3BzID0ge307XG4gIHRoaXMuc3VicyA9IFtdO1xuICB0aGlzLm9wdHMgPSBvcHRzO1xuICB0aGlzLnJlY29ubmVjdGlvbihvcHRzLnJlY29ubmVjdGlvbiAhPT0gZmFsc2UpO1xuICB0aGlzLnJlY29ubmVjdGlvbkF0dGVtcHRzKG9wdHMucmVjb25uZWN0aW9uQXR0ZW1wdHMgfHwgSW5maW5pdHkpO1xuICB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KG9wdHMucmVjb25uZWN0aW9uRGVsYXkgfHwgMTAwMCk7XG4gIHRoaXMucmVjb25uZWN0aW9uRGVsYXlNYXgob3B0cy5yZWNvbm5lY3Rpb25EZWxheU1heCB8fCA1MDAwKTtcbiAgdGhpcy5yYW5kb21pemF0aW9uRmFjdG9yKG9wdHMucmFuZG9taXphdGlvbkZhY3RvciB8fCAwLjUpO1xuICB0aGlzLmJhY2tvZmYgPSBuZXcgQmFja29mZih7XG4gICAgbWluOiB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KCksXG4gICAgbWF4OiB0aGlzLnJlY29ubmVjdGlvbkRlbGF5TWF4KCksXG4gICAgaml0dGVyOiB0aGlzLnJhbmRvbWl6YXRpb25GYWN0b3IoKVxuICB9KTtcbiAgdGhpcy50aW1lb3V0KG51bGwgPT0gb3B0cy50aW1lb3V0ID8gMjAwMDAgOiBvcHRzLnRpbWVvdXQpO1xuICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgdGhpcy51cmkgPSB1cmk7XG4gIHRoaXMuY29ubmVjdGluZyA9IFtdO1xuICB0aGlzLmxhc3RQaW5nID0gbnVsbDtcbiAgdGhpcy5lbmNvZGluZyA9IGZhbHNlO1xuICB0aGlzLnBhY2tldEJ1ZmZlciA9IFtdO1xuICB0aGlzLmVuY29kZXIgPSBuZXcgcGFyc2VyLkVuY29kZXIoKTtcbiAgdGhpcy5kZWNvZGVyID0gbmV3IHBhcnNlci5EZWNvZGVyKCk7XG4gIHRoaXMuYXV0b0Nvbm5lY3QgPSBvcHRzLmF1dG9Db25uZWN0ICE9PSBmYWxzZTtcbiAgaWYgKHRoaXMuYXV0b0Nvbm5lY3QpIHRoaXMub3BlbigpO1xufVxuXG4vKipcbiAqIFByb3BhZ2F0ZSBnaXZlbiBldmVudCB0byBzb2NrZXRzIGFuZCBlbWl0IG9uIGB0aGlzYFxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLmVtaXRBbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICBmb3IgKHZhciBuc3AgaW4gdGhpcy5uc3BzKSB7XG4gICAgaWYgKGhhcy5jYWxsKHRoaXMubnNwcywgbnNwKSkge1xuICAgICAgdGhpcy5uc3BzW25zcF0uZW1pdC5hcHBseSh0aGlzLm5zcHNbbnNwXSwgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogVXBkYXRlIGBzb2NrZXQuaWRgIG9mIGFsbCBzb2NrZXRzXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUudXBkYXRlU29ja2V0SWRzID0gZnVuY3Rpb24gKCkge1xuICBmb3IgKHZhciBuc3AgaW4gdGhpcy5uc3BzKSB7XG4gICAgaWYgKGhhcy5jYWxsKHRoaXMubnNwcywgbnNwKSkge1xuICAgICAgdGhpcy5uc3BzW25zcF0uaWQgPSB0aGlzLmVuZ2luZS5pZDtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKE1hbmFnZXIucHJvdG90eXBlKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBgcmVjb25uZWN0aW9uYCBjb25maWcuXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSB0cnVlL2ZhbHNlIGlmIGl0IHNob3VsZCBhdXRvbWF0aWNhbGx5IHJlY29ubmVjdFxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb24gPSBmdW5jdGlvbiAodikge1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb247XG4gIHRoaXMuX3JlY29ubmVjdGlvbiA9ICEhdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIHJlY29ubmVjdGlvbiBhdHRlbXB0cyBjb25maWcuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1heCByZWNvbm5lY3Rpb24gYXR0ZW1wdHMgYmVmb3JlIGdpdmluZyB1cFxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25BdHRlbXB0cyA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JlY29ubmVjdGlvbkF0dGVtcHRzO1xuICB0aGlzLl9yZWNvbm5lY3Rpb25BdHRlbXB0cyA9IHY7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBkZWxheSBiZXR3ZWVuIHJlY29ubmVjdGlvbnMuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGRlbGF5XG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnJlY29ubmVjdGlvbkRlbGF5ID0gZnVuY3Rpb24gKHYpIHtcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fcmVjb25uZWN0aW9uRGVsYXk7XG4gIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5ID0gdjtcbiAgdGhpcy5iYWNrb2ZmICYmIHRoaXMuYmFja29mZi5zZXRNaW4odik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuTWFuYWdlci5wcm90b3R5cGUucmFuZG9taXphdGlvbkZhY3RvciA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JhbmRvbWl6YXRpb25GYWN0b3I7XG4gIHRoaXMuX3JhbmRvbWl6YXRpb25GYWN0b3IgPSB2O1xuICB0aGlzLmJhY2tvZmYgJiYgdGhpcy5iYWNrb2ZmLnNldEppdHRlcih2KTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIG1heGltdW0gZGVsYXkgYmV0d2VlbiByZWNvbm5lY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBkZWxheVxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25EZWxheU1heCA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5TWF4O1xuICB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheU1heCA9IHY7XG4gIHRoaXMuYmFja29mZiAmJiB0aGlzLmJhY2tvZmYuc2V0TWF4KHYpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgY29ubmVjdGlvbiB0aW1lb3V0LiBgZmFsc2VgIHRvIGRpc2FibGVcbiAqXG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnRpbWVvdXQgPSBmdW5jdGlvbiAodikge1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl90aW1lb3V0O1xuICB0aGlzLl90aW1lb3V0ID0gdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyB0cnlpbmcgdG8gcmVjb25uZWN0IGlmIHJlY29ubmVjdGlvbiBpcyBlbmFibGVkIGFuZCB3ZSBoYXZlIG5vdFxuICogc3RhcnRlZCByZWNvbm5lY3RpbmcgeWV0XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUubWF5YmVSZWNvbm5lY3RPbk9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIC8vIE9ubHkgdHJ5IHRvIHJlY29ubmVjdCBpZiBpdCdzIHRoZSBmaXJzdCB0aW1lIHdlJ3JlIGNvbm5lY3RpbmdcbiAgaWYgKCF0aGlzLnJlY29ubmVjdGluZyAmJiB0aGlzLl9yZWNvbm5lY3Rpb24gJiYgdGhpcy5iYWNrb2ZmLmF0dGVtcHRzID09PSAwKSB7XG4gICAgLy8ga2VlcHMgcmVjb25uZWN0aW9uIGZyb20gZmlyaW5nIHR3aWNlIGZvciB0aGUgc2FtZSByZWNvbm5lY3Rpb24gbG9vcFxuICAgIHRoaXMucmVjb25uZWN0KCk7XG4gIH1cbn07XG5cbi8qKlxuICogU2V0cyB0aGUgY3VycmVudCB0cmFuc3BvcnQgYHNvY2tldGAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gb3B0aW9uYWwsIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9wZW4gPVxuTWFuYWdlci5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uIChmbiwgb3B0cykge1xuICBkZWJ1ZygncmVhZHlTdGF0ZSAlcycsIHRoaXMucmVhZHlTdGF0ZSk7XG4gIGlmICh+dGhpcy5yZWFkeVN0YXRlLmluZGV4T2YoJ29wZW4nKSkgcmV0dXJuIHRoaXM7XG5cbiAgZGVidWcoJ29wZW5pbmcgJXMnLCB0aGlzLnVyaSk7XG4gIHRoaXMuZW5naW5lID0gZWlvKHRoaXMudXJpLCB0aGlzLm9wdHMpO1xuICB2YXIgc29ja2V0ID0gdGhpcy5lbmdpbmU7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW5pbmcnO1xuICB0aGlzLnNraXBSZWNvbm5lY3QgPSBmYWxzZTtcblxuICAvLyBlbWl0IGBvcGVuYFxuICB2YXIgb3BlblN1YiA9IG9uKHNvY2tldCwgJ29wZW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5vbm9wZW4oKTtcbiAgICBmbiAmJiBmbigpO1xuICB9KTtcblxuICAvLyBlbWl0IGBjb25uZWN0X2Vycm9yYFxuICB2YXIgZXJyb3JTdWIgPSBvbihzb2NrZXQsICdlcnJvcicsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgZGVidWcoJ2Nvbm5lY3RfZXJyb3InKTtcbiAgICBzZWxmLmNsZWFudXAoKTtcbiAgICBzZWxmLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgICBzZWxmLmVtaXRBbGwoJ2Nvbm5lY3RfZXJyb3InLCBkYXRhKTtcbiAgICBpZiAoZm4pIHtcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gZXJyb3InKTtcbiAgICAgIGVyci5kYXRhID0gZGF0YTtcbiAgICAgIGZuKGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE9ubHkgZG8gdGhpcyBpZiB0aGVyZSBpcyBubyBmbiB0byBoYW5kbGUgdGhlIGVycm9yXG4gICAgICBzZWxmLm1heWJlUmVjb25uZWN0T25PcGVuKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBlbWl0IGBjb25uZWN0X3RpbWVvdXRgXG4gIGlmIChmYWxzZSAhPT0gdGhpcy5fdGltZW91dCkge1xuICAgIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgICBkZWJ1ZygnY29ubmVjdCBhdHRlbXB0IHdpbGwgdGltZW91dCBhZnRlciAlZCcsIHRpbWVvdXQpO1xuXG4gICAgLy8gc2V0IHRpbWVyXG4gICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBkZWJ1ZygnY29ubmVjdCBhdHRlbXB0IHRpbWVkIG91dCBhZnRlciAlZCcsIHRpbWVvdXQpO1xuICAgICAgb3BlblN1Yi5kZXN0cm95KCk7XG4gICAgICBzb2NrZXQuY2xvc2UoKTtcbiAgICAgIHNvY2tldC5lbWl0KCdlcnJvcicsICd0aW1lb3V0Jyk7XG4gICAgICBzZWxmLmVtaXRBbGwoJ2Nvbm5lY3RfdGltZW91dCcsIHRpbWVvdXQpO1xuICAgIH0sIHRpbWVvdXQpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdGhpcy5zdWJzLnB1c2gob3BlblN1Yik7XG4gIHRoaXMuc3Vicy5wdXNoKGVycm9yU3ViKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IG9wZW4uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1Zygnb3BlbicpO1xuXG4gIC8vIGNsZWFyIG9sZCBzdWJzXG4gIHRoaXMuY2xlYW51cCgpO1xuXG4gIC8vIG1hcmsgYXMgb3BlblxuICB0aGlzLnJlYWR5U3RhdGUgPSAnb3Blbic7XG4gIHRoaXMuZW1pdCgnb3BlbicpO1xuXG4gIC8vIGFkZCBuZXcgc3Vic1xuICB2YXIgc29ja2V0ID0gdGhpcy5lbmdpbmU7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2RhdGEnLCBiaW5kKHRoaXMsICdvbmRhdGEnKSkpO1xuICB0aGlzLnN1YnMucHVzaChvbihzb2NrZXQsICdwaW5nJywgYmluZCh0aGlzLCAnb25waW5nJykpKTtcbiAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAncG9uZycsIGJpbmQodGhpcywgJ29ucG9uZycpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2Vycm9yJywgYmluZCh0aGlzLCAnb25lcnJvcicpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2Nsb3NlJywgYmluZCh0aGlzLCAnb25jbG9zZScpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHRoaXMuZGVjb2RlciwgJ2RlY29kZWQnLCBiaW5kKHRoaXMsICdvbmRlY29kZWQnKSkpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBhIHBpbmcuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25waW5nID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmxhc3RQaW5nID0gbmV3IERhdGUoKTtcbiAgdGhpcy5lbWl0QWxsKCdwaW5nJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgcGFja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9ucG9uZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0QWxsKCdwb25nJywgbmV3IERhdGUoKSAtIHRoaXMubGFzdFBpbmcpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgd2l0aCBkYXRhLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uZGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuZGVjb2Rlci5hZGQoZGF0YSk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aGVuIHBhcnNlciBmdWxseSBkZWNvZGVzIGEgcGFja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uZGVjb2RlZCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzb2NrZXQgZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25lcnJvciA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgZGVidWcoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5lbWl0QWxsKCdlcnJvcicsIGVycik7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc29ja2V0IGZvciB0aGUgZ2l2ZW4gYG5zcGAuXG4gKlxuICogQHJldHVybiB7U29ja2V0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5zb2NrZXQgPSBmdW5jdGlvbiAobnNwLCBvcHRzKSB7XG4gIHZhciBzb2NrZXQgPSB0aGlzLm5zcHNbbnNwXTtcbiAgaWYgKCFzb2NrZXQpIHtcbiAgICBzb2NrZXQgPSBuZXcgU29ja2V0KHRoaXMsIG5zcCwgb3B0cyk7XG4gICAgdGhpcy5uc3BzW25zcF0gPSBzb2NrZXQ7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHNvY2tldC5vbignY29ubmVjdGluZycsIG9uQ29ubmVjdGluZyk7XG4gICAgc29ja2V0Lm9uKCdjb25uZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgc29ja2V0LmlkID0gc2VsZi5lbmdpbmUuaWQ7XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5hdXRvQ29ubmVjdCkge1xuICAgICAgLy8gbWFudWFsbHkgY2FsbCBoZXJlIHNpbmNlIGNvbm5lY3RpbmcgZXZuZXQgaXMgZmlyZWQgYmVmb3JlIGxpc3RlbmluZ1xuICAgICAgb25Db25uZWN0aW5nKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25Db25uZWN0aW5nICgpIHtcbiAgICBpZiAoIX5pbmRleE9mKHNlbGYuY29ubmVjdGluZywgc29ja2V0KSkge1xuICAgICAgc2VsZi5jb25uZWN0aW5nLnB1c2goc29ja2V0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc29ja2V0O1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBhIHNvY2tldCBjbG9zZS5cbiAqXG4gKiBAcGFyYW0ge1NvY2tldH0gc29ja2V0XG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uIChzb2NrZXQpIHtcbiAgdmFyIGluZGV4ID0gaW5kZXhPZih0aGlzLmNvbm5lY3RpbmcsIHNvY2tldCk7XG4gIGlmICh+aW5kZXgpIHRoaXMuY29ubmVjdGluZy5zcGxpY2UoaW5kZXgsIDEpO1xuICBpZiAodGhpcy5jb25uZWN0aW5nLmxlbmd0aCkgcmV0dXJuO1xuXG4gIHRoaXMuY2xvc2UoKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgcGFja2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgZGVidWcoJ3dyaXRpbmcgcGFja2V0ICVqJywgcGFja2V0KTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAocGFja2V0LnF1ZXJ5ICYmIHBhY2tldC50eXBlID09PSAwKSBwYWNrZXQubnNwICs9ICc/JyArIHBhY2tldC5xdWVyeTtcblxuICBpZiAoIXNlbGYuZW5jb2RpbmcpIHtcbiAgICAvLyBlbmNvZGUsIHRoZW4gd3JpdGUgdG8gZW5naW5lIHdpdGggcmVzdWx0XG4gICAgc2VsZi5lbmNvZGluZyA9IHRydWU7XG4gICAgdGhpcy5lbmNvZGVyLmVuY29kZShwYWNrZXQsIGZ1bmN0aW9uIChlbmNvZGVkUGFja2V0cykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbmNvZGVkUGFja2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBzZWxmLmVuZ2luZS53cml0ZShlbmNvZGVkUGFja2V0c1tpXSwgcGFja2V0Lm9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgc2VsZi5lbmNvZGluZyA9IGZhbHNlO1xuICAgICAgc2VsZi5wcm9jZXNzUGFja2V0UXVldWUoKTtcbiAgICB9KTtcbiAgfSBlbHNlIHsgLy8gYWRkIHBhY2tldCB0byB0aGUgcXVldWVcbiAgICBzZWxmLnBhY2tldEJ1ZmZlci5wdXNoKHBhY2tldCk7XG4gIH1cbn07XG5cbi8qKlxuICogSWYgcGFja2V0IGJ1ZmZlciBpcyBub24tZW1wdHksIGJlZ2lucyBlbmNvZGluZyB0aGVcbiAqIG5leHQgcGFja2V0IGluIGxpbmUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUucHJvY2Vzc1BhY2tldFF1ZXVlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5wYWNrZXRCdWZmZXIubGVuZ3RoID4gMCAmJiAhdGhpcy5lbmNvZGluZykge1xuICAgIHZhciBwYWNrID0gdGhpcy5wYWNrZXRCdWZmZXIuc2hpZnQoKTtcbiAgICB0aGlzLnBhY2tldChwYWNrKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDbGVhbiB1cCB0cmFuc3BvcnQgc3Vic2NyaXB0aW9ucyBhbmQgcGFja2V0IGJ1ZmZlci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5jbGVhbnVwID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2xlYW51cCcpO1xuXG4gIHZhciBzdWJzTGVuZ3RoID0gdGhpcy5zdWJzLmxlbmd0aDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdWJzTGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc3ViID0gdGhpcy5zdWJzLnNoaWZ0KCk7XG4gICAgc3ViLmRlc3Ryb3koKTtcbiAgfVxuXG4gIHRoaXMucGFja2V0QnVmZmVyID0gW107XG4gIHRoaXMuZW5jb2RpbmcgPSBmYWxzZTtcbiAgdGhpcy5sYXN0UGluZyA9IG51bGw7XG5cbiAgdGhpcy5kZWNvZGVyLmRlc3Ryb3koKTtcbn07XG5cbi8qKlxuICogQ2xvc2UgdGhlIGN1cnJlbnQgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLmNsb3NlID1cbk1hbmFnZXIucHJvdG90eXBlLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCdkaXNjb25uZWN0Jyk7XG4gIHRoaXMuc2tpcFJlY29ubmVjdCA9IHRydWU7XG4gIHRoaXMucmVjb25uZWN0aW5nID0gZmFsc2U7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIC8vIGBvbmNsb3NlYCB3aWxsIG5vdCBmaXJlIGJlY2F1c2VcbiAgICAvLyBhbiBvcGVuIGV2ZW50IG5ldmVyIGhhcHBlbmVkXG4gICAgdGhpcy5jbGVhbnVwKCk7XG4gIH1cbiAgdGhpcy5iYWNrb2ZmLnJlc2V0KCk7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuICBpZiAodGhpcy5lbmdpbmUpIHRoaXMuZW5naW5lLmNsb3NlKCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGVuZ2luZSBjbG9zZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vbmNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICBkZWJ1Zygnb25jbG9zZScpO1xuXG4gIHRoaXMuY2xlYW51cCgpO1xuICB0aGlzLmJhY2tvZmYucmVzZXQoKTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnLCByZWFzb24pO1xuXG4gIGlmICh0aGlzLl9yZWNvbm5lY3Rpb24gJiYgIXRoaXMuc2tpcFJlY29ubmVjdCkge1xuICAgIHRoaXMucmVjb25uZWN0KCk7XG4gIH1cbn07XG5cbi8qKlxuICogQXR0ZW1wdCBhIHJlY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnJlY29ubmVjdGluZyB8fCB0aGlzLnNraXBSZWNvbm5lY3QpIHJldHVybiB0aGlzO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAodGhpcy5iYWNrb2ZmLmF0dGVtcHRzID49IHRoaXMuX3JlY29ubmVjdGlvbkF0dGVtcHRzKSB7XG4gICAgZGVidWcoJ3JlY29ubmVjdCBmYWlsZWQnKTtcbiAgICB0aGlzLmJhY2tvZmYucmVzZXQoKTtcbiAgICB0aGlzLmVtaXRBbGwoJ3JlY29ubmVjdF9mYWlsZWQnKTtcbiAgICB0aGlzLnJlY29ubmVjdGluZyA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHZhciBkZWxheSA9IHRoaXMuYmFja29mZi5kdXJhdGlvbigpO1xuICAgIGRlYnVnKCd3aWxsIHdhaXQgJWRtcyBiZWZvcmUgcmVjb25uZWN0IGF0dGVtcHQnLCBkZWxheSk7XG5cbiAgICB0aGlzLnJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoc2VsZi5za2lwUmVjb25uZWN0KSByZXR1cm47XG5cbiAgICAgIGRlYnVnKCdhdHRlbXB0aW5nIHJlY29ubmVjdCcpO1xuICAgICAgc2VsZi5lbWl0QWxsKCdyZWNvbm5lY3RfYXR0ZW1wdCcsIHNlbGYuYmFja29mZi5hdHRlbXB0cyk7XG4gICAgICBzZWxmLmVtaXRBbGwoJ3JlY29ubmVjdGluZycsIHNlbGYuYmFja29mZi5hdHRlbXB0cyk7XG5cbiAgICAgIC8vIGNoZWNrIGFnYWluIGZvciB0aGUgY2FzZSBzb2NrZXQgY2xvc2VkIGluIGFib3ZlIGV2ZW50c1xuICAgICAgaWYgKHNlbGYuc2tpcFJlY29ubmVjdCkgcmV0dXJuO1xuXG4gICAgICBzZWxmLm9wZW4oZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgZGVidWcoJ3JlY29ubmVjdCBhdHRlbXB0IGVycm9yJyk7XG4gICAgICAgICAgc2VsZi5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLnJlY29ubmVjdCgpO1xuICAgICAgICAgIHNlbGYuZW1pdEFsbCgncmVjb25uZWN0X2Vycm9yJywgZXJyLmRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlYnVnKCdyZWNvbm5lY3Qgc3VjY2VzcycpO1xuICAgICAgICAgIHNlbGYub25yZWNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSwgZGVsYXkpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHN1Y2Nlc3NmdWwgcmVjb25uZWN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9ucmVjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXR0ZW1wdCA9IHRoaXMuYmFja29mZi5hdHRlbXB0cztcbiAgdGhpcy5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgdGhpcy5iYWNrb2ZmLnJlc2V0KCk7XG4gIHRoaXMudXBkYXRlU29ja2V0SWRzKCk7XG4gIHRoaXMuZW1pdEFsbCgncmVjb25uZWN0JywgYXR0ZW1wdCk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1e1f\n")},"1ed2":function(module,exports){eval("/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function(val, options){\n  options = options || {};\n  if ('string' == typeof val) return parse(val);\n  return options.long\n    ? long(val)\n    : short(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n  str = '' + str;\n  if (str.length > 10000) return;\n  var match = /^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);\n  if (!match) return;\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'yrs':\n    case 'yr':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'hrs':\n    case 'hr':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'mins':\n    case 'min':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 'secs':\n    case 'sec':\n    case 's':\n      return n * s;\n    case 'milliseconds':\n    case 'millisecond':\n    case 'msecs':\n    case 'msec':\n    case 'ms':\n      return n;\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction short(ms) {\n  if (ms >= d) return Math.round(ms / d) + 'd';\n  if (ms >= h) return Math.round(ms / h) + 'h';\n  if (ms >= m) return Math.round(ms / m) + 'm';\n  if (ms >= s) return Math.round(ms / s) + 's';\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction long(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, n, name) {\n  if (ms < n) return;\n  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMWVkMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvbXMvaW5kZXguanM/NDg1MiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhlbHBlcnMuXG4gKi9cblxudmFyIHMgPSAxMDAwO1xudmFyIG0gPSBzICogNjA7XG52YXIgaCA9IG0gKiA2MDtcbnZhciBkID0gaCAqIDI0O1xudmFyIHkgPSBkICogMzY1LjI1O1xuXG4vKipcbiAqIFBhcnNlIG9yIGZvcm1hdCB0aGUgZ2l2ZW4gYHZhbGAuXG4gKlxuICogT3B0aW9uczpcbiAqXG4gKiAgLSBgbG9uZ2AgdmVyYm9zZSBmb3JtYXR0aW5nIFtmYWxzZV1cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xOdW1iZXJ9IHZhbFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ3xOdW1iZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24odmFsLCBvcHRpb25zKXtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGlmICgnc3RyaW5nJyA9PSB0eXBlb2YgdmFsKSByZXR1cm4gcGFyc2UodmFsKTtcbiAgcmV0dXJuIG9wdGlvbnMubG9uZ1xuICAgID8gbG9uZyh2YWwpXG4gICAgOiBzaG9ydCh2YWwpO1xufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gYHN0cmAgYW5kIHJldHVybiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7TnVtYmVyfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcGFyc2Uoc3RyKSB7XG4gIHN0ciA9ICcnICsgc3RyO1xuICBpZiAoc3RyLmxlbmd0aCA+IDEwMDAwKSByZXR1cm47XG4gIHZhciBtYXRjaCA9IC9eKCg/OlxcZCspP1xcLj9cXGQrKSAqKG1pbGxpc2Vjb25kcz98bXNlY3M/fG1zfHNlY29uZHM/fHNlY3M/fHN8bWludXRlcz98bWlucz98bXxob3Vycz98aHJzP3xofGRheXM/fGR8eWVhcnM/fHlycz98eSk/JC9pLmV4ZWMoc3RyKTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuO1xuICB2YXIgbiA9IHBhcnNlRmxvYXQobWF0Y2hbMV0pO1xuICB2YXIgdHlwZSA9IChtYXRjaFsyXSB8fCAnbXMnKS50b0xvd2VyQ2FzZSgpO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICd5ZWFycyc6XG4gICAgY2FzZSAneWVhcic6XG4gICAgY2FzZSAneXJzJzpcbiAgICBjYXNlICd5cic6XG4gICAgY2FzZSAneSc6XG4gICAgICByZXR1cm4gbiAqIHk7XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZDtcbiAgICBjYXNlICdob3Vycyc6XG4gICAgY2FzZSAnaG91cic6XG4gICAgY2FzZSAnaHJzJzpcbiAgICBjYXNlICdocic6XG4gICAgY2FzZSAnaCc6XG4gICAgICByZXR1cm4gbiAqIGg7XG4gICAgY2FzZSAnbWludXRlcyc6XG4gICAgY2FzZSAnbWludXRlJzpcbiAgICBjYXNlICdtaW5zJzpcbiAgICBjYXNlICdtaW4nOlxuICAgIGNhc2UgJ20nOlxuICAgICAgcmV0dXJuIG4gKiBtO1xuICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgY2FzZSAnc2Vjcyc6XG4gICAgY2FzZSAnc2VjJzpcbiAgICBjYXNlICdzJzpcbiAgICAgIHJldHVybiBuICogcztcbiAgICBjYXNlICdtaWxsaXNlY29uZHMnOlxuICAgIGNhc2UgJ21pbGxpc2Vjb25kJzpcbiAgICBjYXNlICdtc2Vjcyc6XG4gICAgY2FzZSAnbXNlYyc6XG4gICAgY2FzZSAnbXMnOlxuICAgICAgcmV0dXJuIG47XG4gIH1cbn1cblxuLyoqXG4gKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzaG9ydChtcykge1xuICBpZiAobXMgPj0gZCkgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArICdkJztcbiAgaWYgKG1zID49IGgpIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gaCkgKyAnaCc7XG4gIGlmIChtcyA+PSBtKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIG0pICsgJ20nO1xuICBpZiAobXMgPj0gcykgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArICdzJztcbiAgcmV0dXJuIG1zICsgJ21zJztcbn1cblxuLyoqXG4gKiBMb25nIGZvcm1hdCBmb3IgYG1zYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbXNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvbmcobXMpIHtcbiAgcmV0dXJuIHBsdXJhbChtcywgZCwgJ2RheScpXG4gICAgfHwgcGx1cmFsKG1zLCBoLCAnaG91cicpXG4gICAgfHwgcGx1cmFsKG1zLCBtLCAnbWludXRlJylcbiAgICB8fCBwbHVyYWwobXMsIHMsICdzZWNvbmQnKVxuICAgIHx8IG1zICsgJyBtcyc7XG59XG5cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi9cblxuZnVuY3Rpb24gcGx1cmFsKG1zLCBuLCBuYW1lKSB7XG4gIGlmIChtcyA8IG4pIHJldHVybjtcbiAgaWYgKG1zIDwgbiAqIDEuNSkgcmV0dXJuIE1hdGguZmxvb3IobXMgLyBuKSArICcgJyArIG5hbWU7XG4gIHJldHVybiBNYXRoLmNlaWwobXMgLyBuKSArICcgJyArIG5hbWUgKyAncyc7XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1ed2\n")},"23b1":function(module,exports,__webpack_require__){eval("\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = debug.debug = debug;\nexports.coerce = coerce;\nexports.disable = disable;\nexports.enable = enable;\nexports.enabled = enabled;\nexports.humanize = __webpack_require__(/*! ms */ \"0b10\");\n\n/**\n * The currently active debug mode names, and names to skip.\n */\n\nexports.names = [];\nexports.skips = [];\n\n/**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lowercased letter, i.e. \"n\".\n */\n\nexports.formatters = {};\n\n/**\n * Previously assigned color.\n */\n\nvar prevColor = 0;\n\n/**\n * Previous log timestamp.\n */\n\nvar prevTime;\n\n/**\n * Select a color.\n *\n * @return {Number}\n * @api private\n */\n\nfunction selectColor() {\n  return exports.colors[prevColor++ % exports.colors.length];\n}\n\n/**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\nfunction debug(namespace) {\n\n  // define the `disabled` version\n  function disabled() {\n  }\n  disabled.enabled = false;\n\n  // define the `enabled` version\n  function enabled() {\n\n    var self = enabled;\n\n    // set `diff` timestamp\n    var curr = +new Date();\n    var ms = curr - (prevTime || curr);\n    self.diff = ms;\n    self.prev = prevTime;\n    self.curr = curr;\n    prevTime = curr;\n\n    // add the `color` if not set\n    if (null == self.useColors) self.useColors = exports.useColors();\n    if (null == self.color && self.useColors) self.color = selectColor();\n\n    var args = new Array(arguments.length);\n    for (var i = 0; i < args.length; i++) {\n      args[i] = arguments[i];\n    }\n\n    args[0] = exports.coerce(args[0]);\n\n    if ('string' !== typeof args[0]) {\n      // anything else let's inspect with %o\n      args = ['%o'].concat(args);\n    }\n\n    // apply any `formatters` transformations\n    var index = 0;\n    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {\n      // if we encounter an escaped % then don't increase the array index\n      if (match === '%%') return match;\n      index++;\n      var formatter = exports.formatters[format];\n      if ('function' === typeof formatter) {\n        var val = args[index];\n        match = formatter.call(self, val);\n\n        // now we need to remove `args[index]` since it's inlined in the `format`\n        args.splice(index, 1);\n        index--;\n      }\n      return match;\n    });\n\n    // apply env-specific formatting\n    args = exports.formatArgs.apply(self, args);\n\n    var logFn = enabled.log || exports.log || console.log.bind(console);\n    logFn.apply(self, args);\n  }\n  enabled.enabled = true;\n\n  var fn = exports.enabled(namespace) ? enabled : disabled;\n\n  fn.namespace = namespace;\n\n  return fn;\n}\n\n/**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\nfunction enable(namespaces) {\n  exports.save(namespaces);\n\n  var split = (namespaces || '').split(/[\\s,]+/);\n  var len = split.length;\n\n  for (var i = 0; i < len; i++) {\n    if (!split[i]) continue; // ignore empty strings\n    namespaces = split[i].replace(/[\\\\^$+?.()|[\\]{}]/g, '\\\\$&').replace(/\\*/g, '.*?');\n    if (namespaces[0] === '-') {\n      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n    } else {\n      exports.names.push(new RegExp('^' + namespaces + '$'));\n    }\n  }\n}\n\n/**\n * Disable debug output.\n *\n * @api public\n */\n\nfunction disable() {\n  exports.enable('');\n}\n\n/**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\nfunction enabled(name) {\n  var i, len;\n  for (i = 0, len = exports.skips.length; i < len; i++) {\n    if (exports.skips[i].test(name)) {\n      return false;\n    }\n  }\n  for (i = 0, len = exports.names.length; i < len; i++) {\n    if (exports.names[i].test(name)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\nfunction coerce(val) {\n  if (val instanceof Error) return val.stack || val.message;\n  return val;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjNiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZGVidWcvZGVidWcuanM/NjMxMiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogVGhpcyBpcyB0aGUgY29tbW9uIGxvZ2ljIGZvciBib3RoIHRoZSBOb2RlLmpzIGFuZCB3ZWIgYnJvd3NlclxuICogaW1wbGVtZW50YXRpb25zIG9mIGBkZWJ1ZygpYC5cbiAqXG4gKiBFeHBvc2UgYGRlYnVnKClgIGFzIHRoZSBtb2R1bGUuXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZGVidWcuZGVidWcgPSBkZWJ1ZztcbmV4cG9ydHMuY29lcmNlID0gY29lcmNlO1xuZXhwb3J0cy5kaXNhYmxlID0gZGlzYWJsZTtcbmV4cG9ydHMuZW5hYmxlID0gZW5hYmxlO1xuZXhwb3J0cy5lbmFibGVkID0gZW5hYmxlZDtcbmV4cG9ydHMuaHVtYW5pemUgPSByZXF1aXJlKCdtcycpO1xuXG4vKipcbiAqIFRoZSBjdXJyZW50bHkgYWN0aXZlIGRlYnVnIG1vZGUgbmFtZXMsIGFuZCBuYW1lcyB0byBza2lwLlxuICovXG5cbmV4cG9ydHMubmFtZXMgPSBbXTtcbmV4cG9ydHMuc2tpcHMgPSBbXTtcblxuLyoqXG4gKiBNYXAgb2Ygc3BlY2lhbCBcIiVuXCIgaGFuZGxpbmcgZnVuY3Rpb25zLCBmb3IgdGhlIGRlYnVnIFwiZm9ybWF0XCIgYXJndW1lbnQuXG4gKlxuICogVmFsaWQga2V5IG5hbWVzIGFyZSBhIHNpbmdsZSwgbG93ZXJjYXNlZCBsZXR0ZXIsIGkuZS4gXCJuXCIuXG4gKi9cblxuZXhwb3J0cy5mb3JtYXR0ZXJzID0ge307XG5cbi8qKlxuICogUHJldmlvdXNseSBhc3NpZ25lZCBjb2xvci5cbiAqL1xuXG52YXIgcHJldkNvbG9yID0gMDtcblxuLyoqXG4gKiBQcmV2aW91cyBsb2cgdGltZXN0YW1wLlxuICovXG5cbnZhciBwcmV2VGltZTtcblxuLyoqXG4gKiBTZWxlY3QgYSBjb2xvci5cbiAqXG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzZWxlY3RDb2xvcigpIHtcbiAgcmV0dXJuIGV4cG9ydHMuY29sb3JzW3ByZXZDb2xvcisrICUgZXhwb3J0cy5jb2xvcnMubGVuZ3RoXTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBkZWJ1Z2dlciB3aXRoIHRoZSBnaXZlbiBgbmFtZXNwYWNlYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZGVidWcobmFtZXNwYWNlKSB7XG5cbiAgLy8gZGVmaW5lIHRoZSBgZGlzYWJsZWRgIHZlcnNpb25cbiAgZnVuY3Rpb24gZGlzYWJsZWQoKSB7XG4gIH1cbiAgZGlzYWJsZWQuZW5hYmxlZCA9IGZhbHNlO1xuXG4gIC8vIGRlZmluZSB0aGUgYGVuYWJsZWRgIHZlcnNpb25cbiAgZnVuY3Rpb24gZW5hYmxlZCgpIHtcblxuICAgIHZhciBzZWxmID0gZW5hYmxlZDtcblxuICAgIC8vIHNldCBgZGlmZmAgdGltZXN0YW1wXG4gICAgdmFyIGN1cnIgPSArbmV3IERhdGUoKTtcbiAgICB2YXIgbXMgPSBjdXJyIC0gKHByZXZUaW1lIHx8IGN1cnIpO1xuICAgIHNlbGYuZGlmZiA9IG1zO1xuICAgIHNlbGYucHJldiA9IHByZXZUaW1lO1xuICAgIHNlbGYuY3VyciA9IGN1cnI7XG4gICAgcHJldlRpbWUgPSBjdXJyO1xuXG4gICAgLy8gYWRkIHRoZSBgY29sb3JgIGlmIG5vdCBzZXRcbiAgICBpZiAobnVsbCA9PSBzZWxmLnVzZUNvbG9ycykgc2VsZi51c2VDb2xvcnMgPSBleHBvcnRzLnVzZUNvbG9ycygpO1xuICAgIGlmIChudWxsID09IHNlbGYuY29sb3IgJiYgc2VsZi51c2VDb2xvcnMpIHNlbGYuY29sb3IgPSBzZWxlY3RDb2xvcigpO1xuXG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgIH1cblxuICAgIGFyZ3NbMF0gPSBleHBvcnRzLmNvZXJjZShhcmdzWzBdKTtcblxuICAgIGlmICgnc3RyaW5nJyAhPT0gdHlwZW9mIGFyZ3NbMF0pIHtcbiAgICAgIC8vIGFueXRoaW5nIGVsc2UgbGV0J3MgaW5zcGVjdCB3aXRoICVvXG4gICAgICBhcmdzID0gWyclbyddLmNvbmNhdChhcmdzKTtcbiAgICB9XG5cbiAgICAvLyBhcHBseSBhbnkgYGZvcm1hdHRlcnNgIHRyYW5zZm9ybWF0aW9uc1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgYXJnc1swXSA9IGFyZ3NbMF0ucmVwbGFjZSgvJShbYS16JV0pL2csIGZ1bmN0aW9uKG1hdGNoLCBmb3JtYXQpIHtcbiAgICAgIC8vIGlmIHdlIGVuY291bnRlciBhbiBlc2NhcGVkICUgdGhlbiBkb24ndCBpbmNyZWFzZSB0aGUgYXJyYXkgaW5kZXhcbiAgICAgIGlmIChtYXRjaCA9PT0gJyUlJykgcmV0dXJuIG1hdGNoO1xuICAgICAgaW5kZXgrKztcbiAgICAgIHZhciBmb3JtYXR0ZXIgPSBleHBvcnRzLmZvcm1hdHRlcnNbZm9ybWF0XTtcbiAgICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgZm9ybWF0dGVyKSB7XG4gICAgICAgIHZhciB2YWwgPSBhcmdzW2luZGV4XTtcbiAgICAgICAgbWF0Y2ggPSBmb3JtYXR0ZXIuY2FsbChzZWxmLCB2YWwpO1xuXG4gICAgICAgIC8vIG5vdyB3ZSBuZWVkIHRvIHJlbW92ZSBgYXJnc1tpbmRleF1gIHNpbmNlIGl0J3MgaW5saW5lZCBpbiB0aGUgYGZvcm1hdGBcbiAgICAgICAgYXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBpbmRleC0tO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH0pO1xuXG4gICAgLy8gYXBwbHkgZW52LXNwZWNpZmljIGZvcm1hdHRpbmdcbiAgICBhcmdzID0gZXhwb3J0cy5mb3JtYXRBcmdzLmFwcGx5KHNlbGYsIGFyZ3MpO1xuXG4gICAgdmFyIGxvZ0ZuID0gZW5hYmxlZC5sb2cgfHwgZXhwb3J0cy5sb2cgfHwgY29uc29sZS5sb2cuYmluZChjb25zb2xlKTtcbiAgICBsb2dGbi5hcHBseShzZWxmLCBhcmdzKTtcbiAgfVxuICBlbmFibGVkLmVuYWJsZWQgPSB0cnVlO1xuXG4gIHZhciBmbiA9IGV4cG9ydHMuZW5hYmxlZChuYW1lc3BhY2UpID8gZW5hYmxlZCA6IGRpc2FibGVkO1xuXG4gIGZuLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTtcblxuICByZXR1cm4gZm47XG59XG5cbi8qKlxuICogRW5hYmxlcyBhIGRlYnVnIG1vZGUgYnkgbmFtZXNwYWNlcy4gVGhpcyBjYW4gaW5jbHVkZSBtb2Rlc1xuICogc2VwYXJhdGVkIGJ5IGEgY29sb24gYW5kIHdpbGRjYXJkcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGUobmFtZXNwYWNlcykge1xuICBleHBvcnRzLnNhdmUobmFtZXNwYWNlcyk7XG5cbiAgdmFyIHNwbGl0ID0gKG5hbWVzcGFjZXMgfHwgJycpLnNwbGl0KC9bXFxzLF0rLyk7XG4gIHZhciBsZW4gPSBzcGxpdC5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGlmICghc3BsaXRbaV0pIGNvbnRpbnVlOyAvLyBpZ25vcmUgZW1wdHkgc3RyaW5nc1xuICAgIG5hbWVzcGFjZXMgPSBzcGxpdFtpXS5yZXBsYWNlKC9bXFxcXF4kKz8uKCl8W1xcXXt9XS9nLCAnXFxcXCQmJykucmVwbGFjZSgvXFwqL2csICcuKj8nKTtcbiAgICBpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG4gICAgICBleHBvcnRzLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzLnN1YnN0cigxKSArICckJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzICsgJyQnKSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGlzYWJsZSBkZWJ1ZyBvdXRwdXQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkaXNhYmxlKCkge1xuICBleHBvcnRzLmVuYWJsZSgnJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RlIG5hbWUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGVkKG5hbWUpIHtcbiAgdmFyIGksIGxlbjtcbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLnNraXBzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5uYW1lcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLm5hbWVzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29lcmNlIGB2YWxgLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjb2VyY2UodmFsKSB7XG4gIGlmICh2YWwgaW5zdGFuY2VvZiBFcnJvcikgcmV0dXJuIHZhbC5zdGFjayB8fCB2YWwubWVzc2FnZTtcbiAgcmV0dXJuIHZhbDtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///23b1\n")},"2dce":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {\n/**\n * Module requirements.\n */\n\nvar Polling = __webpack_require__(/*! ./polling */ \"181d\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = JSONPPolling;\n\n/**\n * Cached regular expressions.\n */\n\nvar rNewline = /\\n/g;\nvar rEscapedNewline = /\\\\n/g;\n\n/**\n * Global JSONP callbacks.\n */\n\nvar callbacks;\n\n/**\n * Noop.\n */\n\nfunction empty () { }\n\n/**\n * JSONP Polling constructor.\n *\n * @param {Object} opts.\n * @api public\n */\n\nfunction JSONPPolling (opts) {\n  Polling.call(this, opts);\n\n  this.query = this.query || {};\n\n  // define global callbacks array if not present\n  // we do this here (lazily) to avoid unneeded global pollution\n  if (!callbacks) {\n    // we need to consider multiple engines in the same page\n    if (!global.___eio) global.___eio = [];\n    callbacks = global.___eio;\n  }\n\n  // callback identifier\n  this.index = callbacks.length;\n\n  // add callback to jsonp global\n  var self = this;\n  callbacks.push(function (msg) {\n    self.onData(msg);\n  });\n\n  // append to query string\n  this.query.j = this.index;\n\n  // prevent spurious errors from being emitted when the window is unloaded\n  if (global.document && global.addEventListener) {\n    global.addEventListener('beforeunload', function () {\n      if (self.script) self.script.onerror = empty;\n    }, false);\n  }\n}\n\n/**\n * Inherits from Polling.\n */\n\ninherit(JSONPPolling, Polling);\n\n/*\n * JSONP only supports binary as base64 encoded strings\n */\n\nJSONPPolling.prototype.supportsBinary = false;\n\n/**\n * Closes the socket.\n *\n * @api private\n */\n\nJSONPPolling.prototype.doClose = function () {\n  if (this.script) {\n    this.script.parentNode.removeChild(this.script);\n    this.script = null;\n  }\n\n  if (this.form) {\n    this.form.parentNode.removeChild(this.form);\n    this.form = null;\n    this.iframe = null;\n  }\n\n  Polling.prototype.doClose.call(this);\n};\n\n/**\n * Starts a poll cycle.\n *\n * @api private\n */\n\nJSONPPolling.prototype.doPoll = function () {\n  var self = this;\n  var script = document.createElement('script');\n\n  if (this.script) {\n    this.script.parentNode.removeChild(this.script);\n    this.script = null;\n  }\n\n  script.async = true;\n  script.src = this.uri();\n  script.onerror = function (e) {\n    self.onError('jsonp poll error', e);\n  };\n\n  var insertAt = document.getElementsByTagName('script')[0];\n  if (insertAt) {\n    insertAt.parentNode.insertBefore(script, insertAt);\n  } else {\n    (document.head || document.body).appendChild(script);\n  }\n  this.script = script;\n\n  var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent);\n\n  if (isUAgecko) {\n    setTimeout(function () {\n      var iframe = document.createElement('iframe');\n      document.body.appendChild(iframe);\n      document.body.removeChild(iframe);\n    }, 100);\n  }\n};\n\n/**\n * Writes with a hidden iframe.\n *\n * @param {String} data to send\n * @param {Function} called upon flush.\n * @api private\n */\n\nJSONPPolling.prototype.doWrite = function (data, fn) {\n  var self = this;\n\n  if (!this.form) {\n    var form = document.createElement('form');\n    var area = document.createElement('textarea');\n    var id = this.iframeId = 'eio_iframe_' + this.index;\n    var iframe;\n\n    form.className = 'socketio';\n    form.style.position = 'absolute';\n    form.style.top = '-1000px';\n    form.style.left = '-1000px';\n    form.target = id;\n    form.method = 'POST';\n    form.setAttribute('accept-charset', 'utf-8');\n    area.name = 'd';\n    form.appendChild(area);\n    document.body.appendChild(form);\n\n    this.form = form;\n    this.area = area;\n  }\n\n  this.form.action = this.uri();\n\n  function complete () {\n    initIframe();\n    fn();\n  }\n\n  function initIframe () {\n    if (self.iframe) {\n      try {\n        self.form.removeChild(self.iframe);\n      } catch (e) {\n        self.onError('jsonp polling iframe removal error', e);\n      }\n    }\n\n    try {\n      // ie6 dynamic iframes with target=\"\" support (thanks Chris Lambacher)\n      var html = '<iframe src=\"javascript:0\" name=\"' + self.iframeId + '\">';\n      iframe = document.createElement(html);\n    } catch (e) {\n      iframe = document.createElement('iframe');\n      iframe.name = self.iframeId;\n      iframe.src = 'javascript:0';\n    }\n\n    iframe.id = self.iframeId;\n\n    self.form.appendChild(iframe);\n    self.iframe = iframe;\n  }\n\n  initIframe();\n\n  // escape \\n to prevent it from being converted into \\r\\n by some UAs\n  // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side\n  data = data.replace(rEscapedNewline, '\\\\\\n');\n  this.area.value = data.replace(rNewline, '\\\\n');\n\n  try {\n    this.form.submit();\n  } catch (e) {}\n\n  if (this.iframe.attachEvent) {\n    this.iframe.onreadystatechange = function () {\n      if (self.iframe.readyState === 'complete') {\n        complete();\n      }\n    };\n  } else {\n    this.iframe.onload = complete;\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMmRjZS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLWpzb25wLmpzP2RmZDYiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSByZXF1aXJlbWVudHMuXG4gKi9cblxudmFyIFBvbGxpbmcgPSByZXF1aXJlKCcuL3BvbGxpbmcnKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEpTT05QUG9sbGluZztcblxuLyoqXG4gKiBDYWNoZWQgcmVndWxhciBleHByZXNzaW9ucy5cbiAqL1xuXG52YXIgck5ld2xpbmUgPSAvXFxuL2c7XG52YXIgckVzY2FwZWROZXdsaW5lID0gL1xcXFxuL2c7XG5cbi8qKlxuICogR2xvYmFsIEpTT05QIGNhbGxiYWNrcy5cbiAqL1xuXG52YXIgY2FsbGJhY2tzO1xuXG4vKipcbiAqIE5vb3AuXG4gKi9cblxuZnVuY3Rpb24gZW1wdHkgKCkgeyB9XG5cbi8qKlxuICogSlNPTlAgUG9sbGluZyBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cy5cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gSlNPTlBQb2xsaW5nIChvcHRzKSB7XG4gIFBvbGxpbmcuY2FsbCh0aGlzLCBvcHRzKTtcblxuICB0aGlzLnF1ZXJ5ID0gdGhpcy5xdWVyeSB8fCB7fTtcblxuICAvLyBkZWZpbmUgZ2xvYmFsIGNhbGxiYWNrcyBhcnJheSBpZiBub3QgcHJlc2VudFxuICAvLyB3ZSBkbyB0aGlzIGhlcmUgKGxhemlseSkgdG8gYXZvaWQgdW5uZWVkZWQgZ2xvYmFsIHBvbGx1dGlvblxuICBpZiAoIWNhbGxiYWNrcykge1xuICAgIC8vIHdlIG5lZWQgdG8gY29uc2lkZXIgbXVsdGlwbGUgZW5naW5lcyBpbiB0aGUgc2FtZSBwYWdlXG4gICAgaWYgKCFnbG9iYWwuX19fZWlvKSBnbG9iYWwuX19fZWlvID0gW107XG4gICAgY2FsbGJhY2tzID0gZ2xvYmFsLl9fX2VpbztcbiAgfVxuXG4gIC8vIGNhbGxiYWNrIGlkZW50aWZpZXJcbiAgdGhpcy5pbmRleCA9IGNhbGxiYWNrcy5sZW5ndGg7XG5cbiAgLy8gYWRkIGNhbGxiYWNrIHRvIGpzb25wIGdsb2JhbFxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGNhbGxiYWNrcy5wdXNoKGZ1bmN0aW9uIChtc2cpIHtcbiAgICBzZWxmLm9uRGF0YShtc2cpO1xuICB9KTtcblxuICAvLyBhcHBlbmQgdG8gcXVlcnkgc3RyaW5nXG4gIHRoaXMucXVlcnkuaiA9IHRoaXMuaW5kZXg7XG5cbiAgLy8gcHJldmVudCBzcHVyaW91cyBlcnJvcnMgZnJvbSBiZWluZyBlbWl0dGVkIHdoZW4gdGhlIHdpbmRvdyBpcyB1bmxvYWRlZFxuICBpZiAoZ2xvYmFsLmRvY3VtZW50ICYmIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2JlZm9yZXVubG9hZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLnNjcmlwdCkgc2VsZi5zY3JpcHQub25lcnJvciA9IGVtcHR5O1xuICAgIH0sIGZhbHNlKTtcbiAgfVxufVxuXG4vKipcbiAqIEluaGVyaXRzIGZyb20gUG9sbGluZy5cbiAqL1xuXG5pbmhlcml0KEpTT05QUG9sbGluZywgUG9sbGluZyk7XG5cbi8qXG4gKiBKU09OUCBvbmx5IHN1cHBvcnRzIGJpbmFyeSBhcyBiYXNlNjQgZW5jb2RlZCBzdHJpbmdzXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuXG4vKipcbiAqIENsb3NlcyB0aGUgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkpTT05QUG9sbGluZy5wcm90b3R5cGUuZG9DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuc2NyaXB0KSB7XG4gICAgdGhpcy5zY3JpcHQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnNjcmlwdCk7XG4gICAgdGhpcy5zY3JpcHQgPSBudWxsO1xuICB9XG5cbiAgaWYgKHRoaXMuZm9ybSkge1xuICAgIHRoaXMuZm9ybS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuZm9ybSk7XG4gICAgdGhpcy5mb3JtID0gbnVsbDtcbiAgICB0aGlzLmlmcmFtZSA9IG51bGw7XG4gIH1cblxuICBQb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlLmNhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5kb1BvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gIGlmICh0aGlzLnNjcmlwdCkge1xuICAgIHRoaXMuc2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5zY3JpcHQpO1xuICAgIHRoaXMuc2NyaXB0ID0gbnVsbDtcbiAgfVxuXG4gIHNjcmlwdC5hc3luYyA9IHRydWU7XG4gIHNjcmlwdC5zcmMgPSB0aGlzLnVyaSgpO1xuICBzY3JpcHQub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsIGVycm9yJywgZSk7XG4gIH07XG5cbiAgdmFyIGluc2VydEF0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NjcmlwdCcpWzBdO1xuICBpZiAoaW5zZXJ0QXQpIHtcbiAgICBpbnNlcnRBdC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHQsIGluc2VydEF0KTtcbiAgfSBlbHNlIHtcbiAgICAoZG9jdW1lbnQuaGVhZCB8fCBkb2N1bWVudC5ib2R5KS5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICB9XG4gIHRoaXMuc2NyaXB0ID0gc2NyaXB0O1xuXG4gIHZhciBpc1VBZ2Vja28gPSAndW5kZWZpbmVkJyAhPT0gdHlwZW9mIG5hdmlnYXRvciAmJiAvZ2Vja28vaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG4gIGlmIChpc1VBZ2Vja28pIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgICB9LCAxMDApO1xuICB9XG59O1xuXG4vKipcbiAqIFdyaXRlcyB3aXRoIGEgaGlkZGVuIGlmcmFtZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSB0byBzZW5kXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkpTT05QUG9sbGluZy5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uIChkYXRhLCBmbikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKCF0aGlzLmZvcm0pIHtcbiAgICB2YXIgZm9ybSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2Zvcm0nKTtcbiAgICB2YXIgYXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgdmFyIGlkID0gdGhpcy5pZnJhbWVJZCA9ICdlaW9faWZyYW1lXycgKyB0aGlzLmluZGV4O1xuICAgIHZhciBpZnJhbWU7XG5cbiAgICBmb3JtLmNsYXNzTmFtZSA9ICdzb2NrZXRpbyc7XG4gICAgZm9ybS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgZm9ybS5zdHlsZS50b3AgPSAnLTEwMDBweCc7XG4gICAgZm9ybS5zdHlsZS5sZWZ0ID0gJy0xMDAwcHgnO1xuICAgIGZvcm0udGFyZ2V0ID0gaWQ7XG4gICAgZm9ybS5tZXRob2QgPSAnUE9TVCc7XG4gICAgZm9ybS5zZXRBdHRyaWJ1dGUoJ2FjY2VwdC1jaGFyc2V0JywgJ3V0Zi04Jyk7XG4gICAgYXJlYS5uYW1lID0gJ2QnO1xuICAgIGZvcm0uYXBwZW5kQ2hpbGQoYXJlYSk7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmb3JtKTtcblxuICAgIHRoaXMuZm9ybSA9IGZvcm07XG4gICAgdGhpcy5hcmVhID0gYXJlYTtcbiAgfVxuXG4gIHRoaXMuZm9ybS5hY3Rpb24gPSB0aGlzLnVyaSgpO1xuXG4gIGZ1bmN0aW9uIGNvbXBsZXRlICgpIHtcbiAgICBpbml0SWZyYW1lKCk7XG4gICAgZm4oKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRJZnJhbWUgKCkge1xuICAgIGlmIChzZWxmLmlmcmFtZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2VsZi5mb3JtLnJlbW92ZUNoaWxkKHNlbGYuaWZyYW1lKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsaW5nIGlmcmFtZSByZW1vdmFsIGVycm9yJywgZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIGllNiBkeW5hbWljIGlmcmFtZXMgd2l0aCB0YXJnZXQ9XCJcIiBzdXBwb3J0ICh0aGFua3MgQ2hyaXMgTGFtYmFjaGVyKVxuICAgICAgdmFyIGh0bWwgPSAnPGlmcmFtZSBzcmM9XCJqYXZhc2NyaXB0OjBcIiBuYW1lPVwiJyArIHNlbGYuaWZyYW1lSWQgKyAnXCI+JztcbiAgICAgIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaHRtbCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgICBpZnJhbWUubmFtZSA9IHNlbGYuaWZyYW1lSWQ7XG4gICAgICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6MCc7XG4gICAgfVxuXG4gICAgaWZyYW1lLmlkID0gc2VsZi5pZnJhbWVJZDtcblxuICAgIHNlbGYuZm9ybS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICAgIHNlbGYuaWZyYW1lID0gaWZyYW1lO1xuICB9XG5cbiAgaW5pdElmcmFtZSgpO1xuXG4gIC8vIGVzY2FwZSBcXG4gdG8gcHJldmVudCBpdCBmcm9tIGJlaW5nIGNvbnZlcnRlZCBpbnRvIFxcclxcbiBieSBzb21lIFVBc1xuICAvLyBkb3VibGUgZXNjYXBpbmcgaXMgcmVxdWlyZWQgZm9yIGVzY2FwZWQgbmV3IGxpbmVzIGJlY2F1c2UgdW5lc2NhcGluZyBvZiBuZXcgbGluZXMgY2FuIGJlIGRvbmUgc2FmZWx5IG9uIHNlcnZlci1zaWRlXG4gIGRhdGEgPSBkYXRhLnJlcGxhY2UockVzY2FwZWROZXdsaW5lLCAnXFxcXFxcbicpO1xuICB0aGlzLmFyZWEudmFsdWUgPSBkYXRhLnJlcGxhY2Uock5ld2xpbmUsICdcXFxcbicpO1xuXG4gIHRyeSB7XG4gICAgdGhpcy5mb3JtLnN1Ym1pdCgpO1xuICB9IGNhdGNoIChlKSB7fVxuXG4gIGlmICh0aGlzLmlmcmFtZS5hdHRhY2hFdmVudCkge1xuICAgIHRoaXMuaWZyYW1lLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLmlmcmFtZS5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnKSB7XG4gICAgICAgIGNvbXBsZXRlKCk7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmlmcmFtZS5vbmxvYWQgPSBjb21wbGV0ZTtcbiAgfVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2dce\n")},3902:function(module,exports,__webpack_require__){eval("/**\n * Base class\n *\n * Implements unique ID per instance. It is set once, and can not be updated.\n * An ID is generated during initialization; however it is included in the (de-)serializing of the object.\n * @class Base\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\n// see discussion here: https://gist.github.com/gordonbrander/2230317\nfunction uniqueID () {\n  function chr4 () {\n    return Math.random().toString(16).slice(-4);\n  }\n  return chr4() + chr4() +\n    '-' + chr4() +\n    '-' + chr4() +\n    '-' + chr4() +\n    '-' + chr4() + chr4() + chr4();\n}\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Unique ID for this class\n     * @memberof! Base\n     * @readonly\n     * @type {ID}\n     */\n    id: {\n      type: 'string',\n      default: function () {\n        return uniqueID();\n      },\n      setonce: true\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkwMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9iYXNlLmpzP2NlYTgiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCYXNlIGNsYXNzXG4gKlxuICogSW1wbGVtZW50cyB1bmlxdWUgSUQgcGVyIGluc3RhbmNlLiBJdCBpcyBzZXQgb25jZSwgYW5kIGNhbiBub3QgYmUgdXBkYXRlZC5cbiAqIEFuIElEIGlzIGdlbmVyYXRlZCBkdXJpbmcgaW5pdGlhbGl6YXRpb247IGhvd2V2ZXIgaXQgaXMgaW5jbHVkZWQgaW4gdGhlIChkZS0pc2VyaWFsaXppbmcgb2YgdGhlIG9iamVjdC5cbiAqIEBjbGFzcyBCYXNlXG4gKi9cbnZhciBBbXBlcnNhbmRNb2RlbCA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1tb2RlbCcpO1xuXG4vLyBzZWUgZGlzY3Vzc2lvbiBoZXJlOiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9nb3Jkb25icmFuZGVyLzIyMzAzMTdcbmZ1bmN0aW9uIHVuaXF1ZUlEICgpIHtcbiAgZnVuY3Rpb24gY2hyNCAoKSB7XG4gICAgcmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMTYpLnNsaWNlKC00KTtcbiAgfVxuICByZXR1cm4gY2hyNCgpICsgY2hyNCgpICtcbiAgICAnLScgKyBjaHI0KCkgK1xuICAgICctJyArIGNocjQoKSArXG4gICAgJy0nICsgY2hyNCgpICtcbiAgICAnLScgKyBjaHI0KCkgKyBjaHI0KCkgKyBjaHI0KCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBVbmlxdWUgSUQgZm9yIHRoaXMgY2xhc3NcbiAgICAgKiBAbWVtYmVyb2YhIEJhc2VcbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKiBAdHlwZSB7SUR9XG4gICAgICovXG4gICAgaWQ6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdW5pcXVlSUQoKTtcbiAgICAgIH0sXG4gICAgICBzZXRvbmNlOiB0cnVlXG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3902\n")},"3b07":function(module,exports,__webpack_require__){eval("/**\n * Main spot object.\n *\n * @class Spot\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\nvar Datasets = __webpack_require__(/*! ./dataset/collection */ \"544d\");\nvar driverClient = __webpack_require__(/*! ./driver/client */ \"720c\");\nvar driverServer = __webpack_require__(/*! ./driver/server */ \"072d\");\nvar utildx = __webpack_require__(/*! ./util/crossfilter */ \"adfa\");\nvar timeUtil = __webpack_require__(/*! ./util/time */ \"d45b\");\nvar io = __webpack_require__(/*! socket.io-client */ \"b452\");\n\n/**\n * Connect to the spot-server using a websocket and setup callbacks\n *\n * @function\n * @param {address} Optional. IP address and port number to connect to. fi.  'http://localhost:3000'\n *\n * @memberof! Spot\n */\nfunction connectToServer (address) {\n  var me = this;\n  var socket;\n\n  if (address) {\n    // connect to specified address\n    // necessary for when window.location is not availble (node.js)\n    socket = io.connect(address);\n  } else {\n    // Use socket.io fallback to autodetect address\n    // ie. when a website wants to connect, use the window.location\n    socket = io.connect();\n  }\n\n  socket.on('connect', function () {\n    me.isConnected = true;\n    console.log('Connected to server');\n  });\n\n  socket.on('disconnect', function () {\n    me.isConnected = false;\n  });\n\n  socket.on('syncDatasets', function (req) {\n    // do an incremental update, as we typically start without datasets\n    me.datasets.add(req.data, { merge: true });\n  });\n\n  socket.on('syncDataview', function (req) {\n    me.dataview.reset(req.data);\n  });\n\n  socket.on('syncFacets', function (req) {\n    // do an incremental update, as we typically update only a few properties of a facet\n    // Also, a full reset will orphan the view.model objects in spot-app (ie. crashes)\n    var dataset = me.datasets.get(req.datasetId);\n    dataset.facets.add(req.data, { merge: true });\n\n    me.resetDataview(); // NOTE: the cached (serialized) datasets need to be updated, too\n\n    dataset.trigger('syncFacets');\n  });\n\n  socket.on('newData', function (req) {\n    var filter = me.dataview.filters.get(req.filterId);\n    if (req.data) {\n      filter.data = req.data;\n\n      // for text filters, rebuild partition and count\n      filter.partitions.forEach(function (partition, p) {\n        var columnToName = {1: 'a', 2: 'b', 3: 'c', 4: 'd'};\n\n        if (partition.isText) {\n          partition.groups.reset(null, {silent: true});\n          filter.data.forEach(function (d) {\n            var count = (parseFloat(d.aa) || parseInt(d.count)) || 0;\n\n            if (count) {\n              partition.groups.add({\n                min: 0,\n                max: 100,\n                count: count,\n                label: d[columnToName[(p + 1)]],\n                value: d[columnToName[(p + 1)]]\n              }, {silent: true});\n            }\n          });\n          partition.groups.sort();\n        }\n      });\n      filter.trigger('newData');\n    }\n  });\n\n  socket.on('newMetaData', function (req) {\n    me.dataview.dataTotal = parseInt(req.dataTotal);\n    me.dataview.dataSelected = parseInt(req.dataSelected);\n    console.timeEnd('Get data');\n    me.dataview.trigger('newMetaData');\n  });\n\n  socket.connect();\n  me.socket = socket;\n}\n\n/**\n * Disconnect from the spot-server\n *\n * @function\n * @memberof! Spot\n */\nfunction disconnectFromServer () {\n  this.socket.disconnect();\n}\n\n/**\n * Request a list of available datasets from the server\n *\n * Depending on the driver, this can be an asyncrhonous function.\n * It returns a Promise that resolves to the dataset collection\n *\n * @function\n * @returns {Promise}\n *\n * @memberof! Spot\n */\nfunction getDatasets () {\n  var me = this;\n\n  return new Promise(function (resolve, reject) {\n    me.socket.emit('getDatasets');\n\n    me.datasets.once('reset', function () {\n      resolve(me.datasets);\n    });\n  });\n}\n\n/**\n * Reset min, max, and categories for all facets in the dataview\n *\n * @param {Spot} me Main spot instance\n *\n * @memberof! Spot\n */\nfunction resetDataview () {\n  var toSerialize = [];\n\n  // Update list of active datasets, and serialize the datasets parts we need to send on getData requests\n  this.dataview.datasetIds = [];\n  this.datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      // BUGFIX: the list of datasetIds can get out of sync when using spot-server. Just recreate it always.\n      this.dataview.datasetIds.push(dataset.getId());\n      toSerialize.push(dataset.toJSON()); // TODO: only serialize used facets?\n    }\n  }, this);\n  this.cachedDatasets = JSON.stringify(toSerialize);\n\n  // rescan min/max values and categories for the newly added facets\n  this.dataview.facets.forEach(function (facet) {\n    var newFacet = this.dataview.facets.get(facet.name, 'name');\n\n    if (newFacet.isContinuous || newFacet.isDatetime || newFacet.isDuration) {\n      this.setFacetMinMax(facet);\n    } else if (newFacet.isCategorial) {\n      this.setFacetCategories(facet);\n    }\n  }, this);\n}\n\n/*\n * Add or remove facets from a dataset to the global (merged) dataset\n *\n * @memberof! Spot\n * @param {Spot} me Main spot instance\n * @param {Dataset} dataset Dataset set add or remove\n */\nfunction toggleDatasetFacets (me, dataset) {\n  if (dataset.isActive) {\n    // remove active facets in dataset from the global dataset...\n    dataset.facets.forEach(function (facet) {\n      if (!facet.isActive) {\n        return;\n      }\n\n      // ...but only when no other active dataset contains it\n      var facetIsUnique = true;\n      me.datasets.forEach(function (otherDataset) {\n        if (!otherDataset.isActive || otherDataset === dataset) {\n          return;\n        }\n        if (otherDataset.facets.get(facet.name, 'name')) {\n          facetIsUnique = false;\n        }\n      });\n      if (facetIsUnique) {\n        var toRemove = me.dataview.facets.get(facet.name, 'name');\n        me.dataview.facets.remove(toRemove);\n      }\n    });\n  } else if (!dataset.isActive) {\n    // copy facets\n    dataset.facets.forEach(function (facet) {\n      // do nothing if facet is not active\n      if (!facet.isActive) {\n        return;\n      }\n\n      // default options for all facet types\n      var options = {\n        name: facet.name,\n        accessor: facet.name,\n        description: facet.description,\n        type: facet.transform.transformedType,\n        units: facet.units, // TODO: transformed units?\n        isActive: true\n      };\n\n      // do not add if a similar facet already exists\n      if (!me.dataview.facets.get(facet.name, 'name')) {\n        me.dataview.facets.add(options);\n      }\n    });\n  }\n}\n\n/*\n * Add or remove data from a dataset to the global (merged) dataset\n *\n * @memberof! Spot\n * @param {Spot} me Main spot instance\n * @param {Dataset} dataset Dataset set add or remove\n */\nfunction toggleDatasetData (me, dataset) {\n  if (dataset.isActive) {\n    // if dataset is active, remove it:\n    // ...clear all crossfilter filters\n    me.dataview.filters.forEach(function (filter) {\n      // BUGFIX: when loading sessions, the dataset is not initialized properly\n      // so check for it to be sure\n      if (filter.dimension) {\n        filter.dimension.filterAll();\n      }\n    });\n\n    // ...filter all data, originating from the dataset from the dataset\n    var dimension = me.dataview.crossfilter.dimension(function (d) {\n      return d._OriginalDatasetId;\n    });\n    dimension.filter(dataset.getId());\n\n    // ...remove matching data\n    me.dataview.crossfilter.remove();\n\n    // ...restore original filters\n    dimension.filterAll();\n    dimension.dispose();\n    me.dataview.filters.forEach(function (filter) {\n      filter.updateDataFilter();\n    });\n  } else if (!dataset.isActive) {\n    // if dataset is not active, add it\n    // ...find facets to copy\n    var dataTransforms = [];\n    dataset.facets.forEach(function (facet) {\n      // do nothing if facet is not active\n      if (!facet.isActive) {\n        return;\n      }\n      dataTransforms.push({\n        key: facet.name,\n        fn: utildx.valueFn(facet)\n      });\n    });\n\n    // ...transform data\n    var data = dataset.data;\n    var transformedData = [];\n\n    data.forEach(function (datum) {\n      var transformedDatum = {};\n      dataTransforms.forEach(function (transform) {\n        transformedDatum[transform.key] = transform.fn(datum);\n      });\n      transformedDatum._OriginalDatasetId = dataset.getId();\n      transformedData.push(transformedDatum);\n    });\n\n    // ...add to merged dataset\n    me.dataview.crossfilter.add(transformedData);\n  }\n\n  // update counts\n  me.dataview.dataTotal = me.dataview.crossfilter.size();\n  me.dataview.dataSelected = me.dataview.countGroup.value();\n}\n\n/**\n * Add or remove a dataset from the dataview\n * @param {Dataset} dataset Dataset set add or remove\n *\n * @function\n * @memberof! Spot\n */\nfunction toggleDataset (dataset) {\n  if (this.sessionType === 'server') {\n    toggleDatasetFacets(this, dataset);\n  } else if (this.sessionType === 'client') {\n    // release all filters\n    this.dataview.filters.forEach(function (filter) {\n      filter.releaseDataFilter();\n    });\n\n    // manually merge the datasets\n    toggleDatasetFacets(this, dataset);\n    toggleDatasetData(this, dataset);\n  }\n\n  dataset.isActive = !dataset.isActive;\n\n  this.resetDataview();\n}\n\nfunction setFacetMinMax (facet) {\n  // This should work for all kinds of facets:\n  // numbers, durations, and datatimes all implement the relevant operations\n  var datasets = this.datasets;\n\n  var first = true;\n  datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      var subFacet = dataset.facets.get(facet.name, 'name');\n      if (first) {\n        facet.minvalAsText = subFacet.transform.transformedMinAsText;\n        facet.maxvalAsText = subFacet.transform.transformedMaxAsText;\n        first = false;\n      } else {\n        if (subFacet.minval < facet.minval) {\n          facet.minvalAsText = subFacet.transform.transformedMinAsText;\n        }\n        if (subFacet.maxval > facet.maxval) {\n          facet.maxvalAsText = subFacet.transform.transformedMaxAsText;\n        }\n      }\n    }\n  });\n}\n\nfunction setFacetCategories (facet) {\n  var datasets = this.datasets;\n\n  facet.categorialTransform.reset();\n\n  // get categories by combining the sets for the separate datasets\n  datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      var subFacet = dataset.facets.get(facet.name, 'name');\n\n      if (subFacet.isCategorial) {\n        // merge rules from subFacet into those of Facet\n        subFacet.categorialTransform.rules.forEach(function (rule) {\n          var newRule = facet.categorialTransform.rules.get(rule.expression, 'expression');\n          if (newRule) {\n            newRule.count += rule.count;\n          } else {\n            facet.categorialTransform.rules.add(rule.toJSON());\n          }\n        });\n      } else if (subFacet.isDatetime) {\n        var expressions = timeUtil.timeParts.get(subFacet.datetimeTransform.transformedFormat, 'description').groups;\n        expressions.forEach(function (expression) {\n          var newRule = facet.categorialTransform.rules.get(expression, 'expression');\n          if (newRule) {\n            // no-op: category exist and we don't have a proper count\n          } else {\n            facet.categorialTransform.rules.add({\n              expression: expression,\n              count: 0,\n              group: expression\n            });\n          }\n        });\n      }\n    }\n  });\n}\n\nmodule.exports = BaseModel.extend({\n  type: 'user',\n  props: {\n    /**\n     * Is there a connection with a spot sever?\n     * @memberof! Spot\n     * @type {boolean}\n     */\n    isConnected: ['boolean', true, false],\n    /**\n     * When the app in locked down, facets and datasets cannot be edited\n     * @memberof! Spot\n     * @type {boolean}\n     */\n    isLockedDown: ['boolean', true, false],\n    /**\n     * Type of spot session. Must be 'client' or 'server'\n     * @memberof! Spot\n     * @type {string}\n     */\n    sessionType: {\n      type: 'string',\n      required: true,\n      default: 'client',\n      values: ['client', 'server'],\n      setOnce: true\n    }\n  },\n  children: {\n    /**\n     * A union of all active datasets\n     * @memberof! Spot\n     * @type {Dataview}\n     */\n    dataview: Dataview\n  },\n  collections: {\n    /**\n     * Collection of all datasets\n     * @memberof! Spot\n     * @type {Dataset[]}\n     */\n    datasets: Datasets\n  },\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    // default to client side (crossfilter) sessions\n    this.driver = driverClient;\n\n    // assign backend driver\n    if (arguments && arguments[0] && arguments[0].sessionType) {\n      if (arguments[0].sessionType === 'client') {\n        this.driver = driverClient;\n      } else if (arguments[0].sessionType === 'server') {\n        this.driver = driverServer;\n      } else {\n        console.error('No driver for type', arguments[0].sessionType);\n      }\n    }\n  },\n  resetDataview: resetDataview,\n  connectToServer: connectToServer,\n  disconnectFromServer: disconnectFromServer,\n  getDatasets: getDatasets,\n  setFacetMinMax: setFacetMinMax,\n  setFacetCategories: setFacetCategories,\n  toggleDataset: toggleDataset\n});\n\nmodule.exports.util = {\n  dx: utildx,\n  misval: __webpack_require__(/*! ./util/misval */ \"bff6\"),\n  time: timeUtil\n};\n\nmodule.exports.transforms = {\n  categorial: __webpack_require__(/*! ./facet/categorial-transform */ \"9b75\"),\n  continuous: __webpack_require__(/*! ./facet/continuous-transform */ \"5a80\"),\n  datetime: __webpack_require__(/*! ./facet/datetime-transform */ \"a0ca\"),\n  duration: __webpack_require__(/*! ./facet/duration-transform */ \"b123\")\n};\n\nmodule.exports.constructors = {\n  Dataview: Dataview,\n  Dataset: __webpack_require__(/*! ./dataset */ \"545a\"),\n  Datasets: Datasets\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiM2IwNy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvbWUuanM/Y2NmYSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1haW4gc3BvdCBvYmplY3QuXG4gKlxuICogQGNsYXNzIFNwb3RcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG52YXIgRGF0YXZpZXcgPSByZXF1aXJlKCcuL2RhdGF2aWV3Jyk7XG52YXIgRGF0YXNldHMgPSByZXF1aXJlKCcuL2RhdGFzZXQvY29sbGVjdGlvbicpO1xudmFyIGRyaXZlckNsaWVudCA9IHJlcXVpcmUoJy4vZHJpdmVyL2NsaWVudCcpO1xudmFyIGRyaXZlclNlcnZlciA9IHJlcXVpcmUoJy4vZHJpdmVyL3NlcnZlcicpO1xudmFyIHV0aWxkeCA9IHJlcXVpcmUoJy4vdXRpbC9jcm9zc2ZpbHRlcicpO1xudmFyIHRpbWVVdGlsID0gcmVxdWlyZSgnLi91dGlsL3RpbWUnKTtcbnZhciBpbyA9IHJlcXVpcmUoJ3NvY2tldC5pby1jbGllbnQnKTtcblxuLyoqXG4gKiBDb25uZWN0IHRvIHRoZSBzcG90LXNlcnZlciB1c2luZyBhIHdlYnNvY2tldCBhbmQgc2V0dXAgY2FsbGJhY2tzXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge2FkZHJlc3N9IE9wdGlvbmFsLiBJUCBhZGRyZXNzIGFuZCBwb3J0IG51bWJlciB0byBjb25uZWN0IHRvLiBmaS4gICdodHRwOi8vbG9jYWxob3N0OjMwMDAnXG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIGNvbm5lY3RUb1NlcnZlciAoYWRkcmVzcykge1xuICB2YXIgbWUgPSB0aGlzO1xuICB2YXIgc29ja2V0O1xuXG4gIGlmIChhZGRyZXNzKSB7XG4gICAgLy8gY29ubmVjdCB0byBzcGVjaWZpZWQgYWRkcmVzc1xuICAgIC8vIG5lY2Vzc2FyeSBmb3Igd2hlbiB3aW5kb3cubG9jYXRpb24gaXMgbm90IGF2YWlsYmxlIChub2RlLmpzKVxuICAgIHNvY2tldCA9IGlvLmNvbm5lY3QoYWRkcmVzcyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gVXNlIHNvY2tldC5pbyBmYWxsYmFjayB0byBhdXRvZGV0ZWN0IGFkZHJlc3NcbiAgICAvLyBpZS4gd2hlbiBhIHdlYnNpdGUgd2FudHMgdG8gY29ubmVjdCwgdXNlIHRoZSB3aW5kb3cubG9jYXRpb25cbiAgICBzb2NrZXQgPSBpby5jb25uZWN0KCk7XG4gIH1cblxuICBzb2NrZXQub24oJ2Nvbm5lY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgbWUuaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgIGNvbnNvbGUubG9nKCdDb25uZWN0ZWQgdG8gc2VydmVyJyk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignZGlzY29ubmVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBtZS5pc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICB9KTtcblxuICBzb2NrZXQub24oJ3N5bmNEYXRhc2V0cycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAvLyBkbyBhbiBpbmNyZW1lbnRhbCB1cGRhdGUsIGFzIHdlIHR5cGljYWxseSBzdGFydCB3aXRob3V0IGRhdGFzZXRzXG4gICAgbWUuZGF0YXNldHMuYWRkKHJlcS5kYXRhLCB7IG1lcmdlOiB0cnVlIH0pO1xuICB9KTtcblxuICBzb2NrZXQub24oJ3N5bmNEYXRhdmlldycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICBtZS5kYXRhdmlldy5yZXNldChyZXEuZGF0YSk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignc3luY0ZhY2V0cycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAvLyBkbyBhbiBpbmNyZW1lbnRhbCB1cGRhdGUsIGFzIHdlIHR5cGljYWxseSB1cGRhdGUgb25seSBhIGZldyBwcm9wZXJ0aWVzIG9mIGEgZmFjZXRcbiAgICAvLyBBbHNvLCBhIGZ1bGwgcmVzZXQgd2lsbCBvcnBoYW4gdGhlIHZpZXcubW9kZWwgb2JqZWN0cyBpbiBzcG90LWFwcCAoaWUuIGNyYXNoZXMpXG4gICAgdmFyIGRhdGFzZXQgPSBtZS5kYXRhc2V0cy5nZXQocmVxLmRhdGFzZXRJZCk7XG4gICAgZGF0YXNldC5mYWNldHMuYWRkKHJlcS5kYXRhLCB7IG1lcmdlOiB0cnVlIH0pO1xuXG4gICAgbWUucmVzZXREYXRhdmlldygpOyAvLyBOT1RFOiB0aGUgY2FjaGVkIChzZXJpYWxpemVkKSBkYXRhc2V0cyBuZWVkIHRvIGJlIHVwZGF0ZWQsIHRvb1xuXG4gICAgZGF0YXNldC50cmlnZ2VyKCdzeW5jRmFjZXRzJyk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignbmV3RGF0YScsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICB2YXIgZmlsdGVyID0gbWUuZGF0YXZpZXcuZmlsdGVycy5nZXQocmVxLmZpbHRlcklkKTtcbiAgICBpZiAocmVxLmRhdGEpIHtcbiAgICAgIGZpbHRlci5kYXRhID0gcmVxLmRhdGE7XG5cbiAgICAgIC8vIGZvciB0ZXh0IGZpbHRlcnMsIHJlYnVpbGQgcGFydGl0aW9uIGFuZCBjb3VudFxuICAgICAgZmlsdGVyLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uLCBwKSB7XG4gICAgICAgIHZhciBjb2x1bW5Ub05hbWUgPSB7MTogJ2EnLCAyOiAnYicsIDM6ICdjJywgNDogJ2QnfTtcblxuICAgICAgICBpZiAocGFydGl0aW9uLmlzVGV4dCkge1xuICAgICAgICAgIHBhcnRpdGlvbi5ncm91cHMucmVzZXQobnVsbCwge3NpbGVudDogdHJ1ZX0pO1xuICAgICAgICAgIGZpbHRlci5kYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHZhciBjb3VudCA9IChwYXJzZUZsb2F0KGQuYWEpIHx8IHBhcnNlSW50KGQuY291bnQpKSB8fCAwO1xuXG4gICAgICAgICAgICBpZiAoY291bnQpIHtcbiAgICAgICAgICAgICAgcGFydGl0aW9uLmdyb3Vwcy5hZGQoe1xuICAgICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgICBtYXg6IDEwMCxcbiAgICAgICAgICAgICAgICBjb3VudDogY291bnQsXG4gICAgICAgICAgICAgICAgbGFiZWw6IGRbY29sdW1uVG9OYW1lWyhwICsgMSldXSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogZFtjb2x1bW5Ub05hbWVbKHAgKyAxKV1dXG4gICAgICAgICAgICAgIH0sIHtzaWxlbnQ6IHRydWV9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwYXJ0aXRpb24uZ3JvdXBzLnNvcnQoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBmaWx0ZXIudHJpZ2dlcignbmV3RGF0YScpO1xuICAgIH1cbiAgfSk7XG5cbiAgc29ja2V0Lm9uKCduZXdNZXRhRGF0YScsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICBtZS5kYXRhdmlldy5kYXRhVG90YWwgPSBwYXJzZUludChyZXEuZGF0YVRvdGFsKTtcbiAgICBtZS5kYXRhdmlldy5kYXRhU2VsZWN0ZWQgPSBwYXJzZUludChyZXEuZGF0YVNlbGVjdGVkKTtcbiAgICBjb25zb2xlLnRpbWVFbmQoJ0dldCBkYXRhJyk7XG4gICAgbWUuZGF0YXZpZXcudHJpZ2dlcignbmV3TWV0YURhdGEnKTtcbiAgfSk7XG5cbiAgc29ja2V0LmNvbm5lY3QoKTtcbiAgbWUuc29ja2V0ID0gc29ja2V0O1xufVxuXG4vKipcbiAqIERpc2Nvbm5lY3QgZnJvbSB0aGUgc3BvdC1zZXJ2ZXJcbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiEgU3BvdFxuICovXG5mdW5jdGlvbiBkaXNjb25uZWN0RnJvbVNlcnZlciAoKSB7XG4gIHRoaXMuc29ja2V0LmRpc2Nvbm5lY3QoKTtcbn1cblxuLyoqXG4gKiBSZXF1ZXN0IGEgbGlzdCBvZiBhdmFpbGFibGUgZGF0YXNldHMgZnJvbSB0aGUgc2VydmVyXG4gKlxuICogRGVwZW5kaW5nIG9uIHRoZSBkcml2ZXIsIHRoaXMgY2FuIGJlIGFuIGFzeW5jcmhvbm91cyBmdW5jdGlvbi5cbiAqIEl0IHJldHVybnMgYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGRhdGFzZXQgY29sbGVjdGlvblxuICpcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2V9XG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIGdldERhdGFzZXRzICgpIHtcbiAgdmFyIG1lID0gdGhpcztcblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIG1lLnNvY2tldC5lbWl0KCdnZXREYXRhc2V0cycpO1xuXG4gICAgbWUuZGF0YXNldHMub25jZSgncmVzZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXNvbHZlKG1lLmRhdGFzZXRzKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmVzZXQgbWluLCBtYXgsIGFuZCBjYXRlZ29yaWVzIGZvciBhbGwgZmFjZXRzIGluIHRoZSBkYXRhdmlld1xuICpcbiAqIEBwYXJhbSB7U3BvdH0gbWUgTWFpbiBzcG90IGluc3RhbmNlXG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIHJlc2V0RGF0YXZpZXcgKCkge1xuICB2YXIgdG9TZXJpYWxpemUgPSBbXTtcblxuICAvLyBVcGRhdGUgbGlzdCBvZiBhY3RpdmUgZGF0YXNldHMsIGFuZCBzZXJpYWxpemUgdGhlIGRhdGFzZXRzIHBhcnRzIHdlIG5lZWQgdG8gc2VuZCBvbiBnZXREYXRhIHJlcXVlc3RzXG4gIHRoaXMuZGF0YXZpZXcuZGF0YXNldElkcyA9IFtdO1xuICB0aGlzLmRhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24gKGRhdGFzZXQpIHtcbiAgICBpZiAoZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgICAgLy8gQlVHRklYOiB0aGUgbGlzdCBvZiBkYXRhc2V0SWRzIGNhbiBnZXQgb3V0IG9mIHN5bmMgd2hlbiB1c2luZyBzcG90LXNlcnZlci4gSnVzdCByZWNyZWF0ZSBpdCBhbHdheXMuXG4gICAgICB0aGlzLmRhdGF2aWV3LmRhdGFzZXRJZHMucHVzaChkYXRhc2V0LmdldElkKCkpO1xuICAgICAgdG9TZXJpYWxpemUucHVzaChkYXRhc2V0LnRvSlNPTigpKTsgLy8gVE9ETzogb25seSBzZXJpYWxpemUgdXNlZCBmYWNldHM/XG4gICAgfVxuICB9LCB0aGlzKTtcbiAgdGhpcy5jYWNoZWREYXRhc2V0cyA9IEpTT04uc3RyaW5naWZ5KHRvU2VyaWFsaXplKTtcblxuICAvLyByZXNjYW4gbWluL21heCB2YWx1ZXMgYW5kIGNhdGVnb3JpZXMgZm9yIHRoZSBuZXdseSBhZGRlZCBmYWNldHNcbiAgdGhpcy5kYXRhdmlldy5mYWNldHMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICB2YXIgbmV3RmFjZXQgPSB0aGlzLmRhdGF2aWV3LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcblxuICAgIGlmIChuZXdGYWNldC5pc0NvbnRpbnVvdXMgfHwgbmV3RmFjZXQuaXNEYXRldGltZSB8fCBuZXdGYWNldC5pc0R1cmF0aW9uKSB7XG4gICAgICB0aGlzLnNldEZhY2V0TWluTWF4KGZhY2V0KTtcbiAgICB9IGVsc2UgaWYgKG5ld0ZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgdGhpcy5zZXRGYWNldENhdGVnb3JpZXMoZmFjZXQpO1xuICAgIH1cbiAgfSwgdGhpcyk7XG59XG5cbi8qXG4gKiBBZGQgb3IgcmVtb3ZlIGZhY2V0cyBmcm9tIGEgZGF0YXNldCB0byB0aGUgZ2xvYmFsIChtZXJnZWQpIGRhdGFzZXRcbiAqXG4gKiBAbWVtYmVyb2YhIFNwb3RcbiAqIEBwYXJhbSB7U3BvdH0gbWUgTWFpbiBzcG90IGluc3RhbmNlXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXQgRGF0YXNldCBzZXQgYWRkIG9yIHJlbW92ZVxuICovXG5mdW5jdGlvbiB0b2dnbGVEYXRhc2V0RmFjZXRzIChtZSwgZGF0YXNldCkge1xuICBpZiAoZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIHJlbW92ZSBhY3RpdmUgZmFjZXRzIGluIGRhdGFzZXQgZnJvbSB0aGUgZ2xvYmFsIGRhdGFzZXQuLi5cbiAgICBkYXRhc2V0LmZhY2V0cy5mb3JFYWNoKGZ1bmN0aW9uIChmYWNldCkge1xuICAgICAgaWYgKCFmYWNldC5pc0FjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIC4uLmJ1dCBvbmx5IHdoZW4gbm8gb3RoZXIgYWN0aXZlIGRhdGFzZXQgY29udGFpbnMgaXRcbiAgICAgIHZhciBmYWNldElzVW5pcXVlID0gdHJ1ZTtcbiAgICAgIG1lLmRhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24gKG90aGVyRGF0YXNldCkge1xuICAgICAgICBpZiAoIW90aGVyRGF0YXNldC5pc0FjdGl2ZSB8fCBvdGhlckRhdGFzZXQgPT09IGRhdGFzZXQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG90aGVyRGF0YXNldC5mYWNldHMuZ2V0KGZhY2V0Lm5hbWUsICduYW1lJykpIHtcbiAgICAgICAgICBmYWNldElzVW5pcXVlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKGZhY2V0SXNVbmlxdWUpIHtcbiAgICAgICAgdmFyIHRvUmVtb3ZlID0gbWUuZGF0YXZpZXcuZmFjZXRzLmdldChmYWNldC5uYW1lLCAnbmFtZScpO1xuICAgICAgICBtZS5kYXRhdmlldy5mYWNldHMucmVtb3ZlKHRvUmVtb3ZlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIGlmICghZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIGNvcHkgZmFjZXRzXG4gICAgZGF0YXNldC5mYWNldHMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICAgIC8vIGRvIG5vdGhpbmcgaWYgZmFjZXQgaXMgbm90IGFjdGl2ZVxuICAgICAgaWYgKCFmYWNldC5pc0FjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGRlZmF1bHQgb3B0aW9ucyBmb3IgYWxsIGZhY2V0IHR5cGVzXG4gICAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgbmFtZTogZmFjZXQubmFtZSxcbiAgICAgICAgYWNjZXNzb3I6IGZhY2V0Lm5hbWUsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBmYWNldC5kZXNjcmlwdGlvbixcbiAgICAgICAgdHlwZTogZmFjZXQudHJhbnNmb3JtLnRyYW5zZm9ybWVkVHlwZSxcbiAgICAgICAgdW5pdHM6IGZhY2V0LnVuaXRzLCAvLyBUT0RPOiB0cmFuc2Zvcm1lZCB1bml0cz9cbiAgICAgICAgaXNBY3RpdmU6IHRydWVcbiAgICAgIH07XG5cbiAgICAgIC8vIGRvIG5vdCBhZGQgaWYgYSBzaW1pbGFyIGZhY2V0IGFscmVhZHkgZXhpc3RzXG4gICAgICBpZiAoIW1lLmRhdGF2aWV3LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKSkge1xuICAgICAgICBtZS5kYXRhdmlldy5mYWNldHMuYWRkKG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbi8qXG4gKiBBZGQgb3IgcmVtb3ZlIGRhdGEgZnJvbSBhIGRhdGFzZXQgdG8gdGhlIGdsb2JhbCAobWVyZ2VkKSBkYXRhc2V0XG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKiBAcGFyYW0ge1Nwb3R9IG1lIE1haW4gc3BvdCBpbnN0YW5jZVxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0IERhdGFzZXQgc2V0IGFkZCBvciByZW1vdmVcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlRGF0YXNldERhdGEgKG1lLCBkYXRhc2V0KSB7XG4gIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgLy8gaWYgZGF0YXNldCBpcyBhY3RpdmUsIHJlbW92ZSBpdDpcbiAgICAvLyAuLi5jbGVhciBhbGwgY3Jvc3NmaWx0ZXIgZmlsdGVyc1xuICAgIG1lLmRhdGF2aWV3LmZpbHRlcnMuZm9yRWFjaChmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgICAvLyBCVUdGSVg6IHdoZW4gbG9hZGluZyBzZXNzaW9ucywgdGhlIGRhdGFzZXQgaXMgbm90IGluaXRpYWxpemVkIHByb3Blcmx5XG4gICAgICAvLyBzbyBjaGVjayBmb3IgaXQgdG8gYmUgc3VyZVxuICAgICAgaWYgKGZpbHRlci5kaW1lbnNpb24pIHtcbiAgICAgICAgZmlsdGVyLmRpbWVuc2lvbi5maWx0ZXJBbGwoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIC4uLmZpbHRlciBhbGwgZGF0YSwgb3JpZ2luYXRpbmcgZnJvbSB0aGUgZGF0YXNldCBmcm9tIHRoZSBkYXRhc2V0XG4gICAgdmFyIGRpbWVuc2lvbiA9IG1lLmRhdGF2aWV3LmNyb3NzZmlsdGVyLmRpbWVuc2lvbihmdW5jdGlvbiAoZCkge1xuICAgICAgcmV0dXJuIGQuX09yaWdpbmFsRGF0YXNldElkO1xuICAgIH0pO1xuICAgIGRpbWVuc2lvbi5maWx0ZXIoZGF0YXNldC5nZXRJZCgpKTtcblxuICAgIC8vIC4uLnJlbW92ZSBtYXRjaGluZyBkYXRhXG4gICAgbWUuZGF0YXZpZXcuY3Jvc3NmaWx0ZXIucmVtb3ZlKCk7XG5cbiAgICAvLyAuLi5yZXN0b3JlIG9yaWdpbmFsIGZpbHRlcnNcbiAgICBkaW1lbnNpb24uZmlsdGVyQWxsKCk7XG4gICAgZGltZW5zaW9uLmRpc3Bvc2UoKTtcbiAgICBtZS5kYXRhdmlldy5maWx0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpbHRlcikge1xuICAgICAgZmlsdGVyLnVwZGF0ZURhdGFGaWx0ZXIoKTtcbiAgICB9KTtcbiAgfSBlbHNlIGlmICghZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIGlmIGRhdGFzZXQgaXMgbm90IGFjdGl2ZSwgYWRkIGl0XG4gICAgLy8gLi4uZmluZCBmYWNldHMgdG8gY29weVxuICAgIHZhciBkYXRhVHJhbnNmb3JtcyA9IFtdO1xuICAgIGRhdGFzZXQuZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgICAvLyBkbyBub3RoaW5nIGlmIGZhY2V0IGlzIG5vdCBhY3RpdmVcbiAgICAgIGlmICghZmFjZXQuaXNBY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZGF0YVRyYW5zZm9ybXMucHVzaCh7XG4gICAgICAgIGtleTogZmFjZXQubmFtZSxcbiAgICAgICAgZm46IHV0aWxkeC52YWx1ZUZuKGZhY2V0KVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyAuLi50cmFuc2Zvcm0gZGF0YVxuICAgIHZhciBkYXRhID0gZGF0YXNldC5kYXRhO1xuICAgIHZhciB0cmFuc2Zvcm1lZERhdGEgPSBbXTtcblxuICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZGF0dW0pIHtcbiAgICAgIHZhciB0cmFuc2Zvcm1lZERhdHVtID0ge307XG4gICAgICBkYXRhVHJhbnNmb3Jtcy5mb3JFYWNoKGZ1bmN0aW9uICh0cmFuc2Zvcm0pIHtcbiAgICAgICAgdHJhbnNmb3JtZWREYXR1bVt0cmFuc2Zvcm0ua2V5XSA9IHRyYW5zZm9ybS5mbihkYXR1bSk7XG4gICAgICB9KTtcbiAgICAgIHRyYW5zZm9ybWVkRGF0dW0uX09yaWdpbmFsRGF0YXNldElkID0gZGF0YXNldC5nZXRJZCgpO1xuICAgICAgdHJhbnNmb3JtZWREYXRhLnB1c2godHJhbnNmb3JtZWREYXR1bSk7XG4gICAgfSk7XG5cbiAgICAvLyAuLi5hZGQgdG8gbWVyZ2VkIGRhdGFzZXRcbiAgICBtZS5kYXRhdmlldy5jcm9zc2ZpbHRlci5hZGQodHJhbnNmb3JtZWREYXRhKTtcbiAgfVxuXG4gIC8vIHVwZGF0ZSBjb3VudHNcbiAgbWUuZGF0YXZpZXcuZGF0YVRvdGFsID0gbWUuZGF0YXZpZXcuY3Jvc3NmaWx0ZXIuc2l6ZSgpO1xuICBtZS5kYXRhdmlldy5kYXRhU2VsZWN0ZWQgPSBtZS5kYXRhdmlldy5jb3VudEdyb3VwLnZhbHVlKCk7XG59XG5cbi8qKlxuICogQWRkIG9yIHJlbW92ZSBhIGRhdGFzZXQgZnJvbSB0aGUgZGF0YXZpZXdcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldCBEYXRhc2V0IHNldCBhZGQgb3IgcmVtb3ZlXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2YhIFNwb3RcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlRGF0YXNldCAoZGF0YXNldCkge1xuICBpZiAodGhpcy5zZXNzaW9uVHlwZSA9PT0gJ3NlcnZlcicpIHtcbiAgICB0b2dnbGVEYXRhc2V0RmFjZXRzKHRoaXMsIGRhdGFzZXQpO1xuICB9IGVsc2UgaWYgKHRoaXMuc2Vzc2lvblR5cGUgPT09ICdjbGllbnQnKSB7XG4gICAgLy8gcmVsZWFzZSBhbGwgZmlsdGVyc1xuICAgIHRoaXMuZGF0YXZpZXcuZmlsdGVycy5mb3JFYWNoKGZ1bmN0aW9uIChmaWx0ZXIpIHtcbiAgICAgIGZpbHRlci5yZWxlYXNlRGF0YUZpbHRlcigpO1xuICAgIH0pO1xuXG4gICAgLy8gbWFudWFsbHkgbWVyZ2UgdGhlIGRhdGFzZXRzXG4gICAgdG9nZ2xlRGF0YXNldEZhY2V0cyh0aGlzLCBkYXRhc2V0KTtcbiAgICB0b2dnbGVEYXRhc2V0RGF0YSh0aGlzLCBkYXRhc2V0KTtcbiAgfVxuXG4gIGRhdGFzZXQuaXNBY3RpdmUgPSAhZGF0YXNldC5pc0FjdGl2ZTtcblxuICB0aGlzLnJlc2V0RGF0YXZpZXcoKTtcbn1cblxuZnVuY3Rpb24gc2V0RmFjZXRNaW5NYXggKGZhY2V0KSB7XG4gIC8vIFRoaXMgc2hvdWxkIHdvcmsgZm9yIGFsbCBraW5kcyBvZiBmYWNldHM6XG4gIC8vIG51bWJlcnMsIGR1cmF0aW9ucywgYW5kIGRhdGF0aW1lcyBhbGwgaW1wbGVtZW50IHRoZSByZWxldmFudCBvcGVyYXRpb25zXG4gIHZhciBkYXRhc2V0cyA9IHRoaXMuZGF0YXNldHM7XG5cbiAgdmFyIGZpcnN0ID0gdHJ1ZTtcbiAgZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZGF0YXNldCkge1xuICAgIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgICB2YXIgc3ViRmFjZXQgPSBkYXRhc2V0LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcbiAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICBmYWNldC5taW52YWxBc1RleHQgPSBzdWJGYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW5Bc1RleHQ7XG4gICAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IHN1YkZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZE1heEFzVGV4dDtcbiAgICAgICAgZmlyc3QgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChzdWJGYWNldC5taW52YWwgPCBmYWNldC5taW52YWwpIHtcbiAgICAgICAgICBmYWNldC5taW52YWxBc1RleHQgPSBzdWJGYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW5Bc1RleHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN1YkZhY2V0Lm1heHZhbCA+IGZhY2V0Lm1heHZhbCkge1xuICAgICAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IHN1YkZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZE1heEFzVGV4dDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHNldEZhY2V0Q2F0ZWdvcmllcyAoZmFjZXQpIHtcbiAgdmFyIGRhdGFzZXRzID0gdGhpcy5kYXRhc2V0cztcblxuICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJlc2V0KCk7XG5cbiAgLy8gZ2V0IGNhdGVnb3JpZXMgYnkgY29tYmluaW5nIHRoZSBzZXRzIGZvciB0aGUgc2VwYXJhdGUgZGF0YXNldHNcbiAgZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZGF0YXNldCkge1xuICAgIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgICB2YXIgc3ViRmFjZXQgPSBkYXRhc2V0LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcblxuICAgICAgaWYgKHN1YkZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgICAvLyBtZXJnZSBydWxlcyBmcm9tIHN1YkZhY2V0IGludG8gdGhvc2Ugb2YgRmFjZXRcbiAgICAgICAgc3ViRmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChydWxlKSB7XG4gICAgICAgICAgdmFyIG5ld1J1bGUgPSBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLmdldChydWxlLmV4cHJlc3Npb24sICdleHByZXNzaW9uJyk7XG4gICAgICAgICAgaWYgKG5ld1J1bGUpIHtcbiAgICAgICAgICAgIG5ld1J1bGUuY291bnQgKz0gcnVsZS5jb3VudDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5hZGQocnVsZS50b0pTT04oKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoc3ViRmFjZXQuaXNEYXRldGltZSkge1xuICAgICAgICB2YXIgZXhwcmVzc2lvbnMgPSB0aW1lVXRpbC50aW1lUGFydHMuZ2V0KHN1YkZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKS5ncm91cHM7XG4gICAgICAgIGV4cHJlc3Npb25zLmZvckVhY2goZnVuY3Rpb24gKGV4cHJlc3Npb24pIHtcbiAgICAgICAgICB2YXIgbmV3UnVsZSA9IGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuZ2V0KGV4cHJlc3Npb24sICdleHByZXNzaW9uJyk7XG4gICAgICAgICAgaWYgKG5ld1J1bGUpIHtcbiAgICAgICAgICAgIC8vIG5vLW9wOiBjYXRlZ29yeSBleGlzdCBhbmQgd2UgZG9uJ3QgaGF2ZSBhIHByb3BlciBjb3VudFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLmFkZCh7XG4gICAgICAgICAgICAgIGV4cHJlc3Npb246IGV4cHJlc3Npb24sXG4gICAgICAgICAgICAgIGNvdW50OiAwLFxuICAgICAgICAgICAgICBncm91cDogZXhwcmVzc2lvblxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VNb2RlbC5leHRlbmQoe1xuICB0eXBlOiAndXNlcicsXG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogSXMgdGhlcmUgYSBjb25uZWN0aW9uIHdpdGggYSBzcG90IHNldmVyP1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIGlzQ29ubmVjdGVkOiBbJ2Jvb2xlYW4nLCB0cnVlLCBmYWxzZV0sXG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgYXBwIGluIGxvY2tlZCBkb3duLCBmYWNldHMgYW5kIGRhdGFzZXRzIGNhbm5vdCBiZSBlZGl0ZWRcbiAgICAgKiBAbWVtYmVyb2YhIFNwb3RcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0xvY2tlZERvd246IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXSxcbiAgICAvKipcbiAgICAgKiBUeXBlIG9mIHNwb3Qgc2Vzc2lvbi4gTXVzdCBiZSAnY2xpZW50JyBvciAnc2VydmVyJ1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgc2Vzc2lvblR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnY2xpZW50JyxcbiAgICAgIHZhbHVlczogWydjbGllbnQnLCAnc2VydmVyJ10sXG4gICAgICBzZXRPbmNlOiB0cnVlXG4gICAgfVxuICB9LFxuICBjaGlsZHJlbjoge1xuICAgIC8qKlxuICAgICAqIEEgdW5pb24gb2YgYWxsIGFjdGl2ZSBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtEYXRhdmlld31cbiAgICAgKi9cbiAgICBkYXRhdmlldzogRGF0YXZpZXdcbiAgfSxcbiAgY29sbGVjdGlvbnM6IHtcbiAgICAvKipcbiAgICAgKiBDb2xsZWN0aW9uIG9mIGFsbCBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtEYXRhc2V0W119XG4gICAgICovXG4gICAgZGF0YXNldHM6IERhdGFzZXRzXG4gIH0sXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBmaXJzdCBkbyBwYXJlbnQgY2xhc3MgaW5pdGlhbGl6YXRpb25cbiAgICBCYXNlTW9kZWwucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIC8vIGRlZmF1bHQgdG8gY2xpZW50IHNpZGUgKGNyb3NzZmlsdGVyKSBzZXNzaW9uc1xuICAgIHRoaXMuZHJpdmVyID0gZHJpdmVyQ2xpZW50O1xuXG4gICAgLy8gYXNzaWduIGJhY2tlbmQgZHJpdmVyXG4gICAgaWYgKGFyZ3VtZW50cyAmJiBhcmd1bWVudHNbMF0gJiYgYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlKSB7XG4gICAgICBpZiAoYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlID09PSAnY2xpZW50Jykge1xuICAgICAgICB0aGlzLmRyaXZlciA9IGRyaXZlckNsaWVudDtcbiAgICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlID09PSAnc2VydmVyJykge1xuICAgICAgICB0aGlzLmRyaXZlciA9IGRyaXZlclNlcnZlcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ05vIGRyaXZlciBmb3IgdHlwZScsIGFyZ3VtZW50c1swXS5zZXNzaW9uVHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICByZXNldERhdGF2aWV3OiByZXNldERhdGF2aWV3LFxuICBjb25uZWN0VG9TZXJ2ZXI6IGNvbm5lY3RUb1NlcnZlcixcbiAgZGlzY29ubmVjdEZyb21TZXJ2ZXI6IGRpc2Nvbm5lY3RGcm9tU2VydmVyLFxuICBnZXREYXRhc2V0czogZ2V0RGF0YXNldHMsXG4gIHNldEZhY2V0TWluTWF4OiBzZXRGYWNldE1pbk1heCxcbiAgc2V0RmFjZXRDYXRlZ29yaWVzOiBzZXRGYWNldENhdGVnb3JpZXMsXG4gIHRvZ2dsZURhdGFzZXQ6IHRvZ2dsZURhdGFzZXRcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cy51dGlsID0ge1xuICBkeDogdXRpbGR4LFxuICBtaXN2YWw6IHJlcXVpcmUoJy4vdXRpbC9taXN2YWwnKSxcbiAgdGltZTogdGltZVV0aWxcbn07XG5cbm1vZHVsZS5leHBvcnRzLnRyYW5zZm9ybXMgPSB7XG4gIGNhdGVnb3JpYWw6IHJlcXVpcmUoJy4vZmFjZXQvY2F0ZWdvcmlhbC10cmFuc2Zvcm0nKSxcbiAgY29udGludW91czogcmVxdWlyZSgnLi9mYWNldC9jb250aW51b3VzLXRyYW5zZm9ybScpLFxuICBkYXRldGltZTogcmVxdWlyZSgnLi9mYWNldC9kYXRldGltZS10cmFuc2Zvcm0nKSxcbiAgZHVyYXRpb246IHJlcXVpcmUoJy4vZmFjZXQvZHVyYXRpb24tdHJhbnNmb3JtJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNvbnN0cnVjdG9ycyA9IHtcbiAgRGF0YXZpZXc6IERhdGF2aWV3LFxuICBEYXRhc2V0OiByZXF1aXJlKCcuL2RhdGFzZXQnKSxcbiAgRGF0YXNldHM6IERhdGFzZXRzXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3b07\n")},"419b":function(module,exports,__webpack_require__){eval('/* WEBPACK VAR INJECTION */(function(global) {\nmodule.exports = isBuf;\n\n/**\n * Returns true if obj is a buffer or an arraybuffer.\n *\n * @api private\n */\n\nfunction isBuf(obj) {\n  return (global.Buffer && global.Buffer.isBuffer(obj)) ||\n         (global.ArrayBuffer && obj instanceof ArrayBuffer);\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ "698d")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE5Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9pcy1idWZmZXIuanM/MGJlNiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbm1vZHVsZS5leHBvcnRzID0gaXNCdWY7XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIG9iaiBpcyBhIGJ1ZmZlciBvciBhbiBhcnJheWJ1ZmZlci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0J1ZihvYmopIHtcbiAgcmV0dXJuIChnbG9iYWwuQnVmZmVyICYmIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIob2JqKSkgfHxcbiAgICAgICAgIChnbG9iYWwuQXJyYXlCdWZmZXIgJiYgb2JqIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpO1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///419b\n')},"433b":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(process) {\n/**\n * This is the web browser implementation of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = __webpack_require__(/*! ./debug */ \"23b1\");\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = 'undefined' != typeof chrome\n               && 'undefined' != typeof chrome.storage\n                  ? chrome.storage.local\n                  : localstorage();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n  'lightseagreen',\n  'forestgreen',\n  'goldenrod',\n  'dodgerblue',\n  'darkorchid',\n  'crimson'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\nfunction useColors() {\n  // is webkit? http://stackoverflow.com/a/16459606/376773\n  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n  return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) ||\n    // is firebug? http://stackoverflow.com/a/398120/376773\n    (window.console && (console.firebug || (console.exception && console.table))) ||\n    // is firefox >= v31?\n    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n    (navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31);\n}\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nexports.formatters.j = function(v) {\n  try {\n    return JSON.stringify(v);\n  } catch (err) {\n    return '[UnexpectedJSONParseError]: ' + err.message;\n  }\n};\n\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs() {\n  var args = arguments;\n  var useColors = this.useColors;\n\n  args[0] = (useColors ? '%c' : '')\n    + this.namespace\n    + (useColors ? ' %c' : ' ')\n    + args[0]\n    + (useColors ? '%c ' : ' ')\n    + '+' + exports.humanize(this.diff);\n\n  if (!useColors) return args;\n\n  var c = 'color: ' + this.color;\n  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));\n\n  // the final \"%c\" is somewhat tricky, because there could be other\n  // arguments passed either before or after the %c, so we need to\n  // figure out the correct index to insert the CSS into\n  var index = 0;\n  var lastC = 0;\n  args[0].replace(/%[a-z%]/g, function(match) {\n    if ('%%' === match) return;\n    index++;\n    if ('%c' === match) {\n      // we only are interested in the *last* %c\n      // (the user may have provided their own)\n      lastC = index;\n    }\n  });\n\n  args.splice(lastC, 0, c);\n  return args;\n}\n\n/**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\nfunction log() {\n  // this hackery is required for IE8/9, where\n  // the `console.log` function doesn't have 'apply'\n  return 'object' === typeof console\n    && console.log\n    && Function.prototype.apply.call(console.log, console, arguments);\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\nfunction save(namespaces) {\n  try {\n    if (null == namespaces) {\n      exports.storage.removeItem('debug');\n    } else {\n      exports.storage.debug = namespaces;\n    }\n  } catch(e) {}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n  var r;\n  try {\n    return exports.storage.debug;\n  } catch(e) {}\n\n  // If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n  if (typeof process !== 'undefined' && 'env' in process) {\n    return process.env.DEBUG;\n  }\n}\n\n/**\n * Enable namespaces listed in `localStorage.debug` initially.\n */\n\nexports.enable(load());\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage(){\n  try {\n    return window.localStorage;\n  } catch (e) {}\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../process/browser.js */ \"26d5\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMzYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZGVidWcvYnJvd3Nlci5qcz82NDdhIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSB3ZWIgYnJvd3NlciBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gKlxuICogRXhwb3NlIGBkZWJ1ZygpYCBhcyB0aGUgbW9kdWxlLlxuICovXG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZGVidWcnKTtcbmV4cG9ydHMubG9nID0gbG9nO1xuZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbmV4cG9ydHMuc2F2ZSA9IHNhdmU7XG5leHBvcnRzLmxvYWQgPSBsb2FkO1xuZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG5leHBvcnRzLnN0b3JhZ2UgPSAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lXG4gICAgICAgICAgICAgICAmJiAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lLnN0b3JhZ2VcbiAgICAgICAgICAgICAgICAgID8gY2hyb21lLnN0b3JhZ2UubG9jYWxcbiAgICAgICAgICAgICAgICAgIDogbG9jYWxzdG9yYWdlKCk7XG5cbi8qKlxuICogQ29sb3JzLlxuICovXG5cbmV4cG9ydHMuY29sb3JzID0gW1xuICAnbGlnaHRzZWFncmVlbicsXG4gICdmb3Jlc3RncmVlbicsXG4gICdnb2xkZW5yb2QnLFxuICAnZG9kZ2VyYmx1ZScsXG4gICdkYXJrb3JjaGlkJyxcbiAgJ2NyaW1zb24nXG5dO1xuXG4vKipcbiAqIEN1cnJlbnRseSBvbmx5IFdlYktpdC1iYXNlZCBXZWIgSW5zcGVjdG9ycywgRmlyZWZveCA+PSB2MzEsXG4gKiBhbmQgdGhlIEZpcmVidWcgZXh0ZW5zaW9uIChhbnkgRmlyZWZveCB2ZXJzaW9uKSBhcmUga25vd25cbiAqIHRvIHN1cHBvcnQgXCIlY1wiIENTUyBjdXN0b21pemF0aW9ucy5cbiAqXG4gKiBUT0RPOiBhZGQgYSBgbG9jYWxTdG9yYWdlYCB2YXJpYWJsZSB0byBleHBsaWNpdGx5IGVuYWJsZS9kaXNhYmxlIGNvbG9yc1xuICovXG5cbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcbiAgLy8gaXMgd2Via2l0PyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNjQ1OTYwNi8zNzY3NzNcbiAgLy8gZG9jdW1lbnQgaXMgdW5kZWZpbmVkIGluIHJlYWN0LW5hdGl2ZTogaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0LW5hdGl2ZS9wdWxsLzE2MzJcbiAgcmV0dXJuICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmICdXZWJraXRBcHBlYXJhbmNlJyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUpIHx8XG4gICAgLy8gaXMgZmlyZWJ1Zz8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzk4MTIwLzM3Njc3M1xuICAgICh3aW5kb3cuY29uc29sZSAmJiAoY29uc29sZS5maXJlYnVnIHx8IChjb25zb2xlLmV4Y2VwdGlvbiAmJiBjb25zb2xlLnRhYmxlKSkpIHx8XG4gICAgLy8gaXMgZmlyZWZveCA+PSB2MzE/XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9Ub29scy9XZWJfQ29uc29sZSNTdHlsaW5nX21lc3NhZ2VzXG4gICAgKG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5tYXRjaCgvZmlyZWZveFxcLyhcXGQrKS8pICYmIHBhcnNlSW50KFJlZ0V4cC4kMSwgMTApID49IDMxKTtcbn1cblxuLyoqXG4gKiBNYXAgJWogdG8gYEpTT04uc3RyaW5naWZ5KClgLCBzaW5jZSBubyBXZWIgSW5zcGVjdG9ycyBkbyB0aGF0IGJ5IGRlZmF1bHQuXG4gKi9cblxuZXhwb3J0cy5mb3JtYXR0ZXJzLmogPSBmdW5jdGlvbih2KSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHYpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gJ1tVbmV4cGVjdGVkSlNPTlBhcnNlRXJyb3JdOiAnICsgZXJyLm1lc3NhZ2U7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBDb2xvcml6ZSBsb2cgYXJndW1lbnRzIGlmIGVuYWJsZWQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBmb3JtYXRBcmdzKCkge1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIHVzZUNvbG9ycyA9IHRoaXMudXNlQ29sb3JzO1xuXG4gIGFyZ3NbMF0gPSAodXNlQ29sb3JzID8gJyVjJyA6ICcnKVxuICAgICsgdGhpcy5uYW1lc3BhY2VcbiAgICArICh1c2VDb2xvcnMgPyAnICVjJyA6ICcgJylcbiAgICArIGFyZ3NbMF1cbiAgICArICh1c2VDb2xvcnMgPyAnJWMgJyA6ICcgJylcbiAgICArICcrJyArIGV4cG9ydHMuaHVtYW5pemUodGhpcy5kaWZmKTtcblxuICBpZiAoIXVzZUNvbG9ycykgcmV0dXJuIGFyZ3M7XG5cbiAgdmFyIGMgPSAnY29sb3I6ICcgKyB0aGlzLmNvbG9yO1xuICBhcmdzID0gW2FyZ3NbMF0sIGMsICdjb2xvcjogaW5oZXJpdCddLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmdzLCAxKSk7XG5cbiAgLy8gdGhlIGZpbmFsIFwiJWNcIiBpcyBzb21ld2hhdCB0cmlja3ksIGJlY2F1c2UgdGhlcmUgY291bGQgYmUgb3RoZXJcbiAgLy8gYXJndW1lbnRzIHBhc3NlZCBlaXRoZXIgYmVmb3JlIG9yIGFmdGVyIHRoZSAlYywgc28gd2UgbmVlZCB0b1xuICAvLyBmaWd1cmUgb3V0IHRoZSBjb3JyZWN0IGluZGV4IHRvIGluc2VydCB0aGUgQ1NTIGludG9cbiAgdmFyIGluZGV4ID0gMDtcbiAgdmFyIGxhc3RDID0gMDtcbiAgYXJnc1swXS5yZXBsYWNlKC8lW2EteiVdL2csIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgaWYgKCclJScgPT09IG1hdGNoKSByZXR1cm47XG4gICAgaW5kZXgrKztcbiAgICBpZiAoJyVjJyA9PT0gbWF0Y2gpIHtcbiAgICAgIC8vIHdlIG9ubHkgYXJlIGludGVyZXN0ZWQgaW4gdGhlICpsYXN0KiAlY1xuICAgICAgLy8gKHRoZSB1c2VyIG1heSBoYXZlIHByb3ZpZGVkIHRoZWlyIG93bilcbiAgICAgIGxhc3RDID0gaW5kZXg7XG4gICAgfVxuICB9KTtcblxuICBhcmdzLnNwbGljZShsYXN0QywgMCwgYyk7XG4gIHJldHVybiBhcmdzO1xufVxuXG4vKipcbiAqIEludm9rZXMgYGNvbnNvbGUubG9nKClgIHdoZW4gYXZhaWxhYmxlLlxuICogTm8tb3Agd2hlbiBgY29uc29sZS5sb2dgIGlzIG5vdCBhIFwiZnVuY3Rpb25cIi5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGxvZygpIHtcbiAgLy8gdGhpcyBoYWNrZXJ5IGlzIHJlcXVpcmVkIGZvciBJRTgvOSwgd2hlcmVcbiAgLy8gdGhlIGBjb25zb2xlLmxvZ2AgZnVuY3Rpb24gZG9lc24ndCBoYXZlICdhcHBseSdcbiAgcmV0dXJuICdvYmplY3QnID09PSB0eXBlb2YgY29uc29sZVxuICAgICYmIGNvbnNvbGUubG9nXG4gICAgJiYgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoY29uc29sZS5sb2csIGNvbnNvbGUsIGFyZ3VtZW50cyk7XG59XG5cbi8qKlxuICogU2F2ZSBgbmFtZXNwYWNlc2AuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNhdmUobmFtZXNwYWNlcykge1xuICB0cnkge1xuICAgIGlmIChudWxsID09IG5hbWVzcGFjZXMpIHtcbiAgICAgIGV4cG9ydHMuc3RvcmFnZS5yZW1vdmVJdGVtKCdkZWJ1ZycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLnN0b3JhZ2UuZGVidWcgPSBuYW1lc3BhY2VzO1xuICAgIH1cbiAgfSBjYXRjaChlKSB7fVxufVxuXG4vKipcbiAqIExvYWQgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gcmV0dXJucyB0aGUgcHJldmlvdXNseSBwZXJzaXN0ZWQgZGVidWcgbW9kZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvYWQoKSB7XG4gIHZhciByO1xuICB0cnkge1xuICAgIHJldHVybiBleHBvcnRzLnN0b3JhZ2UuZGVidWc7XG4gIH0gY2F0Y2goZSkge31cblxuICAvLyBJZiBkZWJ1ZyBpc24ndCBzZXQgaW4gTFMsIGFuZCB3ZSdyZSBpbiBFbGVjdHJvbiwgdHJ5IHRvIGxvYWQgJERFQlVHXG4gIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ2VudicgaW4gcHJvY2Vzcykge1xuICAgIHJldHVybiBwcm9jZXNzLmVudi5ERUJVRztcbiAgfVxufVxuXG4vKipcbiAqIEVuYWJsZSBuYW1lc3BhY2VzIGxpc3RlZCBpbiBgbG9jYWxTdG9yYWdlLmRlYnVnYCBpbml0aWFsbHkuXG4gKi9cblxuZXhwb3J0cy5lbmFibGUobG9hZCgpKTtcblxuLyoqXG4gKiBMb2NhbHN0b3JhZ2UgYXR0ZW1wdHMgdG8gcmV0dXJuIHRoZSBsb2NhbHN0b3JhZ2UuXG4gKlxuICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBzYWZhcmkgdGhyb3dzXG4gKiB3aGVuIGEgdXNlciBkaXNhYmxlcyBjb29raWVzL2xvY2Fsc3RvcmFnZVxuICogYW5kIHlvdSBhdHRlbXB0IHRvIGFjY2VzcyBpdC5cbiAqXG4gKiBAcmV0dXJuIHtMb2NhbFN0b3JhZ2V9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2NhbHN0b3JhZ2UoKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZTtcbiAgfSBjYXRjaCAoZSkge31cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///433b\n")},"4c13":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar toArray = __webpack_require__(/*! to-array */ \"7de3\");\nvar on = __webpack_require__(/*! ./on */ \"faaa\");\nvar bind = __webpack_require__(/*! component-bind */ \"b6f6\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:socket');\nvar hasBin = __webpack_require__(/*! has-binary */ \"d304\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = exports = Socket;\n\n/**\n * Internal events (blacklisted).\n * These events can't be emitted by the user.\n *\n * @api private\n */\n\nvar events = {\n  connect: 1,\n  connect_error: 1,\n  connect_timeout: 1,\n  connecting: 1,\n  disconnect: 1,\n  error: 1,\n  reconnect: 1,\n  reconnect_attempt: 1,\n  reconnect_failed: 1,\n  reconnect_error: 1,\n  reconnecting: 1,\n  ping: 1,\n  pong: 1\n};\n\n/**\n * Shortcut to `Emitter#emit`.\n */\n\nvar emit = Emitter.prototype.emit;\n\n/**\n * `Socket` constructor.\n *\n * @api public\n */\n\nfunction Socket (io, nsp, opts) {\n  this.io = io;\n  this.nsp = nsp;\n  this.json = this; // compat\n  this.ids = 0;\n  this.acks = {};\n  this.receiveBuffer = [];\n  this.sendBuffer = [];\n  this.connected = false;\n  this.disconnected = true;\n  if (opts && opts.query) {\n    this.query = opts.query;\n  }\n  if (this.io.autoConnect) this.open();\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Socket.prototype);\n\n/**\n * Subscribe to open, close and packet events\n *\n * @api private\n */\n\nSocket.prototype.subEvents = function () {\n  if (this.subs) return;\n\n  var io = this.io;\n  this.subs = [\n    on(io, 'open', bind(this, 'onopen')),\n    on(io, 'packet', bind(this, 'onpacket')),\n    on(io, 'close', bind(this, 'onclose'))\n  ];\n};\n\n/**\n * \"Opens\" the socket.\n *\n * @api public\n */\n\nSocket.prototype.open =\nSocket.prototype.connect = function () {\n  if (this.connected) return this;\n\n  this.subEvents();\n  this.io.open(); // ensure open\n  if ('open' === this.io.readyState) this.onopen();\n  this.emit('connecting');\n  return this;\n};\n\n/**\n * Sends a `message` event.\n *\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.send = function () {\n  var args = toArray(arguments);\n  args.unshift('message');\n  this.emit.apply(this, args);\n  return this;\n};\n\n/**\n * Override `emit`.\n * If the event is in `events`, it's emitted normally.\n *\n * @param {String} event name\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.emit = function (ev) {\n  if (events.hasOwnProperty(ev)) {\n    emit.apply(this, arguments);\n    return this;\n  }\n\n  var args = toArray(arguments);\n  var parserType = parser.EVENT; // default\n  if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary\n  var packet = { type: parserType, data: args };\n\n  packet.options = {};\n  packet.options.compress = !this.flags || false !== this.flags.compress;\n\n  // event ack callback\n  if ('function' === typeof args[args.length - 1]) {\n    debug('emitting packet with ack id %d', this.ids);\n    this.acks[this.ids] = args.pop();\n    packet.id = this.ids++;\n  }\n\n  if (this.connected) {\n    this.packet(packet);\n  } else {\n    this.sendBuffer.push(packet);\n  }\n\n  delete this.flags;\n\n  return this;\n};\n\n/**\n * Sends a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.packet = function (packet) {\n  packet.nsp = this.nsp;\n  this.io.packet(packet);\n};\n\n/**\n * Called upon engine `open`.\n *\n * @api private\n */\n\nSocket.prototype.onopen = function () {\n  debug('transport is open - connecting');\n\n  // write connect packet if necessary\n  if ('/' !== this.nsp) {\n    if (this.query) {\n      this.packet({type: parser.CONNECT, query: this.query});\n    } else {\n      this.packet({type: parser.CONNECT});\n    }\n  }\n};\n\n/**\n * Called upon engine `close`.\n *\n * @param {String} reason\n * @api private\n */\n\nSocket.prototype.onclose = function (reason) {\n  debug('close (%s)', reason);\n  this.connected = false;\n  this.disconnected = true;\n  delete this.id;\n  this.emit('disconnect', reason);\n};\n\n/**\n * Called with socket packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onpacket = function (packet) {\n  if (packet.nsp !== this.nsp) return;\n\n  switch (packet.type) {\n    case parser.CONNECT:\n      this.onconnect();\n      break;\n\n    case parser.EVENT:\n      this.onevent(packet);\n      break;\n\n    case parser.BINARY_EVENT:\n      this.onevent(packet);\n      break;\n\n    case parser.ACK:\n      this.onack(packet);\n      break;\n\n    case parser.BINARY_ACK:\n      this.onack(packet);\n      break;\n\n    case parser.DISCONNECT:\n      this.ondisconnect();\n      break;\n\n    case parser.ERROR:\n      this.emit('error', packet.data);\n      break;\n  }\n};\n\n/**\n * Called upon a server event.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onevent = function (packet) {\n  var args = packet.data || [];\n  debug('emitting event %j', args);\n\n  if (null != packet.id) {\n    debug('attaching ack callback to event');\n    args.push(this.ack(packet.id));\n  }\n\n  if (this.connected) {\n    emit.apply(this, args);\n  } else {\n    this.receiveBuffer.push(args);\n  }\n};\n\n/**\n * Produces an ack callback to emit with an event.\n *\n * @api private\n */\n\nSocket.prototype.ack = function (id) {\n  var self = this;\n  var sent = false;\n  return function () {\n    // prevent double callbacks\n    if (sent) return;\n    sent = true;\n    var args = toArray(arguments);\n    debug('sending ack %j', args);\n\n    var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;\n    self.packet({\n      type: type,\n      id: id,\n      data: args\n    });\n  };\n};\n\n/**\n * Called upon a server acknowlegement.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onack = function (packet) {\n  var ack = this.acks[packet.id];\n  if ('function' === typeof ack) {\n    debug('calling ack %s with %j', packet.id, packet.data);\n    ack.apply(this, packet.data);\n    delete this.acks[packet.id];\n  } else {\n    debug('bad ack %s', packet.id);\n  }\n};\n\n/**\n * Called upon server connect.\n *\n * @api private\n */\n\nSocket.prototype.onconnect = function () {\n  this.connected = true;\n  this.disconnected = false;\n  this.emit('connect');\n  this.emitBuffered();\n};\n\n/**\n * Emit buffered events (received and emitted).\n *\n * @api private\n */\n\nSocket.prototype.emitBuffered = function () {\n  var i;\n  for (i = 0; i < this.receiveBuffer.length; i++) {\n    emit.apply(this, this.receiveBuffer[i]);\n  }\n  this.receiveBuffer = [];\n\n  for (i = 0; i < this.sendBuffer.length; i++) {\n    this.packet(this.sendBuffer[i]);\n  }\n  this.sendBuffer = [];\n};\n\n/**\n * Called upon server disconnect.\n *\n * @api private\n */\n\nSocket.prototype.ondisconnect = function () {\n  debug('server disconnect (%s)', this.nsp);\n  this.destroy();\n  this.onclose('io server disconnect');\n};\n\n/**\n * Called upon forced client/server side disconnections,\n * this method ensures the manager stops tracking us and\n * that reconnections don't get triggered for this.\n *\n * @api private.\n */\n\nSocket.prototype.destroy = function () {\n  if (this.subs) {\n    // clean subscriptions to avoid reconnections\n    for (var i = 0; i < this.subs.length; i++) {\n      this.subs[i].destroy();\n    }\n    this.subs = null;\n  }\n\n  this.io.destroy(this);\n};\n\n/**\n * Disconnects the socket manually.\n *\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.close =\nSocket.prototype.disconnect = function () {\n  if (this.connected) {\n    debug('performing disconnect (%s)', this.nsp);\n    this.packet({ type: parser.DISCONNECT });\n  }\n\n  // remove socket from pool\n  this.destroy();\n\n  if (this.connected) {\n    // fire events\n    this.onclose('io client disconnect');\n  }\n  return this;\n};\n\n/**\n * Sets the compress flag.\n *\n * @param {Boolean} if `true`, compresses the sending data\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.compress = function (compress) {\n  this.flags = this.flags || {};\n  this.flags.compress = compress;\n  return this;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNGMxMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvc29ja2V0LmpzPzg3ZDEiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNlciA9IHJlcXVpcmUoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciB0b0FycmF5ID0gcmVxdWlyZSgndG8tYXJyYXknKTtcbnZhciBvbiA9IHJlcXVpcmUoJy4vb24nKTtcbnZhciBiaW5kID0gcmVxdWlyZSgnY29tcG9uZW50LWJpbmQnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6c29ja2V0Jyk7XG52YXIgaGFzQmluID0gcmVxdWlyZSgnaGFzLWJpbmFyeScpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IFNvY2tldDtcblxuLyoqXG4gKiBJbnRlcm5hbCBldmVudHMgKGJsYWNrbGlzdGVkKS5cbiAqIFRoZXNlIGV2ZW50cyBjYW4ndCBiZSBlbWl0dGVkIGJ5IHRoZSB1c2VyLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbnZhciBldmVudHMgPSB7XG4gIGNvbm5lY3Q6IDEsXG4gIGNvbm5lY3RfZXJyb3I6IDEsXG4gIGNvbm5lY3RfdGltZW91dDogMSxcbiAgY29ubmVjdGluZzogMSxcbiAgZGlzY29ubmVjdDogMSxcbiAgZXJyb3I6IDEsXG4gIHJlY29ubmVjdDogMSxcbiAgcmVjb25uZWN0X2F0dGVtcHQ6IDEsXG4gIHJlY29ubmVjdF9mYWlsZWQ6IDEsXG4gIHJlY29ubmVjdF9lcnJvcjogMSxcbiAgcmVjb25uZWN0aW5nOiAxLFxuICBwaW5nOiAxLFxuICBwb25nOiAxXG59O1xuXG4vKipcbiAqIFNob3J0Y3V0IHRvIGBFbWl0dGVyI2VtaXRgLlxuICovXG5cbnZhciBlbWl0ID0gRW1pdHRlci5wcm90b3R5cGUuZW1pdDtcblxuLyoqXG4gKiBgU29ja2V0YCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFNvY2tldCAoaW8sIG5zcCwgb3B0cykge1xuICB0aGlzLmlvID0gaW87XG4gIHRoaXMubnNwID0gbnNwO1xuICB0aGlzLmpzb24gPSB0aGlzOyAvLyBjb21wYXRcbiAgdGhpcy5pZHMgPSAwO1xuICB0aGlzLmFja3MgPSB7fTtcbiAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG4gIHRoaXMuc2VuZEJ1ZmZlciA9IFtdO1xuICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICB0aGlzLmRpc2Nvbm5lY3RlZCA9IHRydWU7XG4gIGlmIChvcHRzICYmIG9wdHMucXVlcnkpIHtcbiAgICB0aGlzLnF1ZXJ5ID0gb3B0cy5xdWVyeTtcbiAgfVxuICBpZiAodGhpcy5pby5hdXRvQ29ubmVjdCkgdGhpcy5vcGVuKCk7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFNvY2tldC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIFN1YnNjcmliZSB0byBvcGVuLCBjbG9zZSBhbmQgcGFja2V0IGV2ZW50c1xuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc3ViRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zdWJzKSByZXR1cm47XG5cbiAgdmFyIGlvID0gdGhpcy5pbztcbiAgdGhpcy5zdWJzID0gW1xuICAgIG9uKGlvLCAnb3BlbicsIGJpbmQodGhpcywgJ29ub3BlbicpKSxcbiAgICBvbihpbywgJ3BhY2tldCcsIGJpbmQodGhpcywgJ29ucGFja2V0JykpLFxuICAgIG9uKGlvLCAnY2xvc2UnLCBiaW5kKHRoaXMsICdvbmNsb3NlJykpXG4gIF07XG59O1xuXG4vKipcbiAqIFwiT3BlbnNcIiB0aGUgc29ja2V0LlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vcGVuID1cblNvY2tldC5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY29ubmVjdGVkKSByZXR1cm4gdGhpcztcblxuICB0aGlzLnN1YkV2ZW50cygpO1xuICB0aGlzLmlvLm9wZW4oKTsgLy8gZW5zdXJlIG9wZW5cbiAgaWYgKCdvcGVuJyA9PT0gdGhpcy5pby5yZWFkeVN0YXRlKSB0aGlzLm9ub3BlbigpO1xuICB0aGlzLmVtaXQoJ2Nvbm5lY3RpbmcnKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIGEgYG1lc3NhZ2VgIGV2ZW50LlxuICpcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMpO1xuICBhcmdzLnVuc2hpZnQoJ21lc3NhZ2UnKTtcbiAgdGhpcy5lbWl0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgYGVtaXRgLlxuICogSWYgdGhlIGV2ZW50IGlzIGluIGBldmVudHNgLCBpdCdzIGVtaXR0ZWQgbm9ybWFsbHkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IG5hbWVcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShldikpIHtcbiAgICBlbWl0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgdmFyIHBhcnNlclR5cGUgPSBwYXJzZXIuRVZFTlQ7IC8vIGRlZmF1bHRcbiAgaWYgKGhhc0JpbihhcmdzKSkgeyBwYXJzZXJUeXBlID0gcGFyc2VyLkJJTkFSWV9FVkVOVDsgfSAvLyBiaW5hcnlcbiAgdmFyIHBhY2tldCA9IHsgdHlwZTogcGFyc2VyVHlwZSwgZGF0YTogYXJncyB9O1xuXG4gIHBhY2tldC5vcHRpb25zID0ge307XG4gIHBhY2tldC5vcHRpb25zLmNvbXByZXNzID0gIXRoaXMuZmxhZ3MgfHwgZmFsc2UgIT09IHRoaXMuZmxhZ3MuY29tcHJlc3M7XG5cbiAgLy8gZXZlbnQgYWNrIGNhbGxiYWNrXG4gIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgYXJnc1thcmdzLmxlbmd0aCAtIDFdKSB7XG4gICAgZGVidWcoJ2VtaXR0aW5nIHBhY2tldCB3aXRoIGFjayBpZCAlZCcsIHRoaXMuaWRzKTtcbiAgICB0aGlzLmFja3NbdGhpcy5pZHNdID0gYXJncy5wb3AoKTtcbiAgICBwYWNrZXQuaWQgPSB0aGlzLmlkcysrO1xuICB9XG5cbiAgaWYgKHRoaXMuY29ubmVjdGVkKSB7XG4gICAgdGhpcy5wYWNrZXQocGFja2V0KTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnNlbmRCdWZmZXIucHVzaChwYWNrZXQpO1xuICB9XG5cbiAgZGVsZXRlIHRoaXMuZmxhZ3M7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIGEgcGFja2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUucGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICBwYWNrZXQubnNwID0gdGhpcy5uc3A7XG4gIHRoaXMuaW8ucGFja2V0KHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGVuZ2luZSBgb3BlbmAuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCd0cmFuc3BvcnQgaXMgb3BlbiAtIGNvbm5lY3RpbmcnKTtcblxuICAvLyB3cml0ZSBjb25uZWN0IHBhY2tldCBpZiBuZWNlc3NhcnlcbiAgaWYgKCcvJyAhPT0gdGhpcy5uc3ApIHtcbiAgICBpZiAodGhpcy5xdWVyeSkge1xuICAgICAgdGhpcy5wYWNrZXQoe3R5cGU6IHBhcnNlci5DT05ORUNULCBxdWVyeTogdGhpcy5xdWVyeX0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBhY2tldCh7dHlwZTogcGFyc2VyLkNPTk5FQ1R9KTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZW5naW5lIGBjbG9zZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJlYXNvblxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICBkZWJ1ZygnY2xvc2UgKCVzKScsIHJlYXNvbik7XG4gIHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG4gIHRoaXMuZGlzY29ubmVjdGVkID0gdHJ1ZTtcbiAgZGVsZXRlIHRoaXMuaWQ7XG4gIHRoaXMuZW1pdCgnZGlzY29ubmVjdCcsIHJlYXNvbik7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIHNvY2tldCBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbnBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgaWYgKHBhY2tldC5uc3AgIT09IHRoaXMubnNwKSByZXR1cm47XG5cbiAgc3dpdGNoIChwYWNrZXQudHlwZSkge1xuICAgIGNhc2UgcGFyc2VyLkNPTk5FQ1Q6XG4gICAgICB0aGlzLm9uY29ubmVjdCgpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5FVkVOVDpcbiAgICAgIHRoaXMub25ldmVudChwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfRVZFTlQ6XG4gICAgICB0aGlzLm9uZXZlbnQocGFja2V0KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5ESVNDT05ORUNUOlxuICAgICAgdGhpcy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuRVJST1I6XG4gICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgcGFja2V0LmRhdGEpO1xuICAgICAgYnJlYWs7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gYSBzZXJ2ZXIgZXZlbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmV2ZW50ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICB2YXIgYXJncyA9IHBhY2tldC5kYXRhIHx8IFtdO1xuICBkZWJ1ZygnZW1pdHRpbmcgZXZlbnQgJWonLCBhcmdzKTtcblxuICBpZiAobnVsbCAhPSBwYWNrZXQuaWQpIHtcbiAgICBkZWJ1ZygnYXR0YWNoaW5nIGFjayBjYWxsYmFjayB0byBldmVudCcpO1xuICAgIGFyZ3MucHVzaCh0aGlzLmFjayhwYWNrZXQuaWQpKTtcbiAgfVxuXG4gIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgIGVtaXQuYXBwbHkodGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yZWNlaXZlQnVmZmVyLnB1c2goYXJncyk7XG4gIH1cbn07XG5cbi8qKlxuICogUHJvZHVjZXMgYW4gYWNrIGNhbGxiYWNrIHRvIGVtaXQgd2l0aCBhbiBldmVudC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmFjayA9IGZ1bmN0aW9uIChpZCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBzZW50ID0gZmFsc2U7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gcHJldmVudCBkb3VibGUgY2FsbGJhY2tzXG4gICAgaWYgKHNlbnQpIHJldHVybjtcbiAgICBzZW50ID0gdHJ1ZTtcbiAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICBkZWJ1Zygnc2VuZGluZyBhY2sgJWonLCBhcmdzKTtcblxuICAgIHZhciB0eXBlID0gaGFzQmluKGFyZ3MpID8gcGFyc2VyLkJJTkFSWV9BQ0sgOiBwYXJzZXIuQUNLO1xuICAgIHNlbGYucGFja2V0KHtcbiAgICAgIHR5cGU6IHR5cGUsXG4gICAgICBpZDogaWQsXG4gICAgICBkYXRhOiBhcmdzXG4gICAgfSk7XG4gIH07XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgc2VydmVyIGFja25vd2xlZ2VtZW50LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25hY2sgPSBmdW5jdGlvbiAocGFja2V0KSB7XG4gIHZhciBhY2sgPSB0aGlzLmFja3NbcGFja2V0LmlkXTtcbiAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBhY2spIHtcbiAgICBkZWJ1ZygnY2FsbGluZyBhY2sgJXMgd2l0aCAlaicsIHBhY2tldC5pZCwgcGFja2V0LmRhdGEpO1xuICAgIGFjay5hcHBseSh0aGlzLCBwYWNrZXQuZGF0YSk7XG4gICAgZGVsZXRlIHRoaXMuYWNrc1twYWNrZXQuaWRdO1xuICB9IGVsc2Uge1xuICAgIGRlYnVnKCdiYWQgYWNrICVzJywgcGFja2V0LmlkKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzZXJ2ZXIgY29ubmVjdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuICB0aGlzLmRpc2Nvbm5lY3RlZCA9IGZhbHNlO1xuICB0aGlzLmVtaXQoJ2Nvbm5lY3QnKTtcbiAgdGhpcy5lbWl0QnVmZmVyZWQoKTtcbn07XG5cbi8qKlxuICogRW1pdCBidWZmZXJlZCBldmVudHMgKHJlY2VpdmVkIGFuZCBlbWl0dGVkKS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmVtaXRCdWZmZXJlZCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnJlY2VpdmVCdWZmZXIubGVuZ3RoOyBpKyspIHtcbiAgICBlbWl0LmFwcGx5KHRoaXMsIHRoaXMucmVjZWl2ZUJ1ZmZlcltpXSk7XG4gIH1cbiAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMuc2VuZEJ1ZmZlci5sZW5ndGg7IGkrKykge1xuICAgIHRoaXMucGFja2V0KHRoaXMuc2VuZEJ1ZmZlcltpXSk7XG4gIH1cbiAgdGhpcy5zZW5kQnVmZmVyID0gW107XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHNlcnZlciBkaXNjb25uZWN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25kaXNjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1Zygnc2VydmVyIGRpc2Nvbm5lY3QgKCVzKScsIHRoaXMubnNwKTtcbiAgdGhpcy5kZXN0cm95KCk7XG4gIHRoaXMub25jbG9zZSgnaW8gc2VydmVyIGRpc2Nvbm5lY3QnKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZm9yY2VkIGNsaWVudC9zZXJ2ZXIgc2lkZSBkaXNjb25uZWN0aW9ucyxcbiAqIHRoaXMgbWV0aG9kIGVuc3VyZXMgdGhlIG1hbmFnZXIgc3RvcHMgdHJhY2tpbmcgdXMgYW5kXG4gKiB0aGF0IHJlY29ubmVjdGlvbnMgZG9uJ3QgZ2V0IHRyaWdnZXJlZCBmb3IgdGhpcy5cbiAqXG4gKiBAYXBpIHByaXZhdGUuXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zdWJzKSB7XG4gICAgLy8gY2xlYW4gc3Vic2NyaXB0aW9ucyB0byBhdm9pZCByZWNvbm5lY3Rpb25zXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuc3Vic1tpXS5kZXN0cm95KCk7XG4gICAgfVxuICAgIHRoaXMuc3VicyA9IG51bGw7XG4gIH1cblxuICB0aGlzLmlvLmRlc3Ryb3kodGhpcyk7XG59O1xuXG4vKipcbiAqIERpc2Nvbm5lY3RzIHRoZSBzb2NrZXQgbWFudWFsbHkuXG4gKlxuICogQHJldHVybiB7U29ja2V0fSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPVxuU29ja2V0LnByb3RvdHlwZS5kaXNjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jb25uZWN0ZWQpIHtcbiAgICBkZWJ1ZygncGVyZm9ybWluZyBkaXNjb25uZWN0ICglcyknLCB0aGlzLm5zcCk7XG4gICAgdGhpcy5wYWNrZXQoeyB0eXBlOiBwYXJzZXIuRElTQ09OTkVDVCB9KTtcbiAgfVxuXG4gIC8vIHJlbW92ZSBzb2NrZXQgZnJvbSBwb29sXG4gIHRoaXMuZGVzdHJveSgpO1xuXG4gIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgIC8vIGZpcmUgZXZlbnRzXG4gICAgdGhpcy5vbmNsb3NlKCdpbyBjbGllbnQgZGlzY29ubmVjdCcpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBjb21wcmVzcyBmbGFnLlxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaWYgYHRydWVgLCBjb21wcmVzc2VzIHRoZSBzZW5kaW5nIGRhdGFcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNvbXByZXNzID0gZnVuY3Rpb24gKGNvbXByZXNzKSB7XG4gIHRoaXMuZmxhZ3MgPSB0aGlzLmZsYWdzIHx8IHt9O1xuICB0aGlzLmZsYWdzLmNvbXByZXNzID0gY29tcHJlc3M7XG4gIHJldHVybiB0aGlzO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4c13\n")},"4d50":function(module,exports,__webpack_require__){eval("/**\n * Facets are the main abstraction over the data.\n *\n * A `Dataset` is a collection of (similar) items, with each item having a certain set of properties, ie. `Facet`s.\n * The `Facet` class defines the property: It can be a continuous value, a set of labels or tags,\n * or it can be result of some transformation or equation.\n *\n * @class Facet\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar CategorialTransform = __webpack_require__(/*! ./facet/categorial-transform */ \"9b75\");\nvar ContinuousTransform = __webpack_require__(/*! ./facet/continuous-transform */ \"5a80\");\nvar datetimeTransform = __webpack_require__(/*! ./facet/datetime-transform */ \"a0ca\");\nvar durationTransform = __webpack_require__(/*! ./facet/duration-transform */ \"b123\");\nvar textTransform = __webpack_require__(/*! ./facet/text-transform */ \"e810\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    this.on('change:type', function (facet, newval) {\n      // reset transformations on type change\n      this.continuousTransform.reset();\n      this.categorialTransform.reset();\n      this.datetimeTransform.reset();\n      this.durationTransform.reset();\n    });\n  },\n  props: {\n    /**\n     * Show in facet lists (used for interactive searching on Facets page)\n     * @memberof! Facet\n     * @type {boolean}\n     */\n    show: ['boolean', false, true],\n\n    /**\n     * Show facet bar (on Analyze page)\n     * @memberof! Facet\n     * @type {boolean}\n     */\n    isActive: ['boolean', false, false],\n\n    // general facet properties\n    /**\n     * Description of this facet, for displaying purposes\n     * @memberof! Facet\n     * @type {string}\n     */\n    description: ['string', true, ''],\n\n    /**\n     * For continuous facets, its units for displaying purposes\n     * @memberof! Facet\n     * @type {string}\n     */\n    units: ['string', true, ''],\n\n    /**\n     * Short name (human readable) for this facet, must be unique.\n     * @memberof! Facet\n     * @type {string}\n     */\n    name: ['string', true, ''],\n\n    /**\n     * Type of this facet:\n     *  * `constant`        A constant value of \"1\" for all data items\n     *  * `continuous`      The facet takes on real numbers\n     *  * `categorial`      The facet is a string, or an array of strings (for a well defined set of labels and tags)\n     *  * `datetime`        The facet is a datetime (using momentjs.tz)\n     *  * `duration`        The facet is a duration (using momentjs.duration)\n     *  * `text`            Freeform text.\n     * Check for facet type using isConstant, isContinuous, isCategorial, isDatetime, isDuration, or isText  properties.\n     * @memberof! Facet\n     * @type {string}\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['constant', 'continuous', 'categorial', 'datetime', 'duration', 'text']\n    },\n\n    /**\n     * The accessor for this facet.\n     * For nested properties use dot notation: For a dataset `[ {name: {first: \"Santa\", last: \"Claus\"}}, ...]`\n     * you can use `name.first` and `name.last` to get Santa and Claus, respectively.\n     *\n     * @memberof! Facet\n     * @type {string}\n     */\n    accessor: ['string', false, null],\n\n    /**\n     * Missing or invalid data indicator; for multiple values, use a comma separated, quoted list\n     * Numbers, strings, booleans, and the special value null are allowed.\n     * Use single or double quotes for strings \"missing\".\n     * The parsed values are available in the misval property.\n     *\n     * @memberof! Facet\n     * @type {string}\n     */\n    misvalAsText: 'string',\n\n    /**\n     * For continuous or datetime Facets, the minimum value as text.\n     * Parsed value available in the `minval` property\n     * @memberof! Facet\n     * @type {string}\n     */\n    minvalAsText: 'string',\n\n    /**\n     * For continuous or datetime Facets, the maximum value as text.\n     * Parsed value available in the `maxval` property\n     * @memberof! Facet\n     * @type {string}\n     */\n    maxvalAsText: 'string'\n  },\n  children: {\n    /**\n     * A categorial transformation to apply to the data\n     * @memberof! Facet\n     * @type {CategorialTransform}\n     */\n    categorialTransform: CategorialTransform,\n    /**\n     * A datetime transformation to apply to the data\n     * @memberof! Facet\n     * @type {dateimeTransform}\n     */\n    datetimeTransform: datetimeTransform,\n    /**\n     * A duration transformation to apply to the data\n     * @memberof! Facet\n     * @type {dateimeTransform}\n     */\n    durationTransform: durationTransform,\n    /**\n     * A continuous transformation to apply to the data\n     * @memberof! Facet\n     * @type {ContinuousTransform}\n     */\n    continuousTransform: ContinuousTransform,\n    /**\n     * A text transform\n     * @memberof! Facet\n     * @type {TextTransform}\n     */\n    textTransform: textTransform\n  },\n\n  derived: {\n    // properties for: type\n    isConstant: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'constant';\n      }\n    },\n    isContinuous: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'continuous';\n      }\n    },\n    isCategorial: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'categorial';\n      }\n    },\n    isDatetime: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'datetime';\n      }\n    },\n    isDuration: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'duration';\n      }\n    },\n    isText: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'text';\n      }\n    },\n\n    /**\n     * Array of missing data indicators\n     * @memberof! Facet\n     * @type {Object[]}\n     * @readonly\n     */\n    misval: {\n      deps: ['misvalAsText'],\n      fn: function () {\n        // Parse the text content as a JSON array:\n        //  - strings should be quoted\n        //  - numbers unquoated\n        //  - special numbers not allowed: NaN, Infinity\n        try {\n          if (this.misvalAsText !== null) {\n            return JSON.parse('[' + this.misvalAsText + ']');\n          } else {\n            return [];\n          }\n        } catch (e) {\n          return [];\n        }\n      },\n      cache: false\n    },\n\n    /**\n     * For continuous or datetime Facets, the minimum value.\n     * @memberof! Facet\n     * @type {number|datetime}\n     * @readonly\n     */\n    minval: {\n      deps: ['minvalAsText', 'type'],\n      fn: function () {\n        var min;\n        if (this.isContinuous) {\n          min = parseFloat(this.minvalAsText);\n          if (isNaN(min)) {\n            min = 0;\n          }\n        } else if (this.isDatetime) {\n          min = moment(this.minvalAsText, moment.ISO_8601);\n          if (!min.isValid()) {\n            min = moment('2010-01-01 00:00', moment.ISO_8601);\n          }\n        } else if (this.isDuration) {\n          min = moment.duration(this.minvalAsText);\n          if (!moment.isDuration(min)) {\n            min = moment.duration(1, 'seconds');\n          }\n        }\n        return min;\n      },\n      cache: false\n    },\n    /**\n     * For continuous or datetime Facets, the maximum value.\n     * @memberof! Facet\n     * @type {number|datetime}\n     * @readonly\n     */\n    maxval: {\n      deps: ['maxvalAsText', 'type'],\n      fn: function () {\n        var max;\n        if (this.isContinuous) {\n          max = parseFloat(this.maxvalAsText);\n          if (isNaN(max)) {\n            max = 100;\n          }\n        } else if (this.isDatetime) {\n          max = moment(this.maxvalAsText, moment.ISO_8601);\n          if (!max.isValid()) {\n            max = moment('2020-01-01 00:00', moment.ISO_8601);\n          }\n        } else if (this.isDuration) {\n          max = moment.duration(this.maxvalAsText);\n          if (!moment.isDuration(max)) {\n            max = moment.duration(100, 'seconds');\n          }\n        }\n        return max;\n      },\n      cache: false\n    },\n    transform: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isContinuous) {\n          return this.continuousTransform;\n        } else if (this.isCategorial) {\n          return this.categorialTransform;\n        } else if (this.isDatetime) {\n          return this.datetimeTransform;\n        } else if (this.isDuration) {\n          return this.durationTransform;\n        } else if (this.isText) {\n          return this.textTransform;\n        }\n        console.error('Invalid facet');\n      },\n      cache: false\n    }\n  },\n  /**\n   * setMinMax sets the range of a continuous or time facet\n   * For facets in a dataview, the minimum is just the minimum of the facet over all active datasets,\n   * and the same for the maximum.\n   * For facets in a datset, the actual implementation is in the dataset driver.\n   *\n   * @memberof! Facet\n   */\n  setMinMax: function () {\n    var Dataset = __webpack_require__(/*! ./dataset */ \"545a\");\n    var Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\n\n    var ancestor = this.collection.parent;\n    var spot;\n\n    if (ancestor instanceof Dataview) {\n      // Facet -> Facets -> Dataview -> Spot\n      spot = this.collection.parent.parent;\n      spot.setFacetMinMax(this);\n    } else if (ancestor instanceof Dataset) {\n      // Dataset -> Datasets -> Spot\n      spot = ancestor.collection.parent;\n      spot.driver.setMinMax(ancestor, this);\n    }\n  },\n  /**\n   * setCategories finds finds all values on an ordinal (categorial) axis\n   * Updates the categorialTransform of the facet\n   * For facets in a dataview, this is the union of the categories of facet over all active datasets.\n   * For facets in a dataset, the actual implementation is in the dataset driver.\n   *\n   * @memberof! Facet\n   */\n  setCategories: function () {\n    var Dataset = __webpack_require__(/*! ./dataset */ \"545a\");\n    var Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\n\n    var ancestor = this.collection.parent;\n    var spot;\n\n    if (ancestor instanceof Dataview) {\n      // Facet -> Facets -> Dataview -> Spot\n      spot = this.collection.parent.parent;\n      spot.setFacetCategories(this);\n    } else if (ancestor instanceof Dataset) {\n      // Facet -> Facets -> Dataset -> Datasets -> Spot\n      spot = ancestor.collection.parent;\n      spot.driver.setCategories(ancestor, this);\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNGQ1MC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQuanM/ZDdlYiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEZhY2V0cyBhcmUgdGhlIG1haW4gYWJzdHJhY3Rpb24gb3ZlciB0aGUgZGF0YS5cbiAqXG4gKiBBIGBEYXRhc2V0YCBpcyBhIGNvbGxlY3Rpb24gb2YgKHNpbWlsYXIpIGl0ZW1zLCB3aXRoIGVhY2ggaXRlbSBoYXZpbmcgYSBjZXJ0YWluIHNldCBvZiBwcm9wZXJ0aWVzLCBpZS4gYEZhY2V0YHMuXG4gKiBUaGUgYEZhY2V0YCBjbGFzcyBkZWZpbmVzIHRoZSBwcm9wZXJ0eTogSXQgY2FuIGJlIGEgY29udGludW91cyB2YWx1ZSwgYSBzZXQgb2YgbGFiZWxzIG9yIHRhZ3MsXG4gKiBvciBpdCBjYW4gYmUgcmVzdWx0IG9mIHNvbWUgdHJhbnNmb3JtYXRpb24gb3IgZXF1YXRpb24uXG4gKlxuICogQGNsYXNzIEZhY2V0XG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBCYXNlTW9kZWwgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIENhdGVnb3JpYWxUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L2NhdGVnb3JpYWwtdHJhbnNmb3JtJyk7XG52YXIgQ29udGludW91c1RyYW5zZm9ybSA9IHJlcXVpcmUoJy4vZmFjZXQvY29udGludW91cy10cmFuc2Zvcm0nKTtcbnZhciBkYXRldGltZVRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vZmFjZXQvZGF0ZXRpbWUtdHJhbnNmb3JtJyk7XG52YXIgZHVyYXRpb25UcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L2R1cmF0aW9uLXRyYW5zZm9ybScpO1xudmFyIHRleHRUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L3RleHQtdHJhbnNmb3JtJyk7XG52YXIgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50LXRpbWV6b25lJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLm9uKCdjaGFuZ2U6dHlwZScsIGZ1bmN0aW9uIChmYWNldCwgbmV3dmFsKSB7XG4gICAgICAvLyByZXNldCB0cmFuc2Zvcm1hdGlvbnMgb24gdHlwZSBjaGFuZ2VcbiAgICAgIHRoaXMuY29udGludW91c1RyYW5zZm9ybS5yZXNldCgpO1xuICAgICAgdGhpcy5jYXRlZ29yaWFsVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgICB0aGlzLmRhdGV0aW1lVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgICB0aGlzLmR1cmF0aW9uVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgfSk7XG4gIH0sXG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogU2hvdyBpbiBmYWNldCBsaXN0cyAodXNlZCBmb3IgaW50ZXJhY3RpdmUgc2VhcmNoaW5nIG9uIEZhY2V0cyBwYWdlKVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBzaG93OiBbJ2Jvb2xlYW4nLCBmYWxzZSwgdHJ1ZV0sXG5cbiAgICAvKipcbiAgICAgKiBTaG93IGZhY2V0IGJhciAob24gQW5hbHl6ZSBwYWdlKVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0FjdGl2ZTogWydib29sZWFuJywgZmFsc2UsIGZhbHNlXSxcblxuICAgIC8vIGdlbmVyYWwgZmFjZXQgcHJvcGVydGllc1xuICAgIC8qKlxuICAgICAqIERlc2NyaXB0aW9uIG9mIHRoaXMgZmFjZXQsIGZvciBkaXNwbGF5aW5nIHB1cnBvc2VzXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgZGVzY3JpcHRpb246IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgZmFjZXRzLCBpdHMgdW5pdHMgZm9yIGRpc3BsYXlpbmcgcHVycG9zZXNcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB1bml0czogWydzdHJpbmcnLCB0cnVlLCAnJ10sXG5cbiAgICAvKipcbiAgICAgKiBTaG9ydCBuYW1lIChodW1hbiByZWFkYWJsZSkgZm9yIHRoaXMgZmFjZXQsIG11c3QgYmUgdW5pcXVlLlxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG5hbWU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiB0aGlzIGZhY2V0OlxuICAgICAqICAqIGBjb25zdGFudGAgICAgICAgIEEgY29uc3RhbnQgdmFsdWUgb2YgXCIxXCIgZm9yIGFsbCBkYXRhIGl0ZW1zXG4gICAgICogICogYGNvbnRpbnVvdXNgICAgICAgVGhlIGZhY2V0IHRha2VzIG9uIHJlYWwgbnVtYmVyc1xuICAgICAqICAqIGBjYXRlZ29yaWFsYCAgICAgIFRoZSBmYWNldCBpcyBhIHN0cmluZywgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncyAoZm9yIGEgd2VsbCBkZWZpbmVkIHNldCBvZiBsYWJlbHMgYW5kIHRhZ3MpXG4gICAgICogICogYGRhdGV0aW1lYCAgICAgICAgVGhlIGZhY2V0IGlzIGEgZGF0ZXRpbWUgKHVzaW5nIG1vbWVudGpzLnR6KVxuICAgICAqICAqIGBkdXJhdGlvbmAgICAgICAgIFRoZSBmYWNldCBpcyBhIGR1cmF0aW9uICh1c2luZyBtb21lbnRqcy5kdXJhdGlvbilcbiAgICAgKiAgKiBgdGV4dGAgICAgICAgICAgICBGcmVlZm9ybSB0ZXh0LlxuICAgICAqIENoZWNrIGZvciBmYWNldCB0eXBlIHVzaW5nIGlzQ29uc3RhbnQsIGlzQ29udGludW91cywgaXNDYXRlZ29yaWFsLCBpc0RhdGV0aW1lLCBpc0R1cmF0aW9uLCBvciBpc1RleHQgIHByb3BlcnRpZXMuXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHlwZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICdjYXRlZ29yaWFsJyxcbiAgICAgIHZhbHVlczogWydjb25zdGFudCcsICdjb250aW51b3VzJywgJ2NhdGVnb3JpYWwnLCAnZGF0ZXRpbWUnLCAnZHVyYXRpb24nLCAndGV4dCddXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBhY2Nlc3NvciBmb3IgdGhpcyBmYWNldC5cbiAgICAgKiBGb3IgbmVzdGVkIHByb3BlcnRpZXMgdXNlIGRvdCBub3RhdGlvbjogRm9yIGEgZGF0YXNldCBgWyB7bmFtZToge2ZpcnN0OiBcIlNhbnRhXCIsIGxhc3Q6IFwiQ2xhdXNcIn19LCAuLi5dYFxuICAgICAqIHlvdSBjYW4gdXNlIGBuYW1lLmZpcnN0YCBhbmQgYG5hbWUubGFzdGAgdG8gZ2V0IFNhbnRhIGFuZCBDbGF1cywgcmVzcGVjdGl2ZWx5LlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgYWNjZXNzb3I6IFsnc3RyaW5nJywgZmFsc2UsIG51bGxdLFxuXG4gICAgLyoqXG4gICAgICogTWlzc2luZyBvciBpbnZhbGlkIGRhdGEgaW5kaWNhdG9yOyBmb3IgbXVsdGlwbGUgdmFsdWVzLCB1c2UgYSBjb21tYSBzZXBhcmF0ZWQsIHF1b3RlZCBsaXN0XG4gICAgICogTnVtYmVycywgc3RyaW5ncywgYm9vbGVhbnMsIGFuZCB0aGUgc3BlY2lhbCB2YWx1ZSBudWxsIGFyZSBhbGxvd2VkLlxuICAgICAqIFVzZSBzaW5nbGUgb3IgZG91YmxlIHF1b3RlcyBmb3Igc3RyaW5ncyBcIm1pc3NpbmdcIi5cbiAgICAgKiBUaGUgcGFyc2VkIHZhbHVlcyBhcmUgYXZhaWxhYmxlIGluIHRoZSBtaXN2YWwgcHJvcGVydHkuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBtaXN2YWxBc1RleHQ6ICdzdHJpbmcnLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgb3IgZGF0ZXRpbWUgRmFjZXRzLCB0aGUgbWluaW11bSB2YWx1ZSBhcyB0ZXh0LlxuICAgICAqIFBhcnNlZCB2YWx1ZSBhdmFpbGFibGUgaW4gdGhlIGBtaW52YWxgIHByb3BlcnR5XG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgbWludmFsQXNUZXh0OiAnc3RyaW5nJyxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1heGltdW0gdmFsdWUgYXMgdGV4dC5cbiAgICAgKiBQYXJzZWQgdmFsdWUgYXZhaWxhYmxlIGluIHRoZSBgbWF4dmFsYCBwcm9wZXJ0eVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG1heHZhbEFzVGV4dDogJ3N0cmluZydcbiAgfSxcbiAgY2hpbGRyZW46IHtcbiAgICAvKipcbiAgICAgKiBBIGNhdGVnb3JpYWwgdHJhbnNmb3JtYXRpb24gdG8gYXBwbHkgdG8gdGhlIGRhdGFcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge0NhdGVnb3JpYWxUcmFuc2Zvcm19XG4gICAgICovXG4gICAgY2F0ZWdvcmlhbFRyYW5zZm9ybTogQ2F0ZWdvcmlhbFRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGRhdGV0aW1lIHRyYW5zZm9ybWF0aW9uIHRvIGFwcGx5IHRvIHRoZSBkYXRhXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtkYXRlaW1lVHJhbnNmb3JtfVxuICAgICAqL1xuICAgIGRhdGV0aW1lVHJhbnNmb3JtOiBkYXRldGltZVRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGR1cmF0aW9uIHRyYW5zZm9ybWF0aW9uIHRvIGFwcGx5IHRvIHRoZSBkYXRhXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtkYXRlaW1lVHJhbnNmb3JtfVxuICAgICAqL1xuICAgIGR1cmF0aW9uVHJhbnNmb3JtOiBkdXJhdGlvblRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGNvbnRpbnVvdXMgdHJhbnNmb3JtYXRpb24gdG8gYXBwbHkgdG8gdGhlIGRhdGFcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge0NvbnRpbnVvdXNUcmFuc2Zvcm19XG4gICAgICovXG4gICAgY29udGludW91c1RyYW5zZm9ybTogQ29udGludW91c1RyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIHRleHQgdHJhbnNmb3JtXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtUZXh0VHJhbnNmb3JtfVxuICAgICAqL1xuICAgIHRleHRUcmFuc2Zvcm06IHRleHRUcmFuc2Zvcm1cbiAgfSxcblxuICBkZXJpdmVkOiB7XG4gICAgLy8gcHJvcGVydGllcyBmb3I6IHR5cGVcbiAgICBpc0NvbnN0YW50OiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjb25zdGFudCc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0NvbnRpbnVvdXM6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2NvbnRpbnVvdXMnO1xuICAgICAgfVxuICAgIH0sXG4gICAgaXNDYXRlZ29yaWFsOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjYXRlZ29yaWFsJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzRGF0ZXRpbWU6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2RhdGV0aW1lJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzRHVyYXRpb246IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2R1cmF0aW9uJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzVGV4dDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAndGV4dCc7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEFycmF5IG9mIG1pc3NpbmcgZGF0YSBpbmRpY2F0b3JzXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtPYmplY3RbXX1cbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKi9cbiAgICBtaXN2YWw6IHtcbiAgICAgIGRlcHM6IFsnbWlzdmFsQXNUZXh0J10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBQYXJzZSB0aGUgdGV4dCBjb250ZW50IGFzIGEgSlNPTiBhcnJheTpcbiAgICAgICAgLy8gIC0gc3RyaW5ncyBzaG91bGQgYmUgcXVvdGVkXG4gICAgICAgIC8vICAtIG51bWJlcnMgdW5xdW9hdGVkXG4gICAgICAgIC8vICAtIHNwZWNpYWwgbnVtYmVycyBub3QgYWxsb3dlZDogTmFOLCBJbmZpbml0eVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICh0aGlzLm1pc3ZhbEFzVGV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoJ1snICsgdGhpcy5taXN2YWxBc1RleHQgKyAnXScpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1pbmltdW0gdmFsdWUuXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtudW1iZXJ8ZGF0ZXRpbWV9XG4gICAgICogQHJlYWRvbmx5XG4gICAgICovXG4gICAgbWludmFsOiB7XG4gICAgICBkZXBzOiBbJ21pbnZhbEFzVGV4dCcsICd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWluO1xuICAgICAgICBpZiAodGhpcy5pc0NvbnRpbnVvdXMpIHtcbiAgICAgICAgICBtaW4gPSBwYXJzZUZsb2F0KHRoaXMubWludmFsQXNUZXh0KTtcbiAgICAgICAgICBpZiAoaXNOYU4obWluKSkge1xuICAgICAgICAgICAgbWluID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0RhdGV0aW1lKSB7XG4gICAgICAgICAgbWluID0gbW9tZW50KHRoaXMubWludmFsQXNUZXh0LCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICAgIGlmICghbWluLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgbWluID0gbW9tZW50KCcyMDEwLTAxLTAxIDAwOjAwJywgbW9tZW50LklTT184NjAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0R1cmF0aW9uKSB7XG4gICAgICAgICAgbWluID0gbW9tZW50LmR1cmF0aW9uKHRoaXMubWludmFsQXNUZXh0KTtcbiAgICAgICAgICBpZiAoIW1vbWVudC5pc0R1cmF0aW9uKG1pbikpIHtcbiAgICAgICAgICAgIG1pbiA9IG1vbWVudC5kdXJhdGlvbigxLCAnc2Vjb25kcycpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWluO1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgb3IgZGF0ZXRpbWUgRmFjZXRzLCB0aGUgbWF4aW11bSB2YWx1ZS5cbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge251bWJlcnxkYXRldGltZX1cbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKi9cbiAgICBtYXh2YWw6IHtcbiAgICAgIGRlcHM6IFsnbWF4dmFsQXNUZXh0JywgJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXg7XG4gICAgICAgIGlmICh0aGlzLmlzQ29udGludW91cykge1xuICAgICAgICAgIG1heCA9IHBhcnNlRmxvYXQodGhpcy5tYXh2YWxBc1RleHQpO1xuICAgICAgICAgIGlmIChpc05hTihtYXgpKSB7XG4gICAgICAgICAgICBtYXggPSAxMDA7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEYXRldGltZSkge1xuICAgICAgICAgIG1heCA9IG1vbWVudCh0aGlzLm1heHZhbEFzVGV4dCwgbW9tZW50LklTT184NjAxKTtcbiAgICAgICAgICBpZiAoIW1heC5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIG1heCA9IG1vbWVudCgnMjAyMC0wMS0wMSAwMDowMCcsIG1vbWVudC5JU09fODYwMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEdXJhdGlvbikge1xuICAgICAgICAgIG1heCA9IG1vbWVudC5kdXJhdGlvbih0aGlzLm1heHZhbEFzVGV4dCk7XG4gICAgICAgICAgaWYgKCFtb21lbnQuaXNEdXJhdGlvbihtYXgpKSB7XG4gICAgICAgICAgICBtYXggPSBtb21lbnQuZHVyYXRpb24oMTAwLCAnc2Vjb25kcycpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWF4O1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgdHJhbnNmb3JtOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzQ29udGludW91cykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRpbnVvdXNUcmFuc2Zvcm07XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0NhdGVnb3JpYWwpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jYXRlZ29yaWFsVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEYXRldGltZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmRhdGV0aW1lVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEdXJhdGlvbikge1xuICAgICAgICAgIHJldHVybiB0aGlzLmR1cmF0aW9uVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNUZXh0KSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudGV4dFRyYW5zZm9ybTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmVycm9yKCdJbnZhbGlkIGZhY2V0Jyk7XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfVxuICB9LFxuICAvKipcbiAgICogc2V0TWluTWF4IHNldHMgdGhlIHJhbmdlIG9mIGEgY29udGludW91cyBvciB0aW1lIGZhY2V0XG4gICAqIEZvciBmYWNldHMgaW4gYSBkYXRhdmlldywgdGhlIG1pbmltdW0gaXMganVzdCB0aGUgbWluaW11bSBvZiB0aGUgZmFjZXQgb3ZlciBhbGwgYWN0aXZlIGRhdGFzZXRzLFxuICAgKiBhbmQgdGhlIHNhbWUgZm9yIHRoZSBtYXhpbXVtLlxuICAgKiBGb3IgZmFjZXRzIGluIGEgZGF0c2V0LCB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIGlzIGluIHRoZSBkYXRhc2V0IGRyaXZlci5cbiAgICpcbiAgICogQG1lbWJlcm9mISBGYWNldFxuICAgKi9cbiAgc2V0TWluTWF4OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIERhdGFzZXQgPSByZXF1aXJlKCcuL2RhdGFzZXQnKTtcbiAgICB2YXIgRGF0YXZpZXcgPSByZXF1aXJlKCcuL2RhdGF2aWV3Jyk7XG5cbiAgICB2YXIgYW5jZXN0b3IgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90O1xuXG4gICAgaWYgKGFuY2VzdG9yIGluc3RhbmNlb2YgRGF0YXZpZXcpIHtcbiAgICAgIC8vIEZhY2V0IC0+IEZhY2V0cyAtPiBEYXRhdmlldyAtPiBTcG90XG4gICAgICBzcG90ID0gdGhpcy5jb2xsZWN0aW9uLnBhcmVudC5wYXJlbnQ7XG4gICAgICBzcG90LnNldEZhY2V0TWluTWF4KHRoaXMpO1xuICAgIH0gZWxzZSBpZiAoYW5jZXN0b3IgaW5zdGFuY2VvZiBEYXRhc2V0KSB7XG4gICAgICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgICAgIHNwb3QgPSBhbmNlc3Rvci5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICAgIHNwb3QuZHJpdmVyLnNldE1pbk1heChhbmNlc3RvciwgdGhpcyk7XG4gICAgfVxuICB9LFxuICAvKipcbiAgICogc2V0Q2F0ZWdvcmllcyBmaW5kcyBmaW5kcyBhbGwgdmFsdWVzIG9uIGFuIG9yZGluYWwgKGNhdGVnb3JpYWwpIGF4aXNcbiAgICogVXBkYXRlcyB0aGUgY2F0ZWdvcmlhbFRyYW5zZm9ybSBvZiB0aGUgZmFjZXRcbiAgICogRm9yIGZhY2V0cyBpbiBhIGRhdGF2aWV3LCB0aGlzIGlzIHRoZSB1bmlvbiBvZiB0aGUgY2F0ZWdvcmllcyBvZiBmYWNldCBvdmVyIGFsbCBhY3RpdmUgZGF0YXNldHMuXG4gICAqIEZvciBmYWNldHMgaW4gYSBkYXRhc2V0LCB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIGlzIGluIHRoZSBkYXRhc2V0IGRyaXZlci5cbiAgICpcbiAgICogQG1lbWJlcm9mISBGYWNldFxuICAgKi9cbiAgc2V0Q2F0ZWdvcmllczogZnVuY3Rpb24gKCkge1xuICAgIHZhciBEYXRhc2V0ID0gcmVxdWlyZSgnLi9kYXRhc2V0Jyk7XG4gICAgdmFyIERhdGF2aWV3ID0gcmVxdWlyZSgnLi9kYXRhdmlldycpO1xuXG4gICAgdmFyIGFuY2VzdG9yID0gdGhpcy5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICB2YXIgc3BvdDtcblxuICAgIGlmIChhbmNlc3RvciBpbnN0YW5jZW9mIERhdGF2aWV3KSB7XG4gICAgICAvLyBGYWNldCAtPiBGYWNldHMgLT4gRGF0YXZpZXcgLT4gU3BvdFxuICAgICAgc3BvdCA9IHRoaXMuY29sbGVjdGlvbi5wYXJlbnQucGFyZW50O1xuICAgICAgc3BvdC5zZXRGYWNldENhdGVnb3JpZXModGhpcyk7XG4gICAgfSBlbHNlIGlmIChhbmNlc3RvciBpbnN0YW5jZW9mIERhdGFzZXQpIHtcbiAgICAgIC8vIEZhY2V0IC0+IEZhY2V0cyAtPiBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgICAgIHNwb3QgPSBhbmNlc3Rvci5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICAgIHNwb3QuZHJpdmVyLnNldENhdGVnb3JpZXMoYW5jZXN0b3IsIHRoaXMpO1xuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4d50\n")},5066:function(module,exports,__webpack_require__){eval("/**\n * A Dataview is a join of Datasets\n *\n * @class Dataview\n * @extends Base\n */\nvar Crossfilter = __webpack_require__(/*! crossfilter2 */ \"0352\"); // TODO: only for client side datasets\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Filters = __webpack_require__(/*! ./filter/collection */ \"7fa4\");\nvar Facets = __webpack_require__(/*! ./facet/collection */ \"51fb\");\n\nfunction getData () {\n  if (this.isPaused) {\n    return;\n  }\n  console.time('Get data');\n\n  var spot = this.parent;\n\n  return spot.driver.getData(this);\n}\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    /**\n     * Crossfilter instance, see [here](http://square.github.io/crossfilter/)\n     * used for client side data handling.\n     *\n     * @memberof! Dataset\n     */\n    this.crossfilter = new Crossfilter([]);\n    this.countGroup = this.crossfilter.groupAll().reduceCount();\n  },\n  props: {\n    /**\n     * Total number of datapoints in the current dataview\n     *\n     * @memberof! Dataview\n     * @readonly\n     * @type {number}\n     */\n    dataTotal: ['number', true, 0],\n    /**\n     * Number of datapoints that are currently selected\n     *\n     * @memberof! Dataview\n     * @readonly\n     * @type {number}\n     */\n    dataSelected: ['number', true, 0],\n    /**\n     * DatasetId's of active datasets\n     *\n     * @memberof! Dataview\n     * @type {String[]}\n     */\n    datasetIds: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    }\n  },\n  session: {\n    /**\n     * isPaused when true, calls to getAllData are ignored.\n     * This is useful to suppres calls to getData\n     * when adding and removing a number of filters at once.\n     * @memberof! Dataview\n     * @type {boolean}\n     */\n    isPaused: ['boolean', true, false]\n  },\n  collections: {\n    /**\n     * A Facet collection holding pre defined facets\n     *\n     * @memberof! Dataview\n     * @type {Facet[]}\n     */\n    facets: Facets,\n    /**\n     * A Filter collection holding all active filters on the dataview\n     *\n     * @memberof! Dataview\n     * @type {Filter[]}\n     */\n    filters: Filters\n  },\n  /**\n   * Pause the dataview. This means calls to getData are blocked.\n   * Useful when updating a lot of filters and you are not interested in the intermediate state.\n   *\n   * @memberof! Dataview\n   */\n  pause: function () {\n    this.isPaused = true;\n  },\n  /**\n   * Unpause the dataview.\n   *\n   * @memberof! Dataview\n   */\n  play: function () {\n    this.isPaused = false;\n  },\n\n  /**\n   * Get data for all filters linked to this dataview.\n   * When data has become available for a filter, a `newData` event is triggered on that filter.\n   *\n   * @memberof! Dataview\n   * @function\n   */\n  getData: getData\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTA2Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXZpZXcuanM/NGQ0YSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEEgRGF0YXZpZXcgaXMgYSBqb2luIG9mIERhdGFzZXRzXG4gKlxuICogQGNsYXNzIERhdGF2aWV3XG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBDcm9zc2ZpbHRlciA9IHJlcXVpcmUoJ2Nyb3NzZmlsdGVyMicpOyAvLyBUT0RPOiBvbmx5IGZvciBjbGllbnQgc2lkZSBkYXRhc2V0c1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG52YXIgRmlsdGVycyA9IHJlcXVpcmUoJy4vZmlsdGVyL2NvbGxlY3Rpb24nKTtcbnZhciBGYWNldHMgPSByZXF1aXJlKCcuL2ZhY2V0L2NvbGxlY3Rpb24nKTtcblxuZnVuY3Rpb24gZ2V0RGF0YSAoKSB7XG4gIGlmICh0aGlzLmlzUGF1c2VkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnNvbGUudGltZSgnR2V0IGRhdGEnKTtcblxuICB2YXIgc3BvdCA9IHRoaXMucGFyZW50O1xuXG4gIHJldHVybiBzcG90LmRyaXZlci5nZXREYXRhKHRoaXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VNb2RlbC5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gZmlyc3QgZG8gcGFyZW50IGNsYXNzIGluaXRpYWxpemF0aW9uXG4gICAgQmFzZU1vZGVsLnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICAvKipcbiAgICAgKiBDcm9zc2ZpbHRlciBpbnN0YW5jZSwgc2VlIFtoZXJlXShodHRwOi8vc3F1YXJlLmdpdGh1Yi5pby9jcm9zc2ZpbHRlci8pXG4gICAgICogdXNlZCBmb3IgY2xpZW50IHNpZGUgZGF0YSBoYW5kbGluZy5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqL1xuICAgIHRoaXMuY3Jvc3NmaWx0ZXIgPSBuZXcgQ3Jvc3NmaWx0ZXIoW10pO1xuICAgIHRoaXMuY291bnRHcm91cCA9IHRoaXMuY3Jvc3NmaWx0ZXIuZ3JvdXBBbGwoKS5yZWR1Y2VDb3VudCgpO1xuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRvdGFsIG51bWJlciBvZiBkYXRhcG9pbnRzIGluIHRoZSBjdXJyZW50IGRhdGF2aWV3XG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHJlYWRvbmx5XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBkYXRhVG90YWw6IFsnbnVtYmVyJywgdHJ1ZSwgMF0sXG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIGRhdGFwb2ludHMgdGhhdCBhcmUgY3VycmVudGx5IHNlbGVjdGVkXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHJlYWRvbmx5XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBkYXRhU2VsZWN0ZWQ6IFsnbnVtYmVyJywgdHJ1ZSwgMF0sXG4gICAgLyoqXG4gICAgICogRGF0YXNldElkJ3Mgb2YgYWN0aXZlIGRhdGFzZXRzXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge1N0cmluZ1tdfVxuICAgICAqL1xuICAgIGRhdGFzZXRJZHM6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBkZWZhdWx0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHNlc3Npb246IHtcbiAgICAvKipcbiAgICAgKiBpc1BhdXNlZCB3aGVuIHRydWUsIGNhbGxzIHRvIGdldEFsbERhdGEgYXJlIGlnbm9yZWQuXG4gICAgICogVGhpcyBpcyB1c2VmdWwgdG8gc3VwcHJlcyBjYWxscyB0byBnZXREYXRhXG4gICAgICogd2hlbiBhZGRpbmcgYW5kIHJlbW92aW5nIGEgbnVtYmVyIG9mIGZpbHRlcnMgYXQgb25jZS5cbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNQYXVzZWQ6IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXVxuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEEgRmFjZXQgY29sbGVjdGlvbiBob2xkaW5nIHByZSBkZWZpbmVkIGZhY2V0c1xuICAgICAqXG4gICAgICogQG1lbWJlcm9mISBEYXRhdmlld1xuICAgICAqIEB0eXBlIHtGYWNldFtdfVxuICAgICAqL1xuICAgIGZhY2V0czogRmFjZXRzLFxuICAgIC8qKlxuICAgICAqIEEgRmlsdGVyIGNvbGxlY3Rpb24gaG9sZGluZyBhbGwgYWN0aXZlIGZpbHRlcnMgb24gdGhlIGRhdGF2aWV3XG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge0ZpbHRlcltdfVxuICAgICAqL1xuICAgIGZpbHRlcnM6IEZpbHRlcnNcbiAgfSxcbiAgLyoqXG4gICAqIFBhdXNlIHRoZSBkYXRhdmlldy4gVGhpcyBtZWFucyBjYWxscyB0byBnZXREYXRhIGFyZSBibG9ja2VkLlxuICAgKiBVc2VmdWwgd2hlbiB1cGRhdGluZyBhIGxvdCBvZiBmaWx0ZXJzIGFuZCB5b3UgYXJlIG5vdCBpbnRlcmVzdGVkIGluIHRoZSBpbnRlcm1lZGlhdGUgc3RhdGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiEgRGF0YXZpZXdcbiAgICovXG4gIHBhdXNlOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5pc1BhdXNlZCA9IHRydWU7XG4gIH0sXG4gIC8qKlxuICAgKiBVbnBhdXNlIHRoZSBkYXRhdmlldy5cbiAgICpcbiAgICogQG1lbWJlcm9mISBEYXRhdmlld1xuICAgKi9cbiAgcGxheTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuaXNQYXVzZWQgPSBmYWxzZTtcbiAgfSxcblxuICAvKipcbiAgICogR2V0IGRhdGEgZm9yIGFsbCBmaWx0ZXJzIGxpbmtlZCB0byB0aGlzIGRhdGF2aWV3LlxuICAgKiBXaGVuIGRhdGEgaGFzIGJlY29tZSBhdmFpbGFibGUgZm9yIGEgZmlsdGVyLCBhIGBuZXdEYXRhYCBldmVudCBpcyB0cmlnZ2VyZWQgb24gdGhhdCBmaWx0ZXIuXG4gICAqXG4gICAqIEBtZW1iZXJvZiEgRGF0YXZpZXdcbiAgICogQGZ1bmN0aW9uXG4gICAqL1xuICBnZXREYXRhOiBnZXREYXRhXG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5066\n")},"51fb":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Facet = __webpack_require__(/*! ../facet */ \"4d50\");\n\nmodule.exports = Collection.extend({\n  model: Facet,\n  mainIndex: 'id',\n  indexes: ['name'],\n  session: {\n    needle: ['string', true, ''], // search string used on the Facet page\n    showSearch: ['boolean', true, false] // show/hide the search bar on the Facet page\n  },\n  comparator: function (left, right) {\n    return left.name.localeCompare(right.name);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTFmYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29sbGVjdGlvbi5qcz84ZWU5Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBDb2xsZWN0aW9uID0gcmVxdWlyZSgnYW1wZXJzYW5kLWNvbGxlY3Rpb24nKTtcbnZhciBGYWNldCA9IHJlcXVpcmUoJy4uL2ZhY2V0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogRmFjZXQsXG4gIG1haW5JbmRleDogJ2lkJyxcbiAgaW5kZXhlczogWyduYW1lJ10sXG4gIHNlc3Npb246IHtcbiAgICBuZWVkbGU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLCAvLyBzZWFyY2ggc3RyaW5nIHVzZWQgb24gdGhlIEZhY2V0IHBhZ2VcbiAgICBzaG93U2VhcmNoOiBbJ2Jvb2xlYW4nLCB0cnVlLCBmYWxzZV0gLy8gc2hvdy9oaWRlIHRoZSBzZWFyY2ggYmFyIG9uIHRoZSBGYWNldCBwYWdlXG4gIH0sXG4gIGNvbXBhcmF0b3I6IGZ1bmN0aW9uIChsZWZ0LCByaWdodCkge1xuICAgIHJldHVybiBsZWZ0Lm5hbWUubG9jYWxlQ29tcGFyZShyaWdodC5uYW1lKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///51fb\n")},"544d":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Dataset = __webpack_require__(/*! ../dataset */ \"545a\");\n\nmodule.exports = Collection.extend({\n  mainIndex: 'id',\n  indexes: ['name'],\n  model: Dataset\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQ0ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXNldC9jb2xsZWN0aW9uLmpzPzkxZDkiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIENvbGxlY3Rpb24gPSByZXF1aXJlKCdhbXBlcnNhbmQtY29sbGVjdGlvbicpO1xudmFyIERhdGFzZXQgPSByZXF1aXJlKCcuLi9kYXRhc2V0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtYWluSW5kZXg6ICdpZCcsXG4gIGluZGV4ZXM6IFsnbmFtZSddLFxuICBtb2RlbDogRGF0YXNldFxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///544d\n")},"545a":function(module,exports,__webpack_require__){eval("/**\n * @class Dataset\n * @extends Base\n */\nvar Crossfilter = __webpack_require__(/*! crossfilter2 */ \"0352\"); // TODO: only for client side datasets\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Facets = __webpack_require__(/*! ./facet/collection */ \"51fb\");\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    /**\n     * Crossfilter instance, see [here](http://square.github.io/crossfilter/)\n     * used for client side data handling.\n     *\n     * @memberof! Dataset\n     */\n    this.crossfilter = new Crossfilter([]);\n    this.countGroup = this.crossfilter.groupAll().reduceCount();\n  },\n  props: {\n    /**\n     * Name of the dataset\n     * @memberof! Dataset\n     * @type {string}\n     */\n    name: {\n      type: 'string',\n      required: true,\n      default: 'Name'\n    },\n    /**\n     * URL, fi. to paper, dataset owner, etc.\n     * @memberof! Dataset\n     * @type {string}\n     */\n    URL: {\n      type: 'string',\n      required: true,\n      default: 'URL'\n    },\n    /**\n     * Database table name for server datasets\n     * @memberof! Dataset\n     * @type {string}\n     */\n    databaseTable: {\n      type: 'string',\n      default: ''\n    },\n    /**\n     * Short description of the dataset\n     * @memberof! Dataset\n     * @type {string}\n     */\n    description: {\n      type: 'string',\n      required: true,\n      default: 'Description'\n    },\n    /**\n     * If dataset is part of the current session\n     * @memberof! Dataset\n     * @type {boolean}\n     */\n    isActive: {\n      type: 'boolean',\n      required: true,\n      default: false\n    }\n  },\n  session: {\n    /**\n     * For searching through datasets URL and description.\n     * True if this dataset matches the search paramters.\n     */\n    show: {\n      type: 'boolean',\n      required: true,\n      default: true\n    },\n    data: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    }\n  },\n  collections: {\n    /**\n     * A Facet collection holding pre defined facets\n     * @memberof! Dataset\n     * @type {Facet[]}\n     */\n    facets: Facets\n  },\n  scan: function () {\n    // Dataset -> Datasets -> spot\n    var spot = this.collection.parent;\n\n    // clear all existing facets\n    this.facets.reset();\n\n    spot.driver.scan(this);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQ1YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXNldC5qcz9lYTcwIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGNsYXNzIERhdGFzZXRcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xudmFyIENyb3NzZmlsdGVyID0gcmVxdWlyZSgnY3Jvc3NmaWx0ZXIyJyk7IC8vIFRPRE86IG9ubHkgZm9yIGNsaWVudCBzaWRlIGRhdGFzZXRzXG52YXIgQmFzZU1vZGVsID0gcmVxdWlyZSgnLi91dGlsL2Jhc2UnKTtcbnZhciBGYWNldHMgPSByZXF1aXJlKCcuL2ZhY2V0L2NvbGxlY3Rpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlTW9kZWwuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIC8vIGZpcnN0IGRvIHBhcmVudCBjbGFzcyBpbml0aWFsaXphdGlvblxuICAgIEJhc2VNb2RlbC5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgLyoqXG4gICAgICogQ3Jvc3NmaWx0ZXIgaW5zdGFuY2UsIHNlZSBbaGVyZV0oaHR0cDovL3NxdWFyZS5naXRodWIuaW8vY3Jvc3NmaWx0ZXIvKVxuICAgICAqIHVzZWQgZm9yIGNsaWVudCBzaWRlIGRhdGEgaGFuZGxpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKi9cbiAgICB0aGlzLmNyb3NzZmlsdGVyID0gbmV3IENyb3NzZmlsdGVyKFtdKTtcbiAgICB0aGlzLmNvdW50R3JvdXAgPSB0aGlzLmNyb3NzZmlsdGVyLmdyb3VwQWxsKCkucmVkdWNlQ291bnQoKTtcbiAgfSxcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBOYW1lIG9mIHRoZSBkYXRhc2V0XG4gICAgICogQG1lbWJlcm9mISBEYXRhc2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBuYW1lOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ05hbWUnXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBVUkwsIGZpLiB0byBwYXBlciwgZGF0YXNldCBvd25lciwgZXRjLlxuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgVVJMOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ1VSTCdcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIERhdGFiYXNlIHRhYmxlIG5hbWUgZm9yIHNlcnZlciBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgZGF0YWJhc2VUYWJsZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZWZhdWx0OiAnJ1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogU2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIGRhdGFzZXRcbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRlc2NyaXB0aW9uOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ0Rlc2NyaXB0aW9uJ1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogSWYgZGF0YXNldCBpcyBwYXJ0IG9mIHRoZSBjdXJyZW50IHNlc3Npb25cbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0FjdGl2ZToge1xuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiBmYWxzZVxuICAgIH1cbiAgfSxcbiAgc2Vzc2lvbjoge1xuICAgIC8qKlxuICAgICAqIEZvciBzZWFyY2hpbmcgdGhyb3VnaCBkYXRhc2V0cyBVUkwgYW5kIGRlc2NyaXB0aW9uLlxuICAgICAqIFRydWUgaWYgdGhpcyBkYXRhc2V0IG1hdGNoZXMgdGhlIHNlYXJjaCBwYXJhbXRlcnMuXG4gICAgICovXG4gICAgc2hvdzoge1xuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiB0cnVlXG4gICAgfSxcbiAgICBkYXRhOiB7XG4gICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEEgRmFjZXQgY29sbGVjdGlvbiBob2xkaW5nIHByZSBkZWZpbmVkIGZhY2V0c1xuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtGYWNldFtdfVxuICAgICAqL1xuICAgIGZhY2V0czogRmFjZXRzXG4gIH0sXG4gIHNjYW46IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IHNwb3RcbiAgICB2YXIgc3BvdCA9IHRoaXMuY29sbGVjdGlvbi5wYXJlbnQ7XG5cbiAgICAvLyBjbGVhciBhbGwgZXhpc3RpbmcgZmFjZXRzXG4gICAgdGhpcy5mYWNldHMucmVzZXQoKTtcblxuICAgIHNwb3QuZHJpdmVyLnNjYW4odGhpcyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///545a\n")},"58ab":function(module,exports,__webpack_require__){eval('\nmodule.exports = __webpack_require__(/*! ./socket */ "0112");\n\n/**\n * Exports parser\n *\n * @api public\n *\n */\nmodule.exports.parser = __webpack_require__(/*! engine.io-parser */ "aa6c");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNThhYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvaW5kZXguanM/ZWViYiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9zb2NrZXQnKTtcblxuLyoqXG4gKiBFeHBvcnRzIHBhcnNlclxuICpcbiAqIEBhcGkgcHVibGljXG4gKlxuICovXG5tb2R1bGUuZXhwb3J0cy5wYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///58ab\n')},"5a80":function(module,exports,__webpack_require__){eval("/**\n * ContinuousTransfrom defines a transformation on continuous (nummerical) data.\n * Currently linear interpolation between a set of control points is implemented.\n *\n * @class ContinuousTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nvar ControlPoint = __webpack_require__(/*! ./control-point */ \"09c5\");\nvar ControlPoints = Collection.extend({\n  model: ControlPoint\n});\n\n/**\n * Apply piecewise linear transformation\n * The function is constant outside the range spanned by the control points;\n * there it is set to value of the first, or the last, control points.\n *\n * @function\n * @memberof! ContinuousTransform\n * @param {number} x\n * @returns {number} fx\n */\nfunction transform (cps, x) {\n  if (x === misval) {\n    return misval;\n  }\n\n  var ncps = cps.models.length;\n  if (x <= cps.models[0].x) {\n    // outside range on left side\n    return cps.models[0].fx;\n  } else if (x >= cps.models[ncps - 1].x) {\n    // outside range on right side\n    return cps.models[ncps - 1].fx;\n  } else {\n    // inside range\n    var i = 0;\n    while (x > cps.models[i].x) {\n      i = i + 1;\n    }\n\n    // linear interpolate between fx_i and fx_(i+1)\n    var xm = cps.models[i].x;\n    var xp = cps.models[i + 1].x;\n    var fxm = cps.models[i].fx;\n    var fxp = cps.models[i + 1].fx;\n    if (xp === xm) {\n      return 0.5 * (fxm + fxp);\n    } else {\n      return fxm + (x - xm) * (fxp - fxm) / (xp - xm);\n    }\n  }\n}\n\n/**\n * The inverse of the transform\n *\n * @function\n * @memberof! ContinuousTransform\n * @param {number} fx\n * @returns {number} x\n */\nfunction inverse (cps, fx) {\n  if (fx === misval) {\n    return misval;\n  }\n\n  var ncps = cps.models.length;\n  if (fx <= cps.models[0].fx) {\n    // outside range on left side\n    return cps.models[0].x;\n  } else if (fx >= cps.models[ncps - 1].fx) {\n    // outside range on right side\n    return cps.models[ncps - 1].x;\n  } else {\n    // inside range\n    var i = 0;\n    while (fx > cps.models[i].fx) {\n      i = i + 1;\n    }\n\n    // linear interpolate between fx_i and fx_(i+1)\n    var xm = cps.models[i].x;\n    var xp = cps.models[i + 1].x;\n    var fxm = cps.models[i].fx;\n    var fxp = cps.models[i + 1].fx;\n    if (fxp === fxm) {\n      return 0.5 * (xm + xp);\n    } else {\n      return xm + (fx - fxm) * (xp - xm) / (fxp - fxm);\n    }\n  }\n}\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * The type of continuous transform, can be none, or percentiles\n     * Use isNone, or isPercentiles, check for transform type\n     * @memberof! ContinuousTransform\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'none',\n      values: ['none', 'percentiles']\n    },\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'continuous',\n      values: ['continuous']\n    }\n  },\n  derived: {\n    isNone: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'none';\n      }\n    },\n    isPercentiles: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'percentiles';\n      }\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! ContinuousTransform\n     */\n    transformedMin: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isPercentiles) {\n          return 0;\n        } else if (this.isNone) {\n          return this.parent.minval;\n        } else {\n          console.error('Invalid continuous transform');\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! ContinuousTransform\n     */\n    transformedMax: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isPercentiles) {\n          return 100;\n        } else if (this.isNone) {\n          return this.parent.maxval;\n        } else {\n          console.error('Invalid continuous transform');\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! ContinuousTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! ContinuousTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n  collections: {\n    cps: ControlPoints\n  },\n  transform: function (x) {\n    return transform(this.cps, x);\n  },\n  inverse: function (fx) {\n    return inverse(this.cps, fx);\n  },\n  reset: function () {\n    this.type = 'none';\n    this.cps.reset();\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNWE4MC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29udGludW91cy10cmFuc2Zvcm0uanM/YzgwOSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbnRpbnVvdXNUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNvbnRpbnVvdXMgKG51bW1lcmljYWwpIGRhdGEuXG4gKiBDdXJyZW50bHkgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiBhIHNldCBvZiBjb250cm9sIHBvaW50cyBpcyBpbXBsZW1lbnRlZC5cbiAqXG4gKiBAY2xhc3MgQ29udGludW91c1RyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBDb2xsZWN0aW9uID0gcmVxdWlyZSgnYW1wZXJzYW5kLWNvbGxlY3Rpb24nKTtcbnZhciBtaXN2YWwgPSByZXF1aXJlKCcuLi91dGlsL21pc3ZhbCcpO1xuXG52YXIgQ29udHJvbFBvaW50ID0gcmVxdWlyZSgnLi9jb250cm9sLXBvaW50Jyk7XG52YXIgQ29udHJvbFBvaW50cyA9IENvbGxlY3Rpb24uZXh0ZW5kKHtcbiAgbW9kZWw6IENvbnRyb2xQb2ludFxufSk7XG5cbi8qKlxuICogQXBwbHkgcGllY2V3aXNlIGxpbmVhciB0cmFuc2Zvcm1hdGlvblxuICogVGhlIGZ1bmN0aW9uIGlzIGNvbnN0YW50IG91dHNpZGUgdGhlIHJhbmdlIHNwYW5uZWQgYnkgdGhlIGNvbnRyb2wgcG9pbnRzO1xuICogdGhlcmUgaXQgaXMgc2V0IHRvIHZhbHVlIG9mIHRoZSBmaXJzdCwgb3IgdGhlIGxhc3QsIGNvbnRyb2wgcG9pbnRzLlxuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mISBDb250aW51b3VzVHJhbnNmb3JtXG4gKiBAcGFyYW0ge251bWJlcn0geFxuICogQHJldHVybnMge251bWJlcn0gZnhcbiAqL1xuZnVuY3Rpb24gdHJhbnNmb3JtIChjcHMsIHgpIHtcbiAgaWYgKHggPT09IG1pc3ZhbCkge1xuICAgIHJldHVybiBtaXN2YWw7XG4gIH1cblxuICB2YXIgbmNwcyA9IGNwcy5tb2RlbHMubGVuZ3RoO1xuICBpZiAoeCA8PSBjcHMubW9kZWxzWzBdLngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIGxlZnQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzWzBdLmZ4O1xuICB9IGVsc2UgaWYgKHggPj0gY3BzLm1vZGVsc1tuY3BzIC0gMV0ueCkge1xuICAgIC8vIG91dHNpZGUgcmFuZ2Ugb24gcmlnaHQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzW25jcHMgLSAxXS5meDtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbnNpZGUgcmFuZ2VcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKHggPiBjcHMubW9kZWxzW2ldLngpIHtcbiAgICAgIGkgPSBpICsgMTtcbiAgICB9XG5cbiAgICAvLyBsaW5lYXIgaW50ZXJwb2xhdGUgYmV0d2VlbiBmeF9pIGFuZCBmeF8oaSsxKVxuICAgIHZhciB4bSA9IGNwcy5tb2RlbHNbaV0ueDtcbiAgICB2YXIgeHAgPSBjcHMubW9kZWxzW2kgKyAxXS54O1xuICAgIHZhciBmeG0gPSBjcHMubW9kZWxzW2ldLmZ4O1xuICAgIHZhciBmeHAgPSBjcHMubW9kZWxzW2kgKyAxXS5meDtcbiAgICBpZiAoeHAgPT09IHhtKSB7XG4gICAgICByZXR1cm4gMC41ICogKGZ4bSArIGZ4cCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmeG0gKyAoeCAtIHhtKSAqIChmeHAgLSBmeG0pIC8gKHhwIC0geG0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoZSBpbnZlcnNlIG9mIHRoZSB0cmFuc2Zvcm1cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICogQHBhcmFtIHtudW1iZXJ9IGZ4XG4gKiBAcmV0dXJucyB7bnVtYmVyfSB4XG4gKi9cbmZ1bmN0aW9uIGludmVyc2UgKGNwcywgZngpIHtcbiAgaWYgKGZ4ID09PSBtaXN2YWwpIHtcbiAgICByZXR1cm4gbWlzdmFsO1xuICB9XG5cbiAgdmFyIG5jcHMgPSBjcHMubW9kZWxzLmxlbmd0aDtcbiAgaWYgKGZ4IDw9IGNwcy5tb2RlbHNbMF0uZngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIGxlZnQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzWzBdLng7XG4gIH0gZWxzZSBpZiAoZnggPj0gY3BzLm1vZGVsc1tuY3BzIC0gMV0uZngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIHJpZ2h0IHNpZGVcbiAgICByZXR1cm4gY3BzLm1vZGVsc1tuY3BzIC0gMV0ueDtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbnNpZGUgcmFuZ2VcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKGZ4ID4gY3BzLm1vZGVsc1tpXS5meCkge1xuICAgICAgaSA9IGkgKyAxO1xuICAgIH1cblxuICAgIC8vIGxpbmVhciBpbnRlcnBvbGF0ZSBiZXR3ZWVuIGZ4X2kgYW5kIGZ4XyhpKzEpXG4gICAgdmFyIHhtID0gY3BzLm1vZGVsc1tpXS54O1xuICAgIHZhciB4cCA9IGNwcy5tb2RlbHNbaSArIDFdLng7XG4gICAgdmFyIGZ4bSA9IGNwcy5tb2RlbHNbaV0uZng7XG4gICAgdmFyIGZ4cCA9IGNwcy5tb2RlbHNbaSArIDFdLmZ4O1xuICAgIGlmIChmeHAgPT09IGZ4bSkge1xuICAgICAgcmV0dXJuIDAuNSAqICh4bSArIHhwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHhtICsgKGZ4IC0gZnhtKSAqICh4cCAtIHhtKSAvIChmeHAgLSBmeG0pO1xuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEFtcGVyc2FuZE1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgY29udGludW91cyB0cmFuc2Zvcm0sIGNhbiBiZSBub25lLCBvciBwZXJjZW50aWxlc1xuICAgICAqIFVzZSBpc05vbmUsIG9yIGlzUGVyY2VudGlsZXMsIGNoZWNrIGZvciB0cmFuc2Zvcm0gdHlwZVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnbm9uZScsXG4gICAgICB2YWx1ZXM6IFsnbm9uZScsICdwZXJjZW50aWxlcyddXG4gICAgfSxcbiAgICB0cmFuc2Zvcm1lZFR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnY29udGludW91cycsXG4gICAgICB2YWx1ZXM6IFsnY29udGludW91cyddXG4gICAgfVxuICB9LFxuICBkZXJpdmVkOiB7XG4gICAgaXNOb25lOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdub25lJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzUGVyY2VudGlsZXM6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ3BlcmNlbnRpbGVzJztcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1pbjoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5pc1BlcmNlbnRpbGVzKSB7XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc05vbmUpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQubWludmFsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgY29udGludW91cyB0cmFuc2Zvcm0nKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWF4OiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUGVyY2VudGlsZXMpIHtcbiAgICAgICAgICByZXR1cm4gMTAwO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNOb25lKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50Lm1heHZhbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdJbnZhbGlkIGNvbnRpbnVvdXMgdHJhbnNmb3JtJyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkTWluJywgJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1pbnZhbCA9IHRoaXMudHJhbnNmb3JtZWRNaW47XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiBtaW52YWwuZm9ybWF0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1heEFzVGV4dDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZE1heCcsICd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXh2YWwgPSB0aGlzLnRyYW5zZm9ybWVkTWF4O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLmZvcm1hdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH1cbiAgfSxcbiAgY29sbGVjdGlvbnM6IHtcbiAgICBjcHM6IENvbnRyb2xQb2ludHNcbiAgfSxcbiAgdHJhbnNmb3JtOiBmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiB0cmFuc2Zvcm0odGhpcy5jcHMsIHgpO1xuICB9LFxuICBpbnZlcnNlOiBmdW5jdGlvbiAoZngpIHtcbiAgICByZXR1cm4gaW52ZXJzZSh0aGlzLmNwcywgZngpO1xuICB9LFxuICByZXNldDogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMudHlwZSA9ICdub25lJztcbiAgICB0aGlzLmNwcy5yZXNldCgpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5a80\n")},6176:function(module,exports){eval("module.exports = Array.isArray || function (arr) {\n  return Object.prototype.toString.call(arr) == '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjE3Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcz8xYjA4Il0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6176\n")},"636d":function(module,exports){eval("\n/**\n * Expose `Emitter`.\n */\n\nmodule.exports = Emitter;\n\n/**\n * Initialize a new `Emitter`.\n *\n * @api public\n */\n\nfunction Emitter(obj) {\n  if (obj) return mixin(obj);\n};\n\n/**\n * Mixin the emitter properties.\n *\n * @param {Object} obj\n * @return {Object}\n * @api private\n */\n\nfunction mixin(obj) {\n  for (var key in Emitter.prototype) {\n    obj[key] = Emitter.prototype[key];\n  }\n  return obj;\n}\n\n/**\n * Listen on the given `event` with `fn`.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.on =\nEmitter.prototype.addEventListener = function(event, fn){\n  this._callbacks = this._callbacks || {};\n  (this._callbacks[event] = this._callbacks[event] || [])\n    .push(fn);\n  return this;\n};\n\n/**\n * Adds an `event` listener that will be invoked a single\n * time then automatically removed.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.once = function(event, fn){\n  var self = this;\n  this._callbacks = this._callbacks || {};\n\n  function on() {\n    self.off(event, on);\n    fn.apply(this, arguments);\n  }\n\n  on.fn = fn;\n  this.on(event, on);\n  return this;\n};\n\n/**\n * Remove the given callback for `event` or all\n * registered callbacks.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.off =\nEmitter.prototype.removeListener =\nEmitter.prototype.removeAllListeners =\nEmitter.prototype.removeEventListener = function(event, fn){\n  this._callbacks = this._callbacks || {};\n\n  // all\n  if (0 == arguments.length) {\n    this._callbacks = {};\n    return this;\n  }\n\n  // specific event\n  var callbacks = this._callbacks[event];\n  if (!callbacks) return this;\n\n  // remove all handlers\n  if (1 == arguments.length) {\n    delete this._callbacks[event];\n    return this;\n  }\n\n  // remove specific handler\n  var cb;\n  for (var i = 0; i < callbacks.length; i++) {\n    cb = callbacks[i];\n    if (cb === fn || cb.fn === fn) {\n      callbacks.splice(i, 1);\n      break;\n    }\n  }\n  return this;\n};\n\n/**\n * Emit `event` with the given args.\n *\n * @param {String} event\n * @param {Mixed} ...\n * @return {Emitter}\n */\n\nEmitter.prototype.emit = function(event){\n  this._callbacks = this._callbacks || {};\n  var args = [].slice.call(arguments, 1)\n    , callbacks = this._callbacks[event];\n\n  if (callbacks) {\n    callbacks = callbacks.slice(0);\n    for (var i = 0, len = callbacks.length; i < len; ++i) {\n      callbacks[i].apply(this, args);\n    }\n  }\n\n  return this;\n};\n\n/**\n * Return array of callbacks for `event`.\n *\n * @param {String} event\n * @return {Array}\n * @api public\n */\n\nEmitter.prototype.listeners = function(event){\n  this._callbacks = this._callbacks || {};\n  return this._callbacks[event] || [];\n};\n\n/**\n * Check if this emitter has `event` handlers.\n *\n * @param {String} event\n * @return {Boolean}\n * @api public\n */\n\nEmitter.prototype.hasListeners = function(event){\n  return !! this.listeners(event).length;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjM2ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanM/ZWVlMiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogRXhwb3NlIGBFbWl0dGVyYC5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVtaXR0ZXI7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgRW1pdHRlcmAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBFbWl0dGVyKG9iaikge1xuICBpZiAob2JqKSByZXR1cm4gbWl4aW4ob2JqKTtcbn07XG5cbi8qKlxuICogTWl4aW4gdGhlIGVtaXR0ZXIgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBtaXhpbihvYmopIHtcbiAgZm9yICh2YXIga2V5IGluIEVtaXR0ZXIucHJvdG90eXBlKSB7XG4gICAgb2JqW2tleV0gPSBFbWl0dGVyLnByb3RvdHlwZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbiA9XG5FbWl0dGVyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICAodGhpcy5fY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuX2NhbGxiYWNrc1tldmVudF0gfHwgW10pXG4gICAgLnB1c2goZm4pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXG4gKiB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICBmdW5jdGlvbiBvbigpIHtcbiAgICBzZWxmLm9mZihldmVudCwgb24pO1xuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBvbi5mbiA9IGZuO1xuICB0aGlzLm9uKGV2ZW50LCBvbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICogcmVnaXN0ZXJlZCBjYWxsYmFja3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub2ZmID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuXG4gIC8vIGFsbFxuICBpZiAoMCA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgdGhpcy5fY2FsbGJhY2tzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzcGVjaWZpYyBldmVudFxuICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcbiAgaWYgKCFjYWxsYmFja3MpIHJldHVybiB0aGlzO1xuXG4gIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcbiAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcbiAgdmFyIGNiO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgIGNiID0gY2FsbGJhY2tzW2ldO1xuICAgIGlmIChjYiA9PT0gZm4gfHwgY2IuZm4gPT09IGZuKSB7XG4gICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7TWl4ZWR9IC4uLlxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oZXZlbnQpe1xuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG4gIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpXG4gICAgLCBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuXG4gIGlmIChjYWxsYmFja3MpIHtcbiAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgY2FsbGJhY2tzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYXJyYXkgb2YgY2FsbGJhY2tzIGZvciBgZXZlbnRgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7QXJyYXl9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XSB8fCBbXTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhpcyBlbWl0dGVyIGhhcyBgZXZlbnRgIGhhbmRsZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuaGFzTGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xuICByZXR1cm4gISEgdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///636d\n")},"6b20":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar Transport = __webpack_require__(/*! ../transport */ \"0d97\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar yeast = __webpack_require__(/*! yeast */ \"c16d\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:websocket');\nvar BrowserWebSocket = global.WebSocket || global.MozWebSocket;\nvar NodeWebSocket;\nif (typeof window === 'undefined') {\n  try {\n    NodeWebSocket = __webpack_require__(/*! ws */ 1);\n  } catch (e) { }\n}\n\n/**\n * Get either the `WebSocket` or `MozWebSocket` globals\n * in the browser or try to resolve WebSocket-compatible\n * interface exposed by `ws` for Node-like environment.\n */\n\nvar WebSocket = BrowserWebSocket;\nif (!WebSocket && typeof window === 'undefined') {\n  WebSocket = NodeWebSocket;\n}\n\n/**\n * Module exports.\n */\n\nmodule.exports = WS;\n\n/**\n * WebSocket transport constructor.\n *\n * @api {Object} connection options\n * @api public\n */\n\nfunction WS (opts) {\n  var forceBase64 = (opts && opts.forceBase64);\n  if (forceBase64) {\n    this.supportsBinary = false;\n  }\n  this.perMessageDeflate = opts.perMessageDeflate;\n  this.usingBrowserWebSocket = BrowserWebSocket && !opts.forceNode;\n  if (!this.usingBrowserWebSocket) {\n    WebSocket = NodeWebSocket;\n  }\n  Transport.call(this, opts);\n}\n\n/**\n * Inherits from Transport.\n */\n\ninherit(WS, Transport);\n\n/**\n * Transport name.\n *\n * @api public\n */\n\nWS.prototype.name = 'websocket';\n\n/*\n * WebSockets support binary\n */\n\nWS.prototype.supportsBinary = true;\n\n/**\n * Opens socket.\n *\n * @api private\n */\n\nWS.prototype.doOpen = function () {\n  if (!this.check()) {\n    // let probe timeout\n    return;\n  }\n\n  var uri = this.uri();\n  var protocols = void (0);\n  var opts = {\n    agent: this.agent,\n    perMessageDeflate: this.perMessageDeflate\n  };\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n  if (this.extraHeaders) {\n    opts.headers = this.extraHeaders;\n  }\n  if (this.localAddress) {\n    opts.localAddress = this.localAddress;\n  }\n\n  try {\n    this.ws = this.usingBrowserWebSocket ? new WebSocket(uri) : new WebSocket(uri, protocols, opts);\n  } catch (err) {\n    return this.emit('error', err);\n  }\n\n  if (this.ws.binaryType === undefined) {\n    this.supportsBinary = false;\n  }\n\n  if (this.ws.supports && this.ws.supports.binary) {\n    this.supportsBinary = true;\n    this.ws.binaryType = 'nodebuffer';\n  } else {\n    this.ws.binaryType = 'arraybuffer';\n  }\n\n  this.addEventListeners();\n};\n\n/**\n * Adds event listeners to the socket\n *\n * @api private\n */\n\nWS.prototype.addEventListeners = function () {\n  var self = this;\n\n  this.ws.onopen = function () {\n    self.onOpen();\n  };\n  this.ws.onclose = function () {\n    self.onClose();\n  };\n  this.ws.onmessage = function (ev) {\n    self.onData(ev.data);\n  };\n  this.ws.onerror = function (e) {\n    self.onError('websocket error', e);\n  };\n};\n\n/**\n * Writes data to socket.\n *\n * @param {Array} array of packets.\n * @api private\n */\n\nWS.prototype.write = function (packets) {\n  var self = this;\n  this.writable = false;\n\n  // encodePacket efficient as it uses WS framing\n  // no need for encodePayload\n  var total = packets.length;\n  for (var i = 0, l = total; i < l; i++) {\n    (function (packet) {\n      parser.encodePacket(packet, self.supportsBinary, function (data) {\n        if (!self.usingBrowserWebSocket) {\n          // always create a new object (GH-437)\n          var opts = {};\n          if (packet.options) {\n            opts.compress = packet.options.compress;\n          }\n\n          if (self.perMessageDeflate) {\n            var len = 'string' === typeof data ? global.Buffer.byteLength(data) : data.length;\n            if (len < self.perMessageDeflate.threshold) {\n              opts.compress = false;\n            }\n          }\n        }\n\n        // Sometimes the websocket has already been closed but the browser didn't\n        // have a chance of informing us about it yet, in that case send will\n        // throw an error\n        try {\n          if (self.usingBrowserWebSocket) {\n            // TypeError is thrown when passing the second argument on Safari\n            self.ws.send(data);\n          } else {\n            self.ws.send(data, opts);\n          }\n        } catch (e) {\n          debug('websocket closed before onclose event');\n        }\n\n        --total || done();\n      });\n    })(packets[i]);\n  }\n\n  function done () {\n    self.emit('flush');\n\n    // fake drain\n    // defer to next tick to allow Socket to clear writeBuffer\n    setTimeout(function () {\n      self.writable = true;\n      self.emit('drain');\n    }, 0);\n  }\n};\n\n/**\n * Called upon close\n *\n * @api private\n */\n\nWS.prototype.onClose = function () {\n  Transport.prototype.onClose.call(this);\n};\n\n/**\n * Closes socket.\n *\n * @api private\n */\n\nWS.prototype.doClose = function () {\n  if (typeof this.ws !== 'undefined') {\n    this.ws.close();\n  }\n};\n\n/**\n * Generates uri for connection.\n *\n * @api private\n */\n\nWS.prototype.uri = function () {\n  var query = this.query || {};\n  var schema = this.secure ? 'wss' : 'ws';\n  var port = '';\n\n  // avoid port if default for schema\n  if (this.port && (('wss' === schema && Number(this.port) !== 443) ||\n    ('ws' === schema && Number(this.port) !== 80))) {\n    port = ':' + this.port;\n  }\n\n  // append timestamp to URI\n  if (this.timestampRequests) {\n    query[this.timestampParam] = yeast();\n  }\n\n  // communicate binary support capabilities\n  if (!this.supportsBinary) {\n    query.b64 = 1;\n  }\n\n  query = parseqs.encode(query);\n\n  // prepend ? to query\n  if (query.length) {\n    query = '?' + query;\n  }\n\n  var ipv6 = this.hostname.indexOf(':') !== -1;\n  return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;\n};\n\n/**\n * Feature detection for WebSocket.\n *\n * @return {Boolean} whether this transport is available.\n * @api public\n */\n\nWS.prototype.check = function () {\n  return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNmIyMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy93ZWJzb2NrZXQuanM/ZGI4MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIFRyYW5zcG9ydCA9IHJlcXVpcmUoJy4uL3RyYW5zcG9ydCcpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBwYXJzZXFzID0gcmVxdWlyZSgncGFyc2VxcycpO1xudmFyIGluaGVyaXQgPSByZXF1aXJlKCdjb21wb25lbnQtaW5oZXJpdCcpO1xudmFyIHllYXN0ID0gcmVxdWlyZSgneWVhc3QnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ2VuZ2luZS5pby1jbGllbnQ6d2Vic29ja2V0Jyk7XG52YXIgQnJvd3NlcldlYlNvY2tldCA9IGdsb2JhbC5XZWJTb2NrZXQgfHwgZ2xvYmFsLk1veldlYlNvY2tldDtcbnZhciBOb2RlV2ViU29ja2V0O1xuaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gIHRyeSB7XG4gICAgTm9kZVdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG4gIH0gY2F0Y2ggKGUpIHsgfVxufVxuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxudmFyIFdlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQ7XG5pZiAoIVdlYlNvY2tldCAmJiB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICBXZWJTb2NrZXQgPSBOb2RlV2ViU29ja2V0O1xufVxuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gV1M7XG5cbi8qKlxuICogV2ViU29ja2V0IHRyYW5zcG9ydCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHtPYmplY3R9IGNvbm5lY3Rpb24gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBXUyAob3B0cykge1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIHRoaXMucGVyTWVzc2FnZURlZmxhdGUgPSBvcHRzLnBlck1lc3NhZ2VEZWZsYXRlO1xuICB0aGlzLnVzaW5nQnJvd3NlcldlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQgJiYgIW9wdHMuZm9yY2VOb2RlO1xuICBpZiAoIXRoaXMudXNpbmdCcm93c2VyV2ViU29ja2V0KSB7XG4gICAgV2ViU29ja2V0ID0gTm9kZVdlYlNvY2tldDtcbiAgfVxuICBUcmFuc3BvcnQuY2FsbCh0aGlzLCBvcHRzKTtcbn1cblxuLyoqXG4gKiBJbmhlcml0cyBmcm9tIFRyYW5zcG9ydC5cbiAqL1xuXG5pbmhlcml0KFdTLCBUcmFuc3BvcnQpO1xuXG4vKipcbiAqIFRyYW5zcG9ydCBuYW1lLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuV1MucHJvdG90eXBlLm5hbWUgPSAnd2Vic29ja2V0JztcblxuLypcbiAqIFdlYlNvY2tldHMgc3VwcG9ydCBiaW5hcnlcbiAqL1xuXG5XUy5wcm90b3R5cGUuc3VwcG9ydHNCaW5hcnkgPSB0cnVlO1xuXG4vKipcbiAqIE9wZW5zIHNvY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5XUy5wcm90b3R5cGUuZG9PcGVuID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuY2hlY2soKSkge1xuICAgIC8vIGxldCBwcm9iZSB0aW1lb3V0XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHVyaSA9IHRoaXMudXJpKCk7XG4gIHZhciBwcm90b2NvbHMgPSB2b2lkICgwKTtcbiAgdmFyIG9wdHMgPSB7XG4gICAgYWdlbnQ6IHRoaXMuYWdlbnQsXG4gICAgcGVyTWVzc2FnZURlZmxhdGU6IHRoaXMucGVyTWVzc2FnZURlZmxhdGVcbiAgfTtcblxuICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgb3B0cy5wZnggPSB0aGlzLnBmeDtcbiAgb3B0cy5rZXkgPSB0aGlzLmtleTtcbiAgb3B0cy5wYXNzcGhyYXNlID0gdGhpcy5wYXNzcGhyYXNlO1xuICBvcHRzLmNlcnQgPSB0aGlzLmNlcnQ7XG4gIG9wdHMuY2EgPSB0aGlzLmNhO1xuICBvcHRzLmNpcGhlcnMgPSB0aGlzLmNpcGhlcnM7XG4gIG9wdHMucmVqZWN0VW5hdXRob3JpemVkID0gdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQ7XG4gIGlmICh0aGlzLmV4dHJhSGVhZGVycykge1xuICAgIG9wdHMuaGVhZGVycyA9IHRoaXMuZXh0cmFIZWFkZXJzO1xuICB9XG4gIGlmICh0aGlzLmxvY2FsQWRkcmVzcykge1xuICAgIG9wdHMubG9jYWxBZGRyZXNzID0gdGhpcy5sb2NhbEFkZHJlc3M7XG4gIH1cblxuICB0cnkge1xuICAgIHRoaXMud3MgPSB0aGlzLnVzaW5nQnJvd3NlcldlYlNvY2tldCA/IG5ldyBXZWJTb2NrZXQodXJpKSA6IG5ldyBXZWJTb2NrZXQodXJpLCBwcm90b2NvbHMsIG9wdHMpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gIH1cblxuICBpZiAodGhpcy53cy5iaW5hcnlUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG4gIH1cblxuICBpZiAodGhpcy53cy5zdXBwb3J0cyAmJiB0aGlzLndzLnN1cHBvcnRzLmJpbmFyeSkge1xuICAgIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSB0cnVlO1xuICAgIHRoaXMud3MuYmluYXJ5VHlwZSA9ICdub2RlYnVmZmVyJztcbiAgfSBlbHNlIHtcbiAgICB0aGlzLndzLmJpbmFyeVR5cGUgPSAnYXJyYXlidWZmZXInO1xuICB9XG5cbiAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xufTtcblxuLyoqXG4gKiBBZGRzIGV2ZW50IGxpc3RlbmVycyB0byB0aGUgc29ja2V0XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXJzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy53cy5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5vbk9wZW4oKTtcbiAgfTtcbiAgdGhpcy53cy5vbmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgIHNlbGYub25DbG9zZSgpO1xuICB9O1xuICB0aGlzLndzLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChldikge1xuICAgIHNlbGYub25EYXRhKGV2LmRhdGEpO1xuICB9O1xuICB0aGlzLndzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZSkge1xuICAgIHNlbGYub25FcnJvcignd2Vic29ja2V0IGVycm9yJywgZSk7XG4gIH07XG59O1xuXG4vKipcbiAqIFdyaXRlcyBkYXRhIHRvIHNvY2tldC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBvZiBwYWNrZXRzLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKHBhY2tldHMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG5cbiAgLy8gZW5jb2RlUGFja2V0IGVmZmljaWVudCBhcyBpdCB1c2VzIFdTIGZyYW1pbmdcbiAgLy8gbm8gbmVlZCBmb3IgZW5jb2RlUGF5bG9hZFxuICB2YXIgdG90YWwgPSBwYWNrZXRzLmxlbmd0aDtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB0b3RhbDsgaSA8IGw7IGkrKykge1xuICAgIChmdW5jdGlvbiAocGFja2V0KSB7XG4gICAgICBwYXJzZXIuZW5jb2RlUGFja2V0KHBhY2tldCwgc2VsZi5zdXBwb3J0c0JpbmFyeSwgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgaWYgKCFzZWxmLnVzaW5nQnJvd3NlcldlYlNvY2tldCkge1xuICAgICAgICAgIC8vIGFsd2F5cyBjcmVhdGUgYSBuZXcgb2JqZWN0IChHSC00MzcpXG4gICAgICAgICAgdmFyIG9wdHMgPSB7fTtcbiAgICAgICAgICBpZiAocGFja2V0Lm9wdGlvbnMpIHtcbiAgICAgICAgICAgIG9wdHMuY29tcHJlc3MgPSBwYWNrZXQub3B0aW9ucy5jb21wcmVzcztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc2VsZi5wZXJNZXNzYWdlRGVmbGF0ZSkge1xuICAgICAgICAgICAgdmFyIGxlbiA9ICdzdHJpbmcnID09PSB0eXBlb2YgZGF0YSA/IGdsb2JhbC5CdWZmZXIuYnl0ZUxlbmd0aChkYXRhKSA6IGRhdGEubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKGxlbiA8IHNlbGYucGVyTWVzc2FnZURlZmxhdGUudGhyZXNob2xkKSB7XG4gICAgICAgICAgICAgIG9wdHMuY29tcHJlc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTb21ldGltZXMgdGhlIHdlYnNvY2tldCBoYXMgYWxyZWFkeSBiZWVuIGNsb3NlZCBidXQgdGhlIGJyb3dzZXIgZGlkbid0XG4gICAgICAgIC8vIGhhdmUgYSBjaGFuY2Ugb2YgaW5mb3JtaW5nIHVzIGFib3V0IGl0IHlldCwgaW4gdGhhdCBjYXNlIHNlbmQgd2lsbFxuICAgICAgICAvLyB0aHJvdyBhbiBlcnJvclxuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChzZWxmLnVzaW5nQnJvd3NlcldlYlNvY2tldCkge1xuICAgICAgICAgICAgLy8gVHlwZUVycm9yIGlzIHRocm93biB3aGVuIHBhc3NpbmcgdGhlIHNlY29uZCBhcmd1bWVudCBvbiBTYWZhcmlcbiAgICAgICAgICAgIHNlbGYud3Muc2VuZChkYXRhKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi53cy5zZW5kKGRhdGEsIG9wdHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGRlYnVnKCd3ZWJzb2NrZXQgY2xvc2VkIGJlZm9yZSBvbmNsb3NlIGV2ZW50Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAtLXRvdGFsIHx8IGRvbmUoKTtcbiAgICAgIH0pO1xuICAgIH0pKHBhY2tldHNbaV0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZG9uZSAoKSB7XG4gICAgc2VsZi5lbWl0KCdmbHVzaCcpO1xuXG4gICAgLy8gZmFrZSBkcmFpblxuICAgIC8vIGRlZmVyIHRvIG5leHQgdGljayB0byBhbGxvdyBTb2NrZXQgdG8gY2xlYXIgd3JpdGVCdWZmZXJcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYud3JpdGFibGUgPSB0cnVlO1xuICAgICAgc2VsZi5lbWl0KCdkcmFpbicpO1xuICAgIH0sIDApO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGNsb3NlXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLm9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIFRyYW5zcG9ydC5wcm90b3R5cGUub25DbG9zZS5jYWxsKHRoaXMpO1xufTtcblxuLyoqXG4gKiBDbG9zZXMgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbldTLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIHRoaXMud3MgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhpcy53cy5jbG9zZSgpO1xuICB9XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyB1cmkgZm9yIGNvbm5lY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLnVyaSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHF1ZXJ5ID0gdGhpcy5xdWVyeSB8fCB7fTtcbiAgdmFyIHNjaGVtYSA9IHRoaXMuc2VjdXJlID8gJ3dzcycgOiAnd3MnO1xuICB2YXIgcG9ydCA9ICcnO1xuXG4gIC8vIGF2b2lkIHBvcnQgaWYgZGVmYXVsdCBmb3Igc2NoZW1hXG4gIGlmICh0aGlzLnBvcnQgJiYgKCgnd3NzJyA9PT0gc2NoZW1hICYmIE51bWJlcih0aGlzLnBvcnQpICE9PSA0NDMpIHx8XG4gICAgKCd3cycgPT09IHNjaGVtYSAmJiBOdW1iZXIodGhpcy5wb3J0KSAhPT0gODApKSkge1xuICAgIHBvcnQgPSAnOicgKyB0aGlzLnBvcnQ7XG4gIH1cblxuICAvLyBhcHBlbmQgdGltZXN0YW1wIHRvIFVSSVxuICBpZiAodGhpcy50aW1lc3RhbXBSZXF1ZXN0cykge1xuICAgIHF1ZXJ5W3RoaXMudGltZXN0YW1wUGFyYW1dID0geWVhc3QoKTtcbiAgfVxuXG4gIC8vIGNvbW11bmljYXRlIGJpbmFyeSBzdXBwb3J0IGNhcGFiaWxpdGllc1xuICBpZiAoIXRoaXMuc3VwcG9ydHNCaW5hcnkpIHtcbiAgICBxdWVyeS5iNjQgPSAxO1xuICB9XG5cbiAgcXVlcnkgPSBwYXJzZXFzLmVuY29kZShxdWVyeSk7XG5cbiAgLy8gcHJlcGVuZCA/IHRvIHF1ZXJ5XG4gIGlmIChxdWVyeS5sZW5ndGgpIHtcbiAgICBxdWVyeSA9ICc/JyArIHF1ZXJ5O1xuICB9XG5cbiAgdmFyIGlwdjYgPSB0aGlzLmhvc3RuYW1lLmluZGV4T2YoJzonKSAhPT0gLTE7XG4gIHJldHVybiBzY2hlbWEgKyAnOi8vJyArIChpcHY2ID8gJ1snICsgdGhpcy5ob3N0bmFtZSArICddJyA6IHRoaXMuaG9zdG5hbWUpICsgcG9ydCArIHRoaXMucGF0aCArIHF1ZXJ5O1xufTtcblxuLyoqXG4gKiBGZWF0dXJlIGRldGVjdGlvbiBmb3IgV2ViU29ja2V0LlxuICpcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHdoZXRoZXIgdGhpcyB0cmFuc3BvcnQgaXMgYXZhaWxhYmxlLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5XUy5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhIVdlYlNvY2tldCAmJiAhKCdfX2luaXRpYWxpemUnIGluIFdlYlNvY2tldCAmJiB0aGlzLm5hbWUgPT09IFdTLnByb3RvdHlwZS5uYW1lKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6b20\n")},"6fba":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar debug = __webpack_require__(/*! debug */ \"8233\")('socket.io-parser');\nvar json = __webpack_require__(/*! json3 */ \"3b17\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"636d\");\nvar binary = __webpack_require__(/*! ./binary */ \"ea82\");\nvar isBuf = __webpack_require__(/*! ./is-buffer */ \"419b\");\n\n/**\n * Protocol version.\n *\n * @api public\n */\n\nexports.protocol = 4;\n\n/**\n * Packet types.\n *\n * @api public\n */\n\nexports.types = [\n  'CONNECT',\n  'DISCONNECT',\n  'EVENT',\n  'ACK',\n  'ERROR',\n  'BINARY_EVENT',\n  'BINARY_ACK'\n];\n\n/**\n * Packet type `connect`.\n *\n * @api public\n */\n\nexports.CONNECT = 0;\n\n/**\n * Packet type `disconnect`.\n *\n * @api public\n */\n\nexports.DISCONNECT = 1;\n\n/**\n * Packet type `event`.\n *\n * @api public\n */\n\nexports.EVENT = 2;\n\n/**\n * Packet type `ack`.\n *\n * @api public\n */\n\nexports.ACK = 3;\n\n/**\n * Packet type `error`.\n *\n * @api public\n */\n\nexports.ERROR = 4;\n\n/**\n * Packet type 'binary event'\n *\n * @api public\n */\n\nexports.BINARY_EVENT = 5;\n\n/**\n * Packet type `binary ack`. For acks with binary arguments.\n *\n * @api public\n */\n\nexports.BINARY_ACK = 6;\n\n/**\n * Encoder constructor.\n *\n * @api public\n */\n\nexports.Encoder = Encoder;\n\n/**\n * Decoder constructor.\n *\n * @api public\n */\n\nexports.Decoder = Decoder;\n\n/**\n * A socket.io Encoder instance\n *\n * @api public\n */\n\nfunction Encoder() {}\n\n/**\n * Encode a packet as a single string if non-binary, or as a\n * buffer sequence, depending on packet type.\n *\n * @param {Object} obj - packet object\n * @param {Function} callback - function to handle encodings (likely engine.write)\n * @return Calls callback with Array of encodings\n * @api public\n */\n\nEncoder.prototype.encode = function(obj, callback){\n  debug('encoding packet %j', obj);\n\n  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n    encodeAsBinary(obj, callback);\n  }\n  else {\n    var encoding = encodeAsString(obj);\n    callback([encoding]);\n  }\n};\n\n/**\n * Encode packet as string.\n *\n * @param {Object} packet\n * @return {String} encoded\n * @api private\n */\n\nfunction encodeAsString(obj) {\n  var str = '';\n  var nsp = false;\n\n  // first is type\n  str += obj.type;\n\n  // attachments if we have them\n  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n    str += obj.attachments;\n    str += '-';\n  }\n\n  // if we have a namespace other than `/`\n  // we append it followed by a comma `,`\n  if (obj.nsp && '/' != obj.nsp) {\n    nsp = true;\n    str += obj.nsp;\n  }\n\n  // immediately followed by the id\n  if (null != obj.id) {\n    if (nsp) {\n      str += ',';\n      nsp = false;\n    }\n    str += obj.id;\n  }\n\n  // json data\n  if (null != obj.data) {\n    if (nsp) str += ',';\n    str += json.stringify(obj.data);\n  }\n\n  debug('encoded %j as %s', obj, str);\n  return str;\n}\n\n/**\n * Encode packet as 'buffer sequence' by removing blobs, and\n * deconstructing packet into object with placeholders and\n * a list of buffers.\n *\n * @param {Object} packet\n * @return {Buffer} encoded\n * @api private\n */\n\nfunction encodeAsBinary(obj, callback) {\n\n  function writeEncoding(bloblessData) {\n    var deconstruction = binary.deconstructPacket(bloblessData);\n    var pack = encodeAsString(deconstruction.packet);\n    var buffers = deconstruction.buffers;\n\n    buffers.unshift(pack); // add packet info to beginning of data list\n    callback(buffers); // write all the buffers\n  }\n\n  binary.removeBlobs(obj, writeEncoding);\n}\n\n/**\n * A socket.io Decoder instance\n *\n * @return {Object} decoder\n * @api public\n */\n\nfunction Decoder() {\n  this.reconstructor = null;\n}\n\n/**\n * Mix in `Emitter` with Decoder.\n */\n\nEmitter(Decoder.prototype);\n\n/**\n * Decodes an ecoded packet string into packet JSON.\n *\n * @param {String} obj - encoded packet\n * @return {Object} packet\n * @api public\n */\n\nDecoder.prototype.add = function(obj) {\n  var packet;\n  if ('string' == typeof obj) {\n    packet = decodeString(obj);\n    if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) { // binary packet's json\n      this.reconstructor = new BinaryReconstructor(packet);\n\n      // no attachments, labeled binary but no binary data to follow\n      if (this.reconstructor.reconPack.attachments === 0) {\n        this.emit('decoded', packet);\n      }\n    } else { // non-binary full packet\n      this.emit('decoded', packet);\n    }\n  }\n  else if (isBuf(obj) || obj.base64) { // raw binary data\n    if (!this.reconstructor) {\n      throw new Error('got binary data when not reconstructing a packet');\n    } else {\n      packet = this.reconstructor.takeBinaryData(obj);\n      if (packet) { // received final buffer\n        this.reconstructor = null;\n        this.emit('decoded', packet);\n      }\n    }\n  }\n  else {\n    throw new Error('Unknown type: ' + obj);\n  }\n};\n\n/**\n * Decode a packet String (JSON data)\n *\n * @param {String} str\n * @return {Object} packet\n * @api private\n */\n\nfunction decodeString(str) {\n  var p = {};\n  var i = 0;\n\n  // look up type\n  p.type = Number(str.charAt(0));\n  if (null == exports.types[p.type]) return error();\n\n  // look up attachments if type binary\n  if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) {\n    var buf = '';\n    while (str.charAt(++i) != '-') {\n      buf += str.charAt(i);\n      if (i == str.length) break;\n    }\n    if (buf != Number(buf) || str.charAt(i) != '-') {\n      throw new Error('Illegal attachments');\n    }\n    p.attachments = Number(buf);\n  }\n\n  // look up namespace (if any)\n  if ('/' == str.charAt(i + 1)) {\n    p.nsp = '';\n    while (++i) {\n      var c = str.charAt(i);\n      if (',' == c) break;\n      p.nsp += c;\n      if (i == str.length) break;\n    }\n  } else {\n    p.nsp = '/';\n  }\n\n  // look up id\n  var next = str.charAt(i + 1);\n  if ('' !== next && Number(next) == next) {\n    p.id = '';\n    while (++i) {\n      var c = str.charAt(i);\n      if (null == c || Number(c) != c) {\n        --i;\n        break;\n      }\n      p.id += str.charAt(i);\n      if (i == str.length) break;\n    }\n    p.id = Number(p.id);\n  }\n\n  // look up json data\n  if (str.charAt(++i)) {\n    p = tryParse(p, str.substr(i));\n  }\n\n  debug('decoded %s as %j', str, p);\n  return p;\n}\n\nfunction tryParse(p, str) {\n  try {\n    p.data = json.parse(str);\n  } catch(e){\n    return error();\n  }\n  return p; \n};\n\n/**\n * Deallocates a parser's resources\n *\n * @api public\n */\n\nDecoder.prototype.destroy = function() {\n  if (this.reconstructor) {\n    this.reconstructor.finishedReconstruction();\n  }\n};\n\n/**\n * A manager of a binary event's 'buffer sequence'. Should\n * be constructed whenever a packet of type BINARY_EVENT is\n * decoded.\n *\n * @param {Object} packet\n * @return {BinaryReconstructor} initialized reconstructor\n * @api private\n */\n\nfunction BinaryReconstructor(packet) {\n  this.reconPack = packet;\n  this.buffers = [];\n}\n\n/**\n * Method to be called when binary data received from connection\n * after a BINARY_EVENT packet.\n *\n * @param {Buffer | ArrayBuffer} binData - the raw binary data received\n * @return {null | Object} returns null if more binary data is expected or\n *   a reconstructed packet object if all buffers have been received.\n * @api private\n */\n\nBinaryReconstructor.prototype.takeBinaryData = function(binData) {\n  this.buffers.push(binData);\n  if (this.buffers.length == this.reconPack.attachments) { // done with buffer list\n    var packet = binary.reconstructPacket(this.reconPack, this.buffers);\n    this.finishedReconstruction();\n    return packet;\n  }\n  return null;\n};\n\n/**\n * Cleans up binary packet reconstruction variables.\n *\n * @api private\n */\n\nBinaryReconstructor.prototype.finishedReconstruction = function() {\n  this.reconPack = null;\n  this.buffers = [];\n};\n\nfunction error(data){\n  return {\n    type: exports.ERROR,\n    data: 'parser error'\n  };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNmZiYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9pbmRleC5qcz84ZjQzIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBqc29uID0gcmVxdWlyZSgnanNvbjMnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciBiaW5hcnkgPSByZXF1aXJlKCcuL2JpbmFyeScpO1xudmFyIGlzQnVmID0gcmVxdWlyZSgnLi9pcy1idWZmZXInKTtcblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5wcm90b2NvbCA9IDQ7XG5cbi8qKlxuICogUGFja2V0IHR5cGVzLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy50eXBlcyA9IFtcbiAgJ0NPTk5FQ1QnLFxuICAnRElTQ09OTkVDVCcsXG4gICdFVkVOVCcsXG4gICdBQ0snLFxuICAnRVJST1InLFxuICAnQklOQVJZX0VWRU5UJyxcbiAgJ0JJTkFSWV9BQ0snXG5dO1xuXG4vKipcbiAqIFBhY2tldCB0eXBlIGBjb25uZWN0YC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuQ09OTkVDVCA9IDA7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGRpc2Nvbm5lY3RgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5ESVNDT05ORUNUID0gMTtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgZXZlbnRgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5FVkVOVCA9IDI7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGFja2AuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkFDSyA9IDM7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGVycm9yYC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuRVJST1IgPSA0O1xuXG4vKipcbiAqIFBhY2tldCB0eXBlICdiaW5hcnkgZXZlbnQnXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkJJTkFSWV9FVkVOVCA9IDU7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGJpbmFyeSBhY2tgLiBGb3IgYWNrcyB3aXRoIGJpbmFyeSBhcmd1bWVudHMuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkJJTkFSWV9BQ0sgPSA2O1xuXG4vKipcbiAqIEVuY29kZXIgY29uc3RydWN0b3IuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkVuY29kZXIgPSBFbmNvZGVyO1xuXG4vKipcbiAqIERlY29kZXIgY29uc3RydWN0b3IuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkRlY29kZXIgPSBEZWNvZGVyO1xuXG4vKipcbiAqIEEgc29ja2V0LmlvIEVuY29kZXIgaW5zdGFuY2VcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIEVuY29kZXIoKSB7fVxuXG4vKipcbiAqIEVuY29kZSBhIHBhY2tldCBhcyBhIHNpbmdsZSBzdHJpbmcgaWYgbm9uLWJpbmFyeSwgb3IgYXMgYVxuICogYnVmZmVyIHNlcXVlbmNlLCBkZXBlbmRpbmcgb24gcGFja2V0IHR5cGUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiAtIHBhY2tldCBvYmplY3RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIC0gZnVuY3Rpb24gdG8gaGFuZGxlIGVuY29kaW5ncyAobGlrZWx5IGVuZ2luZS53cml0ZSlcbiAqIEByZXR1cm4gQ2FsbHMgY2FsbGJhY2sgd2l0aCBBcnJheSBvZiBlbmNvZGluZ3NcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW5jb2Rlci5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24ob2JqLCBjYWxsYmFjayl7XG4gIGRlYnVnKCdlbmNvZGluZyBwYWNrZXQgJWonLCBvYmopO1xuXG4gIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBvYmoudHlwZSB8fCBleHBvcnRzLkJJTkFSWV9BQ0sgPT0gb2JqLnR5cGUpIHtcbiAgICBlbmNvZGVBc0JpbmFyeShvYmosIGNhbGxiYWNrKTtcbiAgfVxuICBlbHNlIHtcbiAgICB2YXIgZW5jb2RpbmcgPSBlbmNvZGVBc1N0cmluZyhvYmopO1xuICAgIGNhbGxiYWNrKFtlbmNvZGluZ10pO1xuICB9XG59O1xuXG4vKipcbiAqIEVuY29kZSBwYWNrZXQgYXMgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEByZXR1cm4ge1N0cmluZ30gZW5jb2RlZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gZW5jb2RlQXNTdHJpbmcob2JqKSB7XG4gIHZhciBzdHIgPSAnJztcbiAgdmFyIG5zcCA9IGZhbHNlO1xuXG4gIC8vIGZpcnN0IGlzIHR5cGVcbiAgc3RyICs9IG9iai50eXBlO1xuXG4gIC8vIGF0dGFjaG1lbnRzIGlmIHdlIGhhdmUgdGhlbVxuICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gb2JqLnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IG9iai50eXBlKSB7XG4gICAgc3RyICs9IG9iai5hdHRhY2htZW50cztcbiAgICBzdHIgKz0gJy0nO1xuICB9XG5cbiAgLy8gaWYgd2UgaGF2ZSBhIG5hbWVzcGFjZSBvdGhlciB0aGFuIGAvYFxuICAvLyB3ZSBhcHBlbmQgaXQgZm9sbG93ZWQgYnkgYSBjb21tYSBgLGBcbiAgaWYgKG9iai5uc3AgJiYgJy8nICE9IG9iai5uc3ApIHtcbiAgICBuc3AgPSB0cnVlO1xuICAgIHN0ciArPSBvYmoubnNwO1xuICB9XG5cbiAgLy8gaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgdGhlIGlkXG4gIGlmIChudWxsICE9IG9iai5pZCkge1xuICAgIGlmIChuc3ApIHtcbiAgICAgIHN0ciArPSAnLCc7XG4gICAgICBuc3AgPSBmYWxzZTtcbiAgICB9XG4gICAgc3RyICs9IG9iai5pZDtcbiAgfVxuXG4gIC8vIGpzb24gZGF0YVxuICBpZiAobnVsbCAhPSBvYmouZGF0YSkge1xuICAgIGlmIChuc3ApIHN0ciArPSAnLCc7XG4gICAgc3RyICs9IGpzb24uc3RyaW5naWZ5KG9iai5kYXRhKTtcbiAgfVxuXG4gIGRlYnVnKCdlbmNvZGVkICVqIGFzICVzJywgb2JqLCBzdHIpO1xuICByZXR1cm4gc3RyO1xufVxuXG4vKipcbiAqIEVuY29kZSBwYWNrZXQgYXMgJ2J1ZmZlciBzZXF1ZW5jZScgYnkgcmVtb3ZpbmcgYmxvYnMsIGFuZFxuICogZGVjb25zdHJ1Y3RpbmcgcGFja2V0IGludG8gb2JqZWN0IHdpdGggcGxhY2Vob2xkZXJzIGFuZFxuICogYSBsaXN0IG9mIGJ1ZmZlcnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQHJldHVybiB7QnVmZmVyfSBlbmNvZGVkXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBlbmNvZGVBc0JpbmFyeShvYmosIGNhbGxiYWNrKSB7XG5cbiAgZnVuY3Rpb24gd3JpdGVFbmNvZGluZyhibG9ibGVzc0RhdGEpIHtcbiAgICB2YXIgZGVjb25zdHJ1Y3Rpb24gPSBiaW5hcnkuZGVjb25zdHJ1Y3RQYWNrZXQoYmxvYmxlc3NEYXRhKTtcbiAgICB2YXIgcGFjayA9IGVuY29kZUFzU3RyaW5nKGRlY29uc3RydWN0aW9uLnBhY2tldCk7XG4gICAgdmFyIGJ1ZmZlcnMgPSBkZWNvbnN0cnVjdGlvbi5idWZmZXJzO1xuXG4gICAgYnVmZmVycy51bnNoaWZ0KHBhY2spOyAvLyBhZGQgcGFja2V0IGluZm8gdG8gYmVnaW5uaW5nIG9mIGRhdGEgbGlzdFxuICAgIGNhbGxiYWNrKGJ1ZmZlcnMpOyAvLyB3cml0ZSBhbGwgdGhlIGJ1ZmZlcnNcbiAgfVxuXG4gIGJpbmFyeS5yZW1vdmVCbG9icyhvYmosIHdyaXRlRW5jb2RpbmcpO1xufVxuXG4vKipcbiAqIEEgc29ja2V0LmlvIERlY29kZXIgaW5zdGFuY2VcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGRlY29kZXJcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRGVjb2RlcigpIHtcbiAgdGhpcy5yZWNvbnN0cnVjdG9yID0gbnVsbDtcbn1cblxuLyoqXG4gKiBNaXggaW4gYEVtaXR0ZXJgIHdpdGggRGVjb2Rlci5cbiAqL1xuXG5FbWl0dGVyKERlY29kZXIucHJvdG90eXBlKTtcblxuLyoqXG4gKiBEZWNvZGVzIGFuIGVjb2RlZCBwYWNrZXQgc3RyaW5nIGludG8gcGFja2V0IEpTT04uXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG9iaiAtIGVuY29kZWQgcGFja2V0XG4gKiBAcmV0dXJuIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5EZWNvZGVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbihvYmopIHtcbiAgdmFyIHBhY2tldDtcbiAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBvYmopIHtcbiAgICBwYWNrZXQgPSBkZWNvZGVTdHJpbmcob2JqKTtcbiAgICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gcGFja2V0LnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IHBhY2tldC50eXBlKSB7IC8vIGJpbmFyeSBwYWNrZXQncyBqc29uXG4gICAgICB0aGlzLnJlY29uc3RydWN0b3IgPSBuZXcgQmluYXJ5UmVjb25zdHJ1Y3RvcihwYWNrZXQpO1xuXG4gICAgICAvLyBubyBhdHRhY2htZW50cywgbGFiZWxlZCBiaW5hcnkgYnV0IG5vIGJpbmFyeSBkYXRhIHRvIGZvbGxvd1xuICAgICAgaWYgKHRoaXMucmVjb25zdHJ1Y3Rvci5yZWNvblBhY2suYXR0YWNobWVudHMgPT09IDApIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkZWNvZGVkJywgcGFja2V0KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgeyAvLyBub24tYmluYXJ5IGZ1bGwgcGFja2V0XG4gICAgICB0aGlzLmVtaXQoJ2RlY29kZWQnLCBwYWNrZXQpO1xuICAgIH1cbiAgfVxuICBlbHNlIGlmIChpc0J1ZihvYmopIHx8IG9iai5iYXNlNjQpIHsgLy8gcmF3IGJpbmFyeSBkYXRhXG4gICAgaWYgKCF0aGlzLnJlY29uc3RydWN0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ290IGJpbmFyeSBkYXRhIHdoZW4gbm90IHJlY29uc3RydWN0aW5nIGEgcGFja2V0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhY2tldCA9IHRoaXMucmVjb25zdHJ1Y3Rvci50YWtlQmluYXJ5RGF0YShvYmopO1xuICAgICAgaWYgKHBhY2tldCkgeyAvLyByZWNlaXZlZCBmaW5hbCBidWZmZXJcbiAgICAgICAgdGhpcy5yZWNvbnN0cnVjdG9yID0gbnVsbDtcbiAgICAgICAgdGhpcy5lbWl0KCdkZWNvZGVkJywgcGFja2V0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHR5cGU6ICcgKyBvYmopO1xuICB9XG59O1xuXG4vKipcbiAqIERlY29kZSBhIHBhY2tldCBTdHJpbmcgKEpTT04gZGF0YSlcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gZGVjb2RlU3RyaW5nKHN0cikge1xuICB2YXIgcCA9IHt9O1xuICB2YXIgaSA9IDA7XG5cbiAgLy8gbG9vayB1cCB0eXBlXG4gIHAudHlwZSA9IE51bWJlcihzdHIuY2hhckF0KDApKTtcbiAgaWYgKG51bGwgPT0gZXhwb3J0cy50eXBlc1twLnR5cGVdKSByZXR1cm4gZXJyb3IoKTtcblxuICAvLyBsb29rIHVwIGF0dGFjaG1lbnRzIGlmIHR5cGUgYmluYXJ5XG4gIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBwLnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IHAudHlwZSkge1xuICAgIHZhciBidWYgPSAnJztcbiAgICB3aGlsZSAoc3RyLmNoYXJBdCgrK2kpICE9ICctJykge1xuICAgICAgYnVmICs9IHN0ci5jaGFyQXQoaSk7XG4gICAgICBpZiAoaSA9PSBzdHIubGVuZ3RoKSBicmVhaztcbiAgICB9XG4gICAgaWYgKGJ1ZiAhPSBOdW1iZXIoYnVmKSB8fCBzdHIuY2hhckF0KGkpICE9ICctJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbGxlZ2FsIGF0dGFjaG1lbnRzJyk7XG4gICAgfVxuICAgIHAuYXR0YWNobWVudHMgPSBOdW1iZXIoYnVmKTtcbiAgfVxuXG4gIC8vIGxvb2sgdXAgbmFtZXNwYWNlIChpZiBhbnkpXG4gIGlmICgnLycgPT0gc3RyLmNoYXJBdChpICsgMSkpIHtcbiAgICBwLm5zcCA9ICcnO1xuICAgIHdoaWxlICgrK2kpIHtcbiAgICAgIHZhciBjID0gc3RyLmNoYXJBdChpKTtcbiAgICAgIGlmICgnLCcgPT0gYykgYnJlYWs7XG4gICAgICBwLm5zcCArPSBjO1xuICAgICAgaWYgKGkgPT0gc3RyLmxlbmd0aCkgYnJlYWs7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHAubnNwID0gJy8nO1xuICB9XG5cbiAgLy8gbG9vayB1cCBpZFxuICB2YXIgbmV4dCA9IHN0ci5jaGFyQXQoaSArIDEpO1xuICBpZiAoJycgIT09IG5leHQgJiYgTnVtYmVyKG5leHQpID09IG5leHQpIHtcbiAgICBwLmlkID0gJyc7XG4gICAgd2hpbGUgKCsraSkge1xuICAgICAgdmFyIGMgPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKG51bGwgPT0gYyB8fCBOdW1iZXIoYykgIT0gYykge1xuICAgICAgICAtLWk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgcC5pZCArPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKGkgPT0gc3RyLmxlbmd0aCkgYnJlYWs7XG4gICAgfVxuICAgIHAuaWQgPSBOdW1iZXIocC5pZCk7XG4gIH1cblxuICAvLyBsb29rIHVwIGpzb24gZGF0YVxuICBpZiAoc3RyLmNoYXJBdCgrK2kpKSB7XG4gICAgcCA9IHRyeVBhcnNlKHAsIHN0ci5zdWJzdHIoaSkpO1xuICB9XG5cbiAgZGVidWcoJ2RlY29kZWQgJXMgYXMgJWonLCBzdHIsIHApO1xuICByZXR1cm4gcDtcbn1cblxuZnVuY3Rpb24gdHJ5UGFyc2UocCwgc3RyKSB7XG4gIHRyeSB7XG4gICAgcC5kYXRhID0ganNvbi5wYXJzZShzdHIpO1xuICB9IGNhdGNoKGUpe1xuICAgIHJldHVybiBlcnJvcigpO1xuICB9XG4gIHJldHVybiBwOyBcbn07XG5cbi8qKlxuICogRGVhbGxvY2F0ZXMgYSBwYXJzZXIncyByZXNvdXJjZXNcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkRlY29kZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMucmVjb25zdHJ1Y3Rvcikge1xuICAgIHRoaXMucmVjb25zdHJ1Y3Rvci5maW5pc2hlZFJlY29uc3RydWN0aW9uKCk7XG4gIH1cbn07XG5cbi8qKlxuICogQSBtYW5hZ2VyIG9mIGEgYmluYXJ5IGV2ZW50J3MgJ2J1ZmZlciBzZXF1ZW5jZScuIFNob3VsZFxuICogYmUgY29uc3RydWN0ZWQgd2hlbmV2ZXIgYSBwYWNrZXQgb2YgdHlwZSBCSU5BUllfRVZFTlQgaXNcbiAqIGRlY29kZWQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQHJldHVybiB7QmluYXJ5UmVjb25zdHJ1Y3Rvcn0gaW5pdGlhbGl6ZWQgcmVjb25zdHJ1Y3RvclxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gQmluYXJ5UmVjb25zdHJ1Y3RvcihwYWNrZXQpIHtcbiAgdGhpcy5yZWNvblBhY2sgPSBwYWNrZXQ7XG4gIHRoaXMuYnVmZmVycyA9IFtdO1xufVxuXG4vKipcbiAqIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBiaW5hcnkgZGF0YSByZWNlaXZlZCBmcm9tIGNvbm5lY3Rpb25cbiAqIGFmdGVyIGEgQklOQVJZX0VWRU5UIHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge0J1ZmZlciB8IEFycmF5QnVmZmVyfSBiaW5EYXRhIC0gdGhlIHJhdyBiaW5hcnkgZGF0YSByZWNlaXZlZFxuICogQHJldHVybiB7bnVsbCB8IE9iamVjdH0gcmV0dXJucyBudWxsIGlmIG1vcmUgYmluYXJ5IGRhdGEgaXMgZXhwZWN0ZWQgb3JcbiAqICAgYSByZWNvbnN0cnVjdGVkIHBhY2tldCBvYmplY3QgaWYgYWxsIGJ1ZmZlcnMgaGF2ZSBiZWVuIHJlY2VpdmVkLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuQmluYXJ5UmVjb25zdHJ1Y3Rvci5wcm90b3R5cGUudGFrZUJpbmFyeURhdGEgPSBmdW5jdGlvbihiaW5EYXRhKSB7XG4gIHRoaXMuYnVmZmVycy5wdXNoKGJpbkRhdGEpO1xuICBpZiAodGhpcy5idWZmZXJzLmxlbmd0aCA9PSB0aGlzLnJlY29uUGFjay5hdHRhY2htZW50cykgeyAvLyBkb25lIHdpdGggYnVmZmVyIGxpc3RcbiAgICB2YXIgcGFja2V0ID0gYmluYXJ5LnJlY29uc3RydWN0UGFja2V0KHRoaXMucmVjb25QYWNrLCB0aGlzLmJ1ZmZlcnMpO1xuICAgIHRoaXMuZmluaXNoZWRSZWNvbnN0cnVjdGlvbigpO1xuICAgIHJldHVybiBwYWNrZXQ7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIENsZWFucyB1cCBiaW5hcnkgcGFja2V0IHJlY29uc3RydWN0aW9uIHZhcmlhYmxlcy5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5CaW5hcnlSZWNvbnN0cnVjdG9yLnByb3RvdHlwZS5maW5pc2hlZFJlY29uc3RydWN0aW9uID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMucmVjb25QYWNrID0gbnVsbDtcbiAgdGhpcy5idWZmZXJzID0gW107XG59O1xuXG5mdW5jdGlvbiBlcnJvcihkYXRhKXtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBleHBvcnRzLkVSUk9SLFxuICAgIGRhdGE6ICdwYXJzZXIgZXJyb3InXG4gIH07XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6fba\n")},"720c":function(module,exports,__webpack_require__){eval("/**\n * Client side filtering using crossfilter\n * Due to limitation of crossfilter with array (or data that has no natrual ordering), this will not work as expected:\n * * dimension: `function (d) {return [d.x, d.y, d.z]}`\n * * group: `function (d) {return [d.x / 10 , d.y / 10, d.z / 10]}`\n *\n * Therefore, we preform grouping already in the dimension itself, and join the array to a string.\n * Strings have a natural ordering and thus can be used as dimension value.\n * * dimension: `function (d) -> \"d.x/10|d.y/10|d.z/10\"`\n * * group: `function (d) {return d;}`\n *\n * @module driver/client\n */\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nvar utildx = __webpack_require__(/*! ../util/crossfilter */ \"adfa\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nvar grpIdxToName = {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'};\nvar aggRankToName = {1: 'aa', 2: 'bb', 3: 'cc', 4: 'dd', 5: 'ee'};\n\n/**\n * setMinMax sets the range of a continuous or time facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setMinMax (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var valFn = utildx.baseValueFn(facet);\n\n  // to be able to mark the value as missing we need it unprocessed, so rawValueFn\n  var rawValFn = utildx.rawValueFn(facet);\n\n  var lessFn;\n  var moreFn;\n  if (facet.isDatetime) {\n    lessFn = function (a, b) { return (b === misval || a.isBefore(b)); };\n    moreFn = function (a, b) { return (b === misval || b.isBefore(a)); };\n  } else {\n    lessFn = function (a, b) { return (b === misval || a < b); };\n    moreFn = function (a, b) { return (b === misval || a > b); };\n  }\n\n  var minval = misval;\n  var rawMin = misval;\n\n  var maxval = misval;\n  var rawMax = misval;\n\n  dataset.data.forEach(function (d) {\n    var rawV = rawValFn(d);\n    var v = valFn(d);\n\n    if (v !== misval) {\n      if (lessFn(v, minval)) {\n        minval = v;\n        rawMin = rawV;\n      }\n      if (moreFn(v, maxval)) {\n        maxval = v;\n        rawMax = rawV;\n      }\n    }\n  });\n\n  if (minval !== misval) {\n    if (facet.isContinuous) {\n      facet.minvalAsText = minval.toString();\n    } else if (facet.isDatetime) {\n      facet.minvalAsText = minval.toISOString();\n    } else if (facet.isDuration) {\n      facet.minvalAsText = minval.toISOString();\n    }\n    facet.rawMinval = rawMin;\n  } else {\n    facet.minvalAsText = '';\n    facet.rawMinval = misval;\n  }\n\n  if (maxval !== misval) {\n    if (facet.isContinuous) {\n      facet.maxvalAsText = maxval.toString();\n    } else if (facet.isDatetime) {\n      facet.maxvalAsText = maxval.toISOString();\n    } else if (facet.isDuration) {\n      facet.maxvalAsText = maxval.toISOString();\n    }\n    facet.rawMaxval = rawMax;\n  } else {\n    facet.maxvalAsText = '';\n    facet.rawMaxval = misval;\n  }\n}\n\n/**\n * setCategories finds finds all values on an ordinal (categorial) axis\n * Updates the categorialTransform of the facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setCategories (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var valFn = utildx.baseValueFn(facet);\n\n  var p = {};\n  var Plength = 0;\n  dataset.data.forEach(function (d, i) {\n    var vals = valFn(d);\n    if (vals instanceof Array) {\n      vals.forEach(function (val) {\n        if (p.hasOwnProperty(val)) {\n          p[val]++;\n        } else {\n          if (Plength < 75) { // NOTE: limit to maximally 75 categories\n            p[val] = 1;\n            Plength++;\n          }\n        }\n      });\n    } else {\n      if (p.hasOwnProperty(vals)) {\n        p[vals]++;\n      } else {\n        if (Plength < 75) { // NOTE: limit to maximally 75 categories\n          p[vals] = 1;\n          Plength++;\n        }\n      }\n    }\n  });\n\n  facet.categorialTransform.reset();\n\n  Object.keys(p).forEach(function (key) {\n    // TODO: missing data should be mapped to a misval from misvalAsText\n    var keyAsString = key.toString();\n    var groupAsString = keyAsString;\n\n    facet.categorialTransform.rules.add({expression: keyAsString, count: p[key], group: groupAsString});\n  });\n}\n\n/**\n * Calculate 100 percentiles (ie. 1,2,3,4 etc.), and initialize the `facet.continuousTransform`\n * to an approximate percentile mapping.\n * Use the recommended method from [NIST](http://www.itl.nist.gov/div898/handbook/prc/section2/prc262.htm)\n * See also the discussion on [Wikipedia](https://en.wikipedia.org/wiki/Percentile)\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setPercentiles (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var basevalueFn = utildx.baseValueFn(facet);\n  var data = dataset.data;\n\n  data.sort(function (a, b) {\n    var valA = basevalueFn(a);\n    var valB = basevalueFn(b);\n\n    if (valA === valB) {\n      return 0;\n    }\n    if (valA === misval) {\n      return -1;\n    }\n    if (valB === misval) {\n      return 1;\n    }\n\n    if (valA < valB) {\n      return -1;\n    } else {\n      return 1;\n    }\n  });\n\n  var tf = facet.continuousTransform;\n  var x, i;\n\n  // drop missing values, which should be sorted at the start of the array\n  i = 0;\n  while (basevalueFn(data[i]) === misval && i < data.length) {\n    i++;\n  }\n  data.splice(0, i);\n\n  // start clean\n  tf.reset();\n\n  // add minimum value as control points p0 and p1\n  tf.cps.add({x: basevalueFn(data[0]), fx: 0});\n  tf.cps.add({x: basevalueFn(data[0]), fx: 0});\n\n  var p, value;\n  for (p = 1; p < 100; p++) {\n    x = (p * 0.01) * (data.length + 1) - 1; // indexing starts at zero, not at one\n    i = Math.trunc(x);\n    value = (1 - x + i) * basevalueFn(data[i]) + (x - i) * basevalueFn(data[i + 1]);\n    tf.cps.add({x: value, fx: p});\n  }\n\n  // add maximum value as p101 and p102\n  tf.cps.add({x: basevalueFn(data[data.length - 1]), fx: 100});\n  tf.cps.add({x: basevalueFn(data[data.length - 1]), fx: 100});\n\n  tf.type = 'percentiles';\n}\n\n/**\n * Autoconfigure a dataset:\n * 1. pick 10 random elements\n * 2. create facets for their properties\n * 3. add facets' values over the sample to the facet.description\n * 4. set range or categories\n *\n * @param {Dataset} dataset\n */\nfunction scan (dataset) {\n  function facetExists (facets, path) {\n    var exists = false;\n    facets.forEach(function (f) {\n      if (f.accessor === path || f.accessor === path + '[]') {\n        exists = true;\n      }\n    });\n    return exists;\n  }\n\n  function addValue (values, v, missing) {\n    if (v === misval) {\n      v = missing;\n    }\n    if (values.indexOf(v) === -1) {\n      values.push(v);\n    }\n  }\n\n  function guessType (values) {\n    var mytype = {\n      continuous: 0,\n      text: 0,\n      datetime: 0,\n      duration: 0,\n      categorial: 0\n    };\n    values.forEach(function (value) {\n      if (moment(value, moment.ISO_8601).isValid()) {\n        // \"2016-08-17 17:25:00+01\"\n        mytype.datetime++;\n      } else if (\n          (moment.duration(value).asMilliseconds() !== 0) &&\n          (typeof value === 'string') &&\n          (value[0].toLowerCase() === 'p')) {\n        // \"P10Y\"\n        mytype.duration++;\n      } else if (value == +value) {  // eslint-disable-line eqeqeq\n        // \"10\" or 10\n        mytype.continuous++;\n      } else {\n        // \"hello world\"\n        mytype.categorial++;\n      }\n    });\n\n    // get facetType with highest count\n    var max = -1;\n    var facetType;\n    Object.keys(mytype).forEach(function (key) {\n      if (mytype[key] > max) {\n        facetType = key;\n        max = mytype[key];\n      }\n    });\n\n    return facetType;\n  }\n\n  function tryFacet (facets, data, path, value) {\n    // Check for existence\n    if (facetExists(facets, path)) {\n      return;\n    }\n\n    // Create a new facet\n    var facet = facets.add({\n      name: path,\n      accessor: path,\n      type: 'text'\n    });\n\n    // Sample values\n    var baseValueFn = utildx.baseValueFn(facet);\n    var values = [];\n    var isArray = false;\n\n    data.forEach(function (d) {\n      var value = baseValueFn(d);\n      if (value instanceof Array) {\n        isArray = true;\n        value.forEach(function (v) {\n          addValue(values, v, facet.misval[0]);\n        });\n      } else {\n        addValue(values, value, facet.misval[0]);\n      }\n    });\n\n    // Reconfigure facet\n    facet.accessor = isArray ? facet.accessor + '[]' : facet.accessor;\n    facet.type = guessType(values);\n    facet.description = values.join(', ').match('^.{0,40}') + '...';\n    facet.isActive = true;\n  }\n\n  function recurse (facets, data, path, tree) {\n    var props = Object.getOwnPropertyNames(tree);\n    props.forEach(function (name) {\n      var subpath;\n      if (path) {\n        subpath = path + '##' + name;\n      } else {\n        subpath = name;\n      }\n\n      if (tree[name] instanceof Array) {\n        // add an array as a itself as a facet, ie. labelset, to prevent adding each element as separate facet\n        // also add the array length as facet\n        tryFacet(facets, data, subpath, tree[name]);\n        tryFacet(facets, data, subpath + '.length', tree[name].length);\n      } else if (tree[name] instanceof Object) {\n        // recurse into objects\n        recurse(facets, data, subpath, tree[name]);\n      } else {\n        // add strings and numbers as facets\n        tryFacet(facets, data, subpath, tree[name]);\n      }\n    });\n  }\n\n  // Add facets\n  var data = dataset.data.slice(0, 10);\n  data.forEach(function (d) {\n    recurse(dataset.facets, data, '', d);\n  });\n\n  dataset.facets.forEach(function (facet) {\n    if (facet.isCategorial) {\n      setCategories(dataset, facet);\n    } else if (facet.isContinuous || facet.isDatetime) {\n      setMinMax(dataset, facet);\n    }\n  });\n  dataset.trigger('syncFacets');\n}\n\n/**\n * Initialize the data filter, and construct the getData callback function on the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction initDataFilter (dataview, filter) {\n  var facet;\n\n  // use the partitions as groups:\n  var groupFns = [];\n  filter.partitions.forEach(function (partition) {\n    facet = dataview.facets.get(partition.facetName, 'name');\n    var valueFn = utildx.valueFn(facet);\n    var groupFn = utildx.groupFn(partition);\n\n    var rank = partition.rank;\n    groupFns[rank - 1] = function (d) {\n      return groupFn(valueFn(d));\n    };\n  });\n\n  // and then create keys from the group values\n  var groupsKeys = function (d) {\n    var keys = [];\n\n    groupFns.forEach(function (groupFn) {\n      var result = groupFn(d);\n      var newKeys = [];\n      if (keys.length === 0) {\n        if (result instanceof Array) {\n          newKeys = result;\n        } else {\n          newKeys = [result];\n        }\n      } else {\n        if (result instanceof Array) {\n          keys.forEach(function (oldKey) {\n            result.forEach(function (key) {\n              newKeys.push(oldKey + '|' + key);\n            });\n          });\n        } else {\n          keys.forEach(function (oldKey) {\n            newKeys.push(oldKey + '|' + result);\n          });\n        }\n      }\n      keys = newKeys;\n    });\n    return keys;\n  };\n\n  // set up the facet valueFns to aggregate over\n  // and the reduction functions for them\n  var aggregateFns = [];\n  var aggregateRanks = [];\n  var reduceFns = [];\n  filter.aggregates.forEach(function (aggregate) {\n    facet = dataview.facets.get(aggregate.facetName, 'name');\n    aggregateRanks.push(aggregate.rank);\n    aggregateFns.push(utildx.valueFn(facet));\n    reduceFns.push(utildx.reduceFn(aggregate));\n  });\n\n  // setup the crossfilter dimensions and groups\n  filter.dimension = dataview.crossfilter.dimension(function (d) {\n    return groupsKeys(d);\n  }, true);\n  var crossfilterGroup = filter.dimension.group(function (d) { return d; });\n\n  crossfilterGroup.reduce(\n    // add\n    function (p, d) {\n      if (aggregateFns.length === 0) {\n        p[0] = p[0] ? p[0] : {count: 0};\n        p[0].count += 1;\n      }\n\n      aggregateFns.forEach(function (aggregateFn, i) {\n        var val = aggregateFn(d);\n        if (val !== misval) {\n          val = parseFloat(val);\n          p[i] = p[i] || {count: 0, sum: 0, sumsquares: 0};\n          p[i].count += 1;\n          p[i].sum += val;\n          p[i].sumsquares += val * val;\n        }\n      });\n      return p;\n    },\n    // subtract\n    function (p, d) {\n      if (aggregateFns.length === 0) {\n        p[0] = p[0] ? p[0] : {count: 0};\n        p[0].count -= 1;\n      }\n\n      aggregateFns.forEach(function (aggregateFn, i) {\n        var val = aggregateFn(d);\n        if (val !== misval) {\n          val = parseFloat(val);\n          p[i] = p[i] || {count: 0, sum: 0, sumsquares: 0};\n          p[i].count -= 1;\n          p[i].sum -= val;\n          p[i].sumsquares -= val * val;\n        }\n      });\n      return p;\n    },\n    // initialize\n    function () {\n      return [];\n    }\n  );\n\n  filter.getData = function () {\n    filter.data = [];\n\n    // Get data from crossfilter\n    var groups = crossfilterGroup.all();\n\n    // { key: \"group1|group2|...\",\n    //   value: [ {count: agg1, sum: agg1}\n    //            {count: agg2, sum: agg2}\n    //            {count: agg3, sum: agg3}\n    //                    ...             ]}\n    groups.forEach(function (group) {\n      var item = {};\n\n      // turn the string back into individual group values\n      var groupsKeys;\n      if (typeof group.key === 'string') {\n        groupsKeys = group.key.split('|');\n      } else {\n        // shortcut for numeric non-partitioned case\n        groupsKeys = [group.key];\n      }\n\n      // add paritioning data to the item\n      groupsKeys.forEach(function (subkey, i) {\n        item[grpIdxToName[i]] = subkey;\n      });\n\n      // add aggregated data to the item\n      reduceFns.forEach(function (reduceFn, i) {\n        var name = aggRankToName[aggregateRanks[i]];\n        item[name] = reduceFn(group.value[i]);\n      });\n\n      // add an overall count\n      // becuase the filtering removes missing data points, this is the same as\n      // the count for any one of the aggregates\n      item.count = group.value[0] ? group.value[0].count : 0;\n\n      filter.data.push(item);\n    });\n  };\n}\n\n/**\n * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n * related to the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction releaseDataFilter (dataview, filter) {\n  if (filter.dimension) {\n    filter.dimension.filterAll();\n    filter.dimension.dispose();\n    delete filter.dimension;\n    delete filter.getData;\n  }\n}\n\n/**\n * Change the filter parameters for an initialized filter\n * @param {Filter} filter\n */\nfunction updateDataFilter (filter) {\n  if (filter.dimension) {\n    filter.dimension.filterFunction(filter.filterFunction());\n  }\n}\n\n/**\n * Get data for every filter, and trigger a 'newData' event\n *\n * Returns a Promise that resolves to the dataview when all data and metadata has been updated\n *\n * @param {Dataview} dataview\n * @returns {Promise}\n */\nfunction getData (dataview) {\n  dataview.filters.forEach(function (filter) {\n    if (filter.isInitialized) {\n      filter.getData();\n      filter.trigger('newData');\n    }\n  });\n\n  // update counts\n  dataview.dataTotal = dataview.crossfilter.size();\n  dataview.dataSelected = dataview.countGroup.value();\n  dataview.trigger('newMetaData');\n\n  return Promise.resolve(dataview);\n}\n\nmodule.exports = {\n  driverType: 'client',\n  scan: scan,\n  setMinMax: setMinMax,\n  setCategories: setCategories,\n  setPercentiles: setPercentiles,\n  initDataFilter: initDataFilter,\n  releaseDataFilter: releaseDataFilter,\n  updateDataFilter: updateDataFilter,\n  getData: getData\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwYy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZHJpdmVyL2NsaWVudC5qcz9kZjc3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2xpZW50IHNpZGUgZmlsdGVyaW5nIHVzaW5nIGNyb3NzZmlsdGVyXG4gKiBEdWUgdG8gbGltaXRhdGlvbiBvZiBjcm9zc2ZpbHRlciB3aXRoIGFycmF5IChvciBkYXRhIHRoYXQgaGFzIG5vIG5hdHJ1YWwgb3JkZXJpbmcpLCB0aGlzIHdpbGwgbm90IHdvcmsgYXMgZXhwZWN0ZWQ6XG4gKiAqIGRpbWVuc2lvbjogYGZ1bmN0aW9uIChkKSB7cmV0dXJuIFtkLngsIGQueSwgZC56XX1gXG4gKiAqIGdyb3VwOiBgZnVuY3Rpb24gKGQpIHtyZXR1cm4gW2QueCAvIDEwICwgZC55IC8gMTAsIGQueiAvIDEwXX1gXG4gKlxuICogVGhlcmVmb3JlLCB3ZSBwcmVmb3JtIGdyb3VwaW5nIGFscmVhZHkgaW4gdGhlIGRpbWVuc2lvbiBpdHNlbGYsIGFuZCBqb2luIHRoZSBhcnJheSB0byBhIHN0cmluZy5cbiAqIFN0cmluZ3MgaGF2ZSBhIG5hdHVyYWwgb3JkZXJpbmcgYW5kIHRodXMgY2FuIGJlIHVzZWQgYXMgZGltZW5zaW9uIHZhbHVlLlxuICogKiBkaW1lbnNpb246IGBmdW5jdGlvbiAoZCkgLT4gXCJkLngvMTB8ZC55LzEwfGQuei8xMFwiYFxuICogKiBncm91cDogYGZ1bmN0aW9uIChkKSB7cmV0dXJuIGQ7fWBcbiAqXG4gKiBAbW9kdWxlIGRyaXZlci9jbGllbnRcbiAqL1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xuXG52YXIgdXRpbGR4ID0gcmVxdWlyZSgnLi4vdXRpbC9jcm9zc2ZpbHRlcicpO1xudmFyIG1pc3ZhbCA9IHJlcXVpcmUoJy4uL3V0aWwvbWlzdmFsJyk7XG5cbnZhciBncnBJZHhUb05hbWUgPSB7MDogJ2EnLCAxOiAnYicsIDI6ICdjJywgMzogJ2QnLCA0OiAnZSd9O1xudmFyIGFnZ1JhbmtUb05hbWUgPSB7MTogJ2FhJywgMjogJ2JiJywgMzogJ2NjJywgNDogJ2RkJywgNTogJ2VlJ307XG5cbi8qKlxuICogc2V0TWluTWF4IHNldHMgdGhlIHJhbmdlIG9mIGEgY29udGludW91cyBvciB0aW1lIGZhY2V0XG4gKlxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0XG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICovXG5mdW5jdGlvbiBzZXRNaW5NYXggKGRhdGFzZXQsIGZhY2V0KSB7XG4gIC8vIHdlIG5lZWQgdGhlIHZhbHVlIGp1c3QgYmVmb3JlIGEgdHJhbnNmb3JtYXRpb24sIHNvIGJhc2VWYWx1ZUZuXG4gIHZhciB2YWxGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG5cbiAgLy8gdG8gYmUgYWJsZSB0byBtYXJrIHRoZSB2YWx1ZSBhcyBtaXNzaW5nIHdlIG5lZWQgaXQgdW5wcm9jZXNzZWQsIHNvIHJhd1ZhbHVlRm5cbiAgdmFyIHJhd1ZhbEZuID0gdXRpbGR4LnJhd1ZhbHVlRm4oZmFjZXQpO1xuXG4gIHZhciBsZXNzRm47XG4gIHZhciBtb3JlRm47XG4gIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgbGVzc0ZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYS5pc0JlZm9yZShiKSk7IH07XG4gICAgbW9yZUZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYi5pc0JlZm9yZShhKSk7IH07XG4gIH0gZWxzZSB7XG4gICAgbGVzc0ZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYSA8IGIpOyB9O1xuICAgIG1vcmVGbiA9IGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiAoYiA9PT0gbWlzdmFsIHx8IGEgPiBiKTsgfTtcbiAgfVxuXG4gIHZhciBtaW52YWwgPSBtaXN2YWw7XG4gIHZhciByYXdNaW4gPSBtaXN2YWw7XG5cbiAgdmFyIG1heHZhbCA9IG1pc3ZhbDtcbiAgdmFyIHJhd01heCA9IG1pc3ZhbDtcblxuICBkYXRhc2V0LmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgIHZhciByYXdWID0gcmF3VmFsRm4oZCk7XG4gICAgdmFyIHYgPSB2YWxGbihkKTtcblxuICAgIGlmICh2ICE9PSBtaXN2YWwpIHtcbiAgICAgIGlmIChsZXNzRm4odiwgbWludmFsKSkge1xuICAgICAgICBtaW52YWwgPSB2O1xuICAgICAgICByYXdNaW4gPSByYXdWO1xuICAgICAgfVxuICAgICAgaWYgKG1vcmVGbih2LCBtYXh2YWwpKSB7XG4gICAgICAgIG1heHZhbCA9IHY7XG4gICAgICAgIHJhd01heCA9IHJhd1Y7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBpZiAobWludmFsICE9PSBtaXN2YWwpIHtcbiAgICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgICBmYWNldC5taW52YWxBc1RleHQgPSBtaW52YWwudG9TdHJpbmcoKTtcbiAgICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICAgIGZhY2V0Lm1pbnZhbEFzVGV4dCA9IG1pbnZhbC50b0lTT1N0cmluZygpO1xuICAgIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgICAgZmFjZXQubWludmFsQXNUZXh0ID0gbWludmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGZhY2V0LnJhd01pbnZhbCA9IHJhd01pbjtcbiAgfSBlbHNlIHtcbiAgICBmYWNldC5taW52YWxBc1RleHQgPSAnJztcbiAgICBmYWNldC5yYXdNaW52YWwgPSBtaXN2YWw7XG4gIH1cblxuICBpZiAobWF4dmFsICE9PSBtaXN2YWwpIHtcbiAgICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgICBmYWNldC5tYXh2YWxBc1RleHQgPSBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IG1heHZhbC50b0lTT1N0cmluZygpO1xuICAgIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgICAgZmFjZXQubWF4dmFsQXNUZXh0ID0gbWF4dmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGZhY2V0LnJhd01heHZhbCA9IHJhd01heDtcbiAgfSBlbHNlIHtcbiAgICBmYWNldC5tYXh2YWxBc1RleHQgPSAnJztcbiAgICBmYWNldC5yYXdNYXh2YWwgPSBtaXN2YWw7XG4gIH1cbn1cblxuLyoqXG4gKiBzZXRDYXRlZ29yaWVzIGZpbmRzIGZpbmRzIGFsbCB2YWx1ZXMgb24gYW4gb3JkaW5hbCAoY2F0ZWdvcmlhbCkgYXhpc1xuICogVXBkYXRlcyB0aGUgY2F0ZWdvcmlhbFRyYW5zZm9ybSBvZiB0aGUgZmFjZXRcbiAqXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXRcbiAqIEBwYXJhbSB7RmFjZXR9IGZhY2V0XG4gKi9cbmZ1bmN0aW9uIHNldENhdGVnb3JpZXMgKGRhdGFzZXQsIGZhY2V0KSB7XG4gIC8vIHdlIG5lZWQgdGhlIHZhbHVlIGp1c3QgYmVmb3JlIGEgdHJhbnNmb3JtYXRpb24sIHNvIGJhc2VWYWx1ZUZuXG4gIHZhciB2YWxGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG5cbiAgdmFyIHAgPSB7fTtcbiAgdmFyIFBsZW5ndGggPSAwO1xuICBkYXRhc2V0LmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZCwgaSkge1xuICAgIHZhciB2YWxzID0gdmFsRm4oZCk7XG4gICAgaWYgKHZhbHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgdmFscy5mb3JFYWNoKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgaWYgKHAuaGFzT3duUHJvcGVydHkodmFsKSkge1xuICAgICAgICAgIHBbdmFsXSsrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChQbGVuZ3RoIDwgNzUpIHsgLy8gTk9URTogbGltaXQgdG8gbWF4aW1hbGx5IDc1IGNhdGVnb3JpZXNcbiAgICAgICAgICAgIHBbdmFsXSA9IDE7XG4gICAgICAgICAgICBQbGVuZ3RoKys7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHAuaGFzT3duUHJvcGVydHkodmFscykpIHtcbiAgICAgICAgcFt2YWxzXSsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKFBsZW5ndGggPCA3NSkgeyAvLyBOT1RFOiBsaW1pdCB0byBtYXhpbWFsbHkgNzUgY2F0ZWdvcmllc1xuICAgICAgICAgIHBbdmFsc10gPSAxO1xuICAgICAgICAgIFBsZW5ndGgrKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5yZXNldCgpO1xuXG4gIE9iamVjdC5rZXlzKHApLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIC8vIFRPRE86IG1pc3NpbmcgZGF0YSBzaG91bGQgYmUgbWFwcGVkIHRvIGEgbWlzdmFsIGZyb20gbWlzdmFsQXNUZXh0XG4gICAgdmFyIGtleUFzU3RyaW5nID0ga2V5LnRvU3RyaW5nKCk7XG4gICAgdmFyIGdyb3VwQXNTdHJpbmcgPSBrZXlBc1N0cmluZztcblxuICAgIGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuYWRkKHtleHByZXNzaW9uOiBrZXlBc1N0cmluZywgY291bnQ6IHBba2V5XSwgZ3JvdXA6IGdyb3VwQXNTdHJpbmd9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIDEwMCBwZXJjZW50aWxlcyAoaWUuIDEsMiwzLDQgZXRjLiksIGFuZCBpbml0aWFsaXplIHRoZSBgZmFjZXQuY29udGludW91c1RyYW5zZm9ybWBcbiAqIHRvIGFuIGFwcHJveGltYXRlIHBlcmNlbnRpbGUgbWFwcGluZy5cbiAqIFVzZSB0aGUgcmVjb21tZW5kZWQgbWV0aG9kIGZyb20gW05JU1RdKGh0dHA6Ly93d3cuaXRsLm5pc3QuZ292L2Rpdjg5OC9oYW5kYm9vay9wcmMvc2VjdGlvbjIvcHJjMjYyLmh0bSlcbiAqIFNlZSBhbHNvIHRoZSBkaXNjdXNzaW9uIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1BlcmNlbnRpbGUpXG4gKlxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0XG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICovXG5mdW5jdGlvbiBzZXRQZXJjZW50aWxlcyAoZGF0YXNldCwgZmFjZXQpIHtcbiAgLy8gd2UgbmVlZCB0aGUgdmFsdWUganVzdCBiZWZvcmUgYSB0cmFuc2Zvcm1hdGlvbiwgc28gYmFzZVZhbHVlRm5cbiAgdmFyIGJhc2V2YWx1ZUZuID0gdXRpbGR4LmJhc2VWYWx1ZUZuKGZhY2V0KTtcbiAgdmFyIGRhdGEgPSBkYXRhc2V0LmRhdGE7XG5cbiAgZGF0YS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgdmFyIHZhbEEgPSBiYXNldmFsdWVGbihhKTtcbiAgICB2YXIgdmFsQiA9IGJhc2V2YWx1ZUZuKGIpO1xuXG4gICAgaWYgKHZhbEEgPT09IHZhbEIpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpZiAodmFsQSA9PT0gbWlzdmFsKSB7XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIGlmICh2YWxCID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIGlmICh2YWxBIDwgdmFsQikge1xuICAgICAgcmV0dXJuIC0xO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH0pO1xuXG4gIHZhciB0ZiA9IGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm07XG4gIHZhciB4LCBpO1xuXG4gIC8vIGRyb3AgbWlzc2luZyB2YWx1ZXMsIHdoaWNoIHNob3VsZCBiZSBzb3J0ZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZSBhcnJheVxuICBpID0gMDtcbiAgd2hpbGUgKGJhc2V2YWx1ZUZuKGRhdGFbaV0pID09PSBtaXN2YWwgJiYgaSA8IGRhdGEubGVuZ3RoKSB7XG4gICAgaSsrO1xuICB9XG4gIGRhdGEuc3BsaWNlKDAsIGkpO1xuXG4gIC8vIHN0YXJ0IGNsZWFuXG4gIHRmLnJlc2V0KCk7XG5cbiAgLy8gYWRkIG1pbmltdW0gdmFsdWUgYXMgY29udHJvbCBwb2ludHMgcDAgYW5kIHAxXG4gIHRmLmNwcy5hZGQoe3g6IGJhc2V2YWx1ZUZuKGRhdGFbMF0pLCBmeDogMH0pO1xuICB0Zi5jcHMuYWRkKHt4OiBiYXNldmFsdWVGbihkYXRhWzBdKSwgZng6IDB9KTtcblxuICB2YXIgcCwgdmFsdWU7XG4gIGZvciAocCA9IDE7IHAgPCAxMDA7IHArKykge1xuICAgIHggPSAocCAqIDAuMDEpICogKGRhdGEubGVuZ3RoICsgMSkgLSAxOyAvLyBpbmRleGluZyBzdGFydHMgYXQgemVybywgbm90IGF0IG9uZVxuICAgIGkgPSBNYXRoLnRydW5jKHgpO1xuICAgIHZhbHVlID0gKDEgLSB4ICsgaSkgKiBiYXNldmFsdWVGbihkYXRhW2ldKSArICh4IC0gaSkgKiBiYXNldmFsdWVGbihkYXRhW2kgKyAxXSk7XG4gICAgdGYuY3BzLmFkZCh7eDogdmFsdWUsIGZ4OiBwfSk7XG4gIH1cblxuICAvLyBhZGQgbWF4aW11bSB2YWx1ZSBhcyBwMTAxIGFuZCBwMTAyXG4gIHRmLmNwcy5hZGQoe3g6IGJhc2V2YWx1ZUZuKGRhdGFbZGF0YS5sZW5ndGggLSAxXSksIGZ4OiAxMDB9KTtcbiAgdGYuY3BzLmFkZCh7eDogYmFzZXZhbHVlRm4oZGF0YVtkYXRhLmxlbmd0aCAtIDFdKSwgZng6IDEwMH0pO1xuXG4gIHRmLnR5cGUgPSAncGVyY2VudGlsZXMnO1xufVxuXG4vKipcbiAqIEF1dG9jb25maWd1cmUgYSBkYXRhc2V0OlxuICogMS4gcGljayAxMCByYW5kb20gZWxlbWVudHNcbiAqIDIuIGNyZWF0ZSBmYWNldHMgZm9yIHRoZWlyIHByb3BlcnRpZXNcbiAqIDMuIGFkZCBmYWNldHMnIHZhbHVlcyBvdmVyIHRoZSBzYW1wbGUgdG8gdGhlIGZhY2V0LmRlc2NyaXB0aW9uXG4gKiA0LiBzZXQgcmFuZ2Ugb3IgY2F0ZWdvcmllc1xuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICovXG5mdW5jdGlvbiBzY2FuIChkYXRhc2V0KSB7XG4gIGZ1bmN0aW9uIGZhY2V0RXhpc3RzIChmYWNldHMsIHBhdGgpIHtcbiAgICB2YXIgZXhpc3RzID0gZmFsc2U7XG4gICAgZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgIGlmIChmLmFjY2Vzc29yID09PSBwYXRoIHx8IGYuYWNjZXNzb3IgPT09IHBhdGggKyAnW10nKSB7XG4gICAgICAgIGV4aXN0cyA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGV4aXN0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFZhbHVlICh2YWx1ZXMsIHYsIG1pc3NpbmcpIHtcbiAgICBpZiAodiA9PT0gbWlzdmFsKSB7XG4gICAgICB2ID0gbWlzc2luZztcbiAgICB9XG4gICAgaWYgKHZhbHVlcy5pbmRleE9mKHYpID09PSAtMSkge1xuICAgICAgdmFsdWVzLnB1c2godik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZ3Vlc3NUeXBlICh2YWx1ZXMpIHtcbiAgICB2YXIgbXl0eXBlID0ge1xuICAgICAgY29udGludW91czogMCxcbiAgICAgIHRleHQ6IDAsXG4gICAgICBkYXRldGltZTogMCxcbiAgICAgIGR1cmF0aW9uOiAwLFxuICAgICAgY2F0ZWdvcmlhbDogMFxuICAgIH07XG4gICAgdmFsdWVzLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBpZiAobW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpLmlzVmFsaWQoKSkge1xuICAgICAgICAvLyBcIjIwMTYtMDgtMTcgMTc6MjU6MDArMDFcIlxuICAgICAgICBteXR5cGUuZGF0ZXRpbWUrKztcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgKG1vbWVudC5kdXJhdGlvbih2YWx1ZSkuYXNNaWxsaXNlY29uZHMoKSAhPT0gMCkgJiZcbiAgICAgICAgICAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgJiZcbiAgICAgICAgICAodmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSkge1xuICAgICAgICAvLyBcIlAxMFlcIlxuICAgICAgICBteXR5cGUuZHVyYXRpb24rKztcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gK3ZhbHVlKSB7ICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgICAgICAvLyBcIjEwXCIgb3IgMTBcbiAgICAgICAgbXl0eXBlLmNvbnRpbnVvdXMrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFwiaGVsbG8gd29ybGRcIlxuICAgICAgICBteXR5cGUuY2F0ZWdvcmlhbCsrO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gZ2V0IGZhY2V0VHlwZSB3aXRoIGhpZ2hlc3QgY291bnRcbiAgICB2YXIgbWF4ID0gLTE7XG4gICAgdmFyIGZhY2V0VHlwZTtcbiAgICBPYmplY3Qua2V5cyhteXR5cGUpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgaWYgKG15dHlwZVtrZXldID4gbWF4KSB7XG4gICAgICAgIGZhY2V0VHlwZSA9IGtleTtcbiAgICAgICAgbWF4ID0gbXl0eXBlW2tleV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZmFjZXRUeXBlO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJ5RmFjZXQgKGZhY2V0cywgZGF0YSwgcGF0aCwgdmFsdWUpIHtcbiAgICAvLyBDaGVjayBmb3IgZXhpc3RlbmNlXG4gICAgaWYgKGZhY2V0RXhpc3RzKGZhY2V0cywgcGF0aCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYSBuZXcgZmFjZXRcbiAgICB2YXIgZmFjZXQgPSBmYWNldHMuYWRkKHtcbiAgICAgIG5hbWU6IHBhdGgsXG4gICAgICBhY2Nlc3NvcjogcGF0aCxcbiAgICAgIHR5cGU6ICd0ZXh0J1xuICAgIH0pO1xuXG4gICAgLy8gU2FtcGxlIHZhbHVlc1xuICAgIHZhciBiYXNlVmFsdWVGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIHZhciBpc0FycmF5ID0gZmFsc2U7XG5cbiAgICBkYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGJhc2VWYWx1ZUZuKGQpO1xuICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgaXNBcnJheSA9IHRydWU7XG4gICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICBhZGRWYWx1ZSh2YWx1ZXMsIHYsIGZhY2V0Lm1pc3ZhbFswXSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWRkVmFsdWUodmFsdWVzLCB2YWx1ZSwgZmFjZXQubWlzdmFsWzBdKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFJlY29uZmlndXJlIGZhY2V0XG4gICAgZmFjZXQuYWNjZXNzb3IgPSBpc0FycmF5ID8gZmFjZXQuYWNjZXNzb3IgKyAnW10nIDogZmFjZXQuYWNjZXNzb3I7XG4gICAgZmFjZXQudHlwZSA9IGd1ZXNzVHlwZSh2YWx1ZXMpO1xuICAgIGZhY2V0LmRlc2NyaXB0aW9uID0gdmFsdWVzLmpvaW4oJywgJykubWF0Y2goJ14uezAsNDB9JykgKyAnLi4uJztcbiAgICBmYWNldC5pc0FjdGl2ZSA9IHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiByZWN1cnNlIChmYWNldHMsIGRhdGEsIHBhdGgsIHRyZWUpIHtcbiAgICB2YXIgcHJvcHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0cmVlKTtcbiAgICBwcm9wcy5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICB2YXIgc3VicGF0aDtcbiAgICAgIGlmIChwYXRoKSB7XG4gICAgICAgIHN1YnBhdGggPSBwYXRoICsgJyMjJyArIG5hbWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdWJwYXRoID0gbmFtZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRyZWVbbmFtZV0gaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAvLyBhZGQgYW4gYXJyYXkgYXMgYSBpdHNlbGYgYXMgYSBmYWNldCwgaWUuIGxhYmVsc2V0LCB0byBwcmV2ZW50IGFkZGluZyBlYWNoIGVsZW1lbnQgYXMgc2VwYXJhdGUgZmFjZXRcbiAgICAgICAgLy8gYWxzbyBhZGQgdGhlIGFycmF5IGxlbmd0aCBhcyBmYWNldFxuICAgICAgICB0cnlGYWNldChmYWNldHMsIGRhdGEsIHN1YnBhdGgsIHRyZWVbbmFtZV0pO1xuICAgICAgICB0cnlGYWNldChmYWNldHMsIGRhdGEsIHN1YnBhdGggKyAnLmxlbmd0aCcsIHRyZWVbbmFtZV0ubGVuZ3RoKTtcbiAgICAgIH0gZWxzZSBpZiAodHJlZVtuYW1lXSBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgICAgICAvLyByZWN1cnNlIGludG8gb2JqZWN0c1xuICAgICAgICByZWN1cnNlKGZhY2V0cywgZGF0YSwgc3VicGF0aCwgdHJlZVtuYW1lXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBhZGQgc3RyaW5ncyBhbmQgbnVtYmVycyBhcyBmYWNldHNcbiAgICAgICAgdHJ5RmFjZXQoZmFjZXRzLCBkYXRhLCBzdWJwYXRoLCB0cmVlW25hbWVdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIEFkZCBmYWNldHNcbiAgdmFyIGRhdGEgPSBkYXRhc2V0LmRhdGEuc2xpY2UoMCwgMTApO1xuICBkYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICByZWN1cnNlKGRhdGFzZXQuZmFjZXRzLCBkYXRhLCAnJywgZCk7XG4gIH0pO1xuXG4gIGRhdGFzZXQuZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgaWYgKGZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgc2V0Q2F0ZWdvcmllcyhkYXRhc2V0LCBmYWNldCk7XG4gICAgfSBlbHNlIGlmIChmYWNldC5pc0NvbnRpbnVvdXMgfHwgZmFjZXQuaXNEYXRldGltZSkge1xuICAgICAgc2V0TWluTWF4KGRhdGFzZXQsIGZhY2V0KTtcbiAgICB9XG4gIH0pO1xuICBkYXRhc2V0LnRyaWdnZXIoJ3N5bmNGYWNldHMnKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gaW5pdERhdGFGaWx0ZXIgKGRhdGF2aWV3LCBmaWx0ZXIpIHtcbiAgdmFyIGZhY2V0O1xuXG4gIC8vIHVzZSB0aGUgcGFydGl0aW9ucyBhcyBncm91cHM6XG4gIHZhciBncm91cEZucyA9IFtdO1xuICBmaWx0ZXIucGFydGl0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgICBmYWNldCA9IGRhdGF2aWV3LmZhY2V0cy5nZXQocGFydGl0aW9uLmZhY2V0TmFtZSwgJ25hbWUnKTtcbiAgICB2YXIgdmFsdWVGbiA9IHV0aWxkeC52YWx1ZUZuKGZhY2V0KTtcbiAgICB2YXIgZ3JvdXBGbiA9IHV0aWxkeC5ncm91cEZuKHBhcnRpdGlvbik7XG5cbiAgICB2YXIgcmFuayA9IHBhcnRpdGlvbi5yYW5rO1xuICAgIGdyb3VwRm5zW3JhbmsgLSAxXSA9IGZ1bmN0aW9uIChkKSB7XG4gICAgICByZXR1cm4gZ3JvdXBGbih2YWx1ZUZuKGQpKTtcbiAgICB9O1xuICB9KTtcblxuICAvLyBhbmQgdGhlbiBjcmVhdGUga2V5cyBmcm9tIHRoZSBncm91cCB2YWx1ZXNcbiAgdmFyIGdyb3Vwc0tleXMgPSBmdW5jdGlvbiAoZCkge1xuICAgIHZhciBrZXlzID0gW107XG5cbiAgICBncm91cEZucy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cEZuKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gZ3JvdXBGbihkKTtcbiAgICAgIHZhciBuZXdLZXlzID0gW107XG4gICAgICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgbmV3S2V5cyA9IHJlc3VsdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdLZXlzID0gW3Jlc3VsdF07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAob2xkS2V5KSB7XG4gICAgICAgICAgICByZXN1bHQuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgIG5ld0tleXMucHVzaChvbGRLZXkgKyAnfCcgKyBrZXkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChvbGRLZXkpIHtcbiAgICAgICAgICAgIG5ld0tleXMucHVzaChvbGRLZXkgKyAnfCcgKyByZXN1bHQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBrZXlzID0gbmV3S2V5cztcbiAgICB9KTtcbiAgICByZXR1cm4ga2V5cztcbiAgfTtcblxuICAvLyBzZXQgdXAgdGhlIGZhY2V0IHZhbHVlRm5zIHRvIGFnZ3JlZ2F0ZSBvdmVyXG4gIC8vIGFuZCB0aGUgcmVkdWN0aW9uIGZ1bmN0aW9ucyBmb3IgdGhlbVxuICB2YXIgYWdncmVnYXRlRm5zID0gW107XG4gIHZhciBhZ2dyZWdhdGVSYW5rcyA9IFtdO1xuICB2YXIgcmVkdWNlRm5zID0gW107XG4gIGZpbHRlci5hZ2dyZWdhdGVzLmZvckVhY2goZnVuY3Rpb24gKGFnZ3JlZ2F0ZSkge1xuICAgIGZhY2V0ID0gZGF0YXZpZXcuZmFjZXRzLmdldChhZ2dyZWdhdGUuZmFjZXROYW1lLCAnbmFtZScpO1xuICAgIGFnZ3JlZ2F0ZVJhbmtzLnB1c2goYWdncmVnYXRlLnJhbmspO1xuICAgIGFnZ3JlZ2F0ZUZucy5wdXNoKHV0aWxkeC52YWx1ZUZuKGZhY2V0KSk7XG4gICAgcmVkdWNlRm5zLnB1c2godXRpbGR4LnJlZHVjZUZuKGFnZ3JlZ2F0ZSkpO1xuICB9KTtcblxuICAvLyBzZXR1cCB0aGUgY3Jvc3NmaWx0ZXIgZGltZW5zaW9ucyBhbmQgZ3JvdXBzXG4gIGZpbHRlci5kaW1lbnNpb24gPSBkYXRhdmlldy5jcm9zc2ZpbHRlci5kaW1lbnNpb24oZnVuY3Rpb24gKGQpIHtcbiAgICByZXR1cm4gZ3JvdXBzS2V5cyhkKTtcbiAgfSwgdHJ1ZSk7XG4gIHZhciBjcm9zc2ZpbHRlckdyb3VwID0gZmlsdGVyLmRpbWVuc2lvbi5ncm91cChmdW5jdGlvbiAoZCkgeyByZXR1cm4gZDsgfSk7XG5cbiAgY3Jvc3NmaWx0ZXJHcm91cC5yZWR1Y2UoXG4gICAgLy8gYWRkXG4gICAgZnVuY3Rpb24gKHAsIGQpIHtcbiAgICAgIGlmIChhZ2dyZWdhdGVGbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHBbMF0gPSBwWzBdID8gcFswXSA6IHtjb3VudDogMH07XG4gICAgICAgIHBbMF0uY291bnQgKz0gMTtcbiAgICAgIH1cblxuICAgICAgYWdncmVnYXRlRm5zLmZvckVhY2goZnVuY3Rpb24gKGFnZ3JlZ2F0ZUZuLCBpKSB7XG4gICAgICAgIHZhciB2YWwgPSBhZ2dyZWdhdGVGbihkKTtcbiAgICAgICAgaWYgKHZhbCAhPT0gbWlzdmFsKSB7XG4gICAgICAgICAgdmFsID0gcGFyc2VGbG9hdCh2YWwpO1xuICAgICAgICAgIHBbaV0gPSBwW2ldIHx8IHtjb3VudDogMCwgc3VtOiAwLCBzdW1zcXVhcmVzOiAwfTtcbiAgICAgICAgICBwW2ldLmNvdW50ICs9IDE7XG4gICAgICAgICAgcFtpXS5zdW0gKz0gdmFsO1xuICAgICAgICAgIHBbaV0uc3Vtc3F1YXJlcyArPSB2YWwgKiB2YWw7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHA7XG4gICAgfSxcbiAgICAvLyBzdWJ0cmFjdFxuICAgIGZ1bmN0aW9uIChwLCBkKSB7XG4gICAgICBpZiAoYWdncmVnYXRlRm5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBwWzBdID0gcFswXSA/IHBbMF0gOiB7Y291bnQ6IDB9O1xuICAgICAgICBwWzBdLmNvdW50IC09IDE7XG4gICAgICB9XG5cbiAgICAgIGFnZ3JlZ2F0ZUZucy5mb3JFYWNoKGZ1bmN0aW9uIChhZ2dyZWdhdGVGbiwgaSkge1xuICAgICAgICB2YXIgdmFsID0gYWdncmVnYXRlRm4oZCk7XG4gICAgICAgIGlmICh2YWwgIT09IG1pc3ZhbCkge1xuICAgICAgICAgIHZhbCA9IHBhcnNlRmxvYXQodmFsKTtcbiAgICAgICAgICBwW2ldID0gcFtpXSB8fCB7Y291bnQ6IDAsIHN1bTogMCwgc3Vtc3F1YXJlczogMH07XG4gICAgICAgICAgcFtpXS5jb3VudCAtPSAxO1xuICAgICAgICAgIHBbaV0uc3VtIC09IHZhbDtcbiAgICAgICAgICBwW2ldLnN1bXNxdWFyZXMgLT0gdmFsICogdmFsO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBwO1xuICAgIH0sXG4gICAgLy8gaW5pdGlhbGl6ZVxuICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICk7XG5cbiAgZmlsdGVyLmdldERhdGEgPSBmdW5jdGlvbiAoKSB7XG4gICAgZmlsdGVyLmRhdGEgPSBbXTtcblxuICAgIC8vIEdldCBkYXRhIGZyb20gY3Jvc3NmaWx0ZXJcbiAgICB2YXIgZ3JvdXBzID0gY3Jvc3NmaWx0ZXJHcm91cC5hbGwoKTtcblxuICAgIC8vIHsga2V5OiBcImdyb3VwMXxncm91cDJ8Li4uXCIsXG4gICAgLy8gICB2YWx1ZTogWyB7Y291bnQ6IGFnZzEsIHN1bTogYWdnMX1cbiAgICAvLyAgICAgICAgICAgIHtjb3VudDogYWdnMiwgc3VtOiBhZ2cyfVxuICAgIC8vICAgICAgICAgICAge2NvdW50OiBhZ2czLCBzdW06IGFnZzN9XG4gICAgLy8gICAgICAgICAgICAgICAgICAgIC4uLiAgICAgICAgICAgICBdfVxuICAgIGdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgdmFyIGl0ZW0gPSB7fTtcblxuICAgICAgLy8gdHVybiB0aGUgc3RyaW5nIGJhY2sgaW50byBpbmRpdmlkdWFsIGdyb3VwIHZhbHVlc1xuICAgICAgdmFyIGdyb3Vwc0tleXM7XG4gICAgICBpZiAodHlwZW9mIGdyb3VwLmtleSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZ3JvdXBzS2V5cyA9IGdyb3VwLmtleS5zcGxpdCgnfCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gc2hvcnRjdXQgZm9yIG51bWVyaWMgbm9uLXBhcnRpdGlvbmVkIGNhc2VcbiAgICAgICAgZ3JvdXBzS2V5cyA9IFtncm91cC5rZXldO1xuICAgICAgfVxuXG4gICAgICAvLyBhZGQgcGFyaXRpb25pbmcgZGF0YSB0byB0aGUgaXRlbVxuICAgICAgZ3JvdXBzS2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChzdWJrZXksIGkpIHtcbiAgICAgICAgaXRlbVtncnBJZHhUb05hbWVbaV1dID0gc3Via2V5O1xuICAgICAgfSk7XG5cbiAgICAgIC8vIGFkZCBhZ2dyZWdhdGVkIGRhdGEgdG8gdGhlIGl0ZW1cbiAgICAgIHJlZHVjZUZucy5mb3JFYWNoKGZ1bmN0aW9uIChyZWR1Y2VGbiwgaSkge1xuICAgICAgICB2YXIgbmFtZSA9IGFnZ1JhbmtUb05hbWVbYWdncmVnYXRlUmFua3NbaV1dO1xuICAgICAgICBpdGVtW25hbWVdID0gcmVkdWNlRm4oZ3JvdXAudmFsdWVbaV0pO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIGFkZCBhbiBvdmVyYWxsIGNvdW50XG4gICAgICAvLyBiZWN1YXNlIHRoZSBmaWx0ZXJpbmcgcmVtb3ZlcyBtaXNzaW5nIGRhdGEgcG9pbnRzLCB0aGlzIGlzIHRoZSBzYW1lIGFzXG4gICAgICAvLyB0aGUgY291bnQgZm9yIGFueSBvbmUgb2YgdGhlIGFnZ3JlZ2F0ZXNcbiAgICAgIGl0ZW0uY291bnQgPSBncm91cC52YWx1ZVswXSA/IGdyb3VwLnZhbHVlWzBdLmNvdW50IDogMDtcblxuICAgICAgZmlsdGVyLmRhdGEucHVzaChpdGVtKTtcbiAgICB9KTtcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGUgb3Bwb3NpdGUgb3IgaW5pdERhdGFGaWx0ZXIsIGl0IHNob3VsZCByZW1vdmUgdGhlIGZpbHRlciBhbmQgZGVhbGxvY2F0ZSBvdGhlciBjb25maWd1cmF0aW9uXG4gKiByZWxhdGVkIHRvIHRoZSBmaWx0ZXIuXG4gKiBAcGFyYW0ge0RhdGF2aWV3fSBkYXRhdmlld1xuICogQHBhcmFtIHtGaWx0ZXJ9IGZpbHRlclxuICovXG5mdW5jdGlvbiByZWxlYXNlRGF0YUZpbHRlciAoZGF0YXZpZXcsIGZpbHRlcikge1xuICBpZiAoZmlsdGVyLmRpbWVuc2lvbikge1xuICAgIGZpbHRlci5kaW1lbnNpb24uZmlsdGVyQWxsKCk7XG4gICAgZmlsdGVyLmRpbWVuc2lvbi5kaXNwb3NlKCk7XG4gICAgZGVsZXRlIGZpbHRlci5kaW1lbnNpb247XG4gICAgZGVsZXRlIGZpbHRlci5nZXREYXRhO1xuICB9XG59XG5cbi8qKlxuICogQ2hhbmdlIHRoZSBmaWx0ZXIgcGFyYW1ldGVycyBmb3IgYW4gaW5pdGlhbGl6ZWQgZmlsdGVyXG4gKiBAcGFyYW0ge0ZpbHRlcn0gZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZURhdGFGaWx0ZXIgKGZpbHRlcikge1xuICBpZiAoZmlsdGVyLmRpbWVuc2lvbikge1xuICAgIGZpbHRlci5kaW1lbnNpb24uZmlsdGVyRnVuY3Rpb24oZmlsdGVyLmZpbHRlckZ1bmN0aW9uKCkpO1xuICB9XG59XG5cbi8qKlxuICogR2V0IGRhdGEgZm9yIGV2ZXJ5IGZpbHRlciwgYW5kIHRyaWdnZXIgYSAnbmV3RGF0YScgZXZlbnRcbiAqXG4gKiBSZXR1cm5zIGEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkYXRhdmlldyB3aGVuIGFsbCBkYXRhIGFuZCBtZXRhZGF0YSBoYXMgYmVlbiB1cGRhdGVkXG4gKlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEByZXR1cm5zIHtQcm9taXNlfVxuICovXG5mdW5jdGlvbiBnZXREYXRhIChkYXRhdmlldykge1xuICBkYXRhdmlldy5maWx0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpbHRlcikge1xuICAgIGlmIChmaWx0ZXIuaXNJbml0aWFsaXplZCkge1xuICAgICAgZmlsdGVyLmdldERhdGEoKTtcbiAgICAgIGZpbHRlci50cmlnZ2VyKCduZXdEYXRhJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyB1cGRhdGUgY291bnRzXG4gIGRhdGF2aWV3LmRhdGFUb3RhbCA9IGRhdGF2aWV3LmNyb3NzZmlsdGVyLnNpemUoKTtcbiAgZGF0YXZpZXcuZGF0YVNlbGVjdGVkID0gZGF0YXZpZXcuY291bnRHcm91cC52YWx1ZSgpO1xuICBkYXRhdmlldy50cmlnZ2VyKCduZXdNZXRhRGF0YScpO1xuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoZGF0YXZpZXcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZHJpdmVyVHlwZTogJ2NsaWVudCcsXG4gIHNjYW46IHNjYW4sXG4gIHNldE1pbk1heDogc2V0TWluTWF4LFxuICBzZXRDYXRlZ29yaWVzOiBzZXRDYXRlZ29yaWVzLFxuICBzZXRQZXJjZW50aWxlczogc2V0UGVyY2VudGlsZXMsXG4gIGluaXREYXRhRmlsdGVyOiBpbml0RGF0YUZpbHRlcixcbiAgcmVsZWFzZURhdGFGaWx0ZXI6IHJlbGVhc2VEYXRhRmlsdGVyLFxuICB1cGRhdGVEYXRhRmlsdGVyOiB1cGRhdGVEYXRhRmlsdGVyLFxuICBnZXREYXRhOiBnZXREYXRhXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///720c\n")},"780f":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {\n/**\n * Module dependencies.\n */\n\nvar parseuri = __webpack_require__(/*! parseuri */ \"64a0\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:url');\n\n/**\n * Module exports.\n */\n\nmodule.exports = url;\n\n/**\n * URL parser.\n *\n * @param {String} url\n * @param {Object} An object meant to mimic window.location.\n *                 Defaults to window.location.\n * @api public\n */\n\nfunction url (uri, loc) {\n  var obj = uri;\n\n  // default to window.location\n  loc = loc || global.location;\n  if (null == uri) uri = loc.protocol + '//' + loc.host;\n\n  // relative path support\n  if ('string' === typeof uri) {\n    if ('/' === uri.charAt(0)) {\n      if ('/' === uri.charAt(1)) {\n        uri = loc.protocol + uri;\n      } else {\n        uri = loc.host + uri;\n      }\n    }\n\n    if (!/^(https?|wss?):\\/\\//.test(uri)) {\n      debug('protocol-less url %s', uri);\n      if ('undefined' !== typeof loc) {\n        uri = loc.protocol + '//' + uri;\n      } else {\n        uri = 'https://' + uri;\n      }\n    }\n\n    // parse\n    debug('parse %s', uri);\n    obj = parseuri(uri);\n  }\n\n  // make sure we treat `localhost:80` and `localhost` equally\n  if (!obj.port) {\n    if (/^(http|ws)$/.test(obj.protocol)) {\n      obj.port = '80';\n    } else if (/^(http|ws)s$/.test(obj.protocol)) {\n      obj.port = '443';\n    }\n  }\n\n  obj.path = obj.path || '/';\n\n  var ipv6 = obj.host.indexOf(':') !== -1;\n  var host = ipv6 ? '[' + obj.host + ']' : obj.host;\n\n  // define unique id\n  obj.id = obj.protocol + '://' + host + ':' + obj.port;\n  // define href\n  obj.href = obj.protocol + '://' + host + (loc && loc.port === obj.port ? '' : (':' + obj.port));\n\n  return obj;\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzgwZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvdXJsLmpzPzAwMGMiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNldXJpID0gcmVxdWlyZSgncGFyc2V1cmknKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6dXJsJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSB1cmw7XG5cbi8qKlxuICogVVJMIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge09iamVjdH0gQW4gb2JqZWN0IG1lYW50IHRvIG1pbWljIHdpbmRvdy5sb2NhdGlvbi5cbiAqICAgICAgICAgICAgICAgICBEZWZhdWx0cyB0byB3aW5kb3cubG9jYXRpb24uXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIHVybCAodXJpLCBsb2MpIHtcbiAgdmFyIG9iaiA9IHVyaTtcblxuICAvLyBkZWZhdWx0IHRvIHdpbmRvdy5sb2NhdGlvblxuICBsb2MgPSBsb2MgfHwgZ2xvYmFsLmxvY2F0aW9uO1xuICBpZiAobnVsbCA9PSB1cmkpIHVyaSA9IGxvYy5wcm90b2NvbCArICcvLycgKyBsb2MuaG9zdDtcblxuICAvLyByZWxhdGl2ZSBwYXRoIHN1cHBvcnRcbiAgaWYgKCdzdHJpbmcnID09PSB0eXBlb2YgdXJpKSB7XG4gICAgaWYgKCcvJyA9PT0gdXJpLmNoYXJBdCgwKSkge1xuICAgICAgaWYgKCcvJyA9PT0gdXJpLmNoYXJBdCgxKSkge1xuICAgICAgICB1cmkgPSBsb2MucHJvdG9jb2wgKyB1cmk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cmkgPSBsb2MuaG9zdCArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIS9eKGh0dHBzP3x3c3M/KTpcXC9cXC8vLnRlc3QodXJpKSkge1xuICAgICAgZGVidWcoJ3Byb3RvY29sLWxlc3MgdXJsICVzJywgdXJpKTtcbiAgICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGxvYykge1xuICAgICAgICB1cmkgPSBsb2MucHJvdG9jb2wgKyAnLy8nICsgdXJpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdXJpID0gJ2h0dHBzOi8vJyArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBwYXJzZVxuICAgIGRlYnVnKCdwYXJzZSAlcycsIHVyaSk7XG4gICAgb2JqID0gcGFyc2V1cmkodXJpKTtcbiAgfVxuXG4gIC8vIG1ha2Ugc3VyZSB3ZSB0cmVhdCBgbG9jYWxob3N0OjgwYCBhbmQgYGxvY2FsaG9zdGAgZXF1YWxseVxuICBpZiAoIW9iai5wb3J0KSB7XG4gICAgaWYgKC9eKGh0dHB8d3MpJC8udGVzdChvYmoucHJvdG9jb2wpKSB7XG4gICAgICBvYmoucG9ydCA9ICc4MCc7XG4gICAgfSBlbHNlIGlmICgvXihodHRwfHdzKXMkLy50ZXN0KG9iai5wcm90b2NvbCkpIHtcbiAgICAgIG9iai5wb3J0ID0gJzQ0Myc7XG4gICAgfVxuICB9XG5cbiAgb2JqLnBhdGggPSBvYmoucGF0aCB8fCAnLyc7XG5cbiAgdmFyIGlwdjYgPSBvYmouaG9zdC5pbmRleE9mKCc6JykgIT09IC0xO1xuICB2YXIgaG9zdCA9IGlwdjYgPyAnWycgKyBvYmouaG9zdCArICddJyA6IG9iai5ob3N0O1xuXG4gIC8vIGRlZmluZSB1bmlxdWUgaWRcbiAgb2JqLmlkID0gb2JqLnByb3RvY29sICsgJzovLycgKyBob3N0ICsgJzonICsgb2JqLnBvcnQ7XG4gIC8vIGRlZmluZSBocmVmXG4gIG9iai5ocmVmID0gb2JqLnByb3RvY29sICsgJzovLycgKyBob3N0ICsgKGxvYyAmJiBsb2MucG9ydCA9PT0gb2JqLnBvcnQgPyAnJyA6ICgnOicgKyBvYmoucG9ydCkpO1xuXG4gIHJldHVybiBvYmo7XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///780f\n")},"7d91":function(module,exports){eval("\n/**\n * Gets the keys for an object.\n *\n * @return {Array} keys\n * @api private\n */\n\nmodule.exports = Object.keys || function keys (obj){\n  var arr = [];\n  var has = Object.prototype.hasOwnProperty;\n\n  for (var i in obj) {\n    if (has.call(obj, i)) {\n      arr.push(i);\n    }\n  }\n  return arr;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2Q5MS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIva2V5cy5qcz83NTljIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBHZXRzIHRoZSBrZXlzIGZvciBhbiBvYmplY3QuXG4gKlxuICogQHJldHVybiB7QXJyYXl9IGtleXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ga2V5cyAob2JqKXtcbiAgdmFyIGFyciA9IFtdO1xuICB2YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGkpKSB7XG4gICAgICBhcnIucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycjtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7d91\n")},"7fa4":function(module,exports,__webpack_require__){eval('var Collection = __webpack_require__(/*! ampersand-collection */ "7bd3");\nvar Filter = __webpack_require__(/*! ../filter */ "9476");\n\nmodule.exports = Collection.extend({\n  mainIndex: \'id\',\n  model: Filter,\n  comparator: function (a, b) {\n    if (a.row > b.row || a.row === b.row && a.col > b.col) {\n      return 1;\n    }\n    if (a.col === b.col) {\n      return 0;\n    }\n    return -1;\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2ZhNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmlsdGVyL2NvbGxlY3Rpb24uanM/ODgyYyJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgRmlsdGVyID0gcmVxdWlyZSgnLi4vZmlsdGVyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtYWluSW5kZXg6ICdpZCcsXG4gIG1vZGVsOiBGaWx0ZXIsXG4gIGNvbXBhcmF0b3I6IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgaWYgKGEucm93ID4gYi5yb3cgfHwgYS5yb3cgPT09IGIucm93ICYmIGEuY29sID4gYi5jb2wpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICBpZiAoYS5jb2wgPT09IGIuY29sKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7fa4\n')},8191:function(module,exports,__webpack_require__){eval("/**\n * Partition\n *\n * Describes a partitioning of the data, based on the values a Facet can take.\n *\n * @class Partition\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Groups = __webpack_require__(/*! ./partition/group-collection */ \"0056\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar selection = __webpack_require__(/*! ./util/selection */ \"1278\");\nvar util = __webpack_require__(/*! ./util/time */ \"d45b\");\n\n/*\n * @param {Partition} partition\n * @param {Group[]} groups\n * @memberof! Partition\n */\nfunction setDatetimeGroups (partition, groups) {\n  var timeStart = partition.minval;\n  var timeEnd = partition.maxval;\n  var timeRes = util.getDatetimeResolution(timeStart, timeEnd);\n  var timeZone = partition.zone;\n\n  var current = moment(timeStart);\n  while ((!current.isAfter(timeEnd)) && groups.length < 500) {\n    groups.add({\n      min: moment(current).tz(timeZone).startOf(timeRes),\n      max: moment(current).tz(timeZone).endOf(timeRes),\n      value: moment(current).tz(timeZone).startOf(timeRes).format(),\n      label: moment(current).tz(timeZone).startOf(timeRes).format()\n    });\n    current.add(1, timeRes);\n  }\n}\n\n/*\n * @param {Partition} partition\n * @param {Group[]} groups\n * @memberof! Partition\n */\nfunction setDurationGroups (partition, groups) {\n  var dStart = partition.minval;\n  var dEnd = partition.maxval;\n  var dRes = util.getDurationResolution(dStart, dEnd);\n\n  var current = Math.floor(parseFloat(dStart.as(dRes)));\n  var last = Math.floor(parseFloat(dEnd.as(dRes)));\n\n  while (current < last) {\n    groups.add({\n      min: moment.duration(current, dRes),\n      max: moment.duration(current + 1, dRes),\n      value: moment.duration(current, dRes).toISOString(),\n      label: moment.duration(current, dRes).toISOString()\n    });\n\n    current = current + 1;\n  }\n}\n\n/*\n * Setup a grouping based on the `partition.groupingContinuous`, `partition.minval`,\n * `partition.maxval`, and the `partition.groupingParam`.\n * @memberof! Partition\n * @param {Partition} partition\n * @param {Group[]} groups\n */\nfunction setContinuousGroups (partition, groups) {\n  var param = partition.groupingParam;\n  var x0, x1, size, nbins;\n\n  if (partition.groupFixedN) {\n    // A fixed number of equally sized bins\n    nbins = param;\n    x0 = partition.minval;\n    x1 = partition.maxval;\n    size = (x1 - x0) / nbins;\n  } else if (partition.groupFixedS) {\n    // A fixed bin size\n    size = param;\n    x0 = Math.floor(partition.minval / size) * size;\n    x1 = Math.ceil(partition.maxval / size) * size;\n    nbins = (x1 - x0) / size;\n  } else if (partition.groupFixedSC) {\n    // A fixed bin size, centered on 0\n    size = param;\n    x0 = (Math.floor(partition.minval / size) - 0.5) * size;\n    x1 = (Math.ceil(partition.maxval / size) + 0.5) * size;\n    nbins = (x1 - x0) / size;\n  } else if (partition.groupLog) {\n    // Fixed number of logarithmically (base 10) sized bins\n    nbins = param;\n    x0 = Math.log(partition.minval) / Math.log(10.0);\n    x1 = Math.log(partition.maxval) / Math.log(10.0);\n    size = (x1 - x0) / nbins;\n  }\n\n  function unlog (x) {\n    return Math.exp(x * Math.log(10));\n  }\n\n  var i;\n  for (i = 0; i < nbins; i++) {\n    var start = x0 + i * size;\n    var end = x0 + (i + 1) * size;\n    var mid = 0.5 * (start + end);\n\n    if (partition.groupLog) {\n      groups.add({\n        min: unlog(start),\n        max: unlog(end),\n        value: unlog(start),\n        label: unlog(end).toPrecision(5)\n      });\n    } else {\n      groups.add({\n        min: start,\n        max: end,\n        value: mid,\n        label: mid.toPrecision(5)\n      });\n    }\n  }\n}\n\n/*\n * Setup a grouping based on the `partition.categorialTransform`\n * @memberof! Partition\n * @param {Partition} partition\n * @param {Group[]} groups\n */\nfunction setCategorialGroups (partition, groups) {\n  // dataview -> filters -> filter -> partitions -> partition\n  //          -> facets\n\n  var dataview;\n  var facet;\n  try {\n    dataview = partition.collection.parent.collection.parent;\n    facet = dataview.facets.get(partition.facetName, 'name');\n  } catch (e) {\n    console.error('setCategorialGroups: cannot locate facet for this partition');\n    return;\n  }\n\n  if (facet.isCategorial) {\n    // default: a categorial facet, with a categorial parittion\n    facet.categorialTransform.rules.forEach(function (rule, i) {\n      groups.add({\n        value: rule.group,\n        label: rule.group,\n        count: rule.count\n      });\n    });\n  } else if (facet.isDatetime) {\n    var format = facet.datetimeTransform.transformedFormat;\n    var timePart = util.timeParts.get(format, 'description');\n\n    timePart.groups.forEach(function (g, i) {\n      groups.add({\n        value: g,\n        label: g,\n        count: 0\n      });\n    });\n  } else {\n    console.warn('Not implemented');\n  }\n}\n\n/**\n * Reset type, minimum and maximum values\n * @params {Partition} partition\n * @params {Object} Options - silent do not trigger change events\n * @memberof! Partition\n */\nfunction reset (options) {\n  var partition = this;\n  // partition -> partitions -> filter -> filters -> dataview\n  var filter = partition.collection.parent;\n  var dataview = filter.collection.parent;\n  var facet = dataview.facets.get(partition.facetName, 'name');\n  options = options || {};\n\n  partition.set({\n    type: facet.transform.transformedType,\n    minval: facet.transform.transformedMin,\n    maxval: facet.transform.transformedMax\n  }, options);\n}\n\nmodule.exports = BaseModel.extend({\n  dataTypes: {\n    'numberDatetimeOrDuration': {\n      set: function (value) {\n        var newValue;\n\n        // check for momentjs objects\n        if (moment.isDuration(value)) {\n          return {\n            val: moment.duration(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (moment.isMoment(value)) {\n          return {\n            val: value.clone(),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to create momentjs objects\n        newValue = moment(value, moment.ISO_8601);\n        if (newValue.isValid()) {\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          newValue = moment.duration(value);\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to set a number\n        if (value === +value) {\n          return {\n            val: +value,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // failed..\n        return {\n          val: value,\n          type: typeof value\n        };\n      },\n      compare: function (currentVal, newVal) {\n        if (currentVal instanceof moment) {\n          return currentVal.isSame(newVal);\n        } else {\n          return +currentVal === +newVal;\n        }\n      }\n    }\n  },\n  props: {\n    /**\n     * Label for displaying on plots\n     * @memberof! Partition\n     * @type {string}\n     */\n    label: {\n      type: 'string',\n      required: true,\n      default: ''\n    },\n    /**\n     * Show a legend for this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    showLegend: {\n      type: 'boolean',\n      required: false,\n      default: true\n    },\n    /**\n     * Show an axis label for this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    showLabel: {\n      type: 'boolean',\n      required: false,\n      default: true\n    },\n\n    /**\n     * Timezone for partitioning\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    zone: {\n      type: 'string',\n      required: 'true',\n      default: function () {\n        return moment.tz.guess();\n      }\n    },\n\n    /**\n     * Type of this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['constant', 'continuous', 'categorial', 'datetime', 'duration', 'text']\n    },\n\n    /**\n     * The name of the facet to partition over\n     * @memberof! Partition\n     * @type {string}\n     */\n    facetName: 'string',\n\n    /**\n     * When part of a partitioning, this deterimines the ordering\n     * @memberof! Partition\n     * @type {number}\n     */\n    rank: {\n      type: 'number',\n      required: true\n    },\n\n    /**\n     * For categorial and text Facets, the ordering can be alfabetical or by count\n     * @memberof! Partition\n     */\n    ordering: {\n      type: 'string',\n      values: ['count', 'value'],\n      required: true,\n      default: 'value'\n    },\n\n    /**\n     * For continuous or datetime Facets, the minimum value. Values lower than this are grouped to 'missing'\n     * @memberof! Partition\n     * @type {number|moment}\n     */\n    minval: 'numberDatetimeOrDuration',\n\n    /**\n     * For continuous or datetime Facets, the maximum value. Values higher than this are grouped to 'missing'\n     * @memberof! Partition\n     * @type {number|moment}\n     */\n    maxval: 'numberDatetimeOrDuration',\n\n    /**\n     * Extra parameter used in the grouping strategy: either the number of bins, or the bin size.\n     * @memberof! Partition\n     * @type {number}\n     */\n    groupingParam: ['number', true, 20],\n\n    /**\n     * Grouping strategy:\n     *  * `fixedn`  fixed number of bins in the interval [minval, maxval]\n     *  * `fixedsc` a fixed binsize, centered on zero\n     *  * `fixeds`  a fixed binsize, starting at zero\n     *  * `log`     fixed number of bins but on a logarithmic scale\n     * Don't use directly but check grouping via the groupFixedN, groupFixedSC,\n     * groupFixedS, and groupLog properties\n     * @memberof! Partition\n     * @type {number}\n     */\n    groupingContinuous: {\n      type: 'string',\n      required: true,\n      default: 'fixedn',\n      values: ['fixedn', 'fixedsc', 'fixeds', 'log']\n    },\n\n    /**\n     * Depending on the type of partition, this can be an array of the selected groups,\n     * or a numberic interval [start, end]\n     * @memberof! Partition\n     * @type {array}\n     */\n    // NOTE: for categorial facets, contains rule.group\n    selected: {\n      type: 'array',\n      required: true,\n      default: function () {\n        return [];\n      }\n    }\n  },\n  derived: {\n    // properties for: type\n    isConstant: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'constant';\n      }\n    },\n    isContinuous: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'continuous';\n      }\n    },\n    isCategorial: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'categorial';\n      }\n    },\n    isDatetime: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'datetime';\n      }\n    },\n    isDuration: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'duration';\n      }\n    },\n    isText: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'text';\n      }\n    },\n    // properties for grouping-continuous\n    groupFixedN: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixedn';\n      }\n    },\n    groupFixedSC: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixedsc';\n      }\n    },\n    groupFixedS: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixeds';\n      }\n    },\n    groupLog: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'log';\n      }\n    },\n    /**\n     * The (ordered) set of groups this Partition can take, making up this partition.\n     * The list is recalculated when any of the partition's properties change:\n     * 'groupingContinuous', 'groupingParam', 'minval', 'maxval', 'type', 'zone' change\n     * The list keeps itself sorted according to the partition.ordering\n     *\n     * Can be used for plotting etc.\n     * @memberof! Partition\n     * @type {Group[]}\n     */\n    groups: {\n      deps: ['groupingContinuous', 'groupingParam', 'minval', 'maxval', 'type', 'zone'],\n      fn: function () {\n        var partition = this;\n        var groups = new Groups([], {\n          parent: partition\n        });\n\n        if (partition.isCategorial) {\n          setCategorialGroups(partition, groups);\n        } else if (partition.isContinuous) {\n          setContinuousGroups(partition, groups);\n        } else if (partition.isDatetime) {\n          setDatetimeGroups(partition, groups);\n        } else if (partition.isDuration) {\n          setDurationGroups(partition, groups);\n        } else if (partition.isText) {\n          // no-op\n        } else {\n          console.error('Cannot set groups for partition', partition.getId());\n        }\n\n        return groups;\n      }\n    }\n  },\n  updateSelection: function (group) {\n    selection.updateSelection(this, group);\n  },\n  filterFunction: function () {\n    return selection.filterFunction(this);\n  },\n  reset: reset\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODE5MS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uLmpzPzUzODciXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQYXJ0aXRpb25cbiAqXG4gKiBEZXNjcmliZXMgYSBwYXJ0aXRpb25pbmcgb2YgdGhlIGRhdGEsIGJhc2VkIG9uIHRoZSB2YWx1ZXMgYSBGYWNldCBjYW4gdGFrZS5cbiAqXG4gKiBAY2xhc3MgUGFydGl0aW9uXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBCYXNlTW9kZWwgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIEdyb3VwcyA9IHJlcXVpcmUoJy4vcGFydGl0aW9uL2dyb3VwLWNvbGxlY3Rpb24nKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciBzZWxlY3Rpb24gPSByZXF1aXJlKCcuL3V0aWwvc2VsZWN0aW9uJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbC90aW1lJyk7XG5cbi8qXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKiBAcGFyYW0ge0dyb3VwW119IGdyb3Vwc1xuICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAqL1xuZnVuY3Rpb24gc2V0RGF0ZXRpbWVHcm91cHMgKHBhcnRpdGlvbiwgZ3JvdXBzKSB7XG4gIHZhciB0aW1lU3RhcnQgPSBwYXJ0aXRpb24ubWludmFsO1xuICB2YXIgdGltZUVuZCA9IHBhcnRpdGlvbi5tYXh2YWw7XG4gIHZhciB0aW1lUmVzID0gdXRpbC5nZXREYXRldGltZVJlc29sdXRpb24odGltZVN0YXJ0LCB0aW1lRW5kKTtcbiAgdmFyIHRpbWVab25lID0gcGFydGl0aW9uLnpvbmU7XG5cbiAgdmFyIGN1cnJlbnQgPSBtb21lbnQodGltZVN0YXJ0KTtcbiAgd2hpbGUgKCghY3VycmVudC5pc0FmdGVyKHRpbWVFbmQpKSAmJiBncm91cHMubGVuZ3RoIDwgNTAwKSB7XG4gICAgZ3JvdXBzLmFkZCh7XG4gICAgICBtaW46IG1vbWVudChjdXJyZW50KS50eih0aW1lWm9uZSkuc3RhcnRPZih0aW1lUmVzKSxcbiAgICAgIG1heDogbW9tZW50KGN1cnJlbnQpLnR6KHRpbWVab25lKS5lbmRPZih0aW1lUmVzKSxcbiAgICAgIHZhbHVlOiBtb21lbnQoY3VycmVudCkudHoodGltZVpvbmUpLnN0YXJ0T2YodGltZVJlcykuZm9ybWF0KCksXG4gICAgICBsYWJlbDogbW9tZW50KGN1cnJlbnQpLnR6KHRpbWVab25lKS5zdGFydE9mKHRpbWVSZXMpLmZvcm1hdCgpXG4gICAgfSk7XG4gICAgY3VycmVudC5hZGQoMSwgdGltZVJlcyk7XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7R3JvdXBbXX0gZ3JvdXBzXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBzZXREdXJhdGlvbkdyb3VwcyAocGFydGl0aW9uLCBncm91cHMpIHtcbiAgdmFyIGRTdGFydCA9IHBhcnRpdGlvbi5taW52YWw7XG4gIHZhciBkRW5kID0gcGFydGl0aW9uLm1heHZhbDtcbiAgdmFyIGRSZXMgPSB1dGlsLmdldER1cmF0aW9uUmVzb2x1dGlvbihkU3RhcnQsIGRFbmQpO1xuXG4gIHZhciBjdXJyZW50ID0gTWF0aC5mbG9vcihwYXJzZUZsb2F0KGRTdGFydC5hcyhkUmVzKSkpO1xuICB2YXIgbGFzdCA9IE1hdGguZmxvb3IocGFyc2VGbG9hdChkRW5kLmFzKGRSZXMpKSk7XG5cbiAgd2hpbGUgKGN1cnJlbnQgPCBsYXN0KSB7XG4gICAgZ3JvdXBzLmFkZCh7XG4gICAgICBtaW46IG1vbWVudC5kdXJhdGlvbihjdXJyZW50LCBkUmVzKSxcbiAgICAgIG1heDogbW9tZW50LmR1cmF0aW9uKGN1cnJlbnQgKyAxLCBkUmVzKSxcbiAgICAgIHZhbHVlOiBtb21lbnQuZHVyYXRpb24oY3VycmVudCwgZFJlcykudG9JU09TdHJpbmcoKSxcbiAgICAgIGxhYmVsOiBtb21lbnQuZHVyYXRpb24oY3VycmVudCwgZFJlcykudG9JU09TdHJpbmcoKVxuICAgIH0pO1xuXG4gICAgY3VycmVudCA9IGN1cnJlbnQgKyAxO1xuICB9XG59XG5cbi8qXG4gKiBTZXR1cCBhIGdyb3VwaW5nIGJhc2VkIG9uIHRoZSBgcGFydGl0aW9uLmdyb3VwaW5nQ29udGludW91c2AsIGBwYXJ0aXRpb24ubWludmFsYCxcbiAqIGBwYXJ0aXRpb24ubWF4dmFsYCwgYW5kIHRoZSBgcGFydGl0aW9uLmdyb3VwaW5nUGFyYW1gLlxuICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7R3JvdXBbXX0gZ3JvdXBzXG4gKi9cbmZ1bmN0aW9uIHNldENvbnRpbnVvdXNHcm91cHMgKHBhcnRpdGlvbiwgZ3JvdXBzKSB7XG4gIHZhciBwYXJhbSA9IHBhcnRpdGlvbi5ncm91cGluZ1BhcmFtO1xuICB2YXIgeDAsIHgxLCBzaXplLCBuYmlucztcblxuICBpZiAocGFydGl0aW9uLmdyb3VwRml4ZWROKSB7XG4gICAgLy8gQSBmaXhlZCBudW1iZXIgb2YgZXF1YWxseSBzaXplZCBiaW5zXG4gICAgbmJpbnMgPSBwYXJhbTtcbiAgICB4MCA9IHBhcnRpdGlvbi5taW52YWw7XG4gICAgeDEgPSBwYXJ0aXRpb24ubWF4dmFsO1xuICAgIHNpemUgPSAoeDEgLSB4MCkgLyBuYmlucztcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uZ3JvdXBGaXhlZFMpIHtcbiAgICAvLyBBIGZpeGVkIGJpbiBzaXplXG4gICAgc2l6ZSA9IHBhcmFtO1xuICAgIHgwID0gTWF0aC5mbG9vcihwYXJ0aXRpb24ubWludmFsIC8gc2l6ZSkgKiBzaXplO1xuICAgIHgxID0gTWF0aC5jZWlsKHBhcnRpdGlvbi5tYXh2YWwgLyBzaXplKSAqIHNpemU7XG4gICAgbmJpbnMgPSAoeDEgLSB4MCkgLyBzaXplO1xuICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5ncm91cEZpeGVkU0MpIHtcbiAgICAvLyBBIGZpeGVkIGJpbiBzaXplLCBjZW50ZXJlZCBvbiAwXG4gICAgc2l6ZSA9IHBhcmFtO1xuICAgIHgwID0gKE1hdGguZmxvb3IocGFydGl0aW9uLm1pbnZhbCAvIHNpemUpIC0gMC41KSAqIHNpemU7XG4gICAgeDEgPSAoTWF0aC5jZWlsKHBhcnRpdGlvbi5tYXh2YWwgLyBzaXplKSArIDAuNSkgKiBzaXplO1xuICAgIG5iaW5zID0gKHgxIC0geDApIC8gc2l6ZTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAvLyBGaXhlZCBudW1iZXIgb2YgbG9nYXJpdGhtaWNhbGx5IChiYXNlIDEwKSBzaXplZCBiaW5zXG4gICAgbmJpbnMgPSBwYXJhbTtcbiAgICB4MCA9IE1hdGgubG9nKHBhcnRpdGlvbi5taW52YWwpIC8gTWF0aC5sb2coMTAuMCk7XG4gICAgeDEgPSBNYXRoLmxvZyhwYXJ0aXRpb24ubWF4dmFsKSAvIE1hdGgubG9nKDEwLjApO1xuICAgIHNpemUgPSAoeDEgLSB4MCkgLyBuYmlucztcbiAgfVxuXG4gIGZ1bmN0aW9uIHVubG9nICh4KSB7XG4gICAgcmV0dXJuIE1hdGguZXhwKHggKiBNYXRoLmxvZygxMCkpO1xuICB9XG5cbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBuYmluczsgaSsrKSB7XG4gICAgdmFyIHN0YXJ0ID0geDAgKyBpICogc2l6ZTtcbiAgICB2YXIgZW5kID0geDAgKyAoaSArIDEpICogc2l6ZTtcbiAgICB2YXIgbWlkID0gMC41ICogKHN0YXJ0ICsgZW5kKTtcblxuICAgIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAgIGdyb3Vwcy5hZGQoe1xuICAgICAgICBtaW46IHVubG9nKHN0YXJ0KSxcbiAgICAgICAgbWF4OiB1bmxvZyhlbmQpLFxuICAgICAgICB2YWx1ZTogdW5sb2coc3RhcnQpLFxuICAgICAgICBsYWJlbDogdW5sb2coZW5kKS50b1ByZWNpc2lvbig1KVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdyb3Vwcy5hZGQoe1xuICAgICAgICBtaW46IHN0YXJ0LFxuICAgICAgICBtYXg6IGVuZCxcbiAgICAgICAgdmFsdWU6IG1pZCxcbiAgICAgICAgbGFiZWw6IG1pZC50b1ByZWNpc2lvbig1KVxuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qXG4gKiBTZXR1cCBhIGdyb3VwaW5nIGJhc2VkIG9uIHRoZSBgcGFydGl0aW9uLmNhdGVnb3JpYWxUcmFuc2Zvcm1gXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICogQHBhcmFtIHtHcm91cFtdfSBncm91cHNcbiAqL1xuZnVuY3Rpb24gc2V0Q2F0ZWdvcmlhbEdyb3VwcyAocGFydGl0aW9uLCBncm91cHMpIHtcbiAgLy8gZGF0YXZpZXcgLT4gZmlsdGVycyAtPiBmaWx0ZXIgLT4gcGFydGl0aW9ucyAtPiBwYXJ0aXRpb25cbiAgLy8gICAgICAgICAgLT4gZmFjZXRzXG5cbiAgdmFyIGRhdGF2aWV3O1xuICB2YXIgZmFjZXQ7XG4gIHRyeSB7XG4gICAgZGF0YXZpZXcgPSBwYXJ0aXRpb24uY29sbGVjdGlvbi5wYXJlbnQuY29sbGVjdGlvbi5wYXJlbnQ7XG4gICAgZmFjZXQgPSBkYXRhdmlldy5mYWNldHMuZ2V0KHBhcnRpdGlvbi5mYWNldE5hbWUsICduYW1lJyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKCdzZXRDYXRlZ29yaWFsR3JvdXBzOiBjYW5ub3QgbG9jYXRlIGZhY2V0IGZvciB0aGlzIHBhcnRpdGlvbicpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmYWNldC5pc0NhdGVnb3JpYWwpIHtcbiAgICAvLyBkZWZhdWx0OiBhIGNhdGVnb3JpYWwgZmFjZXQsIHdpdGggYSBjYXRlZ29yaWFsIHBhcml0dGlvblxuICAgIGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuZm9yRWFjaChmdW5jdGlvbiAocnVsZSwgaSkge1xuICAgICAgZ3JvdXBzLmFkZCh7XG4gICAgICAgIHZhbHVlOiBydWxlLmdyb3VwLFxuICAgICAgICBsYWJlbDogcnVsZS5ncm91cCxcbiAgICAgICAgY291bnQ6IHJ1bGUuY291bnRcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICB2YXIgZm9ybWF0ID0gZmFjZXQuZGF0ZXRpbWVUcmFuc2Zvcm0udHJhbnNmb3JtZWRGb3JtYXQ7XG4gICAgdmFyIHRpbWVQYXJ0ID0gdXRpbC50aW1lUGFydHMuZ2V0KGZvcm1hdCwgJ2Rlc2NyaXB0aW9uJyk7XG5cbiAgICB0aW1lUGFydC5ncm91cHMuZm9yRWFjaChmdW5jdGlvbiAoZywgaSkge1xuICAgICAgZ3JvdXBzLmFkZCh7XG4gICAgICAgIHZhbHVlOiBnLFxuICAgICAgICBsYWJlbDogZyxcbiAgICAgICAgY291bnQ6IDBcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUud2FybignTm90IGltcGxlbWVudGVkJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNldCB0eXBlLCBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlc1xuICogQHBhcmFtcyB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbXMge09iamVjdH0gT3B0aW9ucyAtIHNpbGVudCBkbyBub3QgdHJpZ2dlciBjaGFuZ2UgZXZlbnRzXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICovXG5mdW5jdGlvbiByZXNldCAob3B0aW9ucykge1xuICB2YXIgcGFydGl0aW9uID0gdGhpcztcbiAgLy8gcGFydGl0aW9uIC0+IHBhcnRpdGlvbnMgLT4gZmlsdGVyIC0+IGZpbHRlcnMgLT4gZGF0YXZpZXdcbiAgdmFyIGZpbHRlciA9IHBhcnRpdGlvbi5jb2xsZWN0aW9uLnBhcmVudDtcbiAgdmFyIGRhdGF2aWV3ID0gZmlsdGVyLmNvbGxlY3Rpb24ucGFyZW50O1xuICB2YXIgZmFjZXQgPSBkYXRhdmlldy5mYWNldHMuZ2V0KHBhcnRpdGlvbi5mYWNldE5hbWUsICduYW1lJyk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHBhcnRpdGlvbi5zZXQoe1xuICAgIHR5cGU6IGZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZFR5cGUsXG4gICAgbWludmFsOiBmYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW4sXG4gICAgbWF4dmFsOiBmYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNYXhcbiAgfSwgb3B0aW9ucyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIGRhdGFUeXBlczoge1xuICAgICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nOiB7XG4gICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIG1vbWVudGpzIG9iamVjdHNcbiAgICAgICAgaWYgKG1vbWVudC5pc0R1cmF0aW9uKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG1vbWVudC5kdXJhdGlvbih2YWx1ZSksXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vbWVudC5pc01vbWVudCh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsOiB2YWx1ZS5jbG9uZSgpLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIGNyZWF0ZSBtb21lbnRqcyBvYmplY3RzXG4gICAgICAgIG5ld1ZhbHVlID0gbW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICBpZiAobmV3VmFsdWUuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbDogbmV3VmFsdWUsXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSB7XG4gICAgICAgICAgbmV3VmFsdWUgPSBtb21lbnQuZHVyYXRpb24odmFsdWUpO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG5ld1ZhbHVlLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIHNldCBhIG51bWJlclxuICAgICAgICBpZiAodmFsdWUgPT09ICt2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6ICt2YWx1ZSxcbiAgICAgICAgICAgIHR5cGU6ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZhaWxlZC4uXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsOiB2YWx1ZSxcbiAgICAgICAgICB0eXBlOiB0eXBlb2YgdmFsdWVcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBjb21wYXJlOiBmdW5jdGlvbiAoY3VycmVudFZhbCwgbmV3VmFsKSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsIGluc3RhbmNlb2YgbW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuIGN1cnJlbnRWYWwuaXNTYW1lKG5ld1ZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICtjdXJyZW50VmFsID09PSArbmV3VmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIExhYmVsIGZvciBkaXNwbGF5aW5nIG9uIHBsb3RzXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGxhYmVsOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJydcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFNob3cgYSBsZWdlbmQgZm9yIHRoaXMgcGFydGl0aW9uXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHNob3dMZWdlbmQ6IHtcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgIGRlZmF1bHQ6IHRydWVcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFNob3cgYW4gYXhpcyBsYWJlbCBmb3IgdGhpcyBwYXJ0aXRpb25cbiAgICAgKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgc2hvd0xhYmVsOiB7XG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICBkZWZhdWx0OiB0cnVlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRpbWV6b25lIGZvciBwYXJ0aXRpb25pbmdcbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB6b25lOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiAndHJ1ZScsXG4gICAgICBkZWZhdWx0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiB0aGlzIHBhcnRpdGlvblxuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0eXBlOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ2NhdGVnb3JpYWwnLFxuICAgICAgdmFsdWVzOiBbJ2NvbnN0YW50JywgJ2NvbnRpbnVvdXMnLCAnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICd0ZXh0J11cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGZhY2V0IHRvIHBhcnRpdGlvbiBvdmVyXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZhY2V0TmFtZTogJ3N0cmluZycsXG5cbiAgICAvKipcbiAgICAgKiBXaGVuIHBhcnQgb2YgYSBwYXJ0aXRpb25pbmcsIHRoaXMgZGV0ZXJpbWluZXMgdGhlIG9yZGVyaW5nXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHJhbms6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNhdGVnb3JpYWwgYW5kIHRleHQgRmFjZXRzLCB0aGUgb3JkZXJpbmcgY2FuIGJlIGFsZmFiZXRpY2FsIG9yIGJ5IGNvdW50XG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKi9cbiAgICBvcmRlcmluZzoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICB2YWx1ZXM6IFsnY291bnQnLCAndmFsdWUnXSxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ3ZhbHVlJ1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBGb3IgY29udGludW91cyBvciBkYXRldGltZSBGYWNldHMsIHRoZSBtaW5pbXVtIHZhbHVlLiBWYWx1ZXMgbG93ZXIgdGhhbiB0aGlzIGFyZSBncm91cGVkIHRvICdtaXNzaW5nJ1xuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICovXG4gICAgbWludmFsOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJyxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1heGltdW0gdmFsdWUuIFZhbHVlcyBoaWdoZXIgdGhhbiB0aGlzIGFyZSBncm91cGVkIHRvICdtaXNzaW5nJ1xuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICovXG4gICAgbWF4dmFsOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJyxcblxuICAgIC8qKlxuICAgICAqIEV4dHJhIHBhcmFtZXRlciB1c2VkIGluIHRoZSBncm91cGluZyBzdHJhdGVneTogZWl0aGVyIHRoZSBudW1iZXIgb2YgYmlucywgb3IgdGhlIGJpbiBzaXplLlxuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBncm91cGluZ1BhcmFtOiBbJ251bWJlcicsIHRydWUsIDIwXSxcblxuICAgIC8qKlxuICAgICAqIEdyb3VwaW5nIHN0cmF0ZWd5OlxuICAgICAqICAqIGBmaXhlZG5gICBmaXhlZCBudW1iZXIgb2YgYmlucyBpbiB0aGUgaW50ZXJ2YWwgW21pbnZhbCwgbWF4dmFsXVxuICAgICAqICAqIGBmaXhlZHNjYCBhIGZpeGVkIGJpbnNpemUsIGNlbnRlcmVkIG9uIHplcm9cbiAgICAgKiAgKiBgZml4ZWRzYCAgYSBmaXhlZCBiaW5zaXplLCBzdGFydGluZyBhdCB6ZXJvXG4gICAgICogICogYGxvZ2AgICAgIGZpeGVkIG51bWJlciBvZiBiaW5zIGJ1dCBvbiBhIGxvZ2FyaXRobWljIHNjYWxlXG4gICAgICogRG9uJ3QgdXNlIGRpcmVjdGx5IGJ1dCBjaGVjayBncm91cGluZyB2aWEgdGhlIGdyb3VwRml4ZWROLCBncm91cEZpeGVkU0MsXG4gICAgICogZ3JvdXBGaXhlZFMsIGFuZCBncm91cExvZyBwcm9wZXJ0aWVzXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdyb3VwaW5nQ29udGludW91czoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICdmaXhlZG4nLFxuICAgICAgdmFsdWVzOiBbJ2ZpeGVkbicsICdmaXhlZHNjJywgJ2ZpeGVkcycsICdsb2cnXVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBEZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgcGFydGl0aW9uLCB0aGlzIGNhbiBiZSBhbiBhcnJheSBvZiB0aGUgc2VsZWN0ZWQgZ3JvdXBzLFxuICAgICAqIG9yIGEgbnVtYmVyaWMgaW50ZXJ2YWwgW3N0YXJ0LCBlbmRdXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7YXJyYXl9XG4gICAgICovXG4gICAgLy8gTk9URTogZm9yIGNhdGVnb3JpYWwgZmFjZXRzLCBjb250YWlucyBydWxlLmdyb3VwXG4gICAgc2VsZWN0ZWQ6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgZGVyaXZlZDoge1xuICAgIC8vIHByb3BlcnRpZXMgZm9yOiB0eXBlXG4gICAgaXNDb25zdGFudDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAnY29uc3RhbnQnO1xuICAgICAgfVxuICAgIH0sXG4gICAgaXNDb250aW51b3VzOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjb250aW51b3VzJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzQ2F0ZWdvcmlhbDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAnY2F0ZWdvcmlhbCc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0RhdGV0aW1lOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdkYXRldGltZSc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0R1cmF0aW9uOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdkdXJhdGlvbic7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ3RleHQnO1xuICAgICAgfVxuICAgIH0sXG4gICAgLy8gcHJvcGVydGllcyBmb3IgZ3JvdXBpbmctY29udGludW91c1xuICAgIGdyb3VwRml4ZWROOiB7XG4gICAgICBkZXBzOiBbJ2dyb3VwaW5nQ29udGludW91cyddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JvdXBpbmdDb250aW51b3VzID09PSAnZml4ZWRuJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGdyb3VwRml4ZWRTQzoge1xuICAgICAgZGVwczogWydncm91cGluZ0NvbnRpbnVvdXMnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyb3VwaW5nQ29udGludW91cyA9PT0gJ2ZpeGVkc2MnO1xuICAgICAgfVxuICAgIH0sXG4gICAgZ3JvdXBGaXhlZFM6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cGluZ0NvbnRpbnVvdXMgPT09ICdmaXhlZHMnO1xuICAgICAgfVxuICAgIH0sXG4gICAgZ3JvdXBMb2c6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cGluZ0NvbnRpbnVvdXMgPT09ICdsb2cnO1xuICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIChvcmRlcmVkKSBzZXQgb2YgZ3JvdXBzIHRoaXMgUGFydGl0aW9uIGNhbiB0YWtlLCBtYWtpbmcgdXAgdGhpcyBwYXJ0aXRpb24uXG4gICAgICogVGhlIGxpc3QgaXMgcmVjYWxjdWxhdGVkIHdoZW4gYW55IG9mIHRoZSBwYXJ0aXRpb24ncyBwcm9wZXJ0aWVzIGNoYW5nZTpcbiAgICAgKiAnZ3JvdXBpbmdDb250aW51b3VzJywgJ2dyb3VwaW5nUGFyYW0nLCAnbWludmFsJywgJ21heHZhbCcsICd0eXBlJywgJ3pvbmUnIGNoYW5nZVxuICAgICAqIFRoZSBsaXN0IGtlZXBzIGl0c2VsZiBzb3J0ZWQgYWNjb3JkaW5nIHRvIHRoZSBwYXJ0aXRpb24ub3JkZXJpbmdcbiAgICAgKlxuICAgICAqIENhbiBiZSB1c2VkIGZvciBwbG90dGluZyBldGMuXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7R3JvdXBbXX1cbiAgICAgKi9cbiAgICBncm91cHM6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJywgJ2dyb3VwaW5nUGFyYW0nLCAnbWludmFsJywgJ21heHZhbCcsICd0eXBlJywgJ3pvbmUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwYXJ0aXRpb24gPSB0aGlzO1xuICAgICAgICB2YXIgZ3JvdXBzID0gbmV3IEdyb3VwcyhbXSwge1xuICAgICAgICAgIHBhcmVudDogcGFydGl0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChwYXJ0aXRpb24uaXNDYXRlZ29yaWFsKSB7XG4gICAgICAgICAgc2V0Q2F0ZWdvcmlhbEdyb3VwcyhwYXJ0aXRpb24sIGdyb3Vwcyk7XG4gICAgICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzQ29udGludW91cykge1xuICAgICAgICAgIHNldENvbnRpbnVvdXNHcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0RhdGV0aW1lKSB7XG4gICAgICAgICAgc2V0RGF0ZXRpbWVHcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0R1cmF0aW9uKSB7XG4gICAgICAgICAgc2V0RHVyYXRpb25Hcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc1RleHQpIHtcbiAgICAgICAgICAvLyBuby1vcFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Nhbm5vdCBzZXQgZ3JvdXBzIGZvciBwYXJ0aXRpb24nLCBwYXJ0aXRpb24uZ2V0SWQoKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ3JvdXBzO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgdXBkYXRlU2VsZWN0aW9uOiBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICBzZWxlY3Rpb24udXBkYXRlU2VsZWN0aW9uKHRoaXMsIGdyb3VwKTtcbiAgfSxcbiAgZmlsdGVyRnVuY3Rpb246IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gc2VsZWN0aW9uLmZpbHRlckZ1bmN0aW9uKHRoaXMpO1xuICB9LFxuICByZXNldDogcmVzZXRcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8191\n")},8233:function(module,exports,__webpack_require__){eval("\n/**\n * This is the web browser implementation of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = __webpack_require__(/*! ./debug */ \"bb16\");\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = 'undefined' != typeof chrome\n               && 'undefined' != typeof chrome.storage\n                  ? chrome.storage.local\n                  : localstorage();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n  'lightseagreen',\n  'forestgreen',\n  'goldenrod',\n  'dodgerblue',\n  'darkorchid',\n  'crimson'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\nfunction useColors() {\n  // is webkit? http://stackoverflow.com/a/16459606/376773\n  return ('WebkitAppearance' in document.documentElement.style) ||\n    // is firebug? http://stackoverflow.com/a/398120/376773\n    (window.console && (console.firebug || (console.exception && console.table))) ||\n    // is firefox >= v31?\n    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n    (navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31);\n}\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nexports.formatters.j = function(v) {\n  return JSON.stringify(v);\n};\n\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs() {\n  var args = arguments;\n  var useColors = this.useColors;\n\n  args[0] = (useColors ? '%c' : '')\n    + this.namespace\n    + (useColors ? ' %c' : ' ')\n    + args[0]\n    + (useColors ? '%c ' : ' ')\n    + '+' + exports.humanize(this.diff);\n\n  if (!useColors) return args;\n\n  var c = 'color: ' + this.color;\n  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));\n\n  // the final \"%c\" is somewhat tricky, because there could be other\n  // arguments passed either before or after the %c, so we need to\n  // figure out the correct index to insert the CSS into\n  var index = 0;\n  var lastC = 0;\n  args[0].replace(/%[a-z%]/g, function(match) {\n    if ('%%' === match) return;\n    index++;\n    if ('%c' === match) {\n      // we only are interested in the *last* %c\n      // (the user may have provided their own)\n      lastC = index;\n    }\n  });\n\n  args.splice(lastC, 0, c);\n  return args;\n}\n\n/**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\nfunction log() {\n  // this hackery is required for IE8/9, where\n  // the `console.log` function doesn't have 'apply'\n  return 'object' === typeof console\n    && console.log\n    && Function.prototype.apply.call(console.log, console, arguments);\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\nfunction save(namespaces) {\n  try {\n    if (null == namespaces) {\n      exports.storage.removeItem('debug');\n    } else {\n      exports.storage.debug = namespaces;\n    }\n  } catch(e) {}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n  var r;\n  try {\n    r = exports.storage.debug;\n  } catch(e) {}\n  return r;\n}\n\n/**\n * Enable namespaces listed in `localStorage.debug` initially.\n */\n\nexports.enable(load());\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage(){\n  try {\n    return window.localStorage;\n  } catch (e) {}\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvZGVidWcvYnJvd3Nlci5qcz80ZDVhIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSB3ZWIgYnJvd3NlciBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gKlxuICogRXhwb3NlIGBkZWJ1ZygpYCBhcyB0aGUgbW9kdWxlLlxuICovXG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZGVidWcnKTtcbmV4cG9ydHMubG9nID0gbG9nO1xuZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbmV4cG9ydHMuc2F2ZSA9IHNhdmU7XG5leHBvcnRzLmxvYWQgPSBsb2FkO1xuZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG5leHBvcnRzLnN0b3JhZ2UgPSAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lXG4gICAgICAgICAgICAgICAmJiAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lLnN0b3JhZ2VcbiAgICAgICAgICAgICAgICAgID8gY2hyb21lLnN0b3JhZ2UubG9jYWxcbiAgICAgICAgICAgICAgICAgIDogbG9jYWxzdG9yYWdlKCk7XG5cbi8qKlxuICogQ29sb3JzLlxuICovXG5cbmV4cG9ydHMuY29sb3JzID0gW1xuICAnbGlnaHRzZWFncmVlbicsXG4gICdmb3Jlc3RncmVlbicsXG4gICdnb2xkZW5yb2QnLFxuICAnZG9kZ2VyYmx1ZScsXG4gICdkYXJrb3JjaGlkJyxcbiAgJ2NyaW1zb24nXG5dO1xuXG4vKipcbiAqIEN1cnJlbnRseSBvbmx5IFdlYktpdC1iYXNlZCBXZWIgSW5zcGVjdG9ycywgRmlyZWZveCA+PSB2MzEsXG4gKiBhbmQgdGhlIEZpcmVidWcgZXh0ZW5zaW9uIChhbnkgRmlyZWZveCB2ZXJzaW9uKSBhcmUga25vd25cbiAqIHRvIHN1cHBvcnQgXCIlY1wiIENTUyBjdXN0b21pemF0aW9ucy5cbiAqXG4gKiBUT0RPOiBhZGQgYSBgbG9jYWxTdG9yYWdlYCB2YXJpYWJsZSB0byBleHBsaWNpdGx5IGVuYWJsZS9kaXNhYmxlIGNvbG9yc1xuICovXG5cbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcbiAgLy8gaXMgd2Via2l0PyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNjQ1OTYwNi8zNzY3NzNcbiAgcmV0dXJuICgnV2Via2l0QXBwZWFyYW5jZScgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlKSB8fFxuICAgIC8vIGlzIGZpcmVidWc/IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM5ODEyMC8zNzY3NzNcbiAgICAod2luZG93LmNvbnNvbGUgJiYgKGNvbnNvbGUuZmlyZWJ1ZyB8fCAoY29uc29sZS5leGNlcHRpb24gJiYgY29uc29sZS50YWJsZSkpKSB8fFxuICAgIC8vIGlzIGZpcmVmb3ggPj0gdjMxP1xuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvVG9vbHMvV2ViX0NvbnNvbGUjU3R5bGluZ19tZXNzYWdlc1xuICAgIChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkubWF0Y2goL2ZpcmVmb3hcXC8oXFxkKykvKSAmJiBwYXJzZUludChSZWdFeHAuJDEsIDEwKSA+PSAzMSk7XG59XG5cbi8qKlxuICogTWFwICVqIHRvIGBKU09OLnN0cmluZ2lmeSgpYCwgc2luY2Ugbm8gV2ViIEluc3BlY3RvcnMgZG8gdGhhdCBieSBkZWZhdWx0LlxuICovXG5cbmV4cG9ydHMuZm9ybWF0dGVycy5qID0gZnVuY3Rpb24odikge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodik7XG59O1xuXG5cbi8qKlxuICogQ29sb3JpemUgbG9nIGFyZ3VtZW50cyBpZiBlbmFibGVkLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZm9ybWF0QXJncygpIHtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciB1c2VDb2xvcnMgPSB0aGlzLnVzZUNvbG9ycztcblxuICBhcmdzWzBdID0gKHVzZUNvbG9ycyA/ICclYycgOiAnJylcbiAgICArIHRoaXMubmFtZXNwYWNlXG4gICAgKyAodXNlQ29sb3JzID8gJyAlYycgOiAnICcpXG4gICAgKyBhcmdzWzBdXG4gICAgKyAodXNlQ29sb3JzID8gJyVjICcgOiAnICcpXG4gICAgKyAnKycgKyBleHBvcnRzLmh1bWFuaXplKHRoaXMuZGlmZik7XG5cbiAgaWYgKCF1c2VDb2xvcnMpIHJldHVybiBhcmdzO1xuXG4gIHZhciBjID0gJ2NvbG9yOiAnICsgdGhpcy5jb2xvcjtcbiAgYXJncyA9IFthcmdzWzBdLCBjLCAnY29sb3I6IGluaGVyaXQnXS5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncywgMSkpO1xuXG4gIC8vIHRoZSBmaW5hbCBcIiVjXCIgaXMgc29tZXdoYXQgdHJpY2t5LCBiZWNhdXNlIHRoZXJlIGNvdWxkIGJlIG90aGVyXG4gIC8vIGFyZ3VtZW50cyBwYXNzZWQgZWl0aGVyIGJlZm9yZSBvciBhZnRlciB0aGUgJWMsIHNvIHdlIG5lZWQgdG9cbiAgLy8gZmlndXJlIG91dCB0aGUgY29ycmVjdCBpbmRleCB0byBpbnNlcnQgdGhlIENTUyBpbnRvXG4gIHZhciBpbmRleCA9IDA7XG4gIHZhciBsYXN0QyA9IDA7XG4gIGFyZ3NbMF0ucmVwbGFjZSgvJVthLXolXS9nLCBmdW5jdGlvbihtYXRjaCkge1xuICAgIGlmICgnJSUnID09PSBtYXRjaCkgcmV0dXJuO1xuICAgIGluZGV4Kys7XG4gICAgaWYgKCclYycgPT09IG1hdGNoKSB7XG4gICAgICAvLyB3ZSBvbmx5IGFyZSBpbnRlcmVzdGVkIGluIHRoZSAqbGFzdCogJWNcbiAgICAgIC8vICh0aGUgdXNlciBtYXkgaGF2ZSBwcm92aWRlZCB0aGVpciBvd24pXG4gICAgICBsYXN0QyA9IGluZGV4O1xuICAgIH1cbiAgfSk7XG5cbiAgYXJncy5zcGxpY2UobGFzdEMsIDAsIGMpO1xuICByZXR1cm4gYXJncztcbn1cblxuLyoqXG4gKiBJbnZva2VzIGBjb25zb2xlLmxvZygpYCB3aGVuIGF2YWlsYWJsZS5cbiAqIE5vLW9wIHdoZW4gYGNvbnNvbGUubG9nYCBpcyBub3QgYSBcImZ1bmN0aW9uXCIuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBsb2coKSB7XG4gIC8vIHRoaXMgaGFja2VyeSBpcyByZXF1aXJlZCBmb3IgSUU4LzksIHdoZXJlXG4gIC8vIHRoZSBgY29uc29sZS5sb2dgIGZ1bmN0aW9uIGRvZXNuJ3QgaGF2ZSAnYXBwbHknXG4gIHJldHVybiAnb2JqZWN0JyA9PT0gdHlwZW9mIGNvbnNvbGVcbiAgICAmJiBjb25zb2xlLmxvZ1xuICAgICYmIEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKGNvbnNvbGUubG9nLCBjb25zb2xlLCBhcmd1bWVudHMpO1xufVxuXG4vKipcbiAqIFNhdmUgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lc3BhY2VzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzYXZlKG5hbWVzcGFjZXMpIHtcbiAgdHJ5IHtcbiAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2VzKSB7XG4gICAgICBleHBvcnRzLnN0b3JhZ2UucmVtb3ZlSXRlbSgnZGVidWcnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhwb3J0cy5zdG9yYWdlLmRlYnVnID0gbmFtZXNwYWNlcztcbiAgICB9XG4gIH0gY2F0Y2goZSkge31cbn1cblxuLyoqXG4gKiBMb2FkIGBuYW1lc3BhY2VzYC5cbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHJldHVybnMgdGhlIHByZXZpb3VzbHkgcGVyc2lzdGVkIGRlYnVnIG1vZGVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2FkKCkge1xuICB2YXIgcjtcbiAgdHJ5IHtcbiAgICByID0gZXhwb3J0cy5zdG9yYWdlLmRlYnVnO1xuICB9IGNhdGNoKGUpIHt9XG4gIHJldHVybiByO1xufVxuXG4vKipcbiAqIEVuYWJsZSBuYW1lc3BhY2VzIGxpc3RlZCBpbiBgbG9jYWxTdG9yYWdlLmRlYnVnYCBpbml0aWFsbHkuXG4gKi9cblxuZXhwb3J0cy5lbmFibGUobG9hZCgpKTtcblxuLyoqXG4gKiBMb2NhbHN0b3JhZ2UgYXR0ZW1wdHMgdG8gcmV0dXJuIHRoZSBsb2NhbHN0b3JhZ2UuXG4gKlxuICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBzYWZhcmkgdGhyb3dzXG4gKiB3aGVuIGEgdXNlciBkaXNhYmxlcyBjb29raWVzL2xvY2Fsc3RvcmFnZVxuICogYW5kIHlvdSBhdHRlbXB0IHRvIGFjY2VzcyBpdC5cbiAqXG4gKiBAcmV0dXJuIHtMb2NhbFN0b3JhZ2V9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2NhbHN0b3JhZ2UoKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZTtcbiAgfSBjYXRjaCAoZSkge31cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8233\n")},"834b":function(module,exports,__webpack_require__){eval('/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies\n */\n\nvar XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ "86e3");\nvar XHR = __webpack_require__(/*! ./polling-xhr */ "108d");\nvar JSONP = __webpack_require__(/*! ./polling-jsonp */ "2dce");\nvar websocket = __webpack_require__(/*! ./websocket */ "6b20");\n\n/**\n * Export transports.\n */\n\nexports.polling = polling;\nexports.websocket = websocket;\n\n/**\n * Polling transport polymorphic constructor.\n * Decides on xhr vs jsonp based on feature detection.\n *\n * @api private\n */\n\nfunction polling (opts) {\n  var xhr;\n  var xd = false;\n  var xs = false;\n  var jsonp = false !== opts.jsonp;\n\n  if (global.location) {\n    var isSSL = \'https:\' === location.protocol;\n    var port = location.port;\n\n    // some user agents have empty `location.port`\n    if (!port) {\n      port = isSSL ? 443 : 80;\n    }\n\n    xd = opts.hostname !== location.hostname || port !== opts.port;\n    xs = opts.secure !== isSSL;\n  }\n\n  opts.xdomain = xd;\n  opts.xscheme = xs;\n  xhr = new XMLHttpRequest(opts);\n\n  if (\'open\' in xhr && !opts.forceJSONP) {\n    return new XHR(opts);\n  } else {\n    if (!jsonp) throw new Error(\'JSONP disabled\');\n    return new JSONP(opts);\n  }\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ "698d")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODM0Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9pbmRleC5qcz84OTk2Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llc1xuICovXG5cbnZhciBYTUxIdHRwUmVxdWVzdCA9IHJlcXVpcmUoJ3htbGh0dHByZXF1ZXN0LXNzbCcpO1xudmFyIFhIUiA9IHJlcXVpcmUoJy4vcG9sbGluZy14aHInKTtcbnZhciBKU09OUCA9IHJlcXVpcmUoJy4vcG9sbGluZy1qc29ucCcpO1xudmFyIHdlYnNvY2tldCA9IHJlcXVpcmUoJy4vd2Vic29ja2V0Jyk7XG5cbi8qKlxuICogRXhwb3J0IHRyYW5zcG9ydHMuXG4gKi9cblxuZXhwb3J0cy5wb2xsaW5nID0gcG9sbGluZztcbmV4cG9ydHMud2Vic29ja2V0ID0gd2Vic29ja2V0O1xuXG4vKipcbiAqIFBvbGxpbmcgdHJhbnNwb3J0IHBvbHltb3JwaGljIGNvbnN0cnVjdG9yLlxuICogRGVjaWRlcyBvbiB4aHIgdnMganNvbnAgYmFzZWQgb24gZmVhdHVyZSBkZXRlY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcG9sbGluZyAob3B0cykge1xuICB2YXIgeGhyO1xuICB2YXIgeGQgPSBmYWxzZTtcbiAgdmFyIHhzID0gZmFsc2U7XG4gIHZhciBqc29ucCA9IGZhbHNlICE9PSBvcHRzLmpzb25wO1xuXG4gIGlmIChnbG9iYWwubG9jYXRpb24pIHtcbiAgICB2YXIgaXNTU0wgPSAnaHR0cHM6JyA9PT0gbG9jYXRpb24ucHJvdG9jb2w7XG4gICAgdmFyIHBvcnQgPSBsb2NhdGlvbi5wb3J0O1xuXG4gICAgLy8gc29tZSB1c2VyIGFnZW50cyBoYXZlIGVtcHR5IGBsb2NhdGlvbi5wb3J0YFxuICAgIGlmICghcG9ydCkge1xuICAgICAgcG9ydCA9IGlzU1NMID8gNDQzIDogODA7XG4gICAgfVxuXG4gICAgeGQgPSBvcHRzLmhvc3RuYW1lICE9PSBsb2NhdGlvbi5ob3N0bmFtZSB8fCBwb3J0ICE9PSBvcHRzLnBvcnQ7XG4gICAgeHMgPSBvcHRzLnNlY3VyZSAhPT0gaXNTU0w7XG4gIH1cblxuICBvcHRzLnhkb21haW4gPSB4ZDtcbiAgb3B0cy54c2NoZW1lID0geHM7XG4gIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdChvcHRzKTtcblxuICBpZiAoJ29wZW4nIGluIHhociAmJiAhb3B0cy5mb3JjZUpTT05QKSB7XG4gICAgcmV0dXJuIG5ldyBYSFIob3B0cyk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFqc29ucCkgdGhyb3cgbmV3IEVycm9yKCdKU09OUCBkaXNhYmxlZCcpO1xuICAgIHJldHVybiBuZXcgSlNPTlAob3B0cyk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///834b\n')},"86e3":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {// browser shim for xmlhttprequest module\n\nvar hasCORS = __webpack_require__(/*! has-cors */ \"0392\");\n\nmodule.exports = function (opts) {\n  var xdomain = opts.xdomain;\n\n  // scheme must be same when usign XDomainRequest\n  // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx\n  var xscheme = opts.xscheme;\n\n  // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.\n  // https://github.com/Automattic/engine.io-client/pull/217\n  var enablesXDR = opts.enablesXDR;\n\n  // XMLHttpRequest can be disabled on IE\n  try {\n    if ('undefined' !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {\n      return new XMLHttpRequest();\n    }\n  } catch (e) { }\n\n  // Use XDomainRequest for IE8 if enablesXDR is true\n  // because loading bar keeps flashing when using jsonp-polling\n  // https://github.com/yujiosaka/socke.io-ie8-loading-example\n  try {\n    if ('undefined' !== typeof XDomainRequest && !xscheme && enablesXDR) {\n      return new XDomainRequest();\n    }\n  } catch (e) { }\n\n  if (!xdomain) {\n    try {\n      return new global[['Active'].concat('Object').join('X')]('Microsoft.XMLHTTP');\n    } catch (e) { }\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODZlMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIveG1saHR0cHJlcXVlc3QuanM/NzY2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBicm93c2VyIHNoaW0gZm9yIHhtbGh0dHByZXF1ZXN0IG1vZHVsZVxuXG52YXIgaGFzQ09SUyA9IHJlcXVpcmUoJ2hhcy1jb3JzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgdmFyIHhkb21haW4gPSBvcHRzLnhkb21haW47XG5cbiAgLy8gc2NoZW1lIG11c3QgYmUgc2FtZSB3aGVuIHVzaWduIFhEb21haW5SZXF1ZXN0XG4gIC8vIGh0dHA6Ly9ibG9ncy5tc2RuLmNvbS9iL2llaW50ZXJuYWxzL2FyY2hpdmUvMjAxMC8wNS8xMy94ZG9tYWlucmVxdWVzdC1yZXN0cmljdGlvbnMtbGltaXRhdGlvbnMtYW5kLXdvcmthcm91bmRzLmFzcHhcbiAgdmFyIHhzY2hlbWUgPSBvcHRzLnhzY2hlbWU7XG5cbiAgLy8gWERvbWFpblJlcXVlc3QgaGFzIGEgZmxvdyBvZiBub3Qgc2VuZGluZyBjb29raWUsIHRoZXJlZm9yZSBpdCBzaG91bGQgYmUgZGlzYWJsZWQgYXMgYSBkZWZhdWx0LlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vQXV0b21hdHRpYy9lbmdpbmUuaW8tY2xpZW50L3B1bGwvMjE3XG4gIHZhciBlbmFibGVzWERSID0gb3B0cy5lbmFibGVzWERSO1xuXG4gIC8vIFhNTEh0dHBSZXF1ZXN0IGNhbiBiZSBkaXNhYmxlZCBvbiBJRVxuICB0cnkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIFhNTEh0dHBSZXF1ZXN0ICYmICgheGRvbWFpbiB8fCBoYXNDT1JTKSkge1xuICAgICAgcmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkgeyB9XG5cbiAgLy8gVXNlIFhEb21haW5SZXF1ZXN0IGZvciBJRTggaWYgZW5hYmxlc1hEUiBpcyB0cnVlXG4gIC8vIGJlY2F1c2UgbG9hZGluZyBiYXIga2VlcHMgZmxhc2hpbmcgd2hlbiB1c2luZyBqc29ucC1wb2xsaW5nXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS95dWppb3Nha2Evc29ja2UuaW8taWU4LWxvYWRpbmctZXhhbXBsZVxuICB0cnkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIFhEb21haW5SZXF1ZXN0ICYmICF4c2NoZW1lICYmIGVuYWJsZXNYRFIpIHtcbiAgICAgIHJldHVybiBuZXcgWERvbWFpblJlcXVlc3QoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHsgfVxuXG4gIGlmICgheGRvbWFpbikge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbmV3IGdsb2JhbFtbJ0FjdGl2ZSddLmNvbmNhdCgnT2JqZWN0Jykuam9pbignWCcpXSgnTWljcm9zb2Z0LlhNTEhUVFAnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbiAgfVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///86e3\n")},9083:function(module,exports,__webpack_require__){eval("/**\n * A `Group` represents a value a `Facet` can take using a partitioning.\n * For continuous or time facets, it represents an interval.\n * For categorial facets, it is a single label.\n *\n * The `Facet.groups` collection is used for plotting, to deterime the postion along the axis.\n * Selections can be updated using a `Group`.\n *\n * @extends Base\n * @class Group\n */\nvar Base = __webpack_require__(/*! ../util/base */ \"3902\");\nvar moment = __webpack_require__(/*! moment */ \"da01\");\n\nmodule.exports = Base.extend({\n  dataTypes: {\n    'numberDatetimeOrDuration': {\n      set: function (value) {\n        var newValue;\n\n        // check for momentjs objects\n        if (moment.isDuration(value)) {\n          return {\n            val: moment.duration(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (moment.isMoment(value)) {\n          return {\n            val: moment(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to create momentjs objects\n        newValue = moment(value, moment.ISO_8601);\n        if (newValue.isValid()) {\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          newValue = moment.duration(value);\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to set a number\n        if (value === +value) {\n          return {\n            val: +value,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // failed..\n        return {\n          val: value,\n          type: typeof value\n        };\n      },\n      compare: function (currentVal, newVal) {\n        if (currentVal instanceof moment) {\n          return currentVal.isSame(newVal);\n        } else {\n          return +currentVal === +newVal;\n        }\n      }\n    }\n  },\n  props: {\n    /**\n     * For continuous, datetime, or duration facets. Lower limit of interval\n     * @type {number|moment}\n     * @memberof! Group\n     */\n    min: 'numberDatetimeOrDuration',\n\n    /**\n     * For continuous, datetime, or duration facets. Upper limit of interval\n     * @type {number|moment}\n     * @memberof! Group\n     */\n    max: 'numberDatetimeOrDuration',\n\n    /**\n     * Number of times this transform is used\n     * @type {number}\n     * @memberof! Group\n     */\n    count: ['number', true, 0],\n\n    /**\n     * Label for display\n     * @type {string}\n     * @memberof! Group\n     */\n    label: ['string', true, 'label'],\n\n    /**\n     * A value guaranteed to be in this group, used to check if this group is currently selected.\n     * moments and durations should be stored as moment.format() and duration.toISOString()\n     * @type {string|number}\n     * @memberof! Group\n     */\n    value: 'any',\n\n    /**\n     * Index, cached version of groups.models.indexOf(group)\n     * @type {number}\n     * @memberof! Group\n     */\n    groupIndex: 'number'\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2dyb3VwLmpzPzEwNGMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBIGBHcm91cGAgcmVwcmVzZW50cyBhIHZhbHVlIGEgYEZhY2V0YCBjYW4gdGFrZSB1c2luZyBhIHBhcnRpdGlvbmluZy5cbiAqIEZvciBjb250aW51b3VzIG9yIHRpbWUgZmFjZXRzLCBpdCByZXByZXNlbnRzIGFuIGludGVydmFsLlxuICogRm9yIGNhdGVnb3JpYWwgZmFjZXRzLCBpdCBpcyBhIHNpbmdsZSBsYWJlbC5cbiAqXG4gKiBUaGUgYEZhY2V0Lmdyb3Vwc2AgY29sbGVjdGlvbiBpcyB1c2VkIGZvciBwbG90dGluZywgdG8gZGV0ZXJpbWUgdGhlIHBvc3Rpb24gYWxvbmcgdGhlIGF4aXMuXG4gKiBTZWxlY3Rpb25zIGNhbiBiZSB1cGRhdGVkIHVzaW5nIGEgYEdyb3VwYC5cbiAqXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKiBAY2xhc3MgR3JvdXBcbiAqL1xudmFyIEJhc2UgPSByZXF1aXJlKCcuLi91dGlsL2Jhc2UnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlLmV4dGVuZCh7XG4gIGRhdGFUeXBlczoge1xuICAgICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nOiB7XG4gICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIG1vbWVudGpzIG9iamVjdHNcbiAgICAgICAgaWYgKG1vbWVudC5pc0R1cmF0aW9uKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG1vbWVudC5kdXJhdGlvbih2YWx1ZSksXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vbWVudC5pc01vbWVudCh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsOiBtb21lbnQodmFsdWUpLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIGNyZWF0ZSBtb21lbnRqcyBvYmplY3RzXG4gICAgICAgIG5ld1ZhbHVlID0gbW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICBpZiAobmV3VmFsdWUuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbDogbmV3VmFsdWUsXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSB7XG4gICAgICAgICAgbmV3VmFsdWUgPSBtb21lbnQuZHVyYXRpb24odmFsdWUpO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG5ld1ZhbHVlLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIHNldCBhIG51bWJlclxuICAgICAgICBpZiAodmFsdWUgPT09ICt2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6ICt2YWx1ZSxcbiAgICAgICAgICAgIHR5cGU6ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZhaWxlZC4uXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsOiB2YWx1ZSxcbiAgICAgICAgICB0eXBlOiB0eXBlb2YgdmFsdWVcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBjb21wYXJlOiBmdW5jdGlvbiAoY3VycmVudFZhbCwgbmV3VmFsKSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsIGluc3RhbmNlb2YgbW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuIGN1cnJlbnRWYWwuaXNTYW1lKG5ld1ZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICtjdXJyZW50VmFsID09PSArbmV3VmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzLCBkYXRldGltZSwgb3IgZHVyYXRpb24gZmFjZXRzLiBMb3dlciBsaW1pdCBvZiBpbnRlcnZhbFxuICAgICAqIEB0eXBlIHtudW1iZXJ8bW9tZW50fVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICBtaW46ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMsIGRhdGV0aW1lLCBvciBkdXJhdGlvbiBmYWNldHMuIFVwcGVyIGxpbWl0IG9mIGludGVydmFsXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIG1heDogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbicsXG5cbiAgICAvKipcbiAgICAgKiBOdW1iZXIgb2YgdGltZXMgdGhpcyB0cmFuc2Zvcm0gaXMgdXNlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIGNvdW50OiBbJ251bWJlcicsIHRydWUsIDBdLFxuXG4gICAgLyoqXG4gICAgICogTGFiZWwgZm9yIGRpc3BsYXlcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICBsYWJlbDogWydzdHJpbmcnLCB0cnVlLCAnbGFiZWwnXSxcblxuICAgIC8qKlxuICAgICAqIEEgdmFsdWUgZ3VhcmFudGVlZCB0byBiZSBpbiB0aGlzIGdyb3VwLCB1c2VkIHRvIGNoZWNrIGlmIHRoaXMgZ3JvdXAgaXMgY3VycmVudGx5IHNlbGVjdGVkLlxuICAgICAqIG1vbWVudHMgYW5kIGR1cmF0aW9ucyBzaG91bGQgYmUgc3RvcmVkIGFzIG1vbWVudC5mb3JtYXQoKSBhbmQgZHVyYXRpb24udG9JU09TdHJpbmcoKVxuICAgICAqIEB0eXBlIHtzdHJpbmd8bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICB2YWx1ZTogJ2FueScsXG5cbiAgICAvKipcbiAgICAgKiBJbmRleCwgY2FjaGVkIHZlcnNpb24gb2YgZ3JvdXBzLm1vZGVscy5pbmRleE9mKGdyb3VwKVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIGdyb3VwSW5kZXg6ICdudW1iZXInXG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9083\n")},"939f":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Create a blob builder even when vendor prefixes exist\n */\n\nvar BlobBuilder = global.BlobBuilder\n  || global.WebKitBlobBuilder\n  || global.MSBlobBuilder\n  || global.MozBlobBuilder;\n\n/**\n * Check if Blob constructor is supported\n */\n\nvar blobSupported = (function() {\n  try {\n    var a = new Blob(['hi']);\n    return a.size === 2;\n  } catch(e) {\n    return false;\n  }\n})();\n\n/**\n * Check if Blob constructor supports ArrayBufferViews\n * Fails in Safari 6, so we need to map to ArrayBuffers there.\n */\n\nvar blobSupportsArrayBufferView = blobSupported && (function() {\n  try {\n    var b = new Blob([new Uint8Array([1,2])]);\n    return b.size === 2;\n  } catch(e) {\n    return false;\n  }\n})();\n\n/**\n * Check if BlobBuilder is supported\n */\n\nvar blobBuilderSupported = BlobBuilder\n  && BlobBuilder.prototype.append\n  && BlobBuilder.prototype.getBlob;\n\n/**\n * Helper function that maps ArrayBufferViews to ArrayBuffers\n * Used by BlobBuilder constructor and old browsers that didn't\n * support it in the Blob constructor.\n */\n\nfunction mapArrayBufferViews(ary) {\n  for (var i = 0; i < ary.length; i++) {\n    var chunk = ary[i];\n    if (chunk.buffer instanceof ArrayBuffer) {\n      var buf = chunk.buffer;\n\n      // if this is a subarray, make a copy so we only\n      // include the subarray region from the underlying buffer\n      if (chunk.byteLength !== buf.byteLength) {\n        var copy = new Uint8Array(chunk.byteLength);\n        copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength));\n        buf = copy.buffer;\n      }\n\n      ary[i] = buf;\n    }\n  }\n}\n\nfunction BlobBuilderConstructor(ary, options) {\n  options = options || {};\n\n  var bb = new BlobBuilder();\n  mapArrayBufferViews(ary);\n\n  for (var i = 0; i < ary.length; i++) {\n    bb.append(ary[i]);\n  }\n\n  return (options.type) ? bb.getBlob(options.type) : bb.getBlob();\n};\n\nfunction BlobConstructor(ary, options) {\n  mapArrayBufferViews(ary);\n  return new Blob(ary, options || {});\n};\n\nmodule.exports = (function() {\n  if (blobSupported) {\n    return blobSupportsArrayBufferView ? global.Blob : BlobConstructor;\n  } else if (blobBuilderSupported) {\n    return BlobBuilderConstructor;\n  } else {\n    return undefined;\n  }\n})();\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM5Zi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvYmxvYi9pbmRleC5qcz8yMTA3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ3JlYXRlIGEgYmxvYiBidWlsZGVyIGV2ZW4gd2hlbiB2ZW5kb3IgcHJlZml4ZXMgZXhpc3RcbiAqL1xuXG52YXIgQmxvYkJ1aWxkZXIgPSBnbG9iYWwuQmxvYkJ1aWxkZXJcbiAgfHwgZ2xvYmFsLldlYktpdEJsb2JCdWlsZGVyXG4gIHx8IGdsb2JhbC5NU0Jsb2JCdWlsZGVyXG4gIHx8IGdsb2JhbC5Nb3pCbG9iQnVpbGRlcjtcblxuLyoqXG4gKiBDaGVjayBpZiBCbG9iIGNvbnN0cnVjdG9yIGlzIHN1cHBvcnRlZFxuICovXG5cbnZhciBibG9iU3VwcG9ydGVkID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIHZhciBhID0gbmV3IEJsb2IoWydoaSddKTtcbiAgICByZXR1cm4gYS5zaXplID09PSAyO1xuICB9IGNhdGNoKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8qKlxuICogQ2hlY2sgaWYgQmxvYiBjb25zdHJ1Y3RvciBzdXBwb3J0cyBBcnJheUJ1ZmZlclZpZXdzXG4gKiBGYWlscyBpbiBTYWZhcmkgNiwgc28gd2UgbmVlZCB0byBtYXAgdG8gQXJyYXlCdWZmZXJzIHRoZXJlLlxuICovXG5cbnZhciBibG9iU3VwcG9ydHNBcnJheUJ1ZmZlclZpZXcgPSBibG9iU3VwcG9ydGVkICYmIChmdW5jdGlvbigpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYiA9IG5ldyBCbG9iKFtuZXcgVWludDhBcnJheShbMSwyXSldKTtcbiAgICByZXR1cm4gYi5zaXplID09PSAyO1xuICB9IGNhdGNoKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8qKlxuICogQ2hlY2sgaWYgQmxvYkJ1aWxkZXIgaXMgc3VwcG9ydGVkXG4gKi9cblxudmFyIGJsb2JCdWlsZGVyU3VwcG9ydGVkID0gQmxvYkJ1aWxkZXJcbiAgJiYgQmxvYkJ1aWxkZXIucHJvdG90eXBlLmFwcGVuZFxuICAmJiBCbG9iQnVpbGRlci5wcm90b3R5cGUuZ2V0QmxvYjtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBtYXBzIEFycmF5QnVmZmVyVmlld3MgdG8gQXJyYXlCdWZmZXJzXG4gKiBVc2VkIGJ5IEJsb2JCdWlsZGVyIGNvbnN0cnVjdG9yIGFuZCBvbGQgYnJvd3NlcnMgdGhhdCBkaWRuJ3RcbiAqIHN1cHBvcnQgaXQgaW4gdGhlIEJsb2IgY29uc3RydWN0b3IuXG4gKi9cblxuZnVuY3Rpb24gbWFwQXJyYXlCdWZmZXJWaWV3cyhhcnkpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnkubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgY2h1bmsgPSBhcnlbaV07XG4gICAgaWYgKGNodW5rLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICB2YXIgYnVmID0gY2h1bmsuYnVmZmVyO1xuXG4gICAgICAvLyBpZiB0aGlzIGlzIGEgc3ViYXJyYXksIG1ha2UgYSBjb3B5IHNvIHdlIG9ubHlcbiAgICAgIC8vIGluY2x1ZGUgdGhlIHN1YmFycmF5IHJlZ2lvbiBmcm9tIHRoZSB1bmRlcmx5aW5nIGJ1ZmZlclxuICAgICAgaWYgKGNodW5rLmJ5dGVMZW5ndGggIT09IGJ1Zi5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHZhciBjb3B5ID0gbmV3IFVpbnQ4QXJyYXkoY2h1bmsuYnl0ZUxlbmd0aCk7XG4gICAgICAgIGNvcHkuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZiwgY2h1bmsuYnl0ZU9mZnNldCwgY2h1bmsuYnl0ZUxlbmd0aCkpO1xuICAgICAgICBidWYgPSBjb3B5LmJ1ZmZlcjtcbiAgICAgIH1cblxuICAgICAgYXJ5W2ldID0gYnVmO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBCbG9iQnVpbGRlckNvbnN0cnVjdG9yKGFyeSwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgYmIgPSBuZXcgQmxvYkJ1aWxkZXIoKTtcbiAgbWFwQXJyYXlCdWZmZXJWaWV3cyhhcnkpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgYmIuYXBwZW5kKGFyeVtpXSk7XG4gIH1cblxuICByZXR1cm4gKG9wdGlvbnMudHlwZSkgPyBiYi5nZXRCbG9iKG9wdGlvbnMudHlwZSkgOiBiYi5nZXRCbG9iKCk7XG59O1xuXG5mdW5jdGlvbiBCbG9iQ29uc3RydWN0b3IoYXJ5LCBvcHRpb25zKSB7XG4gIG1hcEFycmF5QnVmZmVyVmlld3MoYXJ5KTtcbiAgcmV0dXJuIG5ldyBCbG9iKGFyeSwgb3B0aW9ucyB8fCB7fSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IChmdW5jdGlvbigpIHtcbiAgaWYgKGJsb2JTdXBwb3J0ZWQpIHtcbiAgICByZXR1cm4gYmxvYlN1cHBvcnRzQXJyYXlCdWZmZXJWaWV3ID8gZ2xvYmFsLkJsb2IgOiBCbG9iQ29uc3RydWN0b3I7XG4gIH0gZWxzZSBpZiAoYmxvYkJ1aWxkZXJTdXBwb3J0ZWQpIHtcbiAgICByZXR1cm4gQmxvYkJ1aWxkZXJDb25zdHJ1Y3RvcjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59KSgpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///939f\n")},9476:function(module,exports,__webpack_require__){eval("/**\n * A filter provides a chart with an interface to the data.\n * The filter contains a number of `Partition`s and `Aggregate`s.\n * It takes care of calling the relevant functions provided by a `Dataset`.\n *\n * @class Filter\n * @extends Base\n */\n\n/**\n * @typedef {Object} DataRecord - Object holding the plot data, partitions are labelled with a single small letter, aggregates with a double small letter\n * @property {string} DataRecord.a Value of first partition\n * @property {string} DataRecord.b Value of second partition\n * @property {string} DataRecord.c Value of third partition, etc.\n * @property {string} DataRecord.aa Value of first aggregate\n * @property {string} DataRecord.bb Value of second aggregate, etc.\n */\n\n/**\n * @typedef {DataRecord[]} Data - Array of DataRecords\n */\n\nvar Base = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Aggregates = __webpack_require__(/*! ./aggregate/collection */ \"fbef\");\nvar Partitions = __webpack_require__(/*! ./partition/collection */ \"e59a\");\n\nmodule.exports = Base.extend({\n  props: {\n    /**\n     * Hint for the client (website) how to visualize this filter\n     * @memberof! Filter\n     * @type {string}\n     */\n    chartType: {\n      type: 'string',\n      required: true,\n      default: 'barchart',\n      values: ['piechart', 'horizontalbarchart', 'barchart', 'linechart', 'radarchart', 'polarareachart', 'bubbleplot', 'scatterchart', 'networkchart']\n    },\n    /**\n     * Title for displaying purposes\n     * @memberof! Filter\n     * @type {string}\n     */\n    title: ['string', true, ''],\n    /**\n     * Hint for the client (website) how to position the chart for this filter\n     * position (col, row) and size (size_x, size_y) of chart\n     */\n    col: 'number',\n    row: 'number',\n    size_x: 'number',\n    size_y: 'number'\n  },\n  collections: {\n    /**\n     * @memberof! Filter\n     * @type {Partitions[]}\n     */\n    partitions: Partitions,\n    /**\n     * @memberof! Filter\n     * @type {Aggregate[]}\n     */\n    aggregates: Aggregates\n  },\n  // Session properties are not typically persisted to the server,\n  // and are not returned by calls to toJSON() or serialize().\n  session: {\n    /**\n     * Array containing the data to plot\n     * @memberof! Filter\n     * @type {Data}\n     */\n    data: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    },\n    /*\n     * Call this function to request new data.\n     * The dataset backing the facet will copy the data to Filter.data.\n     * A newData event is fired when the data is ready to be plotted.\n     *\n     * @function\n     * @virtual\n     * @private\n     * @memberof! Filter\n     * @emits newData\n     */\n    getData: {\n      type: 'any'\n    },\n    /**\n     * A history of the current drill-down (ie. partitions.toJSON())\n     */\n    zoomHistory: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    },\n    /**\n     * Boolean indicating if the filter is initialized\n     */\n    isInitialized: {\n      type: 'boolean',\n      required: true,\n      default: false\n    }\n  },\n  initialize: function () {\n    // set up callback to free internal state on remove\n    this.on('remove', function () {\n      this.releaseDataFilter();\n    });\n  },\n  zoomIn: function () {\n    this.releaseDataFilter();\n\n    // save current state\n    this.zoomHistory.push(JSON.stringify(this.partitions.toJSON()));\n\n    this.partitions.forEach(function (partition) {\n      if ((partition.selected.length === 2) && (partition.isDatetime || partition.isContinuous)) {\n        if (partition.groupFixedS || partition.groupFixedSC) {\n          // scale down binsize\n          var newSize = partition.selected[1] - partition.selected[0];\n          var oldSize = partition.maxval - partition.minval;\n          partition.groupingParam = partition.groupingParam * newSize / oldSize;\n        }\n        // zoom to selected range, if possible\n        partition.set({\n          minval: partition.selected[0],\n          maxval: partition.selected[1]\n        });\n      } else if (partition.selected.length > 0 && (partition.isCategorial)) {\n        // zoom to selected categories, if possible\n        partition.groups.reset();\n        partition.selected.forEach(function (value) {\n          partition.groups.add({\n            value: value,\n            label: value,\n            count: 0,\n            isSelected: true\n          });\n        });\n      }\n      // select all\n      partition.updateSelection();\n    });\n    this.initDataFilter();\n    this.updateDataFilter(); // also triggers a getAllData()\n  },\n  zoomOut: function () {\n    var doReset = true;\n\n    // clear current selection\n    this.partitions.forEach(function (partition) {\n      if (partition.selected.length > 0) {\n        partition.updateSelection();\n        doReset = false;\n      }\n    });\n\n    if (doReset) {\n      this.releaseDataFilter();\n      if (this.zoomHistory.length > 0) {\n        // nothing was selected and we have drilled down: go up\n        var state = JSON.parse(this.zoomHistory.pop());\n        this.partitions.reset(state);\n      } else {\n        // nothing was selected and no drill down: reset partitioning\n        this.partitions.forEach(function (partition) {\n          if (partition.isDatetime || partition.isContinuous) {\n            partition.reset();\n          }\n        });\n      }\n      this.initDataFilter();\n    }\n    this.updateDataFilter(); // also triggers a getAllData()\n  },\n  // Apply the separate filterFunctions from each partition in a single function\n  filterFunction: function () {\n    var fs = [];\n    this.partitions.forEach(function (partition) {\n      fs.push(partition.filterFunction());\n    });\n    return function (d) {\n      if (typeof d === 'string') {\n        var groups = d.split('|');\n        return fs.every(function (f, i) { return f(groups[i]); });\n      } else {\n        // shortcut for non-partitioned numeric data\n        return fs[0](d);\n      }\n    };\n  },\n  /**\n   * Initialize the data filter, and construct the getData callback function on the filter.\n   *\n   * @memberof! Filter\n   */\n  initDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.releaseDataFilter(dataview, this);\n    spot.driver.initDataFilter(dataview, this);\n    spot.driver.updateDataFilter(this);\n\n    this.isInitialized = true;\n  },\n  /**\n   * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n   * related to the filter.\n   *\n   * @memberof! Filter\n   */\n  releaseDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.releaseDataFilter(dataview, this);\n\n    this.isInitialized = false;\n  },\n  /**\n   * Apply changes to the filter (like selecting groups)\n   *\n   * @memberof! Filter\n   */\n  updateDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.updateDataFilter(this);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ3Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmlsdGVyLmpzPzM4ZmYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBIGZpbHRlciBwcm92aWRlcyBhIGNoYXJ0IHdpdGggYW4gaW50ZXJmYWNlIHRvIHRoZSBkYXRhLlxuICogVGhlIGZpbHRlciBjb250YWlucyBhIG51bWJlciBvZiBgUGFydGl0aW9uYHMgYW5kIGBBZ2dyZWdhdGVgcy5cbiAqIEl0IHRha2VzIGNhcmUgb2YgY2FsbGluZyB0aGUgcmVsZXZhbnQgZnVuY3Rpb25zIHByb3ZpZGVkIGJ5IGEgYERhdGFzZXRgLlxuICpcbiAqIEBjbGFzcyBGaWx0ZXJcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IERhdGFSZWNvcmQgLSBPYmplY3QgaG9sZGluZyB0aGUgcGxvdCBkYXRhLCBwYXJ0aXRpb25zIGFyZSBsYWJlbGxlZCB3aXRoIGEgc2luZ2xlIHNtYWxsIGxldHRlciwgYWdncmVnYXRlcyB3aXRoIGEgZG91YmxlIHNtYWxsIGxldHRlclxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYSBWYWx1ZSBvZiBmaXJzdCBwYXJ0aXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEYXRhUmVjb3JkLmIgVmFsdWUgb2Ygc2Vjb25kIHBhcnRpdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYyBWYWx1ZSBvZiB0aGlyZCBwYXJ0aXRpb24sIGV0Yy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEYXRhUmVjb3JkLmFhIFZhbHVlIG9mIGZpcnN0IGFnZ3JlZ2F0ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYmIgVmFsdWUgb2Ygc2Vjb25kIGFnZ3JlZ2F0ZSwgZXRjLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge0RhdGFSZWNvcmRbXX0gRGF0YSAtIEFycmF5IG9mIERhdGFSZWNvcmRzXG4gKi9cblxudmFyIEJhc2UgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIEFnZ3JlZ2F0ZXMgPSByZXF1aXJlKCcuL2FnZ3JlZ2F0ZS9jb2xsZWN0aW9uJyk7XG52YXIgUGFydGl0aW9ucyA9IHJlcXVpcmUoJy4vcGFydGl0aW9uL2NvbGxlY3Rpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogSGludCBmb3IgdGhlIGNsaWVudCAod2Vic2l0ZSkgaG93IHRvIHZpc3VhbGl6ZSB0aGlzIGZpbHRlclxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBjaGFydFR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnYmFyY2hhcnQnLFxuICAgICAgdmFsdWVzOiBbJ3BpZWNoYXJ0JywgJ2hvcml6b250YWxiYXJjaGFydCcsICdiYXJjaGFydCcsICdsaW5lY2hhcnQnLCAncmFkYXJjaGFydCcsICdwb2xhcmFyZWFjaGFydCcsICdidWJibGVwbG90JywgJ3NjYXR0ZXJjaGFydCcsICduZXR3b3JrY2hhcnQnXVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGl0bGUgZm9yIGRpc3BsYXlpbmcgcHVycG9zZXNcbiAgICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGl0bGU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuICAgIC8qKlxuICAgICAqIEhpbnQgZm9yIHRoZSBjbGllbnQgKHdlYnNpdGUpIGhvdyB0byBwb3NpdGlvbiB0aGUgY2hhcnQgZm9yIHRoaXMgZmlsdGVyXG4gICAgICogcG9zaXRpb24gKGNvbCwgcm93KSBhbmQgc2l6ZSAoc2l6ZV94LCBzaXplX3kpIG9mIGNoYXJ0XG4gICAgICovXG4gICAgY29sOiAnbnVtYmVyJyxcbiAgICByb3c6ICdudW1iZXInLFxuICAgIHNpemVfeDogJ251bWJlcicsXG4gICAgc2l6ZV95OiAnbnVtYmVyJ1xuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge1BhcnRpdGlvbnNbXX1cbiAgICAgKi9cbiAgICBwYXJ0aXRpb25zOiBQYXJ0aXRpb25zLFxuICAgIC8qKlxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge0FnZ3JlZ2F0ZVtdfVxuICAgICAqL1xuICAgIGFnZ3JlZ2F0ZXM6IEFnZ3JlZ2F0ZXNcbiAgfSxcbiAgLy8gU2Vzc2lvbiBwcm9wZXJ0aWVzIGFyZSBub3QgdHlwaWNhbGx5IHBlcnNpc3RlZCB0byB0aGUgc2VydmVyLFxuICAvLyBhbmQgYXJlIG5vdCByZXR1cm5lZCBieSBjYWxscyB0byB0b0pTT04oKSBvciBzZXJpYWxpemUoKS5cbiAgc2Vzc2lvbjoge1xuICAgIC8qKlxuICAgICAqIEFycmF5IGNvbnRhaW5pbmcgdGhlIGRhdGEgdG8gcGxvdFxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge0RhdGF9XG4gICAgICovXG4gICAgZGF0YToge1xuICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0sXG4gICAgLypcbiAgICAgKiBDYWxsIHRoaXMgZnVuY3Rpb24gdG8gcmVxdWVzdCBuZXcgZGF0YS5cbiAgICAgKiBUaGUgZGF0YXNldCBiYWNraW5nIHRoZSBmYWNldCB3aWxsIGNvcHkgdGhlIGRhdGEgdG8gRmlsdGVyLmRhdGEuXG4gICAgICogQSBuZXdEYXRhIGV2ZW50IGlzIGZpcmVkIHdoZW4gdGhlIGRhdGEgaXMgcmVhZHkgdG8gYmUgcGxvdHRlZC5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEB2aXJ0dWFsXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgICAqIEBlbWl0cyBuZXdEYXRhXG4gICAgICovXG4gICAgZ2V0RGF0YToge1xuICAgICAgdHlwZTogJ2FueSdcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIEEgaGlzdG9yeSBvZiB0aGUgY3VycmVudCBkcmlsbC1kb3duIChpZS4gcGFydGl0aW9ucy50b0pTT04oKSlcbiAgICAgKi9cbiAgICB6b29tSGlzdG9yeToge1xuICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogQm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSBmaWx0ZXIgaXMgaW5pdGlhbGl6ZWRcbiAgICAgKi9cbiAgICBpc0luaXRpYWxpemVkOiB7XG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IGZhbHNlXG4gICAgfVxuICB9LFxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gc2V0IHVwIGNhbGxiYWNrIHRvIGZyZWUgaW50ZXJuYWwgc3RhdGUgb24gcmVtb3ZlXG4gICAgdGhpcy5vbigncmVtb3ZlJywgZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5yZWxlYXNlRGF0YUZpbHRlcigpO1xuICAgIH0pO1xuICB9LFxuICB6b29tSW46IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlbGVhc2VEYXRhRmlsdGVyKCk7XG5cbiAgICAvLyBzYXZlIGN1cnJlbnQgc3RhdGVcbiAgICB0aGlzLnpvb21IaXN0b3J5LnB1c2goSlNPTi5zdHJpbmdpZnkodGhpcy5wYXJ0aXRpb25zLnRvSlNPTigpKSk7XG5cbiAgICB0aGlzLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uKSB7XG4gICAgICBpZiAoKHBhcnRpdGlvbi5zZWxlY3RlZC5sZW5ndGggPT09IDIpICYmIChwYXJ0aXRpb24uaXNEYXRldGltZSB8fCBwYXJ0aXRpb24uaXNDb250aW51b3VzKSkge1xuICAgICAgICBpZiAocGFydGl0aW9uLmdyb3VwRml4ZWRTIHx8IHBhcnRpdGlvbi5ncm91cEZpeGVkU0MpIHtcbiAgICAgICAgICAvLyBzY2FsZSBkb3duIGJpbnNpemVcbiAgICAgICAgICB2YXIgbmV3U2l6ZSA9IHBhcnRpdGlvbi5zZWxlY3RlZFsxXSAtIHBhcnRpdGlvbi5zZWxlY3RlZFswXTtcbiAgICAgICAgICB2YXIgb2xkU2l6ZSA9IHBhcnRpdGlvbi5tYXh2YWwgLSBwYXJ0aXRpb24ubWludmFsO1xuICAgICAgICAgIHBhcnRpdGlvbi5ncm91cGluZ1BhcmFtID0gcGFydGl0aW9uLmdyb3VwaW5nUGFyYW0gKiBuZXdTaXplIC8gb2xkU2l6ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyB6b29tIHRvIHNlbGVjdGVkIHJhbmdlLCBpZiBwb3NzaWJsZVxuICAgICAgICBwYXJ0aXRpb24uc2V0KHtcbiAgICAgICAgICBtaW52YWw6IHBhcnRpdGlvbi5zZWxlY3RlZFswXSxcbiAgICAgICAgICBtYXh2YWw6IHBhcnRpdGlvbi5zZWxlY3RlZFsxXVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCA+IDAgJiYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwpKSB7XG4gICAgICAgIC8vIHpvb20gdG8gc2VsZWN0ZWQgY2F0ZWdvcmllcywgaWYgcG9zc2libGVcbiAgICAgICAgcGFydGl0aW9uLmdyb3Vwcy5yZXNldCgpO1xuICAgICAgICBwYXJ0aXRpb24uc2VsZWN0ZWQuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICBwYXJ0aXRpb24uZ3JvdXBzLmFkZCh7XG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICBsYWJlbDogdmFsdWUsXG4gICAgICAgICAgICBjb3VudDogMCxcbiAgICAgICAgICAgIGlzU2VsZWN0ZWQ6IHRydWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyBzZWxlY3QgYWxsXG4gICAgICBwYXJ0aXRpb24udXBkYXRlU2VsZWN0aW9uKCk7XG4gICAgfSk7XG4gICAgdGhpcy5pbml0RGF0YUZpbHRlcigpO1xuICAgIHRoaXMudXBkYXRlRGF0YUZpbHRlcigpOyAvLyBhbHNvIHRyaWdnZXJzIGEgZ2V0QWxsRGF0YSgpXG4gIH0sXG4gIHpvb21PdXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZG9SZXNldCA9IHRydWU7XG5cbiAgICAvLyBjbGVhciBjdXJyZW50IHNlbGVjdGlvblxuICAgIHRoaXMucGFydGl0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgICAgIGlmIChwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoID4gMCkge1xuICAgICAgICBwYXJ0aXRpb24udXBkYXRlU2VsZWN0aW9uKCk7XG4gICAgICAgIGRvUmVzZXQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChkb1Jlc2V0KSB7XG4gICAgICB0aGlzLnJlbGVhc2VEYXRhRmlsdGVyKCk7XG4gICAgICBpZiAodGhpcy56b29tSGlzdG9yeS5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIG5vdGhpbmcgd2FzIHNlbGVjdGVkIGFuZCB3ZSBoYXZlIGRyaWxsZWQgZG93bjogZ28gdXBcbiAgICAgICAgdmFyIHN0YXRlID0gSlNPTi5wYXJzZSh0aGlzLnpvb21IaXN0b3J5LnBvcCgpKTtcbiAgICAgICAgdGhpcy5wYXJ0aXRpb25zLnJlc2V0KHN0YXRlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG5vdGhpbmcgd2FzIHNlbGVjdGVkIGFuZCBubyBkcmlsbCBkb3duOiByZXNldCBwYXJ0aXRpb25pbmdcbiAgICAgICAgdGhpcy5wYXJ0aXRpb25zLmZvckVhY2goZnVuY3Rpb24gKHBhcnRpdGlvbikge1xuICAgICAgICAgIGlmIChwYXJ0aXRpb24uaXNEYXRldGltZSB8fCBwYXJ0aXRpb24uaXNDb250aW51b3VzKSB7XG4gICAgICAgICAgICBwYXJ0aXRpb24ucmVzZXQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgdGhpcy5pbml0RGF0YUZpbHRlcigpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZURhdGFGaWx0ZXIoKTsgLy8gYWxzbyB0cmlnZ2VycyBhIGdldEFsbERhdGEoKVxuICB9LFxuICAvLyBBcHBseSB0aGUgc2VwYXJhdGUgZmlsdGVyRnVuY3Rpb25zIGZyb20gZWFjaCBwYXJ0aXRpb24gaW4gYSBzaW5nbGUgZnVuY3Rpb25cbiAgZmlsdGVyRnVuY3Rpb246IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZnMgPSBbXTtcbiAgICB0aGlzLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uKSB7XG4gICAgICBmcy5wdXNoKHBhcnRpdGlvbi5maWx0ZXJGdW5jdGlvbigpKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmICh0eXBlb2YgZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdmFyIGdyb3VwcyA9IGQuc3BsaXQoJ3wnKTtcbiAgICAgICAgcmV0dXJuIGZzLmV2ZXJ5KGZ1bmN0aW9uIChmLCBpKSB7IHJldHVybiBmKGdyb3Vwc1tpXSk7IH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gc2hvcnRjdXQgZm9yIG5vbi1wYXJ0aXRpb25lZCBudW1lcmljIGRhdGFcbiAgICAgICAgcmV0dXJuIGZzWzBdKGQpO1xuICAgICAgfVxuICAgIH07XG4gIH0sXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICAgKlxuICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgKi9cbiAgaW5pdERhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIucmVsZWFzZURhdGFGaWx0ZXIoZGF0YXZpZXcsIHRoaXMpO1xuICAgIHNwb3QuZHJpdmVyLmluaXREYXRhRmlsdGVyKGRhdGF2aWV3LCB0aGlzKTtcbiAgICBzcG90LmRyaXZlci51cGRhdGVEYXRhRmlsdGVyKHRoaXMpO1xuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgfSxcbiAgLyoqXG4gICAqIFRoZSBvcHBvc2l0ZSBvciBpbml0RGF0YUZpbHRlciwgaXQgc2hvdWxkIHJlbW92ZSB0aGUgZmlsdGVyIGFuZCBkZWFsbG9jYXRlIG90aGVyIGNvbmZpZ3VyYXRpb25cbiAgICogcmVsYXRlZCB0byB0aGUgZmlsdGVyLlxuICAgKlxuICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgKi9cbiAgcmVsZWFzZURhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIucmVsZWFzZURhdGFGaWx0ZXIoZGF0YXZpZXcsIHRoaXMpO1xuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gZmFsc2U7XG4gIH0sXG4gIC8qKlxuICAgKiBBcHBseSBjaGFuZ2VzIHRvIHRoZSBmaWx0ZXIgKGxpa2Ugc2VsZWN0aW5nIGdyb3VwcylcbiAgICpcbiAgICogQG1lbWJlcm9mISBGaWx0ZXJcbiAgICovXG4gIHVwZGF0ZURhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIudXBkYXRlRGF0YUZpbHRlcih0aGlzKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9476\n")},"9b75":function(module,exports,__webpack_require__){eval("/**\n * CategorialTransfrom defines a transformation on categorial and textual data,\n * and is implemented as a collection of rules.\n *\n * @class CategorialTransform\n */\nvar Model = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\n\nvar Rule = __webpack_require__(/*! ./categorial-rule */ \"ba23\");\nvar Rules = Collection.extend({\n  indexes: ['expression'],\n  model: Rule\n});\n\n/**\n * Apply the first applicable transformation rule.\n * When no matching rule is found, return 'Other'\n *\n * @function\n * @memberof! CategorialTransform\n * @param {string} text\n * @returns {string} text The transformed text\n */\nfunction transform (rules, text) {\n  var i;\n  for (i = 0; i < rules.length; i++) {\n    var group = rules.models[i].match(text);\n    if (group) {\n      return group;\n    }\n  }\n  return 'Other';\n}\n\nmodule.exports = Model.extend({\n  props: {\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['categorial']\n    },\n    transformedMin: {\n      type: 'number',\n      required: true,\n      default: 0\n    },\n    transformedMax: {\n      type: 'number',\n      required: true,\n      default: 100\n    },\n    transformedMinAsText: {\n      type: 'string',\n      required: true,\n      default: '0'\n    },\n    transformedMaxAsText: {\n      type: 'string',\n      required: true,\n      default: '100'\n    }\n  },\n  collections: {\n    rules: Rules\n  },\n  transform: function (labels) {\n    if (!this.rules) {\n      return labels;\n    }\n    if (labels instanceof Array) {\n      labels.forEach(function (label, i) {\n        labels[i] = transform(this.rules, label);\n      }, this);\n    } else {\n      labels = transform(this.rules, labels);\n    }\n    return labels;\n  },\n  reset: function () {\n    this.rules.reset();\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWI3NS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY2F0ZWdvcmlhbC10cmFuc2Zvcm0uanM/MzBlYiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENhdGVnb3JpYWxUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNhdGVnb3JpYWwgYW5kIHRleHR1YWwgZGF0YSxcbiAqIGFuZCBpcyBpbXBsZW1lbnRlZCBhcyBhIGNvbGxlY3Rpb24gb2YgcnVsZXMuXG4gKlxuICogQGNsYXNzIENhdGVnb3JpYWxUcmFuc2Zvcm1cbiAqL1xudmFyIE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG52YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG5cbnZhciBSdWxlID0gcmVxdWlyZSgnLi9jYXRlZ29yaWFsLXJ1bGUnKTtcbnZhciBSdWxlcyA9IENvbGxlY3Rpb24uZXh0ZW5kKHtcbiAgaW5kZXhlczogWydleHByZXNzaW9uJ10sXG4gIG1vZGVsOiBSdWxlXG59KTtcblxuLyoqXG4gKiBBcHBseSB0aGUgZmlyc3QgYXBwbGljYWJsZSB0cmFuc2Zvcm1hdGlvbiBydWxlLlxuICogV2hlbiBubyBtYXRjaGluZyBydWxlIGlzIGZvdW5kLCByZXR1cm4gJ090aGVyJ1xuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mISBDYXRlZ29yaWFsVHJhbnNmb3JtXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICogQHJldHVybnMge3N0cmluZ30gdGV4dCBUaGUgdHJhbnNmb3JtZWQgdGV4dFxuICovXG5mdW5jdGlvbiB0cmFuc2Zvcm0gKHJ1bGVzLCB0ZXh0KSB7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgcnVsZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZ3JvdXAgPSBydWxlcy5tb2RlbHNbaV0ubWF0Y2godGV4dCk7XG4gICAgaWYgKGdyb3VwKSB7XG4gICAgICByZXR1cm4gZ3JvdXA7XG4gICAgfVxuICB9XG4gIHJldHVybiAnT3RoZXInO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IE1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgdHJhbnNmb3JtZWRUeXBlOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ2NhdGVnb3JpYWwnLFxuICAgICAgdmFsdWVzOiBbJ2NhdGVnb3JpYWwnXVxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNaW46IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAwXG4gICAgfSxcbiAgICB0cmFuc2Zvcm1lZE1heDoge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IDEwMFxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNaW5Bc1RleHQ6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnMCdcbiAgICB9LFxuICAgIHRyYW5zZm9ybWVkTWF4QXNUZXh0OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJzEwMCdcbiAgICB9XG4gIH0sXG4gIGNvbGxlY3Rpb25zOiB7XG4gICAgcnVsZXM6IFJ1bGVzXG4gIH0sXG4gIHRyYW5zZm9ybTogZnVuY3Rpb24gKGxhYmVscykge1xuICAgIGlmICghdGhpcy5ydWxlcykge1xuICAgICAgcmV0dXJuIGxhYmVscztcbiAgICB9XG4gICAgaWYgKGxhYmVscyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBsYWJlbHMuZm9yRWFjaChmdW5jdGlvbiAobGFiZWwsIGkpIHtcbiAgICAgICAgbGFiZWxzW2ldID0gdHJhbnNmb3JtKHRoaXMucnVsZXMsIGxhYmVsKTtcbiAgICAgIH0sIHRoaXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYWJlbHMgPSB0cmFuc2Zvcm0odGhpcy5ydWxlcywgbGFiZWxzKTtcbiAgICB9XG4gICAgcmV0dXJuIGxhYmVscztcbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJ1bGVzLnJlc2V0KCk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9b75\n")},"9d63":function(module,exports,__webpack_require__){eval("/**\n * The Aggregate class describes how to aggregate data, as described by a `Facet` into a single value.\n * For example, you can sum or average over numbers, or count the number of different labels.\n *\n * @class Aggregate\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\n\nmodule.exports = BaseModel.extend({\n  props: {\n    /**\n     * The name of the facet to aggregate over\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    facetName: 'string',\n\n    /**\n     * Label for displaying on plots\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    label: {\n      type: 'string',\n      required: true,\n      default: ''\n    },\n\n    /**\n     * When part of a aggregates, this deterimines the ordering\n     * @memberof! Aggregate\n     * @type {number}\n     */\n    rank: {\n      type: 'number',\n      required: true\n    },\n\n    /**\n     * Operation:\n     *  * `count`  count the number of elements in the group\n     *  * `sum`    sum the elements in the group\n     *  * `avg`    take the average of the elements in the group\n     *  * `stddev`  take the sample\n     *  * `min`    minum value of the elements in the group\n     *  * `max`    maximum value of the elements in the group\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    operation: {\n      type: 'string',\n      required: true,\n      default: 'avg',\n      values: ['count', 'avg', 'sum', 'stddev', 'min', 'max']\n    },\n    // NOTE: properties for reduction, should be a valid SQL aggregation function\n\n    /**\n     * Normalization: TODO\n     *  * `none`      data in same units as the original data\n     *  * `relative`  data is in percentages of the total; for subgroups in percentage of the parent group\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    normalization: {\n      type: 'string',\n      required: true,\n      default: 'none',\n      values: ['none', 'percentage']\n    }\n  },\n  derived: {\n    // operation values\n    doSum: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'sum';\n      }\n    },\n    doCount: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'count';\n      }\n    },\n    doAverage: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'avg';\n      }\n    },\n    doStddev: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'stddev';\n      }\n    },\n    doMin: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'min';\n      }\n    },\n    doMax: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'max';\n      }\n    },\n\n    // normalization values\n    normalizeNone: {\n      deps: ['normalization'],\n      fn: function () {\n        return this.normalization === 'absolute';\n      }\n    },\n    normalizePercentage: {\n      deps: ['normalization'],\n      fn: function () {\n        return this.normalization === 'percentage';\n      }\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWQ2My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvYWdncmVnYXRlLmpzP2JkNmEiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgQWdncmVnYXRlIGNsYXNzIGRlc2NyaWJlcyBob3cgdG8gYWdncmVnYXRlIGRhdGEsIGFzIGRlc2NyaWJlZCBieSBhIGBGYWNldGAgaW50byBhIHNpbmdsZSB2YWx1ZS5cbiAqIEZvciBleGFtcGxlLCB5b3UgY2FuIHN1bSBvciBhdmVyYWdlIG92ZXIgbnVtYmVycywgb3IgY291bnQgdGhlIG51bWJlciBvZiBkaWZmZXJlbnQgbGFiZWxzLlxuICpcbiAqIEBjbGFzcyBBZ2dyZWdhdGVcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGZhY2V0IHRvIGFnZ3JlZ2F0ZSBvdmVyXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZhY2V0TmFtZTogJ3N0cmluZycsXG5cbiAgICAvKipcbiAgICAgKiBMYWJlbCBmb3IgZGlzcGxheWluZyBvbiBwbG90c1xuICAgICAqIEBtZW1iZXJvZiEgQWdncmVnYXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBsYWJlbDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICcnXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFdoZW4gcGFydCBvZiBhIGFnZ3JlZ2F0ZXMsIHRoaXMgZGV0ZXJpbWluZXMgdGhlIG9yZGVyaW5nXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHJhbms6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogT3BlcmF0aW9uOlxuICAgICAqICAqIGBjb3VudGAgIGNvdW50IHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGdyb3VwXG4gICAgICogICogYHN1bWAgICAgc3VtIHRoZSBlbGVtZW50cyBpbiB0aGUgZ3JvdXBcbiAgICAgKiAgKiBgYXZnYCAgICB0YWtlIHRoZSBhdmVyYWdlIG9mIHRoZSBlbGVtZW50cyBpbiB0aGUgZ3JvdXBcbiAgICAgKiAgKiBgc3RkZGV2YCAgdGFrZSB0aGUgc2FtcGxlXG4gICAgICogICogYG1pbmAgICAgbWludW0gdmFsdWUgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBncm91cFxuICAgICAqICAqIGBtYXhgICAgIG1heGltdW0gdmFsdWUgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBncm91cFxuICAgICAqIEBtZW1iZXJvZiEgQWdncmVnYXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBvcGVyYXRpb246IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnYXZnJyxcbiAgICAgIHZhbHVlczogWydjb3VudCcsICdhdmcnLCAnc3VtJywgJ3N0ZGRldicsICdtaW4nLCAnbWF4J11cbiAgICB9LFxuICAgIC8vIE5PVEU6IHByb3BlcnRpZXMgZm9yIHJlZHVjdGlvbiwgc2hvdWxkIGJlIGEgdmFsaWQgU1FMIGFnZ3JlZ2F0aW9uIGZ1bmN0aW9uXG5cbiAgICAvKipcbiAgICAgKiBOb3JtYWxpemF0aW9uOiBUT0RPXG4gICAgICogICogYG5vbmVgICAgICAgZGF0YSBpbiBzYW1lIHVuaXRzIGFzIHRoZSBvcmlnaW5hbCBkYXRhXG4gICAgICogICogYHJlbGF0aXZlYCAgZGF0YSBpcyBpbiBwZXJjZW50YWdlcyBvZiB0aGUgdG90YWw7IGZvciBzdWJncm91cHMgaW4gcGVyY2VudGFnZSBvZiB0aGUgcGFyZW50IGdyb3VwXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG5vcm1hbGl6YXRpb246IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnbm9uZScsXG4gICAgICB2YWx1ZXM6IFsnbm9uZScsICdwZXJjZW50YWdlJ11cbiAgICB9XG4gIH0sXG4gIGRlcml2ZWQ6IHtcbiAgICAvLyBvcGVyYXRpb24gdmFsdWVzXG4gICAgZG9TdW06IHtcbiAgICAgIGRlcHM6IFsnb3BlcmF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vcGVyYXRpb24gPT09ICdzdW0nO1xuICAgICAgfVxuICAgIH0sXG4gICAgZG9Db3VudDoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ2NvdW50JztcbiAgICAgIH1cbiAgICB9LFxuICAgIGRvQXZlcmFnZToge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ2F2Zyc7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb1N0ZGRldjoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ3N0ZGRldic7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb01pbjoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ21pbic7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb01heDoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ21heCc7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8vIG5vcm1hbGl6YXRpb24gdmFsdWVzXG4gICAgbm9ybWFsaXplTm9uZToge1xuICAgICAgZGVwczogWydub3JtYWxpemF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxpemF0aW9uID09PSAnYWJzb2x1dGUnO1xuICAgICAgfVxuICAgIH0sXG4gICAgbm9ybWFsaXplUGVyY2VudGFnZToge1xuICAgICAgZGVwczogWydub3JtYWxpemF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxpemF0aW9uID09PSAncGVyY2VudGFnZSc7XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9d63\n")},a0ca:function(module,exports,__webpack_require__){eval("/**\n * DatetimeTransform defines a transformation on time or dates with timezones\n *\n * @class DatetimeTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Timezone to use when parsing, for when timezone information is absent or incorrect.\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    zone: ['string', true, 'ISO8601'],\n\n    /**\n     * Format indentifier to use when parsing, when not in ISO8601 format\n     * Mappings are defined in util/time.js => timeParts.description\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    format: ['string', true, 'ISO8601'],\n\n    /**\n     * Reformats to a string using the momentjs or postgreSQL format specifiers.\n     * This allows a transformation to day of the year, or day of week etc.\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedFormat: ['string', true, 'ISO8601'],\n\n    /**\n     * Controls conversion to duration by subtracting this date\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedReference: 'string',\n\n    /**\n     * Reference timezone for conversion from datetime to duration\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedZone: ['string', true, 'ISO8601']\n\n  },\n  derived: {\n    // reference momentjs for duration <-> datetime conversion\n    referenceMoment: {\n      deps: ['transformedReference', 'transformedZone'],\n      fn: function () {\n        var tz;\n        if (this.transformedZone === 'ISO8601') {\n          tz = moment.tz.guess();\n        } else {\n          var timeZone = util.timeZones.get(this.transformedZone, 'description');\n          if (timeZone && timeZone.format) {\n            tz = timeZone.format;\n          } else {\n            tz = moment.tz.guess();\n          }\n        }\n        if (this.transformedReference) {\n          return moment.tz(this.transformedReference, tz);\n        }\n        return null;\n      }\n    },\n    /**\n     * The type of the facet after the transformation has been applied\n     * @memberof! DatetimeTransform\n     */\n    transformedType: {\n      deps: ['transformedFormat', 'transformedReference'],\n      fn: function () {\n        if (this.transformedReference) {\n          // datetime -> duration\n          return 'duration';\n        } else if (this.transformedFormat === 'ISO8601') {\n          // datetime -> datetime\n          return 'datetime';\n        } else {\n          // datetime -> time part\n          var timePart = util.timeParts.get(this.transformedFormat, 'description');\n          if (timePart && timePart.type) {\n            return timePart.type;\n          }\n        }\n        return 'datetime';\n      },\n      cache: false\n    },\n    /**\n     * The minium value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! DatetimeTransform\n     */\n    transformedMin: {\n      deps: ['transformedType'],\n      fn: function () {\n        var timePart;\n        if (this.transformedType === 'datetime' || this.transformedType === 'duration') {\n          return this.transform(this.parent.minval);\n        }\n        timePart = util.timeParts.get(this.transformedFormat, 'description');\n        if (timePart.calcualte) {\n          return this.transform(this.parent.minval);\n        } else {\n          return timePart.min;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! DatetimeTransform\n     */\n    transformedMax: {\n      deps: ['transformedType'],\n      fn: function () {\n        var timePart;\n        if (this.transformedType === 'datetime' || this.transformedType === 'duration') {\n          return this.transform(this.parent.maxval);\n        }\n        timePart = util.timeParts.get(this.transformedFormat, 'description');\n        if (timePart.calcualte) {\n          return this.transform(this.parent.maxval);\n        } else {\n          return timePart.max;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DatetimeTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DatetimeTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n\n  /**\n   * @function\n   * @memberof! DatetimeTransform\n   * @param {Object} momentjs\n   * @returns {Object} momentjs\n   */\n  transform: function transform (inval) {\n    if (typeof inval === 'undefined') {\n      return misval;\n    }\n\n    var d = inval.clone();\n    var timePart;\n\n    if (this.referenceMoment) {\n      // datetime -> duration\n      return moment.duration(d.diff(this.referenceMoment, 'milliseconds', true), 'milliseconds');\n    } else if (this.transformedFormat !== 'ISO8601') {\n      timePart = util.timeParts.get(this.transformedFormat, 'description');\n      if (timePart && timePart.momentFormat) {\n        return d.format(timePart.momentFormat);\n      }\n      return d;\n    } else {\n      return d;\n    }\n  },\n  reset: function () {\n    this.unset(['zone', 'transformedFormat', 'transformedZone', 'transformedReference']);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYTBjYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvZGF0ZXRpbWUtdHJhbnNmb3JtLmpzPzM1YTIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEYXRldGltZVRyYW5zZm9ybSBkZWZpbmVzIGEgdHJhbnNmb3JtYXRpb24gb24gdGltZSBvciBkYXRlcyB3aXRoIHRpbWV6b25lc1xuICpcbiAqIEBjbGFzcyBEYXRldGltZVRyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC90aW1lJyk7XG52YXIgbWlzdmFsID0gcmVxdWlyZSgnLi4vdXRpbC9taXN2YWwnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRpbWV6b25lIHRvIHVzZSB3aGVuIHBhcnNpbmcsIGZvciB3aGVuIHRpbWV6b25lIGluZm9ybWF0aW9uIGlzIGFic2VudCBvciBpbmNvcnJlY3QuXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgem9uZTogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogRm9ybWF0IGluZGVudGlmaWVyIHRvIHVzZSB3aGVuIHBhcnNpbmcsIHdoZW4gbm90IGluIElTTzg2MDEgZm9ybWF0XG4gICAgICogTWFwcGluZ3MgYXJlIGRlZmluZWQgaW4gdXRpbC90aW1lLmpzID0+IHRpbWVQYXJ0cy5kZXNjcmlwdGlvblxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZvcm1hdDogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogUmVmb3JtYXRzIHRvIGEgc3RyaW5nIHVzaW5nIHRoZSBtb21lbnRqcyBvciBwb3N0Z3JlU1FMIGZvcm1hdCBzcGVjaWZpZXJzLlxuICAgICAqIFRoaXMgYWxsb3dzIGEgdHJhbnNmb3JtYXRpb24gdG8gZGF5IG9mIHRoZSB5ZWFyLCBvciBkYXkgb2Ygd2VlayBldGMuXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRGb3JtYXQ6IFsnc3RyaW5nJywgdHJ1ZSwgJ0lTTzg2MDEnXSxcblxuICAgIC8qKlxuICAgICAqIENvbnRyb2xzIGNvbnZlcnNpb24gdG8gZHVyYXRpb24gYnkgc3VidHJhY3RpbmcgdGhpcyBkYXRlXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRSZWZlcmVuY2U6ICdzdHJpbmcnLFxuXG4gICAgLyoqXG4gICAgICogUmVmZXJlbmNlIHRpbWV6b25lIGZvciBjb252ZXJzaW9uIGZyb20gZGF0ZXRpbWUgdG8gZHVyYXRpb25cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFpvbmU6IFsnc3RyaW5nJywgdHJ1ZSwgJ0lTTzg2MDEnXVxuXG4gIH0sXG4gIGRlcml2ZWQ6IHtcbiAgICAvLyByZWZlcmVuY2UgbW9tZW50anMgZm9yIGR1cmF0aW9uIDwtPiBkYXRldGltZSBjb252ZXJzaW9uXG4gICAgcmVmZXJlbmNlTW9tZW50OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkUmVmZXJlbmNlJywgJ3RyYW5zZm9ybWVkWm9uZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHR6O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFpvbmUgPT09ICdJU084NjAxJykge1xuICAgICAgICAgIHR6ID0gbW9tZW50LnR6Lmd1ZXNzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHRpbWVab25lID0gdXRpbC50aW1lWm9uZXMuZ2V0KHRoaXMudHJhbnNmb3JtZWRab25lLCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgICBpZiAodGltZVpvbmUgJiYgdGltZVpvbmUuZm9ybWF0KSB7XG4gICAgICAgICAgICB0eiA9IHRpbWVab25lLmZvcm1hdDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHogPSBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXR1cm4gbW9tZW50LnR6KHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UsIHR6KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBmYWNldCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFR5cGU6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRGb3JtYXQnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkUmVmZXJlbmNlKSB7XG4gICAgICAgICAgLy8gZGF0ZXRpbWUgLT4gZHVyYXRpb25cbiAgICAgICAgICByZXR1cm4gJ2R1cmF0aW9uJztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0ID09PSAnSVNPODYwMScpIHtcbiAgICAgICAgICAvLyBkYXRldGltZSAtPiBkYXRldGltZVxuICAgICAgICAgIHJldHVybiAnZGF0ZXRpbWUnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGRhdGV0aW1lIC0+IHRpbWUgcGFydFxuICAgICAgICAgIHZhciB0aW1lUGFydCA9IHV0aWwudGltZVBhcnRzLmdldCh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgICBpZiAodGltZVBhcnQgJiYgdGltZVBhcnQudHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRpbWVQYXJ0LnR5cGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnZGF0ZXRpbWUnO1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1pbml1bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluOiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRpbWVQYXJ0O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScgfHwgdGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkdXJhdGlvbicpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0odGhpcy5wYXJlbnQubWludmFsKTtcbiAgICAgICAgfVxuICAgICAgICB0aW1lUGFydCA9IHV0aWwudGltZVBhcnRzLmdldCh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgaWYgKHRpbWVQYXJ0LmNhbGN1YWx0ZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybSh0aGlzLnBhcmVudC5taW52YWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aW1lUGFydC5taW47XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNYXg6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGltZVBhcnQ7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJyB8fCB0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2R1cmF0aW9uJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybSh0aGlzLnBhcmVudC5tYXh2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHRpbWVQYXJ0ID0gdXRpbC50aW1lUGFydHMuZ2V0KHRoaXMudHJhbnNmb3JtZWRGb3JtYXQsICdkZXNjcmlwdGlvbicpO1xuICAgICAgICBpZiAodGltZVBhcnQuY2FsY3VhbHRlKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKHRoaXMucGFyZW50Lm1heHZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRpbWVQYXJ0Lm1heDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKlxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkTWluJywgJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1pbnZhbCA9IHRoaXMudHJhbnNmb3JtZWRNaW47XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiBtaW52YWwuZm9ybWF0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNYXhBc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRNYXgnLCAndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWF4dmFsID0gdGhpcy50cmFuc2Zvcm1lZE1heDtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnZGF0ZXRpbWUnKSB7XG4gICAgICAgICAgcmV0dXJuIG1heHZhbC5mb3JtYXQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIEBmdW5jdGlvblxuICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtb21lbnRqc1xuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBtb21lbnRqc1xuICAgKi9cbiAgdHJhbnNmb3JtOiBmdW5jdGlvbiB0cmFuc2Zvcm0gKGludmFsKSB7XG4gICAgaWYgKHR5cGVvZiBpbnZhbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfVxuXG4gICAgdmFyIGQgPSBpbnZhbC5jbG9uZSgpO1xuICAgIHZhciB0aW1lUGFydDtcblxuICAgIGlmICh0aGlzLnJlZmVyZW5jZU1vbWVudCkge1xuICAgICAgLy8gZGF0ZXRpbWUgLT4gZHVyYXRpb25cbiAgICAgIHJldHVybiBtb21lbnQuZHVyYXRpb24oZC5kaWZmKHRoaXMucmVmZXJlbmNlTW9tZW50LCAnbWlsbGlzZWNvbmRzJywgdHJ1ZSksICdtaWxsaXNlY29uZHMnKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudHJhbnNmb3JtZWRGb3JtYXQgIT09ICdJU084NjAxJykge1xuICAgICAgdGltZVBhcnQgPSB1dGlsLnRpbWVQYXJ0cy5nZXQodGhpcy50cmFuc2Zvcm1lZEZvcm1hdCwgJ2Rlc2NyaXB0aW9uJyk7XG4gICAgICBpZiAodGltZVBhcnQgJiYgdGltZVBhcnQubW9tZW50Rm9ybWF0KSB7XG4gICAgICAgIHJldHVybiBkLmZvcm1hdCh0aW1lUGFydC5tb21lbnRGb3JtYXQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBkO1xuICAgIH1cbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVuc2V0KFsnem9uZScsICd0cmFuc2Zvcm1lZEZvcm1hdCcsICd0cmFuc2Zvcm1lZFpvbmUnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///a0ca\n")},aa6c:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar keys = __webpack_require__(/*! ./keys */ \"7d91\");\nvar hasBinary = __webpack_require__(/*! has-binary */ \"d304\");\nvar sliceBuffer = __webpack_require__(/*! arraybuffer.slice */ \"ef13\");\nvar after = __webpack_require__(/*! after */ \"4aa5\");\nvar utf8 = __webpack_require__(/*! wtf-8 */ \"943e\");\n\nvar base64encoder;\nif (global && global.ArrayBuffer) {\n  base64encoder = __webpack_require__(/*! base64-arraybuffer */ \"21de\");\n}\n\n/**\n * Check if we are running an android browser. That requires us to use\n * ArrayBuffer with polling transports...\n *\n * http://ghinda.net/jpeg-blob-ajax-android/\n */\n\nvar isAndroid = typeof navigator !== 'undefined' && /Android/i.test(navigator.userAgent);\n\n/**\n * Check if we are running in PhantomJS.\n * Uploading a Blob with PhantomJS does not work correctly, as reported here:\n * https://github.com/ariya/phantomjs/issues/11395\n * @type boolean\n */\nvar isPhantomJS = typeof navigator !== 'undefined' && /PhantomJS/i.test(navigator.userAgent);\n\n/**\n * When true, avoids using Blobs to encode payloads.\n * @type boolean\n */\nvar dontSendBlobs = isAndroid || isPhantomJS;\n\n/**\n * Current protocol version.\n */\n\nexports.protocol = 3;\n\n/**\n * Packet types.\n */\n\nvar packets = exports.packets = {\n    open:     0    // non-ws\n  , close:    1    // non-ws\n  , ping:     2\n  , pong:     3\n  , message:  4\n  , upgrade:  5\n  , noop:     6\n};\n\nvar packetslist = keys(packets);\n\n/**\n * Premade error packet.\n */\n\nvar err = { type: 'error', data: 'parser error' };\n\n/**\n * Create a blob api even for blob builder when vendor prefixes exist\n */\n\nvar Blob = __webpack_require__(/*! blob */ \"939f\");\n\n/**\n * Encodes a packet.\n *\n *     <packet type id> [ <data> ]\n *\n * Example:\n *\n *     5hello world\n *     3\n *     4\n *\n * Binary is encoded in an identical principle\n *\n * @api private\n */\n\nexports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {\n  if ('function' == typeof supportsBinary) {\n    callback = supportsBinary;\n    supportsBinary = false;\n  }\n\n  if ('function' == typeof utf8encode) {\n    callback = utf8encode;\n    utf8encode = null;\n  }\n\n  var data = (packet.data === undefined)\n    ? undefined\n    : packet.data.buffer || packet.data;\n\n  if (global.ArrayBuffer && data instanceof ArrayBuffer) {\n    return encodeArrayBuffer(packet, supportsBinary, callback);\n  } else if (Blob && data instanceof global.Blob) {\n    return encodeBlob(packet, supportsBinary, callback);\n  }\n\n  // might be an object with { base64: true, data: dataAsBase64String }\n  if (data && data.base64) {\n    return encodeBase64Object(packet, callback);\n  }\n\n  // Sending data as a utf-8 string\n  var encoded = packets[packet.type];\n\n  // data fragment is optional\n  if (undefined !== packet.data) {\n    encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data);\n  }\n\n  return callback('' + encoded);\n\n};\n\nfunction encodeBase64Object(packet, callback) {\n  // packet data is an object { base64: true, data: dataAsBase64String }\n  var message = 'b' + exports.packets[packet.type] + packet.data.data;\n  return callback(message);\n}\n\n/**\n * Encode packet helpers for binary types\n */\n\nfunction encodeArrayBuffer(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  var data = packet.data;\n  var contentArray = new Uint8Array(data);\n  var resultBuffer = new Uint8Array(1 + data.byteLength);\n\n  resultBuffer[0] = packets[packet.type];\n  for (var i = 0; i < contentArray.length; i++) {\n    resultBuffer[i+1] = contentArray[i];\n  }\n\n  return callback(resultBuffer.buffer);\n}\n\nfunction encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  var fr = new FileReader();\n  fr.onload = function() {\n    packet.data = fr.result;\n    exports.encodePacket(packet, supportsBinary, true, callback);\n  };\n  return fr.readAsArrayBuffer(packet.data);\n}\n\nfunction encodeBlob(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  if (dontSendBlobs) {\n    return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);\n  }\n\n  var length = new Uint8Array(1);\n  length[0] = packets[packet.type];\n  var blob = new Blob([length.buffer, packet.data]);\n\n  return callback(blob);\n}\n\n/**\n * Encodes a packet with binary data in a base64 string\n *\n * @param {Object} packet, has `type` and `data`\n * @return {String} base64 encoded message\n */\n\nexports.encodeBase64Packet = function(packet, callback) {\n  var message = 'b' + exports.packets[packet.type];\n  if (Blob && packet.data instanceof global.Blob) {\n    var fr = new FileReader();\n    fr.onload = function() {\n      var b64 = fr.result.split(',')[1];\n      callback(message + b64);\n    };\n    return fr.readAsDataURL(packet.data);\n  }\n\n  var b64data;\n  try {\n    b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));\n  } catch (e) {\n    // iPhone Safari doesn't let you apply with typed arrays\n    var typed = new Uint8Array(packet.data);\n    var basic = new Array(typed.length);\n    for (var i = 0; i < typed.length; i++) {\n      basic[i] = typed[i];\n    }\n    b64data = String.fromCharCode.apply(null, basic);\n  }\n  message += global.btoa(b64data);\n  return callback(message);\n};\n\n/**\n * Decodes a packet. Changes format to Blob if requested.\n *\n * @return {Object} with `type` and `data` (if any)\n * @api private\n */\n\nexports.decodePacket = function (data, binaryType, utf8decode) {\n  if (data === undefined) {\n    return err;\n  }\n  // String data\n  if (typeof data == 'string') {\n    if (data.charAt(0) == 'b') {\n      return exports.decodeBase64Packet(data.substr(1), binaryType);\n    }\n\n    if (utf8decode) {\n      data = tryDecode(data);\n      if (data === false) {\n        return err;\n      }\n    }\n    var type = data.charAt(0);\n\n    if (Number(type) != type || !packetslist[type]) {\n      return err;\n    }\n\n    if (data.length > 1) {\n      return { type: packetslist[type], data: data.substring(1) };\n    } else {\n      return { type: packetslist[type] };\n    }\n  }\n\n  var asArray = new Uint8Array(data);\n  var type = asArray[0];\n  var rest = sliceBuffer(data, 1);\n  if (Blob && binaryType === 'blob') {\n    rest = new Blob([rest]);\n  }\n  return { type: packetslist[type], data: rest };\n};\n\nfunction tryDecode(data) {\n  try {\n    data = utf8.decode(data);\n  } catch (e) {\n    return false;\n  }\n  return data;\n}\n\n/**\n * Decodes a packet encoded in a base64 string\n *\n * @param {String} base64 encoded message\n * @return {Object} with `type` and `data` (if any)\n */\n\nexports.decodeBase64Packet = function(msg, binaryType) {\n  var type = packetslist[msg.charAt(0)];\n  if (!base64encoder) {\n    return { type: type, data: { base64: true, data: msg.substr(1) } };\n  }\n\n  var data = base64encoder.decode(msg.substr(1));\n\n  if (binaryType === 'blob' && Blob) {\n    data = new Blob([data]);\n  }\n\n  return { type: type, data: data };\n};\n\n/**\n * Encodes multiple messages (payload).\n *\n *     <length>:data\n *\n * Example:\n *\n *     11:hello world2:hi\n *\n * If any contents are binary, they will be encoded as base64 strings. Base64\n * encoded strings are marked with a b before the length specifier\n *\n * @param {Array} packets\n * @api private\n */\n\nexports.encodePayload = function (packets, supportsBinary, callback) {\n  if (typeof supportsBinary == 'function') {\n    callback = supportsBinary;\n    supportsBinary = null;\n  }\n\n  var isBinary = hasBinary(packets);\n\n  if (supportsBinary && isBinary) {\n    if (Blob && !dontSendBlobs) {\n      return exports.encodePayloadAsBlob(packets, callback);\n    }\n\n    return exports.encodePayloadAsArrayBuffer(packets, callback);\n  }\n\n  if (!packets.length) {\n    return callback('0:');\n  }\n\n  function setLengthHeader(message) {\n    return message.length + ':' + message;\n  }\n\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function(message) {\n      doneCallback(null, setLengthHeader(message));\n    });\n  }\n\n  map(packets, encodeOne, function(err, results) {\n    return callback(results.join(''));\n  });\n};\n\n/**\n * Async array map using after\n */\n\nfunction map(ary, each, done) {\n  var result = new Array(ary.length);\n  var next = after(ary.length, done);\n\n  var eachWithIndex = function(i, el, cb) {\n    each(el, function(error, msg) {\n      result[i] = msg;\n      cb(error, result);\n    });\n  };\n\n  for (var i = 0; i < ary.length; i++) {\n    eachWithIndex(i, ary[i], next);\n  }\n}\n\n/*\n * Decodes data when a payload is maybe expected. Possible binary contents are\n * decoded from their base64 representation\n *\n * @param {String} data, callback method\n * @api public\n */\n\nexports.decodePayload = function (data, binaryType, callback) {\n  if (typeof data != 'string') {\n    return exports.decodePayloadAsBinary(data, binaryType, callback);\n  }\n\n  if (typeof binaryType === 'function') {\n    callback = binaryType;\n    binaryType = null;\n  }\n\n  var packet;\n  if (data == '') {\n    // parser error - ignoring payload\n    return callback(err, 0, 1);\n  }\n\n  var length = ''\n    , n, msg;\n\n  for (var i = 0, l = data.length; i < l; i++) {\n    var chr = data.charAt(i);\n\n    if (':' != chr) {\n      length += chr;\n    } else {\n      if ('' == length || (length != (n = Number(length)))) {\n        // parser error - ignoring payload\n        return callback(err, 0, 1);\n      }\n\n      msg = data.substr(i + 1, n);\n\n      if (length != msg.length) {\n        // parser error - ignoring payload\n        return callback(err, 0, 1);\n      }\n\n      if (msg.length) {\n        packet = exports.decodePacket(msg, binaryType, true);\n\n        if (err.type == packet.type && err.data == packet.data) {\n          // parser error in individual packet - ignoring payload\n          return callback(err, 0, 1);\n        }\n\n        var ret = callback(packet, i + n, l);\n        if (false === ret) return;\n      }\n\n      // advance cursor\n      i += n;\n      length = '';\n    }\n  }\n\n  if (length != '') {\n    // parser error - ignoring payload\n    return callback(err, 0, 1);\n  }\n\n};\n\n/**\n * Encodes multiple messages (payload) as binary.\n *\n * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number\n * 255><data>\n *\n * Example:\n * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers\n *\n * @param {Array} packets\n * @return {ArrayBuffer} encoded payload\n * @api private\n */\n\nexports.encodePayloadAsArrayBuffer = function(packets, callback) {\n  if (!packets.length) {\n    return callback(new ArrayBuffer(0));\n  }\n\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, true, true, function(data) {\n      return doneCallback(null, data);\n    });\n  }\n\n  map(packets, encodeOne, function(err, encodedPackets) {\n    var totalLength = encodedPackets.reduce(function(acc, p) {\n      var len;\n      if (typeof p === 'string'){\n        len = p.length;\n      } else {\n        len = p.byteLength;\n      }\n      return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2\n    }, 0);\n\n    var resultArray = new Uint8Array(totalLength);\n\n    var bufferIndex = 0;\n    encodedPackets.forEach(function(p) {\n      var isString = typeof p === 'string';\n      var ab = p;\n      if (isString) {\n        var view = new Uint8Array(p.length);\n        for (var i = 0; i < p.length; i++) {\n          view[i] = p.charCodeAt(i);\n        }\n        ab = view.buffer;\n      }\n\n      if (isString) { // not true binary\n        resultArray[bufferIndex++] = 0;\n      } else { // true binary\n        resultArray[bufferIndex++] = 1;\n      }\n\n      var lenStr = ab.byteLength.toString();\n      for (var i = 0; i < lenStr.length; i++) {\n        resultArray[bufferIndex++] = parseInt(lenStr[i]);\n      }\n      resultArray[bufferIndex++] = 255;\n\n      var view = new Uint8Array(ab);\n      for (var i = 0; i < view.length; i++) {\n        resultArray[bufferIndex++] = view[i];\n      }\n    });\n\n    return callback(resultArray.buffer);\n  });\n};\n\n/**\n * Encode as Blob\n */\n\nexports.encodePayloadAsBlob = function(packets, callback) {\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, true, true, function(encoded) {\n      var binaryIdentifier = new Uint8Array(1);\n      binaryIdentifier[0] = 1;\n      if (typeof encoded === 'string') {\n        var view = new Uint8Array(encoded.length);\n        for (var i = 0; i < encoded.length; i++) {\n          view[i] = encoded.charCodeAt(i);\n        }\n        encoded = view.buffer;\n        binaryIdentifier[0] = 0;\n      }\n\n      var len = (encoded instanceof ArrayBuffer)\n        ? encoded.byteLength\n        : encoded.size;\n\n      var lenStr = len.toString();\n      var lengthAry = new Uint8Array(lenStr.length + 1);\n      for (var i = 0; i < lenStr.length; i++) {\n        lengthAry[i] = parseInt(lenStr[i]);\n      }\n      lengthAry[lenStr.length] = 255;\n\n      if (Blob) {\n        var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);\n        doneCallback(null, blob);\n      }\n    });\n  }\n\n  map(packets, encodeOne, function(err, results) {\n    return callback(new Blob(results));\n  });\n};\n\n/*\n * Decodes data when a payload is maybe expected. Strings are decoded by\n * interpreting each byte as a key code for entries marked to start with 0. See\n * description of encodePayloadAsBinary\n *\n * @param {ArrayBuffer} data, callback method\n * @api public\n */\n\nexports.decodePayloadAsBinary = function (data, binaryType, callback) {\n  if (typeof binaryType === 'function') {\n    callback = binaryType;\n    binaryType = null;\n  }\n\n  var bufferTail = data;\n  var buffers = [];\n\n  var numberTooLong = false;\n  while (bufferTail.byteLength > 0) {\n    var tailArray = new Uint8Array(bufferTail);\n    var isString = tailArray[0] === 0;\n    var msgLength = '';\n\n    for (var i = 1; ; i++) {\n      if (tailArray[i] == 255) break;\n\n      if (msgLength.length > 310) {\n        numberTooLong = true;\n        break;\n      }\n\n      msgLength += tailArray[i];\n    }\n\n    if(numberTooLong) return callback(err, 0, 1);\n\n    bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);\n    msgLength = parseInt(msgLength);\n\n    var msg = sliceBuffer(bufferTail, 0, msgLength);\n    if (isString) {\n      try {\n        msg = String.fromCharCode.apply(null, new Uint8Array(msg));\n      } catch (e) {\n        // iPhone Safari doesn't let you apply to typed arrays\n        var typed = new Uint8Array(msg);\n        msg = '';\n        for (var i = 0; i < typed.length; i++) {\n          msg += String.fromCharCode(typed[i]);\n        }\n      }\n    }\n\n    buffers.push(msg);\n    bufferTail = sliceBuffer(bufferTail, msgLength);\n  }\n\n  var total = buffers.length;\n  buffers.forEach(function(buffer, i) {\n    callback(exports.decodePacket(buffer, binaryType, true), i, total);\n  });\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWE2Yy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIvYnJvd3Nlci5qcz9hZjAyIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIga2V5cyA9IHJlcXVpcmUoJy4va2V5cycpO1xudmFyIGhhc0JpbmFyeSA9IHJlcXVpcmUoJ2hhcy1iaW5hcnknKTtcbnZhciBzbGljZUJ1ZmZlciA9IHJlcXVpcmUoJ2FycmF5YnVmZmVyLnNsaWNlJyk7XG52YXIgYWZ0ZXIgPSByZXF1aXJlKCdhZnRlcicpO1xudmFyIHV0ZjggPSByZXF1aXJlKCd3dGYtOCcpO1xuXG52YXIgYmFzZTY0ZW5jb2RlcjtcbmlmIChnbG9iYWwgJiYgZ2xvYmFsLkFycmF5QnVmZmVyKSB7XG4gIGJhc2U2NGVuY29kZXIgPSByZXF1aXJlKCdiYXNlNjQtYXJyYXlidWZmZXInKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgcnVubmluZyBhbiBhbmRyb2lkIGJyb3dzZXIuIFRoYXQgcmVxdWlyZXMgdXMgdG8gdXNlXG4gKiBBcnJheUJ1ZmZlciB3aXRoIHBvbGxpbmcgdHJhbnNwb3J0cy4uLlxuICpcbiAqIGh0dHA6Ly9naGluZGEubmV0L2pwZWctYmxvYi1hamF4LWFuZHJvaWQvXG4gKi9cblxudmFyIGlzQW5kcm9pZCA9IHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmIC9BbmRyb2lkL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgcnVubmluZyBpbiBQaGFudG9tSlMuXG4gKiBVcGxvYWRpbmcgYSBCbG9iIHdpdGggUGhhbnRvbUpTIGRvZXMgbm90IHdvcmsgY29ycmVjdGx5LCBhcyByZXBvcnRlZCBoZXJlOlxuICogaHR0cHM6Ly9naXRodWIuY29tL2FyaXlhL3BoYW50b21qcy9pc3N1ZXMvMTEzOTVcbiAqIEB0eXBlIGJvb2xlYW5cbiAqL1xudmFyIGlzUGhhbnRvbUpTID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgL1BoYW50b21KUy9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG5cbi8qKlxuICogV2hlbiB0cnVlLCBhdm9pZHMgdXNpbmcgQmxvYnMgdG8gZW5jb2RlIHBheWxvYWRzLlxuICogQHR5cGUgYm9vbGVhblxuICovXG52YXIgZG9udFNlbmRCbG9icyA9IGlzQW5kcm9pZCB8fCBpc1BoYW50b21KUztcblxuLyoqXG4gKiBDdXJyZW50IHByb3RvY29sIHZlcnNpb24uXG4gKi9cblxuZXhwb3J0cy5wcm90b2NvbCA9IDM7XG5cbi8qKlxuICogUGFja2V0IHR5cGVzLlxuICovXG5cbnZhciBwYWNrZXRzID0gZXhwb3J0cy5wYWNrZXRzID0ge1xuICAgIG9wZW46ICAgICAwICAgIC8vIG5vbi13c1xuICAsIGNsb3NlOiAgICAxICAgIC8vIG5vbi13c1xuICAsIHBpbmc6ICAgICAyXG4gICwgcG9uZzogICAgIDNcbiAgLCBtZXNzYWdlOiAgNFxuICAsIHVwZ3JhZGU6ICA1XG4gICwgbm9vcDogICAgIDZcbn07XG5cbnZhciBwYWNrZXRzbGlzdCA9IGtleXMocGFja2V0cyk7XG5cbi8qKlxuICogUHJlbWFkZSBlcnJvciBwYWNrZXQuXG4gKi9cblxudmFyIGVyciA9IHsgdHlwZTogJ2Vycm9yJywgZGF0YTogJ3BhcnNlciBlcnJvcicgfTtcblxuLyoqXG4gKiBDcmVhdGUgYSBibG9iIGFwaSBldmVuIGZvciBibG9iIGJ1aWxkZXIgd2hlbiB2ZW5kb3IgcHJlZml4ZXMgZXhpc3RcbiAqL1xuXG52YXIgQmxvYiA9IHJlcXVpcmUoJ2Jsb2InKTtcblxuLyoqXG4gKiBFbmNvZGVzIGEgcGFja2V0LlxuICpcbiAqICAgICA8cGFja2V0IHR5cGUgaWQ+IFsgPGRhdGE+IF1cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICA1aGVsbG8gd29ybGRcbiAqICAgICAzXG4gKiAgICAgNFxuICpcbiAqIEJpbmFyeSBpcyBlbmNvZGVkIGluIGFuIGlkZW50aWNhbCBwcmluY2lwbGVcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLmVuY29kZVBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCB1dGY4ZW5jb2RlLCBjYWxsYmFjaykge1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2Ygc3VwcG9ydHNCaW5hcnkpIHtcbiAgICBjYWxsYmFjayA9IHN1cHBvcnRzQmluYXJ5O1xuICAgIHN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG4gIH1cblxuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgdXRmOGVuY29kZSkge1xuICAgIGNhbGxiYWNrID0gdXRmOGVuY29kZTtcbiAgICB1dGY4ZW5jb2RlID0gbnVsbDtcbiAgfVxuXG4gIHZhciBkYXRhID0gKHBhY2tldC5kYXRhID09PSB1bmRlZmluZWQpXG4gICAgPyB1bmRlZmluZWRcbiAgICA6IHBhY2tldC5kYXRhLmJ1ZmZlciB8fCBwYWNrZXQuZGF0YTtcblxuICBpZiAoZ2xvYmFsLkFycmF5QnVmZmVyICYmIGRhdGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiBlbmNvZGVBcnJheUJ1ZmZlcihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjayk7XG4gIH0gZWxzZSBpZiAoQmxvYiAmJiBkYXRhIGluc3RhbmNlb2YgZ2xvYmFsLkJsb2IpIHtcbiAgICByZXR1cm4gZW5jb2RlQmxvYihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjayk7XG4gIH1cblxuICAvLyBtaWdodCBiZSBhbiBvYmplY3Qgd2l0aCB7IGJhc2U2NDogdHJ1ZSwgZGF0YTogZGF0YUFzQmFzZTY0U3RyaW5nIH1cbiAgaWYgKGRhdGEgJiYgZGF0YS5iYXNlNjQpIHtcbiAgICByZXR1cm4gZW5jb2RlQmFzZTY0T2JqZWN0KHBhY2tldCwgY2FsbGJhY2spO1xuICB9XG5cbiAgLy8gU2VuZGluZyBkYXRhIGFzIGEgdXRmLTggc3RyaW5nXG4gIHZhciBlbmNvZGVkID0gcGFja2V0c1twYWNrZXQudHlwZV07XG5cbiAgLy8gZGF0YSBmcmFnbWVudCBpcyBvcHRpb25hbFxuICBpZiAodW5kZWZpbmVkICE9PSBwYWNrZXQuZGF0YSkge1xuICAgIGVuY29kZWQgKz0gdXRmOGVuY29kZSA/IHV0ZjguZW5jb2RlKFN0cmluZyhwYWNrZXQuZGF0YSkpIDogU3RyaW5nKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHJldHVybiBjYWxsYmFjaygnJyArIGVuY29kZWQpO1xuXG59O1xuXG5mdW5jdGlvbiBlbmNvZGVCYXNlNjRPYmplY3QocGFja2V0LCBjYWxsYmFjaykge1xuICAvLyBwYWNrZXQgZGF0YSBpcyBhbiBvYmplY3QgeyBiYXNlNjQ6IHRydWUsIGRhdGE6IGRhdGFBc0Jhc2U2NFN0cmluZyB9XG4gIHZhciBtZXNzYWdlID0gJ2InICsgZXhwb3J0cy5wYWNrZXRzW3BhY2tldC50eXBlXSArIHBhY2tldC5kYXRhLmRhdGE7XG4gIHJldHVybiBjYWxsYmFjayhtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBFbmNvZGUgcGFja2V0IGhlbHBlcnMgZm9yIGJpbmFyeSB0eXBlc1xuICovXG5cbmZ1bmN0aW9uIGVuY29kZUFycmF5QnVmZmVyKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKSB7XG4gIGlmICghc3VwcG9ydHNCaW5hcnkpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQocGFja2V0LCBjYWxsYmFjayk7XG4gIH1cblxuICB2YXIgZGF0YSA9IHBhY2tldC5kYXRhO1xuICB2YXIgY29udGVudEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gIHZhciByZXN1bHRCdWZmZXIgPSBuZXcgVWludDhBcnJheSgxICsgZGF0YS5ieXRlTGVuZ3RoKTtcblxuICByZXN1bHRCdWZmZXJbMF0gPSBwYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb250ZW50QXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICByZXN1bHRCdWZmZXJbaSsxXSA9IGNvbnRlbnRBcnJheVtpXTtcbiAgfVxuXG4gIHJldHVybiBjYWxsYmFjayhyZXN1bHRCdWZmZXIuYnVmZmVyKTtcbn1cblxuZnVuY3Rpb24gZW5jb2RlQmxvYkFzQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgaWYgKCFzdXBwb3J0c0JpbmFyeSkge1xuICAgIHJldHVybiBleHBvcnRzLmVuY29kZUJhc2U2NFBhY2tldChwYWNrZXQsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHZhciBmciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gIGZyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgIHBhY2tldC5kYXRhID0gZnIucmVzdWx0O1xuICAgIGV4cG9ydHMuZW5jb2RlUGFja2V0KHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIHRydWUsIGNhbGxiYWNrKTtcbiAgfTtcbiAgcmV0dXJuIGZyLnJlYWRBc0FycmF5QnVmZmVyKHBhY2tldC5kYXRhKTtcbn1cblxuZnVuY3Rpb24gZW5jb2RlQmxvYihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjaykge1xuICBpZiAoIXN1cHBvcnRzQmluYXJ5KSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuZW5jb2RlQmFzZTY0UGFja2V0KHBhY2tldCwgY2FsbGJhY2spO1xuICB9XG5cbiAgaWYgKGRvbnRTZW5kQmxvYnMpIHtcbiAgICByZXR1cm4gZW5jb2RlQmxvYkFzQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spO1xuICB9XG5cbiAgdmFyIGxlbmd0aCA9IG5ldyBVaW50OEFycmF5KDEpO1xuICBsZW5ndGhbMF0gPSBwYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgdmFyIGJsb2IgPSBuZXcgQmxvYihbbGVuZ3RoLmJ1ZmZlciwgcGFja2V0LmRhdGFdKTtcblxuICByZXR1cm4gY2FsbGJhY2soYmxvYik7XG59XG5cbi8qKlxuICogRW5jb2RlcyBhIHBhY2tldCB3aXRoIGJpbmFyeSBkYXRhIGluIGEgYmFzZTY0IHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQsIGhhcyBgdHlwZWAgYW5kIGBkYXRhYFxuICogQHJldHVybiB7U3RyaW5nfSBiYXNlNjQgZW5jb2RlZCBtZXNzYWdlXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQsIGNhbGxiYWNrKSB7XG4gIHZhciBtZXNzYWdlID0gJ2InICsgZXhwb3J0cy5wYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgaWYgKEJsb2IgJiYgcGFja2V0LmRhdGEgaW5zdGFuY2VvZiBnbG9iYWwuQmxvYikge1xuICAgIHZhciBmciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgZnIub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYjY0ID0gZnIucmVzdWx0LnNwbGl0KCcsJylbMV07XG4gICAgICBjYWxsYmFjayhtZXNzYWdlICsgYjY0KTtcbiAgICB9O1xuICAgIHJldHVybiBmci5yZWFkQXNEYXRhVVJMKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHZhciBiNjRkYXRhO1xuICB0cnkge1xuICAgIGI2NGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBpUGhvbmUgU2FmYXJpIGRvZXNuJ3QgbGV0IHlvdSBhcHBseSB3aXRoIHR5cGVkIGFycmF5c1xuICAgIHZhciB0eXBlZCA9IG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKTtcbiAgICB2YXIgYmFzaWMgPSBuZXcgQXJyYXkodHlwZWQubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICBiYXNpY1tpXSA9IHR5cGVkW2ldO1xuICAgIH1cbiAgICBiNjRkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBiYXNpYyk7XG4gIH1cbiAgbWVzc2FnZSArPSBnbG9iYWwuYnRvYShiNjRkYXRhKTtcbiAgcmV0dXJuIGNhbGxiYWNrKG1lc3NhZ2UpO1xufTtcblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0LiBDaGFuZ2VzIGZvcm1hdCB0byBCbG9iIGlmIHJlcXVlc3RlZC5cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHdpdGggYHR5cGVgIGFuZCBgZGF0YWAgKGlmIGFueSlcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZGVjb2RlUGFja2V0ID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIHV0ZjhkZWNvZGUpIHtcbiAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBlcnI7XG4gIH1cbiAgLy8gU3RyaW5nIGRhdGFcbiAgaWYgKHR5cGVvZiBkYXRhID09ICdzdHJpbmcnKSB7XG4gICAgaWYgKGRhdGEuY2hhckF0KDApID09ICdiJykge1xuICAgICAgcmV0dXJuIGV4cG9ydHMuZGVjb2RlQmFzZTY0UGFja2V0KGRhdGEuc3Vic3RyKDEpLCBiaW5hcnlUeXBlKTtcbiAgICB9XG5cbiAgICBpZiAodXRmOGRlY29kZSkge1xuICAgICAgZGF0YSA9IHRyeURlY29kZShkYXRhKTtcbiAgICAgIGlmIChkYXRhID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gZXJyO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgdHlwZSA9IGRhdGEuY2hhckF0KDApO1xuXG4gICAgaWYgKE51bWJlcih0eXBlKSAhPSB0eXBlIHx8ICFwYWNrZXRzbGlzdFt0eXBlXSkge1xuICAgICAgcmV0dXJuIGVycjtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS5sZW5ndGggPiAxKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBwYWNrZXRzbGlzdFt0eXBlXSwgZGF0YTogZGF0YS5zdWJzdHJpbmcoMSkgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHsgdHlwZTogcGFja2V0c2xpc3RbdHlwZV0gfTtcbiAgICB9XG4gIH1cblxuICB2YXIgYXNBcnJheSA9IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICB2YXIgdHlwZSA9IGFzQXJyYXlbMF07XG4gIHZhciByZXN0ID0gc2xpY2VCdWZmZXIoZGF0YSwgMSk7XG4gIGlmIChCbG9iICYmIGJpbmFyeVR5cGUgPT09ICdibG9iJykge1xuICAgIHJlc3QgPSBuZXcgQmxvYihbcmVzdF0pO1xuICB9XG4gIHJldHVybiB7IHR5cGU6IHBhY2tldHNsaXN0W3R5cGVdLCBkYXRhOiByZXN0IH07XG59O1xuXG5mdW5jdGlvbiB0cnlEZWNvZGUoZGF0YSkge1xuICB0cnkge1xuICAgIGRhdGEgPSB1dGY4LmRlY29kZShkYXRhKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gZGF0YTtcbn1cblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0IGVuY29kZWQgaW4gYSBiYXNlNjQgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGJhc2U2NCBlbmNvZGVkIG1lc3NhZ2VcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBgdHlwZWAgYW5kIGBkYXRhYCAoaWYgYW55KVxuICovXG5cbmV4cG9ydHMuZGVjb2RlQmFzZTY0UGFja2V0ID0gZnVuY3Rpb24obXNnLCBiaW5hcnlUeXBlKSB7XG4gIHZhciB0eXBlID0gcGFja2V0c2xpc3RbbXNnLmNoYXJBdCgwKV07XG4gIGlmICghYmFzZTY0ZW5jb2Rlcikge1xuICAgIHJldHVybiB7IHR5cGU6IHR5cGUsIGRhdGE6IHsgYmFzZTY0OiB0cnVlLCBkYXRhOiBtc2cuc3Vic3RyKDEpIH0gfTtcbiAgfVxuXG4gIHZhciBkYXRhID0gYmFzZTY0ZW5jb2Rlci5kZWNvZGUobXNnLnN1YnN0cigxKSk7XG5cbiAgaWYgKGJpbmFyeVR5cGUgPT09ICdibG9iJyAmJiBCbG9iKSB7XG4gICAgZGF0YSA9IG5ldyBCbG9iKFtkYXRhXSk7XG4gIH1cblxuICByZXR1cm4geyB0eXBlOiB0eXBlLCBkYXRhOiBkYXRhIH07XG59O1xuXG4vKipcbiAqIEVuY29kZXMgbXVsdGlwbGUgbWVzc2FnZXMgKHBheWxvYWQpLlxuICpcbiAqICAgICA8bGVuZ3RoPjpkYXRhXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgMTE6aGVsbG8gd29ybGQyOmhpXG4gKlxuICogSWYgYW55IGNvbnRlbnRzIGFyZSBiaW5hcnksIHRoZXkgd2lsbCBiZSBlbmNvZGVkIGFzIGJhc2U2NCBzdHJpbmdzLiBCYXNlNjRcbiAqIGVuY29kZWQgc3RyaW5ncyBhcmUgbWFya2VkIHdpdGggYSBiIGJlZm9yZSB0aGUgbGVuZ3RoIHNwZWNpZmllclxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHBhY2tldHNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGF5bG9hZCA9IGZ1bmN0aW9uIChwYWNrZXRzLCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBzdXBwb3J0c0JpbmFyeSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBzdXBwb3J0c0JpbmFyeTtcbiAgICBzdXBwb3J0c0JpbmFyeSA9IG51bGw7XG4gIH1cblxuICB2YXIgaXNCaW5hcnkgPSBoYXNCaW5hcnkocGFja2V0cyk7XG5cbiAgaWYgKHN1cHBvcnRzQmluYXJ5ICYmIGlzQmluYXJ5KSB7XG4gICAgaWYgKEJsb2IgJiYgIWRvbnRTZW5kQmxvYnMpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0Jsb2IocGFja2V0cywgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0FycmF5QnVmZmVyKHBhY2tldHMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIGlmICghcGFja2V0cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gY2FsbGJhY2soJzA6Jyk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkge1xuICAgIHJldHVybiBtZXNzYWdlLmxlbmd0aCArICc6JyArIG1lc3NhZ2U7XG4gIH1cblxuICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICBleHBvcnRzLmVuY29kZVBhY2tldChwYWNrZXQsICFpc0JpbmFyeSA/IGZhbHNlIDogc3VwcG9ydHNCaW5hcnksIHRydWUsIGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgIGRvbmVDYWxsYmFjayhudWxsLCBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkpO1xuICAgIH0pO1xuICB9XG5cbiAgbWFwKHBhY2tldHMsIGVuY29kZU9uZSwgZnVuY3Rpb24oZXJyLCByZXN1bHRzKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdHMuam9pbignJykpO1xuICB9KTtcbn07XG5cbi8qKlxuICogQXN5bmMgYXJyYXkgbWFwIHVzaW5nIGFmdGVyXG4gKi9cblxuZnVuY3Rpb24gbWFwKGFyeSwgZWFjaCwgZG9uZSkge1xuICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KGFyeS5sZW5ndGgpO1xuICB2YXIgbmV4dCA9IGFmdGVyKGFyeS5sZW5ndGgsIGRvbmUpO1xuXG4gIHZhciBlYWNoV2l0aEluZGV4ID0gZnVuY3Rpb24oaSwgZWwsIGNiKSB7XG4gICAgZWFjaChlbCwgZnVuY3Rpb24oZXJyb3IsIG1zZykge1xuICAgICAgcmVzdWx0W2ldID0gbXNnO1xuICAgICAgY2IoZXJyb3IsIHJlc3VsdCk7XG4gICAgfSk7XG4gIH07XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnkubGVuZ3RoOyBpKyspIHtcbiAgICBlYWNoV2l0aEluZGV4KGksIGFyeVtpXSwgbmV4dCk7XG4gIH1cbn1cblxuLypcbiAqIERlY29kZXMgZGF0YSB3aGVuIGEgcGF5bG9hZCBpcyBtYXliZSBleHBlY3RlZC4gUG9zc2libGUgYmluYXJ5IGNvbnRlbnRzIGFyZVxuICogZGVjb2RlZCBmcm9tIHRoZWlyIGJhc2U2NCByZXByZXNlbnRhdGlvblxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhLCBjYWxsYmFjayBtZXRob2RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5kZWNvZGVQYXlsb2FkID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgZGF0YSAhPSAnc3RyaW5nJykge1xuICAgIHJldHVybiBleHBvcnRzLmRlY29kZVBheWxvYWRBc0JpbmFyeShkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjayk7XG4gIH1cblxuICBpZiAodHlwZW9mIGJpbmFyeVR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IGJpbmFyeVR5cGU7XG4gICAgYmluYXJ5VHlwZSA9IG51bGw7XG4gIH1cblxuICB2YXIgcGFja2V0O1xuICBpZiAoZGF0YSA9PSAnJykge1xuICAgIC8vIHBhcnNlciBlcnJvciAtIGlnbm9yaW5nIHBheWxvYWRcbiAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgfVxuXG4gIHZhciBsZW5ndGggPSAnJ1xuICAgICwgbiwgbXNnO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gZGF0YS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIgY2hyID0gZGF0YS5jaGFyQXQoaSk7XG5cbiAgICBpZiAoJzonICE9IGNocikge1xuICAgICAgbGVuZ3RoICs9IGNocjtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCcnID09IGxlbmd0aCB8fCAobGVuZ3RoICE9IChuID0gTnVtYmVyKGxlbmd0aCkpKSkge1xuICAgICAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICAgICAgfVxuXG4gICAgICBtc2cgPSBkYXRhLnN1YnN0cihpICsgMSwgbik7XG5cbiAgICAgIGlmIChsZW5ndGggIT0gbXNnLmxlbmd0aCkge1xuICAgICAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICAgICAgfVxuXG4gICAgICBpZiAobXNnLmxlbmd0aCkge1xuICAgICAgICBwYWNrZXQgPSBleHBvcnRzLmRlY29kZVBhY2tldChtc2csIGJpbmFyeVR5cGUsIHRydWUpO1xuXG4gICAgICAgIGlmIChlcnIudHlwZSA9PSBwYWNrZXQudHlwZSAmJiBlcnIuZGF0YSA9PSBwYWNrZXQuZGF0YSkge1xuICAgICAgICAgIC8vIHBhcnNlciBlcnJvciBpbiBpbmRpdmlkdWFsIHBhY2tldCAtIGlnbm9yaW5nIHBheWxvYWRcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXQgPSBjYWxsYmFjayhwYWNrZXQsIGkgKyBuLCBsKTtcbiAgICAgICAgaWYgKGZhbHNlID09PSByZXQpIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gYWR2YW5jZSBjdXJzb3JcbiAgICAgIGkgKz0gbjtcbiAgICAgIGxlbmd0aCA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIGlmIChsZW5ndGggIT0gJycpIHtcbiAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG4gIH1cblxufTtcblxuLyoqXG4gKiBFbmNvZGVzIG11bHRpcGxlIG1lc3NhZ2VzIChwYXlsb2FkKSBhcyBiaW5hcnkuXG4gKlxuICogPDEgPSBiaW5hcnksIDAgPSBzdHJpbmc+PG51bWJlciBmcm9tIDAtOT48bnVtYmVyIGZyb20gMC05PlsuLi5dPG51bWJlclxuICogMjU1PjxkYXRhPlxuICpcbiAqIEV4YW1wbGU6XG4gKiAxIDMgMjU1IDEgMiAzLCBpZiB0aGUgYmluYXJ5IGNvbnRlbnRzIGFyZSBpbnRlcnByZXRlZCBhcyA4IGJpdCBpbnRlZ2Vyc1xuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHBhY2tldHNcbiAqIEByZXR1cm4ge0FycmF5QnVmZmVyfSBlbmNvZGVkIHBheWxvYWRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGF5bG9hZEFzQXJyYXlCdWZmZXIgPSBmdW5jdGlvbihwYWNrZXRzLCBjYWxsYmFjaykge1xuICBpZiAoIXBhY2tldHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBBcnJheUJ1ZmZlcigwKSk7XG4gIH1cblxuICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICBleHBvcnRzLmVuY29kZVBhY2tldChwYWNrZXQsIHRydWUsIHRydWUsIGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHJldHVybiBkb25lQ2FsbGJhY2sobnVsbCwgZGF0YSk7XG4gICAgfSk7XG4gIH1cblxuICBtYXAocGFja2V0cywgZW5jb2RlT25lLCBmdW5jdGlvbihlcnIsIGVuY29kZWRQYWNrZXRzKSB7XG4gICAgdmFyIHRvdGFsTGVuZ3RoID0gZW5jb2RlZFBhY2tldHMucmVkdWNlKGZ1bmN0aW9uKGFjYywgcCkge1xuICAgICAgdmFyIGxlbjtcbiAgICAgIGlmICh0eXBlb2YgcCA9PT0gJ3N0cmluZycpe1xuICAgICAgICBsZW4gPSBwLmxlbmd0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxlbiA9IHAuYnl0ZUxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2MgKyBsZW4udG9TdHJpbmcoKS5sZW5ndGggKyBsZW4gKyAyOyAvLyBzdHJpbmcvYmluYXJ5IGlkZW50aWZpZXIgKyBzZXBhcmF0b3IgPSAyXG4gICAgfSwgMCk7XG5cbiAgICB2YXIgcmVzdWx0QXJyYXkgPSBuZXcgVWludDhBcnJheSh0b3RhbExlbmd0aCk7XG5cbiAgICB2YXIgYnVmZmVySW5kZXggPSAwO1xuICAgIGVuY29kZWRQYWNrZXRzLmZvckVhY2goZnVuY3Rpb24ocCkge1xuICAgICAgdmFyIGlzU3RyaW5nID0gdHlwZW9mIHAgPT09ICdzdHJpbmcnO1xuICAgICAgdmFyIGFiID0gcDtcbiAgICAgIGlmIChpc1N0cmluZykge1xuICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KHAubGVuZ3RoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmlld1tpXSA9IHAuY2hhckNvZGVBdChpKTtcbiAgICAgICAgfVxuICAgICAgICBhYiA9IHZpZXcuYnVmZmVyO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNTdHJpbmcpIHsgLy8gbm90IHRydWUgYmluYXJ5XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMDtcbiAgICAgIH0gZWxzZSB7IC8vIHRydWUgYmluYXJ5XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMTtcbiAgICAgIH1cblxuICAgICAgdmFyIGxlblN0ciA9IGFiLmJ5dGVMZW5ndGgudG9TdHJpbmcoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuU3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gcGFyc2VJbnQobGVuU3RyW2ldKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMjU1O1xuXG4gICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGFiKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IHZpZXdbaV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY2FsbGJhY2socmVzdWx0QXJyYXkuYnVmZmVyKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEVuY29kZSBhcyBCbG9iXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVQYXlsb2FkQXNCbG9iID0gZnVuY3Rpb24ocGFja2V0cywgY2FsbGJhY2spIHtcbiAgZnVuY3Rpb24gZW5jb2RlT25lKHBhY2tldCwgZG9uZUNhbGxiYWNrKSB7XG4gICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCB0cnVlLCB0cnVlLCBmdW5jdGlvbihlbmNvZGVkKSB7XG4gICAgICB2YXIgYmluYXJ5SWRlbnRpZmllciA9IG5ldyBVaW50OEFycmF5KDEpO1xuICAgICAgYmluYXJ5SWRlbnRpZmllclswXSA9IDE7XG4gICAgICBpZiAodHlwZW9mIGVuY29kZWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoZW5jb2RlZC5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVuY29kZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2aWV3W2ldID0gZW5jb2RlZC5jaGFyQ29kZUF0KGkpO1xuICAgICAgICB9XG4gICAgICAgIGVuY29kZWQgPSB2aWV3LmJ1ZmZlcjtcbiAgICAgICAgYmluYXJ5SWRlbnRpZmllclswXSA9IDA7XG4gICAgICB9XG5cbiAgICAgIHZhciBsZW4gPSAoZW5jb2RlZCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKVxuICAgICAgICA/IGVuY29kZWQuYnl0ZUxlbmd0aFxuICAgICAgICA6IGVuY29kZWQuc2l6ZTtcblxuICAgICAgdmFyIGxlblN0ciA9IGxlbi50b1N0cmluZygpO1xuICAgICAgdmFyIGxlbmd0aEFyeSA9IG5ldyBVaW50OEFycmF5KGxlblN0ci5sZW5ndGggKyAxKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuU3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxlbmd0aEFyeVtpXSA9IHBhcnNlSW50KGxlblN0cltpXSk7XG4gICAgICB9XG4gICAgICBsZW5ndGhBcnlbbGVuU3RyLmxlbmd0aF0gPSAyNTU7XG5cbiAgICAgIGlmIChCbG9iKSB7XG4gICAgICAgIHZhciBibG9iID0gbmV3IEJsb2IoW2JpbmFyeUlkZW50aWZpZXIuYnVmZmVyLCBsZW5ndGhBcnkuYnVmZmVyLCBlbmNvZGVkXSk7XG4gICAgICAgIGRvbmVDYWxsYmFjayhudWxsLCBibG9iKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG1hcChwYWNrZXRzLCBlbmNvZGVPbmUsIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICAgIHJldHVybiBjYWxsYmFjayhuZXcgQmxvYihyZXN1bHRzKSk7XG4gIH0pO1xufTtcblxuLypcbiAqIERlY29kZXMgZGF0YSB3aGVuIGEgcGF5bG9hZCBpcyBtYXliZSBleHBlY3RlZC4gU3RyaW5ncyBhcmUgZGVjb2RlZCBieVxuICogaW50ZXJwcmV0aW5nIGVhY2ggYnl0ZSBhcyBhIGtleSBjb2RlIGZvciBlbnRyaWVzIG1hcmtlZCB0byBzdGFydCB3aXRoIDAuIFNlZVxuICogZGVzY3JpcHRpb24gb2YgZW5jb2RlUGF5bG9hZEFzQmluYXJ5XG4gKlxuICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gZGF0YSwgY2FsbGJhY2sgbWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb2RlUGF5bG9hZEFzQmluYXJ5ID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgYmluYXJ5VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gYmluYXJ5VHlwZTtcbiAgICBiaW5hcnlUeXBlID0gbnVsbDtcbiAgfVxuXG4gIHZhciBidWZmZXJUYWlsID0gZGF0YTtcbiAgdmFyIGJ1ZmZlcnMgPSBbXTtcblxuICB2YXIgbnVtYmVyVG9vTG9uZyA9IGZhbHNlO1xuICB3aGlsZSAoYnVmZmVyVGFpbC5ieXRlTGVuZ3RoID4gMCkge1xuICAgIHZhciB0YWlsQXJyYXkgPSBuZXcgVWludDhBcnJheShidWZmZXJUYWlsKTtcbiAgICB2YXIgaXNTdHJpbmcgPSB0YWlsQXJyYXlbMF0gPT09IDA7XG4gICAgdmFyIG1zZ0xlbmd0aCA9ICcnO1xuXG4gICAgZm9yICh2YXIgaSA9IDE7IDsgaSsrKSB7XG4gICAgICBpZiAodGFpbEFycmF5W2ldID09IDI1NSkgYnJlYWs7XG5cbiAgICAgIGlmIChtc2dMZW5ndGgubGVuZ3RoID4gMzEwKSB7XG4gICAgICAgIG51bWJlclRvb0xvbmcgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgbXNnTGVuZ3RoICs9IHRhaWxBcnJheVtpXTtcbiAgICB9XG5cbiAgICBpZihudW1iZXJUb29Mb25nKSByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcblxuICAgIGJ1ZmZlclRhaWwgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCAyICsgbXNnTGVuZ3RoLmxlbmd0aCk7XG4gICAgbXNnTGVuZ3RoID0gcGFyc2VJbnQobXNnTGVuZ3RoKTtcblxuICAgIHZhciBtc2cgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCAwLCBtc2dMZW5ndGgpO1xuICAgIGlmIChpc1N0cmluZykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbXNnID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDhBcnJheShtc2cpKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gaVBob25lIFNhZmFyaSBkb2Vzbid0IGxldCB5b3UgYXBwbHkgdG8gdHlwZWQgYXJyYXlzXG4gICAgICAgIHZhciB0eXBlZCA9IG5ldyBVaW50OEFycmF5KG1zZyk7XG4gICAgICAgIG1zZyA9ICcnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgbXNnICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodHlwZWRbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgYnVmZmVycy5wdXNoKG1zZyk7XG4gICAgYnVmZmVyVGFpbCA9IHNsaWNlQnVmZmVyKGJ1ZmZlclRhaWwsIG1zZ0xlbmd0aCk7XG4gIH1cblxuICB2YXIgdG90YWwgPSBidWZmZXJzLmxlbmd0aDtcbiAgYnVmZmVycy5mb3JFYWNoKGZ1bmN0aW9uKGJ1ZmZlciwgaSkge1xuICAgIGNhbGxiYWNrKGV4cG9ydHMuZGVjb2RlUGFja2V0KGJ1ZmZlciwgYmluYXJ5VHlwZSwgdHJ1ZSksIGksIHRvdGFsKTtcbiAgfSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///aa6c\n")},adfa:function(module,exports,__webpack_require__){eval("/**\n * Utility functions for crossfilter datasets\n * We roughly follow the crossfilter design of dimensions and groups, but we\n * add extra steps to allow transformations on the data.\n * 1. a datum is turned into a raw value, ie. string or number etc. by rawValueFn\n * 2. it is then cast to the correct type value using baseValFn\n * 3. a further transfrom can be applied with valueFn\n * 4. a value is grouped using groupFn; this value must be either a number or a string.\n *\n * @module client/util-crossfilter\n * @see rawValueFn, baseValueFn, valueFn, groupFn\n */\nvar misval = __webpack_require__(/*! ./misval */ \"bff6\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\n\n/**\n * @typedef {Object} SubgroupValue\n * @property {number} count The count of the number of elements in this subgroup\n * @property {number} sum The sum of all elements in this subgroup\n */\n\n/**\n * Reduce a SubgroupValue to a single number\n *\n * @callback reduceCB\n * @param {SubgroupValue} d SubgroupValue\n * @returns {number} Reduced value\n */\n/**\n\n/**\n * Returns a function for further reducing the crossfilter group\n * to a single value, depending on sum/count/average settings of\n * the Aggregate class.\n * @param {Aggregate} facet - The Aggregate class for which to create the reduction function\n * @returns {cb} The required reduction function\n */\nfunction reduceFn (aggregate) {\n  if (aggregate.doSum) {\n    /**\n     * @callback subgroupSum\n     * @param {SubgroupValue} d\n     * @returns {number} sum\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n      if (d.count > 0) {\n        return d.sum;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doCount) {\n    /**\n     * @callback subgroupCount\n     * @param {SubgroupValue} d\n     * @returns {number} count\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n      if (d.count > 0) {\n        return d.count;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doAverage) {\n    /**\n     * @callback subgroupAverage\n     * @param {SubgroupValue} d\n     * @returns {number} d.sum/d.count\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n\n      if (d.count > 0) {\n        return d.sum / d.count;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doStddev) {\n    /**\n     * @callback subgroupStddev\n     * @param {SubgroupValue} d\n     * @returns {number} stddev(d)\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n\n      // \\sum_i (x_i - \\bar x)^2 =\n      //   \\sum_i (x_i^2 - 2x_i\\bar x + (\\bar x)^2) =\n      //   \\sum_i (x_i^2) - 2 N (\\bar x)^2 + N(\\bar x)^2 =\n      //   \\sum_i (x_i^2) - N (\\bar x)^2\n      if (d.count > 1) {\n        return Math.sqrt((d.sumsquares - (d.sum * d.sum / d.count)) / (d.count - 1));\n      } else {\n        return misval;\n      }\n    };\n  }\n\n  console.error('Operation not implemented for this Aggregate', aggregate);\n  return function (d) {\n    if (d === misval || d == null) {\n      return misval;\n    }\n    if (d.count > 0) {\n      return d.count;\n    } else {\n      return misval;\n    }\n  };\n}\n\n// ********************************************************\n// Facet transform utility function\n// ********************************************************\n\n/**\n * Returns the base value for a datum\n *\n * @callback baseValueCB\n * @param {Object} d Raw data record\n * @returns {Object} base value\n */\n\n/**\n * Raw value for given facet\n * @param {Facet} facet\n * @returns {rawValueCB} Raw value function for this facet\n */\nfunction rawValueFn (facet) {\n  var accessor;\n\n  // Array dimensions have a [] appended to the accessor,\n  // remove it to get to the actual accessor\n  var path = facet.accessor;\n  if (path.match(/\\[]$/)) {\n    path = path.substring(0, path.length - 2);\n  }\n\n  var misvals = {};\n  facet.misval.forEach(function (val) {\n    misvals[val] = true;\n  });\n\n  // Access nested properties via a double hash sign, this to prevent collision with regular keys; fi. 'person.name'\n  path = path.split('##');\n\n  if (path.length === 1) {\n    // Use a simple direct accessor, as it is probably faster than the more general case\n    // and it was implemented already\n    if (facet.misval.length > 0) {\n      accessor = function (d) {\n        var value = d[path[0]];\n        if (value === undefined || value === null || value in misvals) {\n          return misval;\n        }\n        return value;\n      };\n    } else {\n      accessor = function (d) {\n        var value = d[path[0]];\n        if (value === undefined || value === null) {\n          return misval;\n        }\n        return value;\n      };\n    }\n  } else {\n    // Recursively follow the crumbs to the desired property\n    accessor = function (d) {\n      var i = 0;\n      var value = d;\n\n      for (i = 0; i < path.length; i++) {\n        if (value && value[path[i]] !== undefined) {\n          value = value[path[i]];\n        } else {\n          return misval;\n        }\n      }\n\n      if (value === null || value in misvals) {\n        value = misval;\n      }\n      return value;\n    };\n  }\n\n  return accessor;\n}\n\n/**\n * Base value for given facet, ie. cast to correct type or object.\n * @param {Facet} facet\n * @returns {vaseValueCB} Base value function for this facet\n */\nfunction baseValueFn (facet) {\n  var rawValFn = rawValueFn(facet);\n\n  if (facet.isContinuous) {\n    /*\n     * Continuous facets:\n     * Parse numeric value from base value\n     */\n    return function (d) {\n      var val = parseFloat(rawValFn(d));\n      if (isNaN(val) || val === Infinity || val === -Infinity) {\n        return misval;\n      }\n      return val;\n    };\n  } else if (facet.isCategorial) {\n    return function (d) {\n      var vals = rawValFn(d);\n      if (vals !== misval) {\n        if (vals instanceof Array) {\n          vals.forEach(function (val, i) {\n            vals[i] = val.toString();\n          });\n        } else {\n          vals = vals.toString();\n        }\n        return vals;\n      }\n      return misval;\n    };\n  } else if (facet.isDatetime) {\n    /*\n     * Time parsing:\n     * 1. moment parses the string using the given format, but defaults to\n     *    the [ISO 8601 standard](https://en.wikipedia.org/wiki/ISO_8601)\n     * 2. Note that if the string contains timezone information, that is parsed too.\n     * 3. The time is transformed to requested timezone, defaulting the locale default\n     *    when no zone is set\n    */\n    var timeFormat = facet.datetimeTransform.format;\n    if (timeFormat === 'ISO8601') {\n      // use default ISO formatting\n      timeFormat = moment.ISO_8601;\n    }\n\n    var timeZone = facet.datetimeTransform.zone;\n    if (timeZone === 'ISO8601') {\n      // use default locale timezone, get overridden if a string contains a timezone\n      timeZone = moment.tz.guess();\n    } else {\n      timeZone = util.timeZones.get(timeZone, 'description').format;\n    }\n\n    return function (d) {\n      var value = rawValFn(d);\n      if (value !== misval) {\n        var m = moment.tz(value, timeFormat, timeZone);\n        if (m.isValid()) {\n          return m;\n        }\n      }\n      return misval;\n    };\n  } else if (facet.isDuration) {\n    /*\n     * Duration parsing:\n     * 1. If no format is given, the string parsed using\n     *    the [ISO 8601 standard](https://en.wikipedia.org/wiki/ISO_8601)\n     * 2. If a format is given, the string is parsed as float and interpreted in the given units\n     */\n    var units = facet.durationTransform.units;\n    if (units === 'ISO8601') {\n      return function (d) {\n        var value = rawValFn(d);\n\n        // parse string if necessary\n        if (value !== misval && typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          value = moment.duration(value);\n        }\n\n        // check for valid duration\n        if (moment.isDuration(value)) {\n          return value;\n        }\n\n        return misval;\n      };\n    } else {\n      units = util.durationUnits.get(units, 'description').momentFormat;\n      return function (d) {\n        var value = rawValFn(d);\n\n        // parse string if necessary\n        if (value !== misval && !isNaN(value)) {\n          // NOTE: isNaN('0') is false, if that gives problems, we could use:\n          // value == +value) { // eslint-disable-line eqeqeq\n          value = moment.duration(parseFloat(value), units);\n        }\n\n        // check for valid duration\n        if (moment.isDuration(value)) {\n          return value;\n        }\n\n        return misval;\n      };\n    }\n  }\n\n  // isCategorial, isText\n  // no casting or constructing necessary, return the raw value\n  return rawValFn;\n}\n\n/**\n * Returns the transformed value from a base value\n *\n * @callback valueCB\n * @param {Object} d Base value\n * @returns {Object} Transformed value\n */\n\n/**\n * Create a function that returns the transformed value for this facet\n * @param {Facet} facet\n * @returns {valueCB} Value function for this facet\n */\nfunction valueFn (facet) {\n  // get base value function\n  var baseValFn = baseValueFn(facet);\n\n  if (facet.isConstant) {\n    return function () { return '1'; };\n  } else if (facet.isContinuous) {\n    // do we have a continuous transform?\n    if (facet.continuousTransform && facet.continuousTransform.type !== 'none') {\n      // yes, use it\n      return function (d) {\n        var val = facet.continuousTransform.transform(parseFloat(baseValFn(d)));\n        if (isNaN(val) || val === Infinity || val === -Infinity) {\n          return misval;\n        }\n        return val;\n      };\n    }\n  } else if (facet.isCategorial) {\n    // do we have a categorial transform?\n    if (facet.categorialTransform && facet.categorialTransform.rules.length > 0) {\n      // yes, use it\n      return function (d) {\n        var val = baseValFn(d);\n        return val === misval ? misval : facet.categorialTransform.transform(baseValFn(d));\n      };\n    }\n  } else if (facet.isDatetime) {\n    // always use the transform, so we do not have to repeat the yes/no transfrom logic here\n    return function (d) {\n      var val = baseValFn(d);\n      return val === misval ? misval : facet.datetimeTransform.transform(val);\n    };\n  } else if (facet.isDuration) {\n    // always use the transform, so we do not have to repeat the yes/no transfrom logic here\n    return function (d) {\n      var val = baseValFn(d);\n      return val === misval ? misval : facet.durationTransform.transform(val);\n    };\n  }\n\n  // no transfrom, return base value\n  return baseValFn;\n}\n\nfunction continuousGroupFn (partition) {\n  return function (d) {\n    if (d === misval) {\n      return d;\n    }\n\n    var ngroups = partition.groups.length;\n    if (d < partition.minval || d > partition.maxval) {\n      return misval;\n    }\n\n    // bins include their lower bound, but not their upper bound\n    var i = 0;\n    while (i < ngroups && d >= partition.groups.models[i].max) {\n      i++;\n    }\n    // special case last bin includes also upperbound d === partition.maxval\n    if (i === ngroups) {\n      return partition.groups.models[i - 1].value;\n    }\n    return partition.groups.models[i].value;\n  };\n}\n\n/*\n * Round the datetime to the specified resolution\n * see:\n * http://momentjs.com/docs/#/manipulating/start-of/\n * http://momentjs.com/docs/#/displaying/as-javascript-date/\n */\nfunction datetimeGroupFn (partition) {\n  var timeStep = util.getDatetimeResolution(partition.minval, partition.maxval);\n  return function (d) {\n    if (d === misval) {\n      return misval;\n    }\n    if (d.isBefore(partition.minval) || d.isAfter(partition.maxval)) {\n      return misval;\n    }\n    var grouped = moment(d).startOf(timeStep).format();\n    return grouped;\n  };\n}\n\n/*\n * Round the duration to the specified resolution\n */\nfunction durationGroupFn (partition) {\n  var timeStep = util.getDurationResolution(partition.minval, partition.maxval);\n  return function (d) {\n    if (d === misval) {\n      return misval;\n    }\n    if (d < partition.minval || d > partition.maxval) {\n      return misval;\n    }\n    var rounded = Math.floor(parseFloat(d.as(timeStep)));\n    return moment.duration(rounded, timeStep).toISOString();\n  };\n}\n\n/*\n * Don't do any grouping; that is done in the step from base value to value.\n * Matching of facet value and group could lead to a different ordering,\n * which is not allowed by crossfilter\n */\nfunction categorialGroupFn (partition) {\n  return function (d) { return d; };\n}\n\n/**\n * Returns the grouped value for a transformed value\n *\n * @callback groupCB\n * @param {Object} d Transformed value\n * @returns {Object} Group\n */\n\n/**\n * Create a function that returns the group value for a partition\n * @param {Partition} partition\n * @returns {cb} Group function for this partition, taking a `Data`\n */\nfunction groupFn (partition) {\n  if (partition.isConstant) {\n    return function () { return '1'; };\n  } else if (partition.isContinuous) {\n    return continuousGroupFn(partition);\n  } else if (partition.isCategorial) {\n    return categorialGroupFn(partition);\n  } else if (partition.isDatetime) {\n    return datetimeGroupFn(partition);\n  } else if (partition.isDuration) {\n    return durationGroupFn(partition);\n  } else if (partition.isText) {\n    return function (d) { return d.toString(); };\n  } else {\n    console.error('Group function not implemented for partition', partition);\n  }\n}\n\nmodule.exports = {\n  rawValueFn: rawValueFn,\n  baseValueFn: baseValueFn,\n  valueFn: valueFn,\n  groupFn: groupFn,\n\n  reduceFn: reduceFn\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRmYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9jcm9zc2ZpbHRlci5qcz8xZjdhIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIGNyb3NzZmlsdGVyIGRhdGFzZXRzXG4gKiBXZSByb3VnaGx5IGZvbGxvdyB0aGUgY3Jvc3NmaWx0ZXIgZGVzaWduIG9mIGRpbWVuc2lvbnMgYW5kIGdyb3VwcywgYnV0IHdlXG4gKiBhZGQgZXh0cmEgc3RlcHMgdG8gYWxsb3cgdHJhbnNmb3JtYXRpb25zIG9uIHRoZSBkYXRhLlxuICogMS4gYSBkYXR1bSBpcyB0dXJuZWQgaW50byBhIHJhdyB2YWx1ZSwgaWUuIHN0cmluZyBvciBudW1iZXIgZXRjLiBieSByYXdWYWx1ZUZuXG4gKiAyLiBpdCBpcyB0aGVuIGNhc3QgdG8gdGhlIGNvcnJlY3QgdHlwZSB2YWx1ZSB1c2luZyBiYXNlVmFsRm5cbiAqIDMuIGEgZnVydGhlciB0cmFuc2Zyb20gY2FuIGJlIGFwcGxpZWQgd2l0aCB2YWx1ZUZuXG4gKiA0LiBhIHZhbHVlIGlzIGdyb3VwZWQgdXNpbmcgZ3JvdXBGbjsgdGhpcyB2YWx1ZSBtdXN0IGJlIGVpdGhlciBhIG51bWJlciBvciBhIHN0cmluZy5cbiAqXG4gKiBAbW9kdWxlIGNsaWVudC91dGlsLWNyb3NzZmlsdGVyXG4gKiBAc2VlIHJhd1ZhbHVlRm4sIGJhc2VWYWx1ZUZuLCB2YWx1ZUZuLCBncm91cEZuXG4gKi9cbnZhciBtaXN2YWwgPSByZXF1aXJlKCcuL21pc3ZhbCcpO1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsL3RpbWUnKTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTdWJncm91cFZhbHVlXG4gKiBAcHJvcGVydHkge251bWJlcn0gY291bnQgVGhlIGNvdW50IG9mIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBzdWJncm91cFxuICogQHByb3BlcnR5IHtudW1iZXJ9IHN1bSBUaGUgc3VtIG9mIGFsbCBlbGVtZW50cyBpbiB0aGlzIHN1Ymdyb3VwXG4gKi9cblxuLyoqXG4gKiBSZWR1Y2UgYSBTdWJncm91cFZhbHVlIHRvIGEgc2luZ2xlIG51bWJlclxuICpcbiAqIEBjYWxsYmFjayByZWR1Y2VDQlxuICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkIFN1Ymdyb3VwVmFsdWVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJlZHVjZWQgdmFsdWVcbiAqL1xuLyoqXG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIGZvciBmdXJ0aGVyIHJlZHVjaW5nIHRoZSBjcm9zc2ZpbHRlciBncm91cFxuICogdG8gYSBzaW5nbGUgdmFsdWUsIGRlcGVuZGluZyBvbiBzdW0vY291bnQvYXZlcmFnZSBzZXR0aW5ncyBvZlxuICogdGhlIEFnZ3JlZ2F0ZSBjbGFzcy5cbiAqIEBwYXJhbSB7QWdncmVnYXRlfSBmYWNldCAtIFRoZSBBZ2dyZWdhdGUgY2xhc3MgZm9yIHdoaWNoIHRvIGNyZWF0ZSB0aGUgcmVkdWN0aW9uIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7Y2J9IFRoZSByZXF1aXJlZCByZWR1Y3Rpb24gZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gcmVkdWNlRm4gKGFnZ3JlZ2F0ZSkge1xuICBpZiAoYWdncmVnYXRlLmRvU3VtKSB7XG4gICAgLyoqXG4gICAgICogQGNhbGxiYWNrIHN1Ymdyb3VwU3VtXG4gICAgICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkXG4gICAgICogQHJldHVybnMge251bWJlcn0gc3VtXG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICBpZiAoZCA9PT0gbWlzdmFsIHx8IGQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgICAgaWYgKGQuY291bnQgPiAwKSB7XG4gICAgICAgIHJldHVybiBkLnN1bTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIGlmIChhZ2dyZWdhdGUuZG9Db3VudCkge1xuICAgIC8qKlxuICAgICAqIEBjYWxsYmFjayBzdWJncm91cENvdW50XG4gICAgICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkXG4gICAgICogQHJldHVybnMge251bWJlcn0gY291bnRcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGQuY291bnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgIH07XG4gIH0gZWxzZSBpZiAoYWdncmVnYXRlLmRvQXZlcmFnZSkge1xuICAgIC8qKlxuICAgICAqIEBjYWxsYmFjayBzdWJncm91cEF2ZXJhZ2VcbiAgICAgKiBAcGFyYW0ge1N1Ymdyb3VwVmFsdWV9IGRcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBkLnN1bS9kLmNvdW50XG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICBpZiAoZCA9PT0gbWlzdmFsIHx8IGQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuXG4gICAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGQuc3VtIC8gZC5jb3VudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIGlmIChhZ2dyZWdhdGUuZG9TdGRkZXYpIHtcbiAgICAvKipcbiAgICAgKiBAY2FsbGJhY2sgc3ViZ3JvdXBTdGRkZXZcbiAgICAgKiBAcGFyYW0ge1N1Ymdyb3VwVmFsdWV9IGRcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBzdGRkZXYoZClcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG5cbiAgICAgIC8vIFxcc3VtX2kgKHhfaSAtIFxcYmFyIHgpXjIgPVxuICAgICAgLy8gICBcXHN1bV9pICh4X2leMiAtIDJ4X2lcXGJhciB4ICsgKFxcYmFyIHgpXjIpID1cbiAgICAgIC8vICAgXFxzdW1faSAoeF9pXjIpIC0gMiBOIChcXGJhciB4KV4yICsgTihcXGJhciB4KV4yID1cbiAgICAgIC8vICAgXFxzdW1faSAoeF9pXjIpIC0gTiAoXFxiYXIgeCleMlxuICAgICAgaWYgKGQuY291bnQgPiAxKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnNxcnQoKGQuc3Vtc3F1YXJlcyAtIChkLnN1bSAqIGQuc3VtIC8gZC5jb3VudCkpIC8gKGQuY291bnQgLSAxKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBjb25zb2xlLmVycm9yKCdPcGVyYXRpb24gbm90IGltcGxlbWVudGVkIGZvciB0aGlzIEFnZ3JlZ2F0ZScsIGFnZ3JlZ2F0ZSk7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgIHJldHVybiBkLmNvdW50O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgfTtcbn1cblxuLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbi8vIEZhY2V0IHRyYW5zZm9ybSB1dGlsaXR5IGZ1bmN0aW9uXG4vLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG4vKipcbiAqIFJldHVybnMgdGhlIGJhc2UgdmFsdWUgZm9yIGEgZGF0dW1cbiAqXG4gKiBAY2FsbGJhY2sgYmFzZVZhbHVlQ0JcbiAqIEBwYXJhbSB7T2JqZWN0fSBkIFJhdyBkYXRhIHJlY29yZFxuICogQHJldHVybnMge09iamVjdH0gYmFzZSB2YWx1ZVxuICovXG5cbi8qKlxuICogUmF3IHZhbHVlIGZvciBnaXZlbiBmYWNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqIEByZXR1cm5zIHtyYXdWYWx1ZUNCfSBSYXcgdmFsdWUgZnVuY3Rpb24gZm9yIHRoaXMgZmFjZXRcbiAqL1xuZnVuY3Rpb24gcmF3VmFsdWVGbiAoZmFjZXQpIHtcbiAgdmFyIGFjY2Vzc29yO1xuXG4gIC8vIEFycmF5IGRpbWVuc2lvbnMgaGF2ZSBhIFtdIGFwcGVuZGVkIHRvIHRoZSBhY2Nlc3NvcixcbiAgLy8gcmVtb3ZlIGl0IHRvIGdldCB0byB0aGUgYWN0dWFsIGFjY2Vzc29yXG4gIHZhciBwYXRoID0gZmFjZXQuYWNjZXNzb3I7XG4gIGlmIChwYXRoLm1hdGNoKC9cXFtdJC8pKSB7XG4gICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoIC0gMik7XG4gIH1cblxuICB2YXIgbWlzdmFscyA9IHt9O1xuICBmYWNldC5taXN2YWwuZm9yRWFjaChmdW5jdGlvbiAodmFsKSB7XG4gICAgbWlzdmFsc1t2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgLy8gQWNjZXNzIG5lc3RlZCBwcm9wZXJ0aWVzIHZpYSBhIGRvdWJsZSBoYXNoIHNpZ24sIHRoaXMgdG8gcHJldmVudCBjb2xsaXNpb24gd2l0aCByZWd1bGFyIGtleXM7IGZpLiAncGVyc29uLm5hbWUnXG4gIHBhdGggPSBwYXRoLnNwbGl0KCcjIycpO1xuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMSkge1xuICAgIC8vIFVzZSBhIHNpbXBsZSBkaXJlY3QgYWNjZXNzb3IsIGFzIGl0IGlzIHByb2JhYmx5IGZhc3RlciB0aGFuIHRoZSBtb3JlIGdlbmVyYWwgY2FzZVxuICAgIC8vIGFuZCBpdCB3YXMgaW1wbGVtZW50ZWQgYWxyZWFkeVxuICAgIGlmIChmYWNldC5taXN2YWwubGVuZ3RoID4gMCkge1xuICAgICAgYWNjZXNzb3IgPSBmdW5jdGlvbiAoZCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBkW3BhdGhbMF1dO1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSBpbiBtaXN2YWxzKSB7XG4gICAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBhY2Nlc3NvciA9IGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGRbcGF0aFswXV07XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBSZWN1cnNpdmVseSBmb2xsb3cgdGhlIGNydW1icyB0byB0aGUgZGVzaXJlZCBwcm9wZXJ0eVxuICAgIGFjY2Vzc29yID0gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciBpID0gMDtcbiAgICAgIHZhciB2YWx1ZSA9IGQ7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh2YWx1ZSAmJiB2YWx1ZVtwYXRoW2ldXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZVtwYXRoW2ldXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSBpbiBtaXN2YWxzKSB7XG4gICAgICAgIHZhbHVlID0gbWlzdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gYWNjZXNzb3I7XG59XG5cbi8qKlxuICogQmFzZSB2YWx1ZSBmb3IgZ2l2ZW4gZmFjZXQsIGllLiBjYXN0IHRvIGNvcnJlY3QgdHlwZSBvciBvYmplY3QuXG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICogQHJldHVybnMge3Zhc2VWYWx1ZUNCfSBCYXNlIHZhbHVlIGZ1bmN0aW9uIGZvciB0aGlzIGZhY2V0XG4gKi9cbmZ1bmN0aW9uIGJhc2VWYWx1ZUZuIChmYWNldCkge1xuICB2YXIgcmF3VmFsRm4gPSByYXdWYWx1ZUZuKGZhY2V0KTtcblxuICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgLypcbiAgICAgKiBDb250aW51b3VzIGZhY2V0czpcbiAgICAgKiBQYXJzZSBudW1lcmljIHZhbHVlIGZyb20gYmFzZSB2YWx1ZVxuICAgICAqL1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbCA9IHBhcnNlRmxvYXQocmF3VmFsRm4oZCkpO1xuICAgICAgaWYgKGlzTmFOKHZhbCkgfHwgdmFsID09PSBJbmZpbml0eSB8fCB2YWwgPT09IC1JbmZpbml0eSkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbDtcbiAgICB9O1xuICB9IGVsc2UgaWYgKGZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbHMgPSByYXdWYWxGbihkKTtcbiAgICAgIGlmICh2YWxzICE9PSBtaXN2YWwpIHtcbiAgICAgICAgaWYgKHZhbHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgIHZhbHMuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBpKSB7XG4gICAgICAgICAgICB2YWxzW2ldID0gdmFsLnRvU3RyaW5nKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFscyA9IHZhbHMudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFscztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgLypcbiAgICAgKiBUaW1lIHBhcnNpbmc6XG4gICAgICogMS4gbW9tZW50IHBhcnNlcyB0aGUgc3RyaW5nIHVzaW5nIHRoZSBnaXZlbiBmb3JtYXQsIGJ1dCBkZWZhdWx0cyB0b1xuICAgICAqICAgIHRoZSBbSVNPIDg2MDEgc3RhbmRhcmRdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT184NjAxKVxuICAgICAqIDIuIE5vdGUgdGhhdCBpZiB0aGUgc3RyaW5nIGNvbnRhaW5zIHRpbWV6b25lIGluZm9ybWF0aW9uLCB0aGF0IGlzIHBhcnNlZCB0b28uXG4gICAgICogMy4gVGhlIHRpbWUgaXMgdHJhbnNmb3JtZWQgdG8gcmVxdWVzdGVkIHRpbWV6b25lLCBkZWZhdWx0aW5nIHRoZSBsb2NhbGUgZGVmYXVsdFxuICAgICAqICAgIHdoZW4gbm8gem9uZSBpcyBzZXRcbiAgICAqL1xuICAgIHZhciB0aW1lRm9ybWF0ID0gZmFjZXQuZGF0ZXRpbWVUcmFuc2Zvcm0uZm9ybWF0O1xuICAgIGlmICh0aW1lRm9ybWF0ID09PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIHVzZSBkZWZhdWx0IElTTyBmb3JtYXR0aW5nXG4gICAgICB0aW1lRm9ybWF0ID0gbW9tZW50LklTT184NjAxO1xuICAgIH1cblxuICAgIHZhciB0aW1lWm9uZSA9IGZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnpvbmU7XG4gICAgaWYgKHRpbWVab25lID09PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIHVzZSBkZWZhdWx0IGxvY2FsZSB0aW1lem9uZSwgZ2V0IG92ZXJyaWRkZW4gaWYgYSBzdHJpbmcgY29udGFpbnMgYSB0aW1lem9uZVxuICAgICAgdGltZVpvbmUgPSBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGltZVpvbmUgPSB1dGlsLnRpbWVab25lcy5nZXQodGltZVpvbmUsICdkZXNjcmlwdGlvbicpLmZvcm1hdDtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWx1ZSA9IHJhd1ZhbEZuKGQpO1xuICAgICAgaWYgKHZhbHVlICE9PSBtaXN2YWwpIHtcbiAgICAgICAgdmFyIG0gPSBtb21lbnQudHoodmFsdWUsIHRpbWVGb3JtYXQsIHRpbWVab25lKTtcbiAgICAgICAgaWYgKG0uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIG07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0R1cmF0aW9uKSB7XG4gICAgLypcbiAgICAgKiBEdXJhdGlvbiBwYXJzaW5nOlxuICAgICAqIDEuIElmIG5vIGZvcm1hdCBpcyBnaXZlbiwgdGhlIHN0cmluZyBwYXJzZWQgdXNpbmdcbiAgICAgKiAgICB0aGUgW0lTTyA4NjAxIHN0YW5kYXJkXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSlcbiAgICAgKiAyLiBJZiBhIGZvcm1hdCBpcyBnaXZlbiwgdGhlIHN0cmluZyBpcyBwYXJzZWQgYXMgZmxvYXQgYW5kIGludGVycHJldGVkIGluIHRoZSBnaXZlbiB1bml0c1xuICAgICAqL1xuICAgIHZhciB1bml0cyA9IGZhY2V0LmR1cmF0aW9uVHJhbnNmb3JtLnVuaXRzO1xuICAgIGlmICh1bml0cyA9PT0gJ0lTTzg2MDEnKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gcmF3VmFsRm4oZCk7XG5cbiAgICAgICAgLy8gcGFyc2Ugc3RyaW5nIGlmIG5lY2Vzc2FyeVxuICAgICAgICBpZiAodmFsdWUgIT09IG1pc3ZhbCAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlWzBdLnRvTG93ZXJDYXNlKCkgPT09ICdwJykge1xuICAgICAgICAgIHZhbHVlID0gbW9tZW50LmR1cmF0aW9uKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGZvciB2YWxpZCBkdXJhdGlvblxuICAgICAgICBpZiAobW9tZW50LmlzRHVyYXRpb24odmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuaXRzID0gdXRpbC5kdXJhdGlvblVuaXRzLmdldCh1bml0cywgJ2Rlc2NyaXB0aW9uJykubW9tZW50Rm9ybWF0O1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJhd1ZhbEZuKGQpO1xuXG4gICAgICAgIC8vIHBhcnNlIHN0cmluZyBpZiBuZWNlc3NhcnlcbiAgICAgICAgaWYgKHZhbHVlICE9PSBtaXN2YWwgJiYgIWlzTmFOKHZhbHVlKSkge1xuICAgICAgICAgIC8vIE5PVEU6IGlzTmFOKCcwJykgaXMgZmFsc2UsIGlmIHRoYXQgZ2l2ZXMgcHJvYmxlbXMsIHdlIGNvdWxkIHVzZTpcbiAgICAgICAgICAvLyB2YWx1ZSA9PSArdmFsdWUpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICAgICAgICB2YWx1ZSA9IG1vbWVudC5kdXJhdGlvbihwYXJzZUZsb2F0KHZhbHVlKSwgdW5pdHMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIHZhbGlkIGR1cmF0aW9uXG4gICAgICAgIGlmIChtb21lbnQuaXNEdXJhdGlvbih2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvLyBpc0NhdGVnb3JpYWwsIGlzVGV4dFxuICAvLyBubyBjYXN0aW5nIG9yIGNvbnN0cnVjdGluZyBuZWNlc3NhcnksIHJldHVybiB0aGUgcmF3IHZhbHVlXG4gIHJldHVybiByYXdWYWxGbjtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB0cmFuc2Zvcm1lZCB2YWx1ZSBmcm9tIGEgYmFzZSB2YWx1ZVxuICpcbiAqIEBjYWxsYmFjayB2YWx1ZUNCXG4gKiBAcGFyYW0ge09iamVjdH0gZCBCYXNlIHZhbHVlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBUcmFuc2Zvcm1lZCB2YWx1ZVxuICovXG5cbi8qKlxuICogQ3JlYXRlIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB0cmFuc2Zvcm1lZCB2YWx1ZSBmb3IgdGhpcyBmYWNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqIEByZXR1cm5zIHt2YWx1ZUNCfSBWYWx1ZSBmdW5jdGlvbiBmb3IgdGhpcyBmYWNldFxuICovXG5mdW5jdGlvbiB2YWx1ZUZuIChmYWNldCkge1xuICAvLyBnZXQgYmFzZSB2YWx1ZSBmdW5jdGlvblxuICB2YXIgYmFzZVZhbEZuID0gYmFzZVZhbHVlRm4oZmFjZXQpO1xuXG4gIGlmIChmYWNldC5pc0NvbnN0YW50KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsgcmV0dXJuICcxJzsgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0NvbnRpbnVvdXMpIHtcbiAgICAvLyBkbyB3ZSBoYXZlIGEgY29udGludW91cyB0cmFuc2Zvcm0/XG4gICAgaWYgKGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm0gJiYgZmFjZXQuY29udGludW91c1RyYW5zZm9ybS50eXBlICE9PSAnbm9uZScpIHtcbiAgICAgIC8vIHllcywgdXNlIGl0XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgdmFyIHZhbCA9IGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm0udHJhbnNmb3JtKHBhcnNlRmxvYXQoYmFzZVZhbEZuKGQpKSk7XG4gICAgICAgIGlmIChpc05hTih2YWwpIHx8IHZhbCA9PT0gSW5maW5pdHkgfHwgdmFsID09PSAtSW5maW5pdHkpIHtcbiAgICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIGlmIChmYWNldC5pc0NhdGVnb3JpYWwpIHtcbiAgICAvLyBkbyB3ZSBoYXZlIGEgY2F0ZWdvcmlhbCB0cmFuc2Zvcm0/XG4gICAgaWYgKGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0gJiYgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyB5ZXMsIHVzZSBpdFxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWwgPSBiYXNlVmFsRm4oZCk7XG4gICAgICAgIHJldHVybiB2YWwgPT09IG1pc3ZhbCA/IG1pc3ZhbCA6IGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0udHJhbnNmb3JtKGJhc2VWYWxGbihkKSk7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgLy8gYWx3YXlzIHVzZSB0aGUgdHJhbnNmb3JtLCBzbyB3ZSBkbyBub3QgaGF2ZSB0byByZXBlYXQgdGhlIHllcy9ubyB0cmFuc2Zyb20gbG9naWMgaGVyZVxuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbCA9IGJhc2VWYWxGbihkKTtcbiAgICAgIHJldHVybiB2YWwgPT09IG1pc3ZhbCA/IG1pc3ZhbCA6IGZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnRyYW5zZm9ybSh2YWwpO1xuICAgIH07XG4gIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgIC8vIGFsd2F5cyB1c2UgdGhlIHRyYW5zZm9ybSwgc28gd2UgZG8gbm90IGhhdmUgdG8gcmVwZWF0IHRoZSB5ZXMvbm8gdHJhbnNmcm9tIGxvZ2ljIGhlcmVcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWwgPSBiYXNlVmFsRm4oZCk7XG4gICAgICByZXR1cm4gdmFsID09PSBtaXN2YWwgPyBtaXN2YWwgOiBmYWNldC5kdXJhdGlvblRyYW5zZm9ybS50cmFuc2Zvcm0odmFsKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gbm8gdHJhbnNmcm9tLCByZXR1cm4gYmFzZSB2YWx1ZVxuICByZXR1cm4gYmFzZVZhbEZuO1xufVxuXG5mdW5jdGlvbiBjb250aW51b3VzR3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiBkO1xuICAgIH1cblxuICAgIHZhciBuZ3JvdXBzID0gcGFydGl0aW9uLmdyb3Vwcy5sZW5ndGg7XG4gICAgaWYgKGQgPCBwYXJ0aXRpb24ubWludmFsIHx8IGQgPiBwYXJ0aXRpb24ubWF4dmFsKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cblxuICAgIC8vIGJpbnMgaW5jbHVkZSB0aGVpciBsb3dlciBib3VuZCwgYnV0IG5vdCB0aGVpciB1cHBlciBib3VuZFxuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoaSA8IG5ncm91cHMgJiYgZCA+PSBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpXS5tYXgpIHtcbiAgICAgIGkrKztcbiAgICB9XG4gICAgLy8gc3BlY2lhbCBjYXNlIGxhc3QgYmluIGluY2x1ZGVzIGFsc28gdXBwZXJib3VuZCBkID09PSBwYXJ0aXRpb24ubWF4dmFsXG4gICAgaWYgKGkgPT09IG5ncm91cHMpIHtcbiAgICAgIHJldHVybiBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpIC0gMV0udmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpXS52YWx1ZTtcbiAgfTtcbn1cblxuLypcbiAqIFJvdW5kIHRoZSBkYXRldGltZSB0byB0aGUgc3BlY2lmaWVkIHJlc29sdXRpb25cbiAqIHNlZTpcbiAqIGh0dHA6Ly9tb21lbnRqcy5jb20vZG9jcy8jL21hbmlwdWxhdGluZy9zdGFydC1vZi9cbiAqIGh0dHA6Ly9tb21lbnRqcy5jb20vZG9jcy8jL2Rpc3BsYXlpbmcvYXMtamF2YXNjcmlwdC1kYXRlL1xuICovXG5mdW5jdGlvbiBkYXRldGltZUdyb3VwRm4gKHBhcnRpdGlvbikge1xuICB2YXIgdGltZVN0ZXAgPSB1dGlsLmdldERhdGV0aW1lUmVzb2x1dGlvbihwYXJ0aXRpb24ubWludmFsLCBwYXJ0aXRpb24ubWF4dmFsKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgaWYgKGQgPT09IG1pc3ZhbCkge1xuICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICB9XG4gICAgaWYgKGQuaXNCZWZvcmUocGFydGl0aW9uLm1pbnZhbCkgfHwgZC5pc0FmdGVyKHBhcnRpdGlvbi5tYXh2YWwpKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgICB2YXIgZ3JvdXBlZCA9IG1vbWVudChkKS5zdGFydE9mKHRpbWVTdGVwKS5mb3JtYXQoKTtcbiAgICByZXR1cm4gZ3JvdXBlZDtcbiAgfTtcbn1cblxuLypcbiAqIFJvdW5kIHRoZSBkdXJhdGlvbiB0byB0aGUgc3BlY2lmaWVkIHJlc29sdXRpb25cbiAqL1xuZnVuY3Rpb24gZHVyYXRpb25Hcm91cEZuIChwYXJ0aXRpb24pIHtcbiAgdmFyIHRpbWVTdGVwID0gdXRpbC5nZXREdXJhdGlvblJlc29sdXRpb24ocGFydGl0aW9uLm1pbnZhbCwgcGFydGl0aW9uLm1heHZhbCk7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfVxuICAgIGlmIChkIDwgcGFydGl0aW9uLm1pbnZhbCB8fCBkID4gcGFydGl0aW9uLm1heHZhbCkge1xuICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICB9XG4gICAgdmFyIHJvdW5kZWQgPSBNYXRoLmZsb29yKHBhcnNlRmxvYXQoZC5hcyh0aW1lU3RlcCkpKTtcbiAgICByZXR1cm4gbW9tZW50LmR1cmF0aW9uKHJvdW5kZWQsIHRpbWVTdGVwKS50b0lTT1N0cmluZygpO1xuICB9O1xufVxuXG4vKlxuICogRG9uJ3QgZG8gYW55IGdyb3VwaW5nOyB0aGF0IGlzIGRvbmUgaW4gdGhlIHN0ZXAgZnJvbSBiYXNlIHZhbHVlIHRvIHZhbHVlLlxuICogTWF0Y2hpbmcgb2YgZmFjZXQgdmFsdWUgYW5kIGdyb3VwIGNvdWxkIGxlYWQgdG8gYSBkaWZmZXJlbnQgb3JkZXJpbmcsXG4gKiB3aGljaCBpcyBub3QgYWxsb3dlZCBieSBjcm9zc2ZpbHRlclxuICovXG5mdW5jdGlvbiBjYXRlZ29yaWFsR3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkgeyByZXR1cm4gZDsgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBncm91cGVkIHZhbHVlIGZvciBhIHRyYW5zZm9ybWVkIHZhbHVlXG4gKlxuICogQGNhbGxiYWNrIGdyb3VwQ0JcbiAqIEBwYXJhbSB7T2JqZWN0fSBkIFRyYW5zZm9ybWVkIHZhbHVlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBHcm91cFxuICovXG5cbi8qKlxuICogQ3JlYXRlIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBncm91cCB2YWx1ZSBmb3IgYSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEByZXR1cm5zIHtjYn0gR3JvdXAgZnVuY3Rpb24gZm9yIHRoaXMgcGFydGl0aW9uLCB0YWtpbmcgYSBgRGF0YWBcbiAqL1xuZnVuY3Rpb24gZ3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIGlmIChwYXJ0aXRpb24uaXNDb25zdGFudCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7IHJldHVybiAnMSc7IH07XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzQ29udGludW91cykge1xuICAgIHJldHVybiBjb250aW51b3VzR3JvdXBGbihwYXJ0aXRpb24pO1xuICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwpIHtcbiAgICByZXR1cm4gY2F0ZWdvcmlhbEdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNEYXRldGltZSkge1xuICAgIHJldHVybiBkYXRldGltZUdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNEdXJhdGlvbikge1xuICAgIHJldHVybiBkdXJhdGlvbkdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNUZXh0KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7IHJldHVybiBkLnRvU3RyaW5nKCk7IH07XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS5lcnJvcignR3JvdXAgZnVuY3Rpb24gbm90IGltcGxlbWVudGVkIGZvciBwYXJ0aXRpb24nLCBwYXJ0aXRpb24pO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICByYXdWYWx1ZUZuOiByYXdWYWx1ZUZuLFxuICBiYXNlVmFsdWVGbjogYmFzZVZhbHVlRm4sXG4gIHZhbHVlRm46IHZhbHVlRm4sXG4gIGdyb3VwRm46IGdyb3VwRm4sXG5cbiAgcmVkdWNlRm46IHJlZHVjZUZuXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///adfa\n")},b123:function(module,exports,__webpack_require__){eval("/**\n * DurationTransfrom defines a transformation on duration data\n *\n * @class DurationTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Units of the duration\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    units: ['string', true, 'ISO8601'],\n\n    /**\n     * For durations, transforms duration to these units\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    transformedUnits: ['string', true, 'ISO8601'],\n\n    /**\n     * Transform the date to this timezone.\n     *\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedZone: ['string', true, 'ISO8601'],\n\n    /**\n     * Controls conversion to datetime by adding this date\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    transformedReference: 'string'\n  },\n  derived: {\n    /**\n     * Reference momentjs for duration <-> datetime conversion\n     *\n     * @type {moment}\n     * @memberof! DurationTransform\n     */\n    referenceMoment: {\n      deps: ['transformedReference', 'transformedZone'],\n      fn: function () {\n        var tz;\n        if (this.transformedZone === 'ISO8601') {\n          tz = moment.tz.guess();\n        } else {\n          var timeZone = util.timeZones.get(this.transformedZone, 'description');\n          if (timeZone && timeZone.format) {\n            tz = timeZone.format;\n          } else {\n            tz = moment.tz.guess();\n          }\n        }\n\n        if (this.transformedReference) {\n          return moment.tz(this.transformedReference, tz);\n        }\n        return null;\n      }\n    },\n    /**\n     * The type of the facet after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DurationTransform\n     */\n    transformedType: {\n      deps: ['transformedFormat', 'transformedReference', 'transformedZone'],\n      fn: function () {\n        if (this.referenceMoment) {\n          return 'datetime';\n        } else if (this.transformedUnits !== 'ISO8601') {\n          return 'continuous';\n        } else {\n          return 'duration';\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minium value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMin: {\n      deps: ['transformedType'],\n      fn: function () {\n        var facet = this.parent;\n        if (this.transformedType === 'datetime') {\n          return this.transform(facet.minval);\n        } else if (this.transformedType === 'continuous') {\n          return this.transform(facet.minval);\n        } else {\n          return facet.minval;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMax: {\n      deps: ['transformedType'],\n      fn: function () {\n        var facet = this.parent;\n        if (this.transformedType === 'datetime') {\n          return this.transform(facet.maxval);\n        } else if (this.transformedType === 'continuous') {\n          return this.transform(facet.maxval);\n        } else {\n          return facet.maxval;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n\n  /**\n   * Apply the configured transformation to this Facet's value\n   *\n   * @function\n   * @memberof! DurationTransform\n   * @param {Object} inval momentjs duration\n   * @returns {Object} outval momentjs duration or datetime\n   */\n  transform: function transform (inval) {\n    var units;\n    if (this.referenceMoment) {\n      // duration -> datetime\n      return this.referenceMoment.clone().add(inval);\n    } else if (this.transformedUnits !== 'ISO8601') {\n      // duration -> continuous\n      units = util.durationUnits.get(this.transformedUnits, 'description').momentFormat;\n      return inval.as(units);\n    } else {\n      // no change\n      return inval;\n    }\n  },\n  reset: function () {\n    this.unset(['zone', 'transformedFormat', 'transformedZone', 'transformedReference']);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjEyMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvZHVyYXRpb24tdHJhbnNmb3JtLmpzPzJkZjUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEdXJhdGlvblRyYW5zZnJvbSBkZWZpbmVzIGEgdHJhbnNmb3JtYXRpb24gb24gZHVyYXRpb24gZGF0YVxuICpcbiAqIEBjbGFzcyBEdXJhdGlvblRyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC90aW1lJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBVbml0cyBvZiB0aGUgZHVyYXRpb25cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHVuaXRzOiBbJ3N0cmluZycsIHRydWUsICdJU084NjAxJ10sXG5cbiAgICAvKipcbiAgICAgKiBGb3IgZHVyYXRpb25zLCB0cmFuc2Zvcm1zIGR1cmF0aW9uIHRvIHRoZXNlIHVuaXRzXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFVuaXRzOiBbJ3N0cmluZycsIHRydWUsICdJU084NjAxJ10sXG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm0gdGhlIGRhdGUgdG8gdGhpcyB0aW1lem9uZS5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkWm9uZTogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogQ29udHJvbHMgY29udmVyc2lvbiB0byBkYXRldGltZSBieSBhZGRpbmcgdGhpcyBkYXRlXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFJlZmVyZW5jZTogJ3N0cmluZydcbiAgfSxcbiAgZGVyaXZlZDoge1xuICAgIC8qKlxuICAgICAqIFJlZmVyZW5jZSBtb21lbnRqcyBmb3IgZHVyYXRpb24gPC0+IGRhdGV0aW1lIGNvbnZlcnNpb25cbiAgICAgKlxuICAgICAqIEB0eXBlIHttb21lbnR9XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblRyYW5zZm9ybVxuICAgICAqL1xuICAgIHJlZmVyZW5jZU1vbWVudDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZFJlZmVyZW5jZScsICd0cmFuc2Zvcm1lZFpvbmUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0ejtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRab25lID09PSAnSVNPODYwMScpIHtcbiAgICAgICAgICB0eiA9IG1vbWVudC50ei5ndWVzcygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciB0aW1lWm9uZSA9IHV0aWwudGltZVpvbmVzLmdldCh0aGlzLnRyYW5zZm9ybWVkWm9uZSwgJ2Rlc2NyaXB0aW9uJyk7XG4gICAgICAgICAgaWYgKHRpbWVab25lICYmIHRpbWVab25lLmZvcm1hdCkge1xuICAgICAgICAgICAgdHogPSB0aW1lWm9uZS5mb3JtYXQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHR6ID0gbW9tZW50LnR6Lmd1ZXNzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXR1cm4gbW9tZW50LnR6KHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UsIHR6KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBmYWNldCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRUeXBlOiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkRm9ybWF0JywgJ3RyYW5zZm9ybWVkUmVmZXJlbmNlJywgJ3RyYW5zZm9ybWVkWm9uZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMucmVmZXJlbmNlTW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuICdkYXRldGltZSc7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy50cmFuc2Zvcm1lZFVuaXRzICE9PSAnSVNPODYwMScpIHtcbiAgICAgICAgICByZXR1cm4gJ2NvbnRpbnVvdXMnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiAnZHVyYXRpb24nO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWluaXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1pbjoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmYWNldCA9IHRoaXMucGFyZW50O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0oZmFjZXQubWludmFsKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2NvbnRpbnVvdXMnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKGZhY2V0Lm1pbnZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGZhY2V0Lm1pbnZhbDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWF4OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZhY2V0ID0gdGhpcy5wYXJlbnQ7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybShmYWNldC5tYXh2YWwpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnY29udGludW91cycpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0oZmFjZXQubWF4dmFsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZmFjZXQubWF4dmFsO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWluaW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNaW5Bc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRNaW4nLCAndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWludmFsID0gdGhpcy50cmFuc2Zvcm1lZE1pbjtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnZGF0ZXRpbWUnKSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC5mb3JtYXQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWludmFsLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1heEFzVGV4dDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZE1heCcsICd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXh2YWwgPSB0aGlzLnRyYW5zZm9ybWVkTWF4O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLmZvcm1hdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogQXBwbHkgdGhlIGNvbmZpZ3VyZWQgdHJhbnNmb3JtYXRpb24gdG8gdGhpcyBGYWNldCdzIHZhbHVlXG4gICAqXG4gICAqIEBmdW5jdGlvblxuICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBpbnZhbCBtb21lbnRqcyBkdXJhdGlvblxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBvdXR2YWwgbW9tZW50anMgZHVyYXRpb24gb3IgZGF0ZXRpbWVcbiAgICovXG4gIHRyYW5zZm9ybTogZnVuY3Rpb24gdHJhbnNmb3JtIChpbnZhbCkge1xuICAgIHZhciB1bml0cztcbiAgICBpZiAodGhpcy5yZWZlcmVuY2VNb21lbnQpIHtcbiAgICAgIC8vIGR1cmF0aW9uIC0+IGRhdGV0aW1lXG4gICAgICByZXR1cm4gdGhpcy5yZWZlcmVuY2VNb21lbnQuY2xvbmUoKS5hZGQoaW52YWwpO1xuICAgIH0gZWxzZSBpZiAodGhpcy50cmFuc2Zvcm1lZFVuaXRzICE9PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIGR1cmF0aW9uIC0+IGNvbnRpbnVvdXNcbiAgICAgIHVuaXRzID0gdXRpbC5kdXJhdGlvblVuaXRzLmdldCh0aGlzLnRyYW5zZm9ybWVkVW5pdHMsICdkZXNjcmlwdGlvbicpLm1vbWVudEZvcm1hdDtcbiAgICAgIHJldHVybiBpbnZhbC5hcyh1bml0cyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG5vIGNoYW5nZVxuICAgICAgcmV0dXJuIGludmFsO1xuICAgIH1cbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVuc2V0KFsnem9uZScsICd0cmFuc2Zvcm1lZEZvcm1hdCcsICd0cmFuc2Zvcm1lZFpvbmUnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///b123\n")},b452:function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar url = __webpack_require__(/*! ./url */ \"780f\");\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar Manager = __webpack_require__(/*! ./manager */ \"1e1f\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client');\n\n/**\n * Module exports.\n */\n\nmodule.exports = exports = lookup;\n\n/**\n * Managers cache.\n */\n\nvar cache = exports.managers = {};\n\n/**\n * Looks up an existing `Manager` for multiplexing.\n * If the user summons:\n *\n *   `io('http://localhost/a');`\n *   `io('http://localhost/b');`\n *\n * We reuse the existing instance based on same scheme/port/host,\n * and we initialize sockets for each namespace.\n *\n * @api public\n */\n\nfunction lookup (uri, opts) {\n  if (typeof uri === 'object') {\n    opts = uri;\n    uri = undefined;\n  }\n\n  opts = opts || {};\n\n  var parsed = url(uri);\n  var source = parsed.source;\n  var id = parsed.id;\n  var path = parsed.path;\n  var sameNamespace = cache[id] && path in cache[id].nsps;\n  var newConnection = opts.forceNew || opts['force new connection'] ||\n                      false === opts.multiplex || sameNamespace;\n\n  var io;\n\n  if (newConnection) {\n    debug('ignoring socket cache for %s', source);\n    io = Manager(source, opts);\n  } else {\n    if (!cache[id]) {\n      debug('new io instance for %s', source);\n      cache[id] = Manager(source, opts);\n    }\n    io = cache[id];\n  }\n  if (parsed.query && !opts.query) {\n    opts.query = parsed.query;\n  } else if (opts && 'object' === typeof opts.query) {\n    opts.query = encodeQueryString(opts.query);\n  }\n  return io.socket(parsed.path, opts);\n}\n/**\n *  Helper method to parse query objects to string.\n * @param {object} query\n * @returns {string}\n */\nfunction encodeQueryString (obj) {\n  var str = [];\n  for (var p in obj) {\n    if (obj.hasOwnProperty(p)) {\n      str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));\n    }\n  }\n  return str.join('&');\n}\n/**\n * Protocol version.\n *\n * @api public\n */\n\nexports.protocol = parser.protocol;\n\n/**\n * `connect`.\n *\n * @param {String} uri\n * @api public\n */\n\nexports.connect = lookup;\n\n/**\n * Expose constructors for standalone build.\n *\n * @api public\n */\n\nexports.Manager = __webpack_require__(/*! ./manager */ \"1e1f\");\nexports.Socket = __webpack_require__(/*! ./socket */ \"4c13\");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjQ1Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvaW5kZXguanM/ZjQyZiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgdXJsID0gcmVxdWlyZSgnLi91cmwnKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgTWFuYWdlciA9IHJlcXVpcmUoJy4vbWFuYWdlcicpO1xudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnc29ja2V0LmlvLWNsaWVudCcpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGxvb2t1cDtcblxuLyoqXG4gKiBNYW5hZ2VycyBjYWNoZS5cbiAqL1xuXG52YXIgY2FjaGUgPSBleHBvcnRzLm1hbmFnZXJzID0ge307XG5cbi8qKlxuICogTG9va3MgdXAgYW4gZXhpc3RpbmcgYE1hbmFnZXJgIGZvciBtdWx0aXBsZXhpbmcuXG4gKiBJZiB0aGUgdXNlciBzdW1tb25zOlxuICpcbiAqICAgYGlvKCdodHRwOi8vbG9jYWxob3N0L2EnKTtgXG4gKiAgIGBpbygnaHR0cDovL2xvY2FsaG9zdC9iJyk7YFxuICpcbiAqIFdlIHJldXNlIHRoZSBleGlzdGluZyBpbnN0YW5jZSBiYXNlZCBvbiBzYW1lIHNjaGVtZS9wb3J0L2hvc3QsXG4gKiBhbmQgd2UgaW5pdGlhbGl6ZSBzb2NrZXRzIGZvciBlYWNoIG5hbWVzcGFjZS5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGxvb2t1cCAodXJpLCBvcHRzKSB7XG4gIGlmICh0eXBlb2YgdXJpID09PSAnb2JqZWN0Jykge1xuICAgIG9wdHMgPSB1cmk7XG4gICAgdXJpID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgdmFyIHBhcnNlZCA9IHVybCh1cmkpO1xuICB2YXIgc291cmNlID0gcGFyc2VkLnNvdXJjZTtcbiAgdmFyIGlkID0gcGFyc2VkLmlkO1xuICB2YXIgcGF0aCA9IHBhcnNlZC5wYXRoO1xuICB2YXIgc2FtZU5hbWVzcGFjZSA9IGNhY2hlW2lkXSAmJiBwYXRoIGluIGNhY2hlW2lkXS5uc3BzO1xuICB2YXIgbmV3Q29ubmVjdGlvbiA9IG9wdHMuZm9yY2VOZXcgfHwgb3B0c1snZm9yY2UgbmV3IGNvbm5lY3Rpb24nXSB8fFxuICAgICAgICAgICAgICAgICAgICAgIGZhbHNlID09PSBvcHRzLm11bHRpcGxleCB8fCBzYW1lTmFtZXNwYWNlO1xuXG4gIHZhciBpbztcblxuICBpZiAobmV3Q29ubmVjdGlvbikge1xuICAgIGRlYnVnKCdpZ25vcmluZyBzb2NrZXQgY2FjaGUgZm9yICVzJywgc291cmNlKTtcbiAgICBpbyA9IE1hbmFnZXIoc291cmNlLCBvcHRzKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoIWNhY2hlW2lkXSkge1xuICAgICAgZGVidWcoJ25ldyBpbyBpbnN0YW5jZSBmb3IgJXMnLCBzb3VyY2UpO1xuICAgICAgY2FjaGVbaWRdID0gTWFuYWdlcihzb3VyY2UsIG9wdHMpO1xuICAgIH1cbiAgICBpbyA9IGNhY2hlW2lkXTtcbiAgfVxuICBpZiAocGFyc2VkLnF1ZXJ5ICYmICFvcHRzLnF1ZXJ5KSB7XG4gICAgb3B0cy5xdWVyeSA9IHBhcnNlZC5xdWVyeTtcbiAgfSBlbHNlIGlmIChvcHRzICYmICdvYmplY3QnID09PSB0eXBlb2Ygb3B0cy5xdWVyeSkge1xuICAgIG9wdHMucXVlcnkgPSBlbmNvZGVRdWVyeVN0cmluZyhvcHRzLnF1ZXJ5KTtcbiAgfVxuICByZXR1cm4gaW8uc29ja2V0KHBhcnNlZC5wYXRoLCBvcHRzKTtcbn1cbi8qKlxuICogIEhlbHBlciBtZXRob2QgdG8gcGFyc2UgcXVlcnkgb2JqZWN0cyB0byBzdHJpbmcuXG4gKiBAcGFyYW0ge29iamVjdH0gcXVlcnlcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGVuY29kZVF1ZXJ5U3RyaW5nIChvYmopIHtcbiAgdmFyIHN0ciA9IFtdO1xuICBmb3IgKHZhciBwIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkocCkpIHtcbiAgICAgIHN0ci5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChwKSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChvYmpbcF0pKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0ci5qb2luKCcmJyk7XG59XG4vKipcbiAqIFByb3RvY29sIHZlcnNpb24uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sO1xuXG4vKipcbiAqIGBjb25uZWN0YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJpXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuY29ubmVjdCA9IGxvb2t1cDtcblxuLyoqXG4gKiBFeHBvc2UgY29uc3RydWN0b3JzIGZvciBzdGFuZGFsb25lIGJ1aWxkLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5NYW5hZ2VyID0gcmVxdWlyZSgnLi9tYW5hZ2VyJyk7XG5leHBvcnRzLlNvY2tldCA9IHJlcXVpcmUoJy4vc29ja2V0Jyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///b452\n")},ba23:function(module,exports,__webpack_require__){eval("/**\n * Categorial Rule abstracts a single matching rule\n *\n * @class CategorialRule\n */\nvar Base = __webpack_require__(/*! ../util/base */ \"3902\");\n\n// Data structure for mapping categorial (and textual) data on groups\nmodule.exports = Base.extend({\n  props: {\n    /**\n     * string or string format of regexp to match data against.\n     * To use a regular expression, start and end the string with a slash, '/'.\n     * Options can be appedended, notably 'i' for case insensitive matching.\n     * The first captured group can be used in the group, see below.\n     * Examples\n     * 1. 'hello' matches 'hello', not 'hello world'\n     * 2. '/hello/' matches 'hello world', but not 'Hello world'\n     * 3. '/hello/i' matches 'I say Hello'\n     * @type {string}\n     * @memberof! CategorialRule\n     */\n    expression: ['string', true, 'Missing'],\n\n    /**\n     * Number of items this transform is used\n     * @type {number}\n     * @memberof! CategorialRule\n     */\n    count: ['number', true, 0],\n\n    /**\n     * Name of the group this is mapped to. The special substring $1 is replaced by the first captured group,\n     * in example 4 above, with group set to 'He says $1', the match results in 'He says goodbye'\n     * @type {string}\n     * @memberof! CategorialRule\n     */\n    group: ['string', true, 'Missing']\n  },\n  derived: {\n\n    /**\n     * Match function\n     * @memberof! CategorialRule\n     * @function\n     * @param {string} text The text to match\n     * @returns {string|false} group The group label if matching, else false\n     */\n    match: {\n      deps: ['expression', 'group'],\n      fn: function () {\n        var that = this;\n\n        var reFormat = new RegExp(/^\\/(.*)\\/([gimuy]*)$/);\n        var match = reFormat.exec(that.expression);\n\n        if (match) {\n          // if the expression is in the form of /<text>/<flags>, it is a regular expression, compile it\n          var exp = RegExp(match[1], match[2]);\n          return function (text) {\n            var m = exp.exec(text);\n            if (m) {\n              return that.group;\n              // return that.group.replace('$1', m[1]);\n            } else {\n              return false;\n            }\n          };\n        } else {\n          // otherwise do matching using '==='\n          return function (text) {\n            if (text === that.expression) {\n              return that.group;\n            } else {\n              return false;\n            }\n          };\n        }\n      }\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmEyMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY2F0ZWdvcmlhbC1ydWxlLmpzP2UxNzMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDYXRlZ29yaWFsIFJ1bGUgYWJzdHJhY3RzIGEgc2luZ2xlIG1hdGNoaW5nIHJ1bGVcbiAqXG4gKiBAY2xhc3MgQ2F0ZWdvcmlhbFJ1bGVcbiAqL1xudmFyIEJhc2UgPSByZXF1aXJlKCcuLi91dGlsL2Jhc2UnKTtcblxuLy8gRGF0YSBzdHJ1Y3R1cmUgZm9yIG1hcHBpbmcgY2F0ZWdvcmlhbCAoYW5kIHRleHR1YWwpIGRhdGEgb24gZ3JvdXBzXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2UuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBzdHJpbmcgb3Igc3RyaW5nIGZvcm1hdCBvZiByZWdleHAgdG8gbWF0Y2ggZGF0YSBhZ2FpbnN0LlxuICAgICAqIFRvIHVzZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbiwgc3RhcnQgYW5kIGVuZCB0aGUgc3RyaW5nIHdpdGggYSBzbGFzaCwgJy8nLlxuICAgICAqIE9wdGlvbnMgY2FuIGJlIGFwcGVkZW5kZWQsIG5vdGFibHkgJ2knIGZvciBjYXNlIGluc2Vuc2l0aXZlIG1hdGNoaW5nLlxuICAgICAqIFRoZSBmaXJzdCBjYXB0dXJlZCBncm91cCBjYW4gYmUgdXNlZCBpbiB0aGUgZ3JvdXAsIHNlZSBiZWxvdy5cbiAgICAgKiBFeGFtcGxlc1xuICAgICAqIDEuICdoZWxsbycgbWF0Y2hlcyAnaGVsbG8nLCBub3QgJ2hlbGxvIHdvcmxkJ1xuICAgICAqIDIuICcvaGVsbG8vJyBtYXRjaGVzICdoZWxsbyB3b3JsZCcsIGJ1dCBub3QgJ0hlbGxvIHdvcmxkJ1xuICAgICAqIDMuICcvaGVsbG8vaScgbWF0Y2hlcyAnSSBzYXkgSGVsbG8nXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIENhdGVnb3JpYWxSdWxlXG4gICAgICovXG4gICAgZXhwcmVzc2lvbjogWydzdHJpbmcnLCB0cnVlLCAnTWlzc2luZyddLFxuXG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIGl0ZW1zIHRoaXMgdHJhbnNmb3JtIGlzIHVzZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ2F0ZWdvcmlhbFJ1bGVcbiAgICAgKi9cbiAgICBjb3VudDogWydudW1iZXInLCB0cnVlLCAwXSxcblxuICAgIC8qKlxuICAgICAqIE5hbWUgb2YgdGhlIGdyb3VwIHRoaXMgaXMgbWFwcGVkIHRvLiBUaGUgc3BlY2lhbCBzdWJzdHJpbmcgJDEgaXMgcmVwbGFjZWQgYnkgdGhlIGZpcnN0IGNhcHR1cmVkIGdyb3VwLFxuICAgICAqIGluIGV4YW1wbGUgNCBhYm92ZSwgd2l0aCBncm91cCBzZXQgdG8gJ0hlIHNheXMgJDEnLCB0aGUgbWF0Y2ggcmVzdWx0cyBpbiAnSGUgc2F5cyBnb29kYnllJ1xuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQG1lbWJlcm9mISBDYXRlZ29yaWFsUnVsZVxuICAgICAqL1xuICAgIGdyb3VwOiBbJ3N0cmluZycsIHRydWUsICdNaXNzaW5nJ11cbiAgfSxcbiAgZGVyaXZlZDoge1xuXG4gICAgLyoqXG4gICAgICogTWF0Y2ggZnVuY3Rpb25cbiAgICAgKiBAbWVtYmVyb2YhIENhdGVnb3JpYWxSdWxlXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgVGhlIHRleHQgdG8gbWF0Y2hcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfGZhbHNlfSBncm91cCBUaGUgZ3JvdXAgbGFiZWwgaWYgbWF0Y2hpbmcsIGVsc2UgZmFsc2VcbiAgICAgKi9cbiAgICBtYXRjaDoge1xuICAgICAgZGVwczogWydleHByZXNzaW9uJywgJ2dyb3VwJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHJlRm9ybWF0ID0gbmV3IFJlZ0V4cCgvXlxcLyguKilcXC8oW2dpbXV5XSopJC8pO1xuICAgICAgICB2YXIgbWF0Y2ggPSByZUZvcm1hdC5leGVjKHRoYXQuZXhwcmVzc2lvbik7XG5cbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgLy8gaWYgdGhlIGV4cHJlc3Npb24gaXMgaW4gdGhlIGZvcm0gb2YgLzx0ZXh0Pi88ZmxhZ3M+LCBpdCBpcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiwgY29tcGlsZSBpdFxuICAgICAgICAgIHZhciBleHAgPSBSZWdFeHAobWF0Y2hbMV0sIG1hdGNoWzJdKTtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHRleHQpIHtcbiAgICAgICAgICAgIHZhciBtID0gZXhwLmV4ZWModGV4dCk7XG4gICAgICAgICAgICBpZiAobSkge1xuICAgICAgICAgICAgICByZXR1cm4gdGhhdC5ncm91cDtcbiAgICAgICAgICAgICAgLy8gcmV0dXJuIHRoYXQuZ3JvdXAucmVwbGFjZSgnJDEnLCBtWzFdKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG90aGVyd2lzZSBkbyBtYXRjaGluZyB1c2luZyAnPT09J1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICAgICAgaWYgKHRleHQgPT09IHRoYXQuZXhwcmVzc2lvbikge1xuICAgICAgICAgICAgICByZXR1cm4gdGhhdC5ncm91cDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///ba23\n")},bb16:function(module,exports,__webpack_require__){eval("\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = debug;\nexports.coerce = coerce;\nexports.disable = disable;\nexports.enable = enable;\nexports.enabled = enabled;\nexports.humanize = __webpack_require__(/*! ms */ \"1ed2\");\n\n/**\n * The currently active debug mode names, and names to skip.\n */\n\nexports.names = [];\nexports.skips = [];\n\n/**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lowercased letter, i.e. \"n\".\n */\n\nexports.formatters = {};\n\n/**\n * Previously assigned color.\n */\n\nvar prevColor = 0;\n\n/**\n * Previous log timestamp.\n */\n\nvar prevTime;\n\n/**\n * Select a color.\n *\n * @return {Number}\n * @api private\n */\n\nfunction selectColor() {\n  return exports.colors[prevColor++ % exports.colors.length];\n}\n\n/**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\nfunction debug(namespace) {\n\n  // define the `disabled` version\n  function disabled() {\n  }\n  disabled.enabled = false;\n\n  // define the `enabled` version\n  function enabled() {\n\n    var self = enabled;\n\n    // set `diff` timestamp\n    var curr = +new Date();\n    var ms = curr - (prevTime || curr);\n    self.diff = ms;\n    self.prev = prevTime;\n    self.curr = curr;\n    prevTime = curr;\n\n    // add the `color` if not set\n    if (null == self.useColors) self.useColors = exports.useColors();\n    if (null == self.color && self.useColors) self.color = selectColor();\n\n    var args = Array.prototype.slice.call(arguments);\n\n    args[0] = exports.coerce(args[0]);\n\n    if ('string' !== typeof args[0]) {\n      // anything else let's inspect with %o\n      args = ['%o'].concat(args);\n    }\n\n    // apply any `formatters` transformations\n    var index = 0;\n    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {\n      // if we encounter an escaped % then don't increase the array index\n      if (match === '%%') return match;\n      index++;\n      var formatter = exports.formatters[format];\n      if ('function' === typeof formatter) {\n        var val = args[index];\n        match = formatter.call(self, val);\n\n        // now we need to remove `args[index]` since it's inlined in the `format`\n        args.splice(index, 1);\n        index--;\n      }\n      return match;\n    });\n\n    if ('function' === typeof exports.formatArgs) {\n      args = exports.formatArgs.apply(self, args);\n    }\n    var logFn = enabled.log || exports.log || console.log.bind(console);\n    logFn.apply(self, args);\n  }\n  enabled.enabled = true;\n\n  var fn = exports.enabled(namespace) ? enabled : disabled;\n\n  fn.namespace = namespace;\n\n  return fn;\n}\n\n/**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\nfunction enable(namespaces) {\n  exports.save(namespaces);\n\n  var split = (namespaces || '').split(/[\\s,]+/);\n  var len = split.length;\n\n  for (var i = 0; i < len; i++) {\n    if (!split[i]) continue; // ignore empty strings\n    namespaces = split[i].replace(/\\*/g, '.*?');\n    if (namespaces[0] === '-') {\n      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n    } else {\n      exports.names.push(new RegExp('^' + namespaces + '$'));\n    }\n  }\n}\n\n/**\n * Disable debug output.\n *\n * @api public\n */\n\nfunction disable() {\n  exports.enable('');\n}\n\n/**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\nfunction enabled(name) {\n  var i, len;\n  for (i = 0, len = exports.skips.length; i < len; i++) {\n    if (exports.skips[i].test(name)) {\n      return false;\n    }\n  }\n  for (i = 0, len = exports.names.length; i < len; i++) {\n    if (exports.names[i].test(name)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\nfunction coerce(val) {\n  if (val instanceof Error) return val.stack || val.message;\n  return val;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmIxNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvZGVidWcvZGVidWcuanM/NTJhNyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogVGhpcyBpcyB0aGUgY29tbW9uIGxvZ2ljIGZvciBib3RoIHRoZSBOb2RlLmpzIGFuZCB3ZWIgYnJvd3NlclxuICogaW1wbGVtZW50YXRpb25zIG9mIGBkZWJ1ZygpYC5cbiAqXG4gKiBFeHBvc2UgYGRlYnVnKClgIGFzIHRoZSBtb2R1bGUuXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZGVidWc7XG5leHBvcnRzLmNvZXJjZSA9IGNvZXJjZTtcbmV4cG9ydHMuZGlzYWJsZSA9IGRpc2FibGU7XG5leHBvcnRzLmVuYWJsZSA9IGVuYWJsZTtcbmV4cG9ydHMuZW5hYmxlZCA9IGVuYWJsZWQ7XG5leHBvcnRzLmh1bWFuaXplID0gcmVxdWlyZSgnbXMnKTtcblxuLyoqXG4gKiBUaGUgY3VycmVudGx5IGFjdGl2ZSBkZWJ1ZyBtb2RlIG5hbWVzLCBhbmQgbmFtZXMgdG8gc2tpcC5cbiAqL1xuXG5leHBvcnRzLm5hbWVzID0gW107XG5leHBvcnRzLnNraXBzID0gW107XG5cbi8qKlxuICogTWFwIG9mIHNwZWNpYWwgXCIlblwiIGhhbmRsaW5nIGZ1bmN0aW9ucywgZm9yIHRoZSBkZWJ1ZyBcImZvcm1hdFwiIGFyZ3VtZW50LlxuICpcbiAqIFZhbGlkIGtleSBuYW1lcyBhcmUgYSBzaW5nbGUsIGxvd2VyY2FzZWQgbGV0dGVyLCBpLmUuIFwiblwiLlxuICovXG5cbmV4cG9ydHMuZm9ybWF0dGVycyA9IHt9O1xuXG4vKipcbiAqIFByZXZpb3VzbHkgYXNzaWduZWQgY29sb3IuXG4gKi9cblxudmFyIHByZXZDb2xvciA9IDA7XG5cbi8qKlxuICogUHJldmlvdXMgbG9nIHRpbWVzdGFtcC5cbiAqL1xuXG52YXIgcHJldlRpbWU7XG5cbi8qKlxuICogU2VsZWN0IGEgY29sb3IuXG4gKlxuICogQHJldHVybiB7TnVtYmVyfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2VsZWN0Q29sb3IoKSB7XG4gIHJldHVybiBleHBvcnRzLmNvbG9yc1twcmV2Q29sb3IrKyAlIGV4cG9ydHMuY29sb3JzLmxlbmd0aF07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgZGVidWdnZXIgd2l0aCB0aGUgZ2l2ZW4gYG5hbWVzcGFjZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlYnVnKG5hbWVzcGFjZSkge1xuXG4gIC8vIGRlZmluZSB0aGUgYGRpc2FibGVkYCB2ZXJzaW9uXG4gIGZ1bmN0aW9uIGRpc2FibGVkKCkge1xuICB9XG4gIGRpc2FibGVkLmVuYWJsZWQgPSBmYWxzZTtcblxuICAvLyBkZWZpbmUgdGhlIGBlbmFibGVkYCB2ZXJzaW9uXG4gIGZ1bmN0aW9uIGVuYWJsZWQoKSB7XG5cbiAgICB2YXIgc2VsZiA9IGVuYWJsZWQ7XG5cbiAgICAvLyBzZXQgYGRpZmZgIHRpbWVzdGFtcFxuICAgIHZhciBjdXJyID0gK25ldyBEYXRlKCk7XG4gICAgdmFyIG1zID0gY3VyciAtIChwcmV2VGltZSB8fCBjdXJyKTtcbiAgICBzZWxmLmRpZmYgPSBtcztcbiAgICBzZWxmLnByZXYgPSBwcmV2VGltZTtcbiAgICBzZWxmLmN1cnIgPSBjdXJyO1xuICAgIHByZXZUaW1lID0gY3VycjtcblxuICAgIC8vIGFkZCB0aGUgYGNvbG9yYCBpZiBub3Qgc2V0XG4gICAgaWYgKG51bGwgPT0gc2VsZi51c2VDb2xvcnMpIHNlbGYudXNlQ29sb3JzID0gZXhwb3J0cy51c2VDb2xvcnMoKTtcbiAgICBpZiAobnVsbCA9PSBzZWxmLmNvbG9yICYmIHNlbGYudXNlQ29sb3JzKSBzZWxmLmNvbG9yID0gc2VsZWN0Q29sb3IoKTtcblxuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgIGFyZ3NbMF0gPSBleHBvcnRzLmNvZXJjZShhcmdzWzBdKTtcblxuICAgIGlmICgnc3RyaW5nJyAhPT0gdHlwZW9mIGFyZ3NbMF0pIHtcbiAgICAgIC8vIGFueXRoaW5nIGVsc2UgbGV0J3MgaW5zcGVjdCB3aXRoICVvXG4gICAgICBhcmdzID0gWyclbyddLmNvbmNhdChhcmdzKTtcbiAgICB9XG5cbiAgICAvLyBhcHBseSBhbnkgYGZvcm1hdHRlcnNgIHRyYW5zZm9ybWF0aW9uc1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgYXJnc1swXSA9IGFyZ3NbMF0ucmVwbGFjZSgvJShbYS16JV0pL2csIGZ1bmN0aW9uKG1hdGNoLCBmb3JtYXQpIHtcbiAgICAgIC8vIGlmIHdlIGVuY291bnRlciBhbiBlc2NhcGVkICUgdGhlbiBkb24ndCBpbmNyZWFzZSB0aGUgYXJyYXkgaW5kZXhcbiAgICAgIGlmIChtYXRjaCA9PT0gJyUlJykgcmV0dXJuIG1hdGNoO1xuICAgICAgaW5kZXgrKztcbiAgICAgIHZhciBmb3JtYXR0ZXIgPSBleHBvcnRzLmZvcm1hdHRlcnNbZm9ybWF0XTtcbiAgICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgZm9ybWF0dGVyKSB7XG4gICAgICAgIHZhciB2YWwgPSBhcmdzW2luZGV4XTtcbiAgICAgICAgbWF0Y2ggPSBmb3JtYXR0ZXIuY2FsbChzZWxmLCB2YWwpO1xuXG4gICAgICAgIC8vIG5vdyB3ZSBuZWVkIHRvIHJlbW92ZSBgYXJnc1tpbmRleF1gIHNpbmNlIGl0J3MgaW5saW5lZCBpbiB0aGUgYGZvcm1hdGBcbiAgICAgICAgYXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBpbmRleC0tO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH0pO1xuXG4gICAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBleHBvcnRzLmZvcm1hdEFyZ3MpIHtcbiAgICAgIGFyZ3MgPSBleHBvcnRzLmZvcm1hdEFyZ3MuYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgfVxuICAgIHZhciBsb2dGbiA9IGVuYWJsZWQubG9nIHx8IGV4cG9ydHMubG9nIHx8IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSk7XG4gICAgbG9nRm4uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbiAgZW5hYmxlZC5lbmFibGVkID0gdHJ1ZTtcblxuICB2YXIgZm4gPSBleHBvcnRzLmVuYWJsZWQobmFtZXNwYWNlKSA/IGVuYWJsZWQgOiBkaXNhYmxlZDtcblxuICBmbi5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7XG5cbiAgcmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgYSBkZWJ1ZyBtb2RlIGJ5IG5hbWVzcGFjZXMuIFRoaXMgY2FuIGluY2x1ZGUgbW9kZXNcbiAqIHNlcGFyYXRlZCBieSBhIGNvbG9uIGFuZCB3aWxkY2FyZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZW5hYmxlKG5hbWVzcGFjZXMpIHtcbiAgZXhwb3J0cy5zYXZlKG5hbWVzcGFjZXMpO1xuXG4gIHZhciBzcGxpdCA9IChuYW1lc3BhY2VzIHx8ICcnKS5zcGxpdCgvW1xccyxdKy8pO1xuICB2YXIgbGVuID0gc3BsaXQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoIXNwbGl0W2ldKSBjb250aW51ZTsgLy8gaWdub3JlIGVtcHR5IHN0cmluZ3NcbiAgICBuYW1lc3BhY2VzID0gc3BsaXRbaV0ucmVwbGFjZSgvXFwqL2csICcuKj8nKTtcbiAgICBpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG4gICAgICBleHBvcnRzLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzLnN1YnN0cigxKSArICckJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzICsgJyQnKSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGlzYWJsZSBkZWJ1ZyBvdXRwdXQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkaXNhYmxlKCkge1xuICBleHBvcnRzLmVuYWJsZSgnJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RlIG5hbWUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGVkKG5hbWUpIHtcbiAgdmFyIGksIGxlbjtcbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLnNraXBzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5uYW1lcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLm5hbWVzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29lcmNlIGB2YWxgLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjb2VyY2UodmFsKSB7XG4gIGlmICh2YWwgaW5zdGFuY2VvZiBFcnJvcikgcmV0dXJuIHZhbC5zdGFjayB8fCB2YWwubWVzc2FnZTtcbiAgcmV0dXJuIHZhbDtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///bb16\n")},bff6:function(module,exports){eval("/**\n * This module defines a single unique missing value indicator.\n * All invalid, absent, or user-indicated missing value is internally set to this value.\n *\n * @example\n * var misval = require('./framework/misval');\n * if ( a === misval ) {\n *   ...\n * }\n * @module client/misval\n */\n\n// module.exports = -Number.MAX_VALUE;\nmodule.exports = 'missing';\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmZmNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9taXN2YWwuanM/YjI3OSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoaXMgbW9kdWxlIGRlZmluZXMgYSBzaW5nbGUgdW5pcXVlIG1pc3NpbmcgdmFsdWUgaW5kaWNhdG9yLlxuICogQWxsIGludmFsaWQsIGFic2VudCwgb3IgdXNlci1pbmRpY2F0ZWQgbWlzc2luZyB2YWx1ZSBpcyBpbnRlcm5hbGx5IHNldCB0byB0aGlzIHZhbHVlLlxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbWlzdmFsID0gcmVxdWlyZSgnLi9mcmFtZXdvcmsvbWlzdmFsJyk7XG4gKiBpZiAoIGEgPT09IG1pc3ZhbCApIHtcbiAqICAgLi4uXG4gKiB9XG4gKiBAbW9kdWxlIGNsaWVudC9taXN2YWxcbiAqL1xuXG4vLyBtb2R1bGUuZXhwb3J0cyA9IC1OdW1iZXIuTUFYX1ZBTFVFO1xubW9kdWxlLmV4cG9ydHMgPSAnbWlzc2luZyc7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///bff6\n")},c59b:function(module,exports,__webpack_require__){eval('\nmodule.exports = __webpack_require__(/*! ./lib/index */ "58ab");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYzU5Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9pbmRleC5qcz80NmEyIl0sInNvdXJjZXNDb250ZW50IjpbIlxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9pbmRleCcpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///c59b\n')},d45b:function(module,exports,__webpack_require__){eval("var AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar AmpersandColllection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\n/*\n * Time is grouped by truncating; the resolution is determined in util-time.getResolution()\n * See [this table](http://momentjs.com/docs/#/durations/creating/) for accpetable values\n * when using a crossfilter dataset.\n */\nfunction unitsForMilliseconds (milliseconds) {\n  var count = milliseconds;\n  if (count < 10000) { // 10 seconds\n    return 'milliseconds';\n  }\n  count = count / 1000;\n\n  if (count < 15 * 60) { // 15 minutes\n    return 'seconds';\n  }\n  count = count / 60;\n\n  if (count < 3 * 60) { // 3 hours\n    return 'minutes';\n  }\n  count = count / 60;\n\n  if (count < 3 * 24) { // 3 days\n    return 'hours';\n  }\n  count = count / 24;\n\n  if (count < 3 * 7) { // 3 weeks\n    return 'days';\n  }\n  if (count < 7 * 52) { // 52 weeks\n    return 'weeks';\n  }\n  if (count < 2 * 365) { // 2 years\n    return 'months';\n  }\n  return 'years';\n}\n\nfunction getFormat (units) {\n  var fmt;\n  if (units === 'seconds') {\n    fmt = 'mm:ss';\n  } else if (units === 'minutes') {\n    fmt = 'HH:mm';\n  } else if (units === 'hours') {\n    fmt = 'HH:00';\n  } else if (units === 'days') {\n    fmt = 'dddd do';\n  } else if (units === 'weeks') {\n    fmt = 'wo';\n  } else if (units === 'months') {\n    fmt = 'YY MMM';\n  } else if (units === 'years') {\n    fmt = 'YYYY';\n  }\n  return fmt;\n}\n\nfunction getDatetimeResolution (start, end) {\n  var difference = end.diff(start);\n  return unitsForMilliseconds(difference);\n}\n\nfunction getDurationResolution (min, max) {\n  var length = moment.duration(max.as('milliseconds') - min.as('milliseconds'), 'milliseconds');\n  return unitsForMilliseconds(length);\n}\n\nvar TimePart = AmpersandModel.extend({\n  props: {\n    /**\n     * The format string for momentjs\n     * @memberof! TimePart\n     * @type {string}\n     */\n    momentFormat: ['string', true],\n    /**\n     * The format string for postgresql\n     * @memberof! TimePart\n     * @type {string}\n     */\n    postgresFormat: ['string', true],\n    /**\n     * The human readable descprition of the datetime part\n     * @memberof! TimePart\n     * @type {string}\n     */\n    description: ['string', true],\n    /**\n     * Data type after conversion: 'continuous', or 'categorial'\n     * @memberof! TimePart\n     * @type {string}\n     */\n    type: ['string', true],\n    /**\n     * For continuous datetime parts (ie, day-of-year), the minimum value\n     * @memberof! TimePart\n     * @type {number}\n     */\n    min: ['number', true, 0],\n    /**\n     * For continuous datetime parts (ie, day-of-year), the maximum value\n     * @memberof! TimePart\n     * @type {number}\n     */\n    max: ['number', true, 1],\n    /**\n     * When true, calculate the minimum and maximum value from the\n     * original datetime limits. Used for continuous datetime parts (ie, year)\n     * @memberof! TimePart\n     * @type {boolean}\n     */\n    calculate: ['boolean', true, false],\n    /**\n     * For categorial datetime parts (Mon, Tue, ..), the array of possible values\n     * @memberof! TimePart\n     * @type {String[]}\n     */\n    groups: ['array']\n  }\n});\n\nvar TimeParts = AmpersandColllection.extend({\n  model: TimePart,\n  indexes: ['description']\n});\n\nvar timeParts = new TimeParts([\n  { description: 'ISO8601', type: 'datetime', calculate: true },\n  { postgresFormat: 'month', momentFormat: 'M', description: 'Month (1-12)', type: 'continuous', min: 1, max: 12 },\n  { postgresFormat: 'quarter', momentFormat: 'Q', description: 'Quarter (1-4)', type: 'continuous', min: 1, max: 4 },\n  { postgresFormat: 'day', momentFormat: 'D', description: 'Day of Month  (1-31)', type: 'continuous', min: 1, max: 31 },\n  { postgresFormat: 'doy', momentFormat: 'DDD', description: 'Day of Year (1-365)', type: 'continuous', min: 1, max: 365 },\n  { postgresFormat: 'dow', momentFormat: 'd', description: 'Day of Week (0-6)', type: 'continuous', min: 0, max: 6 },\n  { postgresFormat: 'isodow', momentFormat: 'E', description: 'Day of Week ISO (1-7)', type: 'continuous', min: 1, max: 7 },\n  { postgresFormat: 'week', momentFormat: 'W', description: 'Week of Year ISO  (1-53)', type: 'continuous', min: 1, max: 53 },\n  { postgresFormat: 'year', momentFormat: 'Y', description: 'Year', type: 'continuous', calculate: true },\n  { postgresFormat: 'hours', momentFormat: 'H', description: 'Hour (0-23)', type: 'continuous', min: 0, max: 23 },\n  { postgresFormat: 'minute', momentFormat: 'm', description: 'Minute (0-59)', type: 'continuous', min: 0, max: 59 },\n  { postgresFormat: 'second', momentFormat: 's', description: 'Second (0-59)', type: 'continuous', min: 0, max: 59 },\n  { postgresFormat: 'milliseconds', momentFormat: 'SSS', description: 'Milliseconds (0-999)', type: 'continuous', min: 0, max: 999 },\n  { postgresFormat: 'microseconds', momentFormat: 'SSSSSS', description: 'microseconds (0-999999)', type: 'continuous', min: 0, max: 999999 },\n  { postgresFormat: 'epoch', momentFormat: 'X', description: 'Unix Timestamp', type: 'continuous', calculate: true },\n  { postgresFormat: 'Mon', momentFormat: 'MMM', description: 'Month (Jan - Dec)', type: 'categorial', groups: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] },\n  { postgresFormat: 'Month', momentFormat: 'MMMM', description: 'Month (January - December)', type: 'categorial', groups: ['January', 'Feburary', 'March', 'April', 'May', 'June', 'July', 'August', 'Septebmer', 'October', 'November', 'December'] },\n  { postgresFormat: 'Dy', momentFormat: 'ddd', description: 'Day of Week (Sun-Sat)', type: 'categorial', groups: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] },\n  { postgresFormat: 'Day', momentFormat: 'dddd', description: 'Day of Week (Sunday-Saturday)', type: 'categorial', groups: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] },\n  { postgresFormat: 'AM', momentFormat: 'A', description: 'AM/PM', type: 'categorial', groups: ['AM', 'PM'] }\n]);\n\nvar DurationUnit = AmpersandModel.extend({\n  props: {\n    /**\n     * The descriptive name of the time unit\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    description: ['string'],\n    /**\n     * Momentjs parsing format\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    momentFormat: ['string'],\n    /**\n     * Postgres parsing format\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    postgresFormat: ['string'],\n    /**\n     * Conversion factor to seconds\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    seconds: ['number']\n  }\n});\n\nvar DurationUnits = AmpersandColllection.extend({\n  indexes: ['description'],\n  model: DurationUnit\n});\n\nvar durationUnits = new DurationUnits([\n  {\n    description: 'ISO8601',\n    seconds: 1\n  }, {\n    description: 'millenium',\n    momentFormat: 'millenium',\n    postgresFormat: 'millenium',\n    seconds: 100 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'century',\n    momentFormat: 'century',\n    postgresFormat: 'century',\n    seconds: 100 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'decades',\n    momentFormat: 'decades',\n    postgresFormat: 'decade',\n    seconds: 10 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'years',\n    momentFormat: 'years',\n    postgresFormat: 'year',\n    seconds: 365.25 * 24 * 60 * 60\n  }, {\n    description: 'quarters',\n    momentFormat: '',\n    postgresFormat: 'quarter',\n    seconds: 365.25 * 8 * 60 * 60\n  }, {\n    description: 'months',\n    momentFormat: 'months',\n    postgresFormat: 'month',\n    seconds: 30 * 24 * 60 * 60\n  }, {\n    description: 'weeks',\n    momentFormat: 'weeks',\n    postgresFormat: 'week',\n    seconds: 7 * 24 * 60 * 60\n  }, {\n    description: 'days',\n    momentFormat: 'days',\n    postgresFormat: 'day',\n    seconds: 24 * 60 * 60\n  }, {\n    description: 'hours',\n    momentFormat: 'hours',\n    postgresFormat: 'hour',\n    seconds: 60 * 60\n  }, {\n    description: 'minutes',\n    momentFormat: 'minutes',\n    postgresFormat: 'minute',\n    seconds: 60\n  }, {\n    description: 'seconds',\n    momentFormat: 'seconds',\n    postgresFormat: 'second',\n    seconds: 1\n  }, {\n    description: 'milliseconds',\n    momentFormat: 'milliseconds',\n    postgresFormat: 'milliseconds',\n    seconds: 0.001\n  }, {\n    description: 'microseconds',\n    momentFormat: 'microseconds',\n    postgresFormat: 'microseconds',\n    seconds: 0.000001\n  }\n]);\n\nvar TimeZone = AmpersandModel.extend({\n  props: {\n    /**\n     * The descriptive name of the time zone\n     * @memberof! TimeZone\n     * @type {string}\n     */\n    description: ['string'],\n    /**\n     * The time zone format\n     * @memberof! TimeZone\n     * @type {string}\n     */\n    format: ['string']\n  }\n});\n\nvar TimeZones = AmpersandColllection.extend({\n  indexes: ['description'],\n  model: TimeZone\n});\n\nvar timeZones = new TimeZones();\ntimeZones.add({\n  description: 'ISO8601',\n  format: 'ISO8601'\n});\n\nmoment.tz.names().forEach(function (tz) {\n  timeZones.add({\n    description: tz,\n    format: tz\n  });\n});\n\nmodule.exports = {\n  timeParts: timeParts,\n  timeZones: timeZones,\n  durationUnits: durationUnits,\n  getDatetimeResolution: getDatetimeResolution,\n  getDurationResolution: getDurationResolution,\n  getFormat: getFormat\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZDQ1Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC90aW1lLmpzP2ExMzkiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIEFtcGVyc2FuZE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG52YXIgQW1wZXJzYW5kQ29sbGxlY3Rpb24gPSByZXF1aXJlKCdhbXBlcnNhbmQtY29sbGVjdGlvbicpO1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xuXG4vKlxuICogVGltZSBpcyBncm91cGVkIGJ5IHRydW5jYXRpbmc7IHRoZSByZXNvbHV0aW9uIGlzIGRldGVybWluZWQgaW4gdXRpbC10aW1lLmdldFJlc29sdXRpb24oKVxuICogU2VlIFt0aGlzIHRhYmxlXShodHRwOi8vbW9tZW50anMuY29tL2RvY3MvIy9kdXJhdGlvbnMvY3JlYXRpbmcvKSBmb3IgYWNjcGV0YWJsZSB2YWx1ZXNcbiAqIHdoZW4gdXNpbmcgYSBjcm9zc2ZpbHRlciBkYXRhc2V0LlxuICovXG5mdW5jdGlvbiB1bml0c0Zvck1pbGxpc2Vjb25kcyAobWlsbGlzZWNvbmRzKSB7XG4gIHZhciBjb3VudCA9IG1pbGxpc2Vjb25kcztcbiAgaWYgKGNvdW50IDwgMTAwMDApIHsgLy8gMTAgc2Vjb25kc1xuICAgIHJldHVybiAnbWlsbGlzZWNvbmRzJztcbiAgfVxuICBjb3VudCA9IGNvdW50IC8gMTAwMDtcblxuICBpZiAoY291bnQgPCAxNSAqIDYwKSB7IC8vIDE1IG1pbnV0ZXNcbiAgICByZXR1cm4gJ3NlY29uZHMnO1xuICB9XG4gIGNvdW50ID0gY291bnQgLyA2MDtcblxuICBpZiAoY291bnQgPCAzICogNjApIHsgLy8gMyBob3Vyc1xuICAgIHJldHVybiAnbWludXRlcyc7XG4gIH1cbiAgY291bnQgPSBjb3VudCAvIDYwO1xuXG4gIGlmIChjb3VudCA8IDMgKiAyNCkgeyAvLyAzIGRheXNcbiAgICByZXR1cm4gJ2hvdXJzJztcbiAgfVxuICBjb3VudCA9IGNvdW50IC8gMjQ7XG5cbiAgaWYgKGNvdW50IDwgMyAqIDcpIHsgLy8gMyB3ZWVrc1xuICAgIHJldHVybiAnZGF5cyc7XG4gIH1cbiAgaWYgKGNvdW50IDwgNyAqIDUyKSB7IC8vIDUyIHdlZWtzXG4gICAgcmV0dXJuICd3ZWVrcyc7XG4gIH1cbiAgaWYgKGNvdW50IDwgMiAqIDM2NSkgeyAvLyAyIHllYXJzXG4gICAgcmV0dXJuICdtb250aHMnO1xuICB9XG4gIHJldHVybiAneWVhcnMnO1xufVxuXG5mdW5jdGlvbiBnZXRGb3JtYXQgKHVuaXRzKSB7XG4gIHZhciBmbXQ7XG4gIGlmICh1bml0cyA9PT0gJ3NlY29uZHMnKSB7XG4gICAgZm10ID0gJ21tOnNzJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ21pbnV0ZXMnKSB7XG4gICAgZm10ID0gJ0hIOm1tJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ2hvdXJzJykge1xuICAgIGZtdCA9ICdISDowMCc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICdkYXlzJykge1xuICAgIGZtdCA9ICdkZGRkIGRvJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ3dlZWtzJykge1xuICAgIGZtdCA9ICd3byc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICdtb250aHMnKSB7XG4gICAgZm10ID0gJ1lZIE1NTSc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICd5ZWFycycpIHtcbiAgICBmbXQgPSAnWVlZWSc7XG4gIH1cbiAgcmV0dXJuIGZtdDtcbn1cblxuZnVuY3Rpb24gZ2V0RGF0ZXRpbWVSZXNvbHV0aW9uIChzdGFydCwgZW5kKSB7XG4gIHZhciBkaWZmZXJlbmNlID0gZW5kLmRpZmYoc3RhcnQpO1xuICByZXR1cm4gdW5pdHNGb3JNaWxsaXNlY29uZHMoZGlmZmVyZW5jZSk7XG59XG5cbmZ1bmN0aW9uIGdldER1cmF0aW9uUmVzb2x1dGlvbiAobWluLCBtYXgpIHtcbiAgdmFyIGxlbmd0aCA9IG1vbWVudC5kdXJhdGlvbihtYXguYXMoJ21pbGxpc2Vjb25kcycpIC0gbWluLmFzKCdtaWxsaXNlY29uZHMnKSwgJ21pbGxpc2Vjb25kcycpO1xuICByZXR1cm4gdW5pdHNGb3JNaWxsaXNlY29uZHMobGVuZ3RoKTtcbn1cblxudmFyIFRpbWVQYXJ0ID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBUaGUgZm9ybWF0IHN0cmluZyBmb3IgbW9tZW50anNcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBtb21lbnRGb3JtYXQ6IFsnc3RyaW5nJywgdHJ1ZV0sXG4gICAgLyoqXG4gICAgICogVGhlIGZvcm1hdCBzdHJpbmcgZm9yIHBvc3RncmVzcWxcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBwb3N0Z3Jlc0Zvcm1hdDogWydzdHJpbmcnLCB0cnVlXSxcbiAgICAvKipcbiAgICAgKiBUaGUgaHVtYW4gcmVhZGFibGUgZGVzY3ByaXRpb24gb2YgdGhlIGRhdGV0aW1lIHBhcnRcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBkZXNjcmlwdGlvbjogWydzdHJpbmcnLCB0cnVlXSxcbiAgICAvKipcbiAgICAgKiBEYXRhIHR5cGUgYWZ0ZXIgY29udmVyc2lvbjogJ2NvbnRpbnVvdXMnLCBvciAnY2F0ZWdvcmlhbCdcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0eXBlOiBbJ3N0cmluZycsIHRydWVdLFxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIGRhdGV0aW1lIHBhcnRzIChpZSwgZGF5LW9mLXllYXIpLCB0aGUgbWluaW11bSB2YWx1ZVxuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIG1pbjogWydudW1iZXInLCB0cnVlLCAwXSxcbiAgICAvKipcbiAgICAgKiBGb3IgY29udGludW91cyBkYXRldGltZSBwYXJ0cyAoaWUsIGRheS1vZi15ZWFyKSwgdGhlIG1heGltdW0gdmFsdWVcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBtYXg6IFsnbnVtYmVyJywgdHJ1ZSwgMV0sXG4gICAgLyoqXG4gICAgICogV2hlbiB0cnVlLCBjYWxjdWxhdGUgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gdmFsdWUgZnJvbSB0aGVcbiAgICAgKiBvcmlnaW5hbCBkYXRldGltZSBsaW1pdHMuIFVzZWQgZm9yIGNvbnRpbnVvdXMgZGF0ZXRpbWUgcGFydHMgKGllLCB5ZWFyKVxuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBjYWxjdWxhdGU6IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXSxcbiAgICAvKipcbiAgICAgKiBGb3IgY2F0ZWdvcmlhbCBkYXRldGltZSBwYXJ0cyAoTW9uLCBUdWUsIC4uKSwgdGhlIGFycmF5IG9mIHBvc3NpYmxlIHZhbHVlc1xuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7U3RyaW5nW119XG4gICAgICovXG4gICAgZ3JvdXBzOiBbJ2FycmF5J11cbiAgfVxufSk7XG5cbnZhciBUaW1lUGFydHMgPSBBbXBlcnNhbmRDb2xsbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogVGltZVBhcnQsXG4gIGluZGV4ZXM6IFsnZGVzY3JpcHRpb24nXVxufSk7XG5cbnZhciB0aW1lUGFydHMgPSBuZXcgVGltZVBhcnRzKFtcbiAgeyBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLCB0eXBlOiAnZGF0ZXRpbWUnLCBjYWxjdWxhdGU6IHRydWUgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ21vbnRoJywgbW9tZW50Rm9ybWF0OiAnTScsIGRlc2NyaXB0aW9uOiAnTW9udGggKDEtMTIpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogMTIgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3F1YXJ0ZXInLCBtb21lbnRGb3JtYXQ6ICdRJywgZGVzY3JpcHRpb246ICdRdWFydGVyICgxLTQpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogNCB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZGF5JywgbW9tZW50Rm9ybWF0OiAnRCcsIGRlc2NyaXB0aW9uOiAnRGF5IG9mIE1vbnRoICAoMS0zMSknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMSwgbWF4OiAzMSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZG95JywgbW9tZW50Rm9ybWF0OiAnREREJywgZGVzY3JpcHRpb246ICdEYXkgb2YgWWVhciAoMS0zNjUpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogMzY1IH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdkb3cnLCBtb21lbnRGb3JtYXQ6ICdkJywgZGVzY3JpcHRpb246ICdEYXkgb2YgV2VlayAoMC02KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDYgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ2lzb2RvdycsIG1vbWVudEZvcm1hdDogJ0UnLCBkZXNjcmlwdGlvbjogJ0RheSBvZiBXZWVrIElTTyAoMS03KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAxLCBtYXg6IDcgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3dlZWsnLCBtb21lbnRGb3JtYXQ6ICdXJywgZGVzY3JpcHRpb246ICdXZWVrIG9mIFllYXIgSVNPICAoMS01MyknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMSwgbWF4OiA1MyB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAneWVhcicsIG1vbWVudEZvcm1hdDogJ1knLCBkZXNjcmlwdGlvbjogJ1llYXInLCB0eXBlOiAnY29udGludW91cycsIGNhbGN1bGF0ZTogdHJ1ZSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnaG91cnMnLCBtb21lbnRGb3JtYXQ6ICdIJywgZGVzY3JpcHRpb246ICdIb3VyICgwLTIzKScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDIzIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdtaW51dGUnLCBtb21lbnRGb3JtYXQ6ICdtJywgZGVzY3JpcHRpb246ICdNaW51dGUgKDAtNTkpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDAsIG1heDogNTkgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3NlY29uZCcsIG1vbWVudEZvcm1hdDogJ3MnLCBkZXNjcmlwdGlvbjogJ1NlY29uZCAoMC01OSknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMCwgbWF4OiA1OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnbWlsbGlzZWNvbmRzJywgbW9tZW50Rm9ybWF0OiAnU1NTJywgZGVzY3JpcHRpb246ICdNaWxsaXNlY29uZHMgKDAtOTk5KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDk5OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnbWljcm9zZWNvbmRzJywgbW9tZW50Rm9ybWF0OiAnU1NTU1NTJywgZGVzY3JpcHRpb246ICdtaWNyb3NlY29uZHMgKDAtOTk5OTk5KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDk5OTk5OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZXBvY2gnLCBtb21lbnRGb3JtYXQ6ICdYJywgZGVzY3JpcHRpb246ICdVbml4IFRpbWVzdGFtcCcsIHR5cGU6ICdjb250aW51b3VzJywgY2FsY3VsYXRlOiB0cnVlIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdNb24nLCBtb21lbnRGb3JtYXQ6ICdNTU0nLCBkZXNjcmlwdGlvbjogJ01vbnRoIChKYW4gLSBEZWMpJywgdHlwZTogJ2NhdGVnb3JpYWwnLCBncm91cHM6IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLCAnT2N0JywgJ05vdicsICdEZWMnXSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnTW9udGgnLCBtb21lbnRGb3JtYXQ6ICdNTU1NJywgZGVzY3JpcHRpb246ICdNb250aCAoSmFudWFyeSAtIERlY2VtYmVyKScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ0phbnVhcnknLCAnRmVidXJhcnknLCAnTWFyY2gnLCAnQXByaWwnLCAnTWF5JywgJ0p1bmUnLCAnSnVseScsICdBdWd1c3QnLCAnU2VwdGVibWVyJywgJ09jdG9iZXInLCAnTm92ZW1iZXInLCAnRGVjZW1iZXInXSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnRHknLCBtb21lbnRGb3JtYXQ6ICdkZGQnLCBkZXNjcmlwdGlvbjogJ0RheSBvZiBXZWVrIChTdW4tU2F0KScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ1N1bicsICdNb24nLCAnVHVlJywgJ1dlZCcsICdUaHUnLCAnRnJpJywgJ1NhdCddIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdEYXknLCBtb21lbnRGb3JtYXQ6ICdkZGRkJywgZGVzY3JpcHRpb246ICdEYXkgb2YgV2VlayAoU3VuZGF5LVNhdHVyZGF5KScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknLCAnU3VuZGF5J10gfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ0FNJywgbW9tZW50Rm9ybWF0OiAnQScsIGRlc2NyaXB0aW9uOiAnQU0vUE0nLCB0eXBlOiAnY2F0ZWdvcmlhbCcsIGdyb3VwczogWydBTScsICdQTSddIH1cbl0pO1xuXG52YXIgRHVyYXRpb25Vbml0ID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBUaGUgZGVzY3JpcHRpdmUgbmFtZSBvZiB0aGUgdGltZSB1bml0XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRlc2NyaXB0aW9uOiBbJ3N0cmluZyddLFxuICAgIC8qKlxuICAgICAqIE1vbWVudGpzIHBhcnNpbmcgZm9ybWF0XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG1vbWVudEZvcm1hdDogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBQb3N0Z3JlcyBwYXJzaW5nIGZvcm1hdFxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25Vbml0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBwb3N0Z3Jlc0Zvcm1hdDogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBDb252ZXJzaW9uIGZhY3RvciB0byBzZWNvbmRzXG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHNlY29uZHM6IFsnbnVtYmVyJ11cbiAgfVxufSk7XG5cbnZhciBEdXJhdGlvblVuaXRzID0gQW1wZXJzYW5kQ29sbGxlY3Rpb24uZXh0ZW5kKHtcbiAgaW5kZXhlczogWydkZXNjcmlwdGlvbiddLFxuICBtb2RlbDogRHVyYXRpb25Vbml0XG59KTtcblxudmFyIGR1cmF0aW9uVW5pdHMgPSBuZXcgRHVyYXRpb25Vbml0cyhbXG4gIHtcbiAgICBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLFxuICAgIHNlY29uZHM6IDFcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnbWlsbGVuaXVtJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaWxsZW5pdW0nLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnbWlsbGVuaXVtJyxcbiAgICBzZWNvbmRzOiAxMDAgKiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnY2VudHVyeScsXG4gICAgbW9tZW50Rm9ybWF0OiAnY2VudHVyeScsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdjZW50dXJ5JyxcbiAgICBzZWNvbmRzOiAxMDAgKiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnZGVjYWRlcycsXG4gICAgbW9tZW50Rm9ybWF0OiAnZGVjYWRlcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdkZWNhZGUnLFxuICAgIHNlY29uZHM6IDEwICogMzY1LjI1ICogMjQgKiA2MCAqIDYwXG4gIH0sIHtcbiAgICBkZXNjcmlwdGlvbjogJ3llYXJzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICd5ZWFycycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICd5ZWFyJyxcbiAgICBzZWNvbmRzOiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAncXVhcnRlcnMnLFxuICAgIG1vbWVudEZvcm1hdDogJycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdxdWFydGVyJyxcbiAgICBzZWNvbmRzOiAzNjUuMjUgKiA4ICogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtb250aHMnLFxuICAgIG1vbWVudEZvcm1hdDogJ21vbnRocycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdtb250aCcsXG4gICAgc2Vjb25kczogMzAgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnd2Vla3MnLFxuICAgIG1vbWVudEZvcm1hdDogJ3dlZWtzJyxcbiAgICBwb3N0Z3Jlc0Zvcm1hdDogJ3dlZWsnLFxuICAgIHNlY29uZHM6IDcgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnZGF5cycsXG4gICAgbW9tZW50Rm9ybWF0OiAnZGF5cycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdkYXknLFxuICAgIHNlY29uZHM6IDI0ICogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdob3VycycsXG4gICAgbW9tZW50Rm9ybWF0OiAnaG91cnMnLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnaG91cicsXG4gICAgc2Vjb25kczogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtaW51dGVzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaW51dGVzJyxcbiAgICBwb3N0Z3Jlc0Zvcm1hdDogJ21pbnV0ZScsXG4gICAgc2Vjb25kczogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnc2Vjb25kcycsXG4gICAgbW9tZW50Rm9ybWF0OiAnc2Vjb25kcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdzZWNvbmQnLFxuICAgIHNlY29uZHM6IDFcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnbWlsbGlzZWNvbmRzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaWxsaXNlY29uZHMnLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnbWlsbGlzZWNvbmRzJyxcbiAgICBzZWNvbmRzOiAwLjAwMVxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtaWNyb3NlY29uZHMnLFxuICAgIG1vbWVudEZvcm1hdDogJ21pY3Jvc2Vjb25kcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdtaWNyb3NlY29uZHMnLFxuICAgIHNlY29uZHM6IDAuMDAwMDAxXG4gIH1cbl0pO1xuXG52YXIgVGltZVpvbmUgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRoZSBkZXNjcmlwdGl2ZSBuYW1lIG9mIHRoZSB0aW1lIHpvbmVcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVab25lXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBkZXNjcmlwdGlvbjogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSB6b25lIGZvcm1hdFxuICAgICAqIEBtZW1iZXJvZiEgVGltZVpvbmVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZvcm1hdDogWydzdHJpbmcnXVxuICB9XG59KTtcblxudmFyIFRpbWVab25lcyA9IEFtcGVyc2FuZENvbGxsZWN0aW9uLmV4dGVuZCh7XG4gIGluZGV4ZXM6IFsnZGVzY3JpcHRpb24nXSxcbiAgbW9kZWw6IFRpbWVab25lXG59KTtcblxudmFyIHRpbWVab25lcyA9IG5ldyBUaW1lWm9uZXMoKTtcbnRpbWVab25lcy5hZGQoe1xuICBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLFxuICBmb3JtYXQ6ICdJU084NjAxJ1xufSk7XG5cbm1vbWVudC50ei5uYW1lcygpLmZvckVhY2goZnVuY3Rpb24gKHR6KSB7XG4gIHRpbWVab25lcy5hZGQoe1xuICAgIGRlc2NyaXB0aW9uOiB0eixcbiAgICBmb3JtYXQ6IHR6XG4gIH0pO1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB0aW1lUGFydHM6IHRpbWVQYXJ0cyxcbiAgdGltZVpvbmVzOiB0aW1lWm9uZXMsXG4gIGR1cmF0aW9uVW5pdHM6IGR1cmF0aW9uVW5pdHMsXG4gIGdldERhdGV0aW1lUmVzb2x1dGlvbjogZ2V0RGF0ZXRpbWVSZXNvbHV0aW9uLFxuICBnZXREdXJhdGlvblJlc29sdXRpb246IGdldER1cmF0aW9uUmVzb2x1dGlvbixcbiAgZ2V0Rm9ybWF0OiBnZXRGb3JtYXRcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///d45b\n")},e59a:function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Partition = __webpack_require__(/*! ../partition */ \"8191\");\n\nmodule.exports = Collection.extend({\n  model: Partition,\n  indexes: ['rank'],\n  comparator: 'rank',\n  initialize: function () {\n    this.on('add', function (newPartition) {\n      newPartition.reset();\n    });\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTU5YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2NvbGxlY3Rpb24uanM/YzRiOCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgUGFydGl0aW9uID0gcmVxdWlyZSgnLi4vcGFydGl0aW9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogUGFydGl0aW9uLFxuICBpbmRleGVzOiBbJ3JhbmsnXSxcbiAgY29tcGFyYXRvcjogJ3JhbmsnLFxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5vbignYWRkJywgZnVuY3Rpb24gKG5ld1BhcnRpdGlvbikge1xuICAgICAgbmV3UGFydGl0aW9uLnJlc2V0KCk7XG4gICAgfSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///e59a\n")},e810:function(module,exports,__webpack_require__){eval("/**\n * ContinuousTransfrom defines a transformation on continuous (nummerical) data.\n * Currently linear interpolation between a set of control points is implemented.\n *\n * @class ContinuousTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'text',\n      values: ['text']\n    },\n    transformedMin: {\n      type: 'number',\n      required: true,\n      default: 0\n    },\n    transformedMax: {\n      type: 'number',\n      required: true,\n      default: 100\n    }\n  },\n  reset: function () {\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTgxMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvdGV4dC10cmFuc2Zvcm0uanM/MzQ1MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbnRpbnVvdXNUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNvbnRpbnVvdXMgKG51bW1lcmljYWwpIGRhdGEuXG4gKiBDdXJyZW50bHkgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiBhIHNldCBvZiBjb250cm9sIHBvaW50cyBpcyBpbXBsZW1lbnRlZC5cbiAqXG4gKiBAY2xhc3MgQ29udGludW91c1RyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIHRyYW5zZm9ybWVkVHlwZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICd0ZXh0JyxcbiAgICAgIHZhbHVlczogWyd0ZXh0J11cbiAgICB9LFxuICAgIHRyYW5zZm9ybWVkTWluOiB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogMFxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNYXg6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAxMDBcbiAgICB9XG4gIH0sXG4gIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///e810\n")},ea82:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/*global Blob,File*/\n\n/**\n * Module requirements\n */\n\nvar isArray = __webpack_require__(/*! isarray */ \"6176\");\nvar isBuf = __webpack_require__(/*! ./is-buffer */ \"419b\");\n\n/**\n * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.\n * Anything with blobs or files should be fed through removeBlobs before coming\n * here.\n *\n * @param {Object} packet - socket.io event packet\n * @return {Object} with deconstructed packet and list of buffers\n * @api public\n */\n\nexports.deconstructPacket = function(packet){\n  var buffers = [];\n  var packetData = packet.data;\n\n  function _deconstructPacket(data) {\n    if (!data) return data;\n\n    if (isBuf(data)) {\n      var placeholder = { _placeholder: true, num: buffers.length };\n      buffers.push(data);\n      return placeholder;\n    } else if (isArray(data)) {\n      var newData = new Array(data.length);\n      for (var i = 0; i < data.length; i++) {\n        newData[i] = _deconstructPacket(data[i]);\n      }\n      return newData;\n    } else if ('object' == typeof data && !(data instanceof Date)) {\n      var newData = {};\n      for (var key in data) {\n        newData[key] = _deconstructPacket(data[key]);\n      }\n      return newData;\n    }\n    return data;\n  }\n\n  var pack = packet;\n  pack.data = _deconstructPacket(packetData);\n  pack.attachments = buffers.length; // number of binary 'attachments'\n  return {packet: pack, buffers: buffers};\n};\n\n/**\n * Reconstructs a binary packet from its placeholder packet and buffers\n *\n * @param {Object} packet - event packet with placeholders\n * @param {Array} buffers - binary buffers to put in placeholder positions\n * @return {Object} reconstructed packet\n * @api public\n */\n\nexports.reconstructPacket = function(packet, buffers) {\n  var curPlaceHolder = 0;\n\n  function _reconstructPacket(data) {\n    if (data && data._placeholder) {\n      var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway)\n      return buf;\n    } else if (isArray(data)) {\n      for (var i = 0; i < data.length; i++) {\n        data[i] = _reconstructPacket(data[i]);\n      }\n      return data;\n    } else if (data && 'object' == typeof data) {\n      for (var key in data) {\n        data[key] = _reconstructPacket(data[key]);\n      }\n      return data;\n    }\n    return data;\n  }\n\n  packet.data = _reconstructPacket(packet.data);\n  packet.attachments = undefined; // no longer useful\n  return packet;\n};\n\n/**\n * Asynchronously removes Blobs or Files from data via\n * FileReader's readAsArrayBuffer method. Used before encoding\n * data as msgpack. Calls callback with the blobless data.\n *\n * @param {Object} data\n * @param {Function} callback\n * @api private\n */\n\nexports.removeBlobs = function(data, callback) {\n  function _removeBlobs(obj, curKey, containingObject) {\n    if (!obj) return obj;\n\n    // convert any blob\n    if ((global.Blob && obj instanceof Blob) ||\n        (global.File && obj instanceof File)) {\n      pendingBlobs++;\n\n      // async filereader\n      var fileReader = new FileReader();\n      fileReader.onload = function() { // this.result == arraybuffer\n        if (containingObject) {\n          containingObject[curKey] = this.result;\n        }\n        else {\n          bloblessData = this.result;\n        }\n\n        // if nothing pending its callback time\n        if(! --pendingBlobs) {\n          callback(bloblessData);\n        }\n      };\n\n      fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer\n    } else if (isArray(obj)) { // handle array\n      for (var i = 0; i < obj.length; i++) {\n        _removeBlobs(obj[i], i, obj);\n      }\n    } else if (obj && 'object' == typeof obj && !isBuf(obj)) { // and object\n      for (var key in obj) {\n        _removeBlobs(obj[key], key, obj);\n      }\n    }\n  }\n\n  var pendingBlobs = 0;\n  var bloblessData = data;\n  _removeBlobs(bloblessData);\n  if (!pendingBlobs) {\n    callback(bloblessData);\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWE4Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9iaW5hcnkuanM/ZGQwNyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKmdsb2JhbCBCbG9iLEZpbGUqL1xuXG4vKipcbiAqIE1vZHVsZSByZXF1aXJlbWVudHNcbiAqL1xuXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcbnZhciBpc0J1ZiA9IHJlcXVpcmUoJy4vaXMtYnVmZmVyJyk7XG5cbi8qKlxuICogUmVwbGFjZXMgZXZlcnkgQnVmZmVyIHwgQXJyYXlCdWZmZXIgaW4gcGFja2V0IHdpdGggYSBudW1iZXJlZCBwbGFjZWhvbGRlci5cbiAqIEFueXRoaW5nIHdpdGggYmxvYnMgb3IgZmlsZXMgc2hvdWxkIGJlIGZlZCB0aHJvdWdoIHJlbW92ZUJsb2JzIGJlZm9yZSBjb21pbmdcbiAqIGhlcmUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldCAtIHNvY2tldC5pbyBldmVudCBwYWNrZXRcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBkZWNvbnN0cnVjdGVkIHBhY2tldCBhbmQgbGlzdCBvZiBidWZmZXJzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb25zdHJ1Y3RQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQpe1xuICB2YXIgYnVmZmVycyA9IFtdO1xuICB2YXIgcGFja2V0RGF0YSA9IHBhY2tldC5kYXRhO1xuXG4gIGZ1bmN0aW9uIF9kZWNvbnN0cnVjdFBhY2tldChkYXRhKSB7XG4gICAgaWYgKCFkYXRhKSByZXR1cm4gZGF0YTtcblxuICAgIGlmIChpc0J1ZihkYXRhKSkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0geyBfcGxhY2Vob2xkZXI6IHRydWUsIG51bTogYnVmZmVycy5sZW5ndGggfTtcbiAgICAgIGJ1ZmZlcnMucHVzaChkYXRhKTtcbiAgICAgIHJldHVybiBwbGFjZWhvbGRlcjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIHZhciBuZXdEYXRhID0gbmV3IEFycmF5KGRhdGEubGVuZ3RoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBuZXdEYXRhW2ldID0gX2RlY29uc3RydWN0UGFja2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgfSBlbHNlIGlmICgnb2JqZWN0JyA9PSB0eXBlb2YgZGF0YSAmJiAhKGRhdGEgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgdmFyIG5ld0RhdGEgPSB7fTtcbiAgICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICAgIG5ld0RhdGFba2V5XSA9IF9kZWNvbnN0cnVjdFBhY2tldChkYXRhW2tleV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgdmFyIHBhY2sgPSBwYWNrZXQ7XG4gIHBhY2suZGF0YSA9IF9kZWNvbnN0cnVjdFBhY2tldChwYWNrZXREYXRhKTtcbiAgcGFjay5hdHRhY2htZW50cyA9IGJ1ZmZlcnMubGVuZ3RoOyAvLyBudW1iZXIgb2YgYmluYXJ5ICdhdHRhY2htZW50cydcbiAgcmV0dXJuIHtwYWNrZXQ6IHBhY2ssIGJ1ZmZlcnM6IGJ1ZmZlcnN9O1xufTtcblxuLyoqXG4gKiBSZWNvbnN0cnVjdHMgYSBiaW5hcnkgcGFja2V0IGZyb20gaXRzIHBsYWNlaG9sZGVyIHBhY2tldCBhbmQgYnVmZmVyc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQgLSBldmVudCBwYWNrZXQgd2l0aCBwbGFjZWhvbGRlcnNcbiAqIEBwYXJhbSB7QXJyYXl9IGJ1ZmZlcnMgLSBiaW5hcnkgYnVmZmVycyB0byBwdXQgaW4gcGxhY2Vob2xkZXIgcG9zaXRpb25zXG4gKiBAcmV0dXJuIHtPYmplY3R9IHJlY29uc3RydWN0ZWQgcGFja2V0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMucmVjb25zdHJ1Y3RQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQsIGJ1ZmZlcnMpIHtcbiAgdmFyIGN1clBsYWNlSG9sZGVyID0gMDtcblxuICBmdW5jdGlvbiBfcmVjb25zdHJ1Y3RQYWNrZXQoZGF0YSkge1xuICAgIGlmIChkYXRhICYmIGRhdGEuX3BsYWNlaG9sZGVyKSB7XG4gICAgICB2YXIgYnVmID0gYnVmZmVyc1tkYXRhLm51bV07IC8vIGFwcHJvcHJpYXRlIGJ1ZmZlciAoc2hvdWxkIGJlIG5hdHVyYWwgb3JkZXIgYW55d2F5KVxuICAgICAgcmV0dXJuIGJ1ZjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBkYXRhW2ldID0gX3JlY29uc3RydWN0UGFja2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSBlbHNlIGlmIChkYXRhICYmICdvYmplY3QnID09IHR5cGVvZiBkYXRhKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkge1xuICAgICAgICBkYXRhW2tleV0gPSBfcmVjb25zdHJ1Y3RQYWNrZXQoZGF0YVtrZXldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIHBhY2tldC5kYXRhID0gX3JlY29uc3RydWN0UGFja2V0KHBhY2tldC5kYXRhKTtcbiAgcGFja2V0LmF0dGFjaG1lbnRzID0gdW5kZWZpbmVkOyAvLyBubyBsb25nZXIgdXNlZnVsXG4gIHJldHVybiBwYWNrZXQ7XG59O1xuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IHJlbW92ZXMgQmxvYnMgb3IgRmlsZXMgZnJvbSBkYXRhIHZpYVxuICogRmlsZVJlYWRlcidzIHJlYWRBc0FycmF5QnVmZmVyIG1ldGhvZC4gVXNlZCBiZWZvcmUgZW5jb2RpbmdcbiAqIGRhdGEgYXMgbXNncGFjay4gQ2FsbHMgY2FsbGJhY2sgd2l0aCB0aGUgYmxvYmxlc3MgZGF0YS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMucmVtb3ZlQmxvYnMgPSBmdW5jdGlvbihkYXRhLCBjYWxsYmFjaykge1xuICBmdW5jdGlvbiBfcmVtb3ZlQmxvYnMob2JqLCBjdXJLZXksIGNvbnRhaW5pbmdPYmplY3QpIHtcbiAgICBpZiAoIW9iaikgcmV0dXJuIG9iajtcblxuICAgIC8vIGNvbnZlcnQgYW55IGJsb2JcbiAgICBpZiAoKGdsb2JhbC5CbG9iICYmIG9iaiBpbnN0YW5jZW9mIEJsb2IpIHx8XG4gICAgICAgIChnbG9iYWwuRmlsZSAmJiBvYmogaW5zdGFuY2VvZiBGaWxlKSkge1xuICAgICAgcGVuZGluZ0Jsb2JzKys7XG5cbiAgICAgIC8vIGFzeW5jIGZpbGVyZWFkZXJcbiAgICAgIHZhciBmaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gZnVuY3Rpb24oKSB7IC8vIHRoaXMucmVzdWx0ID09IGFycmF5YnVmZmVyXG4gICAgICAgIGlmIChjb250YWluaW5nT2JqZWN0KSB7XG4gICAgICAgICAgY29udGFpbmluZ09iamVjdFtjdXJLZXldID0gdGhpcy5yZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYmxvYmxlc3NEYXRhID0gdGhpcy5yZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBub3RoaW5nIHBlbmRpbmcgaXRzIGNhbGxiYWNrIHRpbWVcbiAgICAgICAgaWYoISAtLXBlbmRpbmdCbG9icykge1xuICAgICAgICAgIGNhbGxiYWNrKGJsb2JsZXNzRGF0YSk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIob2JqKTsgLy8gYmxvYiAtPiBhcnJheWJ1ZmZlclxuICAgIH0gZWxzZSBpZiAoaXNBcnJheShvYmopKSB7IC8vIGhhbmRsZSBhcnJheVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtpXSwgaSwgb2JqKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9iaiAmJiAnb2JqZWN0JyA9PSB0eXBlb2Ygb2JqICYmICFpc0J1ZihvYmopKSB7IC8vIGFuZCBvYmplY3RcbiAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHBlbmRpbmdCbG9icyA9IDA7XG4gIHZhciBibG9ibGVzc0RhdGEgPSBkYXRhO1xuICBfcmVtb3ZlQmxvYnMoYmxvYmxlc3NEYXRhKTtcbiAgaWYgKCFwZW5kaW5nQmxvYnMpIHtcbiAgICBjYWxsYmFjayhibG9ibGVzc0RhdGEpO1xuICB9XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///ea82\n")},ef13:function(module,exports){eval("/**\n * An abstraction for slicing an arraybuffer even when\n * ArrayBuffer.prototype.slice is not supported\n *\n * @api public\n */\n\nmodule.exports = function(arraybuffer, start, end) {\n  var bytes = arraybuffer.byteLength;\n  start = start || 0;\n  end = end || bytes;\n\n  if (arraybuffer.slice) { return arraybuffer.slice(start, end); }\n\n  if (start < 0) { start += bytes; }\n  if (end < 0) { end += bytes; }\n  if (end > bytes) { end = bytes; }\n\n  if (start >= bytes || start >= end || bytes === 0) {\n    return new ArrayBuffer(0);\n  }\n\n  var abv = new Uint8Array(arraybuffer);\n  var result = new Uint8Array(end - start);\n  for (var i = start, ii = 0; i < end; i++, ii++) {\n    result[ii] = abv[i];\n  }\n  return result.buffer;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWYxMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvYXJyYXlidWZmZXIuc2xpY2UvaW5kZXguanM/NTM3NCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFuIGFic3RyYWN0aW9uIGZvciBzbGljaW5nIGFuIGFycmF5YnVmZmVyIGV2ZW4gd2hlblxuICogQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlIGlzIG5vdCBzdXBwb3J0ZWRcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYXJyYXlidWZmZXIsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYXJyYXlidWZmZXIuYnl0ZUxlbmd0aDtcbiAgc3RhcnQgPSBzdGFydCB8fCAwO1xuICBlbmQgPSBlbmQgfHwgYnl0ZXM7XG5cbiAgaWYgKGFycmF5YnVmZmVyLnNsaWNlKSB7IHJldHVybiBhcnJheWJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTsgfVxuXG4gIGlmIChzdGFydCA8IDApIHsgc3RhcnQgKz0gYnl0ZXM7IH1cbiAgaWYgKGVuZCA8IDApIHsgZW5kICs9IGJ5dGVzOyB9XG4gIGlmIChlbmQgPiBieXRlcykgeyBlbmQgPSBieXRlczsgfVxuXG4gIGlmIChzdGFydCA+PSBieXRlcyB8fCBzdGFydCA+PSBlbmQgfHwgYnl0ZXMgPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xuICB9XG5cbiAgdmFyIGFidiA9IG5ldyBVaW50OEFycmF5KGFycmF5YnVmZmVyKTtcbiAgdmFyIHJlc3VsdCA9IG5ldyBVaW50OEFycmF5KGVuZCAtIHN0YXJ0KTtcbiAgZm9yICh2YXIgaSA9IHN0YXJ0LCBpaSA9IDA7IGkgPCBlbmQ7IGkrKywgaWkrKykge1xuICAgIHJlc3VsdFtpaV0gPSBhYnZbaV07XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5idWZmZXI7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///ef13\n")},faaa:function(module,exports){eval("\n/**\n * Module exports.\n */\n\nmodule.exports = on;\n\n/**\n * Helper for subscriptions.\n *\n * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`\n * @param {String} event name\n * @param {Function} callback\n * @api public\n */\n\nfunction on (obj, ev, fn) {\n  obj.on(ev, fn);\n  return {\n    destroy: function () {\n      obj.removeListener(ev, fn);\n    }\n  };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFhYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvb24uanM/MTBkYiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBvbjtcblxuLyoqXG4gKiBIZWxwZXIgZm9yIHN1YnNjcmlwdGlvbnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8RXZlbnRFbWl0dGVyfSBvYmogd2l0aCBgRW1pdHRlcmAgbWl4aW4gb3IgYEV2ZW50RW1pdHRlcmBcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBuYW1lXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBvbiAob2JqLCBldiwgZm4pIHtcbiAgb2JqLm9uKGV2LCBmbik7XG4gIHJldHVybiB7XG4gICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgb2JqLnJlbW92ZUxpc3RlbmVyKGV2LCBmbik7XG4gICAgfVxuICB9O1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///faaa\n")},fbef:function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Aggregate = __webpack_require__(/*! ../aggregate */ \"9d63\");\n\nmodule.exports = Collection.extend({\n  model: Aggregate,\n  indexes: ['rank'],\n  comparator: 'rank'\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmJlZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvYWdncmVnYXRlL2NvbGxlY3Rpb24uanM/YmJhNiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgQWdncmVnYXRlID0gcmVxdWlyZSgnLi4vYWdncmVnYXRlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogQWdncmVnYXRlLFxuICBpbmRleGVzOiBbJ3JhbmsnXSxcbiAgY29tcGFyYXRvcjogJ3JhbmsnXG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///fbef\n")}}]);

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.moment"],{da01:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js\n\n;(function (global, factory) {\n     true ? module.exports = factory() :\n    undefined\n}(this, (function () { 'use strict';\n\n    var hookCallback;\n\n    function hooks () {\n        return hookCallback.apply(null, arguments);\n    }\n\n    // This is done to register the method called with moment()\n    // without creating circular dependencies.\n    function setHookCallback (callback) {\n        hookCallback = callback;\n    }\n\n    function isArray(input) {\n        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n    }\n\n    function isObject(input) {\n        // IE8 will treat undefined and null as object if it wasn't for\n        // input != null\n        return input != null && Object.prototype.toString.call(input) === '[object Object]';\n    }\n\n    function isObjectEmpty(obj) {\n        if (Object.getOwnPropertyNames) {\n            return (Object.getOwnPropertyNames(obj).length === 0);\n        } else {\n            var k;\n            for (k in obj) {\n                if (obj.hasOwnProperty(k)) {\n                    return false;\n                }\n            }\n            return true;\n        }\n    }\n\n    function isUndefined(input) {\n        return input === void 0;\n    }\n\n    function isNumber(input) {\n        return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n    }\n\n    function isDate(input) {\n        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n    }\n\n    function map(arr, fn) {\n        var res = [], i;\n        for (i = 0; i < arr.length; ++i) {\n            res.push(fn(arr[i], i));\n        }\n        return res;\n    }\n\n    function hasOwnProp(a, b) {\n        return Object.prototype.hasOwnProperty.call(a, b);\n    }\n\n    function extend(a, b) {\n        for (var i in b) {\n            if (hasOwnProp(b, i)) {\n                a[i] = b[i];\n            }\n        }\n\n        if (hasOwnProp(b, 'toString')) {\n            a.toString = b.toString;\n        }\n\n        if (hasOwnProp(b, 'valueOf')) {\n            a.valueOf = b.valueOf;\n        }\n\n        return a;\n    }\n\n    function createUTC (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, true).utc();\n    }\n\n    function defaultParsingFlags() {\n        // We need to deep clone this object.\n        return {\n            empty           : false,\n            unusedTokens    : [],\n            unusedInput     : [],\n            overflow        : -2,\n            charsLeftOver   : 0,\n            nullInput       : false,\n            invalidMonth    : null,\n            invalidFormat   : false,\n            userInvalidated : false,\n            iso             : false,\n            parsedDateParts : [],\n            meridiem        : null,\n            rfc2822         : false,\n            weekdayMismatch : false\n        };\n    }\n\n    function getParsingFlags(m) {\n        if (m._pf == null) {\n            m._pf = defaultParsingFlags();\n        }\n        return m._pf;\n    }\n\n    var some;\n    if (Array.prototype.some) {\n        some = Array.prototype.some;\n    } else {\n        some = function (fun) {\n            var t = Object(this);\n            var len = t.length >>> 0;\n\n            for (var i = 0; i < len; i++) {\n                if (i in t && fun.call(this, t[i], i, t)) {\n                    return true;\n                }\n            }\n\n            return false;\n        };\n    }\n\n    function isValid(m) {\n        if (m._isValid == null) {\n            var flags = getParsingFlags(m);\n            var parsedParts = some.call(flags.parsedDateParts, function (i) {\n                return i != null;\n            });\n            var isNowValid = !isNaN(m._d.getTime()) &&\n                flags.overflow < 0 &&\n                !flags.empty &&\n                !flags.invalidMonth &&\n                !flags.invalidWeekday &&\n                !flags.weekdayMismatch &&\n                !flags.nullInput &&\n                !flags.invalidFormat &&\n                !flags.userInvalidated &&\n                (!flags.meridiem || (flags.meridiem && parsedParts));\n\n            if (m._strict) {\n                isNowValid = isNowValid &&\n                    flags.charsLeftOver === 0 &&\n                    flags.unusedTokens.length === 0 &&\n                    flags.bigHour === undefined;\n            }\n\n            if (Object.isFrozen == null || !Object.isFrozen(m)) {\n                m._isValid = isNowValid;\n            }\n            else {\n                return isNowValid;\n            }\n        }\n        return m._isValid;\n    }\n\n    function createInvalid (flags) {\n        var m = createUTC(NaN);\n        if (flags != null) {\n            extend(getParsingFlags(m), flags);\n        }\n        else {\n            getParsingFlags(m).userInvalidated = true;\n        }\n\n        return m;\n    }\n\n    // Plugins that add properties should also add the key here (null value),\n    // so we can properly clone ourselves.\n    var momentProperties = hooks.momentProperties = [];\n\n    function copyConfig(to, from) {\n        var i, prop, val;\n\n        if (!isUndefined(from._isAMomentObject)) {\n            to._isAMomentObject = from._isAMomentObject;\n        }\n        if (!isUndefined(from._i)) {\n            to._i = from._i;\n        }\n        if (!isUndefined(from._f)) {\n            to._f = from._f;\n        }\n        if (!isUndefined(from._l)) {\n            to._l = from._l;\n        }\n        if (!isUndefined(from._strict)) {\n            to._strict = from._strict;\n        }\n        if (!isUndefined(from._tzm)) {\n            to._tzm = from._tzm;\n        }\n        if (!isUndefined(from._isUTC)) {\n            to._isUTC = from._isUTC;\n        }\n        if (!isUndefined(from._offset)) {\n            to._offset = from._offset;\n        }\n        if (!isUndefined(from._pf)) {\n            to._pf = getParsingFlags(from);\n        }\n        if (!isUndefined(from._locale)) {\n            to._locale = from._locale;\n        }\n\n        if (momentProperties.length > 0) {\n            for (i = 0; i < momentProperties.length; i++) {\n                prop = momentProperties[i];\n                val = from[prop];\n                if (!isUndefined(val)) {\n                    to[prop] = val;\n                }\n            }\n        }\n\n        return to;\n    }\n\n    var updateInProgress = false;\n\n    // Moment prototype object\n    function Moment(config) {\n        copyConfig(this, config);\n        this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n        if (!this.isValid()) {\n            this._d = new Date(NaN);\n        }\n        // Prevent infinite loop in case updateOffset creates new moment\n        // objects.\n        if (updateInProgress === false) {\n            updateInProgress = true;\n            hooks.updateOffset(this);\n            updateInProgress = false;\n        }\n    }\n\n    function isMoment (obj) {\n        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n    }\n\n    function absFloor (number) {\n        if (number < 0) {\n            // -0 -> 0\n            return Math.ceil(number) || 0;\n        } else {\n            return Math.floor(number);\n        }\n    }\n\n    function toInt(argumentForCoercion) {\n        var coercedNumber = +argumentForCoercion,\n            value = 0;\n\n        if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n            value = absFloor(coercedNumber);\n        }\n\n        return value;\n    }\n\n    // compare two arrays, return the number of differences\n    function compareArrays(array1, array2, dontConvert) {\n        var len = Math.min(array1.length, array2.length),\n            lengthDiff = Math.abs(array1.length - array2.length),\n            diffs = 0,\n            i;\n        for (i = 0; i < len; i++) {\n            if ((dontConvert && array1[i] !== array2[i]) ||\n                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n                diffs++;\n            }\n        }\n        return diffs + lengthDiff;\n    }\n\n    function warn(msg) {\n        if (hooks.suppressDeprecationWarnings === false &&\n                (typeof console !==  'undefined') && console.warn) {\n            console.warn('Deprecation warning: ' + msg);\n        }\n    }\n\n    function deprecate(msg, fn) {\n        var firstTime = true;\n\n        return extend(function () {\n            if (hooks.deprecationHandler != null) {\n                hooks.deprecationHandler(null, msg);\n            }\n            if (firstTime) {\n                var args = [];\n                var arg;\n                for (var i = 0; i < arguments.length; i++) {\n                    arg = '';\n                    if (typeof arguments[i] === 'object') {\n                        arg += '\\n[' + i + '] ';\n                        for (var key in arguments[0]) {\n                            arg += key + ': ' + arguments[0][key] + ', ';\n                        }\n                        arg = arg.slice(0, -2); // Remove trailing comma and space\n                    } else {\n                        arg = arguments[i];\n                    }\n                    args.push(arg);\n                }\n                warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n                firstTime = false;\n            }\n            return fn.apply(this, arguments);\n        }, fn);\n    }\n\n    var deprecations = {};\n\n    function deprecateSimple(name, msg) {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(name, msg);\n        }\n        if (!deprecations[name]) {\n            warn(msg);\n            deprecations[name] = true;\n        }\n    }\n\n    hooks.suppressDeprecationWarnings = false;\n    hooks.deprecationHandler = null;\n\n    function isFunction(input) {\n        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n    }\n\n    function set (config) {\n        var prop, i;\n        for (i in config) {\n            prop = config[i];\n            if (isFunction(prop)) {\n                this[i] = prop;\n            } else {\n                this['_' + i] = prop;\n            }\n        }\n        this._config = config;\n        // Lenient ordinal parsing accepts just a number in addition to\n        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n        // TODO: Remove \"ordinalParse\" fallback in next major release.\n        this._dayOfMonthOrdinalParseLenient = new RegExp(\n            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n                '|' + (/\\d{1,2}/).source);\n    }\n\n    function mergeConfigs(parentConfig, childConfig) {\n        var res = extend({}, parentConfig), prop;\n        for (prop in childConfig) {\n            if (hasOwnProp(childConfig, prop)) {\n                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                    res[prop] = {};\n                    extend(res[prop], parentConfig[prop]);\n                    extend(res[prop], childConfig[prop]);\n                } else if (childConfig[prop] != null) {\n                    res[prop] = childConfig[prop];\n                } else {\n                    delete res[prop];\n                }\n            }\n        }\n        for (prop in parentConfig) {\n            if (hasOwnProp(parentConfig, prop) &&\n                    !hasOwnProp(childConfig, prop) &&\n                    isObject(parentConfig[prop])) {\n                // make sure changes to properties don't modify parent config\n                res[prop] = extend({}, res[prop]);\n            }\n        }\n        return res;\n    }\n\n    function Locale(config) {\n        if (config != null) {\n            this.set(config);\n        }\n    }\n\n    var keys;\n\n    if (Object.keys) {\n        keys = Object.keys;\n    } else {\n        keys = function (obj) {\n            var i, res = [];\n            for (i in obj) {\n                if (hasOwnProp(obj, i)) {\n                    res.push(i);\n                }\n            }\n            return res;\n        };\n    }\n\n    var defaultCalendar = {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    };\n\n    function calendar (key, mom, now) {\n        var output = this._calendar[key] || this._calendar['sameElse'];\n        return isFunction(output) ? output.call(mom, now) : output;\n    }\n\n    var defaultLongDateFormat = {\n        LTS  : 'h:mm:ss A',\n        LT   : 'h:mm A',\n        L    : 'MM/DD/YYYY',\n        LL   : 'MMMM D, YYYY',\n        LLL  : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    };\n\n    function longDateFormat (key) {\n        var format = this._longDateFormat[key],\n            formatUpper = this._longDateFormat[key.toUpperCase()];\n\n        if (format || !formatUpper) {\n            return format;\n        }\n\n        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n            return val.slice(1);\n        });\n\n        return this._longDateFormat[key];\n    }\n\n    var defaultInvalidDate = 'Invalid date';\n\n    function invalidDate () {\n        return this._invalidDate;\n    }\n\n    var defaultOrdinal = '%d';\n    var defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\n    function ordinal (number) {\n        return this._ordinal.replace('%d', number);\n    }\n\n    var defaultRelativeTime = {\n        future : 'in %s',\n        past   : '%s ago',\n        s  : 'a few seconds',\n        ss : '%d seconds',\n        m  : 'a minute',\n        mm : '%d minutes',\n        h  : 'an hour',\n        hh : '%d hours',\n        d  : 'a day',\n        dd : '%d days',\n        M  : 'a month',\n        MM : '%d months',\n        y  : 'a year',\n        yy : '%d years'\n    };\n\n    function relativeTime (number, withoutSuffix, string, isFuture) {\n        var output = this._relativeTime[string];\n        return (isFunction(output)) ?\n            output(number, withoutSuffix, string, isFuture) :\n            output.replace(/%d/i, number);\n    }\n\n    function pastFuture (diff, output) {\n        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n        return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n    }\n\n    var aliases = {};\n\n    function addUnitAlias (unit, shorthand) {\n        var lowerCase = unit.toLowerCase();\n        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n    }\n\n    function normalizeUnits(units) {\n        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n    }\n\n    function normalizeObjectUnits(inputObject) {\n        var normalizedInput = {},\n            normalizedProp,\n            prop;\n\n        for (prop in inputObject) {\n            if (hasOwnProp(inputObject, prop)) {\n                normalizedProp = normalizeUnits(prop);\n                if (normalizedProp) {\n                    normalizedInput[normalizedProp] = inputObject[prop];\n                }\n            }\n        }\n\n        return normalizedInput;\n    }\n\n    var priorities = {};\n\n    function addUnitPriority(unit, priority) {\n        priorities[unit] = priority;\n    }\n\n    function getPrioritizedUnits(unitsObj) {\n        var units = [];\n        for (var u in unitsObj) {\n            units.push({unit: u, priority: priorities[u]});\n        }\n        units.sort(function (a, b) {\n            return a.priority - b.priority;\n        });\n        return units;\n    }\n\n    function zeroFill(number, targetLength, forceSign) {\n        var absNumber = '' + Math.abs(number),\n            zerosToFill = targetLength - absNumber.length,\n            sign = number >= 0;\n        return (sign ? (forceSign ? '+' : '') : '-') +\n            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n    }\n\n    var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\n    var localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\n    var formatFunctions = {};\n\n    var formatTokenFunctions = {};\n\n    // token:    'M'\n    // padded:   ['MM', 2]\n    // ordinal:  'Mo'\n    // callback: function () { this.month() + 1 }\n    function addFormatToken (token, padded, ordinal, callback) {\n        var func = callback;\n        if (typeof callback === 'string') {\n            func = function () {\n                return this[callback]();\n            };\n        }\n        if (token) {\n            formatTokenFunctions[token] = func;\n        }\n        if (padded) {\n            formatTokenFunctions[padded[0]] = function () {\n                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n            };\n        }\n        if (ordinal) {\n            formatTokenFunctions[ordinal] = function () {\n                return this.localeData().ordinal(func.apply(this, arguments), token);\n            };\n        }\n    }\n\n    function removeFormattingTokens(input) {\n        if (input.match(/\\[[\\s\\S]/)) {\n            return input.replace(/^\\[|\\]$/g, '');\n        }\n        return input.replace(/\\\\/g, '');\n    }\n\n    function makeFormatFunction(format) {\n        var array = format.match(formattingTokens), i, length;\n\n        for (i = 0, length = array.length; i < length; i++) {\n            if (formatTokenFunctions[array[i]]) {\n                array[i] = formatTokenFunctions[array[i]];\n            } else {\n                array[i] = removeFormattingTokens(array[i]);\n            }\n        }\n\n        return function (mom) {\n            var output = '', i;\n            for (i = 0; i < length; i++) {\n                output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n            }\n            return output;\n        };\n    }\n\n    // format date using native date object\n    function formatMoment(m, format) {\n        if (!m.isValid()) {\n            return m.localeData().invalidDate();\n        }\n\n        format = expandFormat(format, m.localeData());\n        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n        return formatFunctions[format](m);\n    }\n\n    function expandFormat(format, locale) {\n        var i = 5;\n\n        function replaceLongDateFormatTokens(input) {\n            return locale.longDateFormat(input) || input;\n        }\n\n        localFormattingTokens.lastIndex = 0;\n        while (i >= 0 && localFormattingTokens.test(format)) {\n            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n            localFormattingTokens.lastIndex = 0;\n            i -= 1;\n        }\n\n        return format;\n    }\n\n    var match1         = /\\d/;            //       0 - 9\n    var match2         = /\\d\\d/;          //      00 - 99\n    var match3         = /\\d{3}/;         //     000 - 999\n    var match4         = /\\d{4}/;         //    0000 - 9999\n    var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\n    var match1to2      = /\\d\\d?/;         //       0 - 99\n    var match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\n    var match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\n    var match1to3      = /\\d{1,3}/;       //       0 - 999\n    var match1to4      = /\\d{1,4}/;       //       0 - 9999\n    var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\n    var matchUnsigned  = /\\d+/;           //       0 - inf\n    var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\n    var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n    var matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\n    var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n    // any word (or two) characters or numbers including two/three word month in arabic.\n    // includes scottish gaelic two word and hyphenated months\n    var matchWord = /[0-9]{0,256}['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFF07\\uFF10-\\uFFEF]{1,256}|[\\u0600-\\u06FF\\/]{1,256}(\\s*?[\\u0600-\\u06FF]{1,256}){1,2}/i;\n\n    var regexes = {};\n\n    function addRegexToken (token, regex, strictRegex) {\n        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n            return (isStrict && strictRegex) ? strictRegex : regex;\n        };\n    }\n\n    function getParseRegexForToken (token, config) {\n        if (!hasOwnProp(regexes, token)) {\n            return new RegExp(unescapeFormat(token));\n        }\n\n        return regexes[token](config._strict, config._locale);\n    }\n\n    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\n    function unescapeFormat(s) {\n        return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n            return p1 || p2 || p3 || p4;\n        }));\n    }\n\n    function regexEscape(s) {\n        return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n    }\n\n    var tokens = {};\n\n    function addParseToken (token, callback) {\n        var i, func = callback;\n        if (typeof token === 'string') {\n            token = [token];\n        }\n        if (isNumber(callback)) {\n            func = function (input, array) {\n                array[callback] = toInt(input);\n            };\n        }\n        for (i = 0; i < token.length; i++) {\n            tokens[token[i]] = func;\n        }\n    }\n\n    function addWeekParseToken (token, callback) {\n        addParseToken(token, function (input, array, config, token) {\n            config._w = config._w || {};\n            callback(input, config._w, config, token);\n        });\n    }\n\n    function addTimeToArrayFromToken(token, input, config) {\n        if (input != null && hasOwnProp(tokens, token)) {\n            tokens[token](input, config._a, config, token);\n        }\n    }\n\n    var YEAR = 0;\n    var MONTH = 1;\n    var DATE = 2;\n    var HOUR = 3;\n    var MINUTE = 4;\n    var SECOND = 5;\n    var MILLISECOND = 6;\n    var WEEK = 7;\n    var WEEKDAY = 8;\n\n    // FORMATTING\n\n    addFormatToken('Y', 0, 0, function () {\n        var y = this.year();\n        return y <= 9999 ? '' + y : '+' + y;\n    });\n\n    addFormatToken(0, ['YY', 2], 0, function () {\n        return this.year() % 100;\n    });\n\n    addFormatToken(0, ['YYYY',   4],       0, 'year');\n    addFormatToken(0, ['YYYYY',  5],       0, 'year');\n    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n    // ALIASES\n\n    addUnitAlias('year', 'y');\n\n    // PRIORITIES\n\n    addUnitPriority('year', 1);\n\n    // PARSING\n\n    addRegexToken('Y',      matchSigned);\n    addRegexToken('YY',     match1to2, match2);\n    addRegexToken('YYYY',   match1to4, match4);\n    addRegexToken('YYYYY',  match1to6, match6);\n    addRegexToken('YYYYYY', match1to6, match6);\n\n    addParseToken(['YYYYY', 'YYYYYY'], YEAR);\n    addParseToken('YYYY', function (input, array) {\n        array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n    });\n    addParseToken('YY', function (input, array) {\n        array[YEAR] = hooks.parseTwoDigitYear(input);\n    });\n    addParseToken('Y', function (input, array) {\n        array[YEAR] = parseInt(input, 10);\n    });\n\n    // HELPERS\n\n    function daysInYear(year) {\n        return isLeapYear(year) ? 366 : 365;\n    }\n\n    function isLeapYear(year) {\n        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n    }\n\n    // HOOKS\n\n    hooks.parseTwoDigitYear = function (input) {\n        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n    };\n\n    // MOMENTS\n\n    var getSetYear = makeGetSet('FullYear', true);\n\n    function getIsLeapYear () {\n        return isLeapYear(this.year());\n    }\n\n    function makeGetSet (unit, keepTime) {\n        return function (value) {\n            if (value != null) {\n                set$1(this, unit, value);\n                hooks.updateOffset(this, keepTime);\n                return this;\n            } else {\n                return get(this, unit);\n            }\n        };\n    }\n\n    function get (mom, unit) {\n        return mom.isValid() ?\n            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n    }\n\n    function set$1 (mom, unit, value) {\n        if (mom.isValid() && !isNaN(value)) {\n            if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {\n                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));\n            }\n            else {\n                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function stringGet (units) {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units]();\n        }\n        return this;\n    }\n\n\n    function stringSet (units, value) {\n        if (typeof units === 'object') {\n            units = normalizeObjectUnits(units);\n            var prioritized = getPrioritizedUnits(units);\n            for (var i = 0; i < prioritized.length; i++) {\n                this[prioritized[i].unit](units[prioritized[i].unit]);\n            }\n        } else {\n            units = normalizeUnits(units);\n            if (isFunction(this[units])) {\n                return this[units](value);\n            }\n        }\n        return this;\n    }\n\n    function mod(n, x) {\n        return ((n % x) + x) % x;\n    }\n\n    var indexOf;\n\n    if (Array.prototype.indexOf) {\n        indexOf = Array.prototype.indexOf;\n    } else {\n        indexOf = function (o) {\n            // I know\n            var i;\n            for (i = 0; i < this.length; ++i) {\n                if (this[i] === o) {\n                    return i;\n                }\n            }\n            return -1;\n        };\n    }\n\n    function daysInMonth(year, month) {\n        if (isNaN(year) || isNaN(month)) {\n            return NaN;\n        }\n        var modMonth = mod(month, 12);\n        year += (month - modMonth) / 12;\n        return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);\n    }\n\n    // FORMATTING\n\n    addFormatToken('M', ['MM', 2], 'Mo', function () {\n        return this.month() + 1;\n    });\n\n    addFormatToken('MMM', 0, 0, function (format) {\n        return this.localeData().monthsShort(this, format);\n    });\n\n    addFormatToken('MMMM', 0, 0, function (format) {\n        return this.localeData().months(this, format);\n    });\n\n    // ALIASES\n\n    addUnitAlias('month', 'M');\n\n    // PRIORITY\n\n    addUnitPriority('month', 8);\n\n    // PARSING\n\n    addRegexToken('M',    match1to2);\n    addRegexToken('MM',   match1to2, match2);\n    addRegexToken('MMM',  function (isStrict, locale) {\n        return locale.monthsShortRegex(isStrict);\n    });\n    addRegexToken('MMMM', function (isStrict, locale) {\n        return locale.monthsRegex(isStrict);\n    });\n\n    addParseToken(['M', 'MM'], function (input, array) {\n        array[MONTH] = toInt(input) - 1;\n    });\n\n    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n        var month = config._locale.monthsParse(input, token, config._strict);\n        // if we didn't find a month name, mark the date as invalid.\n        if (month != null) {\n            array[MONTH] = month;\n        } else {\n            getParsingFlags(config).invalidMonth = input;\n        }\n    });\n\n    // LOCALES\n\n    var MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\n    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\n    function localeMonths (m, format) {\n        if (!m) {\n            return isArray(this._months) ? this._months :\n                this._months['standalone'];\n        }\n        return isArray(this._months) ? this._months[m.month()] :\n            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n    }\n\n    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\n    function localeMonthsShort (m, format) {\n        if (!m) {\n            return isArray(this._monthsShort) ? this._monthsShort :\n                this._monthsShort['standalone'];\n        }\n        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n    }\n\n    function handleStrictParse(monthName, format, strict) {\n        var i, ii, mom, llc = monthName.toLocaleLowerCase();\n        if (!this._monthsParse) {\n            // this is not used\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n            for (i = 0; i < 12; ++i) {\n                mom = createUTC([2000, i]);\n                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n            }\n        }\n\n        if (strict) {\n            if (format === 'MMM') {\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._longMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        } else {\n            if (format === 'MMM') {\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._longMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._longMonthsParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        }\n    }\n\n    function localeMonthsParse (monthName, format, strict) {\n        var i, mom, regex;\n\n        if (this._monthsParseExact) {\n            return handleStrictParse.call(this, monthName, format, strict);\n        }\n\n        if (!this._monthsParse) {\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n        }\n\n        // TODO: add sorting\n        // Sorting makes sure if one month (or abbr) is a prefix of another\n        // see sorting in computeMonthsParse\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, i]);\n            if (strict && !this._longMonthsParse[i]) {\n                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n            }\n            if (!strict && !this._monthsParse[i]) {\n                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (!strict && this._monthsParse[i].test(monthName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function setMonth (mom, value) {\n        var dayOfMonth;\n\n        if (!mom.isValid()) {\n            // No op\n            return mom;\n        }\n\n        if (typeof value === 'string') {\n            if (/^\\d+$/.test(value)) {\n                value = toInt(value);\n            } else {\n                value = mom.localeData().monthsParse(value);\n                // TODO: Another silent failure?\n                if (!isNumber(value)) {\n                    return mom;\n                }\n            }\n        }\n\n        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n        return mom;\n    }\n\n    function getSetMonth (value) {\n        if (value != null) {\n            setMonth(this, value);\n            hooks.updateOffset(this, true);\n            return this;\n        } else {\n            return get(this, 'Month');\n        }\n    }\n\n    function getDaysInMonth () {\n        return daysInMonth(this.year(), this.month());\n    }\n\n    var defaultMonthsShortRegex = matchWord;\n    function monthsShortRegex (isStrict) {\n        if (this._monthsParseExact) {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                computeMonthsParse.call(this);\n            }\n            if (isStrict) {\n                return this._monthsShortStrictRegex;\n            } else {\n                return this._monthsShortRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_monthsShortRegex')) {\n                this._monthsShortRegex = defaultMonthsShortRegex;\n            }\n            return this._monthsShortStrictRegex && isStrict ?\n                this._monthsShortStrictRegex : this._monthsShortRegex;\n        }\n    }\n\n    var defaultMonthsRegex = matchWord;\n    function monthsRegex (isStrict) {\n        if (this._monthsParseExact) {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                computeMonthsParse.call(this);\n            }\n            if (isStrict) {\n                return this._monthsStrictRegex;\n            } else {\n                return this._monthsRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                this._monthsRegex = defaultMonthsRegex;\n            }\n            return this._monthsStrictRegex && isStrict ?\n                this._monthsStrictRegex : this._monthsRegex;\n        }\n    }\n\n    function computeMonthsParse () {\n        function cmpLenRev(a, b) {\n            return b.length - a.length;\n        }\n\n        var shortPieces = [], longPieces = [], mixedPieces = [],\n            i, mom;\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, i]);\n            shortPieces.push(this.monthsShort(mom, ''));\n            longPieces.push(this.months(mom, ''));\n            mixedPieces.push(this.months(mom, ''));\n            mixedPieces.push(this.monthsShort(mom, ''));\n        }\n        // Sorting makes sure if one month (or abbr) is a prefix of another it\n        // will match the longer piece.\n        shortPieces.sort(cmpLenRev);\n        longPieces.sort(cmpLenRev);\n        mixedPieces.sort(cmpLenRev);\n        for (i = 0; i < 12; i++) {\n            shortPieces[i] = regexEscape(shortPieces[i]);\n            longPieces[i] = regexEscape(longPieces[i]);\n        }\n        for (i = 0; i < 24; i++) {\n            mixedPieces[i] = regexEscape(mixedPieces[i]);\n        }\n\n        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n        this._monthsShortRegex = this._monthsRegex;\n        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    }\n\n    function createDate (y, m, d, h, M, s, ms) {\n        // can't just apply() to create a date:\n        // https://stackoverflow.com/q/181348\n        var date;\n        // the date constructor remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            date = new Date(y + 400, m, d, h, M, s, ms);\n            if (isFinite(date.getFullYear())) {\n                date.setFullYear(y);\n            }\n        } else {\n            date = new Date(y, m, d, h, M, s, ms);\n        }\n\n        return date;\n    }\n\n    function createUTCDate (y) {\n        var date;\n        // the Date.UTC function remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            var args = Array.prototype.slice.call(arguments);\n            // preserve leap years using a full 400 year cycle, then reset\n            args[0] = y + 400;\n            date = new Date(Date.UTC.apply(null, args));\n            if (isFinite(date.getUTCFullYear())) {\n                date.setUTCFullYear(y);\n            }\n        } else {\n            date = new Date(Date.UTC.apply(null, arguments));\n        }\n\n        return date;\n    }\n\n    // start-of-first-week - start-of-year\n    function firstWeekOffset(year, dow, doy) {\n        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n            fwd = 7 + dow - doy,\n            // first-week day local weekday -- which local weekday is fwd\n            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n        return -fwdlw + fwd - 1;\n    }\n\n    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\n    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n        var localWeekday = (7 + weekday - dow) % 7,\n            weekOffset = firstWeekOffset(year, dow, doy),\n            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n            resYear, resDayOfYear;\n\n        if (dayOfYear <= 0) {\n            resYear = year - 1;\n            resDayOfYear = daysInYear(resYear) + dayOfYear;\n        } else if (dayOfYear > daysInYear(year)) {\n            resYear = year + 1;\n            resDayOfYear = dayOfYear - daysInYear(year);\n        } else {\n            resYear = year;\n            resDayOfYear = dayOfYear;\n        }\n\n        return {\n            year: resYear,\n            dayOfYear: resDayOfYear\n        };\n    }\n\n    function weekOfYear(mom, dow, doy) {\n        var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n            resWeek, resYear;\n\n        if (week < 1) {\n            resYear = mom.year() - 1;\n            resWeek = week + weeksInYear(resYear, dow, doy);\n        } else if (week > weeksInYear(mom.year(), dow, doy)) {\n            resWeek = week - weeksInYear(mom.year(), dow, doy);\n            resYear = mom.year() + 1;\n        } else {\n            resYear = mom.year();\n            resWeek = week;\n        }\n\n        return {\n            week: resWeek,\n            year: resYear\n        };\n    }\n\n    function weeksInYear(year, dow, doy) {\n        var weekOffset = firstWeekOffset(year, dow, doy),\n            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n    }\n\n    // FORMATTING\n\n    addFormatToken('w', ['ww', 2], 'wo', 'week');\n    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n    // ALIASES\n\n    addUnitAlias('week', 'w');\n    addUnitAlias('isoWeek', 'W');\n\n    // PRIORITIES\n\n    addUnitPriority('week', 5);\n    addUnitPriority('isoWeek', 5);\n\n    // PARSING\n\n    addRegexToken('w',  match1to2);\n    addRegexToken('ww', match1to2, match2);\n    addRegexToken('W',  match1to2);\n    addRegexToken('WW', match1to2, match2);\n\n    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n        week[token.substr(0, 1)] = toInt(input);\n    });\n\n    // HELPERS\n\n    // LOCALES\n\n    function localeWeek (mom) {\n        return weekOfYear(mom, this._week.dow, this._week.doy).week;\n    }\n\n    var defaultLocaleWeek = {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 6th is the first week of the year.\n    };\n\n    function localeFirstDayOfWeek () {\n        return this._week.dow;\n    }\n\n    function localeFirstDayOfYear () {\n        return this._week.doy;\n    }\n\n    // MOMENTS\n\n    function getSetWeek (input) {\n        var week = this.localeData().week(this);\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    function getSetISOWeek (input) {\n        var week = weekOfYear(this, 1, 4).week;\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    // FORMATTING\n\n    addFormatToken('d', 0, 'do', 'day');\n\n    addFormatToken('dd', 0, 0, function (format) {\n        return this.localeData().weekdaysMin(this, format);\n    });\n\n    addFormatToken('ddd', 0, 0, function (format) {\n        return this.localeData().weekdaysShort(this, format);\n    });\n\n    addFormatToken('dddd', 0, 0, function (format) {\n        return this.localeData().weekdays(this, format);\n    });\n\n    addFormatToken('e', 0, 0, 'weekday');\n    addFormatToken('E', 0, 0, 'isoWeekday');\n\n    // ALIASES\n\n    addUnitAlias('day', 'd');\n    addUnitAlias('weekday', 'e');\n    addUnitAlias('isoWeekday', 'E');\n\n    // PRIORITY\n    addUnitPriority('day', 11);\n    addUnitPriority('weekday', 11);\n    addUnitPriority('isoWeekday', 11);\n\n    // PARSING\n\n    addRegexToken('d',    match1to2);\n    addRegexToken('e',    match1to2);\n    addRegexToken('E',    match1to2);\n    addRegexToken('dd',   function (isStrict, locale) {\n        return locale.weekdaysMinRegex(isStrict);\n    });\n    addRegexToken('ddd',   function (isStrict, locale) {\n        return locale.weekdaysShortRegex(isStrict);\n    });\n    addRegexToken('dddd',   function (isStrict, locale) {\n        return locale.weekdaysRegex(isStrict);\n    });\n\n    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n        var weekday = config._locale.weekdaysParse(input, token, config._strict);\n        // if we didn't get a weekday name, mark the date as invalid\n        if (weekday != null) {\n            week.d = weekday;\n        } else {\n            getParsingFlags(config).invalidWeekday = input;\n        }\n    });\n\n    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n        week[token] = toInt(input);\n    });\n\n    // HELPERS\n\n    function parseWeekday(input, locale) {\n        if (typeof input !== 'string') {\n            return input;\n        }\n\n        if (!isNaN(input)) {\n            return parseInt(input, 10);\n        }\n\n        input = locale.weekdaysParse(input);\n        if (typeof input === 'number') {\n            return input;\n        }\n\n        return null;\n    }\n\n    function parseIsoWeekday(input, locale) {\n        if (typeof input === 'string') {\n            return locale.weekdaysParse(input) % 7 || 7;\n        }\n        return isNaN(input) ? null : input;\n    }\n\n    // LOCALES\n    function shiftWeekdays (ws, n) {\n        return ws.slice(n, 7).concat(ws.slice(0, n));\n    }\n\n    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\n    function localeWeekdays (m, format) {\n        var weekdays = isArray(this._weekdays) ? this._weekdays :\n            this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone'];\n        return (m === true) ? shiftWeekdays(weekdays, this._week.dow)\n            : (m) ? weekdays[m.day()] : weekdays;\n    }\n\n    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\n    function localeWeekdaysShort (m) {\n        return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow)\n            : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n    }\n\n    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\n    function localeWeekdaysMin (m) {\n        return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow)\n            : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n    }\n\n    function handleStrictParse$1(weekdayName, format, strict) {\n        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n            this._shortWeekdaysParse = [];\n            this._minWeekdaysParse = [];\n\n            for (i = 0; i < 7; ++i) {\n                mom = createUTC([2000, 1]).day(i);\n                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n            }\n        }\n\n        if (strict) {\n            if (format === 'dddd') {\n                ii = indexOf.call(this._weekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else if (format === 'ddd') {\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        } else {\n            if (format === 'dddd') {\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else if (format === 'ddd') {\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        }\n    }\n\n    function localeWeekdaysParse (weekdayName, format, strict) {\n        var i, mom, regex;\n\n        if (this._weekdaysParseExact) {\n            return handleStrictParse$1.call(this, weekdayName, format, strict);\n        }\n\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n            this._minWeekdaysParse = [];\n            this._shortWeekdaysParse = [];\n            this._fullWeekdaysParse = [];\n        }\n\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n\n            mom = createUTC([2000, 1]).day(i);\n            if (strict && !this._fullWeekdaysParse[i]) {\n                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\\\.?') + '$', 'i');\n                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\\\.?') + '$', 'i');\n                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\\\.?') + '$', 'i');\n            }\n            if (!this._weekdaysParse[i]) {\n                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function getSetDayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n        if (input != null) {\n            input = parseWeekday(input, this.localeData());\n            return this.add(input - day, 'd');\n        } else {\n            return day;\n        }\n    }\n\n    function getSetLocaleDayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n        return input == null ? weekday : this.add(input - weekday, 'd');\n    }\n\n    function getSetISODayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n\n        // behaves the same as moment#day except\n        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n        // as a setter, sunday should belong to the previous week.\n\n        if (input != null) {\n            var weekday = parseIsoWeekday(input, this.localeData());\n            return this.day(this.day() % 7 ? weekday : weekday - 7);\n        } else {\n            return this.day() || 7;\n        }\n    }\n\n    var defaultWeekdaysRegex = matchWord;\n    function weekdaysRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysStrictRegex;\n            } else {\n                return this._weekdaysRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                this._weekdaysRegex = defaultWeekdaysRegex;\n            }\n            return this._weekdaysStrictRegex && isStrict ?\n                this._weekdaysStrictRegex : this._weekdaysRegex;\n        }\n    }\n\n    var defaultWeekdaysShortRegex = matchWord;\n    function weekdaysShortRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysShortStrictRegex;\n            } else {\n                return this._weekdaysShortRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n                this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n            }\n            return this._weekdaysShortStrictRegex && isStrict ?\n                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n        }\n    }\n\n    var defaultWeekdaysMinRegex = matchWord;\n    function weekdaysMinRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysMinStrictRegex;\n            } else {\n                return this._weekdaysMinRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n                this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n            }\n            return this._weekdaysMinStrictRegex && isStrict ?\n                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n        }\n    }\n\n\n    function computeWeekdaysParse () {\n        function cmpLenRev(a, b) {\n            return b.length - a.length;\n        }\n\n        var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n            i, mom, minp, shortp, longp;\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, 1]).day(i);\n            minp = this.weekdaysMin(mom, '');\n            shortp = this.weekdaysShort(mom, '');\n            longp = this.weekdays(mom, '');\n            minPieces.push(minp);\n            shortPieces.push(shortp);\n            longPieces.push(longp);\n            mixedPieces.push(minp);\n            mixedPieces.push(shortp);\n            mixedPieces.push(longp);\n        }\n        // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n        // will match the longer piece.\n        minPieces.sort(cmpLenRev);\n        shortPieces.sort(cmpLenRev);\n        longPieces.sort(cmpLenRev);\n        mixedPieces.sort(cmpLenRev);\n        for (i = 0; i < 7; i++) {\n            shortPieces[i] = regexEscape(shortPieces[i]);\n            longPieces[i] = regexEscape(longPieces[i]);\n            mixedPieces[i] = regexEscape(mixedPieces[i]);\n        }\n\n        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n        this._weekdaysShortRegex = this._weekdaysRegex;\n        this._weekdaysMinRegex = this._weekdaysRegex;\n\n        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n    }\n\n    // FORMATTING\n\n    function hFormat() {\n        return this.hours() % 12 || 12;\n    }\n\n    function kFormat() {\n        return this.hours() || 24;\n    }\n\n    addFormatToken('H', ['HH', 2], 0, 'hour');\n    addFormatToken('h', ['hh', 2], 0, hFormat);\n    addFormatToken('k', ['kk', 2], 0, kFormat);\n\n    addFormatToken('hmm', 0, 0, function () {\n        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n    });\n\n    addFormatToken('hmmss', 0, 0, function () {\n        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n            zeroFill(this.seconds(), 2);\n    });\n\n    addFormatToken('Hmm', 0, 0, function () {\n        return '' + this.hours() + zeroFill(this.minutes(), 2);\n    });\n\n    addFormatToken('Hmmss', 0, 0, function () {\n        return '' + this.hours() + zeroFill(this.minutes(), 2) +\n            zeroFill(this.seconds(), 2);\n    });\n\n    function meridiem (token, lowercase) {\n        addFormatToken(token, 0, 0, function () {\n            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n        });\n    }\n\n    meridiem('a', true);\n    meridiem('A', false);\n\n    // ALIASES\n\n    addUnitAlias('hour', 'h');\n\n    // PRIORITY\n    addUnitPriority('hour', 13);\n\n    // PARSING\n\n    function matchMeridiem (isStrict, locale) {\n        return locale._meridiemParse;\n    }\n\n    addRegexToken('a',  matchMeridiem);\n    addRegexToken('A',  matchMeridiem);\n    addRegexToken('H',  match1to2);\n    addRegexToken('h',  match1to2);\n    addRegexToken('k',  match1to2);\n    addRegexToken('HH', match1to2, match2);\n    addRegexToken('hh', match1to2, match2);\n    addRegexToken('kk', match1to2, match2);\n\n    addRegexToken('hmm', match3to4);\n    addRegexToken('hmmss', match5to6);\n    addRegexToken('Hmm', match3to4);\n    addRegexToken('Hmmss', match5to6);\n\n    addParseToken(['H', 'HH'], HOUR);\n    addParseToken(['k', 'kk'], function (input, array, config) {\n        var kInput = toInt(input);\n        array[HOUR] = kInput === 24 ? 0 : kInput;\n    });\n    addParseToken(['a', 'A'], function (input, array, config) {\n        config._isPm = config._locale.isPM(input);\n        config._meridiem = input;\n    });\n    addParseToken(['h', 'hh'], function (input, array, config) {\n        array[HOUR] = toInt(input);\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('hmm', function (input, array, config) {\n        var pos = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos));\n        array[MINUTE] = toInt(input.substr(pos));\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('hmmss', function (input, array, config) {\n        var pos1 = input.length - 4;\n        var pos2 = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos1));\n        array[MINUTE] = toInt(input.substr(pos1, 2));\n        array[SECOND] = toInt(input.substr(pos2));\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('Hmm', function (input, array, config) {\n        var pos = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos));\n        array[MINUTE] = toInt(input.substr(pos));\n    });\n    addParseToken('Hmmss', function (input, array, config) {\n        var pos1 = input.length - 4;\n        var pos2 = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos1));\n        array[MINUTE] = toInt(input.substr(pos1, 2));\n        array[SECOND] = toInt(input.substr(pos2));\n    });\n\n    // LOCALES\n\n    function localeIsPM (input) {\n        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n        // Using charAt should be more compatible.\n        return ((input + '').toLowerCase().charAt(0) === 'p');\n    }\n\n    var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\n    function localeMeridiem (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'pm' : 'PM';\n        } else {\n            return isLower ? 'am' : 'AM';\n        }\n    }\n\n\n    // MOMENTS\n\n    // Setting the hour should keep the time, because the user explicitly\n    // specified which hour they want. So trying to maintain the same hour (in\n    // a new timezone) makes sense. Adding/subtracting hours does not follow\n    // this rule.\n    var getSetHour = makeGetSet('Hours', true);\n\n    var baseConfig = {\n        calendar: defaultCalendar,\n        longDateFormat: defaultLongDateFormat,\n        invalidDate: defaultInvalidDate,\n        ordinal: defaultOrdinal,\n        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n        relativeTime: defaultRelativeTime,\n\n        months: defaultLocaleMonths,\n        monthsShort: defaultLocaleMonthsShort,\n\n        week: defaultLocaleWeek,\n\n        weekdays: defaultLocaleWeekdays,\n        weekdaysMin: defaultLocaleWeekdaysMin,\n        weekdaysShort: defaultLocaleWeekdaysShort,\n\n        meridiemParse: defaultLocaleMeridiemParse\n    };\n\n    // internal storage for locale config files\n    var locales = {};\n    var localeFamilies = {};\n    var globalLocale;\n\n    function normalizeLocale(key) {\n        return key ? key.toLowerCase().replace('_', '-') : key;\n    }\n\n    // pick the locale from the array\n    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\n    function chooseLocale(names) {\n        var i = 0, j, next, locale, split;\n\n        while (i < names.length) {\n            split = normalizeLocale(names[i]).split('-');\n            j = split.length;\n            next = normalizeLocale(names[i + 1]);\n            next = next ? next.split('-') : null;\n            while (j > 0) {\n                locale = loadLocale(split.slice(0, j).join('-'));\n                if (locale) {\n                    return locale;\n                }\n                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                    //the next array item is better than a shallower substring of this one\n                    break;\n                }\n                j--;\n            }\n            i++;\n        }\n        return globalLocale;\n    }\n\n    function loadLocale(name) {\n        var oldLocale = null;\n        // TODO: Find a better way to register and load all the locales in Node\n        if (!locales[name] && (typeof module !== 'undefined') &&\n                module && module.exports) {\n            try {\n                oldLocale = globalLocale._abbr;\n                var aliasedRequire = require;\n                !(function webpackMissingModule() { var e = new Error(\"Cannot find module 'undefined'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }());\n                getSetGlobalLocale(oldLocale);\n            } catch (e) {}\n        }\n        return locales[name];\n    }\n\n    // This function will load locale and then set the global locale.  If\n    // no arguments are passed in, it will simply return the current global\n    // locale key.\n    function getSetGlobalLocale (key, values) {\n        var data;\n        if (key) {\n            if (isUndefined(values)) {\n                data = getLocale(key);\n            }\n            else {\n                data = defineLocale(key, values);\n            }\n\n            if (data) {\n                // moment.duration._locale = moment._locale = data;\n                globalLocale = data;\n            }\n            else {\n                if ((typeof console !==  'undefined') && console.warn) {\n                    //warn user if arguments are passed but the locale could not be set\n                    console.warn('Locale ' + key +  ' not found. Did you forget to load it?');\n                }\n            }\n        }\n\n        return globalLocale._abbr;\n    }\n\n    function defineLocale (name, config) {\n        if (config !== null) {\n            var locale, parentConfig = baseConfig;\n            config.abbr = name;\n            if (locales[name] != null) {\n                deprecateSimple('defineLocaleOverride',\n                        'use moment.updateLocale(localeName, config) to change ' +\n                        'an existing locale. moment.defineLocale(localeName, ' +\n                        'config) should only be used for creating a new locale ' +\n                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n                parentConfig = locales[name]._config;\n            } else if (config.parentLocale != null) {\n                if (locales[config.parentLocale] != null) {\n                    parentConfig = locales[config.parentLocale]._config;\n                } else {\n                    locale = loadLocale(config.parentLocale);\n                    if (locale != null) {\n                        parentConfig = locale._config;\n                    } else {\n                        if (!localeFamilies[config.parentLocale]) {\n                            localeFamilies[config.parentLocale] = [];\n                        }\n                        localeFamilies[config.parentLocale].push({\n                            name: name,\n                            config: config\n                        });\n                        return null;\n                    }\n                }\n            }\n            locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n            if (localeFamilies[name]) {\n                localeFamilies[name].forEach(function (x) {\n                    defineLocale(x.name, x.config);\n                });\n            }\n\n            // backwards compat for now: also set the locale\n            // make sure we set the locale AFTER all child locales have been\n            // created, so we won't end up with the child locale set.\n            getSetGlobalLocale(name);\n\n\n            return locales[name];\n        } else {\n            // useful for testing\n            delete locales[name];\n            return null;\n        }\n    }\n\n    function updateLocale(name, config) {\n        if (config != null) {\n            var locale, tmpLocale, parentConfig = baseConfig;\n            // MERGE\n            tmpLocale = loadLocale(name);\n            if (tmpLocale != null) {\n                parentConfig = tmpLocale._config;\n            }\n            config = mergeConfigs(parentConfig, config);\n            locale = new Locale(config);\n            locale.parentLocale = locales[name];\n            locales[name] = locale;\n\n            // backwards compat for now: also set the locale\n            getSetGlobalLocale(name);\n        } else {\n            // pass null for config to unupdate, useful for tests\n            if (locales[name] != null) {\n                if (locales[name].parentLocale != null) {\n                    locales[name] = locales[name].parentLocale;\n                } else if (locales[name] != null) {\n                    delete locales[name];\n                }\n            }\n        }\n        return locales[name];\n    }\n\n    // returns locale data\n    function getLocale (key) {\n        var locale;\n\n        if (key && key._locale && key._locale._abbr) {\n            key = key._locale._abbr;\n        }\n\n        if (!key) {\n            return globalLocale;\n        }\n\n        if (!isArray(key)) {\n            //short-circuit everything else\n            locale = loadLocale(key);\n            if (locale) {\n                return locale;\n            }\n            key = [key];\n        }\n\n        return chooseLocale(key);\n    }\n\n    function listLocales() {\n        return keys(locales);\n    }\n\n    function checkOverflow (m) {\n        var overflow;\n        var a = m._a;\n\n        if (a && getParsingFlags(m).overflow === -2) {\n            overflow =\n                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n                -1;\n\n            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n                overflow = DATE;\n            }\n            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n                overflow = WEEK;\n            }\n            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n                overflow = WEEKDAY;\n            }\n\n            getParsingFlags(m).overflow = overflow;\n        }\n\n        return m;\n    }\n\n    // Pick the first defined of two or three arguments.\n    function defaults(a, b, c) {\n        if (a != null) {\n            return a;\n        }\n        if (b != null) {\n            return b;\n        }\n        return c;\n    }\n\n    function currentDateArray(config) {\n        // hooks is actually the exported moment object\n        var nowValue = new Date(hooks.now());\n        if (config._useUTC) {\n            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n        }\n        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n    }\n\n    // convert an array to a date.\n    // the array should mirror the parameters below\n    // note: all values past the year are optional and will default to the lowest possible value.\n    // [year, month, day , hour, minute, second, millisecond]\n    function configFromArray (config) {\n        var i, date, input = [], currentDate, expectedWeekday, yearToUse;\n\n        if (config._d) {\n            return;\n        }\n\n        currentDate = currentDateArray(config);\n\n        //compute day of the year from weeks and weekdays\n        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n            dayOfYearFromWeekInfo(config);\n        }\n\n        //if the day of the year is set, figure out what it is\n        if (config._dayOfYear != null) {\n            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n            if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n                getParsingFlags(config)._overflowDayOfYear = true;\n            }\n\n            date = createUTCDate(yearToUse, 0, config._dayOfYear);\n            config._a[MONTH] = date.getUTCMonth();\n            config._a[DATE] = date.getUTCDate();\n        }\n\n        // Default to current date.\n        // * if no year, month, day of month are given, default to today\n        // * if day of month is given, default month and year\n        // * if month is given, default only year\n        // * if year is given, don't default anything\n        for (i = 0; i < 3 && config._a[i] == null; ++i) {\n            config._a[i] = input[i] = currentDate[i];\n        }\n\n        // Zero out whatever was not defaulted, including time\n        for (; i < 7; i++) {\n            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n        }\n\n        // Check for 24:00:00.000\n        if (config._a[HOUR] === 24 &&\n                config._a[MINUTE] === 0 &&\n                config._a[SECOND] === 0 &&\n                config._a[MILLISECOND] === 0) {\n            config._nextDay = true;\n            config._a[HOUR] = 0;\n        }\n\n        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n        expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();\n\n        // Apply timezone offset from input. The actual utcOffset can be changed\n        // with parseZone.\n        if (config._tzm != null) {\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n        }\n\n        if (config._nextDay) {\n            config._a[HOUR] = 24;\n        }\n\n        // check for mismatching day of week\n        if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {\n            getParsingFlags(config).weekdayMismatch = true;\n        }\n    }\n\n    function dayOfYearFromWeekInfo(config) {\n        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n        w = config._w;\n        if (w.GG != null || w.W != null || w.E != null) {\n            dow = 1;\n            doy = 4;\n\n            // TODO: We need to take the current isoWeekYear, but that depends on\n            // how we interpret now (local, utc, fixed offset). So create\n            // a now version of current config (take local/utc/offset flags, and\n            // create now).\n            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n            week = defaults(w.W, 1);\n            weekday = defaults(w.E, 1);\n            if (weekday < 1 || weekday > 7) {\n                weekdayOverflow = true;\n            }\n        } else {\n            dow = config._locale._week.dow;\n            doy = config._locale._week.doy;\n\n            var curWeek = weekOfYear(createLocal(), dow, doy);\n\n            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n            // Default to current week.\n            week = defaults(w.w, curWeek.week);\n\n            if (w.d != null) {\n                // weekday -- low day numbers are considered next week\n                weekday = w.d;\n                if (weekday < 0 || weekday > 6) {\n                    weekdayOverflow = true;\n                }\n            } else if (w.e != null) {\n                // local weekday -- counting starts from beginning of week\n                weekday = w.e + dow;\n                if (w.e < 0 || w.e > 6) {\n                    weekdayOverflow = true;\n                }\n            } else {\n                // default to beginning of week\n                weekday = dow;\n            }\n        }\n        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n            getParsingFlags(config)._overflowWeeks = true;\n        } else if (weekdayOverflow != null) {\n            getParsingFlags(config)._overflowWeekday = true;\n        } else {\n            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n            config._a[YEAR] = temp.year;\n            config._dayOfYear = temp.dayOfYear;\n        }\n    }\n\n    // iso 8601 regex\n    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\n    var extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n    var basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\n    var tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\n    var isoDates = [\n        ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n        ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n        ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n        ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n        ['YYYY-DDD', /\\d{4}-\\d{3}/],\n        ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n        ['YYYYYYMMDD', /[+-]\\d{10}/],\n        ['YYYYMMDD', /\\d{8}/],\n        // YYYYMM is NOT allowed by the standard\n        ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n        ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n        ['YYYYDDD', /\\d{7}/]\n    ];\n\n    // iso time formats and regexes\n    var isoTimes = [\n        ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n        ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n        ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n        ['HH:mm', /\\d\\d:\\d\\d/],\n        ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n        ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n        ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n        ['HHmm', /\\d\\d\\d\\d/],\n        ['HH', /\\d\\d/]\n    ];\n\n    var aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n    // date from iso format\n    function configFromISO(config) {\n        var i, l,\n            string = config._i,\n            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n            allowTime, dateFormat, timeFormat, tzFormat;\n\n        if (match) {\n            getParsingFlags(config).iso = true;\n\n            for (i = 0, l = isoDates.length; i < l; i++) {\n                if (isoDates[i][1].exec(match[1])) {\n                    dateFormat = isoDates[i][0];\n                    allowTime = isoDates[i][2] !== false;\n                    break;\n                }\n            }\n            if (dateFormat == null) {\n                config._isValid = false;\n                return;\n            }\n            if (match[3]) {\n                for (i = 0, l = isoTimes.length; i < l; i++) {\n                    if (isoTimes[i][1].exec(match[3])) {\n                        // match[2] should be 'T' or space\n                        timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                        break;\n                    }\n                }\n                if (timeFormat == null) {\n                    config._isValid = false;\n                    return;\n                }\n            }\n            if (!allowTime && timeFormat != null) {\n                config._isValid = false;\n                return;\n            }\n            if (match[4]) {\n                if (tzRegex.exec(match[4])) {\n                    tzFormat = 'Z';\n                } else {\n                    config._isValid = false;\n                    return;\n                }\n            }\n            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n            configFromStringAndFormat(config);\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\n    var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d{1,2})\\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(\\d{2,4})\\s(\\d\\d):(\\d\\d)(?::(\\d\\d))?\\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\\d{4}))$/;\n\n    function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {\n        var result = [\n            untruncateYear(yearStr),\n            defaultLocaleMonthsShort.indexOf(monthStr),\n            parseInt(dayStr, 10),\n            parseInt(hourStr, 10),\n            parseInt(minuteStr, 10)\n        ];\n\n        if (secondStr) {\n            result.push(parseInt(secondStr, 10));\n        }\n\n        return result;\n    }\n\n    function untruncateYear(yearStr) {\n        var year = parseInt(yearStr, 10);\n        if (year <= 49) {\n            return 2000 + year;\n        } else if (year <= 999) {\n            return 1900 + year;\n        }\n        return year;\n    }\n\n    function preprocessRFC2822(s) {\n        // Remove comments and folding whitespace and replace multiple-spaces with a single space\n        return s.replace(/\\([^)]*\\)|[\\n\\t]/g, ' ').replace(/(\\s\\s+)/g, ' ').replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n    }\n\n    function checkWeekday(weekdayStr, parsedInput, config) {\n        if (weekdayStr) {\n            // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),\n                weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();\n            if (weekdayProvided !== weekdayActual) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return false;\n            }\n        }\n        return true;\n    }\n\n    var obsOffsets = {\n        UT: 0,\n        GMT: 0,\n        EDT: -4 * 60,\n        EST: -5 * 60,\n        CDT: -5 * 60,\n        CST: -6 * 60,\n        MDT: -6 * 60,\n        MST: -7 * 60,\n        PDT: -7 * 60,\n        PST: -8 * 60\n    };\n\n    function calculateOffset(obsOffset, militaryOffset, numOffset) {\n        if (obsOffset) {\n            return obsOffsets[obsOffset];\n        } else if (militaryOffset) {\n            // the only allowed military tz is Z\n            return 0;\n        } else {\n            var hm = parseInt(numOffset, 10);\n            var m = hm % 100, h = (hm - m) / 100;\n            return h * 60 + m;\n        }\n    }\n\n    // date and time from ref 2822 format\n    function configFromRFC2822(config) {\n        var match = rfc2822.exec(preprocessRFC2822(config._i));\n        if (match) {\n            var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);\n            if (!checkWeekday(match[1], parsedArray, config)) {\n                return;\n            }\n\n            config._a = parsedArray;\n            config._tzm = calculateOffset(match[8], match[9], match[10]);\n\n            config._d = createUTCDate.apply(null, config._a);\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n\n            getParsingFlags(config).rfc2822 = true;\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // date from iso format or fallback\n    function configFromString(config) {\n        var matched = aspNetJsonRegex.exec(config._i);\n\n        if (matched !== null) {\n            config._d = new Date(+matched[1]);\n            return;\n        }\n\n        configFromISO(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n        } else {\n            return;\n        }\n\n        configFromRFC2822(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n        } else {\n            return;\n        }\n\n        // Final attempt, use Input Fallback\n        hooks.createFromInputFallback(config);\n    }\n\n    hooks.createFromInputFallback = deprecate(\n        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n        'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n        'discouraged and will be removed in an upcoming major release. Please refer to ' +\n        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n        function (config) {\n            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n        }\n    );\n\n    // constant that refers to the ISO standard\n    hooks.ISO_8601 = function () {};\n\n    // constant that refers to the RFC 2822 form\n    hooks.RFC_2822 = function () {};\n\n    // date from string and format string\n    function configFromStringAndFormat(config) {\n        // TODO: Move this to another part of the creation flow to prevent circular deps\n        if (config._f === hooks.ISO_8601) {\n            configFromISO(config);\n            return;\n        }\n        if (config._f === hooks.RFC_2822) {\n            configFromRFC2822(config);\n            return;\n        }\n        config._a = [];\n        getParsingFlags(config).empty = true;\n\n        // This array is used to make a Date, either with `new Date` or `Date.UTC`\n        var string = '' + config._i,\n            i, parsedInput, tokens, token, skipped,\n            stringLength = string.length,\n            totalParsedInputLength = 0;\n\n        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n        for (i = 0; i < tokens.length; i++) {\n            token = tokens[i];\n            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n            // console.log('token', token, 'parsedInput', parsedInput,\n            //         'regex', getParseRegexForToken(token, config));\n            if (parsedInput) {\n                skipped = string.substr(0, string.indexOf(parsedInput));\n                if (skipped.length > 0) {\n                    getParsingFlags(config).unusedInput.push(skipped);\n                }\n                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n                totalParsedInputLength += parsedInput.length;\n            }\n            // don't parse if it's not a known token\n            if (formatTokenFunctions[token]) {\n                if (parsedInput) {\n                    getParsingFlags(config).empty = false;\n                }\n                else {\n                    getParsingFlags(config).unusedTokens.push(token);\n                }\n                addTimeToArrayFromToken(token, parsedInput, config);\n            }\n            else if (config._strict && !parsedInput) {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n        }\n\n        // add remaining unparsed input length to the string\n        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n        if (string.length > 0) {\n            getParsingFlags(config).unusedInput.push(string);\n        }\n\n        // clear _12h flag if hour is <= 12\n        if (config._a[HOUR] <= 12 &&\n            getParsingFlags(config).bigHour === true &&\n            config._a[HOUR] > 0) {\n            getParsingFlags(config).bigHour = undefined;\n        }\n\n        getParsingFlags(config).parsedDateParts = config._a.slice(0);\n        getParsingFlags(config).meridiem = config._meridiem;\n        // handle meridiem\n        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n        configFromArray(config);\n        checkOverflow(config);\n    }\n\n\n    function meridiemFixWrap (locale, hour, meridiem) {\n        var isPm;\n\n        if (meridiem == null) {\n            // nothing to do\n            return hour;\n        }\n        if (locale.meridiemHour != null) {\n            return locale.meridiemHour(hour, meridiem);\n        } else if (locale.isPM != null) {\n            // Fallback\n            isPm = locale.isPM(meridiem);\n            if (isPm && hour < 12) {\n                hour += 12;\n            }\n            if (!isPm && hour === 12) {\n                hour = 0;\n            }\n            return hour;\n        } else {\n            // this is not supposed to happen\n            return hour;\n        }\n    }\n\n    // date from string and array of format strings\n    function configFromStringAndArray(config) {\n        var tempConfig,\n            bestMoment,\n\n            scoreToBeat,\n            i,\n            currentScore;\n\n        if (config._f.length === 0) {\n            getParsingFlags(config).invalidFormat = true;\n            config._d = new Date(NaN);\n            return;\n        }\n\n        for (i = 0; i < config._f.length; i++) {\n            currentScore = 0;\n            tempConfig = copyConfig({}, config);\n            if (config._useUTC != null) {\n                tempConfig._useUTC = config._useUTC;\n            }\n            tempConfig._f = config._f[i];\n            configFromStringAndFormat(tempConfig);\n\n            if (!isValid(tempConfig)) {\n                continue;\n            }\n\n            // if there is any input that was not parsed add a penalty for that format\n            currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n            //or tokens\n            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n            getParsingFlags(tempConfig).score = currentScore;\n\n            if (scoreToBeat == null || currentScore < scoreToBeat) {\n                scoreToBeat = currentScore;\n                bestMoment = tempConfig;\n            }\n        }\n\n        extend(config, bestMoment || tempConfig);\n    }\n\n    function configFromObject(config) {\n        if (config._d) {\n            return;\n        }\n\n        var i = normalizeObjectUnits(config._i);\n        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n            return obj && parseInt(obj, 10);\n        });\n\n        configFromArray(config);\n    }\n\n    function createFromConfig (config) {\n        var res = new Moment(checkOverflow(prepareConfig(config)));\n        if (res._nextDay) {\n            // Adding is smart enough around DST\n            res.add(1, 'd');\n            res._nextDay = undefined;\n        }\n\n        return res;\n    }\n\n    function prepareConfig (config) {\n        var input = config._i,\n            format = config._f;\n\n        config._locale = config._locale || getLocale(config._l);\n\n        if (input === null || (format === undefined && input === '')) {\n            return createInvalid({nullInput: true});\n        }\n\n        if (typeof input === 'string') {\n            config._i = input = config._locale.preparse(input);\n        }\n\n        if (isMoment(input)) {\n            return new Moment(checkOverflow(input));\n        } else if (isDate(input)) {\n            config._d = input;\n        } else if (isArray(format)) {\n            configFromStringAndArray(config);\n        } else if (format) {\n            configFromStringAndFormat(config);\n        }  else {\n            configFromInput(config);\n        }\n\n        if (!isValid(config)) {\n            config._d = null;\n        }\n\n        return config;\n    }\n\n    function configFromInput(config) {\n        var input = config._i;\n        if (isUndefined(input)) {\n            config._d = new Date(hooks.now());\n        } else if (isDate(input)) {\n            config._d = new Date(input.valueOf());\n        } else if (typeof input === 'string') {\n            configFromString(config);\n        } else if (isArray(input)) {\n            config._a = map(input.slice(0), function (obj) {\n                return parseInt(obj, 10);\n            });\n            configFromArray(config);\n        } else if (isObject(input)) {\n            configFromObject(config);\n        } else if (isNumber(input)) {\n            // from milliseconds\n            config._d = new Date(input);\n        } else {\n            hooks.createFromInputFallback(config);\n        }\n    }\n\n    function createLocalOrUTC (input, format, locale, strict, isUTC) {\n        var c = {};\n\n        if (locale === true || locale === false) {\n            strict = locale;\n            locale = undefined;\n        }\n\n        if ((isObject(input) && isObjectEmpty(input)) ||\n                (isArray(input) && input.length === 0)) {\n            input = undefined;\n        }\n        // object construction must be done this way.\n        // https://github.com/moment/moment/issues/1423\n        c._isAMomentObject = true;\n        c._useUTC = c._isUTC = isUTC;\n        c._l = locale;\n        c._i = input;\n        c._f = format;\n        c._strict = strict;\n\n        return createFromConfig(c);\n    }\n\n    function createLocal (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, false);\n    }\n\n    var prototypeMin = deprecate(\n        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n        function () {\n            var other = createLocal.apply(null, arguments);\n            if (this.isValid() && other.isValid()) {\n                return other < this ? this : other;\n            } else {\n                return createInvalid();\n            }\n        }\n    );\n\n    var prototypeMax = deprecate(\n        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n        function () {\n            var other = createLocal.apply(null, arguments);\n            if (this.isValid() && other.isValid()) {\n                return other > this ? this : other;\n            } else {\n                return createInvalid();\n            }\n        }\n    );\n\n    // Pick a moment m from moments so that m[fn](other) is true for all\n    // other. This relies on the function fn to be transitive.\n    //\n    // moments should either be an array of moment objects or an array, whose\n    // first element is an array of moment objects.\n    function pickBy(fn, moments) {\n        var res, i;\n        if (moments.length === 1 && isArray(moments[0])) {\n            moments = moments[0];\n        }\n        if (!moments.length) {\n            return createLocal();\n        }\n        res = moments[0];\n        for (i = 1; i < moments.length; ++i) {\n            if (!moments[i].isValid() || moments[i][fn](res)) {\n                res = moments[i];\n            }\n        }\n        return res;\n    }\n\n    // TODO: Use [].sort instead?\n    function min () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isBefore', args);\n    }\n\n    function max () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isAfter', args);\n    }\n\n    var now = function () {\n        return Date.now ? Date.now() : +(new Date());\n    };\n\n    var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\n    function isDurationValid(m) {\n        for (var key in m) {\n            if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n                return false;\n            }\n        }\n\n        var unitHasDecimal = false;\n        for (var i = 0; i < ordering.length; ++i) {\n            if (m[ordering[i]]) {\n                if (unitHasDecimal) {\n                    return false; // only allow non-integers for smallest unit\n                }\n                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                    unitHasDecimal = true;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    function isValid$1() {\n        return this._isValid;\n    }\n\n    function createInvalid$1() {\n        return createDuration(NaN);\n    }\n\n    function Duration (duration) {\n        var normalizedInput = normalizeObjectUnits(duration),\n            years = normalizedInput.year || 0,\n            quarters = normalizedInput.quarter || 0,\n            months = normalizedInput.month || 0,\n            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,\n            days = normalizedInput.day || 0,\n            hours = normalizedInput.hour || 0,\n            minutes = normalizedInput.minute || 0,\n            seconds = normalizedInput.second || 0,\n            milliseconds = normalizedInput.millisecond || 0;\n\n        this._isValid = isDurationValid(normalizedInput);\n\n        // representation for dateAddRemove\n        this._milliseconds = +milliseconds +\n            seconds * 1e3 + // 1000\n            minutes * 6e4 + // 1000 * 60\n            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n        // Because of dateAddRemove treats 24 hours as different from a\n        // day when working around DST, we need to store them separately\n        this._days = +days +\n            weeks * 7;\n        // It is impossible to translate months into days without knowing\n        // which months you are are talking about, so we have to store\n        // it separately.\n        this._months = +months +\n            quarters * 3 +\n            years * 12;\n\n        this._data = {};\n\n        this._locale = getLocale();\n\n        this._bubble();\n    }\n\n    function isDuration (obj) {\n        return obj instanceof Duration;\n    }\n\n    function absRound (number) {\n        if (number < 0) {\n            return Math.round(-1 * number) * -1;\n        } else {\n            return Math.round(number);\n        }\n    }\n\n    // FORMATTING\n\n    function offset (token, separator) {\n        addFormatToken(token, 0, 0, function () {\n            var offset = this.utcOffset();\n            var sign = '+';\n            if (offset < 0) {\n                offset = -offset;\n                sign = '-';\n            }\n            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n        });\n    }\n\n    offset('Z', ':');\n    offset('ZZ', '');\n\n    // PARSING\n\n    addRegexToken('Z',  matchShortOffset);\n    addRegexToken('ZZ', matchShortOffset);\n    addParseToken(['Z', 'ZZ'], function (input, array, config) {\n        config._useUTC = true;\n        config._tzm = offsetFromString(matchShortOffset, input);\n    });\n\n    // HELPERS\n\n    // timezone chunker\n    // '+10:00' > ['10',  '00']\n    // '-1530'  > ['-15', '30']\n    var chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\n    function offsetFromString(matcher, string) {\n        var matches = (string || '').match(matcher);\n\n        if (matches === null) {\n            return null;\n        }\n\n        var chunk   = matches[matches.length - 1] || [];\n        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n        var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n        return minutes === 0 ?\n          0 :\n          parts[0] === '+' ? minutes : -minutes;\n    }\n\n    // Return a moment from input, that is local/utc/zone equivalent to model.\n    function cloneWithOffset(input, model) {\n        var res, diff;\n        if (model._isUTC) {\n            res = model.clone();\n            diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n            // Use low-level api, because this fn is low-level api.\n            res._d.setTime(res._d.valueOf() + diff);\n            hooks.updateOffset(res, false);\n            return res;\n        } else {\n            return createLocal(input).local();\n        }\n    }\n\n    function getDateOffset (m) {\n        // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n        // https://github.com/moment/moment/pull/1871\n        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n    }\n\n    // HOOKS\n\n    // This function will be called whenever a moment is mutated.\n    // It is intended to keep the offset in sync with the timezone.\n    hooks.updateOffset = function () {};\n\n    // MOMENTS\n\n    // keepLocalTime = true means only change the timezone, without\n    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--\x3e\n    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n    // +0200, so we adjust the time as needed, to be valid.\n    //\n    // Keeping the time actually adds/subtracts (one hour)\n    // from the actual represented time. That is why we call updateOffset\n    // a second time. In case it wants us to change the offset again\n    // _changeInProgress == true case, then we have to adjust, because\n    // there is no such time in the given timezone.\n    function getSetOffset (input, keepLocalTime, keepMinutes) {\n        var offset = this._offset || 0,\n            localAdjust;\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        if (input != null) {\n            if (typeof input === 'string') {\n                input = offsetFromString(matchShortOffset, input);\n                if (input === null) {\n                    return this;\n                }\n            } else if (Math.abs(input) < 16 && !keepMinutes) {\n                input = input * 60;\n            }\n            if (!this._isUTC && keepLocalTime) {\n                localAdjust = getDateOffset(this);\n            }\n            this._offset = input;\n            this._isUTC = true;\n            if (localAdjust != null) {\n                this.add(localAdjust, 'm');\n            }\n            if (offset !== input) {\n                if (!keepLocalTime || this._changeInProgress) {\n                    addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n                } else if (!this._changeInProgress) {\n                    this._changeInProgress = true;\n                    hooks.updateOffset(this, true);\n                    this._changeInProgress = null;\n                }\n            }\n            return this;\n        } else {\n            return this._isUTC ? offset : getDateOffset(this);\n        }\n    }\n\n    function getSetZone (input, keepLocalTime) {\n        if (input != null) {\n            if (typeof input !== 'string') {\n                input = -input;\n            }\n\n            this.utcOffset(input, keepLocalTime);\n\n            return this;\n        } else {\n            return -this.utcOffset();\n        }\n    }\n\n    function setOffsetToUTC (keepLocalTime) {\n        return this.utcOffset(0, keepLocalTime);\n    }\n\n    function setOffsetToLocal (keepLocalTime) {\n        if (this._isUTC) {\n            this.utcOffset(0, keepLocalTime);\n            this._isUTC = false;\n\n            if (keepLocalTime) {\n                this.subtract(getDateOffset(this), 'm');\n            }\n        }\n        return this;\n    }\n\n    function setOffsetToParsedOffset () {\n        if (this._tzm != null) {\n            this.utcOffset(this._tzm, false, true);\n        } else if (typeof this._i === 'string') {\n            var tZone = offsetFromString(matchOffset, this._i);\n            if (tZone != null) {\n                this.utcOffset(tZone);\n            }\n            else {\n                this.utcOffset(0, true);\n            }\n        }\n        return this;\n    }\n\n    function hasAlignedHourOffset (input) {\n        if (!this.isValid()) {\n            return false;\n        }\n        input = input ? createLocal(input).utcOffset() : 0;\n\n        return (this.utcOffset() - input) % 60 === 0;\n    }\n\n    function isDaylightSavingTime () {\n        return (\n            this.utcOffset() > this.clone().month(0).utcOffset() ||\n            this.utcOffset() > this.clone().month(5).utcOffset()\n        );\n    }\n\n    function isDaylightSavingTimeShifted () {\n        if (!isUndefined(this._isDSTShifted)) {\n            return this._isDSTShifted;\n        }\n\n        var c = {};\n\n        copyConfig(c, this);\n        c = prepareConfig(c);\n\n        if (c._a) {\n            var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n            this._isDSTShifted = this.isValid() &&\n                compareArrays(c._a, other.toArray()) > 0;\n        } else {\n            this._isDSTShifted = false;\n        }\n\n        return this._isDSTShifted;\n    }\n\n    function isLocal () {\n        return this.isValid() ? !this._isUTC : false;\n    }\n\n    function isUtcOffset () {\n        return this.isValid() ? this._isUTC : false;\n    }\n\n    function isUtc () {\n        return this.isValid() ? this._isUTC && this._offset === 0 : false;\n    }\n\n    // ASP.NET json date format regex\n    var aspNetRegex = /^(\\-|\\+)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n    // and further modified to allow for strings containing both week and day\n    var isoRegex = /^(-|\\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;\n\n    function createDuration (input, key) {\n        var duration = input,\n            // matching against regexp is expensive, do it on demand\n            match = null,\n            sign,\n            ret,\n            diffRes;\n\n        if (isDuration(input)) {\n            duration = {\n                ms : input._milliseconds,\n                d  : input._days,\n                M  : input._months\n            };\n        } else if (isNumber(input)) {\n            duration = {};\n            if (key) {\n                duration[key] = input;\n            } else {\n                duration.milliseconds = input;\n            }\n        } else if (!!(match = aspNetRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y  : 0,\n                d  : toInt(match[DATE])                         * sign,\n                h  : toInt(match[HOUR])                         * sign,\n                m  : toInt(match[MINUTE])                       * sign,\n                s  : toInt(match[SECOND])                       * sign,\n                ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n            };\n        } else if (!!(match = isoRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y : parseIso(match[2], sign),\n                M : parseIso(match[3], sign),\n                w : parseIso(match[4], sign),\n                d : parseIso(match[5], sign),\n                h : parseIso(match[6], sign),\n                m : parseIso(match[7], sign),\n                s : parseIso(match[8], sign)\n            };\n        } else if (duration == null) {// checks for null or undefined\n            duration = {};\n        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n            diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n            duration = {};\n            duration.ms = diffRes.milliseconds;\n            duration.M = diffRes.months;\n        }\n\n        ret = new Duration(duration);\n\n        if (isDuration(input) && hasOwnProp(input, '_locale')) {\n            ret._locale = input._locale;\n        }\n\n        return ret;\n    }\n\n    createDuration.fn = Duration.prototype;\n    createDuration.invalid = createInvalid$1;\n\n    function parseIso (inp, sign) {\n        // We'd normally use ~~inp for this, but unfortunately it also\n        // converts floats to ints.\n        // inp may be undefined, so careful calling replace on it.\n        var res = inp && parseFloat(inp.replace(',', '.'));\n        // apply sign while we're at it\n        return (isNaN(res) ? 0 : res) * sign;\n    }\n\n    function positiveMomentsDifference(base, other) {\n        var res = {};\n\n        res.months = other.month() - base.month() +\n            (other.year() - base.year()) * 12;\n        if (base.clone().add(res.months, 'M').isAfter(other)) {\n            --res.months;\n        }\n\n        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n        return res;\n    }\n\n    function momentsDifference(base, other) {\n        var res;\n        if (!(base.isValid() && other.isValid())) {\n            return {milliseconds: 0, months: 0};\n        }\n\n        other = cloneWithOffset(other, base);\n        if (base.isBefore(other)) {\n            res = positiveMomentsDifference(base, other);\n        } else {\n            res = positiveMomentsDifference(other, base);\n            res.milliseconds = -res.milliseconds;\n            res.months = -res.months;\n        }\n\n        return res;\n    }\n\n    // TODO: remove 'name' arg after deprecation is removed\n    function createAdder(direction, name) {\n        return function (val, period) {\n            var dur, tmp;\n            //invert the arguments, but complain about it\n            if (period !== null && !isNaN(+period)) {\n                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n                'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n                tmp = val; val = period; period = tmp;\n            }\n\n            val = typeof val === 'string' ? +val : val;\n            dur = createDuration(val, period);\n            addSubtract(this, dur, direction);\n            return this;\n        };\n    }\n\n    function addSubtract (mom, duration, isAdding, updateOffset) {\n        var milliseconds = duration._milliseconds,\n            days = absRound(duration._days),\n            months = absRound(duration._months);\n\n        if (!mom.isValid()) {\n            // No op\n            return;\n        }\n\n        updateOffset = updateOffset == null ? true : updateOffset;\n\n        if (months) {\n            setMonth(mom, get(mom, 'Month') + months * isAdding);\n        }\n        if (days) {\n            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n        }\n        if (milliseconds) {\n            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n        }\n        if (updateOffset) {\n            hooks.updateOffset(mom, days || months);\n        }\n    }\n\n    var add      = createAdder(1, 'add');\n    var subtract = createAdder(-1, 'subtract');\n\n    function getCalendarFormat(myMoment, now) {\n        var diff = myMoment.diff(now, 'days', true);\n        return diff < -6 ? 'sameElse' :\n                diff < -1 ? 'lastWeek' :\n                diff < 0 ? 'lastDay' :\n                diff < 1 ? 'sameDay' :\n                diff < 2 ? 'nextDay' :\n                diff < 7 ? 'nextWeek' : 'sameElse';\n    }\n\n    function calendar$1 (time, formats) {\n        // We want to compare the start of today, vs this.\n        // Getting start-of-today depends on whether we're local/utc/offset or not.\n        var now = time || createLocal(),\n            sod = cloneWithOffset(now, this).startOf('day'),\n            format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n        return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n    }\n\n    function clone () {\n        return new Moment(this);\n    }\n\n    function isAfter (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input);\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() > localInput.valueOf();\n        } else {\n            return localInput.valueOf() < this.clone().startOf(units).valueOf();\n        }\n    }\n\n    function isBefore (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input);\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() < localInput.valueOf();\n        } else {\n            return this.clone().endOf(units).valueOf() < localInput.valueOf();\n        }\n    }\n\n    function isBetween (from, to, units, inclusivity) {\n        var localFrom = isMoment(from) ? from : createLocal(from),\n            localTo = isMoment(to) ? to : createLocal(to);\n        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {\n            return false;\n        }\n        inclusivity = inclusivity || '()';\n        return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) &&\n            (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));\n    }\n\n    function isSame (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input),\n            inputMs;\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() === localInput.valueOf();\n        } else {\n            inputMs = localInput.valueOf();\n            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n        }\n    }\n\n    function isSameOrAfter (input, units) {\n        return this.isSame(input, units) || this.isAfter(input, units);\n    }\n\n    function isSameOrBefore (input, units) {\n        return this.isSame(input, units) || this.isBefore(input, units);\n    }\n\n    function diff (input, units, asFloat) {\n        var that,\n            zoneDelta,\n            output;\n\n        if (!this.isValid()) {\n            return NaN;\n        }\n\n        that = cloneWithOffset(input, this);\n\n        if (!that.isValid()) {\n            return NaN;\n        }\n\n        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n        units = normalizeUnits(units);\n\n        switch (units) {\n            case 'year': output = monthDiff(this, that) / 12; break;\n            case 'month': output = monthDiff(this, that); break;\n            case 'quarter': output = monthDiff(this, that) / 3; break;\n            case 'second': output = (this - that) / 1e3; break; // 1000\n            case 'minute': output = (this - that) / 6e4; break; // 1000 * 60\n            case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60\n            case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst\n            case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst\n            default: output = this - that;\n        }\n\n        return asFloat ? output : absFloor(output);\n    }\n\n    function monthDiff (a, b) {\n        // difference in months\n        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n            // b is in (anchor - 1 month, anchor + 1 month)\n            anchor = a.clone().add(wholeMonthDiff, 'months'),\n            anchor2, adjust;\n\n        if (b - anchor < 0) {\n            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor - anchor2);\n        } else {\n            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor2 - anchor);\n        }\n\n        //check for negative zero, return zero if negative zero\n        return -(wholeMonthDiff + adjust) || 0;\n    }\n\n    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\n    function toString () {\n        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n    }\n\n    function toISOString(keepOffset) {\n        if (!this.isValid()) {\n            return null;\n        }\n        var utc = keepOffset !== true;\n        var m = utc ? this.clone().utc() : this;\n        if (m.year() < 0 || m.year() > 9999) {\n            return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');\n        }\n        if (isFunction(Date.prototype.toISOString)) {\n            // native implementation is ~50x faster, use it when we can\n            if (utc) {\n                return this.toDate().toISOString();\n            } else {\n                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));\n            }\n        }\n        return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');\n    }\n\n    /**\n     * Return a human readable representation of a moment that can\n     * also be evaluated to get a new moment which is the same\n     *\n     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n     */\n    function inspect () {\n        if (!this.isValid()) {\n            return 'moment.invalid(/* ' + this._i + ' */)';\n        }\n        var func = 'moment';\n        var zone = '';\n        if (!this.isLocal()) {\n            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n            zone = 'Z';\n        }\n        var prefix = '[' + func + '(\"]';\n        var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n        var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n        var suffix = zone + '[\")]';\n\n        return this.format(prefix + year + datetime + suffix);\n    }\n\n    function format (inputString) {\n        if (!inputString) {\n            inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n        }\n        var output = formatMoment(this, inputString);\n        return this.localeData().postformat(output);\n    }\n\n    function from (time, withoutSuffix) {\n        if (this.isValid() &&\n                ((isMoment(time) && time.isValid()) ||\n                 createLocal(time).isValid())) {\n            return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n        } else {\n            return this.localeData().invalidDate();\n        }\n    }\n\n    function fromNow (withoutSuffix) {\n        return this.from(createLocal(), withoutSuffix);\n    }\n\n    function to (time, withoutSuffix) {\n        if (this.isValid() &&\n                ((isMoment(time) && time.isValid()) ||\n                 createLocal(time).isValid())) {\n            return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n        } else {\n            return this.localeData().invalidDate();\n        }\n    }\n\n    function toNow (withoutSuffix) {\n        return this.to(createLocal(), withoutSuffix);\n    }\n\n    // If passed a locale key, it will set the locale for this\n    // instance.  Otherwise, it will return the locale configuration\n    // variables for this instance.\n    function locale (key) {\n        var newLocaleData;\n\n        if (key === undefined) {\n            return this._locale._abbr;\n        } else {\n            newLocaleData = getLocale(key);\n            if (newLocaleData != null) {\n                this._locale = newLocaleData;\n            }\n            return this;\n        }\n    }\n\n    var lang = deprecate(\n        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n        function (key) {\n            if (key === undefined) {\n                return this.localeData();\n            } else {\n                return this.locale(key);\n            }\n        }\n    );\n\n    function localeData () {\n        return this._locale;\n    }\n\n    var MS_PER_SECOND = 1000;\n    var MS_PER_MINUTE = 60 * MS_PER_SECOND;\n    var MS_PER_HOUR = 60 * MS_PER_MINUTE;\n    var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;\n\n    // actual modulo - handles negative numbers (for dates before 1970):\n    function mod$1(dividend, divisor) {\n        return (dividend % divisor + divisor) % divisor;\n    }\n\n    function localStartOfDate(y, m, d) {\n        // the date constructor remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            return new Date(y + 400, m, d) - MS_PER_400_YEARS;\n        } else {\n            return new Date(y, m, d).valueOf();\n        }\n    }\n\n    function utcStartOfDate(y, m, d) {\n        // Date.UTC remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;\n        } else {\n            return Date.UTC(y, m, d);\n        }\n    }\n\n    function startOf (units) {\n        var time;\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond' || !this.isValid()) {\n            return this;\n        }\n\n        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;\n\n        switch (units) {\n            case 'year':\n                time = startOfDate(this.year(), 0, 1);\n                break;\n            case 'quarter':\n                time = startOfDate(this.year(), this.month() - this.month() % 3, 1);\n                break;\n            case 'month':\n                time = startOfDate(this.year(), this.month(), 1);\n                break;\n            case 'week':\n                time = startOfDate(this.year(), this.month(), this.date() - this.weekday());\n                break;\n            case 'isoWeek':\n                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));\n                break;\n            case 'day':\n            case 'date':\n                time = startOfDate(this.year(), this.month(), this.date());\n                break;\n            case 'hour':\n                time = this._d.valueOf();\n                time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);\n                break;\n            case 'minute':\n                time = this._d.valueOf();\n                time -= mod$1(time, MS_PER_MINUTE);\n                break;\n            case 'second':\n                time = this._d.valueOf();\n                time -= mod$1(time, MS_PER_SECOND);\n                break;\n        }\n\n        this._d.setTime(time);\n        hooks.updateOffset(this, true);\n        return this;\n    }\n\n    function endOf (units) {\n        var time;\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond' || !this.isValid()) {\n            return this;\n        }\n\n        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;\n\n        switch (units) {\n            case 'year':\n                time = startOfDate(this.year() + 1, 0, 1) - 1;\n                break;\n            case 'quarter':\n                time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;\n                break;\n            case 'month':\n                time = startOfDate(this.year(), this.month() + 1, 1) - 1;\n                break;\n            case 'week':\n                time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;\n                break;\n            case 'isoWeek':\n                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;\n                break;\n            case 'day':\n            case 'date':\n                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;\n                break;\n            case 'hour':\n                time = this._d.valueOf();\n                time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;\n                break;\n            case 'minute':\n                time = this._d.valueOf();\n                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;\n                break;\n            case 'second':\n                time = this._d.valueOf();\n                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;\n                break;\n        }\n\n        this._d.setTime(time);\n        hooks.updateOffset(this, true);\n        return this;\n    }\n\n    function valueOf () {\n        return this._d.valueOf() - ((this._offset || 0) * 60000);\n    }\n\n    function unix () {\n        return Math.floor(this.valueOf() / 1000);\n    }\n\n    function toDate () {\n        return new Date(this.valueOf());\n    }\n\n    function toArray () {\n        var m = this;\n        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n    }\n\n    function toObject () {\n        var m = this;\n        return {\n            years: m.year(),\n            months: m.month(),\n            date: m.date(),\n            hours: m.hours(),\n            minutes: m.minutes(),\n            seconds: m.seconds(),\n            milliseconds: m.milliseconds()\n        };\n    }\n\n    function toJSON () {\n        // new Date(NaN).toJSON() === null\n        return this.isValid() ? this.toISOString() : null;\n    }\n\n    function isValid$2 () {\n        return isValid(this);\n    }\n\n    function parsingFlags () {\n        return extend({}, getParsingFlags(this));\n    }\n\n    function invalidAt () {\n        return getParsingFlags(this).overflow;\n    }\n\n    function creationData() {\n        return {\n            input: this._i,\n            format: this._f,\n            locale: this._locale,\n            isUTC: this._isUTC,\n            strict: this._strict\n        };\n    }\n\n    // FORMATTING\n\n    addFormatToken(0, ['gg', 2], 0, function () {\n        return this.weekYear() % 100;\n    });\n\n    addFormatToken(0, ['GG', 2], 0, function () {\n        return this.isoWeekYear() % 100;\n    });\n\n    function addWeekYearFormatToken (token, getter) {\n        addFormatToken(0, [token, token.length], 0, getter);\n    }\n\n    addWeekYearFormatToken('gggg',     'weekYear');\n    addWeekYearFormatToken('ggggg',    'weekYear');\n    addWeekYearFormatToken('GGGG',  'isoWeekYear');\n    addWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n    // ALIASES\n\n    addUnitAlias('weekYear', 'gg');\n    addUnitAlias('isoWeekYear', 'GG');\n\n    // PRIORITY\n\n    addUnitPriority('weekYear', 1);\n    addUnitPriority('isoWeekYear', 1);\n\n\n    // PARSING\n\n    addRegexToken('G',      matchSigned);\n    addRegexToken('g',      matchSigned);\n    addRegexToken('GG',     match1to2, match2);\n    addRegexToken('gg',     match1to2, match2);\n    addRegexToken('GGGG',   match1to4, match4);\n    addRegexToken('gggg',   match1to4, match4);\n    addRegexToken('GGGGG',  match1to6, match6);\n    addRegexToken('ggggg',  match1to6, match6);\n\n    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n        week[token.substr(0, 2)] = toInt(input);\n    });\n\n    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n        week[token] = hooks.parseTwoDigitYear(input);\n    });\n\n    // MOMENTS\n\n    function getSetWeekYear (input) {\n        return getSetWeekYearHelper.call(this,\n                input,\n                this.week(),\n                this.weekday(),\n                this.localeData()._week.dow,\n                this.localeData()._week.doy);\n    }\n\n    function getSetISOWeekYear (input) {\n        return getSetWeekYearHelper.call(this,\n                input, this.isoWeek(), this.isoWeekday(), 1, 4);\n    }\n\n    function getISOWeeksInYear () {\n        return weeksInYear(this.year(), 1, 4);\n    }\n\n    function getWeeksInYear () {\n        var weekInfo = this.localeData()._week;\n        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n    }\n\n    function getSetWeekYearHelper(input, week, weekday, dow, doy) {\n        var weeksTarget;\n        if (input == null) {\n            return weekOfYear(this, dow, doy).year;\n        } else {\n            weeksTarget = weeksInYear(input, dow, doy);\n            if (week > weeksTarget) {\n                week = weeksTarget;\n            }\n            return setWeekAll.call(this, input, week, weekday, dow, doy);\n        }\n    }\n\n    function setWeekAll(weekYear, week, weekday, dow, doy) {\n        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n        this.year(date.getUTCFullYear());\n        this.month(date.getUTCMonth());\n        this.date(date.getUTCDate());\n        return this;\n    }\n\n    // FORMATTING\n\n    addFormatToken('Q', 0, 'Qo', 'quarter');\n\n    // ALIASES\n\n    addUnitAlias('quarter', 'Q');\n\n    // PRIORITY\n\n    addUnitPriority('quarter', 7);\n\n    // PARSING\n\n    addRegexToken('Q', match1);\n    addParseToken('Q', function (input, array) {\n        array[MONTH] = (toInt(input) - 1) * 3;\n    });\n\n    // MOMENTS\n\n    function getSetQuarter (input) {\n        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n    }\n\n    // FORMATTING\n\n    addFormatToken('D', ['DD', 2], 'Do', 'date');\n\n    // ALIASES\n\n    addUnitAlias('date', 'D');\n\n    // PRIORITY\n    addUnitPriority('date', 9);\n\n    // PARSING\n\n    addRegexToken('D',  match1to2);\n    addRegexToken('DD', match1to2, match2);\n    addRegexToken('Do', function (isStrict, locale) {\n        // TODO: Remove \"ordinalParse\" fallback in next major release.\n        return isStrict ?\n          (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n          locale._dayOfMonthOrdinalParseLenient;\n    });\n\n    addParseToken(['D', 'DD'], DATE);\n    addParseToken('Do', function (input, array) {\n        array[DATE] = toInt(input.match(match1to2)[0]);\n    });\n\n    // MOMENTS\n\n    var getSetDayOfMonth = makeGetSet('Date', true);\n\n    // FORMATTING\n\n    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n    // ALIASES\n\n    addUnitAlias('dayOfYear', 'DDD');\n\n    // PRIORITY\n    addUnitPriority('dayOfYear', 4);\n\n    // PARSING\n\n    addRegexToken('DDD',  match1to3);\n    addRegexToken('DDDD', match3);\n    addParseToken(['DDD', 'DDDD'], function (input, array, config) {\n        config._dayOfYear = toInt(input);\n    });\n\n    // HELPERS\n\n    // MOMENTS\n\n    function getSetDayOfYear (input) {\n        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n    }\n\n    // FORMATTING\n\n    addFormatToken('m', ['mm', 2], 0, 'minute');\n\n    // ALIASES\n\n    addUnitAlias('minute', 'm');\n\n    // PRIORITY\n\n    addUnitPriority('minute', 14);\n\n    // PARSING\n\n    addRegexToken('m',  match1to2);\n    addRegexToken('mm', match1to2, match2);\n    addParseToken(['m', 'mm'], MINUTE);\n\n    // MOMENTS\n\n    var getSetMinute = makeGetSet('Minutes', false);\n\n    // FORMATTING\n\n    addFormatToken('s', ['ss', 2], 0, 'second');\n\n    // ALIASES\n\n    addUnitAlias('second', 's');\n\n    // PRIORITY\n\n    addUnitPriority('second', 15);\n\n    // PARSING\n\n    addRegexToken('s',  match1to2);\n    addRegexToken('ss', match1to2, match2);\n    addParseToken(['s', 'ss'], SECOND);\n\n    // MOMENTS\n\n    var getSetSecond = makeGetSet('Seconds', false);\n\n    // FORMATTING\n\n    addFormatToken('S', 0, 0, function () {\n        return ~~(this.millisecond() / 100);\n    });\n\n    addFormatToken(0, ['SS', 2], 0, function () {\n        return ~~(this.millisecond() / 10);\n    });\n\n    addFormatToken(0, ['SSS', 3], 0, 'millisecond');\n    addFormatToken(0, ['SSSS', 4], 0, function () {\n        return this.millisecond() * 10;\n    });\n    addFormatToken(0, ['SSSSS', 5], 0, function () {\n        return this.millisecond() * 100;\n    });\n    addFormatToken(0, ['SSSSSS', 6], 0, function () {\n        return this.millisecond() * 1000;\n    });\n    addFormatToken(0, ['SSSSSSS', 7], 0, function () {\n        return this.millisecond() * 10000;\n    });\n    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n        return this.millisecond() * 100000;\n    });\n    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n        return this.millisecond() * 1000000;\n    });\n\n\n    // ALIASES\n\n    addUnitAlias('millisecond', 'ms');\n\n    // PRIORITY\n\n    addUnitPriority('millisecond', 16);\n\n    // PARSING\n\n    addRegexToken('S',    match1to3, match1);\n    addRegexToken('SS',   match1to3, match2);\n    addRegexToken('SSS',  match1to3, match3);\n\n    var token;\n    for (token = 'SSSS'; token.length <= 9; token += 'S') {\n        addRegexToken(token, matchUnsigned);\n    }\n\n    function parseMs(input, array) {\n        array[MILLISECOND] = toInt(('0.' + input) * 1000);\n    }\n\n    for (token = 'S'; token.length <= 9; token += 'S') {\n        addParseToken(token, parseMs);\n    }\n    // MOMENTS\n\n    var getSetMillisecond = makeGetSet('Milliseconds', false);\n\n    // FORMATTING\n\n    addFormatToken('z',  0, 0, 'zoneAbbr');\n    addFormatToken('zz', 0, 0, 'zoneName');\n\n    // MOMENTS\n\n    function getZoneAbbr () {\n        return this._isUTC ? 'UTC' : '';\n    }\n\n    function getZoneName () {\n        return this._isUTC ? 'Coordinated Universal Time' : '';\n    }\n\n    var proto = Moment.prototype;\n\n    proto.add               = add;\n    proto.calendar          = calendar$1;\n    proto.clone             = clone;\n    proto.diff              = diff;\n    proto.endOf             = endOf;\n    proto.format            = format;\n    proto.from              = from;\n    proto.fromNow           = fromNow;\n    proto.to                = to;\n    proto.toNow             = toNow;\n    proto.get               = stringGet;\n    proto.invalidAt         = invalidAt;\n    proto.isAfter           = isAfter;\n    proto.isBefore          = isBefore;\n    proto.isBetween         = isBetween;\n    proto.isSame            = isSame;\n    proto.isSameOrAfter     = isSameOrAfter;\n    proto.isSameOrBefore    = isSameOrBefore;\n    proto.isValid           = isValid$2;\n    proto.lang              = lang;\n    proto.locale            = locale;\n    proto.localeData        = localeData;\n    proto.max               = prototypeMax;\n    proto.min               = prototypeMin;\n    proto.parsingFlags      = parsingFlags;\n    proto.set               = stringSet;\n    proto.startOf           = startOf;\n    proto.subtract          = subtract;\n    proto.toArray           = toArray;\n    proto.toObject          = toObject;\n    proto.toDate            = toDate;\n    proto.toISOString       = toISOString;\n    proto.inspect           = inspect;\n    proto.toJSON            = toJSON;\n    proto.toString          = toString;\n    proto.unix              = unix;\n    proto.valueOf           = valueOf;\n    proto.creationData      = creationData;\n    proto.year       = getSetYear;\n    proto.isLeapYear = getIsLeapYear;\n    proto.weekYear    = getSetWeekYear;\n    proto.isoWeekYear = getSetISOWeekYear;\n    proto.quarter = proto.quarters = getSetQuarter;\n    proto.month       = getSetMonth;\n    proto.daysInMonth = getDaysInMonth;\n    proto.week           = proto.weeks        = getSetWeek;\n    proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\n    proto.weeksInYear    = getWeeksInYear;\n    proto.isoWeeksInYear = getISOWeeksInYear;\n    proto.date       = getSetDayOfMonth;\n    proto.day        = proto.days             = getSetDayOfWeek;\n    proto.weekday    = getSetLocaleDayOfWeek;\n    proto.isoWeekday = getSetISODayOfWeek;\n    proto.dayOfYear  = getSetDayOfYear;\n    proto.hour = proto.hours = getSetHour;\n    proto.minute = proto.minutes = getSetMinute;\n    proto.second = proto.seconds = getSetSecond;\n    proto.millisecond = proto.milliseconds = getSetMillisecond;\n    proto.utcOffset            = getSetOffset;\n    proto.utc                  = setOffsetToUTC;\n    proto.local                = setOffsetToLocal;\n    proto.parseZone            = setOffsetToParsedOffset;\n    proto.hasAlignedHourOffset = hasAlignedHourOffset;\n    proto.isDST                = isDaylightSavingTime;\n    proto.isLocal              = isLocal;\n    proto.isUtcOffset          = isUtcOffset;\n    proto.isUtc                = isUtc;\n    proto.isUTC                = isUtc;\n    proto.zoneAbbr = getZoneAbbr;\n    proto.zoneName = getZoneName;\n    proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\n    proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\n    proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\n    proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\n    proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\n    function createUnix (input) {\n        return createLocal(input * 1000);\n    }\n\n    function createInZone () {\n        return createLocal.apply(null, arguments).parseZone();\n    }\n\n    function preParsePostFormat (string) {\n        return string;\n    }\n\n    var proto$1 = Locale.prototype;\n\n    proto$1.calendar        = calendar;\n    proto$1.longDateFormat  = longDateFormat;\n    proto$1.invalidDate     = invalidDate;\n    proto$1.ordinal         = ordinal;\n    proto$1.preparse        = preParsePostFormat;\n    proto$1.postformat      = preParsePostFormat;\n    proto$1.relativeTime    = relativeTime;\n    proto$1.pastFuture      = pastFuture;\n    proto$1.set             = set;\n\n    proto$1.months            =        localeMonths;\n    proto$1.monthsShort       =        localeMonthsShort;\n    proto$1.monthsParse       =        localeMonthsParse;\n    proto$1.monthsRegex       = monthsRegex;\n    proto$1.monthsShortRegex  = monthsShortRegex;\n    proto$1.week = localeWeek;\n    proto$1.firstDayOfYear = localeFirstDayOfYear;\n    proto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n    proto$1.weekdays       =        localeWeekdays;\n    proto$1.weekdaysMin    =        localeWeekdaysMin;\n    proto$1.weekdaysShort  =        localeWeekdaysShort;\n    proto$1.weekdaysParse  =        localeWeekdaysParse;\n\n    proto$1.weekdaysRegex       =        weekdaysRegex;\n    proto$1.weekdaysShortRegex  =        weekdaysShortRegex;\n    proto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n    proto$1.isPM = localeIsPM;\n    proto$1.meridiem = localeMeridiem;\n\n    function get$1 (format, index, field, setter) {\n        var locale = getLocale();\n        var utc = createUTC().set(setter, index);\n        return locale[field](utc, format);\n    }\n\n    function listMonthsImpl (format, index, field) {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n\n        if (index != null) {\n            return get$1(format, index, field, 'month');\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < 12; i++) {\n            out[i] = get$1(format, i, field, 'month');\n        }\n        return out;\n    }\n\n    // ()\n    // (5)\n    // (fmt, 5)\n    // (fmt)\n    // (true)\n    // (true, 5)\n    // (true, fmt, 5)\n    // (true, fmt)\n    function listWeekdaysImpl (localeSorted, format, index, field) {\n        if (typeof localeSorted === 'boolean') {\n            if (isNumber(format)) {\n                index = format;\n                format = undefined;\n            }\n\n            format = format || '';\n        } else {\n            format = localeSorted;\n            index = format;\n            localeSorted = false;\n\n            if (isNumber(format)) {\n                index = format;\n                format = undefined;\n            }\n\n            format = format || '';\n        }\n\n        var locale = getLocale(),\n            shift = localeSorted ? locale._week.dow : 0;\n\n        if (index != null) {\n            return get$1(format, (index + shift) % 7, field, 'day');\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < 7; i++) {\n            out[i] = get$1(format, (i + shift) % 7, field, 'day');\n        }\n        return out;\n    }\n\n    function listMonths (format, index) {\n        return listMonthsImpl(format, index, 'months');\n    }\n\n    function listMonthsShort (format, index) {\n        return listMonthsImpl(format, index, 'monthsShort');\n    }\n\n    function listWeekdays (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n    }\n\n    function listWeekdaysShort (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n    }\n\n    function listWeekdaysMin (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n    }\n\n    getSetGlobalLocale('en', {\n        dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (toInt(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    // Side effect imports\n\n    hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\n    hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\n    var mathAbs = Math.abs;\n\n    function abs () {\n        var data           = this._data;\n\n        this._milliseconds = mathAbs(this._milliseconds);\n        this._days         = mathAbs(this._days);\n        this._months       = mathAbs(this._months);\n\n        data.milliseconds  = mathAbs(data.milliseconds);\n        data.seconds       = mathAbs(data.seconds);\n        data.minutes       = mathAbs(data.minutes);\n        data.hours         = mathAbs(data.hours);\n        data.months        = mathAbs(data.months);\n        data.years         = mathAbs(data.years);\n\n        return this;\n    }\n\n    function addSubtract$1 (duration, input, value, direction) {\n        var other = createDuration(input, value);\n\n        duration._milliseconds += direction * other._milliseconds;\n        duration._days         += direction * other._days;\n        duration._months       += direction * other._months;\n\n        return duration._bubble();\n    }\n\n    // supports only 2.0-style add(1, 's') or add(duration)\n    function add$1 (input, value) {\n        return addSubtract$1(this, input, value, 1);\n    }\n\n    // supports only 2.0-style subtract(1, 's') or subtract(duration)\n    function subtract$1 (input, value) {\n        return addSubtract$1(this, input, value, -1);\n    }\n\n    function absCeil (number) {\n        if (number < 0) {\n            return Math.floor(number);\n        } else {\n            return Math.ceil(number);\n        }\n    }\n\n    function bubble () {\n        var milliseconds = this._milliseconds;\n        var days         = this._days;\n        var months       = this._months;\n        var data         = this._data;\n        var seconds, minutes, hours, years, monthsFromDays;\n\n        // if we have a mix of positive and negative values, bubble down first\n        // check: https://github.com/moment/moment/issues/2166\n        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n                (milliseconds <= 0 && days <= 0 && months <= 0))) {\n            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n            days = 0;\n            months = 0;\n        }\n\n        // The following code bubbles up values, see the tests for\n        // examples of what that means.\n        data.milliseconds = milliseconds % 1000;\n\n        seconds           = absFloor(milliseconds / 1000);\n        data.seconds      = seconds % 60;\n\n        minutes           = absFloor(seconds / 60);\n        data.minutes      = minutes % 60;\n\n        hours             = absFloor(minutes / 60);\n        data.hours        = hours % 24;\n\n        days += absFloor(hours / 24);\n\n        // convert days to months\n        monthsFromDays = absFloor(daysToMonths(days));\n        months += monthsFromDays;\n        days -= absCeil(monthsToDays(monthsFromDays));\n\n        // 12 months -> 1 year\n        years = absFloor(months / 12);\n        months %= 12;\n\n        data.days   = days;\n        data.months = months;\n        data.years  = years;\n\n        return this;\n    }\n\n    function daysToMonths (days) {\n        // 400 years have 146097 days (taking into account leap year rules)\n        // 400 years have 12 months === 4800\n        return days * 4800 / 146097;\n    }\n\n    function monthsToDays (months) {\n        // the reverse of daysToMonths\n        return months * 146097 / 4800;\n    }\n\n    function as (units) {\n        if (!this.isValid()) {\n            return NaN;\n        }\n        var days;\n        var months;\n        var milliseconds = this._milliseconds;\n\n        units = normalizeUnits(units);\n\n        if (units === 'month' || units === 'quarter' || units === 'year') {\n            days = this._days + milliseconds / 864e5;\n            months = this._months + daysToMonths(days);\n            switch (units) {\n                case 'month':   return months;\n                case 'quarter': return months / 3;\n                case 'year':    return months / 12;\n            }\n        } else {\n            // handle milliseconds separately because of floating point math errors (issue #1867)\n            days = this._days + Math.round(monthsToDays(this._months));\n            switch (units) {\n                case 'week'   : return days / 7     + milliseconds / 6048e5;\n                case 'day'    : return days         + milliseconds / 864e5;\n                case 'hour'   : return days * 24    + milliseconds / 36e5;\n                case 'minute' : return days * 1440  + milliseconds / 6e4;\n                case 'second' : return days * 86400 + milliseconds / 1000;\n                // Math.floor prevents floating point math errors here\n                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n                default: throw new Error('Unknown unit ' + units);\n            }\n        }\n    }\n\n    // TODO: Use this.as('ms')?\n    function valueOf$1 () {\n        if (!this.isValid()) {\n            return NaN;\n        }\n        return (\n            this._milliseconds +\n            this._days * 864e5 +\n            (this._months % 12) * 2592e6 +\n            toInt(this._months / 12) * 31536e6\n        );\n    }\n\n    function makeAs (alias) {\n        return function () {\n            return this.as(alias);\n        };\n    }\n\n    var asMilliseconds = makeAs('ms');\n    var asSeconds      = makeAs('s');\n    var asMinutes      = makeAs('m');\n    var asHours        = makeAs('h');\n    var asDays         = makeAs('d');\n    var asWeeks        = makeAs('w');\n    var asMonths       = makeAs('M');\n    var asQuarters     = makeAs('Q');\n    var asYears        = makeAs('y');\n\n    function clone$1 () {\n        return createDuration(this);\n    }\n\n    function get$2 (units) {\n        units = normalizeUnits(units);\n        return this.isValid() ? this[units + 's']() : NaN;\n    }\n\n    function makeGetter(name) {\n        return function () {\n            return this.isValid() ? this._data[name] : NaN;\n        };\n    }\n\n    var milliseconds = makeGetter('milliseconds');\n    var seconds      = makeGetter('seconds');\n    var minutes      = makeGetter('minutes');\n    var hours        = makeGetter('hours');\n    var days         = makeGetter('days');\n    var months       = makeGetter('months');\n    var years        = makeGetter('years');\n\n    function weeks () {\n        return absFloor(this.days() / 7);\n    }\n\n    var round = Math.round;\n    var thresholds = {\n        ss: 44,         // a few seconds to seconds\n        s : 45,         // seconds to minute\n        m : 45,         // minutes to hour\n        h : 22,         // hours to day\n        d : 26,         // days to month\n        M : 11          // months to year\n    };\n\n    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\n    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n    }\n\n    function relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n        var duration = createDuration(posNegDuration).abs();\n        var seconds  = round(duration.as('s'));\n        var minutes  = round(duration.as('m'));\n        var hours    = round(duration.as('h'));\n        var days     = round(duration.as('d'));\n        var months   = round(duration.as('M'));\n        var years    = round(duration.as('y'));\n\n        var a = seconds <= thresholds.ss && ['s', seconds]  ||\n                seconds < thresholds.s   && ['ss', seconds] ||\n                minutes <= 1             && ['m']           ||\n                minutes < thresholds.m   && ['mm', minutes] ||\n                hours   <= 1             && ['h']           ||\n                hours   < thresholds.h   && ['hh', hours]   ||\n                days    <= 1             && ['d']           ||\n                days    < thresholds.d   && ['dd', days]    ||\n                months  <= 1             && ['M']           ||\n                months  < thresholds.M   && ['MM', months]  ||\n                years   <= 1             && ['y']           || ['yy', years];\n\n        a[2] = withoutSuffix;\n        a[3] = +posNegDuration > 0;\n        a[4] = locale;\n        return substituteTimeAgo.apply(null, a);\n    }\n\n    // This function allows you to set the rounding function for relative time strings\n    function getSetRelativeTimeRounding (roundingFunction) {\n        if (roundingFunction === undefined) {\n            return round;\n        }\n        if (typeof(roundingFunction) === 'function') {\n            round = roundingFunction;\n            return true;\n        }\n        return false;\n    }\n\n    // This function allows you to set a threshold for relative time strings\n    function getSetRelativeTimeThreshold (threshold, limit) {\n        if (thresholds[threshold] === undefined) {\n            return false;\n        }\n        if (limit === undefined) {\n            return thresholds[threshold];\n        }\n        thresholds[threshold] = limit;\n        if (threshold === 's') {\n            thresholds.ss = limit - 1;\n        }\n        return true;\n    }\n\n    function humanize (withSuffix) {\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n\n        var locale = this.localeData();\n        var output = relativeTime$1(this, !withSuffix, locale);\n\n        if (withSuffix) {\n            output = locale.pastFuture(+this, output);\n        }\n\n        return locale.postformat(output);\n    }\n\n    var abs$1 = Math.abs;\n\n    function sign(x) {\n        return ((x > 0) - (x < 0)) || +x;\n    }\n\n    function toISOString$1() {\n        // for ISO strings we do not use the normal bubbling rules:\n        //  * milliseconds bubble up until they become hours\n        //  * days do not bubble at all\n        //  * months bubble up until they become years\n        // This is because there is no context-free conversion between hours and days\n        // (think of clock changes)\n        // and also not between days and months (28-31 days per month)\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n\n        var seconds = abs$1(this._milliseconds) / 1000;\n        var days         = abs$1(this._days);\n        var months       = abs$1(this._months);\n        var minutes, hours, years;\n\n        // 3600 seconds -> 60 minutes -> 1 hour\n        minutes           = absFloor(seconds / 60);\n        hours             = absFloor(minutes / 60);\n        seconds %= 60;\n        minutes %= 60;\n\n        // 12 months -> 1 year\n        years  = absFloor(months / 12);\n        months %= 12;\n\n\n        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n        var Y = years;\n        var M = months;\n        var D = days;\n        var h = hours;\n        var m = minutes;\n        var s = seconds ? seconds.toFixed(3).replace(/\\.?0+$/, '') : '';\n        var total = this.asSeconds();\n\n        if (!total) {\n            // this is the same as C#'s (Noda) and python (isodate)...\n            // but not other JS (goog.date)\n            return 'P0D';\n        }\n\n        var totalSign = total < 0 ? '-' : '';\n        var ymSign = sign(this._months) !== sign(total) ? '-' : '';\n        var daysSign = sign(this._days) !== sign(total) ? '-' : '';\n        var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';\n\n        return totalSign + 'P' +\n            (Y ? ymSign + Y + 'Y' : '') +\n            (M ? ymSign + M + 'M' : '') +\n            (D ? daysSign + D + 'D' : '') +\n            ((h || m || s) ? 'T' : '') +\n            (h ? hmsSign + h + 'H' : '') +\n            (m ? hmsSign + m + 'M' : '') +\n            (s ? hmsSign + s + 'S' : '');\n    }\n\n    var proto$2 = Duration.prototype;\n\n    proto$2.isValid        = isValid$1;\n    proto$2.abs            = abs;\n    proto$2.add            = add$1;\n    proto$2.subtract       = subtract$1;\n    proto$2.as             = as;\n    proto$2.asMilliseconds = asMilliseconds;\n    proto$2.asSeconds      = asSeconds;\n    proto$2.asMinutes      = asMinutes;\n    proto$2.asHours        = asHours;\n    proto$2.asDays         = asDays;\n    proto$2.asWeeks        = asWeeks;\n    proto$2.asMonths       = asMonths;\n    proto$2.asQuarters     = asQuarters;\n    proto$2.asYears        = asYears;\n    proto$2.valueOf        = valueOf$1;\n    proto$2._bubble        = bubble;\n    proto$2.clone          = clone$1;\n    proto$2.get            = get$2;\n    proto$2.milliseconds   = milliseconds;\n    proto$2.seconds        = seconds;\n    proto$2.minutes        = minutes;\n    proto$2.hours          = hours;\n    proto$2.days           = days;\n    proto$2.weeks          = weeks;\n    proto$2.months         = months;\n    proto$2.years          = years;\n    proto$2.humanize       = humanize;\n    proto$2.toISOString    = toISOString$1;\n    proto$2.toString       = toISOString$1;\n    proto$2.toJSON         = toISOString$1;\n    proto$2.locale         = locale;\n    proto$2.localeData     = localeData;\n\n    proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\n    proto$2.lang = lang;\n\n    // Side effect imports\n\n    // FORMATTING\n\n    addFormatToken('X', 0, 0, 'unix');\n    addFormatToken('x', 0, 0, 'valueOf');\n\n    // PARSING\n\n    addRegexToken('x', matchSigned);\n    addRegexToken('X', matchTimestamp);\n    addParseToken('X', function (input, array, config) {\n        config._d = new Date(parseFloat(input, 10) * 1000);\n    });\n    addParseToken('x', function (input, array, config) {\n        config._d = new Date(toInt(input));\n    });\n\n    // Side effect imports\n\n\n    hooks.version = '2.24.0';\n\n    setHookCallback(createLocal);\n\n    hooks.fn                    = proto;\n    hooks.min                   = min;\n    hooks.max                   = max;\n    hooks.now                   = now;\n    hooks.utc                   = createUTC;\n    hooks.unix                  = createUnix;\n    hooks.months                = listMonths;\n    hooks.isDate                = isDate;\n    hooks.locale                = getSetGlobalLocale;\n    hooks.invalid               = createInvalid;\n    hooks.duration              = createDuration;\n    hooks.isMoment              = isMoment;\n    hooks.weekdays              = listWeekdays;\n    hooks.parseZone             = createInZone;\n    hooks.localeData            = getLocale;\n    hooks.isDuration            = isDuration;\n    hooks.monthsShort           = listMonthsShort;\n    hooks.weekdaysMin           = listWeekdaysMin;\n    hooks.defineLocale          = defineLocale;\n    hooks.updateLocale          = updateLocale;\n    hooks.locales               = listLocales;\n    hooks.weekdaysShort         = listWeekdaysShort;\n    hooks.normalizeUnits        = normalizeUnits;\n    hooks.relativeTimeRounding  = getSetRelativeTimeRounding;\n    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\n    hooks.calendarFormat        = getCalendarFormat;\n    hooks.prototype             = proto;\n\n    // currently HTML5 input type only supports 24-hour formats\n    hooks.HTML5_FMT = {\n        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type=\"datetime-local\" />\n        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type=\"datetime-local\" step=\"1\" />\n        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type=\"datetime-local\" step=\"0.001\" />\n        DATE: 'YYYY-MM-DD',                             // <input type=\"date\" />\n        TIME: 'HH:mm',                                  // <input type=\"time\" />\n        TIME_SECONDS: 'HH:mm:ss',                       // <input type=\"time\" step=\"1\" />\n        TIME_MS: 'HH:mm:ss.SSS',                        // <input type=\"time\" step=\"0.001\" />\n        WEEK: 'GGGG-[W]WW',                             // <input type=\"week\" />\n        MONTH: 'YYYY-MM'                                // <input type=\"month\" />\n    };\n\n    return hooks;\n\n})));\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/module.js */ \"f586\")(module)))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGEwMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9tb21lbnQvbW9tZW50LmpzP2MxZGYiXSwic291cmNlc0NvbnRlbnQiOlsiLy8hIG1vbWVudC5qc1xuXG47KGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG4gICAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgICBnbG9iYWwubW9tZW50ID0gZmFjdG9yeSgpXG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuICAgIHZhciBob29rQ2FsbGJhY2s7XG5cbiAgICBmdW5jdGlvbiBob29rcyAoKSB7XG4gICAgICAgIHJldHVybiBob29rQ2FsbGJhY2suYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGlzIGRvbmUgdG8gcmVnaXN0ZXIgdGhlIG1ldGhvZCBjYWxsZWQgd2l0aCBtb21lbnQoKVxuICAgIC8vIHdpdGhvdXQgY3JlYXRpbmcgY2lyY3VsYXIgZGVwZW5kZW5jaWVzLlxuICAgIGZ1bmN0aW9uIHNldEhvb2tDYWxsYmFjayAoY2FsbGJhY2spIHtcbiAgICAgICAgaG9va0NhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBcnJheShpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXQgaW5zdGFuY2VvZiBBcnJheSB8fCBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaW5wdXQpID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzT2JqZWN0KGlucHV0KSB7XG4gICAgICAgIC8vIElFOCB3aWxsIHRyZWF0IHVuZGVmaW5lZCBhbmQgbnVsbCBhcyBvYmplY3QgaWYgaXQgd2Fzbid0IGZvclxuICAgICAgICAvLyBpbnB1dCAhPSBudWxsXG4gICAgICAgIHJldHVybiBpbnB1dCAhPSBudWxsICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IE9iamVjdF0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzT2JqZWN0RW1wdHkob2JqKSB7XG4gICAgICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcykge1xuICAgICAgICAgICAgcmV0dXJuIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCA9PT0gMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaztcbiAgICAgICAgICAgIGZvciAoayBpbiBvYmopIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVW5kZWZpbmVkKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBpbnB1dCA9PT0gdm9pZCAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzTnVtYmVyKGlucHV0KSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IE51bWJlcl0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzRGF0ZShpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXQgaW5zdGFuY2VvZiBEYXRlIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IERhdGVdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXAoYXJyLCBmbikge1xuICAgICAgICB2YXIgcmVzID0gW10sIGk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHJlcy5wdXNoKGZuKGFycltpXSwgaSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzT3duUHJvcChhLCBiKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSwgYik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXh0ZW5kKGEsIGIpIHtcbiAgICAgICAgZm9yICh2YXIgaSBpbiBiKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChiLCBpKSkge1xuICAgICAgICAgICAgICAgIGFbaV0gPSBiW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc093blByb3AoYiwgJ3RvU3RyaW5nJykpIHtcbiAgICAgICAgICAgIGEudG9TdHJpbmcgPSBiLnRvU3RyaW5nO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc093blByb3AoYiwgJ3ZhbHVlT2YnKSkge1xuICAgICAgICAgICAgYS52YWx1ZU9mID0gYi52YWx1ZU9mO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlVVRDIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWxPclVUQyhpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCwgdHJ1ZSkudXRjKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmYXVsdFBhcnNpbmdGbGFncygpIHtcbiAgICAgICAgLy8gV2UgbmVlZCB0byBkZWVwIGNsb25lIHRoaXMgb2JqZWN0LlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZW1wdHkgICAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICB1bnVzZWRUb2tlbnMgICAgOiBbXSxcbiAgICAgICAgICAgIHVudXNlZElucHV0ICAgICA6IFtdLFxuICAgICAgICAgICAgb3ZlcmZsb3cgICAgICAgIDogLTIsXG4gICAgICAgICAgICBjaGFyc0xlZnRPdmVyICAgOiAwLFxuICAgICAgICAgICAgbnVsbElucHV0ICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICBpbnZhbGlkTW9udGggICAgOiBudWxsLFxuICAgICAgICAgICAgaW52YWxpZEZvcm1hdCAgIDogZmFsc2UsXG4gICAgICAgICAgICB1c2VySW52YWxpZGF0ZWQgOiBmYWxzZSxcbiAgICAgICAgICAgIGlzbyAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICAgICAgcGFyc2VkRGF0ZVBhcnRzIDogW10sXG4gICAgICAgICAgICBtZXJpZGllbSAgICAgICAgOiBudWxsLFxuICAgICAgICAgICAgcmZjMjgyMiAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICB3ZWVrZGF5TWlzbWF0Y2ggOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFBhcnNpbmdGbGFncyhtKSB7XG4gICAgICAgIGlmIChtLl9wZiA9PSBudWxsKSB7XG4gICAgICAgICAgICBtLl9wZiA9IGRlZmF1bHRQYXJzaW5nRmxhZ3MoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbS5fcGY7XG4gICAgfVxuXG4gICAgdmFyIHNvbWU7XG4gICAgaWYgKEFycmF5LnByb3RvdHlwZS5zb21lKSB7XG4gICAgICAgIHNvbWUgPSBBcnJheS5wcm90b3R5cGUuc29tZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBzb21lID0gZnVuY3Rpb24gKGZ1bikge1xuICAgICAgICAgICAgdmFyIHQgPSBPYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgbGVuID0gdC5sZW5ndGggPj4+IDA7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiB0ICYmIGZ1bi5jYWxsKHRoaXMsIHRbaV0sIGksIHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVmFsaWQobSkge1xuICAgICAgICBpZiAobS5faXNWYWxpZCA9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgZmxhZ3MgPSBnZXRQYXJzaW5nRmxhZ3MobSk7XG4gICAgICAgICAgICB2YXIgcGFyc2VkUGFydHMgPSBzb21lLmNhbGwoZmxhZ3MucGFyc2VkRGF0ZVBhcnRzLCBmdW5jdGlvbiAoaSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpICE9IG51bGw7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhciBpc05vd1ZhbGlkID0gIWlzTmFOKG0uX2QuZ2V0VGltZSgpKSAmJlxuICAgICAgICAgICAgICAgIGZsYWdzLm92ZXJmbG93IDwgMCAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5lbXB0eSAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5pbnZhbGlkTW9udGggJiZcbiAgICAgICAgICAgICAgICAhZmxhZ3MuaW52YWxpZFdlZWtkYXkgJiZcbiAgICAgICAgICAgICAgICAhZmxhZ3Mud2Vla2RheU1pc21hdGNoICYmXG4gICAgICAgICAgICAgICAgIWZsYWdzLm51bGxJbnB1dCAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5pbnZhbGlkRm9ybWF0ICYmXG4gICAgICAgICAgICAgICAgIWZsYWdzLnVzZXJJbnZhbGlkYXRlZCAmJlxuICAgICAgICAgICAgICAgICghZmxhZ3MubWVyaWRpZW0gfHwgKGZsYWdzLm1lcmlkaWVtICYmIHBhcnNlZFBhcnRzKSk7XG5cbiAgICAgICAgICAgIGlmIChtLl9zdHJpY3QpIHtcbiAgICAgICAgICAgICAgICBpc05vd1ZhbGlkID0gaXNOb3dWYWxpZCAmJlxuICAgICAgICAgICAgICAgICAgICBmbGFncy5jaGFyc0xlZnRPdmVyID09PSAwICYmXG4gICAgICAgICAgICAgICAgICAgIGZsYWdzLnVudXNlZFRva2Vucy5sZW5ndGggPT09IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgZmxhZ3MuYmlnSG91ciA9PT0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoT2JqZWN0LmlzRnJvemVuID09IG51bGwgfHwgIU9iamVjdC5pc0Zyb3plbihtKSkge1xuICAgICAgICAgICAgICAgIG0uX2lzVmFsaWQgPSBpc05vd1ZhbGlkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzTm93VmFsaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG0uX2lzVmFsaWQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlSW52YWxpZCAoZmxhZ3MpIHtcbiAgICAgICAgdmFyIG0gPSBjcmVhdGVVVEMoTmFOKTtcbiAgICAgICAgaWYgKGZsYWdzICE9IG51bGwpIHtcbiAgICAgICAgICAgIGV4dGVuZChnZXRQYXJzaW5nRmxhZ3MobSksIGZsYWdzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhtKS51c2VySW52YWxpZGF0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG07XG4gICAgfVxuXG4gICAgLy8gUGx1Z2lucyB0aGF0IGFkZCBwcm9wZXJ0aWVzIHNob3VsZCBhbHNvIGFkZCB0aGUga2V5IGhlcmUgKG51bGwgdmFsdWUpLFxuICAgIC8vIHNvIHdlIGNhbiBwcm9wZXJseSBjbG9uZSBvdXJzZWx2ZXMuXG4gICAgdmFyIG1vbWVudFByb3BlcnRpZXMgPSBob29rcy5tb21lbnRQcm9wZXJ0aWVzID0gW107XG5cbiAgICBmdW5jdGlvbiBjb3B5Q29uZmlnKHRvLCBmcm9tKSB7XG4gICAgICAgIHZhciBpLCBwcm9wLCB2YWw7XG5cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9pc0FNb21lbnRPYmplY3QpKSB7XG4gICAgICAgICAgICB0by5faXNBTW9tZW50T2JqZWN0ID0gZnJvbS5faXNBTW9tZW50T2JqZWN0O1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5faSkpIHtcbiAgICAgICAgICAgIHRvLl9pID0gZnJvbS5faTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX2YpKSB7XG4gICAgICAgICAgICB0by5fZiA9IGZyb20uX2Y7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9sKSkge1xuICAgICAgICAgICAgdG8uX2wgPSBmcm9tLl9sO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fc3RyaWN0KSkge1xuICAgICAgICAgICAgdG8uX3N0cmljdCA9IGZyb20uX3N0cmljdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX3R6bSkpIHtcbiAgICAgICAgICAgIHRvLl90em0gPSBmcm9tLl90em07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9pc1VUQykpIHtcbiAgICAgICAgICAgIHRvLl9pc1VUQyA9IGZyb20uX2lzVVRDO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fb2Zmc2V0KSkge1xuICAgICAgICAgICAgdG8uX29mZnNldCA9IGZyb20uX29mZnNldDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX3BmKSkge1xuICAgICAgICAgICAgdG8uX3BmID0gZ2V0UGFyc2luZ0ZsYWdzKGZyb20pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fbG9jYWxlKSkge1xuICAgICAgICAgICAgdG8uX2xvY2FsZSA9IGZyb20uX2xvY2FsZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtb21lbnRQcm9wZXJ0aWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBtb21lbnRQcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcHJvcCA9IG1vbWVudFByb3BlcnRpZXNbaV07XG4gICAgICAgICAgICAgICAgdmFsID0gZnJvbVtwcm9wXTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKHZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9bcHJvcF0gPSB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRvO1xuICAgIH1cblxuICAgIHZhciB1cGRhdGVJblByb2dyZXNzID0gZmFsc2U7XG5cbiAgICAvLyBNb21lbnQgcHJvdG90eXBlIG9iamVjdFxuICAgIGZ1bmN0aW9uIE1vbWVudChjb25maWcpIHtcbiAgICAgICAgY29weUNvbmZpZyh0aGlzLCBjb25maWcpO1xuICAgICAgICB0aGlzLl9kID0gbmV3IERhdGUoY29uZmlnLl9kICE9IG51bGwgPyBjb25maWcuX2QuZ2V0VGltZSgpIDogTmFOKTtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgdGhpcy5fZCA9IG5ldyBEYXRlKE5hTik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUHJldmVudCBpbmZpbml0ZSBsb29wIGluIGNhc2UgdXBkYXRlT2Zmc2V0IGNyZWF0ZXMgbmV3IG1vbWVudFxuICAgICAgICAvLyBvYmplY3RzLlxuICAgICAgICBpZiAodXBkYXRlSW5Qcm9ncmVzcyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHVwZGF0ZUluUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMpO1xuICAgICAgICAgICAgdXBkYXRlSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNNb21lbnQgKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgTW9tZW50IHx8IChvYmogIT0gbnVsbCAmJiBvYmouX2lzQU1vbWVudE9iamVjdCAhPSBudWxsKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhYnNGbG9vciAobnVtYmVyKSB7XG4gICAgICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICAgICAgICAvLyAtMCAtPiAwXG4gICAgICAgICAgICByZXR1cm4gTWF0aC5jZWlsKG51bWJlcikgfHwgMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKG51bWJlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0ludChhcmd1bWVudEZvckNvZXJjaW9uKSB7XG4gICAgICAgIHZhciBjb2VyY2VkTnVtYmVyID0gK2FyZ3VtZW50Rm9yQ29lcmNpb24sXG4gICAgICAgICAgICB2YWx1ZSA9IDA7XG5cbiAgICAgICAgaWYgKGNvZXJjZWROdW1iZXIgIT09IDAgJiYgaXNGaW5pdGUoY29lcmNlZE51bWJlcikpIHtcbiAgICAgICAgICAgIHZhbHVlID0gYWJzRmxvb3IoY29lcmNlZE51bWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gY29tcGFyZSB0d28gYXJyYXlzLCByZXR1cm4gdGhlIG51bWJlciBvZiBkaWZmZXJlbmNlc1xuICAgIGZ1bmN0aW9uIGNvbXBhcmVBcnJheXMoYXJyYXkxLCBhcnJheTIsIGRvbnRDb252ZXJ0KSB7XG4gICAgICAgIHZhciBsZW4gPSBNYXRoLm1pbihhcnJheTEubGVuZ3RoLCBhcnJheTIubGVuZ3RoKSxcbiAgICAgICAgICAgIGxlbmd0aERpZmYgPSBNYXRoLmFicyhhcnJheTEubGVuZ3RoIC0gYXJyYXkyLmxlbmd0aCksXG4gICAgICAgICAgICBkaWZmcyA9IDAsXG4gICAgICAgICAgICBpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmICgoZG9udENvbnZlcnQgJiYgYXJyYXkxW2ldICE9PSBhcnJheTJbaV0pIHx8XG4gICAgICAgICAgICAgICAgKCFkb250Q29udmVydCAmJiB0b0ludChhcnJheTFbaV0pICE9PSB0b0ludChhcnJheTJbaV0pKSkge1xuICAgICAgICAgICAgICAgIGRpZmZzKys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRpZmZzICsgbGVuZ3RoRGlmZjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3YXJuKG1zZykge1xuICAgICAgICBpZiAoaG9va3Muc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmdzID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICh0eXBlb2YgY29uc29sZSAhPT0gICd1bmRlZmluZWQnKSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRGVwcmVjYXRpb24gd2FybmluZzogJyArIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkZXByZWNhdGUobXNnLCBmbikge1xuICAgICAgICB2YXIgZmlyc3RUaW1lID0gdHJ1ZTtcblxuICAgICAgICByZXR1cm4gZXh0ZW5kKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChob29rcy5kZXByZWNhdGlvbkhhbmRsZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGhvb2tzLmRlcHJlY2F0aW9uSGFuZGxlcihudWxsLCBtc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZpcnN0VGltZSkge1xuICAgICAgICAgICAgICAgIHZhciBhcmdzID0gW107XG4gICAgICAgICAgICAgICAgdmFyIGFyZztcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBhcmcgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbaV0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgKz0gJ1xcblsnICsgaSArICddICc7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gYXJndW1lbnRzWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnICs9IGtleSArICc6ICcgKyBhcmd1bWVudHNbMF1ba2V5XSArICcsICc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBhcmcuc2xpY2UoMCwgLTIpOyAvLyBSZW1vdmUgdHJhaWxpbmcgY29tbWEgYW5kIHNwYWNlXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKGFyZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdhcm4obXNnICsgJ1xcbkFyZ3VtZW50czogJyArIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MpLmpvaW4oJycpICsgJ1xcbicgKyAobmV3IEVycm9yKCkpLnN0YWNrKTtcbiAgICAgICAgICAgICAgICBmaXJzdFRpbWUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9LCBmbik7XG4gICAgfVxuXG4gICAgdmFyIGRlcHJlY2F0aW9ucyA9IHt9O1xuXG4gICAgZnVuY3Rpb24gZGVwcmVjYXRlU2ltcGxlKG5hbWUsIG1zZykge1xuICAgICAgICBpZiAoaG9va3MuZGVwcmVjYXRpb25IYW5kbGVyICE9IG51bGwpIHtcbiAgICAgICAgICAgIGhvb2tzLmRlcHJlY2F0aW9uSGFuZGxlcihuYW1lLCBtc2cpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZGVwcmVjYXRpb25zW25hbWVdKSB7XG4gICAgICAgICAgICB3YXJuKG1zZyk7XG4gICAgICAgICAgICBkZXByZWNhdGlvbnNbbmFtZV0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaG9va3Muc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmdzID0gZmFsc2U7XG4gICAgaG9va3MuZGVwcmVjYXRpb25IYW5kbGVyID0gbnVsbDtcblxuICAgIGZ1bmN0aW9uIGlzRnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0IGluc3RhbmNlb2YgRnVuY3Rpb24gfHwgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGlucHV0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXQgKGNvbmZpZykge1xuICAgICAgICB2YXIgcHJvcCwgaTtcbiAgICAgICAgZm9yIChpIGluIGNvbmZpZykge1xuICAgICAgICAgICAgcHJvcCA9IGNvbmZpZ1tpXTtcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHByb3ApKSB7XG4gICAgICAgICAgICAgICAgdGhpc1tpXSA9IHByb3A7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXNbJ18nICsgaV0gPSBwcm9wO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgLy8gTGVuaWVudCBvcmRpbmFsIHBhcnNpbmcgYWNjZXB0cyBqdXN0IGEgbnVtYmVyIGluIGFkZGl0aW9uIHRvXG4gICAgICAgIC8vIG51bWJlciArIChwb3NzaWJseSkgc3R1ZmYgY29taW5nIGZyb20gX2RheU9mTW9udGhPcmRpbmFsUGFyc2UuXG4gICAgICAgIC8vIFRPRE86IFJlbW92ZSBcIm9yZGluYWxQYXJzZVwiIGZhbGxiYWNrIGluIG5leHQgbWFqb3IgcmVsZWFzZS5cbiAgICAgICAgdGhpcy5fZGF5T2ZNb250aE9yZGluYWxQYXJzZUxlbmllbnQgPSBuZXcgUmVnRXhwKFxuICAgICAgICAgICAgKHRoaXMuX2RheU9mTW9udGhPcmRpbmFsUGFyc2Uuc291cmNlIHx8IHRoaXMuX29yZGluYWxQYXJzZS5zb3VyY2UpICtcbiAgICAgICAgICAgICAgICAnfCcgKyAoL1xcZHsxLDJ9Lykuc291cmNlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtZXJnZUNvbmZpZ3MocGFyZW50Q29uZmlnLCBjaGlsZENvbmZpZykge1xuICAgICAgICB2YXIgcmVzID0gZXh0ZW5kKHt9LCBwYXJlbnRDb25maWcpLCBwcm9wO1xuICAgICAgICBmb3IgKHByb3AgaW4gY2hpbGRDb25maWcpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd25Qcm9wKGNoaWxkQ29uZmlnLCBwcm9wKSkge1xuICAgICAgICAgICAgICAgIGlmIChpc09iamVjdChwYXJlbnRDb25maWdbcHJvcF0pICYmIGlzT2JqZWN0KGNoaWxkQ29uZmlnW3Byb3BdKSkge1xuICAgICAgICAgICAgICAgICAgICByZXNbcHJvcF0gPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kKHJlc1twcm9wXSwgcGFyZW50Q29uZmlnW3Byb3BdKTtcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kKHJlc1twcm9wXSwgY2hpbGRDb25maWdbcHJvcF0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hpbGRDb25maWdbcHJvcF0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXNbcHJvcF0gPSBjaGlsZENvbmZpZ1twcm9wXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcmVzW3Byb3BdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKHByb3AgaW4gcGFyZW50Q29uZmlnKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChwYXJlbnRDb25maWcsIHByb3ApICYmXG4gICAgICAgICAgICAgICAgICAgICFoYXNPd25Qcm9wKGNoaWxkQ29uZmlnLCBwcm9wKSAmJlxuICAgICAgICAgICAgICAgICAgICBpc09iamVjdChwYXJlbnRDb25maWdbcHJvcF0pKSB7XG4gICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGNoYW5nZXMgdG8gcHJvcGVydGllcyBkb24ndCBtb2RpZnkgcGFyZW50IGNvbmZpZ1xuICAgICAgICAgICAgICAgIHJlc1twcm9wXSA9IGV4dGVuZCh7fSwgcmVzW3Byb3BdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIExvY2FsZShjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZyAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnNldChjb25maWcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGtleXM7XG5cbiAgICBpZiAoT2JqZWN0LmtleXMpIHtcbiAgICAgICAga2V5cyA9IE9iamVjdC5rZXlzO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGtleXMgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICB2YXIgaSwgcmVzID0gW107XG4gICAgICAgICAgICBmb3IgKGkgaW4gb2JqKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhc093blByb3Aob2JqLCBpKSkge1xuICAgICAgICAgICAgICAgICAgICByZXMucHVzaChpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0Q2FsZW5kYXIgPSB7XG4gICAgICAgIHNhbWVEYXkgOiAnW1RvZGF5IGF0XSBMVCcsXG4gICAgICAgIG5leHREYXkgOiAnW1RvbW9ycm93IGF0XSBMVCcsXG4gICAgICAgIG5leHRXZWVrIDogJ2RkZGQgW2F0XSBMVCcsXG4gICAgICAgIGxhc3REYXkgOiAnW1llc3RlcmRheSBhdF0gTFQnLFxuICAgICAgICBsYXN0V2VlayA6ICdbTGFzdF0gZGRkZCBbYXRdIExUJyxcbiAgICAgICAgc2FtZUVsc2UgOiAnTCdcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gY2FsZW5kYXIgKGtleSwgbW9tLCBub3cpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX2NhbGVuZGFyW2tleV0gfHwgdGhpcy5fY2FsZW5kYXJbJ3NhbWVFbHNlJ107XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKG91dHB1dCkgPyBvdXRwdXQuY2FsbChtb20sIG5vdykgOiBvdXRwdXQ7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb25nRGF0ZUZvcm1hdCA9IHtcbiAgICAgICAgTFRTICA6ICdoOm1tOnNzIEEnLFxuICAgICAgICBMVCAgIDogJ2g6bW0gQScsXG4gICAgICAgIEwgICAgOiAnTU0vREQvWVlZWScsXG4gICAgICAgIExMICAgOiAnTU1NTSBELCBZWVlZJyxcbiAgICAgICAgTExMICA6ICdNTU1NIEQsIFlZWVkgaDptbSBBJyxcbiAgICAgICAgTExMTCA6ICdkZGRkLCBNTU1NIEQsIFlZWVkgaDptbSBBJ1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb25nRGF0ZUZvcm1hdCAoa2V5KSB7XG4gICAgICAgIHZhciBmb3JtYXQgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldLFxuICAgICAgICAgICAgZm9ybWF0VXBwZXIgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXkudG9VcHBlckNhc2UoKV07XG5cbiAgICAgICAgaWYgKGZvcm1hdCB8fCAhZm9ybWF0VXBwZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldID0gZm9ybWF0VXBwZXIucmVwbGFjZSgvTU1NTXxNTXxERHxkZGRkL2csIGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWwuc2xpY2UoMSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0SW52YWxpZERhdGUgPSAnSW52YWxpZCBkYXRlJztcblxuICAgIGZ1bmN0aW9uIGludmFsaWREYXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ludmFsaWREYXRlO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0T3JkaW5hbCA9ICclZCc7XG4gICAgdmFyIGRlZmF1bHREYXlPZk1vbnRoT3JkaW5hbFBhcnNlID0gL1xcZHsxLDJ9LztcblxuICAgIGZ1bmN0aW9uIG9yZGluYWwgKG51bWJlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3JkaW5hbC5yZXBsYWNlKCclZCcsIG51bWJlcik7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRSZWxhdGl2ZVRpbWUgPSB7XG4gICAgICAgIGZ1dHVyZSA6ICdpbiAlcycsXG4gICAgICAgIHBhc3QgICA6ICclcyBhZ28nLFxuICAgICAgICBzICA6ICdhIGZldyBzZWNvbmRzJyxcbiAgICAgICAgc3MgOiAnJWQgc2Vjb25kcycsXG4gICAgICAgIG0gIDogJ2EgbWludXRlJyxcbiAgICAgICAgbW0gOiAnJWQgbWludXRlcycsXG4gICAgICAgIGggIDogJ2FuIGhvdXInLFxuICAgICAgICBoaCA6ICclZCBob3VycycsXG4gICAgICAgIGQgIDogJ2EgZGF5JyxcbiAgICAgICAgZGQgOiAnJWQgZGF5cycsXG4gICAgICAgIE0gIDogJ2EgbW9udGgnLFxuICAgICAgICBNTSA6ICclZCBtb250aHMnLFxuICAgICAgICB5ICA6ICdhIHllYXInLFxuICAgICAgICB5eSA6ICclZCB5ZWFycydcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcmVsYXRpdmVUaW1lIChudW1iZXIsIHdpdGhvdXRTdWZmaXgsIHN0cmluZywgaXNGdXR1cmUpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX3JlbGF0aXZlVGltZVtzdHJpbmddO1xuICAgICAgICByZXR1cm4gKGlzRnVuY3Rpb24ob3V0cHV0KSkgP1xuICAgICAgICAgICAgb3V0cHV0KG51bWJlciwgd2l0aG91dFN1ZmZpeCwgc3RyaW5nLCBpc0Z1dHVyZSkgOlxuICAgICAgICAgICAgb3V0cHV0LnJlcGxhY2UoLyVkL2ksIG51bWJlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFzdEZ1dHVyZSAoZGlmZiwgb3V0cHV0KSB7XG4gICAgICAgIHZhciBmb3JtYXQgPSB0aGlzLl9yZWxhdGl2ZVRpbWVbZGlmZiA+IDAgPyAnZnV0dXJlJyA6ICdwYXN0J107XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKGZvcm1hdCkgPyBmb3JtYXQob3V0cHV0KSA6IGZvcm1hdC5yZXBsYWNlKC8lcy9pLCBvdXRwdXQpO1xuICAgIH1cblxuICAgIHZhciBhbGlhc2VzID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRVbml0QWxpYXMgKHVuaXQsIHNob3J0aGFuZCkge1xuICAgICAgICB2YXIgbG93ZXJDYXNlID0gdW5pdC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBhbGlhc2VzW2xvd2VyQ2FzZV0gPSBhbGlhc2VzW2xvd2VyQ2FzZSArICdzJ10gPSBhbGlhc2VzW3Nob3J0aGFuZF0gPSB1bml0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdW5pdHMgPT09ICdzdHJpbmcnID8gYWxpYXNlc1t1bml0c10gfHwgYWxpYXNlc1t1bml0cy50b0xvd2VyQ2FzZSgpXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBub3JtYWxpemVPYmplY3RVbml0cyhpbnB1dE9iamVjdCkge1xuICAgICAgICB2YXIgbm9ybWFsaXplZElucHV0ID0ge30sXG4gICAgICAgICAgICBub3JtYWxpemVkUHJvcCxcbiAgICAgICAgICAgIHByb3A7XG5cbiAgICAgICAgZm9yIChwcm9wIGluIGlucHV0T2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChpbnB1dE9iamVjdCwgcHJvcCkpIHtcbiAgICAgICAgICAgICAgICBub3JtYWxpemVkUHJvcCA9IG5vcm1hbGl6ZVVuaXRzKHByb3ApO1xuICAgICAgICAgICAgICAgIGlmIChub3JtYWxpemVkUHJvcCkge1xuICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkSW5wdXRbbm9ybWFsaXplZFByb3BdID0gaW5wdXRPYmplY3RbcHJvcF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRJbnB1dDtcbiAgICB9XG5cbiAgICB2YXIgcHJpb3JpdGllcyA9IHt9O1xuXG4gICAgZnVuY3Rpb24gYWRkVW5pdFByaW9yaXR5KHVuaXQsIHByaW9yaXR5KSB7XG4gICAgICAgIHByaW9yaXRpZXNbdW5pdF0gPSBwcmlvcml0eTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRQcmlvcml0aXplZFVuaXRzKHVuaXRzT2JqKSB7XG4gICAgICAgIHZhciB1bml0cyA9IFtdO1xuICAgICAgICBmb3IgKHZhciB1IGluIHVuaXRzT2JqKSB7XG4gICAgICAgICAgICB1bml0cy5wdXNoKHt1bml0OiB1LCBwcmlvcml0eTogcHJpb3JpdGllc1t1XX0pO1xuICAgICAgICB9XG4gICAgICAgIHVuaXRzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgIHJldHVybiBhLnByaW9yaXR5IC0gYi5wcmlvcml0eTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB1bml0cztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB6ZXJvRmlsbChudW1iZXIsIHRhcmdldExlbmd0aCwgZm9yY2VTaWduKSB7XG4gICAgICAgIHZhciBhYnNOdW1iZXIgPSAnJyArIE1hdGguYWJzKG51bWJlciksXG4gICAgICAgICAgICB6ZXJvc1RvRmlsbCA9IHRhcmdldExlbmd0aCAtIGFic051bWJlci5sZW5ndGgsXG4gICAgICAgICAgICBzaWduID0gbnVtYmVyID49IDA7XG4gICAgICAgIHJldHVybiAoc2lnbiA/IChmb3JjZVNpZ24gPyAnKycgOiAnJykgOiAnLScpICtcbiAgICAgICAgICAgIE1hdGgucG93KDEwLCBNYXRoLm1heCgwLCB6ZXJvc1RvRmlsbCkpLnRvU3RyaW5nKCkuc3Vic3RyKDEpICsgYWJzTnVtYmVyO1xuICAgIH1cblxuICAgIHZhciBmb3JtYXR0aW5nVG9rZW5zID0gLyhcXFtbXlxcW10qXFxdKXwoXFxcXCk/KFtIaF1tbShzcyk/fE1vfE1NP00/TT98RG98REREb3xERD9EP0Q/fGRkZD9kP3xkbz98d1tvfHddP3xXW298V10/fFFvP3xZWVlZWVl8WVlZWVl8WVlZWXxZWXxnZyhnZ2c/KT98R0coR0dHPyk/fGV8RXxhfEF8aGg/fEhIP3xraz98bW0/fHNzP3xTezEsOX18eHxYfHp6P3xaWj98LikvZztcblxuICAgIHZhciBsb2NhbEZvcm1hdHRpbmdUb2tlbnMgPSAvKFxcW1teXFxbXSpcXF0pfChcXFxcKT8oTFRTfExUfExMP0w/TD98bHsxLDR9KS9nO1xuXG4gICAgdmFyIGZvcm1hdEZ1bmN0aW9ucyA9IHt9O1xuXG4gICAgdmFyIGZvcm1hdFRva2VuRnVuY3Rpb25zID0ge307XG5cbiAgICAvLyB0b2tlbjogICAgJ00nXG4gICAgLy8gcGFkZGVkOiAgIFsnTU0nLCAyXVxuICAgIC8vIG9yZGluYWw6ICAnTW8nXG4gICAgLy8gY2FsbGJhY2s6IGZ1bmN0aW9uICgpIHsgdGhpcy5tb250aCgpICsgMSB9XG4gICAgZnVuY3Rpb24gYWRkRm9ybWF0VG9rZW4gKHRva2VuLCBwYWRkZWQsIG9yZGluYWwsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBmdW5jID0gY2FsbGJhY2s7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBmdW5jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW2NhbGxiYWNrXSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9rZW4pIHtcbiAgICAgICAgICAgIGZvcm1hdFRva2VuRnVuY3Rpb25zW3Rva2VuXSA9IGZ1bmM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhZGRlZCkge1xuICAgICAgICAgICAgZm9ybWF0VG9rZW5GdW5jdGlvbnNbcGFkZGVkWzBdXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gemVyb0ZpbGwoZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpLCBwYWRkZWRbMV0sIHBhZGRlZFsyXSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcmRpbmFsKSB7XG4gICAgICAgICAgICBmb3JtYXRUb2tlbkZ1bmN0aW9uc1tvcmRpbmFsXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkub3JkaW5hbChmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIHRva2VuKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGlucHV0KSB7XG4gICAgICAgIGlmIChpbnB1dC5tYXRjaCgvXFxbW1xcc1xcU10vKSkge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL15cXFt8XFxdJC9nLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL1xcXFwvZywgJycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VGb3JtYXRGdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgICAgdmFyIGFycmF5ID0gZm9ybWF0Lm1hdGNoKGZvcm1hdHRpbmdUb2tlbnMpLCBpLCBsZW5ndGg7XG5cbiAgICAgICAgZm9yIChpID0gMCwgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXRUb2tlbkZ1bmN0aW9uc1thcnJheVtpXV0pIHtcbiAgICAgICAgICAgICAgICBhcnJheVtpXSA9IGZvcm1hdFRva2VuRnVuY3Rpb25zW2FycmF5W2ldXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXJyYXlbaV0gPSByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGFycmF5W2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAobW9tKSB7XG4gICAgICAgICAgICB2YXIgb3V0cHV0ID0gJycsIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gaXNGdW5jdGlvbihhcnJheVtpXSkgPyBhcnJheVtpXS5jYWxsKG1vbSwgZm9ybWF0KSA6IGFycmF5W2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBmb3JtYXQgZGF0ZSB1c2luZyBuYXRpdmUgZGF0ZSBvYmplY3RcbiAgICBmdW5jdGlvbiBmb3JtYXRNb21lbnQobSwgZm9ybWF0KSB7XG4gICAgICAgIGlmICghbS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBtLmxvY2FsZURhdGEoKS5pbnZhbGlkRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9ybWF0ID0gZXhwYW5kRm9ybWF0KGZvcm1hdCwgbS5sb2NhbGVEYXRhKCkpO1xuICAgICAgICBmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XSA9IGZvcm1hdEZ1bmN0aW9uc1tmb3JtYXRdIHx8IG1ha2VGb3JtYXRGdW5jdGlvbihmb3JtYXQpO1xuXG4gICAgICAgIHJldHVybiBmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XShtKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBleHBhbmRGb3JtYXQoZm9ybWF0LCBsb2NhbGUpIHtcbiAgICAgICAgdmFyIGkgPSA1O1xuXG4gICAgICAgIGZ1bmN0aW9uIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2VucyhpbnB1dCkge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS5sb25nRGF0ZUZvcm1hdChpbnB1dCkgfHwgaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPj0gMCAmJiBsb2NhbEZvcm1hdHRpbmdUb2tlbnMudGVzdChmb3JtYXQpKSB7XG4gICAgICAgICAgICBmb3JtYXQgPSBmb3JtYXQucmVwbGFjZShsb2NhbEZvcm1hdHRpbmdUb2tlbnMsIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2Vucyk7XG4gICAgICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgfVxuXG4gICAgdmFyIG1hdGNoMSAgICAgICAgID0gL1xcZC87ICAgICAgICAgICAgLy8gICAgICAgMCAtIDlcbiAgICB2YXIgbWF0Y2gyICAgICAgICAgPSAvXFxkXFxkLzsgICAgICAgICAgLy8gICAgICAwMCAtIDk5XG4gICAgdmFyIG1hdGNoMyAgICAgICAgID0gL1xcZHszfS87ICAgICAgICAgLy8gICAgIDAwMCAtIDk5OVxuICAgIHZhciBtYXRjaDQgICAgICAgICA9IC9cXGR7NH0vOyAgICAgICAgIC8vICAgIDAwMDAgLSA5OTk5XG4gICAgdmFyIG1hdGNoNiAgICAgICAgID0gL1srLV0/XFxkezZ9LzsgICAgLy8gLTk5OTk5OSAtIDk5OTk5OVxuICAgIHZhciBtYXRjaDF0bzIgICAgICA9IC9cXGRcXGQ/LzsgICAgICAgICAvLyAgICAgICAwIC0gOTlcbiAgICB2YXIgbWF0Y2gzdG80ICAgICAgPSAvXFxkXFxkXFxkXFxkPy87ICAgICAvLyAgICAgOTk5IC0gOTk5OVxuICAgIHZhciBtYXRjaDV0bzYgICAgICA9IC9cXGRcXGRcXGRcXGRcXGRcXGQ/LzsgLy8gICA5OTk5OSAtIDk5OTk5OVxuICAgIHZhciBtYXRjaDF0bzMgICAgICA9IC9cXGR7MSwzfS87ICAgICAgIC8vICAgICAgIDAgLSA5OTlcbiAgICB2YXIgbWF0Y2gxdG80ICAgICAgPSAvXFxkezEsNH0vOyAgICAgICAvLyAgICAgICAwIC0gOTk5OVxuICAgIHZhciBtYXRjaDF0bzYgICAgICA9IC9bKy1dP1xcZHsxLDZ9LzsgIC8vIC05OTk5OTkgLSA5OTk5OTlcblxuICAgIHZhciBtYXRjaFVuc2lnbmVkICA9IC9cXGQrLzsgICAgICAgICAgIC8vICAgICAgIDAgLSBpbmZcbiAgICB2YXIgbWF0Y2hTaWduZWQgICAgPSAvWystXT9cXGQrLzsgICAgICAvLyAgICAtaW5mIC0gaW5mXG5cbiAgICB2YXIgbWF0Y2hPZmZzZXQgICAgPSAvWnxbKy1dXFxkXFxkOj9cXGRcXGQvZ2k7IC8vICswMDowMCAtMDA6MDAgKzAwMDAgLTAwMDAgb3IgWlxuICAgIHZhciBtYXRjaFNob3J0T2Zmc2V0ID0gL1p8WystXVxcZFxcZCg/Ojo/XFxkXFxkKT8vZ2k7IC8vICswMCAtMDAgKzAwOjAwIC0wMDowMCArMDAwMCAtMDAwMCBvciBaXG5cbiAgICB2YXIgbWF0Y2hUaW1lc3RhbXAgPSAvWystXT9cXGQrKFxcLlxcZHsxLDN9KT8vOyAvLyAxMjM0NTY3ODkgMTIzNDU2Nzg5LjEyM1xuXG4gICAgLy8gYW55IHdvcmQgKG9yIHR3bykgY2hhcmFjdGVycyBvciBudW1iZXJzIGluY2x1ZGluZyB0d28vdGhyZWUgd29yZCBtb250aCBpbiBhcmFiaWMuXG4gICAgLy8gaW5jbHVkZXMgc2NvdHRpc2ggZ2FlbGljIHR3byB3b3JkIGFuZCBoeXBoZW5hdGVkIG1vbnRoc1xuICAgIHZhciBtYXRjaFdvcmQgPSAvWzAtOV17MCwyNTZ9WydhLXpcXHUwMEEwLVxcdTA1RkZcXHUwNzAwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGMDdcXHVGRjEwLVxcdUZGRUZdezEsMjU2fXxbXFx1MDYwMC1cXHUwNkZGXFwvXXsxLDI1Nn0oXFxzKj9bXFx1MDYwMC1cXHUwNkZGXXsxLDI1Nn0pezEsMn0vaTtcblxuICAgIHZhciByZWdleGVzID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRSZWdleFRva2VuICh0b2tlbiwgcmVnZXgsIHN0cmljdFJlZ2V4KSB7XG4gICAgICAgIHJlZ2V4ZXNbdG9rZW5dID0gaXNGdW5jdGlvbihyZWdleCkgPyByZWdleCA6IGZ1bmN0aW9uIChpc1N0cmljdCwgbG9jYWxlRGF0YSkge1xuICAgICAgICAgICAgcmV0dXJuIChpc1N0cmljdCAmJiBzdHJpY3RSZWdleCkgPyBzdHJpY3RSZWdleCA6IHJlZ2V4O1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFBhcnNlUmVnZXhGb3JUb2tlbiAodG9rZW4sIGNvbmZpZykge1xuICAgICAgICBpZiAoIWhhc093blByb3AocmVnZXhlcywgdG9rZW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cCh1bmVzY2FwZUZvcm1hdCh0b2tlbikpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlZ2V4ZXNbdG9rZW5dKGNvbmZpZy5fc3RyaWN0LCBjb25maWcuX2xvY2FsZSk7XG4gICAgfVxuXG4gICAgLy8gQ29kZSBmcm9tIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzU2MTQ5My9pcy10aGVyZS1hLXJlZ2V4cC1lc2NhcGUtZnVuY3Rpb24taW4tamF2YXNjcmlwdFxuICAgIGZ1bmN0aW9uIHVuZXNjYXBlRm9ybWF0KHMpIHtcbiAgICAgICAgcmV0dXJuIHJlZ2V4RXNjYXBlKHMucmVwbGFjZSgnXFxcXCcsICcnKS5yZXBsYWNlKC9cXFxcKFxcWyl8XFxcXChcXF0pfFxcWyhbXlxcXVxcW10qKVxcXXxcXFxcKC4pL2csIGZ1bmN0aW9uIChtYXRjaGVkLCBwMSwgcDIsIHAzLCBwNCkge1xuICAgICAgICAgICAgcmV0dXJuIHAxIHx8IHAyIHx8IHAzIHx8IHA0O1xuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVnZXhFc2NhcGUocykge1xuICAgICAgICByZXR1cm4gcy5yZXBsYWNlKC9bLVxcL1xcXFxeJCorPy4oKXxbXFxde31dL2csICdcXFxcJCYnKTtcbiAgICB9XG5cbiAgICB2YXIgdG9rZW5zID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRQYXJzZVRva2VuICh0b2tlbiwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGksIGZ1bmMgPSBjYWxsYmFjaztcbiAgICAgICAgaWYgKHR5cGVvZiB0b2tlbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRva2VuID0gW3Rva2VuXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNOdW1iZXIoY2FsbGJhY2spKSB7XG4gICAgICAgICAgICBmdW5jID0gZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICAgICAgICAgIGFycmF5W2NhbGxiYWNrXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRva2VuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0b2tlbnNbdG9rZW5baV1dID0gZnVuYztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFdlZWtQYXJzZVRva2VuICh0b2tlbiwgY2FsbGJhY2spIHtcbiAgICAgICAgYWRkUGFyc2VUb2tlbih0b2tlbiwgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnLCB0b2tlbikge1xuICAgICAgICAgICAgY29uZmlnLl93ID0gY29uZmlnLl93IHx8IHt9O1xuICAgICAgICAgICAgY2FsbGJhY2soaW5wdXQsIGNvbmZpZy5fdywgY29uZmlnLCB0b2tlbik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFRpbWVUb0FycmF5RnJvbVRva2VuKHRva2VuLCBpbnB1dCwgY29uZmlnKSB7XG4gICAgICAgIGlmIChpbnB1dCAhPSBudWxsICYmIGhhc093blByb3AodG9rZW5zLCB0b2tlbikpIHtcbiAgICAgICAgICAgIHRva2Vuc1t0b2tlbl0oaW5wdXQsIGNvbmZpZy5fYSwgY29uZmlnLCB0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgWUVBUiA9IDA7XG4gICAgdmFyIE1PTlRIID0gMTtcbiAgICB2YXIgREFURSA9IDI7XG4gICAgdmFyIEhPVVIgPSAzO1xuICAgIHZhciBNSU5VVEUgPSA0O1xuICAgIHZhciBTRUNPTkQgPSA1O1xuICAgIHZhciBNSUxMSVNFQ09ORCA9IDY7XG4gICAgdmFyIFdFRUsgPSA3O1xuICAgIHZhciBXRUVLREFZID0gODtcblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdZJywgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgeSA9IHRoaXMueWVhcigpO1xuICAgICAgICByZXR1cm4geSA8PSA5OTk5ID8gJycgKyB5IDogJysnICsgeTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnWVknLCAyXSwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy55ZWFyKCkgJSAxMDA7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1lZWVknLCAgIDRdLCAgICAgICAwLCAneWVhcicpO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnWVlZWVknLCAgNV0sICAgICAgIDAsICd5ZWFyJyk7XG4gICAgYWRkRm9ybWF0VG9rZW4oMCwgWydZWVlZWVknLCA2LCB0cnVlXSwgMCwgJ3llYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygneWVhcicsICd5Jyk7XG5cbiAgICAvLyBQUklPUklUSUVTXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ3llYXInLCAxKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1knLCAgICAgIG1hdGNoU2lnbmVkKTtcbiAgICBhZGRSZWdleFRva2VuKCdZWScsICAgICBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignWVlZWScsICAgbWF0Y2gxdG80LCBtYXRjaDQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1lZWVlZJywgIG1hdGNoMXRvNiwgbWF0Y2g2KTtcbiAgICBhZGRSZWdleFRva2VuKCdZWVlZWVknLCBtYXRjaDF0bzYsIG1hdGNoNik7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnWVlZWVknLCAnWVlZWVlZJ10sIFlFQVIpO1xuICAgIGFkZFBhcnNlVG9rZW4oJ1lZWVknLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5KSB7XG4gICAgICAgIGFycmF5W1lFQVJdID0gaW5wdXQubGVuZ3RoID09PSAyID8gaG9va3MucGFyc2VUd29EaWdpdFllYXIoaW5wdXQpIDogdG9JbnQoaW5wdXQpO1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oJ1lZJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtZRUFSXSA9IGhvb2tzLnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCdZJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtZRUFSXSA9IHBhcnNlSW50KGlucHV0LCAxMCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICBmdW5jdGlvbiBkYXlzSW5ZZWFyKHllYXIpIHtcbiAgICAgICAgcmV0dXJuIGlzTGVhcFllYXIoeWVhcikgPyAzNjYgOiAzNjU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNMZWFwWWVhcih5ZWFyKSB7XG4gICAgICAgIHJldHVybiAoeWVhciAlIDQgPT09IDAgJiYgeWVhciAlIDEwMCAhPT0gMCkgfHwgeWVhciAlIDQwMCA9PT0gMDtcbiAgICB9XG5cbiAgICAvLyBIT09LU1xuXG4gICAgaG9va3MucGFyc2VUd29EaWdpdFllYXIgPSBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHRvSW50KGlucHV0KSArICh0b0ludChpbnB1dCkgPiA2OCA/IDE5MDAgOiAyMDAwKTtcbiAgICB9O1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgdmFyIGdldFNldFllYXIgPSBtYWtlR2V0U2V0KCdGdWxsWWVhcicsIHRydWUpO1xuXG4gICAgZnVuY3Rpb24gZ2V0SXNMZWFwWWVhciAoKSB7XG4gICAgICAgIHJldHVybiBpc0xlYXBZZWFyKHRoaXMueWVhcigpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlR2V0U2V0ICh1bml0LCBrZWVwVGltZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHNldCQxKHRoaXMsIHVuaXQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywga2VlcFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0KHRoaXMsIHVuaXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldCAobW9tLCB1bml0KSB7XG4gICAgICAgIHJldHVybiBtb20uaXNWYWxpZCgpID9cbiAgICAgICAgICAgIG1vbS5fZFsnZ2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyB1bml0XSgpIDogTmFOO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldCQxIChtb20sIHVuaXQsIHZhbHVlKSB7XG4gICAgICAgIGlmIChtb20uaXNWYWxpZCgpICYmICFpc05hTih2YWx1ZSkpIHtcbiAgICAgICAgICAgIGlmICh1bml0ID09PSAnRnVsbFllYXInICYmIGlzTGVhcFllYXIobW9tLnllYXIoKSkgJiYgbW9tLm1vbnRoKCkgPT09IDEgJiYgbW9tLmRhdGUoKSA9PT0gMjkpIHtcbiAgICAgICAgICAgICAgICBtb20uX2RbJ3NldCcgKyAobW9tLl9pc1VUQyA/ICdVVEMnIDogJycpICsgdW5pdF0odmFsdWUsIG1vbS5tb250aCgpLCBkYXlzSW5Nb250aCh2YWx1ZSwgbW9tLm1vbnRoKCkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyB1bml0XSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBzdHJpbmdHZXQgKHVuaXRzKSB7XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICBpZiAoaXNGdW5jdGlvbih0aGlzW3VuaXRzXSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzXSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gc3RyaW5nU2V0ICh1bml0cywgdmFsdWUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB1bml0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHVuaXRzID0gbm9ybWFsaXplT2JqZWN0VW5pdHModW5pdHMpO1xuICAgICAgICAgICAgdmFyIHByaW9yaXRpemVkID0gZ2V0UHJpb3JpdGl6ZWRVbml0cyh1bml0cyk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByaW9yaXRpemVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpc1twcmlvcml0aXplZFtpXS51bml0XSh1bml0c1twcmlvcml0aXplZFtpXS51bml0XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHRoaXNbdW5pdHNdKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzXSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbW9kKG4sIHgpIHtcbiAgICAgICAgcmV0dXJuICgobiAlIHgpICsgeCkgJSB4O1xuICAgIH1cblxuICAgIHZhciBpbmRleE9mO1xuXG4gICAgaWYgKEFycmF5LnByb3RvdHlwZS5pbmRleE9mKSB7XG4gICAgICAgIGluZGV4T2YgPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZjtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpbmRleE9mID0gZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgICAgIC8vIEkga25vd1xuICAgICAgICAgICAgdmFyIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSBvKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlzSW5Nb250aCh5ZWFyLCBtb250aCkge1xuICAgICAgICBpZiAoaXNOYU4oeWVhcikgfHwgaXNOYU4obW9udGgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtb2RNb250aCA9IG1vZChtb250aCwgMTIpO1xuICAgICAgICB5ZWFyICs9IChtb250aCAtIG1vZE1vbnRoKSAvIDEyO1xuICAgICAgICByZXR1cm4gbW9kTW9udGggPT09IDEgPyAoaXNMZWFwWWVhcih5ZWFyKSA/IDI5IDogMjgpIDogKDMxIC0gbW9kTW9udGggJSA3ICUgMik7XG4gICAgfVxuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ00nLCBbJ01NJywgMl0sICdNbycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9udGgoKSArIDE7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignTU1NJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzU2hvcnQodGhpcywgZm9ybWF0KTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdNTU1NJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzKHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21vbnRoJywgJ00nKTtcblxuICAgIC8vIFBSSU9SSVRZXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ21vbnRoJywgOCk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdNJywgICAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdNTScsICAgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ01NTScsICBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLm1vbnRoc1Nob3J0UmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ01NTU0nLCBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLm1vbnRoc1JlZ2V4KGlzU3RyaWN0KTtcbiAgICB9KTtcblxuICAgIGFkZFBhcnNlVG9rZW4oWydNJywgJ01NJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbTU9OVEhdID0gdG9JbnQoaW5wdXQpIC0gMTtcbiAgICB9KTtcblxuICAgIGFkZFBhcnNlVG9rZW4oWydNTU0nLCAnTU1NTSddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcsIHRva2VuKSB7XG4gICAgICAgIHZhciBtb250aCA9IGNvbmZpZy5fbG9jYWxlLm1vbnRoc1BhcnNlKGlucHV0LCB0b2tlbiwgY29uZmlnLl9zdHJpY3QpO1xuICAgICAgICAvLyBpZiB3ZSBkaWRuJ3QgZmluZCBhIG1vbnRoIG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZC5cbiAgICAgICAgaWYgKG1vbnRoICE9IG51bGwpIHtcbiAgICAgICAgICAgIGFycmF5W01PTlRIXSA9IG1vbnRoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuaW52YWxpZE1vbnRoID0gaW5wdXQ7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIExPQ0FMRVNcblxuICAgIHZhciBNT05USFNfSU5fRk9STUFUID0gL0Rbb0RdPyhcXFtbXlxcW1xcXV0qXFxdfFxccykrTU1NTT8vO1xuICAgIHZhciBkZWZhdWx0TG9jYWxlTW9udGhzID0gJ0phbnVhcnlfRmVicnVhcnlfTWFyY2hfQXByaWxfTWF5X0p1bmVfSnVseV9BdWd1c3RfU2VwdGVtYmVyX09jdG9iZXJfTm92ZW1iZXJfRGVjZW1iZXInLnNwbGl0KCdfJyk7XG4gICAgZnVuY3Rpb24gbG9jYWxlTW9udGhzIChtLCBmb3JtYXQpIHtcbiAgICAgICAgaWYgKCFtKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNBcnJheSh0aGlzLl9tb250aHMpID8gdGhpcy5fbW9udGhzIDpcbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNbJ3N0YW5kYWxvbmUnXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNBcnJheSh0aGlzLl9tb250aHMpID8gdGhpcy5fbW9udGhzW20ubW9udGgoKV0gOlxuICAgICAgICAgICAgdGhpcy5fbW9udGhzWyh0aGlzLl9tb250aHMuaXNGb3JtYXQgfHwgTU9OVEhTX0lOX0ZPUk1BVCkudGVzdChmb3JtYXQpID8gJ2Zvcm1hdCcgOiAnc3RhbmRhbG9uZSddW20ubW9udGgoKV07XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb2NhbGVNb250aHNTaG9ydCA9ICdKYW5fRmViX01hcl9BcHJfTWF5X0p1bl9KdWxfQXVnX1NlcF9PY3RfTm92X0RlYycuc3BsaXQoJ18nKTtcbiAgICBmdW5jdGlvbiBsb2NhbGVNb250aHNTaG9ydCAobSwgZm9ybWF0KSB7XG4gICAgICAgIGlmICghbSkge1xuICAgICAgICAgICAgcmV0dXJuIGlzQXJyYXkodGhpcy5fbW9udGhzU2hvcnQpID8gdGhpcy5fbW9udGhzU2hvcnQgOlxuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1Nob3J0WydzdGFuZGFsb25lJ107XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlzQXJyYXkodGhpcy5fbW9udGhzU2hvcnQpID8gdGhpcy5fbW9udGhzU2hvcnRbbS5tb250aCgpXSA6XG4gICAgICAgICAgICB0aGlzLl9tb250aHNTaG9ydFtNT05USFNfSU5fRk9STUFULnRlc3QoZm9ybWF0KSA/ICdmb3JtYXQnIDogJ3N0YW5kYWxvbmUnXVttLm1vbnRoKCldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZVN0cmljdFBhcnNlKG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGksIGlpLCBtb20sIGxsYyA9IG1vbnRoTmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoIXRoaXMuX21vbnRoc1BhcnNlKSB7XG4gICAgICAgICAgICAvLyB0aGlzIGlzIG5vdCB1c2VkXG4gICAgICAgICAgICB0aGlzLl9tb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTI7ICsraSkge1xuICAgICAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgaV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Nob3J0TW9udGhzUGFyc2VbaV0gPSB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldID0gdGhpcy5tb250aHMobW9tLCAnJykudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdNTU0nKSB7XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9sb25nTW9udGhzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdNTU0nKSB7XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fbG9uZ01vbnRoc1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpaSAhPT0gLTEgPyBpaSA6IG51bGw7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX2xvbmdNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9jYWxlTW9udGhzUGFyc2UgKG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGksIG1vbSwgcmVnZXg7XG5cbiAgICAgICAgaWYgKHRoaXMuX21vbnRoc1BhcnNlRXhhY3QpIHtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVTdHJpY3RQYXJzZS5jYWxsKHRoaXMsIG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLl9tb250aHNQYXJzZSkge1xuICAgICAgICAgICAgdGhpcy5fbW9udGhzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX2xvbmdNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVE9ETzogYWRkIHNvcnRpbmdcbiAgICAgICAgLy8gU29ydGluZyBtYWtlcyBzdXJlIGlmIG9uZSBtb250aCAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlclxuICAgICAgICAvLyBzZWUgc29ydGluZyBpbiBjb21wdXRlTW9udGhzUGFyc2VcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuICAgICAgICAgICAgbW9tID0gY3JlYXRlVVRDKFsyMDAwLCBpXSk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmICF0aGlzLl9sb25nTW9udGhzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb25nTW9udGhzUGFyc2VbaV0gPSBuZXcgUmVnRXhwKCdeJyArIHRoaXMubW9udGhzKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnJykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZVtpXSA9IG5ldyBSZWdFeHAoJ14nICsgdGhpcy5tb250aHNTaG9ydChtb20sICcnKS5yZXBsYWNlKCcuJywgJycpICsgJyQnLCAnaScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFzdHJpY3QgJiYgIXRoaXMuX21vbnRoc1BhcnNlW2ldKSB7XG4gICAgICAgICAgICAgICAgcmVnZXggPSAnXicgKyB0aGlzLm1vbnRocyhtb20sICcnKSArICd8XicgKyB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1BhcnNlW2ldID0gbmV3IFJlZ0V4cChyZWdleC5yZXBsYWNlKCcuJywgJycpLCAnaScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdGVzdCB0aGUgcmVnZXhcbiAgICAgICAgICAgIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NTScgJiYgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NJyAmJiB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghc3RyaWN0ICYmIHRoaXMuX21vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgZnVuY3Rpb24gc2V0TW9udGggKG1vbSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIGRheU9mTW9udGg7XG5cbiAgICAgICAgaWYgKCFtb20uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICAvLyBObyBvcFxuICAgICAgICAgICAgcmV0dXJuIG1vbTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAoL15cXGQrJC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRvSW50KHZhbHVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBtb20ubG9jYWxlRGF0YSgpLm1vbnRoc1BhcnNlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBBbm90aGVyIHNpbGVudCBmYWlsdXJlP1xuICAgICAgICAgICAgICAgIGlmICghaXNOdW1iZXIodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtb207XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZGF5T2ZNb250aCA9IE1hdGgubWluKG1vbS5kYXRlKCksIGRheXNJbk1vbnRoKG1vbS55ZWFyKCksIHZhbHVlKSk7XG4gICAgICAgIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyAnTW9udGgnXSh2YWx1ZSwgZGF5T2ZNb250aCk7XG4gICAgICAgIHJldHVybiBtb207XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2V0TW9udGggKHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBzZXRNb250aCh0aGlzLCB2YWx1ZSk7XG4gICAgICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBnZXQodGhpcywgJ01vbnRoJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXREYXlzSW5Nb250aCAoKSB7XG4gICAgICAgIHJldHVybiBkYXlzSW5Nb250aCh0aGlzLnllYXIoKSwgdGhpcy5tb250aCgpKTtcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdE1vbnRoc1Nob3J0UmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gbW9udGhzU2hvcnRSZWdleCAoaXNTdHJpY3QpIHtcbiAgICAgICAgaWYgKHRoaXMuX21vbnRoc1BhcnNlRXhhY3QpIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlTW9udGhzUGFyc2UuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1N0cmljdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1Nob3J0UmVnZXgnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1Nob3J0UmVnZXggPSBkZWZhdWx0TW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4ICYmIGlzU3RyaWN0ID9cbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4IDogdGhpcy5fbW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TW9udGhzUmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gbW9udGhzUmVnZXggKGlzU3RyaWN0KSB7XG4gICAgICAgIGlmICh0aGlzLl9tb250aHNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ19tb250aHNSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgY29tcHV0ZU1vbnRoc1BhcnNlLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNTdHJpY3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNSZWdleCA9IGRlZmF1bHRNb250aHNSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTdHJpY3RSZWdleCAmJiBpc1N0cmljdCA/XG4gICAgICAgICAgICAgICAgdGhpcy5fbW9udGhzU3RyaWN0UmVnZXggOiB0aGlzLl9tb250aHNSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbXB1dGVNb250aHNQYXJzZSAoKSB7XG4gICAgICAgIGZ1bmN0aW9uIGNtcExlblJldihhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi5sZW5ndGggLSBhLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzaG9ydFBpZWNlcyA9IFtdLCBsb25nUGllY2VzID0gW10sIG1peGVkUGllY2VzID0gW10sXG4gICAgICAgICAgICBpLCBtb207XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG4gICAgICAgICAgICAvLyBtYWtlIHRoZSByZWdleCBpZiB3ZSBkb24ndCBoYXZlIGl0IGFscmVhZHlcbiAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgaV0pO1xuICAgICAgICAgICAgc2hvcnRQaWVjZXMucHVzaCh0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpKTtcbiAgICAgICAgICAgIGxvbmdQaWVjZXMucHVzaCh0aGlzLm1vbnRocyhtb20sICcnKSk7XG4gICAgICAgICAgICBtaXhlZFBpZWNlcy5wdXNoKHRoaXMubW9udGhzKG1vbSwgJycpKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2godGhpcy5tb250aHNTaG9ydChtb20sICcnKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU29ydGluZyBtYWtlcyBzdXJlIGlmIG9uZSBtb250aCAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlciBpdFxuICAgICAgICAvLyB3aWxsIG1hdGNoIHRoZSBsb25nZXIgcGllY2UuXG4gICAgICAgIHNob3J0UGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgbG9uZ1BpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIG1peGVkUGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgIHNob3J0UGllY2VzW2ldID0gcmVnZXhFc2NhcGUoc2hvcnRQaWVjZXNbaV0pO1xuICAgICAgICAgICAgbG9uZ1BpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKGxvbmdQaWVjZXNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNDsgaSsrKSB7XG4gICAgICAgICAgICBtaXhlZFBpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKG1peGVkUGllY2VzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX21vbnRoc1JlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbWl4ZWRQaWVjZXMuam9pbignfCcpICsgJyknLCAnaScpO1xuICAgICAgICB0aGlzLl9tb250aHNTaG9ydFJlZ2V4ID0gdGhpcy5fbW9udGhzUmVnZXg7XG4gICAgICAgIHRoaXMuX21vbnRoc1N0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbG9uZ1BpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgICAgIHRoaXMuX21vbnRoc1Nob3J0U3RyaWN0UmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBzaG9ydFBpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlRGF0ZSAoeSwgbSwgZCwgaCwgTSwgcywgbXMpIHtcbiAgICAgICAgLy8gY2FuJ3QganVzdCBhcHBseSgpIHRvIGNyZWF0ZSBhIGRhdGU6XG4gICAgICAgIC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcS8xODEzNDhcbiAgICAgICAgdmFyIGRhdGU7XG4gICAgICAgIC8vIHRoZSBkYXRlIGNvbnN0cnVjdG9yIHJlbWFwcyB5ZWFycyAwLTk5IHRvIDE5MDAtMTk5OVxuICAgICAgICBpZiAoeSA8IDEwMCAmJiB5ID49IDApIHtcbiAgICAgICAgICAgIC8vIHByZXNlcnZlIGxlYXAgeWVhcnMgdXNpbmcgYSBmdWxsIDQwMCB5ZWFyIGN5Y2xlLCB0aGVuIHJlc2V0XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoeSArIDQwMCwgbSwgZCwgaCwgTSwgcywgbXMpO1xuICAgICAgICAgICAgaWYgKGlzRmluaXRlKGRhdGUuZ2V0RnVsbFllYXIoKSkpIHtcbiAgICAgICAgICAgICAgICBkYXRlLnNldEZ1bGxZZWFyKHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKHksIG0sIGQsIGgsIE0sIHMsIG1zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkYXRlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZVVUQ0RhdGUgKHkpIHtcbiAgICAgICAgdmFyIGRhdGU7XG4gICAgICAgIC8vIHRoZSBEYXRlLlVUQyBmdW5jdGlvbiByZW1hcHMgeWVhcnMgMC05OSB0byAxOTAwLTE5OTlcbiAgICAgICAgaWYgKHkgPCAxMDAgJiYgeSA+PSAwKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAvLyBwcmVzZXJ2ZSBsZWFwIHllYXJzIHVzaW5nIGEgZnVsbCA0MDAgeWVhciBjeWNsZSwgdGhlbiByZXNldFxuICAgICAgICAgICAgYXJnc1swXSA9IHkgKyA0MDA7XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoRGF0ZS5VVEMuYXBwbHkobnVsbCwgYXJncykpO1xuICAgICAgICAgICAgaWYgKGlzRmluaXRlKGRhdGUuZ2V0VVRDRnVsbFllYXIoKSkpIHtcbiAgICAgICAgICAgICAgICBkYXRlLnNldFVUQ0Z1bGxZZWFyKHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDLmFwcGx5KG51bGwsIGFyZ3VtZW50cykpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgLy8gc3RhcnQtb2YtZmlyc3Qtd2VlayAtIHN0YXJ0LW9mLXllYXJcbiAgICBmdW5jdGlvbiBmaXJzdFdlZWtPZmZzZXQoeWVhciwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIC8vIGZpcnN0LXdlZWsgZGF5IC0tIHdoaWNoIGphbnVhcnkgaXMgYWx3YXlzIGluIHRoZSBmaXJzdCB3ZWVrICg0IGZvciBpc28sIDEgZm9yIG90aGVyKVxuICAgICAgICAgICAgZndkID0gNyArIGRvdyAtIGRveSxcbiAgICAgICAgICAgIC8vIGZpcnN0LXdlZWsgZGF5IGxvY2FsIHdlZWtkYXkgLS0gd2hpY2ggbG9jYWwgd2Vla2RheSBpcyBmd2RcbiAgICAgICAgICAgIGZ3ZGx3ID0gKDcgKyBjcmVhdGVVVENEYXRlKHllYXIsIDAsIGZ3ZCkuZ2V0VVRDRGF5KCkgLSBkb3cpICUgNztcblxuICAgICAgICByZXR1cm4gLWZ3ZGx3ICsgZndkIC0gMTtcbiAgICB9XG5cbiAgICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlI0NhbGN1bGF0aW5nX2FfZGF0ZV9naXZlbl90aGVfeWVhci4yQ193ZWVrX251bWJlcl9hbmRfd2Vla2RheVxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrcyh5ZWFyLCB3ZWVrLCB3ZWVrZGF5LCBkb3csIGRveSkge1xuICAgICAgICB2YXIgbG9jYWxXZWVrZGF5ID0gKDcgKyB3ZWVrZGF5IC0gZG93KSAlIDcsXG4gICAgICAgICAgICB3ZWVrT2Zmc2V0ID0gZmlyc3RXZWVrT2Zmc2V0KHllYXIsIGRvdywgZG95KSxcbiAgICAgICAgICAgIGRheU9mWWVhciA9IDEgKyA3ICogKHdlZWsgLSAxKSArIGxvY2FsV2Vla2RheSArIHdlZWtPZmZzZXQsXG4gICAgICAgICAgICByZXNZZWFyLCByZXNEYXlPZlllYXI7XG5cbiAgICAgICAgaWYgKGRheU9mWWVhciA8PSAwKSB7XG4gICAgICAgICAgICByZXNZZWFyID0geWVhciAtIDE7XG4gICAgICAgICAgICByZXNEYXlPZlllYXIgPSBkYXlzSW5ZZWFyKHJlc1llYXIpICsgZGF5T2ZZZWFyO1xuICAgICAgICB9IGVsc2UgaWYgKGRheU9mWWVhciA+IGRheXNJblllYXIoeWVhcikpIHtcbiAgICAgICAgICAgIHJlc1llYXIgPSB5ZWFyICsgMTtcbiAgICAgICAgICAgIHJlc0RheU9mWWVhciA9IGRheU9mWWVhciAtIGRheXNJblllYXIoeWVhcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNZZWFyID0geWVhcjtcbiAgICAgICAgICAgIHJlc0RheU9mWWVhciA9IGRheU9mWWVhcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB5ZWFyOiByZXNZZWFyLFxuICAgICAgICAgICAgZGF5T2ZZZWFyOiByZXNEYXlPZlllYXJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3ZWVrT2ZZZWFyKG1vbSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIHdlZWtPZmZzZXQgPSBmaXJzdFdlZWtPZmZzZXQobW9tLnllYXIoKSwgZG93LCBkb3kpLFxuICAgICAgICAgICAgd2VlayA9IE1hdGguZmxvb3IoKG1vbS5kYXlPZlllYXIoKSAtIHdlZWtPZmZzZXQgLSAxKSAvIDcpICsgMSxcbiAgICAgICAgICAgIHJlc1dlZWssIHJlc1llYXI7XG5cbiAgICAgICAgaWYgKHdlZWsgPCAxKSB7XG4gICAgICAgICAgICByZXNZZWFyID0gbW9tLnllYXIoKSAtIDE7XG4gICAgICAgICAgICByZXNXZWVrID0gd2VlayArIHdlZWtzSW5ZZWFyKHJlc1llYXIsIGRvdywgZG95KTtcbiAgICAgICAgfSBlbHNlIGlmICh3ZWVrID4gd2Vla3NJblllYXIobW9tLnllYXIoKSwgZG93LCBkb3kpKSB7XG4gICAgICAgICAgICByZXNXZWVrID0gd2VlayAtIHdlZWtzSW5ZZWFyKG1vbS55ZWFyKCksIGRvdywgZG95KTtcbiAgICAgICAgICAgIHJlc1llYXIgPSBtb20ueWVhcigpICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc1llYXIgPSBtb20ueWVhcigpO1xuICAgICAgICAgICAgcmVzV2VlayA9IHdlZWs7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgd2VlazogcmVzV2VlayxcbiAgICAgICAgICAgIHllYXI6IHJlc1llYXJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3ZWVrc0luWWVhcih5ZWFyLCBkb3csIGRveSkge1xuICAgICAgICB2YXIgd2Vla09mZnNldCA9IGZpcnN0V2Vla09mZnNldCh5ZWFyLCBkb3csIGRveSksXG4gICAgICAgICAgICB3ZWVrT2Zmc2V0TmV4dCA9IGZpcnN0V2Vla09mZnNldCh5ZWFyICsgMSwgZG93LCBkb3kpO1xuICAgICAgICByZXR1cm4gKGRheXNJblllYXIoeWVhcikgLSB3ZWVrT2Zmc2V0ICsgd2Vla09mZnNldE5leHQpIC8gNztcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigndycsIFsnd3cnLCAyXSwgJ3dvJywgJ3dlZWsnKTtcbiAgICBhZGRGb3JtYXRUb2tlbignVycsIFsnV1cnLCAyXSwgJ1dvJywgJ2lzb1dlZWsnKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnd2VlaycsICd3Jyk7XG4gICAgYWRkVW5pdEFsaWFzKCdpc29XZWVrJywgJ1cnKTtcblxuICAgIC8vIFBSSU9SSVRJRVNcblxuICAgIGFkZFVuaXRQcmlvcml0eSgnd2VlaycsIDUpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2VlaycsIDUpO1xuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbigndycsICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ3d3JywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1cnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdXVycsIG1hdGNoMXRvMiwgbWF0Y2gyKTtcblxuICAgIGFkZFdlZWtQYXJzZVRva2VuKFsndycsICd3dycsICdXJywgJ1dXJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuLnN1YnN0cigwLCAxKV0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICAvLyBMT0NBTEVTXG5cbiAgICBmdW5jdGlvbiBsb2NhbGVXZWVrIChtb20pIHtcbiAgICAgICAgcmV0dXJuIHdlZWtPZlllYXIobW9tLCB0aGlzLl93ZWVrLmRvdywgdGhpcy5fd2Vlay5kb3kpLndlZWs7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb2NhbGVXZWVrID0ge1xuICAgICAgICBkb3cgOiAwLCAvLyBTdW5kYXkgaXMgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2Vlay5cbiAgICAgICAgZG95IDogNiAgLy8gVGhlIHdlZWsgdGhhdCBjb250YWlucyBKYW4gNnRoIGlzIHRoZSBmaXJzdCB3ZWVrIG9mIHRoZSB5ZWFyLlxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2NhbGVGaXJzdERheU9mV2VlayAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93ZWVrLmRvdztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsb2NhbGVGaXJzdERheU9mWWVhciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93ZWVrLmRveTtcbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBnZXRTZXRXZWVrIChpbnB1dCkge1xuICAgICAgICB2YXIgd2VlayA9IHRoaXMubG9jYWxlRGF0YSgpLndlZWsodGhpcyk7XG4gICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8gd2VlayA6IHRoaXMuYWRkKChpbnB1dCAtIHdlZWspICogNywgJ2QnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRJU09XZWVrIChpbnB1dCkge1xuICAgICAgICB2YXIgd2VlayA9IHdlZWtPZlllYXIodGhpcywgMSwgNCkud2VlaztcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrIDogdGhpcy5hZGQoKGlucHV0IC0gd2VlaykgKiA3LCAnZCcpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdkJywgMCwgJ2RvJywgJ2RheScpO1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ2RkJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkud2Vla2RheXNNaW4odGhpcywgZm9ybWF0KTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdkZGQnLCAwLCAwLCBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS53ZWVrZGF5c1Nob3J0KHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignZGRkZCcsIDAsIDAsIGZ1bmN0aW9uIChmb3JtYXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLndlZWtkYXlzKHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignZScsIDAsIDAsICd3ZWVrZGF5Jyk7XG4gICAgYWRkRm9ybWF0VG9rZW4oJ0UnLCAwLCAwLCAnaXNvV2Vla2RheScpO1xuXG4gICAgLy8gQUxJQVNFU1xuXG4gICAgYWRkVW5pdEFsaWFzKCdkYXknLCAnZCcpO1xuICAgIGFkZFVuaXRBbGlhcygnd2Vla2RheScsICdlJyk7XG4gICAgYWRkVW5pdEFsaWFzKCdpc29XZWVrZGF5JywgJ0UnKTtcblxuICAgIC8vIFBSSU9SSVRZXG4gICAgYWRkVW5pdFByaW9yaXR5KCdkYXknLCAxMSk7XG4gICAgYWRkVW5pdFByaW9yaXR5KCd3ZWVrZGF5JywgMTEpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2Vla2RheScsIDExKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ2QnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2UnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0UnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkJywgICBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLndlZWtkYXlzTWluUmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkZCcsICAgZnVuY3Rpb24gKGlzU3RyaWN0LCBsb2NhbGUpIHtcbiAgICAgICAgcmV0dXJuIGxvY2FsZS53ZWVrZGF5c1Nob3J0UmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkZGQnLCAgIGZ1bmN0aW9uIChpc1N0cmljdCwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUud2Vla2RheXNSZWdleChpc1N0cmljdCk7XG4gICAgfSk7XG5cbiAgICBhZGRXZWVrUGFyc2VUb2tlbihbJ2RkJywgJ2RkZCcsICdkZGRkJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB2YXIgd2Vla2RheSA9IGNvbmZpZy5fbG9jYWxlLndlZWtkYXlzUGFyc2UoaW5wdXQsIHRva2VuLCBjb25maWcuX3N0cmljdCk7XG4gICAgICAgIC8vIGlmIHdlIGRpZG4ndCBnZXQgYSB3ZWVrZGF5IG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZFxuICAgICAgICBpZiAod2Vla2RheSAhPSBudWxsKSB7XG4gICAgICAgICAgICB3ZWVrLmQgPSB3ZWVrZGF5O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuaW52YWxpZFdlZWtkYXkgPSBpbnB1dDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgYWRkV2Vla1BhcnNlVG9rZW4oWydkJywgJ2UnLCAnRSddLCBmdW5jdGlvbiAoaW5wdXQsIHdlZWssIGNvbmZpZywgdG9rZW4pIHtcbiAgICAgICAgd2Vla1t0b2tlbl0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICBmdW5jdGlvbiBwYXJzZVdlZWtkYXkoaW5wdXQsIGxvY2FsZSkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc05hTihpbnB1dCkpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUludChpbnB1dCwgMTApO1xuICAgICAgICB9XG5cbiAgICAgICAgaW5wdXQgPSBsb2NhbGUud2Vla2RheXNQYXJzZShpbnB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZUlzb1dlZWtkYXkoaW5wdXQsIGxvY2FsZSkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS53ZWVrZGF5c1BhcnNlKGlucHV0KSAlIDcgfHwgNztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNOYU4oaW5wdXQpID8gbnVsbCA6IGlucHV0O1xuICAgIH1cblxuICAgIC8vIExPQ0FMRVNcbiAgICBmdW5jdGlvbiBzaGlmdFdlZWtkYXlzICh3cywgbikge1xuICAgICAgICByZXR1cm4gd3Muc2xpY2UobiwgNykuY29uY2F0KHdzLnNsaWNlKDAsIG4pKTtcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdExvY2FsZVdlZWtkYXlzID0gJ1N1bmRheV9Nb25kYXlfVHVlc2RheV9XZWRuZXNkYXlfVGh1cnNkYXlfRnJpZGF5X1NhdHVyZGF5Jy5zcGxpdCgnXycpO1xuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzIChtLCBmb3JtYXQpIHtcbiAgICAgICAgdmFyIHdlZWtkYXlzID0gaXNBcnJheSh0aGlzLl93ZWVrZGF5cykgPyB0aGlzLl93ZWVrZGF5cyA6XG4gICAgICAgICAgICB0aGlzLl93ZWVrZGF5c1sobSAmJiBtICE9PSB0cnVlICYmIHRoaXMuX3dlZWtkYXlzLmlzRm9ybWF0LnRlc3QoZm9ybWF0KSkgPyAnZm9ybWF0JyA6ICdzdGFuZGFsb25lJ107XG4gICAgICAgIHJldHVybiAobSA9PT0gdHJ1ZSkgPyBzaGlmdFdlZWtkYXlzKHdlZWtkYXlzLCB0aGlzLl93ZWVrLmRvdylcbiAgICAgICAgICAgIDogKG0pID8gd2Vla2RheXNbbS5kYXkoKV0gOiB3ZWVrZGF5cztcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdExvY2FsZVdlZWtkYXlzU2hvcnQgPSAnU3VuX01vbl9UdWVfV2VkX1RodV9GcmlfU2F0Jy5zcGxpdCgnXycpO1xuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzU2hvcnQgKG0pIHtcbiAgICAgICAgcmV0dXJuIChtID09PSB0cnVlKSA/IHNoaWZ0V2Vla2RheXModGhpcy5fd2Vla2RheXNTaG9ydCwgdGhpcy5fd2Vlay5kb3cpXG4gICAgICAgICAgICA6IChtKSA/IHRoaXMuX3dlZWtkYXlzU2hvcnRbbS5kYXkoKV0gOiB0aGlzLl93ZWVrZGF5c1Nob3J0O1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TG9jYWxlV2Vla2RheXNNaW4gPSAnU3VfTW9fVHVfV2VfVGhfRnJfU2EnLnNwbGl0KCdfJyk7XG4gICAgZnVuY3Rpb24gbG9jYWxlV2Vla2RheXNNaW4gKG0pIHtcbiAgICAgICAgcmV0dXJuIChtID09PSB0cnVlKSA/IHNoaWZ0V2Vla2RheXModGhpcy5fd2Vla2RheXNNaW4sIHRoaXMuX3dlZWsuZG93KVxuICAgICAgICAgICAgOiAobSkgPyB0aGlzLl93ZWVrZGF5c01pblttLmRheSgpXSA6IHRoaXMuX3dlZWtkYXlzTWluO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZVN0cmljdFBhcnNlJDEod2Vla2RheU5hbWUsIGZvcm1hdCwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBpLCBpaSwgbW9tLCBsbGMgPSB3ZWVrZGF5TmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fbWluV2Vla2RheXNQYXJzZSA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNzsgKytpKSB7XG4gICAgICAgICAgICAgICAgbW9tID0gY3JlYXRlVVRDKFsyMDAwLCAxXSkuZGF5KGkpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21pbldlZWtkYXlzUGFyc2VbaV0gPSB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRXZWVrZGF5c1BhcnNlW2ldID0gdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZVtpXSA9IHRoaXMud2Vla2RheXMobW9tLCAnJykudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdkZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3dlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9taW5XZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpaSAhPT0gLTEgPyBpaSA6IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoZm9ybWF0ID09PSAnZGRkZCcpIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl93ZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9zaG9ydFdlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgaWYgKGlpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX21pbldlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fd2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fbWluV2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9taW5XZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl93ZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9zaG9ydFdlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzUGFyc2UgKHdlZWtkYXlOYW1lLCBmb3JtYXQsIHN0cmljdCkge1xuICAgICAgICB2YXIgaSwgbW9tLCByZWdleDtcblxuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlU3RyaWN0UGFyc2UkMS5jYWxsKHRoaXMsIHdlZWtkYXlOYW1lLCBmb3JtYXQsIHN0cmljdCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX21pbldlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fZnVsbFdlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuXG4gICAgICAgICAgICBtb20gPSBjcmVhdGVVVEMoWzIwMDAsIDFdKS5kYXkoaSk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmICF0aGlzLl9mdWxsV2Vla2RheXNQYXJzZVtpXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2Z1bGxXZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnXFxcXC4/JykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRXZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzU2hvcnQobW9tLCAnJykucmVwbGFjZSgnLicsICdcXFxcLj8nKSArICckJywgJ2knKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9taW5XZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnXFxcXC4/JykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICByZWdleCA9ICdeJyArIHRoaXMud2Vla2RheXMobW9tLCAnJykgKyAnfF4nICsgdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpICsgJ3xeJyArIHRoaXMud2Vla2RheXNNaW4obW9tLCAnJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZVtpXSA9IG5ldyBSZWdFeHAocmVnZXgucmVwbGFjZSgnLicsICcnKSwgJ2knKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHRlc3QgdGhlIHJlZ2V4XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmIGZvcm1hdCA9PT0gJ2RkZGQnICYmIHRoaXMuX2Z1bGxXZWVrZGF5c1BhcnNlW2ldLnRlc3Qod2Vla2RheU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmljdCAmJiBmb3JtYXQgPT09ICdkZGQnICYmIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZVtpXS50ZXN0KHdlZWtkYXlOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnZGQnICYmIHRoaXMuX21pbldlZWtkYXlzUGFyc2VbaV0udGVzdCh3ZWVrZGF5TmFtZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXN0cmljdCAmJiB0aGlzLl93ZWVrZGF5c1BhcnNlW2ldLnRlc3Qod2Vla2RheU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBnZXRTZXREYXlPZldlZWsgKGlucHV0KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnB1dCAhPSBudWxsID8gdGhpcyA6IE5hTjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF5ID0gdGhpcy5faXNVVEMgPyB0aGlzLl9kLmdldFVUQ0RheSgpIDogdGhpcy5fZC5nZXREYXkoKTtcbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlucHV0ID0gcGFyc2VXZWVrZGF5KGlucHV0LCB0aGlzLmxvY2FsZURhdGEoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGQoaW5wdXQgLSBkYXksICdkJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZGF5O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2V0TG9jYWxlRGF5T2ZXZWVrIChpbnB1dCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgIT0gbnVsbCA/IHRoaXMgOiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHdlZWtkYXkgPSAodGhpcy5kYXkoKSArIDcgLSB0aGlzLmxvY2FsZURhdGEoKS5fd2Vlay5kb3cpICUgNztcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrZGF5IDogdGhpcy5hZGQoaW5wdXQgLSB3ZWVrZGF5LCAnZCcpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNldElTT0RheU9mV2VlayAoaW5wdXQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0ICE9IG51bGwgPyB0aGlzIDogTmFOO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYmVoYXZlcyB0aGUgc2FtZSBhcyBtb21lbnQjZGF5IGV4Y2VwdFxuICAgICAgICAvLyBhcyBhIGdldHRlciwgcmV0dXJucyA3IGluc3RlYWQgb2YgMCAoMS03IHJhbmdlIGluc3RlYWQgb2YgMC02KVxuICAgICAgICAvLyBhcyBhIHNldHRlciwgc3VuZGF5IHNob3VsZCBiZWxvbmcgdG8gdGhlIHByZXZpb3VzIHdlZWsuXG5cbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhciB3ZWVrZGF5ID0gcGFyc2VJc29XZWVrZGF5KGlucHV0LCB0aGlzLmxvY2FsZURhdGEoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kYXkodGhpcy5kYXkoKSAlIDcgPyB3ZWVrZGF5IDogd2Vla2RheSAtIDcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF5KCkgfHwgNztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0V2Vla2RheXNSZWdleCA9IG1hdGNoV29yZDtcbiAgICBmdW5jdGlvbiB3ZWVrZGF5c1JlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wKHRoaXMsICdfd2Vla2RheXNSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNSZWdleCA9IGRlZmF1bHRXZWVrZGF5c1JlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggOiB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRXZWVrZGF5c1Nob3J0UmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gd2Vla2RheXNTaG9ydFJlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU2hvcnRTdHJpY3RSZWdleDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX3dlZWtkYXlzU2hvcnRSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNTaG9ydFJlZ2V4ID0gZGVmYXVsdFdlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c1Nob3J0U3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzU2hvcnRTdHJpY3RSZWdleCA6IHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0V2Vla2RheXNNaW5SZWdleCA9IG1hdGNoV29yZDtcbiAgICBmdW5jdGlvbiB3ZWVrZGF5c01pblJlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wKHRoaXMsICdfd2Vla2RheXNNaW5SZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNNaW5SZWdleCA9IGRlZmF1bHRXZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXggOiB0aGlzLl93ZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjb21wdXRlV2Vla2RheXNQYXJzZSAoKSB7XG4gICAgICAgIGZ1bmN0aW9uIGNtcExlblJldihhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi5sZW5ndGggLSBhLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtaW5QaWVjZXMgPSBbXSwgc2hvcnRQaWVjZXMgPSBbXSwgbG9uZ1BpZWNlcyA9IFtdLCBtaXhlZFBpZWNlcyA9IFtdLFxuICAgICAgICAgICAgaSwgbW9tLCBtaW5wLCBzaG9ydHAsIGxvbmdwO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNzsgaSsrKSB7XG4gICAgICAgICAgICAvLyBtYWtlIHRoZSByZWdleCBpZiB3ZSBkb24ndCBoYXZlIGl0IGFscmVhZHlcbiAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgMV0pLmRheShpKTtcbiAgICAgICAgICAgIG1pbnAgPSB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpO1xuICAgICAgICAgICAgc2hvcnRwID0gdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpO1xuICAgICAgICAgICAgbG9uZ3AgPSB0aGlzLndlZWtkYXlzKG1vbSwgJycpO1xuICAgICAgICAgICAgbWluUGllY2VzLnB1c2gobWlucCk7XG4gICAgICAgICAgICBzaG9ydFBpZWNlcy5wdXNoKHNob3J0cCk7XG4gICAgICAgICAgICBsb25nUGllY2VzLnB1c2gobG9uZ3ApO1xuICAgICAgICAgICAgbWl4ZWRQaWVjZXMucHVzaChtaW5wKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2goc2hvcnRwKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2gobG9uZ3ApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNvcnRpbmcgbWFrZXMgc3VyZSBpZiBvbmUgd2Vla2RheSAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlciBpdFxuICAgICAgICAvLyB3aWxsIG1hdGNoIHRoZSBsb25nZXIgcGllY2UuXG4gICAgICAgIG1pblBpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIHNob3J0UGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgbG9uZ1BpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIG1peGVkUGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDc7IGkrKykge1xuICAgICAgICAgICAgc2hvcnRQaWVjZXNbaV0gPSByZWdleEVzY2FwZShzaG9ydFBpZWNlc1tpXSk7XG4gICAgICAgICAgICBsb25nUGllY2VzW2ldID0gcmVnZXhFc2NhcGUobG9uZ1BpZWNlc1tpXSk7XG4gICAgICAgICAgICBtaXhlZFBpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKG1peGVkUGllY2VzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3dlZWtkYXlzUmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBtaXhlZFBpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgICAgIHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleCA9IHRoaXMuX3dlZWtkYXlzUmVnZXg7XG4gICAgICAgIHRoaXMuX3dlZWtkYXlzTWluUmVnZXggPSB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuXG4gICAgICAgIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBsb25nUGllY2VzLmpvaW4oJ3wnKSArICcpJywgJ2knKTtcbiAgICAgICAgdGhpcy5fd2Vla2RheXNTaG9ydFN0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgc2hvcnRQaWVjZXMuam9pbignfCcpICsgJyknLCAnaScpO1xuICAgICAgICB0aGlzLl93ZWVrZGF5c01pblN0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbWluUGllY2VzLmpvaW4oJ3wnKSArICcpJywgJ2knKTtcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBmdW5jdGlvbiBoRm9ybWF0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ob3VycygpICUgMTIgfHwgMTI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24ga0Zvcm1hdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaG91cnMoKSB8fCAyNDtcbiAgICB9XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSCcsIFsnSEgnLCAyXSwgMCwgJ2hvdXInKTtcbiAgICBhZGRGb3JtYXRUb2tlbignaCcsIFsnaGgnLCAyXSwgMCwgaEZvcm1hdCk7XG4gICAgYWRkRm9ybWF0VG9rZW4oJ2snLCBbJ2trJywgMl0sIDAsIGtGb3JtYXQpO1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ2htbScsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnICsgaEZvcm1hdC5hcHBseSh0aGlzKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdobW1zcycsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnICsgaEZvcm1hdC5hcHBseSh0aGlzKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKSArXG4gICAgICAgICAgICB6ZXJvRmlsbCh0aGlzLnNlY29uZHMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSG1tJywgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gJycgKyB0aGlzLmhvdXJzKCkgKyB6ZXJvRmlsbCh0aGlzLm1pbnV0ZXMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSG1tc3MnLCAwLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAnJyArIHRoaXMuaG91cnMoKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKSArXG4gICAgICAgICAgICB6ZXJvRmlsbCh0aGlzLnNlY29uZHMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBtZXJpZGllbSAodG9rZW4sIGxvd2VyY2FzZSkge1xuICAgICAgICBhZGRGb3JtYXRUb2tlbih0b2tlbiwgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLm1lcmlkaWVtKHRoaXMuaG91cnMoKSwgdGhpcy5taW51dGVzKCksIGxvd2VyY2FzZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG1lcmlkaWVtKCdhJywgdHJ1ZSk7XG4gICAgbWVyaWRpZW0oJ0EnLCBmYWxzZSk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ2hvdXInLCAnaCcpO1xuXG4gICAgLy8gUFJJT1JJVFlcbiAgICBhZGRVbml0UHJpb3JpdHkoJ2hvdXInLCAxMyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBmdW5jdGlvbiBtYXRjaE1lcmlkaWVtIChpc1N0cmljdCwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUuX21lcmlkaWVtUGFyc2U7XG4gICAgfVxuXG4gICAgYWRkUmVnZXhUb2tlbignYScsICBtYXRjaE1lcmlkaWVtKTtcbiAgICBhZGRSZWdleFRva2VuKCdBJywgIG1hdGNoTWVyaWRpZW0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0gnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdoJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignaycsICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0hIJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2hoJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2trJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuXG4gICAgYWRkUmVnZXhUb2tlbignaG1tJywgbWF0Y2gzdG80KTtcbiAgICBhZGRSZWdleFRva2VuKCdobW1zcycsIG1hdGNoNXRvNik7XG4gICAgYWRkUmVnZXhUb2tlbignSG1tJywgbWF0Y2gzdG80KTtcbiAgICBhZGRSZWdleFRva2VuKCdIbW1zcycsIG1hdGNoNXRvNik7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnSCcsICdISCddLCBIT1VSKTtcbiAgICBhZGRQYXJzZVRva2VuKFsnaycsICdrayddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIGtJbnB1dCA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgYXJyYXlbSE9VUl0gPSBrSW5wdXQgPT09IDI0ID8gMCA6IGtJbnB1dDtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKFsnYScsICdBJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2lzUG0gPSBjb25maWcuX2xvY2FsZS5pc1BNKGlucHV0KTtcbiAgICAgICAgY29uZmlnLl9tZXJpZGllbSA9IGlucHV0O1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oWydoJywgJ2hoJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuYmlnSG91ciA9IHRydWU7XG4gICAgfSk7XG4gICAgYWRkUGFyc2VUb2tlbignaG1tJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIHZhciBwb3MgPSBpbnB1dC5sZW5ndGggLSAyO1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0LnN1YnN0cigwLCBwb3MpKTtcbiAgICAgICAgYXJyYXlbTUlOVVRFXSA9IHRvSW50KGlucHV0LnN1YnN0cihwb3MpKTtcbiAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuYmlnSG91ciA9IHRydWU7XG4gICAgfSk7XG4gICAgYWRkUGFyc2VUb2tlbignaG1tc3MnLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIHBvczEgPSBpbnB1dC5sZW5ndGggLSA0O1xuICAgICAgICB2YXIgcG9zMiA9IGlucHV0Lmxlbmd0aCAtIDI7XG4gICAgICAgIGFycmF5W0hPVVJdID0gdG9JbnQoaW5wdXQuc3Vic3RyKDAsIHBvczEpKTtcbiAgICAgICAgYXJyYXlbTUlOVVRFXSA9IHRvSW50KGlucHV0LnN1YnN0cihwb3MxLCAyKSk7XG4gICAgICAgIGFycmF5W1NFQ09ORF0gPSB0b0ludChpbnB1dC5zdWJzdHIocG9zMikpO1xuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5iaWdIb3VyID0gdHJ1ZTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCdIbW0nLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIHBvcyA9IGlucHV0Lmxlbmd0aCAtIDI7XG4gICAgICAgIGFycmF5W0hPVVJdID0gdG9JbnQoaW5wdXQuc3Vic3RyKDAsIHBvcykpO1xuICAgICAgICBhcnJheVtNSU5VVEVdID0gdG9JbnQoaW5wdXQuc3Vic3RyKHBvcykpO1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oJ0htbXNzJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIHZhciBwb3MxID0gaW5wdXQubGVuZ3RoIC0gNDtcbiAgICAgICAgdmFyIHBvczIgPSBpbnB1dC5sZW5ndGggLSAyO1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0LnN1YnN0cigwLCBwb3MxKSk7XG4gICAgICAgIGFycmF5W01JTlVURV0gPSB0b0ludChpbnB1dC5zdWJzdHIocG9zMSwgMikpO1xuICAgICAgICBhcnJheVtTRUNPTkRdID0gdG9JbnQoaW5wdXQuc3Vic3RyKHBvczIpKTtcbiAgICB9KTtcblxuICAgIC8vIExPQ0FMRVNcblxuICAgIGZ1bmN0aW9uIGxvY2FsZUlzUE0gKGlucHV0KSB7XG4gICAgICAgIC8vIElFOCBRdWlya3MgTW9kZSAmIElFNyBTdGFuZGFyZHMgTW9kZSBkbyBub3QgYWxsb3cgYWNjZXNzaW5nIHN0cmluZ3MgbGlrZSBhcnJheXNcbiAgICAgICAgLy8gVXNpbmcgY2hhckF0IHNob3VsZCBiZSBtb3JlIGNvbXBhdGlibGUuXG4gICAgICAgIHJldHVybiAoKGlucHV0ICsgJycpLnRvTG93ZXJDYXNlKCkuY2hhckF0KDApID09PSAncCcpO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TG9jYWxlTWVyaWRpZW1QYXJzZSA9IC9bYXBdXFwuP20/XFwuPy9pO1xuICAgIGZ1bmN0aW9uIGxvY2FsZU1lcmlkaWVtIChob3VycywgbWludXRlcywgaXNMb3dlcikge1xuICAgICAgICBpZiAoaG91cnMgPiAxMSkge1xuICAgICAgICAgICAgcmV0dXJuIGlzTG93ZXIgPyAncG0nIDogJ1BNJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBpc0xvd2VyID8gJ2FtJyA6ICdBTSc7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8vIE1PTUVOVFNcblxuICAgIC8vIFNldHRpbmcgdGhlIGhvdXIgc2hvdWxkIGtlZXAgdGhlIHRpbWUsIGJlY2F1c2UgdGhlIHVzZXIgZXhwbGljaXRseVxuICAgIC8vIHNwZWNpZmllZCB3aGljaCBob3VyIHRoZXkgd2FudC4gU28gdHJ5aW5nIHRvIG1haW50YWluIHRoZSBzYW1lIGhvdXIgKGluXG4gICAgLy8gYSBuZXcgdGltZXpvbmUpIG1ha2VzIHNlbnNlLiBBZGRpbmcvc3VidHJhY3RpbmcgaG91cnMgZG9lcyBub3QgZm9sbG93XG4gICAgLy8gdGhpcyBydWxlLlxuICAgIHZhciBnZXRTZXRIb3VyID0gbWFrZUdldFNldCgnSG91cnMnLCB0cnVlKTtcblxuICAgIHZhciBiYXNlQ29uZmlnID0ge1xuICAgICAgICBjYWxlbmRhcjogZGVmYXVsdENhbGVuZGFyLFxuICAgICAgICBsb25nRGF0ZUZvcm1hdDogZGVmYXVsdExvbmdEYXRlRm9ybWF0LFxuICAgICAgICBpbnZhbGlkRGF0ZTogZGVmYXVsdEludmFsaWREYXRlLFxuICAgICAgICBvcmRpbmFsOiBkZWZhdWx0T3JkaW5hbCxcbiAgICAgICAgZGF5T2ZNb250aE9yZGluYWxQYXJzZTogZGVmYXVsdERheU9mTW9udGhPcmRpbmFsUGFyc2UsXG4gICAgICAgIHJlbGF0aXZlVGltZTogZGVmYXVsdFJlbGF0aXZlVGltZSxcblxuICAgICAgICBtb250aHM6IGRlZmF1bHRMb2NhbGVNb250aHMsXG4gICAgICAgIG1vbnRoc1Nob3J0OiBkZWZhdWx0TG9jYWxlTW9udGhzU2hvcnQsXG5cbiAgICAgICAgd2VlazogZGVmYXVsdExvY2FsZVdlZWssXG5cbiAgICAgICAgd2Vla2RheXM6IGRlZmF1bHRMb2NhbGVXZWVrZGF5cyxcbiAgICAgICAgd2Vla2RheXNNaW46IGRlZmF1bHRMb2NhbGVXZWVrZGF5c01pbixcbiAgICAgICAgd2Vla2RheXNTaG9ydDogZGVmYXVsdExvY2FsZVdlZWtkYXlzU2hvcnQsXG5cbiAgICAgICAgbWVyaWRpZW1QYXJzZTogZGVmYXVsdExvY2FsZU1lcmlkaWVtUGFyc2VcbiAgICB9O1xuXG4gICAgLy8gaW50ZXJuYWwgc3RvcmFnZSBmb3IgbG9jYWxlIGNvbmZpZyBmaWxlc1xuICAgIHZhciBsb2NhbGVzID0ge307XG4gICAgdmFyIGxvY2FsZUZhbWlsaWVzID0ge307XG4gICAgdmFyIGdsb2JhbExvY2FsZTtcblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZUxvY2FsZShrZXkpIHtcbiAgICAgICAgcmV0dXJuIGtleSA/IGtleS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoJ18nLCAnLScpIDoga2V5O1xuICAgIH1cblxuICAgIC8vIHBpY2sgdGhlIGxvY2FsZSBmcm9tIHRoZSBhcnJheVxuICAgIC8vIHRyeSBbJ2VuLWF1JywgJ2VuLWdiJ10gYXMgJ2VuLWF1JywgJ2VuLWdiJywgJ2VuJywgYXMgaW4gbW92ZSB0aHJvdWdoIHRoZSBsaXN0IHRyeWluZyBlYWNoXG4gICAgLy8gc3Vic3RyaW5nIGZyb20gbW9zdCBzcGVjaWZpYyB0byBsZWFzdCwgYnV0IG1vdmUgdG8gdGhlIG5leHQgYXJyYXkgaXRlbSBpZiBpdCdzIGEgbW9yZSBzcGVjaWZpYyB2YXJpYW50IHRoYW4gdGhlIGN1cnJlbnQgcm9vdFxuICAgIGZ1bmN0aW9uIGNob29zZUxvY2FsZShuYW1lcykge1xuICAgICAgICB2YXIgaSA9IDAsIGosIG5leHQsIGxvY2FsZSwgc3BsaXQ7XG5cbiAgICAgICAgd2hpbGUgKGkgPCBuYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHNwbGl0ID0gbm9ybWFsaXplTG9jYWxlKG5hbWVzW2ldKS5zcGxpdCgnLScpO1xuICAgICAgICAgICAgaiA9IHNwbGl0Lmxlbmd0aDtcbiAgICAgICAgICAgIG5leHQgPSBub3JtYWxpemVMb2NhbGUobmFtZXNbaSArIDFdKTtcbiAgICAgICAgICAgIG5leHQgPSBuZXh0ID8gbmV4dC5zcGxpdCgnLScpIDogbnVsbDtcbiAgICAgICAgICAgIHdoaWxlIChqID4gMCkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGxvYWRMb2NhbGUoc3BsaXQuc2xpY2UoMCwgaikuam9pbignLScpKTtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChuZXh0ICYmIG5leHQubGVuZ3RoID49IGogJiYgY29tcGFyZUFycmF5cyhzcGxpdCwgbmV4dCwgdHJ1ZSkgPj0gaiAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgLy90aGUgbmV4dCBhcnJheSBpdGVtIGlzIGJldHRlciB0aGFuIGEgc2hhbGxvd2VyIHN1YnN0cmluZyBvZiB0aGlzIG9uZVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgai0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9hZExvY2FsZShuYW1lKSB7XG4gICAgICAgIHZhciBvbGRMb2NhbGUgPSBudWxsO1xuICAgICAgICAvLyBUT0RPOiBGaW5kIGEgYmV0dGVyIHdheSB0byByZWdpc3RlciBhbmQgbG9hZCBhbGwgdGhlIGxvY2FsZXMgaW4gTm9kZVxuICAgICAgICBpZiAoIWxvY2FsZXNbbmFtZV0gJiYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgICAgICAgICAgIG1vZHVsZSAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBvbGRMb2NhbGUgPSBnbG9iYWxMb2NhbGUuX2FiYnI7XG4gICAgICAgICAgICAgICAgdmFyIGFsaWFzZWRSZXF1aXJlID0gcmVxdWlyZTtcbiAgICAgICAgICAgICAgICBhbGlhc2VkUmVxdWlyZSgnLi9sb2NhbGUvJyArIG5hbWUpO1xuICAgICAgICAgICAgICAgIGdldFNldEdsb2JhbExvY2FsZShvbGRMb2NhbGUpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbG9jYWxlc1tuYW1lXTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgbG9hZCBsb2NhbGUgYW5kIHRoZW4gc2V0IHRoZSBnbG9iYWwgbG9jYWxlLiAgSWZcbiAgICAvLyBubyBhcmd1bWVudHMgYXJlIHBhc3NlZCBpbiwgaXQgd2lsbCBzaW1wbHkgcmV0dXJuIHRoZSBjdXJyZW50IGdsb2JhbFxuICAgIC8vIGxvY2FsZSBrZXkuXG4gICAgZnVuY3Rpb24gZ2V0U2V0R2xvYmFsTG9jYWxlIChrZXksIHZhbHVlcykge1xuICAgICAgICB2YXIgZGF0YTtcbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlcykpIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZ2V0TG9jYWxlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZGVmaW5lTG9jYWxlKGtleSwgdmFsdWVzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAvLyBtb21lbnQuZHVyYXRpb24uX2xvY2FsZSA9IG1vbWVudC5fbG9jYWxlID0gZGF0YTtcbiAgICAgICAgICAgICAgICBnbG9iYWxMb2NhbGUgPSBkYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKCh0eXBlb2YgY29uc29sZSAhPT0gICd1bmRlZmluZWQnKSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICAgICAgICAgICAgLy93YXJuIHVzZXIgaWYgYXJndW1lbnRzIGFyZSBwYXNzZWQgYnV0IHRoZSBsb2NhbGUgY291bGQgbm90IGJlIHNldFxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0xvY2FsZSAnICsga2V5ICsgICcgbm90IGZvdW5kLiBEaWQgeW91IGZvcmdldCB0byBsb2FkIGl0PycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGUuX2FiYnI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmaW5lTG9jYWxlIChuYW1lLCBjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxvY2FsZSwgcGFyZW50Q29uZmlnID0gYmFzZUNvbmZpZztcbiAgICAgICAgICAgIGNvbmZpZy5hYmJyID0gbmFtZTtcbiAgICAgICAgICAgIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkZXByZWNhdGVTaW1wbGUoJ2RlZmluZUxvY2FsZU92ZXJyaWRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICd1c2UgbW9tZW50LnVwZGF0ZUxvY2FsZShsb2NhbGVOYW1lLCBjb25maWcpIHRvIGNoYW5nZSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdhbiBleGlzdGluZyBsb2NhbGUuIG1vbWVudC5kZWZpbmVMb2NhbGUobG9jYWxlTmFtZSwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnY29uZmlnKSBzaG91bGQgb25seSBiZSB1c2VkIGZvciBjcmVhdGluZyBhIG5ldyBsb2NhbGUgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnU2VlIGh0dHA6Ly9tb21lbnRqcy5jb20vZ3VpZGVzLyMvd2FybmluZ3MvZGVmaW5lLWxvY2FsZS8gZm9yIG1vcmUgaW5mby4nKTtcbiAgICAgICAgICAgICAgICBwYXJlbnRDb25maWcgPSBsb2NhbGVzW25hbWVdLl9jb25maWc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNvbmZpZy5wYXJlbnRMb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChsb2NhbGVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29uZmlnID0gbG9jYWxlc1tjb25maWcucGFyZW50TG9jYWxlXS5fY29uZmlnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvY2FsZSA9IGxvYWRMb2NhbGUoY29uZmlnLnBhcmVudExvY2FsZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29uZmlnID0gbG9jYWxlLl9jb25maWc7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWxvY2FsZUZhbWlsaWVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlRmFtaWxpZXNbY29uZmlnLnBhcmVudExvY2FsZV0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsZUZhbWlsaWVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnOiBjb25maWdcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhbGVzW25hbWVdID0gbmV3IExvY2FsZShtZXJnZUNvbmZpZ3MocGFyZW50Q29uZmlnLCBjb25maWcpKTtcblxuICAgICAgICAgICAgaWYgKGxvY2FsZUZhbWlsaWVzW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgbG9jYWxlRmFtaWxpZXNbbmFtZV0uZm9yRWFjaChmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgICAgICAgICBkZWZpbmVMb2NhbGUoeC5uYW1lLCB4LmNvbmZpZyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgZm9yIG5vdzogYWxzbyBzZXQgdGhlIGxvY2FsZVxuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHdlIHNldCB0aGUgbG9jYWxlIEFGVEVSIGFsbCBjaGlsZCBsb2NhbGVzIGhhdmUgYmVlblxuICAgICAgICAgICAgLy8gY3JlYXRlZCwgc28gd2Ugd29uJ3QgZW5kIHVwIHdpdGggdGhlIGNoaWxkIGxvY2FsZSBzZXQuXG4gICAgICAgICAgICBnZXRTZXRHbG9iYWxMb2NhbGUobmFtZSk7XG5cblxuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZXNbbmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyB1c2VmdWwgZm9yIHRlc3RpbmdcbiAgICAgICAgICAgIGRlbGV0ZSBsb2NhbGVzW25hbWVdO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1cGRhdGVMb2NhbGUobmFtZSwgY29uZmlnKSB7XG4gICAgICAgIGlmIChjb25maWcgIT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxvY2FsZSwgdG1wTG9jYWxlLCBwYXJlbnRDb25maWcgPSBiYXNlQ29uZmlnO1xuICAgICAgICAgICAgLy8gTUVSR0VcbiAgICAgICAgICAgIHRtcExvY2FsZSA9IGxvYWRMb2NhbGUobmFtZSk7XG4gICAgICAgICAgICBpZiAodG1wTG9jYWxlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnRDb25maWcgPSB0bXBMb2NhbGUuX2NvbmZpZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbmZpZyA9IG1lcmdlQ29uZmlncyhwYXJlbnRDb25maWcsIGNvbmZpZyk7XG4gICAgICAgICAgICBsb2NhbGUgPSBuZXcgTG9jYWxlKGNvbmZpZyk7XG4gICAgICAgICAgICBsb2NhbGUucGFyZW50TG9jYWxlID0gbG9jYWxlc1tuYW1lXTtcbiAgICAgICAgICAgIGxvY2FsZXNbbmFtZV0gPSBsb2NhbGU7XG5cbiAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgZm9yIG5vdzogYWxzbyBzZXQgdGhlIGxvY2FsZVxuICAgICAgICAgICAgZ2V0U2V0R2xvYmFsTG9jYWxlKG5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gcGFzcyBudWxsIGZvciBjb25maWcgdG8gdW51cGRhdGUsIHVzZWZ1bCBmb3IgdGVzdHNcbiAgICAgICAgICAgIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxlc1tuYW1lXS5wYXJlbnRMb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBsb2NhbGVzW25hbWVdID0gbG9jYWxlc1tuYW1lXS5wYXJlbnRMb2NhbGU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGxvY2FsZXNbbmFtZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsb2NhbGVzW25hbWVdO1xuICAgIH1cblxuICAgIC8vIHJldHVybnMgbG9jYWxlIGRhdGFcbiAgICBmdW5jdGlvbiBnZXRMb2NhbGUgKGtleSkge1xuICAgICAgICB2YXIgbG9jYWxlO1xuXG4gICAgICAgIGlmIChrZXkgJiYga2V5Ll9sb2NhbGUgJiYga2V5Ll9sb2NhbGUuX2FiYnIpIHtcbiAgICAgICAgICAgIGtleSA9IGtleS5fbG9jYWxlLl9hYmJyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFrZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzQXJyYXkoa2V5KSkge1xuICAgICAgICAgICAgLy9zaG9ydC1jaXJjdWl0IGV2ZXJ5dGhpbmcgZWxzZVxuICAgICAgICAgICAgbG9jYWxlID0gbG9hZExvY2FsZShrZXkpO1xuICAgICAgICAgICAgaWYgKGxvY2FsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBrZXkgPSBba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjaG9vc2VMb2NhbGUoa2V5KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0TG9jYWxlcygpIHtcbiAgICAgICAgcmV0dXJuIGtleXMobG9jYWxlcyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2tPdmVyZmxvdyAobSkge1xuICAgICAgICB2YXIgb3ZlcmZsb3c7XG4gICAgICAgIHZhciBhID0gbS5fYTtcblxuICAgICAgICBpZiAoYSAmJiBnZXRQYXJzaW5nRmxhZ3MobSkub3ZlcmZsb3cgPT09IC0yKSB7XG4gICAgICAgICAgICBvdmVyZmxvdyA9XG4gICAgICAgICAgICAgICAgYVtNT05USF0gICAgICAgPCAwIHx8IGFbTU9OVEhdICAgICAgID4gMTEgID8gTU9OVEggOlxuICAgICAgICAgICAgICAgIGFbREFURV0gICAgICAgIDwgMSB8fCBhW0RBVEVdICAgICAgICA+IGRheXNJbk1vbnRoKGFbWUVBUl0sIGFbTU9OVEhdKSA/IERBVEUgOlxuICAgICAgICAgICAgICAgIGFbSE9VUl0gICAgICAgIDwgMCB8fCBhW0hPVVJdICAgICAgICA+IDI0IHx8IChhW0hPVVJdID09PSAyNCAmJiAoYVtNSU5VVEVdICE9PSAwIHx8IGFbU0VDT05EXSAhPT0gMCB8fCBhW01JTExJU0VDT05EXSAhPT0gMCkpID8gSE9VUiA6XG4gICAgICAgICAgICAgICAgYVtNSU5VVEVdICAgICAgPCAwIHx8IGFbTUlOVVRFXSAgICAgID4gNTkgID8gTUlOVVRFIDpcbiAgICAgICAgICAgICAgICBhW1NFQ09ORF0gICAgICA8IDAgfHwgYVtTRUNPTkRdICAgICAgPiA1OSAgPyBTRUNPTkQgOlxuICAgICAgICAgICAgICAgIGFbTUlMTElTRUNPTkRdIDwgMCB8fCBhW01JTExJU0VDT05EXSA+IDk5OSA/IE1JTExJU0VDT05EIDpcbiAgICAgICAgICAgICAgICAtMTtcblxuICAgICAgICAgICAgaWYgKGdldFBhcnNpbmdGbGFncyhtKS5fb3ZlcmZsb3dEYXlPZlllYXIgJiYgKG92ZXJmbG93IDwgWUVBUiB8fCBvdmVyZmxvdyA+IERBVEUpKSB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3cgPSBEQVRFO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGdldFBhcnNpbmdGbGFncyhtKS5fb3ZlcmZsb3dXZWVrcyAmJiBvdmVyZmxvdyA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBvdmVyZmxvdyA9IFdFRUs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZ2V0UGFyc2luZ0ZsYWdzKG0pLl9vdmVyZmxvd1dlZWtkYXkgJiYgb3ZlcmZsb3cgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3cgPSBXRUVLREFZO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MobSkub3ZlcmZsb3cgPSBvdmVyZmxvdztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtO1xuICAgIH1cblxuICAgIC8vIFBpY2sgdGhlIGZpcnN0IGRlZmluZWQgb2YgdHdvIG9yIHRocmVlIGFyZ3VtZW50cy5cbiAgICBmdW5jdGlvbiBkZWZhdWx0cyhhLCBiLCBjKSB7XG4gICAgICAgIGlmIChhICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBhO1xuICAgICAgICB9XG4gICAgICAgIGlmIChiICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKSB7XG4gICAgICAgIC8vIGhvb2tzIGlzIGFjdHVhbGx5IHRoZSBleHBvcnRlZCBtb21lbnQgb2JqZWN0XG4gICAgICAgIHZhciBub3dWYWx1ZSA9IG5ldyBEYXRlKGhvb2tzLm5vdygpKTtcbiAgICAgICAgaWYgKGNvbmZpZy5fdXNlVVRDKSB7XG4gICAgICAgICAgICByZXR1cm4gW25vd1ZhbHVlLmdldFVUQ0Z1bGxZZWFyKCksIG5vd1ZhbHVlLmdldFVUQ01vbnRoKCksIG5vd1ZhbHVlLmdldFVUQ0RhdGUoKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtub3dWYWx1ZS5nZXRGdWxsWWVhcigpLCBub3dWYWx1ZS5nZXRNb250aCgpLCBub3dWYWx1ZS5nZXREYXRlKCldO1xuICAgIH1cblxuICAgIC8vIGNvbnZlcnQgYW4gYXJyYXkgdG8gYSBkYXRlLlxuICAgIC8vIHRoZSBhcnJheSBzaG91bGQgbWlycm9yIHRoZSBwYXJhbWV0ZXJzIGJlbG93XG4gICAgLy8gbm90ZTogYWxsIHZhbHVlcyBwYXN0IHRoZSB5ZWFyIGFyZSBvcHRpb25hbCBhbmQgd2lsbCBkZWZhdWx0IHRvIHRoZSBsb3dlc3QgcG9zc2libGUgdmFsdWUuXG4gICAgLy8gW3llYXIsIG1vbnRoLCBkYXkgLCBob3VyLCBtaW51dGUsIHNlY29uZCwgbWlsbGlzZWNvbmRdXG4gICAgZnVuY3Rpb24gY29uZmlnRnJvbUFycmF5IChjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGRhdGUsIGlucHV0ID0gW10sIGN1cnJlbnREYXRlLCBleHBlY3RlZFdlZWtkYXksIHllYXJUb1VzZTtcblxuICAgICAgICBpZiAoY29uZmlnLl9kKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50RGF0ZSA9IGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKTtcblxuICAgICAgICAvL2NvbXB1dGUgZGF5IG9mIHRoZSB5ZWFyIGZyb20gd2Vla3MgYW5kIHdlZWtkYXlzXG4gICAgICAgIGlmIChjb25maWcuX3cgJiYgY29uZmlnLl9hW0RBVEVdID09IG51bGwgJiYgY29uZmlnLl9hW01PTlRIXSA9PSBudWxsKSB7XG4gICAgICAgICAgICBkYXlPZlllYXJGcm9tV2Vla0luZm8oY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vaWYgdGhlIGRheSBvZiB0aGUgeWVhciBpcyBzZXQsIGZpZ3VyZSBvdXQgd2hhdCBpdCBpc1xuICAgICAgICBpZiAoY29uZmlnLl9kYXlPZlllYXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgeWVhclRvVXNlID0gZGVmYXVsdHMoY29uZmlnLl9hW1lFQVJdLCBjdXJyZW50RGF0ZVtZRUFSXSk7XG5cbiAgICAgICAgICAgIGlmIChjb25maWcuX2RheU9mWWVhciA+IGRheXNJblllYXIoeWVhclRvVXNlKSB8fCBjb25maWcuX2RheU9mWWVhciA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLl9vdmVyZmxvd0RheU9mWWVhciA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRhdGUgPSBjcmVhdGVVVENEYXRlKHllYXJUb1VzZSwgMCwgY29uZmlnLl9kYXlPZlllYXIpO1xuICAgICAgICAgICAgY29uZmlnLl9hW01PTlRIXSA9IGRhdGUuZ2V0VVRDTW9udGgoKTtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtEQVRFXSA9IGRhdGUuZ2V0VVRDRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGVmYXVsdCB0byBjdXJyZW50IGRhdGUuXG4gICAgICAgIC8vICogaWYgbm8geWVhciwgbW9udGgsIGRheSBvZiBtb250aCBhcmUgZ2l2ZW4sIGRlZmF1bHQgdG8gdG9kYXlcbiAgICAgICAgLy8gKiBpZiBkYXkgb2YgbW9udGggaXMgZ2l2ZW4sIGRlZmF1bHQgbW9udGggYW5kIHllYXJcbiAgICAgICAgLy8gKiBpZiBtb250aCBpcyBnaXZlbiwgZGVmYXVsdCBvbmx5IHllYXJcbiAgICAgICAgLy8gKiBpZiB5ZWFyIGlzIGdpdmVuLCBkb24ndCBkZWZhdWx0IGFueXRoaW5nXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAzICYmIGNvbmZpZy5fYVtpXSA9PSBudWxsOyArK2kpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gY3VycmVudERhdGVbaV07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBaZXJvIG91dCB3aGF0ZXZlciB3YXMgbm90IGRlZmF1bHRlZCwgaW5jbHVkaW5nIHRpbWVcbiAgICAgICAgZm9yICg7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gKGNvbmZpZy5fYVtpXSA9PSBudWxsKSA/IChpID09PSAyID8gMSA6IDApIDogY29uZmlnLl9hW2ldO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIDI0OjAwOjAwLjAwMFxuICAgICAgICBpZiAoY29uZmlnLl9hW0hPVVJdID09PSAyNCAmJlxuICAgICAgICAgICAgICAgIGNvbmZpZy5fYVtNSU5VVEVdID09PSAwICYmXG4gICAgICAgICAgICAgICAgY29uZmlnLl9hW1NFQ09ORF0gPT09IDAgJiZcbiAgICAgICAgICAgICAgICBjb25maWcuX2FbTUlMTElTRUNPTkRdID09PSAwKSB7XG4gICAgICAgICAgICBjb25maWcuX25leHREYXkgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9hW0hPVVJdID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZy5fZCA9IChjb25maWcuX3VzZVVUQyA/IGNyZWF0ZVVUQ0RhdGUgOiBjcmVhdGVEYXRlKS5hcHBseShudWxsLCBpbnB1dCk7XG4gICAgICAgIGV4cGVjdGVkV2Vla2RheSA9IGNvbmZpZy5fdXNlVVRDID8gY29uZmlnLl9kLmdldFVUQ0RheSgpIDogY29uZmlnLl9kLmdldERheSgpO1xuXG4gICAgICAgIC8vIEFwcGx5IHRpbWV6b25lIG9mZnNldCBmcm9tIGlucHV0LiBUaGUgYWN0dWFsIHV0Y09mZnNldCBjYW4gYmUgY2hhbmdlZFxuICAgICAgICAvLyB3aXRoIHBhcnNlWm9uZS5cbiAgICAgICAgaWYgKGNvbmZpZy5fdHptICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZC5zZXRVVENNaW51dGVzKGNvbmZpZy5fZC5nZXRVVENNaW51dGVzKCkgLSBjb25maWcuX3R6bSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLl9uZXh0RGF5KSB7XG4gICAgICAgICAgICBjb25maWcuX2FbSE9VUl0gPSAyNDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGZvciBtaXNtYXRjaGluZyBkYXkgb2Ygd2Vla1xuICAgICAgICBpZiAoY29uZmlnLl93ICYmIHR5cGVvZiBjb25maWcuX3cuZCAhPT0gJ3VuZGVmaW5lZCcgJiYgY29uZmlnLl93LmQgIT09IGV4cGVjdGVkV2Vla2RheSkge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykud2Vla2RheU1pc21hdGNoID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrSW5mbyhjb25maWcpIHtcbiAgICAgICAgdmFyIHcsIHdlZWtZZWFyLCB3ZWVrLCB3ZWVrZGF5LCBkb3csIGRveSwgdGVtcCwgd2Vla2RheU92ZXJmbG93O1xuXG4gICAgICAgIHcgPSBjb25maWcuX3c7XG4gICAgICAgIGlmICh3LkdHICE9IG51bGwgfHwgdy5XICE9IG51bGwgfHwgdy5FICE9IG51bGwpIHtcbiAgICAgICAgICAgIGRvdyA9IDE7XG4gICAgICAgICAgICBkb3kgPSA0O1xuXG4gICAgICAgICAgICAvLyBUT0RPOiBXZSBuZWVkIHRvIHRha2UgdGhlIGN1cnJlbnQgaXNvV2Vla1llYXIsIGJ1dCB0aGF0IGRlcGVuZHMgb25cbiAgICAgICAgICAgIC8vIGhvdyB3ZSBpbnRlcnByZXQgbm93IChsb2NhbCwgdXRjLCBmaXhlZCBvZmZzZXQpLiBTbyBjcmVhdGVcbiAgICAgICAgICAgIC8vIGEgbm93IHZlcnNpb24gb2YgY3VycmVudCBjb25maWcgKHRha2UgbG9jYWwvdXRjL29mZnNldCBmbGFncywgYW5kXG4gICAgICAgICAgICAvLyBjcmVhdGUgbm93KS5cbiAgICAgICAgICAgIHdlZWtZZWFyID0gZGVmYXVsdHMody5HRywgY29uZmlnLl9hW1lFQVJdLCB3ZWVrT2ZZZWFyKGNyZWF0ZUxvY2FsKCksIDEsIDQpLnllYXIpO1xuICAgICAgICAgICAgd2VlayA9IGRlZmF1bHRzKHcuVywgMSk7XG4gICAgICAgICAgICB3ZWVrZGF5ID0gZGVmYXVsdHMody5FLCAxKTtcbiAgICAgICAgICAgIGlmICh3ZWVrZGF5IDwgMSB8fCB3ZWVrZGF5ID4gNykge1xuICAgICAgICAgICAgICAgIHdlZWtkYXlPdmVyZmxvdyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkb3cgPSBjb25maWcuX2xvY2FsZS5fd2Vlay5kb3c7XG4gICAgICAgICAgICBkb3kgPSBjb25maWcuX2xvY2FsZS5fd2Vlay5kb3k7XG5cbiAgICAgICAgICAgIHZhciBjdXJXZWVrID0gd2Vla09mWWVhcihjcmVhdGVMb2NhbCgpLCBkb3csIGRveSk7XG5cbiAgICAgICAgICAgIHdlZWtZZWFyID0gZGVmYXVsdHMody5nZywgY29uZmlnLl9hW1lFQVJdLCBjdXJXZWVrLnllYXIpO1xuXG4gICAgICAgICAgICAvLyBEZWZhdWx0IHRvIGN1cnJlbnQgd2Vlay5cbiAgICAgICAgICAgIHdlZWsgPSBkZWZhdWx0cyh3LncsIGN1cldlZWsud2Vlayk7XG5cbiAgICAgICAgICAgIGlmICh3LmQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIHdlZWtkYXkgLS0gbG93IGRheSBudW1iZXJzIGFyZSBjb25zaWRlcmVkIG5leHQgd2Vla1xuICAgICAgICAgICAgICAgIHdlZWtkYXkgPSB3LmQ7XG4gICAgICAgICAgICAgICAgaWYgKHdlZWtkYXkgPCAwIHx8IHdlZWtkYXkgPiA2KSB7XG4gICAgICAgICAgICAgICAgICAgIHdlZWtkYXlPdmVyZmxvdyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh3LmUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIGxvY2FsIHdlZWtkYXkgLS0gY291bnRpbmcgc3RhcnRzIGZyb20gYmVnaW5uaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gdy5lICsgZG93O1xuICAgICAgICAgICAgICAgIGlmICh3LmUgPCAwIHx8IHcuZSA+IDYpIHtcbiAgICAgICAgICAgICAgICAgICAgd2Vla2RheU92ZXJmbG93ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGRlZmF1bHQgdG8gYmVnaW5uaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gZG93O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh3ZWVrIDwgMSB8fCB3ZWVrID4gd2Vla3NJblllYXIod2Vla1llYXIsIGRvdywgZG95KSkge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuX292ZXJmbG93V2Vla3MgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHdlZWtkYXlPdmVyZmxvdyAhPSBudWxsKSB7XG4gICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5fb3ZlcmZsb3dXZWVrZGF5ID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRlbXAgPSBkYXlPZlllYXJGcm9tV2Vla3Mod2Vla1llYXIsIHdlZWssIHdlZWtkYXksIGRvdywgZG95KTtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtZRUFSXSA9IHRlbXAueWVhcjtcbiAgICAgICAgICAgIGNvbmZpZy5fZGF5T2ZZZWFyID0gdGVtcC5kYXlPZlllYXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpc28gODYwMSByZWdleFxuICAgIC8vIDAwMDAtMDAtMDAgMDAwMC1XMDAgb3IgMDAwMC1XMDAtMCArIFQgKyAwMCBvciAwMDowMCBvciAwMDowMDowMCBvciAwMDowMDowMC4wMDAgKyArMDA6MDAgb3IgKzAwMDAgb3IgKzAwKVxuICAgIHZhciBleHRlbmRlZElzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KS0oPzpcXGRcXGQtXFxkXFxkfFdcXGRcXGQtXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86OlxcZFxcZCg/OjpcXGRcXGQoPzpbLixdXFxkKyk/KT8pPykoW1xcK1xcLV1cXGRcXGQoPzo6P1xcZFxcZCk/fFxccypaKT8pPyQvO1xuICAgIHZhciBiYXNpY0lzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KSg/OlxcZFxcZFxcZFxcZHxXXFxkXFxkXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86XFxkXFxkKD86XFxkXFxkKD86Wy4sXVxcZCspPyk/KT8pKFtcXCtcXC1dXFxkXFxkKD86Oj9cXGRcXGQpP3xcXHMqWik/KT8kLztcblxuICAgIHZhciB0elJlZ2V4ID0gL1p8WystXVxcZFxcZCg/Ojo/XFxkXFxkKT8vO1xuXG4gICAgdmFyIGlzb0RhdGVzID0gW1xuICAgICAgICBbJ1lZWVlZWS1NTS1ERCcsIC9bKy1dXFxkezZ9LVxcZFxcZC1cXGRcXGQvXSxcbiAgICAgICAgWydZWVlZLU1NLUREJywgL1xcZHs0fS1cXGRcXGQtXFxkXFxkL10sXG4gICAgICAgIFsnR0dHRy1bV11XVy1FJywgL1xcZHs0fS1XXFxkXFxkLVxcZC9dLFxuICAgICAgICBbJ0dHR0ctW1ddV1cnLCAvXFxkezR9LVdcXGRcXGQvLCBmYWxzZV0sXG4gICAgICAgIFsnWVlZWS1EREQnLCAvXFxkezR9LVxcZHszfS9dLFxuICAgICAgICBbJ1lZWVktTU0nLCAvXFxkezR9LVxcZFxcZC8sIGZhbHNlXSxcbiAgICAgICAgWydZWVlZWVlNTUREJywgL1srLV1cXGR7MTB9L10sXG4gICAgICAgIFsnWVlZWU1NREQnLCAvXFxkezh9L10sXG4gICAgICAgIC8vIFlZWVlNTSBpcyBOT1QgYWxsb3dlZCBieSB0aGUgc3RhbmRhcmRcbiAgICAgICAgWydHR0dHW1ddV1dFJywgL1xcZHs0fVdcXGR7M30vXSxcbiAgICAgICAgWydHR0dHW1ddV1cnLCAvXFxkezR9V1xcZHsyfS8sIGZhbHNlXSxcbiAgICAgICAgWydZWVlZREREJywgL1xcZHs3fS9dXG4gICAgXTtcblxuICAgIC8vIGlzbyB0aW1lIGZvcm1hdHMgYW5kIHJlZ2V4ZXNcbiAgICB2YXIgaXNvVGltZXMgPSBbXG4gICAgICAgIFsnSEg6bW06c3MuU1NTUycsIC9cXGRcXGQ6XFxkXFxkOlxcZFxcZFxcLlxcZCsvXSxcbiAgICAgICAgWydISDptbTpzcyxTU1NTJywgL1xcZFxcZDpcXGRcXGQ6XFxkXFxkLFxcZCsvXSxcbiAgICAgICAgWydISDptbTpzcycsIC9cXGRcXGQ6XFxkXFxkOlxcZFxcZC9dLFxuICAgICAgICBbJ0hIOm1tJywgL1xcZFxcZDpcXGRcXGQvXSxcbiAgICAgICAgWydISG1tc3MuU1NTUycsIC9cXGRcXGRcXGRcXGRcXGRcXGRcXC5cXGQrL10sXG4gICAgICAgIFsnSEhtbXNzLFNTU1MnLCAvXFxkXFxkXFxkXFxkXFxkXFxkLFxcZCsvXSxcbiAgICAgICAgWydISG1tc3MnLCAvXFxkXFxkXFxkXFxkXFxkXFxkL10sXG4gICAgICAgIFsnSEhtbScsIC9cXGRcXGRcXGRcXGQvXSxcbiAgICAgICAgWydISCcsIC9cXGRcXGQvXVxuICAgIF07XG5cbiAgICB2YXIgYXNwTmV0SnNvblJlZ2V4ID0gL15cXC8/RGF0ZVxcKChcXC0/XFxkKykvaTtcblxuICAgIC8vIGRhdGUgZnJvbSBpc28gZm9ybWF0XG4gICAgZnVuY3Rpb24gY29uZmlnRnJvbUlTTyhjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGwsXG4gICAgICAgICAgICBzdHJpbmcgPSBjb25maWcuX2ksXG4gICAgICAgICAgICBtYXRjaCA9IGV4dGVuZGVkSXNvUmVnZXguZXhlYyhzdHJpbmcpIHx8IGJhc2ljSXNvUmVnZXguZXhlYyhzdHJpbmcpLFxuICAgICAgICAgICAgYWxsb3dUaW1lLCBkYXRlRm9ybWF0LCB0aW1lRm9ybWF0LCB0ekZvcm1hdDtcblxuICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmlzbyA9IHRydWU7XG5cbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBpc29EYXRlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNvRGF0ZXNbaV1bMV0uZXhlYyhtYXRjaFsxXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdCA9IGlzb0RhdGVzW2ldWzBdO1xuICAgICAgICAgICAgICAgICAgICBhbGxvd1RpbWUgPSBpc29EYXRlc1tpXVsyXSAhPT0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRlRm9ybWF0ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25maWcuX2lzVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWF0Y2hbM10pIHtcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gaXNvVGltZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc29UaW1lc1tpXVsxXS5leGVjKG1hdGNoWzNdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWF0Y2hbMl0gc2hvdWxkIGJlICdUJyBvciBzcGFjZVxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZUZvcm1hdCA9IChtYXRjaFsyXSB8fCAnICcpICsgaXNvVGltZXNbaV1bMF07XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGltZUZvcm1hdCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFhbGxvd1RpbWUgJiYgdGltZUZvcm1hdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1hdGNoWzRdKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR6UmVnZXguZXhlYyhtYXRjaFs0XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHpGb3JtYXQgPSAnWic7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25maWcuX2YgPSBkYXRlRm9ybWF0ICsgKHRpbWVGb3JtYXQgfHwgJycpICsgKHR6Rm9ybWF0IHx8ICcnKTtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUkZDIDI4MjIgcmVnZXg6IEZvciBkZXRhaWxzIHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMjgyMiNzZWN0aW9uLTMuM1xuICAgIHZhciByZmMyODIyID0gL14oPzooTW9ufFR1ZXxXZWR8VGh1fEZyaXxTYXR8U3VuKSw/XFxzKT8oXFxkezEsMn0pXFxzKEphbnxGZWJ8TWFyfEFwcnxNYXl8SnVufEp1bHxBdWd8U2VwfE9jdHxOb3Z8RGVjKVxccyhcXGR7Miw0fSlcXHMoXFxkXFxkKTooXFxkXFxkKSg/OjooXFxkXFxkKSk/XFxzKD86KFVUfEdNVHxbRUNNUF1bU0RdVCl8KFtael0pfChbKy1dXFxkezR9KSkkLztcblxuICAgIGZ1bmN0aW9uIGV4dHJhY3RGcm9tUkZDMjgyMlN0cmluZ3MoeWVhclN0ciwgbW9udGhTdHIsIGRheVN0ciwgaG91clN0ciwgbWludXRlU3RyLCBzZWNvbmRTdHIpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtcbiAgICAgICAgICAgIHVudHJ1bmNhdGVZZWFyKHllYXJTdHIpLFxuICAgICAgICAgICAgZGVmYXVsdExvY2FsZU1vbnRoc1Nob3J0LmluZGV4T2YobW9udGhTdHIpLFxuICAgICAgICAgICAgcGFyc2VJbnQoZGF5U3RyLCAxMCksXG4gICAgICAgICAgICBwYXJzZUludChob3VyU3RyLCAxMCksXG4gICAgICAgICAgICBwYXJzZUludChtaW51dGVTdHIsIDEwKVxuICAgICAgICBdO1xuXG4gICAgICAgIGlmIChzZWNvbmRTdHIpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBhcnNlSW50KHNlY29uZFN0ciwgMTApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdW50cnVuY2F0ZVllYXIoeWVhclN0cikge1xuICAgICAgICB2YXIgeWVhciA9IHBhcnNlSW50KHllYXJTdHIsIDEwKTtcbiAgICAgICAgaWYgKHllYXIgPD0gNDkpIHtcbiAgICAgICAgICAgIHJldHVybiAyMDAwICsgeWVhcjtcbiAgICAgICAgfSBlbHNlIGlmICh5ZWFyIDw9IDk5OSkge1xuICAgICAgICAgICAgcmV0dXJuIDE5MDAgKyB5ZWFyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB5ZWFyO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByZXByb2Nlc3NSRkMyODIyKHMpIHtcbiAgICAgICAgLy8gUmVtb3ZlIGNvbW1lbnRzIGFuZCBmb2xkaW5nIHdoaXRlc3BhY2UgYW5kIHJlcGxhY2UgbXVsdGlwbGUtc3BhY2VzIHdpdGggYSBzaW5nbGUgc3BhY2VcbiAgICAgICAgcmV0dXJuIHMucmVwbGFjZSgvXFwoW14pXSpcXCl8W1xcblxcdF0vZywgJyAnKS5yZXBsYWNlKC8oXFxzXFxzKykvZywgJyAnKS5yZXBsYWNlKC9eXFxzXFxzKi8sICcnKS5yZXBsYWNlKC9cXHNcXHMqJC8sICcnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja1dlZWtkYXkod2Vla2RheVN0ciwgcGFyc2VkSW5wdXQsIGNvbmZpZykge1xuICAgICAgICBpZiAod2Vla2RheVN0cikge1xuICAgICAgICAgICAgLy8gVE9ETzogUmVwbGFjZSB0aGUgdmFuaWxsYSBKUyBEYXRlIG9iamVjdCB3aXRoIGFuIGluZGVwZW50ZW50IGRheS1vZi13ZWVrIGNoZWNrLlxuICAgICAgICAgICAgdmFyIHdlZWtkYXlQcm92aWRlZCA9IGRlZmF1bHRMb2NhbGVXZWVrZGF5c1Nob3J0LmluZGV4T2Yod2Vla2RheVN0ciksXG4gICAgICAgICAgICAgICAgd2Vla2RheUFjdHVhbCA9IG5ldyBEYXRlKHBhcnNlZElucHV0WzBdLCBwYXJzZWRJbnB1dFsxXSwgcGFyc2VkSW5wdXRbMl0pLmdldERheSgpO1xuICAgICAgICAgICAgaWYgKHdlZWtkYXlQcm92aWRlZCAhPT0gd2Vla2RheUFjdHVhbCkge1xuICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLndlZWtkYXlNaXNtYXRjaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciBvYnNPZmZzZXRzID0ge1xuICAgICAgICBVVDogMCxcbiAgICAgICAgR01UOiAwLFxuICAgICAgICBFRFQ6IC00ICogNjAsXG4gICAgICAgIEVTVDogLTUgKiA2MCxcbiAgICAgICAgQ0RUOiAtNSAqIDYwLFxuICAgICAgICBDU1Q6IC02ICogNjAsXG4gICAgICAgIE1EVDogLTYgKiA2MCxcbiAgICAgICAgTVNUOiAtNyAqIDYwLFxuICAgICAgICBQRFQ6IC03ICogNjAsXG4gICAgICAgIFBTVDogLTggKiA2MFxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBjYWxjdWxhdGVPZmZzZXQob2JzT2Zmc2V0LCBtaWxpdGFyeU9mZnNldCwgbnVtT2Zmc2V0KSB7XG4gICAgICAgIGlmIChvYnNPZmZzZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBvYnNPZmZzZXRzW29ic09mZnNldF07XG4gICAgICAgIH0gZWxzZSBpZiAobWlsaXRhcnlPZmZzZXQpIHtcbiAgICAgICAgICAgIC8vIHRoZSBvbmx5IGFsbG93ZWQgbWlsaXRhcnkgdHogaXMgWlxuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaG0gPSBwYXJzZUludChudW1PZmZzZXQsIDEwKTtcbiAgICAgICAgICAgIHZhciBtID0gaG0gJSAxMDAsIGggPSAoaG0gLSBtKSAvIDEwMDtcbiAgICAgICAgICAgIHJldHVybiBoICogNjAgKyBtO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZGF0ZSBhbmQgdGltZSBmcm9tIHJlZiAyODIyIGZvcm1hdFxuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21SRkMyODIyKGNvbmZpZykge1xuICAgICAgICB2YXIgbWF0Y2ggPSByZmMyODIyLmV4ZWMocHJlcHJvY2Vzc1JGQzI4MjIoY29uZmlnLl9pKSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgdmFyIHBhcnNlZEFycmF5ID0gZXh0cmFjdEZyb21SRkMyODIyU3RyaW5ncyhtYXRjaFs0XSwgbWF0Y2hbM10sIG1hdGNoWzJdLCBtYXRjaFs1XSwgbWF0Y2hbNl0sIG1hdGNoWzddKTtcbiAgICAgICAgICAgIGlmICghY2hlY2tXZWVrZGF5KG1hdGNoWzFdLCBwYXJzZWRBcnJheSwgY29uZmlnKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uZmlnLl9hID0gcGFyc2VkQXJyYXk7XG4gICAgICAgICAgICBjb25maWcuX3R6bSA9IGNhbGN1bGF0ZU9mZnNldChtYXRjaFs4XSwgbWF0Y2hbOV0sIG1hdGNoWzEwXSk7XG5cbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IGNyZWF0ZVVUQ0RhdGUuYXBwbHkobnVsbCwgY29uZmlnLl9hKTtcbiAgICAgICAgICAgIGNvbmZpZy5fZC5zZXRVVENNaW51dGVzKGNvbmZpZy5fZC5nZXRVVENNaW51dGVzKCkgLSBjb25maWcuX3R6bSk7XG5cbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnJmYzI4MjIgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gaXNvIGZvcm1hdCBvciBmYWxsYmFja1xuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21TdHJpbmcoY29uZmlnKSB7XG4gICAgICAgIHZhciBtYXRjaGVkID0gYXNwTmV0SnNvblJlZ2V4LmV4ZWMoY29uZmlnLl9pKTtcblxuICAgICAgICBpZiAobWF0Y2hlZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoK21hdGNoZWRbMV0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uZmlnRnJvbUlTTyhjb25maWcpO1xuICAgICAgICBpZiAoY29uZmlnLl9pc1ZhbGlkID09PSBmYWxzZSkge1xuICAgICAgICAgICAgZGVsZXRlIGNvbmZpZy5faXNWYWxpZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZ0Zyb21SRkMyODIyKGNvbmZpZyk7XG4gICAgICAgIGlmIChjb25maWcuX2lzVmFsaWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBkZWxldGUgY29uZmlnLl9pc1ZhbGlkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluYWwgYXR0ZW1wdCwgdXNlIElucHV0IEZhbGxiYWNrXG4gICAgICAgIGhvb2tzLmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgfVxuXG4gICAgaG9va3MuY3JlYXRlRnJvbUlucHV0RmFsbGJhY2sgPSBkZXByZWNhdGUoXG4gICAgICAgICd2YWx1ZSBwcm92aWRlZCBpcyBub3QgaW4gYSByZWNvZ25pemVkIFJGQzI4MjIgb3IgSVNPIGZvcm1hdC4gbW9tZW50IGNvbnN0cnVjdGlvbiBmYWxscyBiYWNrIHRvIGpzIERhdGUoKSwgJyArXG4gICAgICAgICd3aGljaCBpcyBub3QgcmVsaWFibGUgYWNyb3NzIGFsbCBicm93c2VycyBhbmQgdmVyc2lvbnMuIE5vbiBSRkMyODIyL0lTTyBkYXRlIGZvcm1hdHMgYXJlICcgK1xuICAgICAgICAnZGlzY291cmFnZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhbiB1cGNvbWluZyBtYWpvciByZWxlYXNlLiBQbGVhc2UgcmVmZXIgdG8gJyArXG4gICAgICAgICdodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2pzLWRhdGUvIGZvciBtb3JlIGluZm8uJyxcbiAgICAgICAgZnVuY3Rpb24gKGNvbmZpZykge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoY29uZmlnLl9pICsgKGNvbmZpZy5fdXNlVVRDID8gJyBVVEMnIDogJycpKTtcbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBjb25zdGFudCB0aGF0IHJlZmVycyB0byB0aGUgSVNPIHN0YW5kYXJkXG4gICAgaG9va3MuSVNPXzg2MDEgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIGNvbnN0YW50IHRoYXQgcmVmZXJzIHRvIHRoZSBSRkMgMjgyMiBmb3JtXG4gICAgaG9va3MuUkZDXzI4MjIgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIGRhdGUgZnJvbSBzdHJpbmcgYW5kIGZvcm1hdCBzdHJpbmdcbiAgICBmdW5jdGlvbiBjb25maWdGcm9tU3RyaW5nQW5kRm9ybWF0KGNvbmZpZykge1xuICAgICAgICAvLyBUT0RPOiBNb3ZlIHRoaXMgdG8gYW5vdGhlciBwYXJ0IG9mIHRoZSBjcmVhdGlvbiBmbG93IHRvIHByZXZlbnQgY2lyY3VsYXIgZGVwc1xuICAgICAgICBpZiAoY29uZmlnLl9mID09PSBob29rcy5JU09fODYwMSkge1xuICAgICAgICAgICAgY29uZmlnRnJvbUlTTyhjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25maWcuX2YgPT09IGhvb2tzLlJGQ18yODIyKSB7XG4gICAgICAgICAgICBjb25maWdGcm9tUkZDMjgyMihjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbmZpZy5fYSA9IFtdO1xuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5lbXB0eSA9IHRydWU7XG5cbiAgICAgICAgLy8gVGhpcyBhcnJheSBpcyB1c2VkIHRvIG1ha2UgYSBEYXRlLCBlaXRoZXIgd2l0aCBgbmV3IERhdGVgIG9yIGBEYXRlLlVUQ2BcbiAgICAgICAgdmFyIHN0cmluZyA9ICcnICsgY29uZmlnLl9pLFxuICAgICAgICAgICAgaSwgcGFyc2VkSW5wdXQsIHRva2VucywgdG9rZW4sIHNraXBwZWQsXG4gICAgICAgICAgICBzdHJpbmdMZW5ndGggPSBzdHJpbmcubGVuZ3RoLFxuICAgICAgICAgICAgdG90YWxQYXJzZWRJbnB1dExlbmd0aCA9IDA7XG5cbiAgICAgICAgdG9rZW5zID0gZXhwYW5kRm9ybWF0KGNvbmZpZy5fZiwgY29uZmlnLl9sb2NhbGUpLm1hdGNoKGZvcm1hdHRpbmdUb2tlbnMpIHx8IFtdO1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRva2VuID0gdG9rZW5zW2ldO1xuICAgICAgICAgICAgcGFyc2VkSW5wdXQgPSAoc3RyaW5nLm1hdGNoKGdldFBhcnNlUmVnZXhGb3JUb2tlbih0b2tlbiwgY29uZmlnKSkgfHwgW10pWzBdO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ3Rva2VuJywgdG9rZW4sICdwYXJzZWRJbnB1dCcsIHBhcnNlZElucHV0LFxuICAgICAgICAgICAgLy8gICAgICAgICAncmVnZXgnLCBnZXRQYXJzZVJlZ2V4Rm9yVG9rZW4odG9rZW4sIGNvbmZpZykpO1xuICAgICAgICAgICAgaWYgKHBhcnNlZElucHV0KSB7XG4gICAgICAgICAgICAgICAgc2tpcHBlZCA9IHN0cmluZy5zdWJzdHIoMCwgc3RyaW5nLmluZGV4T2YocGFyc2VkSW5wdXQpKTtcbiAgICAgICAgICAgICAgICBpZiAoc2tpcHBlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnVudXNlZElucHV0LnB1c2goc2tpcHBlZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN0cmluZyA9IHN0cmluZy5zbGljZShzdHJpbmcuaW5kZXhPZihwYXJzZWRJbnB1dCkgKyBwYXJzZWRJbnB1dC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIHRvdGFsUGFyc2VkSW5wdXRMZW5ndGggKz0gcGFyc2VkSW5wdXQubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZG9uJ3QgcGFyc2UgaWYgaXQncyBub3QgYSBrbm93biB0b2tlblxuICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuRnVuY3Rpb25zW3Rva2VuXSkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZWRJbnB1dCkge1xuICAgICAgICAgICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5lbXB0eSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykudW51c2VkVG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhZGRUaW1lVG9BcnJheUZyb21Ub2tlbih0b2tlbiwgcGFyc2VkSW5wdXQsIGNvbmZpZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb25maWcuX3N0cmljdCAmJiAhcGFyc2VkSW5wdXQpIHtcbiAgICAgICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS51bnVzZWRUb2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGQgcmVtYWluaW5nIHVucGFyc2VkIGlucHV0IGxlbmd0aCB0byB0aGUgc3RyaW5nXG4gICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmNoYXJzTGVmdE92ZXIgPSBzdHJpbmdMZW5ndGggLSB0b3RhbFBhcnNlZElucHV0TGVuZ3RoO1xuICAgICAgICBpZiAoc3RyaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnVudXNlZElucHV0LnB1c2goc3RyaW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNsZWFyIF8xMmggZmxhZyBpZiBob3VyIGlzIDw9IDEyXG4gICAgICAgIGlmIChjb25maWcuX2FbSE9VUl0gPD0gMTIgJiZcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmJpZ0hvdXIgPT09IHRydWUgJiZcbiAgICAgICAgICAgIGNvbmZpZy5fYVtIT1VSXSA+IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmJpZ0hvdXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5wYXJzZWREYXRlUGFydHMgPSBjb25maWcuX2Euc2xpY2UoMCk7XG4gICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLm1lcmlkaWVtID0gY29uZmlnLl9tZXJpZGllbTtcbiAgICAgICAgLy8gaGFuZGxlIG1lcmlkaWVtXG4gICAgICAgIGNvbmZpZy5fYVtIT1VSXSA9IG1lcmlkaWVtRml4V3JhcChjb25maWcuX2xvY2FsZSwgY29uZmlnLl9hW0hPVVJdLCBjb25maWcuX21lcmlkaWVtKTtcblxuICAgICAgICBjb25maWdGcm9tQXJyYXkoY29uZmlnKTtcbiAgICAgICAgY2hlY2tPdmVyZmxvdyhjb25maWcpO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gbWVyaWRpZW1GaXhXcmFwIChsb2NhbGUsIGhvdXIsIG1lcmlkaWVtKSB7XG4gICAgICAgIHZhciBpc1BtO1xuXG4gICAgICAgIGlmIChtZXJpZGllbSA9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBub3RoaW5nIHRvIGRvXG4gICAgICAgICAgICByZXR1cm4gaG91cjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobG9jYWxlLm1lcmlkaWVtSG91ciAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbG9jYWxlLm1lcmlkaWVtSG91cihob3VyLCBtZXJpZGllbSk7XG4gICAgICAgIH0gZWxzZSBpZiAobG9jYWxlLmlzUE0gIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gRmFsbGJhY2tcbiAgICAgICAgICAgIGlzUG0gPSBsb2NhbGUuaXNQTShtZXJpZGllbSk7XG4gICAgICAgICAgICBpZiAoaXNQbSAmJiBob3VyIDwgMTIpIHtcbiAgICAgICAgICAgICAgICBob3VyICs9IDEyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc1BtICYmIGhvdXIgPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgaG91ciA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaG91cjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgbm90IHN1cHBvc2VkIHRvIGhhcHBlblxuICAgICAgICAgICAgcmV0dXJuIGhvdXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gc3RyaW5nIGFuZCBhcnJheSBvZiBmb3JtYXQgc3RyaW5nc1xuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21TdHJpbmdBbmRBcnJheShjb25maWcpIHtcbiAgICAgICAgdmFyIHRlbXBDb25maWcsXG4gICAgICAgICAgICBiZXN0TW9tZW50LFxuXG4gICAgICAgICAgICBzY29yZVRvQmVhdCxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBjdXJyZW50U2NvcmU7XG5cbiAgICAgICAgaWYgKGNvbmZpZy5fZi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmludmFsaWRGb3JtYXQgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoTmFOKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb25maWcuX2YubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGN1cnJlbnRTY29yZSA9IDA7XG4gICAgICAgICAgICB0ZW1wQ29uZmlnID0gY29weUNvbmZpZyh7fSwgY29uZmlnKTtcbiAgICAgICAgICAgIGlmIChjb25maWcuX3VzZVVUQyAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGVtcENvbmZpZy5fdXNlVVRDID0gY29uZmlnLl91c2VVVEM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZW1wQ29uZmlnLl9mID0gY29uZmlnLl9mW2ldO1xuICAgICAgICAgICAgY29uZmlnRnJvbVN0cmluZ0FuZEZvcm1hdCh0ZW1wQ29uZmlnKTtcblxuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKHRlbXBDb25maWcpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFueSBpbnB1dCB0aGF0IHdhcyBub3QgcGFyc2VkIGFkZCBhIHBlbmFsdHkgZm9yIHRoYXQgZm9ybWF0XG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgKz0gZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLmNoYXJzTGVmdE92ZXI7XG5cbiAgICAgICAgICAgIC8vb3IgdG9rZW5zXG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgKz0gZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLnVudXNlZFRva2Vucy5sZW5ndGggKiAxMDtcblxuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLnNjb3JlID0gY3VycmVudFNjb3JlO1xuXG4gICAgICAgICAgICBpZiAoc2NvcmVUb0JlYXQgPT0gbnVsbCB8fCBjdXJyZW50U2NvcmUgPCBzY29yZVRvQmVhdCkge1xuICAgICAgICAgICAgICAgIHNjb3JlVG9CZWF0ID0gY3VycmVudFNjb3JlO1xuICAgICAgICAgICAgICAgIGJlc3RNb21lbnQgPSB0ZW1wQ29uZmlnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZXh0ZW5kKGNvbmZpZywgYmVzdE1vbWVudCB8fCB0ZW1wQ29uZmlnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb25maWdGcm9tT2JqZWN0KGNvbmZpZykge1xuICAgICAgICBpZiAoY29uZmlnLl9kKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaSA9IG5vcm1hbGl6ZU9iamVjdFVuaXRzKGNvbmZpZy5faSk7XG4gICAgICAgIGNvbmZpZy5fYSA9IG1hcChbaS55ZWFyLCBpLm1vbnRoLCBpLmRheSB8fCBpLmRhdGUsIGkuaG91ciwgaS5taW51dGUsIGkuc2Vjb25kLCBpLm1pbGxpc2Vjb25kXSwgZnVuY3Rpb24gKG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIG9iaiAmJiBwYXJzZUludChvYmosIDEwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uZmlnRnJvbUFycmF5KGNvbmZpZyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlRnJvbUNvbmZpZyAoY29uZmlnKSB7XG4gICAgICAgIHZhciByZXMgPSBuZXcgTW9tZW50KGNoZWNrT3ZlcmZsb3cocHJlcGFyZUNvbmZpZyhjb25maWcpKSk7XG4gICAgICAgIGlmIChyZXMuX25leHREYXkpIHtcbiAgICAgICAgICAgIC8vIEFkZGluZyBpcyBzbWFydCBlbm91Z2ggYXJvdW5kIERTVFxuICAgICAgICAgICAgcmVzLmFkZCgxLCAnZCcpO1xuICAgICAgICAgICAgcmVzLl9uZXh0RGF5ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVwYXJlQ29uZmlnIChjb25maWcpIHtcbiAgICAgICAgdmFyIGlucHV0ID0gY29uZmlnLl9pLFxuICAgICAgICAgICAgZm9ybWF0ID0gY29uZmlnLl9mO1xuXG4gICAgICAgIGNvbmZpZy5fbG9jYWxlID0gY29uZmlnLl9sb2NhbGUgfHwgZ2V0TG9jYWxlKGNvbmZpZy5fbCk7XG5cbiAgICAgICAgaWYgKGlucHV0ID09PSBudWxsIHx8IChmb3JtYXQgPT09IHVuZGVmaW5lZCAmJiBpbnB1dCA9PT0gJycpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlSW52YWxpZCh7bnVsbElucHV0OiB0cnVlfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uZmlnLl9pID0gaW5wdXQgPSBjb25maWcuX2xvY2FsZS5wcmVwYXJzZShpbnB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNNb21lbnQoaW5wdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE1vbWVudChjaGVja092ZXJmbG93KGlucHV0KSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNEYXRlKGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gaW5wdXQ7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNBcnJheShmb3JtYXQpKSB7XG4gICAgICAgICAgICBjb25maWdGcm9tU3RyaW5nQW5kQXJyYXkoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQpIHtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgfSAgZWxzZSB7XG4gICAgICAgICAgICBjb25maWdGcm9tSW5wdXQoY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNWYWxpZChjb25maWcpKSB7XG4gICAgICAgICAgICBjb25maWcuX2QgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb25maWdGcm9tSW5wdXQoY29uZmlnKSB7XG4gICAgICAgIHZhciBpbnB1dCA9IGNvbmZpZy5faTtcbiAgICAgICAgaWYgKGlzVW5kZWZpbmVkKGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoaG9va3Mubm93KCkpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzRGF0ZShpbnB1dCkpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKGlucHV0LnZhbHVlT2YoKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uZmlnRnJvbVN0cmluZyhjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkoaW5wdXQpKSB7XG4gICAgICAgICAgICBjb25maWcuX2EgPSBtYXAoaW5wdXQuc2xpY2UoMCksIGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQob2JqLCAxMCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21BcnJheShjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnRnJvbU9iamVjdChjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKGlucHV0KSkge1xuICAgICAgICAgICAgLy8gZnJvbSBtaWxsaXNlY29uZHNcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKGlucHV0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhvb2tzLmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVMb2NhbE9yVVRDIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCwgaXNVVEMpIHtcbiAgICAgICAgdmFyIGMgPSB7fTtcblxuICAgICAgICBpZiAobG9jYWxlID09PSB0cnVlIHx8IGxvY2FsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHN0cmljdCA9IGxvY2FsZTtcbiAgICAgICAgICAgIGxvY2FsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgoaXNPYmplY3QoaW5wdXQpICYmIGlzT2JqZWN0RW1wdHkoaW5wdXQpKSB8fFxuICAgICAgICAgICAgICAgIChpc0FycmF5KGlucHV0KSAmJiBpbnB1dC5sZW5ndGggPT09IDApKSB7XG4gICAgICAgICAgICBpbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBvYmplY3QgY29uc3RydWN0aW9uIG11c3QgYmUgZG9uZSB0aGlzIHdheS5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzE0MjNcbiAgICAgICAgYy5faXNBTW9tZW50T2JqZWN0ID0gdHJ1ZTtcbiAgICAgICAgYy5fdXNlVVRDID0gYy5faXNVVEMgPSBpc1VUQztcbiAgICAgICAgYy5fbCA9IGxvY2FsZTtcbiAgICAgICAgYy5faSA9IGlucHV0O1xuICAgICAgICBjLl9mID0gZm9ybWF0O1xuICAgICAgICBjLl9zdHJpY3QgPSBzdHJpY3Q7XG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZyb21Db25maWcoYyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlTG9jYWwgKGlucHV0LCBmb3JtYXQsIGxvY2FsZSwgc3RyaWN0KSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVMb2NhbE9yVVRDKGlucHV0LCBmb3JtYXQsIGxvY2FsZSwgc3RyaWN0LCBmYWxzZSk7XG4gICAgfVxuXG4gICAgdmFyIHByb3RvdHlwZU1pbiA9IGRlcHJlY2F0ZShcbiAgICAgICAgJ21vbWVudCgpLm1pbiBpcyBkZXByZWNhdGVkLCB1c2UgbW9tZW50Lm1heCBpbnN0ZWFkLiBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL21pbi1tYXgvJyxcbiAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIG90aGVyID0gY3JlYXRlTG9jYWwuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzVmFsaWQoKSAmJiBvdGhlci5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3RoZXIgPCB0aGlzID8gdGhpcyA6IG90aGVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlSW52YWxpZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIHZhciBwcm90b3R5cGVNYXggPSBkZXByZWNhdGUoXG4gICAgICAgICdtb21lbnQoKS5tYXggaXMgZGVwcmVjYXRlZCwgdXNlIG1vbWVudC5taW4gaW5zdGVhZC4gaHR0cDovL21vbWVudGpzLmNvbS9ndWlkZXMvIy93YXJuaW5ncy9taW4tbWF4LycsXG4gICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBvdGhlciA9IGNyZWF0ZUxvY2FsLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICBpZiAodGhpcy5pc1ZhbGlkKCkgJiYgb3RoZXIuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG90aGVyID4gdGhpcyA/IHRoaXMgOiBvdGhlcjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUludmFsaWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBQaWNrIGEgbW9tZW50IG0gZnJvbSBtb21lbnRzIHNvIHRoYXQgbVtmbl0ob3RoZXIpIGlzIHRydWUgZm9yIGFsbFxuICAgIC8vIG90aGVyLiBUaGlzIHJlbGllcyBvbiB0aGUgZnVuY3Rpb24gZm4gdG8gYmUgdHJhbnNpdGl2ZS5cbiAgICAvL1xuICAgIC8vIG1vbWVudHMgc2hvdWxkIGVpdGhlciBiZSBhbiBhcnJheSBvZiBtb21lbnQgb2JqZWN0cyBvciBhbiBhcnJheSwgd2hvc2VcbiAgICAvLyBmaXJzdCBlbGVtZW50IGlzIGFuIGFycmF5IG9mIG1vbWVudCBvYmplY3RzLlxuICAgIGZ1bmN0aW9uIHBpY2tCeShmbiwgbW9tZW50cykge1xuICAgICAgICB2YXIgcmVzLCBpO1xuICAgICAgICBpZiAobW9tZW50cy5sZW5ndGggPT09IDEgJiYgaXNBcnJheShtb21lbnRzWzBdKSkge1xuICAgICAgICAgICAgbW9tZW50cyA9IG1vbWVudHNbMF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtb21lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUxvY2FsKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzID0gbW9tZW50c1swXTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IG1vbWVudHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmICghbW9tZW50c1tpXS5pc1ZhbGlkKCkgfHwgbW9tZW50c1tpXVtmbl0ocmVzKSkge1xuICAgICAgICAgICAgICAgIHJlcyA9IG1vbWVudHNbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBVc2UgW10uc29ydCBpbnN0ZWFkP1xuICAgIGZ1bmN0aW9uIG1pbiAoKSB7XG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuXG4gICAgICAgIHJldHVybiBwaWNrQnkoJ2lzQmVmb3JlJywgYXJncyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF4ICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG5cbiAgICAgICAgcmV0dXJuIHBpY2tCeSgnaXNBZnRlcicsIGFyZ3MpO1xuICAgIH1cblxuICAgIHZhciBub3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBEYXRlLm5vdyA/IERhdGUubm93KCkgOiArKG5ldyBEYXRlKCkpO1xuICAgIH07XG5cbiAgICB2YXIgb3JkZXJpbmcgPSBbJ3llYXInLCAncXVhcnRlcicsICdtb250aCcsICd3ZWVrJywgJ2RheScsICdob3VyJywgJ21pbnV0ZScsICdzZWNvbmQnLCAnbWlsbGlzZWNvbmQnXTtcblxuICAgIGZ1bmN0aW9uIGlzRHVyYXRpb25WYWxpZChtKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBtKSB7XG4gICAgICAgICAgICBpZiAoIShpbmRleE9mLmNhbGwob3JkZXJpbmcsIGtleSkgIT09IC0xICYmIChtW2tleV0gPT0gbnVsbCB8fCAhaXNOYU4obVtrZXldKSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHVuaXRIYXNEZWNpbWFsID0gZmFsc2U7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3JkZXJpbmcubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChtW29yZGVyaW5nW2ldXSkge1xuICAgICAgICAgICAgICAgIGlmICh1bml0SGFzRGVjaW1hbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG9ubHkgYWxsb3cgbm9uLWludGVnZXJzIGZvciBzbWFsbGVzdCB1bml0XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChwYXJzZUZsb2F0KG1bb3JkZXJpbmdbaV1dKSAhPT0gdG9JbnQobVtvcmRlcmluZ1tpXV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHVuaXRIYXNEZWNpbWFsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkJDEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1ZhbGlkO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUludmFsaWQkMSgpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKE5hTik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gRHVyYXRpb24gKGR1cmF0aW9uKSB7XG4gICAgICAgIHZhciBub3JtYWxpemVkSW5wdXQgPSBub3JtYWxpemVPYmplY3RVbml0cyhkdXJhdGlvbiksXG4gICAgICAgICAgICB5ZWFycyA9IG5vcm1hbGl6ZWRJbnB1dC55ZWFyIHx8IDAsXG4gICAgICAgICAgICBxdWFydGVycyA9IG5vcm1hbGl6ZWRJbnB1dC5xdWFydGVyIHx8IDAsXG4gICAgICAgICAgICBtb250aHMgPSBub3JtYWxpemVkSW5wdXQubW9udGggfHwgMCxcbiAgICAgICAgICAgIHdlZWtzID0gbm9ybWFsaXplZElucHV0LndlZWsgfHwgbm9ybWFsaXplZElucHV0Lmlzb1dlZWsgfHwgMCxcbiAgICAgICAgICAgIGRheXMgPSBub3JtYWxpemVkSW5wdXQuZGF5IHx8IDAsXG4gICAgICAgICAgICBob3VycyA9IG5vcm1hbGl6ZWRJbnB1dC5ob3VyIHx8IDAsXG4gICAgICAgICAgICBtaW51dGVzID0gbm9ybWFsaXplZElucHV0Lm1pbnV0ZSB8fCAwLFxuICAgICAgICAgICAgc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5zZWNvbmQgfHwgMCxcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5taWxsaXNlY29uZCB8fCAwO1xuXG4gICAgICAgIHRoaXMuX2lzVmFsaWQgPSBpc0R1cmF0aW9uVmFsaWQobm9ybWFsaXplZElucHV0KTtcblxuICAgICAgICAvLyByZXByZXNlbnRhdGlvbiBmb3IgZGF0ZUFkZFJlbW92ZVxuICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgPSArbWlsbGlzZWNvbmRzICtcbiAgICAgICAgICAgIHNlY29uZHMgKiAxZTMgKyAvLyAxMDAwXG4gICAgICAgICAgICBtaW51dGVzICogNmU0ICsgLy8gMTAwMCAqIDYwXG4gICAgICAgICAgICBob3VycyAqIDEwMDAgKiA2MCAqIDYwOyAvL3VzaW5nIDEwMDAgKiA2MCAqIDYwIGluc3RlYWQgb2YgMzZlNSB0byBhdm9pZCBmbG9hdGluZyBwb2ludCByb3VuZGluZyBlcnJvcnMgaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzI5NzhcbiAgICAgICAgLy8gQmVjYXVzZSBvZiBkYXRlQWRkUmVtb3ZlIHRyZWF0cyAyNCBob3VycyBhcyBkaWZmZXJlbnQgZnJvbSBhXG4gICAgICAgIC8vIGRheSB3aGVuIHdvcmtpbmcgYXJvdW5kIERTVCwgd2UgbmVlZCB0byBzdG9yZSB0aGVtIHNlcGFyYXRlbHlcbiAgICAgICAgdGhpcy5fZGF5cyA9ICtkYXlzICtcbiAgICAgICAgICAgIHdlZWtzICogNztcbiAgICAgICAgLy8gSXQgaXMgaW1wb3NzaWJsZSB0byB0cmFuc2xhdGUgbW9udGhzIGludG8gZGF5cyB3aXRob3V0IGtub3dpbmdcbiAgICAgICAgLy8gd2hpY2ggbW9udGhzIHlvdSBhcmUgYXJlIHRhbGtpbmcgYWJvdXQsIHNvIHdlIGhhdmUgdG8gc3RvcmVcbiAgICAgICAgLy8gaXQgc2VwYXJhdGVseS5cbiAgICAgICAgdGhpcy5fbW9udGhzID0gK21vbnRocyArXG4gICAgICAgICAgICBxdWFydGVycyAqIDMgK1xuICAgICAgICAgICAgeWVhcnMgKiAxMjtcblxuICAgICAgICB0aGlzLl9kYXRhID0ge307XG5cbiAgICAgICAgdGhpcy5fbG9jYWxlID0gZ2V0TG9jYWxlKCk7XG5cbiAgICAgICAgdGhpcy5fYnViYmxlKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEdXJhdGlvbiAob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmogaW5zdGFuY2VvZiBEdXJhdGlvbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhYnNSb3VuZCAobnVtYmVyKSB7XG4gICAgICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCgtMSAqIG51bWJlcikgKiAtMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKG51bWJlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBmdW5jdGlvbiBvZmZzZXQgKHRva2VuLCBzZXBhcmF0b3IpIHtcbiAgICAgICAgYWRkRm9ybWF0VG9rZW4odG9rZW4sIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLnV0Y09mZnNldCgpO1xuICAgICAgICAgICAgdmFyIHNpZ24gPSAnKyc7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IC1vZmZzZXQ7XG4gICAgICAgICAgICAgICAgc2lnbiA9ICctJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzaWduICsgemVyb0ZpbGwofn4ob2Zmc2V0IC8gNjApLCAyKSArIHNlcGFyYXRvciArIHplcm9GaWxsKH5+KG9mZnNldCkgJSA2MCwgMik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9mZnNldCgnWicsICc6Jyk7XG4gICAgb2Zmc2V0KCdaWicsICcnKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1onLCAgbWF0Y2hTaG9ydE9mZnNldCk7XG4gICAgYWRkUmVnZXhUb2tlbignWlonLCBtYXRjaFNob3J0T2Zmc2V0KTtcbiAgICBhZGRQYXJzZVRva2VuKFsnWicsICdaWiddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgY29uZmlnLl91c2VVVEMgPSB0cnVlO1xuICAgICAgICBjb25maWcuX3R6bSA9IG9mZnNldEZyb21TdHJpbmcobWF0Y2hTaG9ydE9mZnNldCwgaW5wdXQpO1xuICAgIH0pO1xuXG4gICAgLy8gSEVMUEVSU1xuXG4gICAgLy8gdGltZXpvbmUgY2h1bmtlclxuICAgIC8vICcrMTA6MDAnID4gWycxMCcsICAnMDAnXVxuICAgIC8vICctMTUzMCcgID4gWyctMTUnLCAnMzAnXVxuICAgIHZhciBjaHVua09mZnNldCA9IC8oW1xcK1xcLV18XFxkXFxkKS9naTtcblxuICAgIGZ1bmN0aW9uIG9mZnNldEZyb21TdHJpbmcobWF0Y2hlciwgc3RyaW5nKSB7XG4gICAgICAgIHZhciBtYXRjaGVzID0gKHN0cmluZyB8fCAnJykubWF0Y2gobWF0Y2hlcik7XG5cbiAgICAgICAgaWYgKG1hdGNoZXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNodW5rICAgPSBtYXRjaGVzW21hdGNoZXMubGVuZ3RoIC0gMV0gfHwgW107XG4gICAgICAgIHZhciBwYXJ0cyAgID0gKGNodW5rICsgJycpLm1hdGNoKGNodW5rT2Zmc2V0KSB8fCBbJy0nLCAwLCAwXTtcbiAgICAgICAgdmFyIG1pbnV0ZXMgPSArKHBhcnRzWzFdICogNjApICsgdG9JbnQocGFydHNbMl0pO1xuXG4gICAgICAgIHJldHVybiBtaW51dGVzID09PSAwID9cbiAgICAgICAgICAwIDpcbiAgICAgICAgICBwYXJ0c1swXSA9PT0gJysnID8gbWludXRlcyA6IC1taW51dGVzO1xuICAgIH1cblxuICAgIC8vIFJldHVybiBhIG1vbWVudCBmcm9tIGlucHV0LCB0aGF0IGlzIGxvY2FsL3V0Yy96b25lIGVxdWl2YWxlbnQgdG8gbW9kZWwuXG4gICAgZnVuY3Rpb24gY2xvbmVXaXRoT2Zmc2V0KGlucHV0LCBtb2RlbCkge1xuICAgICAgICB2YXIgcmVzLCBkaWZmO1xuICAgICAgICBpZiAobW9kZWwuX2lzVVRDKSB7XG4gICAgICAgICAgICByZXMgPSBtb2RlbC5jbG9uZSgpO1xuICAgICAgICAgICAgZGlmZiA9IChpc01vbWVudChpbnB1dCkgfHwgaXNEYXRlKGlucHV0KSA/IGlucHV0LnZhbHVlT2YoKSA6IGNyZWF0ZUxvY2FsKGlucHV0KS52YWx1ZU9mKCkpIC0gcmVzLnZhbHVlT2YoKTtcbiAgICAgICAgICAgIC8vIFVzZSBsb3ctbGV2ZWwgYXBpLCBiZWNhdXNlIHRoaXMgZm4gaXMgbG93LWxldmVsIGFwaS5cbiAgICAgICAgICAgIHJlcy5fZC5zZXRUaW1lKHJlcy5fZC52YWx1ZU9mKCkgKyBkaWZmKTtcbiAgICAgICAgICAgIGhvb2tzLnVwZGF0ZU9mZnNldChyZXMsIGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwoaW5wdXQpLmxvY2FsKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXREYXRlT2Zmc2V0IChtKSB7XG4gICAgICAgIC8vIE9uIEZpcmVmb3guMjQgRGF0ZSNnZXRUaW1lem9uZU9mZnNldCByZXR1cm5zIGEgZmxvYXRpbmcgcG9pbnQuXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tb21lbnQvbW9tZW50L3B1bGwvMTg3MVxuICAgICAgICByZXR1cm4gLU1hdGgucm91bmQobS5fZC5nZXRUaW1lem9uZU9mZnNldCgpIC8gMTUpICogMTU7XG4gICAgfVxuXG4gICAgLy8gSE9PS1NcblxuICAgIC8vIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgd2hlbmV2ZXIgYSBtb21lbnQgaXMgbXV0YXRlZC5cbiAgICAvLyBJdCBpcyBpbnRlbmRlZCB0byBrZWVwIHRoZSBvZmZzZXQgaW4gc3luYyB3aXRoIHRoZSB0aW1lem9uZS5cbiAgICBob29rcy51cGRhdGVPZmZzZXQgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIC8vIGtlZXBMb2NhbFRpbWUgPSB0cnVlIG1lYW5zIG9ubHkgY2hhbmdlIHRoZSB0aW1lem9uZSwgd2l0aG91dFxuICAgIC8vIGFmZmVjdGluZyB0aGUgbG9jYWwgaG91ci4gU28gNTozMToyNiArMDMwMCAtLVt1dGNPZmZzZXQoMiwgdHJ1ZSldLS0+XG4gICAgLy8gNTozMToyNiArMDIwMCBJdCBpcyBwb3NzaWJsZSB0aGF0IDU6MzE6MjYgZG9lc24ndCBleGlzdCB3aXRoIG9mZnNldFxuICAgIC8vICswMjAwLCBzbyB3ZSBhZGp1c3QgdGhlIHRpbWUgYXMgbmVlZGVkLCB0byBiZSB2YWxpZC5cbiAgICAvL1xuICAgIC8vIEtlZXBpbmcgdGhlIHRpbWUgYWN0dWFsbHkgYWRkcy9zdWJ0cmFjdHMgKG9uZSBob3VyKVxuICAgIC8vIGZyb20gdGhlIGFjdHVhbCByZXByZXNlbnRlZCB0aW1lLiBUaGF0IGlzIHdoeSB3ZSBjYWxsIHVwZGF0ZU9mZnNldFxuICAgIC8vIGEgc2Vjb25kIHRpbWUuIEluIGNhc2UgaXQgd2FudHMgdXMgdG8gY2hhbmdlIHRoZSBvZmZzZXQgYWdhaW5cbiAgICAvLyBfY2hhbmdlSW5Qcm9ncmVzcyA9PSB0cnVlIGNhc2UsIHRoZW4gd2UgaGF2ZSB0byBhZGp1c3QsIGJlY2F1c2VcbiAgICAvLyB0aGVyZSBpcyBubyBzdWNoIHRpbWUgaW4gdGhlIGdpdmVuIHRpbWV6b25lLlxuICAgIGZ1bmN0aW9uIGdldFNldE9mZnNldCAoaW5wdXQsIGtlZXBMb2NhbFRpbWUsIGtlZXBNaW51dGVzKSB7XG4gICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLl9vZmZzZXQgfHwgMCxcbiAgICAgICAgICAgIGxvY2FsQWRqdXN0O1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgIT0gbnVsbCA/IHRoaXMgOiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSBvZmZzZXRGcm9tU3RyaW5nKG1hdGNoU2hvcnRPZmZzZXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChNYXRoLmFicyhpbnB1dCkgPCAxNiAmJiAha2VlcE1pbnV0ZXMpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IGlucHV0ICogNjA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuX2lzVVRDICYmIGtlZXBMb2NhbFRpbWUpIHtcbiAgICAgICAgICAgICAgICBsb2NhbEFkanVzdCA9IGdldERhdGVPZmZzZXQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9vZmZzZXQgPSBpbnB1dDtcbiAgICAgICAgICAgIHRoaXMuX2lzVVRDID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChsb2NhbEFkanVzdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGQobG9jYWxBZGp1c3QsICdtJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2Zmc2V0ICE9PSBpbnB1dCkge1xuICAgICAgICAgICAgICAgIGlmICgha2VlcExvY2FsVGltZSB8fCB0aGlzLl9jaGFuZ2VJblByb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZFN1YnRyYWN0KHRoaXMsIGNyZWF0ZUR1cmF0aW9uKGlucHV0IC0gb2Zmc2V0LCAnbScpLCAxLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5fY2hhbmdlSW5Qcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/IG9mZnNldCA6IGdldERhdGVPZmZzZXQodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRab25lIChpbnB1dCwga2VlcExvY2FsVGltZSkge1xuICAgICAgICBpZiAoaW5wdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IC1pbnB1dDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoaW5wdXQsIGtlZXBMb2NhbFRpbWUpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAtdGhpcy51dGNPZmZzZXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldE9mZnNldFRvVVRDIChrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnV0Y09mZnNldCgwLCBrZWVwTG9jYWxUaW1lKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRPZmZzZXRUb0xvY2FsIChrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9pc1VUQykge1xuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoMCwga2VlcExvY2FsVGltZSk7XG4gICAgICAgICAgICB0aGlzLl9pc1VUQyA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoa2VlcExvY2FsVGltZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3VidHJhY3QoZ2V0RGF0ZU9mZnNldCh0aGlzKSwgJ20nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRPZmZzZXRUb1BhcnNlZE9mZnNldCAoKSB7XG4gICAgICAgIGlmICh0aGlzLl90em0gIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQodGhpcy5fdHptLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuX2kgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB2YXIgdFpvbmUgPSBvZmZzZXRGcm9tU3RyaW5nKG1hdGNoT2Zmc2V0LCB0aGlzLl9pKTtcbiAgICAgICAgICAgIGlmICh0Wm9uZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQodFpvbmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoMCwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzQWxpZ25lZEhvdXJPZmZzZXQgKGlucHV0KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dCA9IGlucHV0ID8gY3JlYXRlTG9jYWwoaW5wdXQpLnV0Y09mZnNldCgpIDogMDtcblxuICAgICAgICByZXR1cm4gKHRoaXMudXRjT2Zmc2V0KCkgLSBpbnB1dCkgJSA2MCA9PT0gMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0RheWxpZ2h0U2F2aW5nVGltZSAoKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLnV0Y09mZnNldCgpID4gdGhpcy5jbG9uZSgpLm1vbnRoKDApLnV0Y09mZnNldCgpIHx8XG4gICAgICAgICAgICB0aGlzLnV0Y09mZnNldCgpID4gdGhpcy5jbG9uZSgpLm1vbnRoKDUpLnV0Y09mZnNldCgpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEYXlsaWdodFNhdmluZ1RpbWVTaGlmdGVkICgpIHtcbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9pc0RTVFNoaWZ0ZWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faXNEU1RTaGlmdGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGMgPSB7fTtcblxuICAgICAgICBjb3B5Q29uZmlnKGMsIHRoaXMpO1xuICAgICAgICBjID0gcHJlcGFyZUNvbmZpZyhjKTtcblxuICAgICAgICBpZiAoYy5fYSkge1xuICAgICAgICAgICAgdmFyIG90aGVyID0gYy5faXNVVEMgPyBjcmVhdGVVVEMoYy5fYSkgOiBjcmVhdGVMb2NhbChjLl9hKTtcbiAgICAgICAgICAgIHRoaXMuX2lzRFNUU2hpZnRlZCA9IHRoaXMuaXNWYWxpZCgpICYmXG4gICAgICAgICAgICAgICAgY29tcGFyZUFycmF5cyhjLl9hLCBvdGhlci50b0FycmF5KCkpID4gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2lzRFNUU2hpZnRlZCA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzRFNUU2hpZnRlZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0xvY2FsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gIXRoaXMuX2lzVVRDIDogZmFsc2U7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNVdGNPZmZzZXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1ZhbGlkKCkgPyB0aGlzLl9pc1VUQyA6IGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVXRjICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpcy5faXNVVEMgJiYgdGhpcy5fb2Zmc2V0ID09PSAwIDogZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQVNQLk5FVCBqc29uIGRhdGUgZm9ybWF0IHJlZ2V4XG4gICAgdmFyIGFzcE5ldFJlZ2V4ID0gL14oXFwtfFxcKyk/KD86KFxcZCopWy4gXSk/KFxcZCspXFw6KFxcZCspKD86XFw6KFxcZCspKFxcLlxcZCopPyk/JC87XG5cbiAgICAvLyBmcm9tIGh0dHA6Ly9kb2NzLmNsb3N1cmUtbGlicmFyeS5nb29nbGVjb2RlLmNvbS9naXQvY2xvc3VyZV9nb29nX2RhdGVfZGF0ZS5qcy5zb3VyY2UuaHRtbFxuICAgIC8vIHNvbWV3aGF0IG1vcmUgaW4gbGluZSB3aXRoIDQuNC4zLjIgMjAwNCBzcGVjLCBidXQgYWxsb3dzIGRlY2ltYWwgYW55d2hlcmVcbiAgICAvLyBhbmQgZnVydGhlciBtb2RpZmllZCB0byBhbGxvdyBmb3Igc3RyaW5ncyBjb250YWluaW5nIGJvdGggd2VlayBhbmQgZGF5XG4gICAgdmFyIGlzb1JlZ2V4ID0gL14oLXxcXCspP1AoPzooWy0rXT9bMC05LC5dKilZKT8oPzooWy0rXT9bMC05LC5dKilNKT8oPzooWy0rXT9bMC05LC5dKilXKT8oPzooWy0rXT9bMC05LC5dKilEKT8oPzpUKD86KFstK10/WzAtOSwuXSopSCk/KD86KFstK10/WzAtOSwuXSopTSk/KD86KFstK10/WzAtOSwuXSopUyk/KT8kLztcblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUR1cmF0aW9uIChpbnB1dCwga2V5KSB7XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IGlucHV0LFxuICAgICAgICAgICAgLy8gbWF0Y2hpbmcgYWdhaW5zdCByZWdleHAgaXMgZXhwZW5zaXZlLCBkbyBpdCBvbiBkZW1hbmRcbiAgICAgICAgICAgIG1hdGNoID0gbnVsbCxcbiAgICAgICAgICAgIHNpZ24sXG4gICAgICAgICAgICByZXQsXG4gICAgICAgICAgICBkaWZmUmVzO1xuXG4gICAgICAgIGlmIChpc0R1cmF0aW9uKGlucHV0KSkge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgbXMgOiBpbnB1dC5fbWlsbGlzZWNvbmRzLFxuICAgICAgICAgICAgICAgIGQgIDogaW5wdXQuX2RheXMsXG4gICAgICAgICAgICAgICAgTSAgOiBpbnB1dC5fbW9udGhzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKGlucHV0KSkge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbltrZXldID0gaW5wdXQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uLm1pbGxpc2Vjb25kcyA9IGlucHV0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEhKG1hdGNoID0gYXNwTmV0UmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeSAgOiAwLFxuICAgICAgICAgICAgICAgIGQgIDogdG9JbnQobWF0Y2hbREFURV0pICAgICAgICAgICAgICAgICAgICAgICAgICogc2lnbixcbiAgICAgICAgICAgICAgICBoICA6IHRvSW50KG1hdGNoW0hPVVJdKSAgICAgICAgICAgICAgICAgICAgICAgICAqIHNpZ24sXG4gICAgICAgICAgICAgICAgbSAgOiB0b0ludChtYXRjaFtNSU5VVEVdKSAgICAgICAgICAgICAgICAgICAgICAgKiBzaWduLFxuICAgICAgICAgICAgICAgIHMgIDogdG9JbnQobWF0Y2hbU0VDT05EXSkgICAgICAgICAgICAgICAgICAgICAgICogc2lnbixcbiAgICAgICAgICAgICAgICBtcyA6IHRvSW50KGFic1JvdW5kKG1hdGNoW01JTExJU0VDT05EXSAqIDEwMDApKSAqIHNpZ24gLy8gdGhlIG1pbGxpc2Vjb25kIGRlY2ltYWwgcG9pbnQgaXMgaW5jbHVkZWQgaW4gdGhlIG1hdGNoXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKCEhKG1hdGNoID0gaXNvUmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeSA6IHBhcnNlSXNvKG1hdGNoWzJdLCBzaWduKSxcbiAgICAgICAgICAgICAgICBNIDogcGFyc2VJc28obWF0Y2hbM10sIHNpZ24pLFxuICAgICAgICAgICAgICAgIHcgOiBwYXJzZUlzbyhtYXRjaFs0XSwgc2lnbiksXG4gICAgICAgICAgICAgICAgZCA6IHBhcnNlSXNvKG1hdGNoWzVdLCBzaWduKSxcbiAgICAgICAgICAgICAgICBoIDogcGFyc2VJc28obWF0Y2hbNl0sIHNpZ24pLFxuICAgICAgICAgICAgICAgIG0gOiBwYXJzZUlzbyhtYXRjaFs3XSwgc2lnbiksXG4gICAgICAgICAgICAgICAgcyA6IHBhcnNlSXNvKG1hdGNoWzhdLCBzaWduKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmIChkdXJhdGlvbiA9PSBudWxsKSB7Ly8gY2hlY2tzIGZvciBudWxsIG9yIHVuZGVmaW5lZFxuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZHVyYXRpb24gPT09ICdvYmplY3QnICYmICgnZnJvbScgaW4gZHVyYXRpb24gfHwgJ3RvJyBpbiBkdXJhdGlvbikpIHtcbiAgICAgICAgICAgIGRpZmZSZXMgPSBtb21lbnRzRGlmZmVyZW5jZShjcmVhdGVMb2NhbChkdXJhdGlvbi5mcm9tKSwgY3JlYXRlTG9jYWwoZHVyYXRpb24udG8pKTtcblxuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGR1cmF0aW9uLm1zID0gZGlmZlJlcy5taWxsaXNlY29uZHM7XG4gICAgICAgICAgICBkdXJhdGlvbi5NID0gZGlmZlJlcy5tb250aHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXQgPSBuZXcgRHVyYXRpb24oZHVyYXRpb24pO1xuXG4gICAgICAgIGlmIChpc0R1cmF0aW9uKGlucHV0KSAmJiBoYXNPd25Qcm9wKGlucHV0LCAnX2xvY2FsZScpKSB7XG4gICAgICAgICAgICByZXQuX2xvY2FsZSA9IGlucHV0Ll9sb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIGNyZWF0ZUR1cmF0aW9uLmZuID0gRHVyYXRpb24ucHJvdG90eXBlO1xuICAgIGNyZWF0ZUR1cmF0aW9uLmludmFsaWQgPSBjcmVhdGVJbnZhbGlkJDE7XG5cbiAgICBmdW5jdGlvbiBwYXJzZUlzbyAoaW5wLCBzaWduKSB7XG4gICAgICAgIC8vIFdlJ2Qgbm9ybWFsbHkgdXNlIH5+aW5wIGZvciB0aGlzLCBidXQgdW5mb3J0dW5hdGVseSBpdCBhbHNvXG4gICAgICAgIC8vIGNvbnZlcnRzIGZsb2F0cyB0byBpbnRzLlxuICAgICAgICAvLyBpbnAgbWF5IGJlIHVuZGVmaW5lZCwgc28gY2FyZWZ1bCBjYWxsaW5nIHJlcGxhY2Ugb24gaXQuXG4gICAgICAgIHZhciByZXMgPSBpbnAgJiYgcGFyc2VGbG9hdChpbnAucmVwbGFjZSgnLCcsICcuJykpO1xuICAgICAgICAvLyBhcHBseSBzaWduIHdoaWxlIHdlJ3JlIGF0IGl0XG4gICAgICAgIHJldHVybiAoaXNOYU4ocmVzKSA/IDAgOiByZXMpICogc2lnbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKSB7XG4gICAgICAgIHZhciByZXMgPSB7fTtcblxuICAgICAgICByZXMubW9udGhzID0gb3RoZXIubW9udGgoKSAtIGJhc2UubW9udGgoKSArXG4gICAgICAgICAgICAob3RoZXIueWVhcigpIC0gYmFzZS55ZWFyKCkpICogMTI7XG4gICAgICAgIGlmIChiYXNlLmNsb25lKCkuYWRkKHJlcy5tb250aHMsICdNJykuaXNBZnRlcihvdGhlcikpIHtcbiAgICAgICAgICAgIC0tcmVzLm1vbnRocztcbiAgICAgICAgfVxuXG4gICAgICAgIHJlcy5taWxsaXNlY29uZHMgPSArb3RoZXIgLSArKGJhc2UuY2xvbmUoKS5hZGQocmVzLm1vbnRocywgJ00nKSk7XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb21lbnRzRGlmZmVyZW5jZShiYXNlLCBvdGhlcikge1xuICAgICAgICB2YXIgcmVzO1xuICAgICAgICBpZiAoIShiYXNlLmlzVmFsaWQoKSAmJiBvdGhlci5pc1ZhbGlkKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4ge21pbGxpc2Vjb25kczogMCwgbW9udGhzOiAwfTtcbiAgICAgICAgfVxuXG4gICAgICAgIG90aGVyID0gY2xvbmVXaXRoT2Zmc2V0KG90aGVyLCBiYXNlKTtcbiAgICAgICAgaWYgKGJhc2UuaXNCZWZvcmUob3RoZXIpKSB7XG4gICAgICAgICAgICByZXMgPSBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcyA9IHBvc2l0aXZlTW9tZW50c0RpZmZlcmVuY2Uob3RoZXIsIGJhc2UpO1xuICAgICAgICAgICAgcmVzLm1pbGxpc2Vjb25kcyA9IC1yZXMubWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgcmVzLm1vbnRocyA9IC1yZXMubW9udGhzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvLyBUT0RPOiByZW1vdmUgJ25hbWUnIGFyZyBhZnRlciBkZXByZWNhdGlvbiBpcyByZW1vdmVkXG4gICAgZnVuY3Rpb24gY3JlYXRlQWRkZXIoZGlyZWN0aW9uLCBuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsLCBwZXJpb2QpIHtcbiAgICAgICAgICAgIHZhciBkdXIsIHRtcDtcbiAgICAgICAgICAgIC8vaW52ZXJ0IHRoZSBhcmd1bWVudHMsIGJ1dCBjb21wbGFpbiBhYm91dCBpdFxuICAgICAgICAgICAgaWYgKHBlcmlvZCAhPT0gbnVsbCAmJiAhaXNOYU4oK3BlcmlvZCkpIHtcbiAgICAgICAgICAgICAgICBkZXByZWNhdGVTaW1wbGUobmFtZSwgJ21vbWVudCgpLicgKyBuYW1lICArICcocGVyaW9kLCBudW1iZXIpIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgbW9tZW50KCkuJyArIG5hbWUgKyAnKG51bWJlciwgcGVyaW9kKS4gJyArXG4gICAgICAgICAgICAgICAgJ1NlZSBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2FkZC1pbnZlcnRlZC1wYXJhbS8gZm9yIG1vcmUgaW5mby4nKTtcbiAgICAgICAgICAgICAgICB0bXAgPSB2YWw7IHZhbCA9IHBlcmlvZDsgcGVyaW9kID0gdG1wO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YWwgPSB0eXBlb2YgdmFsID09PSAnc3RyaW5nJyA/ICt2YWwgOiB2YWw7XG4gICAgICAgICAgICBkdXIgPSBjcmVhdGVEdXJhdGlvbih2YWwsIHBlcmlvZCk7XG4gICAgICAgICAgICBhZGRTdWJ0cmFjdCh0aGlzLCBkdXIsIGRpcmVjdGlvbik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRTdWJ0cmFjdCAobW9tLCBkdXJhdGlvbiwgaXNBZGRpbmcsIHVwZGF0ZU9mZnNldCkge1xuICAgICAgICB2YXIgbWlsbGlzZWNvbmRzID0gZHVyYXRpb24uX21pbGxpc2Vjb25kcyxcbiAgICAgICAgICAgIGRheXMgPSBhYnNSb3VuZChkdXJhdGlvbi5fZGF5cyksXG4gICAgICAgICAgICBtb250aHMgPSBhYnNSb3VuZChkdXJhdGlvbi5fbW9udGhzKTtcblxuICAgICAgICBpZiAoIW1vbS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIC8vIE5vIG9wXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB1cGRhdGVPZmZzZXQgPSB1cGRhdGVPZmZzZXQgPT0gbnVsbCA/IHRydWUgOiB1cGRhdGVPZmZzZXQ7XG5cbiAgICAgICAgaWYgKG1vbnRocykge1xuICAgICAgICAgICAgc2V0TW9udGgobW9tLCBnZXQobW9tLCAnTW9udGgnKSArIG1vbnRocyAqIGlzQWRkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF5cykge1xuICAgICAgICAgICAgc2V0JDEobW9tLCAnRGF0ZScsIGdldChtb20sICdEYXRlJykgKyBkYXlzICogaXNBZGRpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtaWxsaXNlY29uZHMpIHtcbiAgICAgICAgICAgIG1vbS5fZC5zZXRUaW1lKG1vbS5fZC52YWx1ZU9mKCkgKyBtaWxsaXNlY29uZHMgKiBpc0FkZGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVwZGF0ZU9mZnNldCkge1xuICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KG1vbSwgZGF5cyB8fCBtb250aHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGFkZCAgICAgID0gY3JlYXRlQWRkZXIoMSwgJ2FkZCcpO1xuICAgIHZhciBzdWJ0cmFjdCA9IGNyZWF0ZUFkZGVyKC0xLCAnc3VidHJhY3QnKTtcblxuICAgIGZ1bmN0aW9uIGdldENhbGVuZGFyRm9ybWF0KG15TW9tZW50LCBub3cpIHtcbiAgICAgICAgdmFyIGRpZmYgPSBteU1vbWVudC5kaWZmKG5vdywgJ2RheXMnLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIGRpZmYgPCAtNiA/ICdzYW1lRWxzZScgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCAtMSA/ICdsYXN0V2VlaycgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCAwID8gJ2xhc3REYXknIDpcbiAgICAgICAgICAgICAgICBkaWZmIDwgMSA/ICdzYW1lRGF5JyA6XG4gICAgICAgICAgICAgICAgZGlmZiA8IDIgPyAnbmV4dERheScgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCA3ID8gJ25leHRXZWVrJyA6ICdzYW1lRWxzZSc7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsZW5kYXIkMSAodGltZSwgZm9ybWF0cykge1xuICAgICAgICAvLyBXZSB3YW50IHRvIGNvbXBhcmUgdGhlIHN0YXJ0IG9mIHRvZGF5LCB2cyB0aGlzLlxuICAgICAgICAvLyBHZXR0aW5nIHN0YXJ0LW9mLXRvZGF5IGRlcGVuZHMgb24gd2hldGhlciB3ZSdyZSBsb2NhbC91dGMvb2Zmc2V0IG9yIG5vdC5cbiAgICAgICAgdmFyIG5vdyA9IHRpbWUgfHwgY3JlYXRlTG9jYWwoKSxcbiAgICAgICAgICAgIHNvZCA9IGNsb25lV2l0aE9mZnNldChub3csIHRoaXMpLnN0YXJ0T2YoJ2RheScpLFxuICAgICAgICAgICAgZm9ybWF0ID0gaG9va3MuY2FsZW5kYXJGb3JtYXQodGhpcywgc29kKSB8fCAnc2FtZUVsc2UnO1xuXG4gICAgICAgIHZhciBvdXRwdXQgPSBmb3JtYXRzICYmIChpc0Z1bmN0aW9uKGZvcm1hdHNbZm9ybWF0XSkgPyBmb3JtYXRzW2Zvcm1hdF0uY2FsbCh0aGlzLCBub3cpIDogZm9ybWF0c1tmb3JtYXRdKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXQob3V0cHV0IHx8IHRoaXMubG9jYWxlRGF0YSgpLmNhbGVuZGFyKGZvcm1hdCwgdGhpcywgY3JlYXRlTG9jYWwobm93KSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsb25lICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBNb21lbnQodGhpcyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBZnRlciAoaW5wdXQsIHVuaXRzKSB7XG4gICAgICAgIHZhciBsb2NhbElucHV0ID0gaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBjcmVhdGVMb2NhbChpbnB1dCk7XG4gICAgICAgIGlmICghKHRoaXMuaXNWYWxpZCgpICYmIGxvY2FsSW5wdXQuaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpIHx8ICdtaWxsaXNlY29uZCc7XG4gICAgICAgIGlmICh1bml0cyA9PT0gJ21pbGxpc2Vjb25kJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpID4gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbG9jYWxJbnB1dC52YWx1ZU9mKCkgPCB0aGlzLmNsb25lKCkuc3RhcnRPZih1bml0cykudmFsdWVPZigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNCZWZvcmUgKGlucHV0LCB1bml0cykge1xuICAgICAgICB2YXIgbG9jYWxJbnB1dCA9IGlzTW9tZW50KGlucHV0KSA/IGlucHV0IDogY3JlYXRlTG9jYWwoaW5wdXQpO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbElucHV0LmlzVmFsaWQoKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB8fCAnbWlsbGlzZWNvbmQnO1xuICAgICAgICBpZiAodW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKSA8IGxvY2FsSW5wdXQudmFsdWVPZigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmRPZih1bml0cykudmFsdWVPZigpIDwgbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0JldHdlZW4gKGZyb20sIHRvLCB1bml0cywgaW5jbHVzaXZpdHkpIHtcbiAgICAgICAgdmFyIGxvY2FsRnJvbSA9IGlzTW9tZW50KGZyb20pID8gZnJvbSA6IGNyZWF0ZUxvY2FsKGZyb20pLFxuICAgICAgICAgICAgbG9jYWxUbyA9IGlzTW9tZW50KHRvKSA/IHRvIDogY3JlYXRlTG9jYWwodG8pO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbEZyb20uaXNWYWxpZCgpICYmIGxvY2FsVG8uaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGluY2x1c2l2aXR5ID0gaW5jbHVzaXZpdHkgfHwgJygpJztcbiAgICAgICAgcmV0dXJuIChpbmNsdXNpdml0eVswXSA9PT0gJygnID8gdGhpcy5pc0FmdGVyKGxvY2FsRnJvbSwgdW5pdHMpIDogIXRoaXMuaXNCZWZvcmUobG9jYWxGcm9tLCB1bml0cykpICYmXG4gICAgICAgICAgICAoaW5jbHVzaXZpdHlbMV0gPT09ICcpJyA/IHRoaXMuaXNCZWZvcmUobG9jYWxUbywgdW5pdHMpIDogIXRoaXMuaXNBZnRlcihsb2NhbFRvLCB1bml0cykpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzU2FtZSAoaW5wdXQsIHVuaXRzKSB7XG4gICAgICAgIHZhciBsb2NhbElucHV0ID0gaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBjcmVhdGVMb2NhbChpbnB1dCksXG4gICAgICAgICAgICBpbnB1dE1zO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbElucHV0LmlzVmFsaWQoKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB8fCAnbWlsbGlzZWNvbmQnO1xuICAgICAgICBpZiAodW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKSA9PT0gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbnB1dE1zID0gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jbG9uZSgpLnN0YXJ0T2YodW5pdHMpLnZhbHVlT2YoKSA8PSBpbnB1dE1zICYmIGlucHV0TXMgPD0gdGhpcy5jbG9uZSgpLmVuZE9mKHVuaXRzKS52YWx1ZU9mKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1NhbWVPckFmdGVyIChpbnB1dCwgdW5pdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNTYW1lKGlucHV0LCB1bml0cykgfHwgdGhpcy5pc0FmdGVyKGlucHV0LCB1bml0cyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNTYW1lT3JCZWZvcmUgKGlucHV0LCB1bml0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1NhbWUoaW5wdXQsIHVuaXRzKSB8fCB0aGlzLmlzQmVmb3JlKGlucHV0LCB1bml0cyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGlmZiAoaW5wdXQsIHVuaXRzLCBhc0Zsb2F0KSB7XG4gICAgICAgIHZhciB0aGF0LFxuICAgICAgICAgICAgem9uZURlbHRhLFxuICAgICAgICAgICAgb3V0cHV0O1xuXG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgIH1cblxuICAgICAgICB0aGF0ID0gY2xvbmVXaXRoT2Zmc2V0KGlucHV0LCB0aGlzKTtcblxuICAgICAgICBpZiAoIXRoYXQuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG5cbiAgICAgICAgem9uZURlbHRhID0gKHRoYXQudXRjT2Zmc2V0KCkgLSB0aGlzLnV0Y09mZnNldCgpKSAqIDZlNDtcblxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzogb3V0cHV0ID0gbW9udGhEaWZmKHRoaXMsIHRoYXQpIC8gMTI7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOiBvdXRwdXQgPSBtb250aERpZmYodGhpcywgdGhhdCk7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6IG91dHB1dCA9IG1vbnRoRGlmZih0aGlzLCB0aGF0KSAvIDM7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzogb3V0cHV0ID0gKHRoaXMgLSB0aGF0KSAvIDFlMzsgYnJlYWs7IC8vIDEwMDBcbiAgICAgICAgICAgIGNhc2UgJ21pbnV0ZSc6IG91dHB1dCA9ICh0aGlzIC0gdGhhdCkgLyA2ZTQ7IGJyZWFrOyAvLyAxMDAwICogNjBcbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOiBvdXRwdXQgPSAodGhpcyAtIHRoYXQpIC8gMzZlNTsgYnJlYWs7IC8vIDEwMDAgKiA2MCAqIDYwXG4gICAgICAgICAgICBjYXNlICdkYXknOiBvdXRwdXQgPSAodGhpcyAtIHRoYXQgLSB6b25lRGVsdGEpIC8gODY0ZTU7IGJyZWFrOyAvLyAxMDAwICogNjAgKiA2MCAqIDI0LCBuZWdhdGUgZHN0XG4gICAgICAgICAgICBjYXNlICd3ZWVrJzogb3V0cHV0ID0gKHRoaXMgLSB0aGF0IC0gem9uZURlbHRhKSAvIDYwNDhlNTsgYnJlYWs7IC8vIDEwMDAgKiA2MCAqIDYwICogMjQgKiA3LCBuZWdhdGUgZHN0XG4gICAgICAgICAgICBkZWZhdWx0OiBvdXRwdXQgPSB0aGlzIC0gdGhhdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhc0Zsb2F0ID8gb3V0cHV0IDogYWJzRmxvb3Iob3V0cHV0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb250aERpZmYgKGEsIGIpIHtcbiAgICAgICAgLy8gZGlmZmVyZW5jZSBpbiBtb250aHNcbiAgICAgICAgdmFyIHdob2xlTW9udGhEaWZmID0gKChiLnllYXIoKSAtIGEueWVhcigpKSAqIDEyKSArIChiLm1vbnRoKCkgLSBhLm1vbnRoKCkpLFxuICAgICAgICAgICAgLy8gYiBpcyBpbiAoYW5jaG9yIC0gMSBtb250aCwgYW5jaG9yICsgMSBtb250aClcbiAgICAgICAgICAgIGFuY2hvciA9IGEuY2xvbmUoKS5hZGQod2hvbGVNb250aERpZmYsICdtb250aHMnKSxcbiAgICAgICAgICAgIGFuY2hvcjIsIGFkanVzdDtcblxuICAgICAgICBpZiAoYiAtIGFuY2hvciA8IDApIHtcbiAgICAgICAgICAgIGFuY2hvcjIgPSBhLmNsb25lKCkuYWRkKHdob2xlTW9udGhEaWZmIC0gMSwgJ21vbnRocycpO1xuICAgICAgICAgICAgLy8gbGluZWFyIGFjcm9zcyB0aGUgbW9udGhcbiAgICAgICAgICAgIGFkanVzdCA9IChiIC0gYW5jaG9yKSAvIChhbmNob3IgLSBhbmNob3IyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFuY2hvcjIgPSBhLmNsb25lKCkuYWRkKHdob2xlTW9udGhEaWZmICsgMSwgJ21vbnRocycpO1xuICAgICAgICAgICAgLy8gbGluZWFyIGFjcm9zcyB0aGUgbW9udGhcbiAgICAgICAgICAgIGFkanVzdCA9IChiIC0gYW5jaG9yKSAvIChhbmNob3IyIC0gYW5jaG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vY2hlY2sgZm9yIG5lZ2F0aXZlIHplcm8sIHJldHVybiB6ZXJvIGlmIG5lZ2F0aXZlIHplcm9cbiAgICAgICAgcmV0dXJuIC0od2hvbGVNb250aERpZmYgKyBhZGp1c3QpIHx8IDA7XG4gICAgfVxuXG4gICAgaG9va3MuZGVmYXVsdEZvcm1hdCA9ICdZWVlZLU1NLUREVEhIOm1tOnNzWic7XG4gICAgaG9va3MuZGVmYXVsdEZvcm1hdFV0YyA9ICdZWVlZLU1NLUREVEhIOm1tOnNzW1pdJztcblxuICAgIGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5sb2NhbGUoJ2VuJykuZm9ybWF0KCdkZGQgTU1NIEREIFlZWVkgSEg6bW06c3MgW0dNVF1aWicpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvSVNPU3RyaW5nKGtlZXBPZmZzZXQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHV0YyA9IGtlZXBPZmZzZXQgIT09IHRydWU7XG4gICAgICAgIHZhciBtID0gdXRjID8gdGhpcy5jbG9uZSgpLnV0YygpIDogdGhpcztcbiAgICAgICAgaWYgKG0ueWVhcigpIDwgMCB8fCBtLnllYXIoKSA+IDk5OTkpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXRNb21lbnQobSwgdXRjID8gJ1lZWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1taXScgOiAnWVlZWVlZLU1NLUREW1RdSEg6bW06c3MuU1NTWicpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nKSkge1xuICAgICAgICAgICAgLy8gbmF0aXZlIGltcGxlbWVudGF0aW9uIGlzIH41MHggZmFzdGVyLCB1c2UgaXQgd2hlbiB3ZSBjYW5cbiAgICAgICAgICAgIGlmICh1dGMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0RhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkgKyB0aGlzLnV0Y09mZnNldCgpICogNjAgKiAxMDAwKS50b0lTT1N0cmluZygpLnJlcGxhY2UoJ1onLCBmb3JtYXRNb21lbnQobSwgJ1onKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdE1vbWVudChtLCB1dGMgPyAnWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1taXScgOiAnWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1onKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gYSBodW1hbiByZWFkYWJsZSByZXByZXNlbnRhdGlvbiBvZiBhIG1vbWVudCB0aGF0IGNhblxuICAgICAqIGFsc28gYmUgZXZhbHVhdGVkIHRvIGdldCBhIG5ldyBtb21lbnQgd2hpY2ggaXMgdGhlIHNhbWVcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHBzOi8vbm9kZWpzLm9yZy9kaXN0L2xhdGVzdC9kb2NzL2FwaS91dGlsLmh0bWwjdXRpbF9jdXN0b21faW5zcGVjdF9mdW5jdGlvbl9vbl9vYmplY3RzXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiAnbW9tZW50LmludmFsaWQoLyogJyArIHRoaXMuX2kgKyAnICovKSc7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZ1bmMgPSAnbW9tZW50JztcbiAgICAgICAgdmFyIHpvbmUgPSAnJztcbiAgICAgICAgaWYgKCF0aGlzLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgZnVuYyA9IHRoaXMudXRjT2Zmc2V0KCkgPT09IDAgPyAnbW9tZW50LnV0YycgOiAnbW9tZW50LnBhcnNlWm9uZSc7XG4gICAgICAgICAgICB6b25lID0gJ1onO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcmVmaXggPSAnWycgKyBmdW5jICsgJyhcIl0nO1xuICAgICAgICB2YXIgeWVhciA9ICgwIDw9IHRoaXMueWVhcigpICYmIHRoaXMueWVhcigpIDw9IDk5OTkpID8gJ1lZWVknIDogJ1lZWVlZWSc7XG4gICAgICAgIHZhciBkYXRldGltZSA9ICctTU0tRERbVF1ISDptbTpzcy5TU1MnO1xuICAgICAgICB2YXIgc3VmZml4ID0gem9uZSArICdbXCIpXSc7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0KHByZWZpeCArIHllYXIgKyBkYXRldGltZSArIHN1ZmZpeCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0IChpbnB1dFN0cmluZykge1xuICAgICAgICBpZiAoIWlucHV0U3RyaW5nKSB7XG4gICAgICAgICAgICBpbnB1dFN0cmluZyA9IHRoaXMuaXNVdGMoKSA/IGhvb2tzLmRlZmF1bHRGb3JtYXRVdGMgOiBob29rcy5kZWZhdWx0Rm9ybWF0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBvdXRwdXQgPSBmb3JtYXRNb21lbnQodGhpcywgaW5wdXRTdHJpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkucG9zdGZvcm1hdChvdXRwdXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZyb20gKHRpbWUsIHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNWYWxpZCgpICYmXG4gICAgICAgICAgICAgICAgKChpc01vbWVudCh0aW1lKSAmJiB0aW1lLmlzVmFsaWQoKSkgfHxcbiAgICAgICAgICAgICAgICAgY3JlYXRlTG9jYWwodGltZSkuaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKHt0bzogdGhpcywgZnJvbTogdGltZX0pLmxvY2FsZSh0aGlzLmxvY2FsZSgpKS5odW1hbml6ZSghd2l0aG91dFN1ZmZpeCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkuaW52YWxpZERhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZyb21Ob3cgKHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbShjcmVhdGVMb2NhbCgpLCB3aXRob3V0U3VmZml4KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0byAodGltZSwgd2l0aG91dFN1ZmZpeCkge1xuICAgICAgICBpZiAodGhpcy5pc1ZhbGlkKCkgJiZcbiAgICAgICAgICAgICAgICAoKGlzTW9tZW50KHRpbWUpICYmIHRpbWUuaXNWYWxpZCgpKSB8fFxuICAgICAgICAgICAgICAgICBjcmVhdGVMb2NhbCh0aW1lKS5pc1ZhbGlkKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlRHVyYXRpb24oe2Zyb206IHRoaXMsIHRvOiB0aW1lfSkubG9jYWxlKHRoaXMubG9jYWxlKCkpLmh1bWFuaXplKCF3aXRob3V0U3VmZml4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS5pbnZhbGlkRGF0ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9Ob3cgKHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG8oY3JlYXRlTG9jYWwoKSwgd2l0aG91dFN1ZmZpeCk7XG4gICAgfVxuXG4gICAgLy8gSWYgcGFzc2VkIGEgbG9jYWxlIGtleSwgaXQgd2lsbCBzZXQgdGhlIGxvY2FsZSBmb3IgdGhpc1xuICAgIC8vIGluc3RhbmNlLiAgT3RoZXJ3aXNlLCBpdCB3aWxsIHJldHVybiB0aGUgbG9jYWxlIGNvbmZpZ3VyYXRpb25cbiAgICAvLyB2YXJpYWJsZXMgZm9yIHRoaXMgaW5zdGFuY2UuXG4gICAgZnVuY3Rpb24gbG9jYWxlIChrZXkpIHtcbiAgICAgICAgdmFyIG5ld0xvY2FsZURhdGE7XG5cbiAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlLl9hYmJyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3TG9jYWxlRGF0YSA9IGdldExvY2FsZShrZXkpO1xuICAgICAgICAgICAgaWYgKG5ld0xvY2FsZURhdGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvY2FsZSA9IG5ld0xvY2FsZURhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBsYW5nID0gZGVwcmVjYXRlKFxuICAgICAgICAnbW9tZW50KCkubGFuZygpIGlzIGRlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZSBtb21lbnQoKS5sb2NhbGVEYXRhKCkgdG8gZ2V0IHRoZSBsYW5ndWFnZSBjb25maWd1cmF0aW9uLiBVc2UgbW9tZW50KCkubG9jYWxlKCkgdG8gY2hhbmdlIGxhbmd1YWdlcy4nLFxuICAgICAgICBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZShrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIGZ1bmN0aW9uIGxvY2FsZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlO1xuICAgIH1cblxuICAgIHZhciBNU19QRVJfU0VDT05EID0gMTAwMDtcbiAgICB2YXIgTVNfUEVSX01JTlVURSA9IDYwICogTVNfUEVSX1NFQ09ORDtcbiAgICB2YXIgTVNfUEVSX0hPVVIgPSA2MCAqIE1TX1BFUl9NSU5VVEU7XG4gICAgdmFyIE1TX1BFUl80MDBfWUVBUlMgPSAoMzY1ICogNDAwICsgOTcpICogMjQgKiBNU19QRVJfSE9VUjtcblxuICAgIC8vIGFjdHVhbCBtb2R1bG8gLSBoYW5kbGVzIG5lZ2F0aXZlIG51bWJlcnMgKGZvciBkYXRlcyBiZWZvcmUgMTk3MCk6XG4gICAgZnVuY3Rpb24gbW9kJDEoZGl2aWRlbmQsIGRpdmlzb3IpIHtcbiAgICAgICAgcmV0dXJuIChkaXZpZGVuZCAlIGRpdmlzb3IgKyBkaXZpc29yKSAlIGRpdmlzb3I7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9jYWxTdGFydE9mRGF0ZSh5LCBtLCBkKSB7XG4gICAgICAgIC8vIHRoZSBkYXRlIGNvbnN0cnVjdG9yIHJlbWFwcyB5ZWFycyAwLTk5IHRvIDE5MDAtMTk5OVxuICAgICAgICBpZiAoeSA8IDEwMCAmJiB5ID49IDApIHtcbiAgICAgICAgICAgIC8vIHByZXNlcnZlIGxlYXAgeWVhcnMgdXNpbmcgYSBmdWxsIDQwMCB5ZWFyIGN5Y2xlLCB0aGVuIHJlc2V0XG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoeSArIDQwMCwgbSwgZCkgLSBNU19QRVJfNDAwX1lFQVJTO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHksIG0sIGQpLnZhbHVlT2YoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHV0Y1N0YXJ0T2ZEYXRlKHksIG0sIGQpIHtcbiAgICAgICAgLy8gRGF0ZS5VVEMgcmVtYXBzIHllYXJzIDAtOTkgdG8gMTkwMC0xOTk5XG4gICAgICAgIGlmICh5IDwgMTAwICYmIHkgPj0gMCkge1xuICAgICAgICAgICAgLy8gcHJlc2VydmUgbGVhcCB5ZWFycyB1c2luZyBhIGZ1bGwgNDAwIHllYXIgY3ljbGUsIHRoZW4gcmVzZXRcbiAgICAgICAgICAgIHJldHVybiBEYXRlLlVUQyh5ICsgNDAwLCBtLCBkKSAtIE1TX1BFUl80MDBfWUVBUlM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gRGF0ZS5VVEMoeSwgbSwgZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdGFydE9mICh1bml0cykge1xuICAgICAgICB2YXIgdGltZTtcbiAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh1bml0cyk7XG4gICAgICAgIGlmICh1bml0cyA9PT0gdW5kZWZpbmVkIHx8IHVuaXRzID09PSAnbWlsbGlzZWNvbmQnIHx8ICF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc3RhcnRPZkRhdGUgPSB0aGlzLl9pc1VUQyA/IHV0Y1N0YXJ0T2ZEYXRlIDogbG9jYWxTdGFydE9mRGF0ZTtcblxuICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIDAsIDEpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCkgLSB0aGlzLm1vbnRoKCkgJSAzLCAxKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgMSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSB0aGlzLndlZWtkYXkoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdpc29XZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSAodGhpcy5pc29XZWVrZGF5KCkgLSAxKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdkYXknOlxuICAgICAgICAgICAgY2FzZSAnZGF0ZSc6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCksIHRoaXMuZGF0ZSgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOlxuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLl9kLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB0aW1lIC09IG1vZCQxKHRpbWUgKyAodGhpcy5faXNVVEMgPyAwIDogdGhpcy51dGNPZmZzZXQoKSAqIE1TX1BFUl9NSU5VVEUpLCBNU19QRVJfSE9VUik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLl9kLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB0aW1lIC09IG1vZCQxKHRpbWUsIE1TX1BFUl9NSU5VVEUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSAtPSBtb2QkMSh0aW1lLCBNU19QRVJfU0VDT05EKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2Quc2V0VGltZSh0aW1lKTtcbiAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMsIHRydWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBlbmRPZiAodW5pdHMpIHtcbiAgICAgICAgdmFyIHRpbWU7XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICBpZiAodW5pdHMgPT09IHVuZGVmaW5lZCB8fCB1bml0cyA9PT0gJ21pbGxpc2Vjb25kJyB8fCAhdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHN0YXJ0T2ZEYXRlID0gdGhpcy5faXNVVEMgPyB1dGNTdGFydE9mRGF0ZSA6IGxvY2FsU3RhcnRPZkRhdGU7XG5cbiAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpICsgMSwgMCwgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCkgLSB0aGlzLm1vbnRoKCkgJSAzICsgMywgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOlxuICAgICAgICAgICAgICAgIHRpbWUgPSBzdGFydE9mRGF0ZSh0aGlzLnllYXIoKSwgdGhpcy5tb250aCgpICsgMSwgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCksIHRoaXMuZGF0ZSgpIC0gdGhpcy53ZWVrZGF5KCkgKyA3KSAtIDE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdpc29XZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSAodGhpcy5pc29XZWVrZGF5KCkgLSAxKSArIDcpIC0gMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2RheSc6XG4gICAgICAgICAgICBjYXNlICdkYXRlJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgKyAxKSAtIDE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfSE9VUiAtIG1vZCQxKHRpbWUgKyAodGhpcy5faXNVVEMgPyAwIDogdGhpcy51dGNPZmZzZXQoKSAqIE1TX1BFUl9NSU5VVEUpLCBNU19QRVJfSE9VUikgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbWludXRlJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfTUlOVVRFIC0gbW9kJDEodGltZSwgTVNfUEVSX01JTlVURSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfU0VDT05EIC0gbW9kJDEodGltZSwgTVNfUEVSX1NFQ09ORCkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fZC5zZXRUaW1lKHRpbWUpO1xuICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbHVlT2YgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZC52YWx1ZU9mKCkgLSAoKHRoaXMuX29mZnNldCB8fCAwKSAqIDYwMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1bml4ICgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IodGhpcy52YWx1ZU9mKCkgLyAxMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0RhdGUgKCkge1xuICAgICAgICByZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvQXJyYXkgKCkge1xuICAgICAgICB2YXIgbSA9IHRoaXM7XG4gICAgICAgIHJldHVybiBbbS55ZWFyKCksIG0ubW9udGgoKSwgbS5kYXRlKCksIG0uaG91cigpLCBtLm1pbnV0ZSgpLCBtLnNlY29uZCgpLCBtLm1pbGxpc2Vjb25kKCldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvT2JqZWN0ICgpIHtcbiAgICAgICAgdmFyIG0gPSB0aGlzO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeWVhcnM6IG0ueWVhcigpLFxuICAgICAgICAgICAgbW9udGhzOiBtLm1vbnRoKCksXG4gICAgICAgICAgICBkYXRlOiBtLmRhdGUoKSxcbiAgICAgICAgICAgIGhvdXJzOiBtLmhvdXJzKCksXG4gICAgICAgICAgICBtaW51dGVzOiBtLm1pbnV0ZXMoKSxcbiAgICAgICAgICAgIHNlY29uZHM6IG0uc2Vjb25kcygpLFxuICAgICAgICAgICAgbWlsbGlzZWNvbmRzOiBtLm1pbGxpc2Vjb25kcygpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgICAgICAgLy8gbmV3IERhdGUoTmFOKS50b0pTT04oKSA9PT0gbnVsbFxuICAgICAgICByZXR1cm4gdGhpcy5pc1ZhbGlkKCkgPyB0aGlzLnRvSVNPU3RyaW5nKCkgOiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVmFsaWQkMiAoKSB7XG4gICAgICAgIHJldHVybiBpc1ZhbGlkKHRoaXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNpbmdGbGFncyAoKSB7XG4gICAgICAgIHJldHVybiBleHRlbmQoe30sIGdldFBhcnNpbmdGbGFncyh0aGlzKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW52YWxpZEF0ICgpIHtcbiAgICAgICAgcmV0dXJuIGdldFBhcnNpbmdGbGFncyh0aGlzKS5vdmVyZmxvdztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGlvbkRhdGEoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpbnB1dDogdGhpcy5faSxcbiAgICAgICAgICAgIGZvcm1hdDogdGhpcy5fZixcbiAgICAgICAgICAgIGxvY2FsZTogdGhpcy5fbG9jYWxlLFxuICAgICAgICAgICAgaXNVVEM6IHRoaXMuX2lzVVRDLFxuICAgICAgICAgICAgc3RyaWN0OiB0aGlzLl9zdHJpY3RcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ2dnJywgMl0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2Vla1llYXIoKSAlIDEwMDtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnR0cnLCAyXSwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc29XZWVrWWVhcigpICUgMTAwO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYWRkV2Vla1llYXJGb3JtYXRUb2tlbiAodG9rZW4sIGdldHRlcikge1xuICAgICAgICBhZGRGb3JtYXRUb2tlbigwLCBbdG9rZW4sIHRva2VuLmxlbmd0aF0sIDAsIGdldHRlcik7XG4gICAgfVxuXG4gICAgYWRkV2Vla1llYXJGb3JtYXRUb2tlbignZ2dnZycsICAgICAnd2Vla1llYXInKTtcbiAgICBhZGRXZWVrWWVhckZvcm1hdFRva2VuKCdnZ2dnZycsICAgICd3ZWVrWWVhcicpO1xuICAgIGFkZFdlZWtZZWFyRm9ybWF0VG9rZW4oJ0dHR0cnLCAgJ2lzb1dlZWtZZWFyJyk7XG4gICAgYWRkV2Vla1llYXJGb3JtYXRUb2tlbignR0dHR0cnLCAnaXNvV2Vla1llYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnd2Vla1llYXInLCAnZ2cnKTtcbiAgICBhZGRVbml0QWxpYXMoJ2lzb1dlZWtZZWFyJywgJ0dHJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCd3ZWVrWWVhcicsIDEpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2Vla1llYXInLCAxKTtcblxuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbignRycsICAgICAgbWF0Y2hTaWduZWQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2cnLCAgICAgIG1hdGNoU2lnbmVkKTtcbiAgICBhZGRSZWdleFRva2VuKCdHRycsICAgICBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignZ2cnLCAgICAgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0dHR0cnLCAgIG1hdGNoMXRvNCwgbWF0Y2g0KTtcbiAgICBhZGRSZWdleFRva2VuKCdnZ2dnJywgICBtYXRjaDF0bzQsIG1hdGNoNCk7XG4gICAgYWRkUmVnZXhUb2tlbignR0dHR0cnLCAgbWF0Y2gxdG82LCBtYXRjaDYpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2dnZ2dnJywgIG1hdGNoMXRvNiwgbWF0Y2g2KTtcblxuICAgIGFkZFdlZWtQYXJzZVRva2VuKFsnZ2dnZycsICdnZ2dnZycsICdHR0dHJywgJ0dHR0dHJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuLnN1YnN0cigwLCAyKV0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICBhZGRXZWVrUGFyc2VUb2tlbihbJ2dnJywgJ0dHJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuXSA9IGhvb2tzLnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICB9KTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFNldFdlZWtZZWFyIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gZ2V0U2V0V2Vla1llYXJIZWxwZXIuY2FsbCh0aGlzLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIHRoaXMud2VlaygpLFxuICAgICAgICAgICAgICAgIHRoaXMud2Vla2RheSgpLFxuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrLmRvdyxcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsZURhdGEoKS5fd2Vlay5kb3kpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNldElTT1dlZWtZZWFyIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gZ2V0U2V0V2Vla1llYXJIZWxwZXIuY2FsbCh0aGlzLFxuICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLmlzb1dlZWsoKSwgdGhpcy5pc29XZWVrZGF5KCksIDEsIDQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldElTT1dlZWtzSW5ZZWFyICgpIHtcbiAgICAgICAgcmV0dXJuIHdlZWtzSW5ZZWFyKHRoaXMueWVhcigpLCAxLCA0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRXZWVrc0luWWVhciAoKSB7XG4gICAgICAgIHZhciB3ZWVrSW5mbyA9IHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrO1xuICAgICAgICByZXR1cm4gd2Vla3NJblllYXIodGhpcy55ZWFyKCksIHdlZWtJbmZvLmRvdywgd2Vla0luZm8uZG95KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRXZWVrWWVhckhlbHBlcihpbnB1dCwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIHdlZWtzVGFyZ2V0O1xuICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHdlZWtPZlllYXIodGhpcywgZG93LCBkb3kpLnllYXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3ZWVrc1RhcmdldCA9IHdlZWtzSW5ZZWFyKGlucHV0LCBkb3csIGRveSk7XG4gICAgICAgICAgICBpZiAod2VlayA+IHdlZWtzVGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgd2VlayA9IHdlZWtzVGFyZ2V0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNldFdlZWtBbGwuY2FsbCh0aGlzLCBpbnB1dCwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0V2Vla0FsbCh3ZWVrWWVhciwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIGRheU9mWWVhckRhdGEgPSBkYXlPZlllYXJGcm9tV2Vla3Mod2Vla1llYXIsIHdlZWssIHdlZWtkYXksIGRvdywgZG95KSxcbiAgICAgICAgICAgIGRhdGUgPSBjcmVhdGVVVENEYXRlKGRheU9mWWVhckRhdGEueWVhciwgMCwgZGF5T2ZZZWFyRGF0YS5kYXlPZlllYXIpO1xuXG4gICAgICAgIHRoaXMueWVhcihkYXRlLmdldFVUQ0Z1bGxZZWFyKCkpO1xuICAgICAgICB0aGlzLm1vbnRoKGRhdGUuZ2V0VVRDTW9udGgoKSk7XG4gICAgICAgIHRoaXMuZGF0ZShkYXRlLmdldFVUQ0RhdGUoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdRJywgMCwgJ1FvJywgJ3F1YXJ0ZXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygncXVhcnRlcicsICdRJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdxdWFydGVyJywgNyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdRJywgbWF0Y2gxKTtcbiAgICBhZGRQYXJzZVRva2VuKCdRJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtNT05USF0gPSAodG9JbnQoaW5wdXQpIC0gMSkgKiAzO1xuICAgIH0pO1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgZnVuY3Rpb24gZ2V0U2V0UXVhcnRlciAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyBNYXRoLmNlaWwoKHRoaXMubW9udGgoKSArIDEpIC8gMykgOiB0aGlzLm1vbnRoKChpbnB1dCAtIDEpICogMyArIHRoaXMubW9udGgoKSAlIDMpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdEJywgWydERCcsIDJdLCAnRG8nLCAnZGF0ZScpO1xuXG4gICAgLy8gQUxJQVNFU1xuXG4gICAgYWRkVW5pdEFsaWFzKCdkYXRlJywgJ0QnKTtcblxuICAgIC8vIFBSSU9SSVRZXG4gICAgYWRkVW5pdFByaW9yaXR5KCdkYXRlJywgOSk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdEJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignREQnLCBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignRG8nLCBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICAvLyBUT0RPOiBSZW1vdmUgXCJvcmRpbmFsUGFyc2VcIiBmYWxsYmFjayBpbiBuZXh0IG1ham9yIHJlbGVhc2UuXG4gICAgICAgIHJldHVybiBpc1N0cmljdCA/XG4gICAgICAgICAgKGxvY2FsZS5fZGF5T2ZNb250aE9yZGluYWxQYXJzZSB8fCBsb2NhbGUuX29yZGluYWxQYXJzZSkgOlxuICAgICAgICAgIGxvY2FsZS5fZGF5T2ZNb250aE9yZGluYWxQYXJzZUxlbmllbnQ7XG4gICAgfSk7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnRCcsICdERCddLCBEQVRFKTtcbiAgICBhZGRQYXJzZVRva2VuKCdEbycsIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbREFURV0gPSB0b0ludChpbnB1dC5tYXRjaChtYXRjaDF0bzIpWzBdKTtcbiAgICB9KTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIHZhciBnZXRTZXREYXlPZk1vbnRoID0gbWFrZUdldFNldCgnRGF0ZScsIHRydWUpO1xuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ0RERCcsIFsnRERERCcsIDNdLCAnREREbycsICdkYXlPZlllYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnZGF5T2ZZZWFyJywgJ0RERCcpO1xuXG4gICAgLy8gUFJJT1JJVFlcbiAgICBhZGRVbml0UHJpb3JpdHkoJ2RheU9mWWVhcicsIDQpO1xuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbignREREJywgIG1hdGNoMXRvMyk7XG4gICAgYWRkUmVnZXhUb2tlbignRERERCcsIG1hdGNoMyk7XG4gICAgYWRkUGFyc2VUb2tlbihbJ0RERCcsICdEREREJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2RheU9mWWVhciA9IHRvSW50KGlucHV0KTtcbiAgICB9KTtcblxuICAgIC8vIEhFTFBFUlNcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFNldERheU9mWWVhciAoaW5wdXQpIHtcbiAgICAgICAgdmFyIGRheU9mWWVhciA9IE1hdGgucm91bmQoKHRoaXMuY2xvbmUoKS5zdGFydE9mKCdkYXknKSAtIHRoaXMuY2xvbmUoKS5zdGFydE9mKCd5ZWFyJykpIC8gODY0ZTUpICsgMTtcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyBkYXlPZlllYXIgOiB0aGlzLmFkZCgoaW5wdXQgLSBkYXlPZlllYXIpLCAnZCcpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdtJywgWydtbScsIDJdLCAwLCAnbWludXRlJyk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21pbnV0ZScsICdtJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdtaW51dGUnLCAxNCk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdtJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignbW0nLCBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUGFyc2VUb2tlbihbJ20nLCAnbW0nXSwgTUlOVVRFKTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIHZhciBnZXRTZXRNaW51dGUgPSBtYWtlR2V0U2V0KCdNaW51dGVzJywgZmFsc2UpO1xuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ3MnLCBbJ3NzJywgMl0sIDAsICdzZWNvbmQnKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnc2Vjb25kJywgJ3MnKTtcblxuICAgIC8vIFBSSU9SSVRZXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ3NlY29uZCcsIDE1KTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ3MnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdzcycsIG1hdGNoMXRvMiwgbWF0Y2gyKTtcbiAgICBhZGRQYXJzZVRva2VuKFsncycsICdzcyddLCBTRUNPTkQpO1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgdmFyIGdldFNldFNlY29uZCA9IG1ha2VHZXRTZXQoJ1NlY29uZHMnLCBmYWxzZSk7XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbignUycsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIH5+KHRoaXMubWlsbGlzZWNvbmQoKSAvIDEwMCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTJywgMl0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIH5+KHRoaXMubWlsbGlzZWNvbmQoKSAvIDEwKTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTJywgM10sIDAsICdtaWxsaXNlY29uZCcpO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTUycsIDRdLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTJywgNV0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWlsbGlzZWNvbmQoKSAqIDEwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTUycsIDZdLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwO1xuICAgIH0pO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTU1NTUycsIDddLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTU1NTJywgOF0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWlsbGlzZWNvbmQoKSAqIDEwMDAwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTU1NTUycsIDldLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwMDAwO1xuICAgIH0pO1xuXG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21pbGxpc2Vjb25kJywgJ21zJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdtaWxsaXNlY29uZCcsIDE2KTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1MnLCAgICBtYXRjaDF0bzMsIG1hdGNoMSk7XG4gICAgYWRkUmVnZXhUb2tlbignU1MnLCAgIG1hdGNoMXRvMywgbWF0Y2gyKTtcbiAgICBhZGRSZWdleFRva2VuKCdTU1MnLCAgbWF0Y2gxdG8zLCBtYXRjaDMpO1xuXG4gICAgdmFyIHRva2VuO1xuICAgIGZvciAodG9rZW4gPSAnU1NTUyc7IHRva2VuLmxlbmd0aCA8PSA5OyB0b2tlbiArPSAnUycpIHtcbiAgICAgICAgYWRkUmVnZXhUb2tlbih0b2tlbiwgbWF0Y2hVbnNpZ25lZCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VNcyhpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbTUlMTElTRUNPTkRdID0gdG9JbnQoKCcwLicgKyBpbnB1dCkgKiAxMDAwKTtcbiAgICB9XG5cbiAgICBmb3IgKHRva2VuID0gJ1MnOyB0b2tlbi5sZW5ndGggPD0gOTsgdG9rZW4gKz0gJ1MnKSB7XG4gICAgICAgIGFkZFBhcnNlVG9rZW4odG9rZW4sIHBhcnNlTXMpO1xuICAgIH1cbiAgICAvLyBNT01FTlRTXG5cbiAgICB2YXIgZ2V0U2V0TWlsbGlzZWNvbmQgPSBtYWtlR2V0U2V0KCdNaWxsaXNlY29uZHMnLCBmYWxzZSk7XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigneicsICAwLCAwLCAnem9uZUFiYnInKTtcbiAgICBhZGRGb3JtYXRUb2tlbignenonLCAwLCAwLCAnem9uZU5hbWUnKTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFpvbmVBYmJyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzVVRDID8gJ1VUQycgOiAnJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRab25lTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/ICdDb29yZGluYXRlZCBVbml2ZXJzYWwgVGltZScgOiAnJztcbiAgICB9XG5cbiAgICB2YXIgcHJvdG8gPSBNb21lbnQucHJvdG90eXBlO1xuXG4gICAgcHJvdG8uYWRkICAgICAgICAgICAgICAgPSBhZGQ7XG4gICAgcHJvdG8uY2FsZW5kYXIgICAgICAgICAgPSBjYWxlbmRhciQxO1xuICAgIHByb3RvLmNsb25lICAgICAgICAgICAgID0gY2xvbmU7XG4gICAgcHJvdG8uZGlmZiAgICAgICAgICAgICAgPSBkaWZmO1xuICAgIHByb3RvLmVuZE9mICAgICAgICAgICAgID0gZW5kT2Y7XG4gICAgcHJvdG8uZm9ybWF0ICAgICAgICAgICAgPSBmb3JtYXQ7XG4gICAgcHJvdG8uZnJvbSAgICAgICAgICAgICAgPSBmcm9tO1xuICAgIHByb3RvLmZyb21Ob3cgICAgICAgICAgID0gZnJvbU5vdztcbiAgICBwcm90by50byAgICAgICAgICAgICAgICA9IHRvO1xuICAgIHByb3RvLnRvTm93ICAgICAgICAgICAgID0gdG9Ob3c7XG4gICAgcHJvdG8uZ2V0ICAgICAgICAgICAgICAgPSBzdHJpbmdHZXQ7XG4gICAgcHJvdG8uaW52YWxpZEF0ICAgICAgICAgPSBpbnZhbGlkQXQ7XG4gICAgcHJvdG8uaXNBZnRlciAgICAgICAgICAgPSBpc0FmdGVyO1xuICAgIHByb3RvLmlzQmVmb3JlICAgICAgICAgID0gaXNCZWZvcmU7XG4gICAgcHJvdG8uaXNCZXR3ZWVuICAgICAgICAgPSBpc0JldHdlZW47XG4gICAgcHJvdG8uaXNTYW1lICAgICAgICAgICAgPSBpc1NhbWU7XG4gICAgcHJvdG8uaXNTYW1lT3JBZnRlciAgICAgPSBpc1NhbWVPckFmdGVyO1xuICAgIHByb3RvLmlzU2FtZU9yQmVmb3JlICAgID0gaXNTYW1lT3JCZWZvcmU7XG4gICAgcHJvdG8uaXNWYWxpZCAgICAgICAgICAgPSBpc1ZhbGlkJDI7XG4gICAgcHJvdG8ubGFuZyAgICAgICAgICAgICAgPSBsYW5nO1xuICAgIHByb3RvLmxvY2FsZSAgICAgICAgICAgID0gbG9jYWxlO1xuICAgIHByb3RvLmxvY2FsZURhdGEgICAgICAgID0gbG9jYWxlRGF0YTtcbiAgICBwcm90by5tYXggICAgICAgICAgICAgICA9IHByb3RvdHlwZU1heDtcbiAgICBwcm90by5taW4gICAgICAgICAgICAgICA9IHByb3RvdHlwZU1pbjtcbiAgICBwcm90by5wYXJzaW5nRmxhZ3MgICAgICA9IHBhcnNpbmdGbGFncztcbiAgICBwcm90by5zZXQgICAgICAgICAgICAgICA9IHN0cmluZ1NldDtcbiAgICBwcm90by5zdGFydE9mICAgICAgICAgICA9IHN0YXJ0T2Y7XG4gICAgcHJvdG8uc3VidHJhY3QgICAgICAgICAgPSBzdWJ0cmFjdDtcbiAgICBwcm90by50b0FycmF5ICAgICAgICAgICA9IHRvQXJyYXk7XG4gICAgcHJvdG8udG9PYmplY3QgICAgICAgICAgPSB0b09iamVjdDtcbiAgICBwcm90by50b0RhdGUgICAgICAgICAgICA9IHRvRGF0ZTtcbiAgICBwcm90by50b0lTT1N0cmluZyAgICAgICA9IHRvSVNPU3RyaW5nO1xuICAgIHByb3RvLmluc3BlY3QgICAgICAgICAgID0gaW5zcGVjdDtcbiAgICBwcm90by50b0pTT04gICAgICAgICAgICA9IHRvSlNPTjtcbiAgICBwcm90by50b1N0cmluZyAgICAgICAgICA9IHRvU3RyaW5nO1xuICAgIHByb3RvLnVuaXggICAgICAgICAgICAgID0gdW5peDtcbiAgICBwcm90by52YWx1ZU9mICAgICAgICAgICA9IHZhbHVlT2Y7XG4gICAgcHJvdG8uY3JlYXRpb25EYXRhICAgICAgPSBjcmVhdGlvbkRhdGE7XG4gICAgcHJvdG8ueWVhciAgICAgICA9IGdldFNldFllYXI7XG4gICAgcHJvdG8uaXNMZWFwWWVhciA9IGdldElzTGVhcFllYXI7XG4gICAgcHJvdG8ud2Vla1llYXIgICAgPSBnZXRTZXRXZWVrWWVhcjtcbiAgICBwcm90by5pc29XZWVrWWVhciA9IGdldFNldElTT1dlZWtZZWFyO1xuICAgIHByb3RvLnF1YXJ0ZXIgPSBwcm90by5xdWFydGVycyA9IGdldFNldFF1YXJ0ZXI7XG4gICAgcHJvdG8ubW9udGggICAgICAgPSBnZXRTZXRNb250aDtcbiAgICBwcm90by5kYXlzSW5Nb250aCA9IGdldERheXNJbk1vbnRoO1xuICAgIHByb3RvLndlZWsgICAgICAgICAgID0gcHJvdG8ud2Vla3MgICAgICAgID0gZ2V0U2V0V2VlaztcbiAgICBwcm90by5pc29XZWVrICAgICAgICA9IHByb3RvLmlzb1dlZWtzICAgICA9IGdldFNldElTT1dlZWs7XG4gICAgcHJvdG8ud2Vla3NJblllYXIgICAgPSBnZXRXZWVrc0luWWVhcjtcbiAgICBwcm90by5pc29XZWVrc0luWWVhciA9IGdldElTT1dlZWtzSW5ZZWFyO1xuICAgIHByb3RvLmRhdGUgICAgICAgPSBnZXRTZXREYXlPZk1vbnRoO1xuICAgIHByb3RvLmRheSAgICAgICAgPSBwcm90by5kYXlzICAgICAgICAgICAgID0gZ2V0U2V0RGF5T2ZXZWVrO1xuICAgIHByb3RvLndlZWtkYXkgICAgPSBnZXRTZXRMb2NhbGVEYXlPZldlZWs7XG4gICAgcHJvdG8uaXNvV2Vla2RheSA9IGdldFNldElTT0RheU9mV2VlaztcbiAgICBwcm90by5kYXlPZlllYXIgID0gZ2V0U2V0RGF5T2ZZZWFyO1xuICAgIHByb3RvLmhvdXIgPSBwcm90by5ob3VycyA9IGdldFNldEhvdXI7XG4gICAgcHJvdG8ubWludXRlID0gcHJvdG8ubWludXRlcyA9IGdldFNldE1pbnV0ZTtcbiAgICBwcm90by5zZWNvbmQgPSBwcm90by5zZWNvbmRzID0gZ2V0U2V0U2Vjb25kO1xuICAgIHByb3RvLm1pbGxpc2Vjb25kID0gcHJvdG8ubWlsbGlzZWNvbmRzID0gZ2V0U2V0TWlsbGlzZWNvbmQ7XG4gICAgcHJvdG8udXRjT2Zmc2V0ICAgICAgICAgICAgPSBnZXRTZXRPZmZzZXQ7XG4gICAgcHJvdG8udXRjICAgICAgICAgICAgICAgICAgPSBzZXRPZmZzZXRUb1VUQztcbiAgICBwcm90by5sb2NhbCAgICAgICAgICAgICAgICA9IHNldE9mZnNldFRvTG9jYWw7XG4gICAgcHJvdG8ucGFyc2Vab25lICAgICAgICAgICAgPSBzZXRPZmZzZXRUb1BhcnNlZE9mZnNldDtcbiAgICBwcm90by5oYXNBbGlnbmVkSG91ck9mZnNldCA9IGhhc0FsaWduZWRIb3VyT2Zmc2V0O1xuICAgIHByb3RvLmlzRFNUICAgICAgICAgICAgICAgID0gaXNEYXlsaWdodFNhdmluZ1RpbWU7XG4gICAgcHJvdG8uaXNMb2NhbCAgICAgICAgICAgICAgPSBpc0xvY2FsO1xuICAgIHByb3RvLmlzVXRjT2Zmc2V0ICAgICAgICAgID0gaXNVdGNPZmZzZXQ7XG4gICAgcHJvdG8uaXNVdGMgICAgICAgICAgICAgICAgPSBpc1V0YztcbiAgICBwcm90by5pc1VUQyAgICAgICAgICAgICAgICA9IGlzVXRjO1xuICAgIHByb3RvLnpvbmVBYmJyID0gZ2V0Wm9uZUFiYnI7XG4gICAgcHJvdG8uem9uZU5hbWUgPSBnZXRab25lTmFtZTtcbiAgICBwcm90by5kYXRlcyAgPSBkZXByZWNhdGUoJ2RhdGVzIGFjY2Vzc29yIGlzIGRlcHJlY2F0ZWQuIFVzZSBkYXRlIGluc3RlYWQuJywgZ2V0U2V0RGF5T2ZNb250aCk7XG4gICAgcHJvdG8ubW9udGhzID0gZGVwcmVjYXRlKCdtb250aHMgYWNjZXNzb3IgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbnRoIGluc3RlYWQnLCBnZXRTZXRNb250aCk7XG4gICAgcHJvdG8ueWVhcnMgID0gZGVwcmVjYXRlKCd5ZWFycyBhY2Nlc3NvciBpcyBkZXByZWNhdGVkLiBVc2UgeWVhciBpbnN0ZWFkJywgZ2V0U2V0WWVhcik7XG4gICAgcHJvdG8uem9uZSAgID0gZGVwcmVjYXRlKCdtb21lbnQoKS56b25lIGlzIGRlcHJlY2F0ZWQsIHVzZSBtb21lbnQoKS51dGNPZmZzZXQgaW5zdGVhZC4gaHR0cDovL21vbWVudGpzLmNvbS9ndWlkZXMvIy93YXJuaW5ncy96b25lLycsIGdldFNldFpvbmUpO1xuICAgIHByb3RvLmlzRFNUU2hpZnRlZCA9IGRlcHJlY2F0ZSgnaXNEU1RTaGlmdGVkIGlzIGRlcHJlY2F0ZWQuIFNlZSBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2RzdC1zaGlmdGVkLyBmb3IgbW9yZSBpbmZvcm1hdGlvbicsIGlzRGF5bGlnaHRTYXZpbmdUaW1lU2hpZnRlZCk7XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVVbml4IChpbnB1dCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwoaW5wdXQgKiAxMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVJblpvbmUgKCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwuYXBwbHkobnVsbCwgYXJndW1lbnRzKS5wYXJzZVpvbmUoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVQYXJzZVBvc3RGb3JtYXQgKHN0cmluZykge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgIH1cblxuICAgIHZhciBwcm90byQxID0gTG9jYWxlLnByb3RvdHlwZTtcblxuICAgIHByb3RvJDEuY2FsZW5kYXIgICAgICAgID0gY2FsZW5kYXI7XG4gICAgcHJvdG8kMS5sb25nRGF0ZUZvcm1hdCAgPSBsb25nRGF0ZUZvcm1hdDtcbiAgICBwcm90byQxLmludmFsaWREYXRlICAgICA9IGludmFsaWREYXRlO1xuICAgIHByb3RvJDEub3JkaW5hbCAgICAgICAgID0gb3JkaW5hbDtcbiAgICBwcm90byQxLnByZXBhcnNlICAgICAgICA9IHByZVBhcnNlUG9zdEZvcm1hdDtcbiAgICBwcm90byQxLnBvc3Rmb3JtYXQgICAgICA9IHByZVBhcnNlUG9zdEZvcm1hdDtcbiAgICBwcm90byQxLnJlbGF0aXZlVGltZSAgICA9IHJlbGF0aXZlVGltZTtcbiAgICBwcm90byQxLnBhc3RGdXR1cmUgICAgICA9IHBhc3RGdXR1cmU7XG4gICAgcHJvdG8kMS5zZXQgICAgICAgICAgICAgPSBzZXQ7XG5cbiAgICBwcm90byQxLm1vbnRocyAgICAgICAgICAgID0gICAgICAgIGxvY2FsZU1vbnRocztcbiAgICBwcm90byQxLm1vbnRoc1Nob3J0ICAgICAgID0gICAgICAgIGxvY2FsZU1vbnRoc1Nob3J0O1xuICAgIHByb3RvJDEubW9udGhzUGFyc2UgICAgICAgPSAgICAgICAgbG9jYWxlTW9udGhzUGFyc2U7XG4gICAgcHJvdG8kMS5tb250aHNSZWdleCAgICAgICA9IG1vbnRoc1JlZ2V4O1xuICAgIHByb3RvJDEubW9udGhzU2hvcnRSZWdleCAgPSBtb250aHNTaG9ydFJlZ2V4O1xuICAgIHByb3RvJDEud2VlayA9IGxvY2FsZVdlZWs7XG4gICAgcHJvdG8kMS5maXJzdERheU9mWWVhciA9IGxvY2FsZUZpcnN0RGF5T2ZZZWFyO1xuICAgIHByb3RvJDEuZmlyc3REYXlPZldlZWsgPSBsb2NhbGVGaXJzdERheU9mV2VlaztcblxuICAgIHByb3RvJDEud2Vla2RheXMgICAgICAgPSAgICAgICAgbG9jYWxlV2Vla2RheXM7XG4gICAgcHJvdG8kMS53ZWVrZGF5c01pbiAgICA9ICAgICAgICBsb2NhbGVXZWVrZGF5c01pbjtcbiAgICBwcm90byQxLndlZWtkYXlzU2hvcnQgID0gICAgICAgIGxvY2FsZVdlZWtkYXlzU2hvcnQ7XG4gICAgcHJvdG8kMS53ZWVrZGF5c1BhcnNlICA9ICAgICAgICBsb2NhbGVXZWVrZGF5c1BhcnNlO1xuXG4gICAgcHJvdG8kMS53ZWVrZGF5c1JlZ2V4ICAgICAgID0gICAgICAgIHdlZWtkYXlzUmVnZXg7XG4gICAgcHJvdG8kMS53ZWVrZGF5c1Nob3J0UmVnZXggID0gICAgICAgIHdlZWtkYXlzU2hvcnRSZWdleDtcbiAgICBwcm90byQxLndlZWtkYXlzTWluUmVnZXggICAgPSAgICAgICAgd2Vla2RheXNNaW5SZWdleDtcblxuICAgIHByb3RvJDEuaXNQTSA9IGxvY2FsZUlzUE07XG4gICAgcHJvdG8kMS5tZXJpZGllbSA9IGxvY2FsZU1lcmlkaWVtO1xuXG4gICAgZnVuY3Rpb24gZ2V0JDEgKGZvcm1hdCwgaW5kZXgsIGZpZWxkLCBzZXR0ZXIpIHtcbiAgICAgICAgdmFyIGxvY2FsZSA9IGdldExvY2FsZSgpO1xuICAgICAgICB2YXIgdXRjID0gY3JlYXRlVVRDKCkuc2V0KHNldHRlciwgaW5kZXgpO1xuICAgICAgICByZXR1cm4gbG9jYWxlW2ZpZWxkXSh1dGMsIGZvcm1hdCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdE1vbnRoc0ltcGwgKGZvcm1hdCwgaW5kZXgsIGZpZWxkKSB7XG4gICAgICAgIGlmIChpc051bWJlcihmb3JtYXQpKSB7XG4gICAgICAgICAgICBpbmRleCA9IGZvcm1hdDtcbiAgICAgICAgICAgIGZvcm1hdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvcm1hdCA9IGZvcm1hdCB8fCAnJztcblxuICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldCQxKGZvcm1hdCwgaW5kZXgsIGZpZWxkLCAnbW9udGgnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgb3V0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG4gICAgICAgICAgICBvdXRbaV0gPSBnZXQkMShmb3JtYXQsIGksIGZpZWxkLCAnbW9udGgnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH1cblxuICAgIC8vICgpXG4gICAgLy8gKDUpXG4gICAgLy8gKGZtdCwgNSlcbiAgICAvLyAoZm10KVxuICAgIC8vICh0cnVlKVxuICAgIC8vICh0cnVlLCA1KVxuICAgIC8vICh0cnVlLCBmbXQsIDUpXG4gICAgLy8gKHRydWUsIGZtdClcbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNJbXBsIChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgsIGZpZWxkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbG9jYWxlU29ydGVkID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIGlmIChpc051bWJlcihmb3JtYXQpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBmb3JtYXQ7XG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3JtYXQgPSBmb3JtYXQgfHwgJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3JtYXQgPSBsb2NhbGVTb3J0ZWQ7XG4gICAgICAgICAgICBpbmRleCA9IGZvcm1hdDtcbiAgICAgICAgICAgIGxvY2FsZVNvcnRlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoaXNOdW1iZXIoZm9ybWF0KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gZm9ybWF0O1xuICAgICAgICAgICAgICAgIGZvcm1hdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9ybWF0ID0gZm9ybWF0IHx8ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGxvY2FsZSA9IGdldExvY2FsZSgpLFxuICAgICAgICAgICAgc2hpZnQgPSBsb2NhbGVTb3J0ZWQgPyBsb2NhbGUuX3dlZWsuZG93IDogMDtcblxuICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldCQxKGZvcm1hdCwgKGluZGV4ICsgc2hpZnQpICUgNywgZmllbGQsICdkYXknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgb3V0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIG91dFtpXSA9IGdldCQxKGZvcm1hdCwgKGkgKyBzaGlmdCkgJSA3LCBmaWVsZCwgJ2RheScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdE1vbnRocyAoZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdE1vbnRoc0ltcGwoZm9ybWF0LCBpbmRleCwgJ21vbnRocycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpc3RNb250aHNTaG9ydCAoZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdE1vbnRoc0ltcGwoZm9ybWF0LCBpbmRleCwgJ21vbnRoc1Nob3J0Jyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdFdlZWtkYXlzIChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGxpc3RXZWVrZGF5c0ltcGwobG9jYWxlU29ydGVkLCBmb3JtYXQsIGluZGV4LCAnd2Vla2RheXMnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNTaG9ydCAobG9jYWxlU29ydGVkLCBmb3JtYXQsIGluZGV4KSB7XG4gICAgICAgIHJldHVybiBsaXN0V2Vla2RheXNJbXBsKGxvY2FsZVNvcnRlZCwgZm9ybWF0LCBpbmRleCwgJ3dlZWtkYXlzU2hvcnQnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNNaW4gKGxvY2FsZVNvcnRlZCwgZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdFdlZWtkYXlzSW1wbChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgsICd3ZWVrZGF5c01pbicpO1xuICAgIH1cblxuICAgIGdldFNldEdsb2JhbExvY2FsZSgnZW4nLCB7XG4gICAgICAgIGRheU9mTW9udGhPcmRpbmFsUGFyc2U6IC9cXGR7MSwyfSh0aHxzdHxuZHxyZCkvLFxuICAgICAgICBvcmRpbmFsIDogZnVuY3Rpb24gKG51bWJlcikge1xuICAgICAgICAgICAgdmFyIGIgPSBudW1iZXIgJSAxMCxcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSAodG9JbnQobnVtYmVyICUgMTAwIC8gMTApID09PSAxKSA/ICd0aCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAxKSA/ICdzdCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAyKSA/ICduZCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAzKSA/ICdyZCcgOiAndGgnO1xuICAgICAgICAgICAgcmV0dXJuIG51bWJlciArIG91dHB1dDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gU2lkZSBlZmZlY3QgaW1wb3J0c1xuXG4gICAgaG9va3MubGFuZyA9IGRlcHJlY2F0ZSgnbW9tZW50LmxhbmcgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGUgaW5zdGVhZC4nLCBnZXRTZXRHbG9iYWxMb2NhbGUpO1xuICAgIGhvb2tzLmxhbmdEYXRhID0gZGVwcmVjYXRlKCdtb21lbnQubGFuZ0RhdGEgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGVEYXRhIGluc3RlYWQuJywgZ2V0TG9jYWxlKTtcblxuICAgIHZhciBtYXRoQWJzID0gTWF0aC5hYnM7XG5cbiAgICBmdW5jdGlvbiBhYnMgKCkge1xuICAgICAgICB2YXIgZGF0YSAgICAgICAgICAgPSB0aGlzLl9kYXRhO1xuXG4gICAgICAgIHRoaXMuX21pbGxpc2Vjb25kcyA9IG1hdGhBYnModGhpcy5fbWlsbGlzZWNvbmRzKTtcbiAgICAgICAgdGhpcy5fZGF5cyAgICAgICAgID0gbWF0aEFicyh0aGlzLl9kYXlzKTtcbiAgICAgICAgdGhpcy5fbW9udGhzICAgICAgID0gbWF0aEFicyh0aGlzLl9tb250aHMpO1xuXG4gICAgICAgIGRhdGEubWlsbGlzZWNvbmRzICA9IG1hdGhBYnMoZGF0YS5taWxsaXNlY29uZHMpO1xuICAgICAgICBkYXRhLnNlY29uZHMgICAgICAgPSBtYXRoQWJzKGRhdGEuc2Vjb25kcyk7XG4gICAgICAgIGRhdGEubWludXRlcyAgICAgICA9IG1hdGhBYnMoZGF0YS5taW51dGVzKTtcbiAgICAgICAgZGF0YS5ob3VycyAgICAgICAgID0gbWF0aEFicyhkYXRhLmhvdXJzKTtcbiAgICAgICAgZGF0YS5tb250aHMgICAgICAgID0gbWF0aEFicyhkYXRhLm1vbnRocyk7XG4gICAgICAgIGRhdGEueWVhcnMgICAgICAgICA9IG1hdGhBYnMoZGF0YS55ZWFycyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWRkU3VidHJhY3QkMSAoZHVyYXRpb24sIGlucHV0LCB2YWx1ZSwgZGlyZWN0aW9uKSB7XG4gICAgICAgIHZhciBvdGhlciA9IGNyZWF0ZUR1cmF0aW9uKGlucHV0LCB2YWx1ZSk7XG5cbiAgICAgICAgZHVyYXRpb24uX21pbGxpc2Vjb25kcyArPSBkaXJlY3Rpb24gKiBvdGhlci5fbWlsbGlzZWNvbmRzO1xuICAgICAgICBkdXJhdGlvbi5fZGF5cyAgICAgICAgICs9IGRpcmVjdGlvbiAqIG90aGVyLl9kYXlzO1xuICAgICAgICBkdXJhdGlvbi5fbW9udGhzICAgICAgICs9IGRpcmVjdGlvbiAqIG90aGVyLl9tb250aHM7XG5cbiAgICAgICAgcmV0dXJuIGR1cmF0aW9uLl9idWJibGUoKTtcbiAgICB9XG5cbiAgICAvLyBzdXBwb3J0cyBvbmx5IDIuMC1zdHlsZSBhZGQoMSwgJ3MnKSBvciBhZGQoZHVyYXRpb24pXG4gICAgZnVuY3Rpb24gYWRkJDEgKGlucHV0LCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gYWRkU3VidHJhY3QkMSh0aGlzLCBpbnB1dCwgdmFsdWUsIDEpO1xuICAgIH1cblxuICAgIC8vIHN1cHBvcnRzIG9ubHkgMi4wLXN0eWxlIHN1YnRyYWN0KDEsICdzJykgb3Igc3VidHJhY3QoZHVyYXRpb24pXG4gICAgZnVuY3Rpb24gc3VidHJhY3QkMSAoaW5wdXQsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBhZGRTdWJ0cmFjdCQxKHRoaXMsIGlucHV0LCB2YWx1ZSwgLTEpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFic0NlaWwgKG51bWJlcikge1xuICAgICAgICBpZiAobnVtYmVyIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IobnVtYmVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmNlaWwobnVtYmVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJ1YmJsZSAoKSB7XG4gICAgICAgIHZhciBtaWxsaXNlY29uZHMgPSB0aGlzLl9taWxsaXNlY29uZHM7XG4gICAgICAgIHZhciBkYXlzICAgICAgICAgPSB0aGlzLl9kYXlzO1xuICAgICAgICB2YXIgbW9udGhzICAgICAgID0gdGhpcy5fbW9udGhzO1xuICAgICAgICB2YXIgZGF0YSAgICAgICAgID0gdGhpcy5fZGF0YTtcbiAgICAgICAgdmFyIHNlY29uZHMsIG1pbnV0ZXMsIGhvdXJzLCB5ZWFycywgbW9udGhzRnJvbURheXM7XG5cbiAgICAgICAgLy8gaWYgd2UgaGF2ZSBhIG1peCBvZiBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgdmFsdWVzLCBidWJibGUgZG93biBmaXJzdFxuICAgICAgICAvLyBjaGVjazogaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzIxNjZcbiAgICAgICAgaWYgKCEoKG1pbGxpc2Vjb25kcyA+PSAwICYmIGRheXMgPj0gMCAmJiBtb250aHMgPj0gMCkgfHxcbiAgICAgICAgICAgICAgICAobWlsbGlzZWNvbmRzIDw9IDAgJiYgZGF5cyA8PSAwICYmIG1vbnRocyA8PSAwKSkpIHtcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kcyArPSBhYnNDZWlsKG1vbnRoc1RvRGF5cyhtb250aHMpICsgZGF5cykgKiA4NjRlNTtcbiAgICAgICAgICAgIGRheXMgPSAwO1xuICAgICAgICAgICAgbW9udGhzID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgY29kZSBidWJibGVzIHVwIHZhbHVlcywgc2VlIHRoZSB0ZXN0cyBmb3JcbiAgICAgICAgLy8gZXhhbXBsZXMgb2Ygd2hhdCB0aGF0IG1lYW5zLlxuICAgICAgICBkYXRhLm1pbGxpc2Vjb25kcyA9IG1pbGxpc2Vjb25kcyAlIDEwMDA7XG5cbiAgICAgICAgc2Vjb25kcyAgICAgICAgICAgPSBhYnNGbG9vcihtaWxsaXNlY29uZHMgLyAxMDAwKTtcbiAgICAgICAgZGF0YS5zZWNvbmRzICAgICAgPSBzZWNvbmRzICUgNjA7XG5cbiAgICAgICAgbWludXRlcyAgICAgICAgICAgPSBhYnNGbG9vcihzZWNvbmRzIC8gNjApO1xuICAgICAgICBkYXRhLm1pbnV0ZXMgICAgICA9IG1pbnV0ZXMgJSA2MDtcblxuICAgICAgICBob3VycyAgICAgICAgICAgICA9IGFic0Zsb29yKG1pbnV0ZXMgLyA2MCk7XG4gICAgICAgIGRhdGEuaG91cnMgICAgICAgID0gaG91cnMgJSAyNDtcblxuICAgICAgICBkYXlzICs9IGFic0Zsb29yKGhvdXJzIC8gMjQpO1xuXG4gICAgICAgIC8vIGNvbnZlcnQgZGF5cyB0byBtb250aHNcbiAgICAgICAgbW9udGhzRnJvbURheXMgPSBhYnNGbG9vcihkYXlzVG9Nb250aHMoZGF5cykpO1xuICAgICAgICBtb250aHMgKz0gbW9udGhzRnJvbURheXM7XG4gICAgICAgIGRheXMgLT0gYWJzQ2VpbChtb250aHNUb0RheXMobW9udGhzRnJvbURheXMpKTtcblxuICAgICAgICAvLyAxMiBtb250aHMgLT4gMSB5ZWFyXG4gICAgICAgIHllYXJzID0gYWJzRmxvb3IobW9udGhzIC8gMTIpO1xuICAgICAgICBtb250aHMgJT0gMTI7XG5cbiAgICAgICAgZGF0YS5kYXlzICAgPSBkYXlzO1xuICAgICAgICBkYXRhLm1vbnRocyA9IG1vbnRocztcbiAgICAgICAgZGF0YS55ZWFycyAgPSB5ZWFycztcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlzVG9Nb250aHMgKGRheXMpIHtcbiAgICAgICAgLy8gNDAwIHllYXJzIGhhdmUgMTQ2MDk3IGRheXMgKHRha2luZyBpbnRvIGFjY291bnQgbGVhcCB5ZWFyIHJ1bGVzKVxuICAgICAgICAvLyA0MDAgeWVhcnMgaGF2ZSAxMiBtb250aHMgPT09IDQ4MDBcbiAgICAgICAgcmV0dXJuIGRheXMgKiA0ODAwIC8gMTQ2MDk3O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1vbnRoc1RvRGF5cyAobW9udGhzKSB7XG4gICAgICAgIC8vIHRoZSByZXZlcnNlIG9mIGRheXNUb01vbnRoc1xuICAgICAgICByZXR1cm4gbW9udGhzICogMTQ2MDk3IC8gNDgwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhcyAodW5pdHMpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIE5hTjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF5cztcbiAgICAgICAgdmFyIG1vbnRocztcbiAgICAgICAgdmFyIG1pbGxpc2Vjb25kcyA9IHRoaXMuX21pbGxpc2Vjb25kcztcblxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICBpZiAodW5pdHMgPT09ICdtb250aCcgfHwgdW5pdHMgPT09ICdxdWFydGVyJyB8fCB1bml0cyA9PT0gJ3llYXInKSB7XG4gICAgICAgICAgICBkYXlzID0gdGhpcy5fZGF5cyArIG1pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgbW9udGhzID0gdGhpcy5fbW9udGhzICsgZGF5c1RvTW9udGhzKGRheXMpO1xuICAgICAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgICAgIGNhc2UgJ21vbnRoJzogICByZXR1cm4gbW9udGhzO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3F1YXJ0ZXInOiByZXR1cm4gbW9udGhzIC8gMztcbiAgICAgICAgICAgICAgICBjYXNlICd5ZWFyJzogICAgcmV0dXJuIG1vbnRocyAvIDEyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaGFuZGxlIG1pbGxpc2Vjb25kcyBzZXBhcmF0ZWx5IGJlY2F1c2Ugb2YgZmxvYXRpbmcgcG9pbnQgbWF0aCBlcnJvcnMgKGlzc3VlICMxODY3KVxuICAgICAgICAgICAgZGF5cyA9IHRoaXMuX2RheXMgKyBNYXRoLnJvdW5kKG1vbnRoc1RvRGF5cyh0aGlzLl9tb250aHMpKTtcbiAgICAgICAgICAgIHN3aXRjaCAodW5pdHMpIHtcbiAgICAgICAgICAgICAgICBjYXNlICd3ZWVrJyAgIDogcmV0dXJuIGRheXMgLyA3ICAgICArIG1pbGxpc2Vjb25kcyAvIDYwNDhlNTtcbiAgICAgICAgICAgICAgICBjYXNlICdkYXknICAgIDogcmV0dXJuIGRheXMgICAgICAgICArIG1pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgICAgIGNhc2UgJ2hvdXInICAgOiByZXR1cm4gZGF5cyAqIDI0ICAgICsgbWlsbGlzZWNvbmRzIC8gMzZlNTtcbiAgICAgICAgICAgICAgICBjYXNlICdtaW51dGUnIDogcmV0dXJuIGRheXMgKiAxNDQwICArIG1pbGxpc2Vjb25kcyAvIDZlNDtcbiAgICAgICAgICAgICAgICBjYXNlICdzZWNvbmQnIDogcmV0dXJuIGRheXMgKiA4NjQwMCArIG1pbGxpc2Vjb25kcyAvIDEwMDA7XG4gICAgICAgICAgICAgICAgLy8gTWF0aC5mbG9vciBwcmV2ZW50cyBmbG9hdGluZyBwb2ludCBtYXRoIGVycm9ycyBoZXJlXG4gICAgICAgICAgICAgICAgY2FzZSAnbWlsbGlzZWNvbmQnOiByZXR1cm4gTWF0aC5mbG9vcihkYXlzICogODY0ZTUpICsgbWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcignVW5rbm93biB1bml0ICcgKyB1bml0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPOiBVc2UgdGhpcy5hcygnbXMnKT9cbiAgICBmdW5jdGlvbiB2YWx1ZU9mJDEgKCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgK1xuICAgICAgICAgICAgdGhpcy5fZGF5cyAqIDg2NGU1ICtcbiAgICAgICAgICAgICh0aGlzLl9tb250aHMgJSAxMikgKiAyNTkyZTYgK1xuICAgICAgICAgICAgdG9JbnQodGhpcy5fbW9udGhzIC8gMTIpICogMzE1MzZlNlxuICAgICAgICApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VBcyAoYWxpYXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFzKGFsaWFzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgYXNNaWxsaXNlY29uZHMgPSBtYWtlQXMoJ21zJyk7XG4gICAgdmFyIGFzU2Vjb25kcyAgICAgID0gbWFrZUFzKCdzJyk7XG4gICAgdmFyIGFzTWludXRlcyAgICAgID0gbWFrZUFzKCdtJyk7XG4gICAgdmFyIGFzSG91cnMgICAgICAgID0gbWFrZUFzKCdoJyk7XG4gICAgdmFyIGFzRGF5cyAgICAgICAgID0gbWFrZUFzKCdkJyk7XG4gICAgdmFyIGFzV2Vla3MgICAgICAgID0gbWFrZUFzKCd3Jyk7XG4gICAgdmFyIGFzTW9udGhzICAgICAgID0gbWFrZUFzKCdNJyk7XG4gICAgdmFyIGFzUXVhcnRlcnMgICAgID0gbWFrZUFzKCdRJyk7XG4gICAgdmFyIGFzWWVhcnMgICAgICAgID0gbWFrZUFzKCd5Jyk7XG5cbiAgICBmdW5jdGlvbiBjbG9uZSQxICgpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKHRoaXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldCQyICh1bml0cykge1xuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpc1t1bml0cyArICdzJ10oKSA6IE5hTjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlR2V0dGVyKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmlzVmFsaWQoKSA/IHRoaXMuX2RhdGFbbmFtZV0gOiBOYU47XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIG1pbGxpc2Vjb25kcyA9IG1ha2VHZXR0ZXIoJ21pbGxpc2Vjb25kcycpO1xuICAgIHZhciBzZWNvbmRzICAgICAgPSBtYWtlR2V0dGVyKCdzZWNvbmRzJyk7XG4gICAgdmFyIG1pbnV0ZXMgICAgICA9IG1ha2VHZXR0ZXIoJ21pbnV0ZXMnKTtcbiAgICB2YXIgaG91cnMgICAgICAgID0gbWFrZUdldHRlcignaG91cnMnKTtcbiAgICB2YXIgZGF5cyAgICAgICAgID0gbWFrZUdldHRlcignZGF5cycpO1xuICAgIHZhciBtb250aHMgICAgICAgPSBtYWtlR2V0dGVyKCdtb250aHMnKTtcbiAgICB2YXIgeWVhcnMgICAgICAgID0gbWFrZUdldHRlcigneWVhcnMnKTtcblxuICAgIGZ1bmN0aW9uIHdlZWtzICgpIHtcbiAgICAgICAgcmV0dXJuIGFic0Zsb29yKHRoaXMuZGF5cygpIC8gNyk7XG4gICAgfVxuXG4gICAgdmFyIHJvdW5kID0gTWF0aC5yb3VuZDtcbiAgICB2YXIgdGhyZXNob2xkcyA9IHtcbiAgICAgICAgc3M6IDQ0LCAgICAgICAgIC8vIGEgZmV3IHNlY29uZHMgdG8gc2Vjb25kc1xuICAgICAgICBzIDogNDUsICAgICAgICAgLy8gc2Vjb25kcyB0byBtaW51dGVcbiAgICAgICAgbSA6IDQ1LCAgICAgICAgIC8vIG1pbnV0ZXMgdG8gaG91clxuICAgICAgICBoIDogMjIsICAgICAgICAgLy8gaG91cnMgdG8gZGF5XG4gICAgICAgIGQgOiAyNiwgICAgICAgICAvLyBkYXlzIHRvIG1vbnRoXG4gICAgICAgIE0gOiAxMSAgICAgICAgICAvLyBtb250aHMgdG8geWVhclxuICAgIH07XG5cbiAgICAvLyBoZWxwZXIgZnVuY3Rpb24gZm9yIG1vbWVudC5mbi5mcm9tLCBtb21lbnQuZm4uZnJvbU5vdywgYW5kIG1vbWVudC5kdXJhdGlvbi5mbi5odW1hbml6ZVxuICAgIGZ1bmN0aW9uIHN1YnN0aXR1dGVUaW1lQWdvKHN0cmluZywgbnVtYmVyLCB3aXRob3V0U3VmZml4LCBpc0Z1dHVyZSwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUucmVsYXRpdmVUaW1lKG51bWJlciB8fCAxLCAhIXdpdGhvdXRTdWZmaXgsIHN0cmluZywgaXNGdXR1cmUpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbGF0aXZlVGltZSQxIChwb3NOZWdEdXJhdGlvbiwgd2l0aG91dFN1ZmZpeCwgbG9jYWxlKSB7XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IGNyZWF0ZUR1cmF0aW9uKHBvc05lZ0R1cmF0aW9uKS5hYnMoKTtcbiAgICAgICAgdmFyIHNlY29uZHMgID0gcm91bmQoZHVyYXRpb24uYXMoJ3MnKSk7XG4gICAgICAgIHZhciBtaW51dGVzICA9IHJvdW5kKGR1cmF0aW9uLmFzKCdtJykpO1xuICAgICAgICB2YXIgaG91cnMgICAgPSByb3VuZChkdXJhdGlvbi5hcygnaCcpKTtcbiAgICAgICAgdmFyIGRheXMgICAgID0gcm91bmQoZHVyYXRpb24uYXMoJ2QnKSk7XG4gICAgICAgIHZhciBtb250aHMgICA9IHJvdW5kKGR1cmF0aW9uLmFzKCdNJykpO1xuICAgICAgICB2YXIgeWVhcnMgICAgPSByb3VuZChkdXJhdGlvbi5hcygneScpKTtcblxuICAgICAgICB2YXIgYSA9IHNlY29uZHMgPD0gdGhyZXNob2xkcy5zcyAmJiBbJ3MnLCBzZWNvbmRzXSAgfHxcbiAgICAgICAgICAgICAgICBzZWNvbmRzIDwgdGhyZXNob2xkcy5zICAgJiYgWydzcycsIHNlY29uZHNdIHx8XG4gICAgICAgICAgICAgICAgbWludXRlcyA8PSAxICAgICAgICAgICAgICYmIFsnbSddICAgICAgICAgICB8fFxuICAgICAgICAgICAgICAgIG1pbnV0ZXMgPCB0aHJlc2hvbGRzLm0gICAmJiBbJ21tJywgbWludXRlc10gfHxcbiAgICAgICAgICAgICAgICBob3VycyAgIDw9IDEgICAgICAgICAgICAgJiYgWydoJ10gICAgICAgICAgIHx8XG4gICAgICAgICAgICAgICAgaG91cnMgICA8IHRocmVzaG9sZHMuaCAgICYmIFsnaGgnLCBob3Vyc10gICB8fFxuICAgICAgICAgICAgICAgIGRheXMgICAgPD0gMSAgICAgICAgICAgICAmJiBbJ2QnXSAgICAgICAgICAgfHxcbiAgICAgICAgICAgICAgICBkYXlzICAgIDwgdGhyZXNob2xkcy5kICAgJiYgWydkZCcsIGRheXNdICAgIHx8XG4gICAgICAgICAgICAgICAgbW9udGhzICA8PSAxICAgICAgICAgICAgICYmIFsnTSddICAgICAgICAgICB8fFxuICAgICAgICAgICAgICAgIG1vbnRocyAgPCB0aHJlc2hvbGRzLk0gICAmJiBbJ01NJywgbW9udGhzXSAgfHxcbiAgICAgICAgICAgICAgICB5ZWFycyAgIDw9IDEgICAgICAgICAgICAgJiYgWyd5J10gICAgICAgICAgIHx8IFsneXknLCB5ZWFyc107XG5cbiAgICAgICAgYVsyXSA9IHdpdGhvdXRTdWZmaXg7XG4gICAgICAgIGFbM10gPSArcG9zTmVnRHVyYXRpb24gPiAwO1xuICAgICAgICBhWzRdID0gbG9jYWxlO1xuICAgICAgICByZXR1cm4gc3Vic3RpdHV0ZVRpbWVBZ28uYXBwbHkobnVsbCwgYSk7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHNldCB0aGUgcm91bmRpbmcgZnVuY3Rpb24gZm9yIHJlbGF0aXZlIHRpbWUgc3RyaW5nc1xuICAgIGZ1bmN0aW9uIGdldFNldFJlbGF0aXZlVGltZVJvdW5kaW5nIChyb3VuZGluZ0Z1bmN0aW9uKSB7XG4gICAgICAgIGlmIChyb3VuZGluZ0Z1bmN0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiByb3VuZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mKHJvdW5kaW5nRnVuY3Rpb24pID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByb3VuZCA9IHJvdW5kaW5nRnVuY3Rpb247XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHNldCBhIHRocmVzaG9sZCBmb3IgcmVsYXRpdmUgdGltZSBzdHJpbmdzXG4gICAgZnVuY3Rpb24gZ2V0U2V0UmVsYXRpdmVUaW1lVGhyZXNob2xkICh0aHJlc2hvbGQsIGxpbWl0KSB7XG4gICAgICAgIGlmICh0aHJlc2hvbGRzW3RocmVzaG9sZF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW1pdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhyZXNob2xkc1t0aHJlc2hvbGRdO1xuICAgICAgICB9XG4gICAgICAgIHRocmVzaG9sZHNbdGhyZXNob2xkXSA9IGxpbWl0O1xuICAgICAgICBpZiAodGhyZXNob2xkID09PSAncycpIHtcbiAgICAgICAgICAgIHRocmVzaG9sZHMuc3MgPSBsaW1pdCAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaHVtYW5pemUgKHdpdGhTdWZmaXgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLmludmFsaWREYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbG9jYWxlID0gdGhpcy5sb2NhbGVEYXRhKCk7XG4gICAgICAgIHZhciBvdXRwdXQgPSByZWxhdGl2ZVRpbWUkMSh0aGlzLCAhd2l0aFN1ZmZpeCwgbG9jYWxlKTtcblxuICAgICAgICBpZiAod2l0aFN1ZmZpeCkge1xuICAgICAgICAgICAgb3V0cHV0ID0gbG9jYWxlLnBhc3RGdXR1cmUoK3RoaXMsIG91dHB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbG9jYWxlLnBvc3Rmb3JtYXQob3V0cHV0KTtcbiAgICB9XG5cbiAgICB2YXIgYWJzJDEgPSBNYXRoLmFicztcblxuICAgIGZ1bmN0aW9uIHNpZ24oeCkge1xuICAgICAgICByZXR1cm4gKCh4ID4gMCkgLSAoeCA8IDApKSB8fCAreDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0lTT1N0cmluZyQxKCkge1xuICAgICAgICAvLyBmb3IgSVNPIHN0cmluZ3Mgd2UgZG8gbm90IHVzZSB0aGUgbm9ybWFsIGJ1YmJsaW5nIHJ1bGVzOlxuICAgICAgICAvLyAgKiBtaWxsaXNlY29uZHMgYnViYmxlIHVwIHVudGlsIHRoZXkgYmVjb21lIGhvdXJzXG4gICAgICAgIC8vICAqIGRheXMgZG8gbm90IGJ1YmJsZSBhdCBhbGxcbiAgICAgICAgLy8gICogbW9udGhzIGJ1YmJsZSB1cCB1bnRpbCB0aGV5IGJlY29tZSB5ZWFyc1xuICAgICAgICAvLyBUaGlzIGlzIGJlY2F1c2UgdGhlcmUgaXMgbm8gY29udGV4dC1mcmVlIGNvbnZlcnNpb24gYmV0d2VlbiBob3VycyBhbmQgZGF5c1xuICAgICAgICAvLyAodGhpbmsgb2YgY2xvY2sgY2hhbmdlcylcbiAgICAgICAgLy8gYW5kIGFsc28gbm90IGJldHdlZW4gZGF5cyBhbmQgbW9udGhzICgyOC0zMSBkYXlzIHBlciBtb250aClcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLmludmFsaWREYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc2Vjb25kcyA9IGFicyQxKHRoaXMuX21pbGxpc2Vjb25kcykgLyAxMDAwO1xuICAgICAgICB2YXIgZGF5cyAgICAgICAgID0gYWJzJDEodGhpcy5fZGF5cyk7XG4gICAgICAgIHZhciBtb250aHMgICAgICAgPSBhYnMkMSh0aGlzLl9tb250aHMpO1xuICAgICAgICB2YXIgbWludXRlcywgaG91cnMsIHllYXJzO1xuXG4gICAgICAgIC8vIDM2MDAgc2Vjb25kcyAtPiA2MCBtaW51dGVzIC0+IDEgaG91clxuICAgICAgICBtaW51dGVzICAgICAgICAgICA9IGFic0Zsb29yKHNlY29uZHMgLyA2MCk7XG4gICAgICAgIGhvdXJzICAgICAgICAgICAgID0gYWJzRmxvb3IobWludXRlcyAvIDYwKTtcbiAgICAgICAgc2Vjb25kcyAlPSA2MDtcbiAgICAgICAgbWludXRlcyAlPSA2MDtcblxuICAgICAgICAvLyAxMiBtb250aHMgLT4gMSB5ZWFyXG4gICAgICAgIHllYXJzICA9IGFic0Zsb29yKG1vbnRocyAvIDEyKTtcbiAgICAgICAgbW9udGhzICU9IDEyO1xuXG5cbiAgICAgICAgLy8gaW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2RvcmRpbGxlL21vbWVudC1pc29kdXJhdGlvbi9ibG9iL21hc3Rlci9tb21lbnQuaXNvZHVyYXRpb24uanNcbiAgICAgICAgdmFyIFkgPSB5ZWFycztcbiAgICAgICAgdmFyIE0gPSBtb250aHM7XG4gICAgICAgIHZhciBEID0gZGF5cztcbiAgICAgICAgdmFyIGggPSBob3VycztcbiAgICAgICAgdmFyIG0gPSBtaW51dGVzO1xuICAgICAgICB2YXIgcyA9IHNlY29uZHMgPyBzZWNvbmRzLnRvRml4ZWQoMykucmVwbGFjZSgvXFwuPzArJC8sICcnKSA6ICcnO1xuICAgICAgICB2YXIgdG90YWwgPSB0aGlzLmFzU2Vjb25kcygpO1xuXG4gICAgICAgIGlmICghdG90YWwpIHtcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgdGhlIHNhbWUgYXMgQyMncyAoTm9kYSkgYW5kIHB5dGhvbiAoaXNvZGF0ZSkuLi5cbiAgICAgICAgICAgIC8vIGJ1dCBub3Qgb3RoZXIgSlMgKGdvb2cuZGF0ZSlcbiAgICAgICAgICAgIHJldHVybiAnUDBEJztcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0b3RhbFNpZ24gPSB0b3RhbCA8IDAgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIHltU2lnbiA9IHNpZ24odGhpcy5fbW9udGhzKSAhPT0gc2lnbih0b3RhbCkgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIGRheXNTaWduID0gc2lnbih0aGlzLl9kYXlzKSAhPT0gc2lnbih0b3RhbCkgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIGhtc1NpZ24gPSBzaWduKHRoaXMuX21pbGxpc2Vjb25kcykgIT09IHNpZ24odG90YWwpID8gJy0nIDogJyc7XG5cbiAgICAgICAgcmV0dXJuIHRvdGFsU2lnbiArICdQJyArXG4gICAgICAgICAgICAoWSA/IHltU2lnbiArIFkgKyAnWScgOiAnJykgK1xuICAgICAgICAgICAgKE0gPyB5bVNpZ24gKyBNICsgJ00nIDogJycpICtcbiAgICAgICAgICAgIChEID8gZGF5c1NpZ24gKyBEICsgJ0QnIDogJycpICtcbiAgICAgICAgICAgICgoaCB8fCBtIHx8IHMpID8gJ1QnIDogJycpICtcbiAgICAgICAgICAgIChoID8gaG1zU2lnbiArIGggKyAnSCcgOiAnJykgK1xuICAgICAgICAgICAgKG0gPyBobXNTaWduICsgbSArICdNJyA6ICcnKSArXG4gICAgICAgICAgICAocyA/IGhtc1NpZ24gKyBzICsgJ1MnIDogJycpO1xuICAgIH1cblxuICAgIHZhciBwcm90byQyID0gRHVyYXRpb24ucHJvdG90eXBlO1xuXG4gICAgcHJvdG8kMi5pc1ZhbGlkICAgICAgICA9IGlzVmFsaWQkMTtcbiAgICBwcm90byQyLmFicyAgICAgICAgICAgID0gYWJzO1xuICAgIHByb3RvJDIuYWRkICAgICAgICAgICAgPSBhZGQkMTtcbiAgICBwcm90byQyLnN1YnRyYWN0ICAgICAgID0gc3VidHJhY3QkMTtcbiAgICBwcm90byQyLmFzICAgICAgICAgICAgID0gYXM7XG4gICAgcHJvdG8kMi5hc01pbGxpc2Vjb25kcyA9IGFzTWlsbGlzZWNvbmRzO1xuICAgIHByb3RvJDIuYXNTZWNvbmRzICAgICAgPSBhc1NlY29uZHM7XG4gICAgcHJvdG8kMi5hc01pbnV0ZXMgICAgICA9IGFzTWludXRlcztcbiAgICBwcm90byQyLmFzSG91cnMgICAgICAgID0gYXNIb3VycztcbiAgICBwcm90byQyLmFzRGF5cyAgICAgICAgID0gYXNEYXlzO1xuICAgIHByb3RvJDIuYXNXZWVrcyAgICAgICAgPSBhc1dlZWtzO1xuICAgIHByb3RvJDIuYXNNb250aHMgICAgICAgPSBhc01vbnRocztcbiAgICBwcm90byQyLmFzUXVhcnRlcnMgICAgID0gYXNRdWFydGVycztcbiAgICBwcm90byQyLmFzWWVhcnMgICAgICAgID0gYXNZZWFycztcbiAgICBwcm90byQyLnZhbHVlT2YgICAgICAgID0gdmFsdWVPZiQxO1xuICAgIHByb3RvJDIuX2J1YmJsZSAgICAgICAgPSBidWJibGU7XG4gICAgcHJvdG8kMi5jbG9uZSAgICAgICAgICA9IGNsb25lJDE7XG4gICAgcHJvdG8kMi5nZXQgICAgICAgICAgICA9IGdldCQyO1xuICAgIHByb3RvJDIubWlsbGlzZWNvbmRzICAgPSBtaWxsaXNlY29uZHM7XG4gICAgcHJvdG8kMi5zZWNvbmRzICAgICAgICA9IHNlY29uZHM7XG4gICAgcHJvdG8kMi5taW51dGVzICAgICAgICA9IG1pbnV0ZXM7XG4gICAgcHJvdG8kMi5ob3VycyAgICAgICAgICA9IGhvdXJzO1xuICAgIHByb3RvJDIuZGF5cyAgICAgICAgICAgPSBkYXlzO1xuICAgIHByb3RvJDIud2Vla3MgICAgICAgICAgPSB3ZWVrcztcbiAgICBwcm90byQyLm1vbnRocyAgICAgICAgID0gbW9udGhzO1xuICAgIHByb3RvJDIueWVhcnMgICAgICAgICAgPSB5ZWFycztcbiAgICBwcm90byQyLmh1bWFuaXplICAgICAgID0gaHVtYW5pemU7XG4gICAgcHJvdG8kMi50b0lTT1N0cmluZyAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi50b1N0cmluZyAgICAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi50b0pTT04gICAgICAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi5sb2NhbGUgICAgICAgICA9IGxvY2FsZTtcbiAgICBwcm90byQyLmxvY2FsZURhdGEgICAgID0gbG9jYWxlRGF0YTtcblxuICAgIHByb3RvJDIudG9Jc29TdHJpbmcgPSBkZXByZWNhdGUoJ3RvSXNvU3RyaW5nKCkgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSB0b0lTT1N0cmluZygpIGluc3RlYWQgKG5vdGljZSB0aGUgY2FwaXRhbHMpJywgdG9JU09TdHJpbmckMSk7XG4gICAgcHJvdG8kMi5sYW5nID0gbGFuZztcblxuICAgIC8vIFNpZGUgZWZmZWN0IGltcG9ydHNcblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdYJywgMCwgMCwgJ3VuaXgnKTtcbiAgICBhZGRGb3JtYXRUb2tlbigneCcsIDAsIDAsICd2YWx1ZU9mJyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCd4JywgbWF0Y2hTaWduZWQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1gnLCBtYXRjaFRpbWVzdGFtcCk7XG4gICAgYWRkUGFyc2VUb2tlbignWCcsIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2QgPSBuZXcgRGF0ZShwYXJzZUZsb2F0KGlucHV0LCAxMCkgKiAxMDAwKTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCd4JywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKHRvSW50KGlucHV0KSk7XG4gICAgfSk7XG5cbiAgICAvLyBTaWRlIGVmZmVjdCBpbXBvcnRzXG5cblxuICAgIGhvb2tzLnZlcnNpb24gPSAnMi4yNC4wJztcblxuICAgIHNldEhvb2tDYWxsYmFjayhjcmVhdGVMb2NhbCk7XG5cbiAgICBob29rcy5mbiAgICAgICAgICAgICAgICAgICAgPSBwcm90bztcbiAgICBob29rcy5taW4gICAgICAgICAgICAgICAgICAgPSBtaW47XG4gICAgaG9va3MubWF4ICAgICAgICAgICAgICAgICAgID0gbWF4O1xuICAgIGhvb2tzLm5vdyAgICAgICAgICAgICAgICAgICA9IG5vdztcbiAgICBob29rcy51dGMgICAgICAgICAgICAgICAgICAgPSBjcmVhdGVVVEM7XG4gICAgaG9va3MudW5peCAgICAgICAgICAgICAgICAgID0gY3JlYXRlVW5peDtcbiAgICBob29rcy5tb250aHMgICAgICAgICAgICAgICAgPSBsaXN0TW9udGhzO1xuICAgIGhvb2tzLmlzRGF0ZSAgICAgICAgICAgICAgICA9IGlzRGF0ZTtcbiAgICBob29rcy5sb2NhbGUgICAgICAgICAgICAgICAgPSBnZXRTZXRHbG9iYWxMb2NhbGU7XG4gICAgaG9va3MuaW52YWxpZCAgICAgICAgICAgICAgID0gY3JlYXRlSW52YWxpZDtcbiAgICBob29rcy5kdXJhdGlvbiAgICAgICAgICAgICAgPSBjcmVhdGVEdXJhdGlvbjtcbiAgICBob29rcy5pc01vbWVudCAgICAgICAgICAgICAgPSBpc01vbWVudDtcbiAgICBob29rcy53ZWVrZGF5cyAgICAgICAgICAgICAgPSBsaXN0V2Vla2RheXM7XG4gICAgaG9va3MucGFyc2Vab25lICAgICAgICAgICAgID0gY3JlYXRlSW5ab25lO1xuICAgIGhvb2tzLmxvY2FsZURhdGEgICAgICAgICAgICA9IGdldExvY2FsZTtcbiAgICBob29rcy5pc0R1cmF0aW9uICAgICAgICAgICAgPSBpc0R1cmF0aW9uO1xuICAgIGhvb2tzLm1vbnRoc1Nob3J0ICAgICAgICAgICA9IGxpc3RNb250aHNTaG9ydDtcbiAgICBob29rcy53ZWVrZGF5c01pbiAgICAgICAgICAgPSBsaXN0V2Vla2RheXNNaW47XG4gICAgaG9va3MuZGVmaW5lTG9jYWxlICAgICAgICAgID0gZGVmaW5lTG9jYWxlO1xuICAgIGhvb2tzLnVwZGF0ZUxvY2FsZSAgICAgICAgICA9IHVwZGF0ZUxvY2FsZTtcbiAgICBob29rcy5sb2NhbGVzICAgICAgICAgICAgICAgPSBsaXN0TG9jYWxlcztcbiAgICBob29rcy53ZWVrZGF5c1Nob3J0ICAgICAgICAgPSBsaXN0V2Vla2RheXNTaG9ydDtcbiAgICBob29rcy5ub3JtYWxpemVVbml0cyAgICAgICAgPSBub3JtYWxpemVVbml0cztcbiAgICBob29rcy5yZWxhdGl2ZVRpbWVSb3VuZGluZyAgPSBnZXRTZXRSZWxhdGl2ZVRpbWVSb3VuZGluZztcbiAgICBob29rcy5yZWxhdGl2ZVRpbWVUaHJlc2hvbGQgPSBnZXRTZXRSZWxhdGl2ZVRpbWVUaHJlc2hvbGQ7XG4gICAgaG9va3MuY2FsZW5kYXJGb3JtYXQgICAgICAgID0gZ2V0Q2FsZW5kYXJGb3JtYXQ7XG4gICAgaG9va3MucHJvdG90eXBlICAgICAgICAgICAgID0gcHJvdG87XG5cbiAgICAvLyBjdXJyZW50bHkgSFRNTDUgaW5wdXQgdHlwZSBvbmx5IHN1cHBvcnRzIDI0LWhvdXIgZm9ybWF0c1xuICAgIGhvb2tzLkhUTUw1X0ZNVCA9IHtcbiAgICAgICAgREFURVRJTUVfTE9DQUw6ICdZWVlZLU1NLUREVEhIOm1tJywgICAgICAgICAgICAgLy8gPGlucHV0IHR5cGU9XCJkYXRldGltZS1sb2NhbFwiIC8+XG4gICAgICAgIERBVEVUSU1FX0xPQ0FMX1NFQ09ORFM6ICdZWVlZLU1NLUREVEhIOm1tOnNzJywgIC8vIDxpbnB1dCB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIiBzdGVwPVwiMVwiIC8+XG4gICAgICAgIERBVEVUSU1FX0xPQ0FMX01TOiAnWVlZWS1NTS1ERFRISDptbTpzcy5TU1MnLCAgIC8vIDxpbnB1dCB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIiBzdGVwPVwiMC4wMDFcIiAvPlxuICAgICAgICBEQVRFOiAnWVlZWS1NTS1ERCcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cImRhdGVcIiAvPlxuICAgICAgICBUSU1FOiAnSEg6bW0nLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cInRpbWVcIiAvPlxuICAgICAgICBUSU1FX1NFQ09ORFM6ICdISDptbTpzcycsICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cInRpbWVcIiBzdGVwPVwiMVwiIC8+XG4gICAgICAgIFRJTUVfTVM6ICdISDptbTpzcy5TU1MnLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwidGltZVwiIHN0ZXA9XCIwLjAwMVwiIC8+XG4gICAgICAgIFdFRUs6ICdHR0dHLVtXXVdXJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwid2Vla1wiIC8+XG4gICAgICAgIE1PTlRIOiAnWVlZWS1NTScgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwibW9udGhcIiAvPlxuICAgIH07XG5cbiAgICByZXR1cm4gaG9va3M7XG5cbn0pKSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///da01\n")}}]);

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.moment"],{da01:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js\n\n;(function (global, factory) {\n     true ? module.exports = factory() :\n    undefined\n}(this, (function () { 'use strict';\n\n    var hookCallback;\n\n    function hooks () {\n        return hookCallback.apply(null, arguments);\n    }\n\n    // This is done to register the method called with moment()\n    // without creating circular dependencies.\n    function setHookCallback (callback) {\n        hookCallback = callback;\n    }\n\n    function isArray(input) {\n        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';\n    }\n\n    function isObject(input) {\n        // IE8 will treat undefined and null as object if it wasn't for\n        // input != null\n        return input != null && Object.prototype.toString.call(input) === '[object Object]';\n    }\n\n    function isObjectEmpty(obj) {\n        if (Object.getOwnPropertyNames) {\n            return (Object.getOwnPropertyNames(obj).length === 0);\n        } else {\n            var k;\n            for (k in obj) {\n                if (obj.hasOwnProperty(k)) {\n                    return false;\n                }\n            }\n            return true;\n        }\n    }\n\n    function isUndefined(input) {\n        return input === void 0;\n    }\n\n    function isNumber(input) {\n        return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';\n    }\n\n    function isDate(input) {\n        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';\n    }\n\n    function map(arr, fn) {\n        var res = [], i;\n        for (i = 0; i < arr.length; ++i) {\n            res.push(fn(arr[i], i));\n        }\n        return res;\n    }\n\n    function hasOwnProp(a, b) {\n        return Object.prototype.hasOwnProperty.call(a, b);\n    }\n\n    function extend(a, b) {\n        for (var i in b) {\n            if (hasOwnProp(b, i)) {\n                a[i] = b[i];\n            }\n        }\n\n        if (hasOwnProp(b, 'toString')) {\n            a.toString = b.toString;\n        }\n\n        if (hasOwnProp(b, 'valueOf')) {\n            a.valueOf = b.valueOf;\n        }\n\n        return a;\n    }\n\n    function createUTC (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, true).utc();\n    }\n\n    function defaultParsingFlags() {\n        // We need to deep clone this object.\n        return {\n            empty           : false,\n            unusedTokens    : [],\n            unusedInput     : [],\n            overflow        : -2,\n            charsLeftOver   : 0,\n            nullInput       : false,\n            invalidMonth    : null,\n            invalidFormat   : false,\n            userInvalidated : false,\n            iso             : false,\n            parsedDateParts : [],\n            meridiem        : null,\n            rfc2822         : false,\n            weekdayMismatch : false\n        };\n    }\n\n    function getParsingFlags(m) {\n        if (m._pf == null) {\n            m._pf = defaultParsingFlags();\n        }\n        return m._pf;\n    }\n\n    var some;\n    if (Array.prototype.some) {\n        some = Array.prototype.some;\n    } else {\n        some = function (fun) {\n            var t = Object(this);\n            var len = t.length >>> 0;\n\n            for (var i = 0; i < len; i++) {\n                if (i in t && fun.call(this, t[i], i, t)) {\n                    return true;\n                }\n            }\n\n            return false;\n        };\n    }\n\n    function isValid(m) {\n        if (m._isValid == null) {\n            var flags = getParsingFlags(m);\n            var parsedParts = some.call(flags.parsedDateParts, function (i) {\n                return i != null;\n            });\n            var isNowValid = !isNaN(m._d.getTime()) &&\n                flags.overflow < 0 &&\n                !flags.empty &&\n                !flags.invalidMonth &&\n                !flags.invalidWeekday &&\n                !flags.weekdayMismatch &&\n                !flags.nullInput &&\n                !flags.invalidFormat &&\n                !flags.userInvalidated &&\n                (!flags.meridiem || (flags.meridiem && parsedParts));\n\n            if (m._strict) {\n                isNowValid = isNowValid &&\n                    flags.charsLeftOver === 0 &&\n                    flags.unusedTokens.length === 0 &&\n                    flags.bigHour === undefined;\n            }\n\n            if (Object.isFrozen == null || !Object.isFrozen(m)) {\n                m._isValid = isNowValid;\n            }\n            else {\n                return isNowValid;\n            }\n        }\n        return m._isValid;\n    }\n\n    function createInvalid (flags) {\n        var m = createUTC(NaN);\n        if (flags != null) {\n            extend(getParsingFlags(m), flags);\n        }\n        else {\n            getParsingFlags(m).userInvalidated = true;\n        }\n\n        return m;\n    }\n\n    // Plugins that add properties should also add the key here (null value),\n    // so we can properly clone ourselves.\n    var momentProperties = hooks.momentProperties = [];\n\n    function copyConfig(to, from) {\n        var i, prop, val;\n\n        if (!isUndefined(from._isAMomentObject)) {\n            to._isAMomentObject = from._isAMomentObject;\n        }\n        if (!isUndefined(from._i)) {\n            to._i = from._i;\n        }\n        if (!isUndefined(from._f)) {\n            to._f = from._f;\n        }\n        if (!isUndefined(from._l)) {\n            to._l = from._l;\n        }\n        if (!isUndefined(from._strict)) {\n            to._strict = from._strict;\n        }\n        if (!isUndefined(from._tzm)) {\n            to._tzm = from._tzm;\n        }\n        if (!isUndefined(from._isUTC)) {\n            to._isUTC = from._isUTC;\n        }\n        if (!isUndefined(from._offset)) {\n            to._offset = from._offset;\n        }\n        if (!isUndefined(from._pf)) {\n            to._pf = getParsingFlags(from);\n        }\n        if (!isUndefined(from._locale)) {\n            to._locale = from._locale;\n        }\n\n        if (momentProperties.length > 0) {\n            for (i = 0; i < momentProperties.length; i++) {\n                prop = momentProperties[i];\n                val = from[prop];\n                if (!isUndefined(val)) {\n                    to[prop] = val;\n                }\n            }\n        }\n\n        return to;\n    }\n\n    var updateInProgress = false;\n\n    // Moment prototype object\n    function Moment(config) {\n        copyConfig(this, config);\n        this._d = new Date(config._d != null ? config._d.getTime() : NaN);\n        if (!this.isValid()) {\n            this._d = new Date(NaN);\n        }\n        // Prevent infinite loop in case updateOffset creates new moment\n        // objects.\n        if (updateInProgress === false) {\n            updateInProgress = true;\n            hooks.updateOffset(this);\n            updateInProgress = false;\n        }\n    }\n\n    function isMoment (obj) {\n        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);\n    }\n\n    function absFloor (number) {\n        if (number < 0) {\n            // -0 -> 0\n            return Math.ceil(number) || 0;\n        } else {\n            return Math.floor(number);\n        }\n    }\n\n    function toInt(argumentForCoercion) {\n        var coercedNumber = +argumentForCoercion,\n            value = 0;\n\n        if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n            value = absFloor(coercedNumber);\n        }\n\n        return value;\n    }\n\n    // compare two arrays, return the number of differences\n    function compareArrays(array1, array2, dontConvert) {\n        var len = Math.min(array1.length, array2.length),\n            lengthDiff = Math.abs(array1.length - array2.length),\n            diffs = 0,\n            i;\n        for (i = 0; i < len; i++) {\n            if ((dontConvert && array1[i] !== array2[i]) ||\n                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n                diffs++;\n            }\n        }\n        return diffs + lengthDiff;\n    }\n\n    function warn(msg) {\n        if (hooks.suppressDeprecationWarnings === false &&\n                (typeof console !==  'undefined') && console.warn) {\n            console.warn('Deprecation warning: ' + msg);\n        }\n    }\n\n    function deprecate(msg, fn) {\n        var firstTime = true;\n\n        return extend(function () {\n            if (hooks.deprecationHandler != null) {\n                hooks.deprecationHandler(null, msg);\n            }\n            if (firstTime) {\n                var args = [];\n                var arg;\n                for (var i = 0; i < arguments.length; i++) {\n                    arg = '';\n                    if (typeof arguments[i] === 'object') {\n                        arg += '\\n[' + i + '] ';\n                        for (var key in arguments[0]) {\n                            arg += key + ': ' + arguments[0][key] + ', ';\n                        }\n                        arg = arg.slice(0, -2); // Remove trailing comma and space\n                    } else {\n                        arg = arguments[i];\n                    }\n                    args.push(arg);\n                }\n                warn(msg + '\\nArguments: ' + Array.prototype.slice.call(args).join('') + '\\n' + (new Error()).stack);\n                firstTime = false;\n            }\n            return fn.apply(this, arguments);\n        }, fn);\n    }\n\n    var deprecations = {};\n\n    function deprecateSimple(name, msg) {\n        if (hooks.deprecationHandler != null) {\n            hooks.deprecationHandler(name, msg);\n        }\n        if (!deprecations[name]) {\n            warn(msg);\n            deprecations[name] = true;\n        }\n    }\n\n    hooks.suppressDeprecationWarnings = false;\n    hooks.deprecationHandler = null;\n\n    function isFunction(input) {\n        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';\n    }\n\n    function set (config) {\n        var prop, i;\n        for (i in config) {\n            prop = config[i];\n            if (isFunction(prop)) {\n                this[i] = prop;\n            } else {\n                this['_' + i] = prop;\n            }\n        }\n        this._config = config;\n        // Lenient ordinal parsing accepts just a number in addition to\n        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.\n        // TODO: Remove \"ordinalParse\" fallback in next major release.\n        this._dayOfMonthOrdinalParseLenient = new RegExp(\n            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +\n                '|' + (/\\d{1,2}/).source);\n    }\n\n    function mergeConfigs(parentConfig, childConfig) {\n        var res = extend({}, parentConfig), prop;\n        for (prop in childConfig) {\n            if (hasOwnProp(childConfig, prop)) {\n                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {\n                    res[prop] = {};\n                    extend(res[prop], parentConfig[prop]);\n                    extend(res[prop], childConfig[prop]);\n                } else if (childConfig[prop] != null) {\n                    res[prop] = childConfig[prop];\n                } else {\n                    delete res[prop];\n                }\n            }\n        }\n        for (prop in parentConfig) {\n            if (hasOwnProp(parentConfig, prop) &&\n                    !hasOwnProp(childConfig, prop) &&\n                    isObject(parentConfig[prop])) {\n                // make sure changes to properties don't modify parent config\n                res[prop] = extend({}, res[prop]);\n            }\n        }\n        return res;\n    }\n\n    function Locale(config) {\n        if (config != null) {\n            this.set(config);\n        }\n    }\n\n    var keys;\n\n    if (Object.keys) {\n        keys = Object.keys;\n    } else {\n        keys = function (obj) {\n            var i, res = [];\n            for (i in obj) {\n                if (hasOwnProp(obj, i)) {\n                    res.push(i);\n                }\n            }\n            return res;\n        };\n    }\n\n    var defaultCalendar = {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    };\n\n    function calendar (key, mom, now) {\n        var output = this._calendar[key] || this._calendar['sameElse'];\n        return isFunction(output) ? output.call(mom, now) : output;\n    }\n\n    var defaultLongDateFormat = {\n        LTS  : 'h:mm:ss A',\n        LT   : 'h:mm A',\n        L    : 'MM/DD/YYYY',\n        LL   : 'MMMM D, YYYY',\n        LLL  : 'MMMM D, YYYY h:mm A',\n        LLLL : 'dddd, MMMM D, YYYY h:mm A'\n    };\n\n    function longDateFormat (key) {\n        var format = this._longDateFormat[key],\n            formatUpper = this._longDateFormat[key.toUpperCase()];\n\n        if (format || !formatUpper) {\n            return format;\n        }\n\n        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {\n            return val.slice(1);\n        });\n\n        return this._longDateFormat[key];\n    }\n\n    var defaultInvalidDate = 'Invalid date';\n\n    function invalidDate () {\n        return this._invalidDate;\n    }\n\n    var defaultOrdinal = '%d';\n    var defaultDayOfMonthOrdinalParse = /\\d{1,2}/;\n\n    function ordinal (number) {\n        return this._ordinal.replace('%d', number);\n    }\n\n    var defaultRelativeTime = {\n        future : 'in %s',\n        past   : '%s ago',\n        s  : 'a few seconds',\n        ss : '%d seconds',\n        m  : 'a minute',\n        mm : '%d minutes',\n        h  : 'an hour',\n        hh : '%d hours',\n        d  : 'a day',\n        dd : '%d days',\n        M  : 'a month',\n        MM : '%d months',\n        y  : 'a year',\n        yy : '%d years'\n    };\n\n    function relativeTime (number, withoutSuffix, string, isFuture) {\n        var output = this._relativeTime[string];\n        return (isFunction(output)) ?\n            output(number, withoutSuffix, string, isFuture) :\n            output.replace(/%d/i, number);\n    }\n\n    function pastFuture (diff, output) {\n        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n        return isFunction(format) ? format(output) : format.replace(/%s/i, output);\n    }\n\n    var aliases = {};\n\n    function addUnitAlias (unit, shorthand) {\n        var lowerCase = unit.toLowerCase();\n        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n    }\n\n    function normalizeUnits(units) {\n        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n    }\n\n    function normalizeObjectUnits(inputObject) {\n        var normalizedInput = {},\n            normalizedProp,\n            prop;\n\n        for (prop in inputObject) {\n            if (hasOwnProp(inputObject, prop)) {\n                normalizedProp = normalizeUnits(prop);\n                if (normalizedProp) {\n                    normalizedInput[normalizedProp] = inputObject[prop];\n                }\n            }\n        }\n\n        return normalizedInput;\n    }\n\n    var priorities = {};\n\n    function addUnitPriority(unit, priority) {\n        priorities[unit] = priority;\n    }\n\n    function getPrioritizedUnits(unitsObj) {\n        var units = [];\n        for (var u in unitsObj) {\n            units.push({unit: u, priority: priorities[u]});\n        }\n        units.sort(function (a, b) {\n            return a.priority - b.priority;\n        });\n        return units;\n    }\n\n    function zeroFill(number, targetLength, forceSign) {\n        var absNumber = '' + Math.abs(number),\n            zerosToFill = targetLength - absNumber.length,\n            sign = number >= 0;\n        return (sign ? (forceSign ? '+' : '') : '-') +\n            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;\n    }\n\n    var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;\n\n    var localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\n    var formatFunctions = {};\n\n    var formatTokenFunctions = {};\n\n    // token:    'M'\n    // padded:   ['MM', 2]\n    // ordinal:  'Mo'\n    // callback: function () { this.month() + 1 }\n    function addFormatToken (token, padded, ordinal, callback) {\n        var func = callback;\n        if (typeof callback === 'string') {\n            func = function () {\n                return this[callback]();\n            };\n        }\n        if (token) {\n            formatTokenFunctions[token] = func;\n        }\n        if (padded) {\n            formatTokenFunctions[padded[0]] = function () {\n                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n            };\n        }\n        if (ordinal) {\n            formatTokenFunctions[ordinal] = function () {\n                return this.localeData().ordinal(func.apply(this, arguments), token);\n            };\n        }\n    }\n\n    function removeFormattingTokens(input) {\n        if (input.match(/\\[[\\s\\S]/)) {\n            return input.replace(/^\\[|\\]$/g, '');\n        }\n        return input.replace(/\\\\/g, '');\n    }\n\n    function makeFormatFunction(format) {\n        var array = format.match(formattingTokens), i, length;\n\n        for (i = 0, length = array.length; i < length; i++) {\n            if (formatTokenFunctions[array[i]]) {\n                array[i] = formatTokenFunctions[array[i]];\n            } else {\n                array[i] = removeFormattingTokens(array[i]);\n            }\n        }\n\n        return function (mom) {\n            var output = '', i;\n            for (i = 0; i < length; i++) {\n                output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];\n            }\n            return output;\n        };\n    }\n\n    // format date using native date object\n    function formatMoment(m, format) {\n        if (!m.isValid()) {\n            return m.localeData().invalidDate();\n        }\n\n        format = expandFormat(format, m.localeData());\n        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);\n\n        return formatFunctions[format](m);\n    }\n\n    function expandFormat(format, locale) {\n        var i = 5;\n\n        function replaceLongDateFormatTokens(input) {\n            return locale.longDateFormat(input) || input;\n        }\n\n        localFormattingTokens.lastIndex = 0;\n        while (i >= 0 && localFormattingTokens.test(format)) {\n            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n            localFormattingTokens.lastIndex = 0;\n            i -= 1;\n        }\n\n        return format;\n    }\n\n    var match1         = /\\d/;            //       0 - 9\n    var match2         = /\\d\\d/;          //      00 - 99\n    var match3         = /\\d{3}/;         //     000 - 999\n    var match4         = /\\d{4}/;         //    0000 - 9999\n    var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\n    var match1to2      = /\\d\\d?/;         //       0 - 99\n    var match3to4      = /\\d\\d\\d\\d?/;     //     999 - 9999\n    var match5to6      = /\\d\\d\\d\\d\\d\\d?/; //   99999 - 999999\n    var match1to3      = /\\d{1,3}/;       //       0 - 999\n    var match1to4      = /\\d{1,4}/;       //       0 - 9999\n    var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\n    var matchUnsigned  = /\\d+/;           //       0 - inf\n    var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\n    var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n    var matchShortOffset = /Z|[+-]\\d\\d(?::?\\d\\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z\n\n    var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n\n    // any word (or two) characters or numbers including two/three word month in arabic.\n    // includes scottish gaelic two word and hyphenated months\n    var matchWord = /[0-9]{0,256}['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFF07\\uFF10-\\uFFEF]{1,256}|[\\u0600-\\u06FF\\/]{1,256}(\\s*?[\\u0600-\\u06FF]{1,256}){1,2}/i;\n\n    var regexes = {};\n\n    function addRegexToken (token, regex, strictRegex) {\n        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {\n            return (isStrict && strictRegex) ? strictRegex : regex;\n        };\n    }\n\n    function getParseRegexForToken (token, config) {\n        if (!hasOwnProp(regexes, token)) {\n            return new RegExp(unescapeFormat(token));\n        }\n\n        return regexes[token](config._strict, config._locale);\n    }\n\n    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\n    function unescapeFormat(s) {\n        return regexEscape(s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n            return p1 || p2 || p3 || p4;\n        }));\n    }\n\n    function regexEscape(s) {\n        return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n    }\n\n    var tokens = {};\n\n    function addParseToken (token, callback) {\n        var i, func = callback;\n        if (typeof token === 'string') {\n            token = [token];\n        }\n        if (isNumber(callback)) {\n            func = function (input, array) {\n                array[callback] = toInt(input);\n            };\n        }\n        for (i = 0; i < token.length; i++) {\n            tokens[token[i]] = func;\n        }\n    }\n\n    function addWeekParseToken (token, callback) {\n        addParseToken(token, function (input, array, config, token) {\n            config._w = config._w || {};\n            callback(input, config._w, config, token);\n        });\n    }\n\n    function addTimeToArrayFromToken(token, input, config) {\n        if (input != null && hasOwnProp(tokens, token)) {\n            tokens[token](input, config._a, config, token);\n        }\n    }\n\n    var YEAR = 0;\n    var MONTH = 1;\n    var DATE = 2;\n    var HOUR = 3;\n    var MINUTE = 4;\n    var SECOND = 5;\n    var MILLISECOND = 6;\n    var WEEK = 7;\n    var WEEKDAY = 8;\n\n    // FORMATTING\n\n    addFormatToken('Y', 0, 0, function () {\n        var y = this.year();\n        return y <= 9999 ? '' + y : '+' + y;\n    });\n\n    addFormatToken(0, ['YY', 2], 0, function () {\n        return this.year() % 100;\n    });\n\n    addFormatToken(0, ['YYYY',   4],       0, 'year');\n    addFormatToken(0, ['YYYYY',  5],       0, 'year');\n    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n    // ALIASES\n\n    addUnitAlias('year', 'y');\n\n    // PRIORITIES\n\n    addUnitPriority('year', 1);\n\n    // PARSING\n\n    addRegexToken('Y',      matchSigned);\n    addRegexToken('YY',     match1to2, match2);\n    addRegexToken('YYYY',   match1to4, match4);\n    addRegexToken('YYYYY',  match1to6, match6);\n    addRegexToken('YYYYYY', match1to6, match6);\n\n    addParseToken(['YYYYY', 'YYYYYY'], YEAR);\n    addParseToken('YYYY', function (input, array) {\n        array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);\n    });\n    addParseToken('YY', function (input, array) {\n        array[YEAR] = hooks.parseTwoDigitYear(input);\n    });\n    addParseToken('Y', function (input, array) {\n        array[YEAR] = parseInt(input, 10);\n    });\n\n    // HELPERS\n\n    function daysInYear(year) {\n        return isLeapYear(year) ? 366 : 365;\n    }\n\n    function isLeapYear(year) {\n        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n    }\n\n    // HOOKS\n\n    hooks.parseTwoDigitYear = function (input) {\n        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n    };\n\n    // MOMENTS\n\n    var getSetYear = makeGetSet('FullYear', true);\n\n    function getIsLeapYear () {\n        return isLeapYear(this.year());\n    }\n\n    function makeGetSet (unit, keepTime) {\n        return function (value) {\n            if (value != null) {\n                set$1(this, unit, value);\n                hooks.updateOffset(this, keepTime);\n                return this;\n            } else {\n                return get(this, unit);\n            }\n        };\n    }\n\n    function get (mom, unit) {\n        return mom.isValid() ?\n            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;\n    }\n\n    function set$1 (mom, unit, value) {\n        if (mom.isValid() && !isNaN(value)) {\n            if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {\n                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));\n            }\n            else {\n                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function stringGet (units) {\n        units = normalizeUnits(units);\n        if (isFunction(this[units])) {\n            return this[units]();\n        }\n        return this;\n    }\n\n\n    function stringSet (units, value) {\n        if (typeof units === 'object') {\n            units = normalizeObjectUnits(units);\n            var prioritized = getPrioritizedUnits(units);\n            for (var i = 0; i < prioritized.length; i++) {\n                this[prioritized[i].unit](units[prioritized[i].unit]);\n            }\n        } else {\n            units = normalizeUnits(units);\n            if (isFunction(this[units])) {\n                return this[units](value);\n            }\n        }\n        return this;\n    }\n\n    function mod(n, x) {\n        return ((n % x) + x) % x;\n    }\n\n    var indexOf;\n\n    if (Array.prototype.indexOf) {\n        indexOf = Array.prototype.indexOf;\n    } else {\n        indexOf = function (o) {\n            // I know\n            var i;\n            for (i = 0; i < this.length; ++i) {\n                if (this[i] === o) {\n                    return i;\n                }\n            }\n            return -1;\n        };\n    }\n\n    function daysInMonth(year, month) {\n        if (isNaN(year) || isNaN(month)) {\n            return NaN;\n        }\n        var modMonth = mod(month, 12);\n        year += (month - modMonth) / 12;\n        return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);\n    }\n\n    // FORMATTING\n\n    addFormatToken('M', ['MM', 2], 'Mo', function () {\n        return this.month() + 1;\n    });\n\n    addFormatToken('MMM', 0, 0, function (format) {\n        return this.localeData().monthsShort(this, format);\n    });\n\n    addFormatToken('MMMM', 0, 0, function (format) {\n        return this.localeData().months(this, format);\n    });\n\n    // ALIASES\n\n    addUnitAlias('month', 'M');\n\n    // PRIORITY\n\n    addUnitPriority('month', 8);\n\n    // PARSING\n\n    addRegexToken('M',    match1to2);\n    addRegexToken('MM',   match1to2, match2);\n    addRegexToken('MMM',  function (isStrict, locale) {\n        return locale.monthsShortRegex(isStrict);\n    });\n    addRegexToken('MMMM', function (isStrict, locale) {\n        return locale.monthsRegex(isStrict);\n    });\n\n    addParseToken(['M', 'MM'], function (input, array) {\n        array[MONTH] = toInt(input) - 1;\n    });\n\n    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n        var month = config._locale.monthsParse(input, token, config._strict);\n        // if we didn't find a month name, mark the date as invalid.\n        if (month != null) {\n            array[MONTH] = month;\n        } else {\n            getParsingFlags(config).invalidMonth = input;\n        }\n    });\n\n    // LOCALES\n\n    var MONTHS_IN_FORMAT = /D[oD]?(\\[[^\\[\\]]*\\]|\\s)+MMMM?/;\n    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\n    function localeMonths (m, format) {\n        if (!m) {\n            return isArray(this._months) ? this._months :\n                this._months['standalone'];\n        }\n        return isArray(this._months) ? this._months[m.month()] :\n            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];\n    }\n\n    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\n    function localeMonthsShort (m, format) {\n        if (!m) {\n            return isArray(this._monthsShort) ? this._monthsShort :\n                this._monthsShort['standalone'];\n        }\n        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :\n            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];\n    }\n\n    function handleStrictParse(monthName, format, strict) {\n        var i, ii, mom, llc = monthName.toLocaleLowerCase();\n        if (!this._monthsParse) {\n            // this is not used\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n            for (i = 0; i < 12; ++i) {\n                mom = createUTC([2000, i]);\n                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();\n                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();\n            }\n        }\n\n        if (strict) {\n            if (format === 'MMM') {\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._longMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        } else {\n            if (format === 'MMM') {\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._longMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._longMonthsParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortMonthsParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        }\n    }\n\n    function localeMonthsParse (monthName, format, strict) {\n        var i, mom, regex;\n\n        if (this._monthsParseExact) {\n            return handleStrictParse.call(this, monthName, format, strict);\n        }\n\n        if (!this._monthsParse) {\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n        }\n\n        // TODO: add sorting\n        // Sorting makes sure if one month (or abbr) is a prefix of another\n        // see sorting in computeMonthsParse\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, i]);\n            if (strict && !this._longMonthsParse[i]) {\n                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n            }\n            if (!strict && !this._monthsParse[i]) {\n                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (!strict && this._monthsParse[i].test(monthName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function setMonth (mom, value) {\n        var dayOfMonth;\n\n        if (!mom.isValid()) {\n            // No op\n            return mom;\n        }\n\n        if (typeof value === 'string') {\n            if (/^\\d+$/.test(value)) {\n                value = toInt(value);\n            } else {\n                value = mom.localeData().monthsParse(value);\n                // TODO: Another silent failure?\n                if (!isNumber(value)) {\n                    return mom;\n                }\n            }\n        }\n\n        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n        return mom;\n    }\n\n    function getSetMonth (value) {\n        if (value != null) {\n            setMonth(this, value);\n            hooks.updateOffset(this, true);\n            return this;\n        } else {\n            return get(this, 'Month');\n        }\n    }\n\n    function getDaysInMonth () {\n        return daysInMonth(this.year(), this.month());\n    }\n\n    var defaultMonthsShortRegex = matchWord;\n    function monthsShortRegex (isStrict) {\n        if (this._monthsParseExact) {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                computeMonthsParse.call(this);\n            }\n            if (isStrict) {\n                return this._monthsShortStrictRegex;\n            } else {\n                return this._monthsShortRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_monthsShortRegex')) {\n                this._monthsShortRegex = defaultMonthsShortRegex;\n            }\n            return this._monthsShortStrictRegex && isStrict ?\n                this._monthsShortStrictRegex : this._monthsShortRegex;\n        }\n    }\n\n    var defaultMonthsRegex = matchWord;\n    function monthsRegex (isStrict) {\n        if (this._monthsParseExact) {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                computeMonthsParse.call(this);\n            }\n            if (isStrict) {\n                return this._monthsStrictRegex;\n            } else {\n                return this._monthsRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_monthsRegex')) {\n                this._monthsRegex = defaultMonthsRegex;\n            }\n            return this._monthsStrictRegex && isStrict ?\n                this._monthsStrictRegex : this._monthsRegex;\n        }\n    }\n\n    function computeMonthsParse () {\n        function cmpLenRev(a, b) {\n            return b.length - a.length;\n        }\n\n        var shortPieces = [], longPieces = [], mixedPieces = [],\n            i, mom;\n        for (i = 0; i < 12; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, i]);\n            shortPieces.push(this.monthsShort(mom, ''));\n            longPieces.push(this.months(mom, ''));\n            mixedPieces.push(this.months(mom, ''));\n            mixedPieces.push(this.monthsShort(mom, ''));\n        }\n        // Sorting makes sure if one month (or abbr) is a prefix of another it\n        // will match the longer piece.\n        shortPieces.sort(cmpLenRev);\n        longPieces.sort(cmpLenRev);\n        mixedPieces.sort(cmpLenRev);\n        for (i = 0; i < 12; i++) {\n            shortPieces[i] = regexEscape(shortPieces[i]);\n            longPieces[i] = regexEscape(longPieces[i]);\n        }\n        for (i = 0; i < 24; i++) {\n            mixedPieces[i] = regexEscape(mixedPieces[i]);\n        }\n\n        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n        this._monthsShortRegex = this._monthsRegex;\n        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n    }\n\n    function createDate (y, m, d, h, M, s, ms) {\n        // can't just apply() to create a date:\n        // https://stackoverflow.com/q/181348\n        var date;\n        // the date constructor remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            date = new Date(y + 400, m, d, h, M, s, ms);\n            if (isFinite(date.getFullYear())) {\n                date.setFullYear(y);\n            }\n        } else {\n            date = new Date(y, m, d, h, M, s, ms);\n        }\n\n        return date;\n    }\n\n    function createUTCDate (y) {\n        var date;\n        // the Date.UTC function remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            var args = Array.prototype.slice.call(arguments);\n            // preserve leap years using a full 400 year cycle, then reset\n            args[0] = y + 400;\n            date = new Date(Date.UTC.apply(null, args));\n            if (isFinite(date.getUTCFullYear())) {\n                date.setUTCFullYear(y);\n            }\n        } else {\n            date = new Date(Date.UTC.apply(null, arguments));\n        }\n\n        return date;\n    }\n\n    // start-of-first-week - start-of-year\n    function firstWeekOffset(year, dow, doy) {\n        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n            fwd = 7 + dow - doy,\n            // first-week day local weekday -- which local weekday is fwd\n            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;\n\n        return -fwdlw + fwd - 1;\n    }\n\n    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\n    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {\n        var localWeekday = (7 + weekday - dow) % 7,\n            weekOffset = firstWeekOffset(year, dow, doy),\n            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,\n            resYear, resDayOfYear;\n\n        if (dayOfYear <= 0) {\n            resYear = year - 1;\n            resDayOfYear = daysInYear(resYear) + dayOfYear;\n        } else if (dayOfYear > daysInYear(year)) {\n            resYear = year + 1;\n            resDayOfYear = dayOfYear - daysInYear(year);\n        } else {\n            resYear = year;\n            resDayOfYear = dayOfYear;\n        }\n\n        return {\n            year: resYear,\n            dayOfYear: resDayOfYear\n        };\n    }\n\n    function weekOfYear(mom, dow, doy) {\n        var weekOffset = firstWeekOffset(mom.year(), dow, doy),\n            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,\n            resWeek, resYear;\n\n        if (week < 1) {\n            resYear = mom.year() - 1;\n            resWeek = week + weeksInYear(resYear, dow, doy);\n        } else if (week > weeksInYear(mom.year(), dow, doy)) {\n            resWeek = week - weeksInYear(mom.year(), dow, doy);\n            resYear = mom.year() + 1;\n        } else {\n            resYear = mom.year();\n            resWeek = week;\n        }\n\n        return {\n            week: resWeek,\n            year: resYear\n        };\n    }\n\n    function weeksInYear(year, dow, doy) {\n        var weekOffset = firstWeekOffset(year, dow, doy),\n            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);\n        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;\n    }\n\n    // FORMATTING\n\n    addFormatToken('w', ['ww', 2], 'wo', 'week');\n    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n    // ALIASES\n\n    addUnitAlias('week', 'w');\n    addUnitAlias('isoWeek', 'W');\n\n    // PRIORITIES\n\n    addUnitPriority('week', 5);\n    addUnitPriority('isoWeek', 5);\n\n    // PARSING\n\n    addRegexToken('w',  match1to2);\n    addRegexToken('ww', match1to2, match2);\n    addRegexToken('W',  match1to2);\n    addRegexToken('WW', match1to2, match2);\n\n    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n        week[token.substr(0, 1)] = toInt(input);\n    });\n\n    // HELPERS\n\n    // LOCALES\n\n    function localeWeek (mom) {\n        return weekOfYear(mom, this._week.dow, this._week.doy).week;\n    }\n\n    var defaultLocaleWeek = {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 6th is the first week of the year.\n    };\n\n    function localeFirstDayOfWeek () {\n        return this._week.dow;\n    }\n\n    function localeFirstDayOfYear () {\n        return this._week.doy;\n    }\n\n    // MOMENTS\n\n    function getSetWeek (input) {\n        var week = this.localeData().week(this);\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    function getSetISOWeek (input) {\n        var week = weekOfYear(this, 1, 4).week;\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    // FORMATTING\n\n    addFormatToken('d', 0, 'do', 'day');\n\n    addFormatToken('dd', 0, 0, function (format) {\n        return this.localeData().weekdaysMin(this, format);\n    });\n\n    addFormatToken('ddd', 0, 0, function (format) {\n        return this.localeData().weekdaysShort(this, format);\n    });\n\n    addFormatToken('dddd', 0, 0, function (format) {\n        return this.localeData().weekdays(this, format);\n    });\n\n    addFormatToken('e', 0, 0, 'weekday');\n    addFormatToken('E', 0, 0, 'isoWeekday');\n\n    // ALIASES\n\n    addUnitAlias('day', 'd');\n    addUnitAlias('weekday', 'e');\n    addUnitAlias('isoWeekday', 'E');\n\n    // PRIORITY\n    addUnitPriority('day', 11);\n    addUnitPriority('weekday', 11);\n    addUnitPriority('isoWeekday', 11);\n\n    // PARSING\n\n    addRegexToken('d',    match1to2);\n    addRegexToken('e',    match1to2);\n    addRegexToken('E',    match1to2);\n    addRegexToken('dd',   function (isStrict, locale) {\n        return locale.weekdaysMinRegex(isStrict);\n    });\n    addRegexToken('ddd',   function (isStrict, locale) {\n        return locale.weekdaysShortRegex(isStrict);\n    });\n    addRegexToken('dddd',   function (isStrict, locale) {\n        return locale.weekdaysRegex(isStrict);\n    });\n\n    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {\n        var weekday = config._locale.weekdaysParse(input, token, config._strict);\n        // if we didn't get a weekday name, mark the date as invalid\n        if (weekday != null) {\n            week.d = weekday;\n        } else {\n            getParsingFlags(config).invalidWeekday = input;\n        }\n    });\n\n    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n        week[token] = toInt(input);\n    });\n\n    // HELPERS\n\n    function parseWeekday(input, locale) {\n        if (typeof input !== 'string') {\n            return input;\n        }\n\n        if (!isNaN(input)) {\n            return parseInt(input, 10);\n        }\n\n        input = locale.weekdaysParse(input);\n        if (typeof input === 'number') {\n            return input;\n        }\n\n        return null;\n    }\n\n    function parseIsoWeekday(input, locale) {\n        if (typeof input === 'string') {\n            return locale.weekdaysParse(input) % 7 || 7;\n        }\n        return isNaN(input) ? null : input;\n    }\n\n    // LOCALES\n    function shiftWeekdays (ws, n) {\n        return ws.slice(n, 7).concat(ws.slice(0, n));\n    }\n\n    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\n    function localeWeekdays (m, format) {\n        var weekdays = isArray(this._weekdays) ? this._weekdays :\n            this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone'];\n        return (m === true) ? shiftWeekdays(weekdays, this._week.dow)\n            : (m) ? weekdays[m.day()] : weekdays;\n    }\n\n    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\n    function localeWeekdaysShort (m) {\n        return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow)\n            : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;\n    }\n\n    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\n    function localeWeekdaysMin (m) {\n        return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow)\n            : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;\n    }\n\n    function handleStrictParse$1(weekdayName, format, strict) {\n        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n            this._shortWeekdaysParse = [];\n            this._minWeekdaysParse = [];\n\n            for (i = 0; i < 7; ++i) {\n                mom = createUTC([2000, 1]).day(i);\n                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();\n                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();\n                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();\n            }\n        }\n\n        if (strict) {\n            if (format === 'dddd') {\n                ii = indexOf.call(this._weekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else if (format === 'ddd') {\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        } else {\n            if (format === 'dddd') {\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else if (format === 'ddd') {\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            } else {\n                ii = indexOf.call(this._minWeekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._weekdaysParse, llc);\n                if (ii !== -1) {\n                    return ii;\n                }\n                ii = indexOf.call(this._shortWeekdaysParse, llc);\n                return ii !== -1 ? ii : null;\n            }\n        }\n    }\n\n    function localeWeekdaysParse (weekdayName, format, strict) {\n        var i, mom, regex;\n\n        if (this._weekdaysParseExact) {\n            return handleStrictParse$1.call(this, weekdayName, format, strict);\n        }\n\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n            this._minWeekdaysParse = [];\n            this._shortWeekdaysParse = [];\n            this._fullWeekdaysParse = [];\n        }\n\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n\n            mom = createUTC([2000, 1]).day(i);\n            if (strict && !this._fullWeekdaysParse[i]) {\n                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\\\.?') + '$', 'i');\n                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\\\.?') + '$', 'i');\n                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\\\.?') + '$', 'i');\n            }\n            if (!this._weekdaysParse[i]) {\n                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            // test the regex\n            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {\n                return i;\n            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {\n                return i;\n            }\n        }\n    }\n\n    // MOMENTS\n\n    function getSetDayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n        if (input != null) {\n            input = parseWeekday(input, this.localeData());\n            return this.add(input - day, 'd');\n        } else {\n            return day;\n        }\n    }\n\n    function getSetLocaleDayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n        return input == null ? weekday : this.add(input - weekday, 'd');\n    }\n\n    function getSetISODayOfWeek (input) {\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n\n        // behaves the same as moment#day except\n        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n        // as a setter, sunday should belong to the previous week.\n\n        if (input != null) {\n            var weekday = parseIsoWeekday(input, this.localeData());\n            return this.day(this.day() % 7 ? weekday : weekday - 7);\n        } else {\n            return this.day() || 7;\n        }\n    }\n\n    var defaultWeekdaysRegex = matchWord;\n    function weekdaysRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysStrictRegex;\n            } else {\n                return this._weekdaysRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                this._weekdaysRegex = defaultWeekdaysRegex;\n            }\n            return this._weekdaysStrictRegex && isStrict ?\n                this._weekdaysStrictRegex : this._weekdaysRegex;\n        }\n    }\n\n    var defaultWeekdaysShortRegex = matchWord;\n    function weekdaysShortRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysShortStrictRegex;\n            } else {\n                return this._weekdaysShortRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysShortRegex')) {\n                this._weekdaysShortRegex = defaultWeekdaysShortRegex;\n            }\n            return this._weekdaysShortStrictRegex && isStrict ?\n                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;\n        }\n    }\n\n    var defaultWeekdaysMinRegex = matchWord;\n    function weekdaysMinRegex (isStrict) {\n        if (this._weekdaysParseExact) {\n            if (!hasOwnProp(this, '_weekdaysRegex')) {\n                computeWeekdaysParse.call(this);\n            }\n            if (isStrict) {\n                return this._weekdaysMinStrictRegex;\n            } else {\n                return this._weekdaysMinRegex;\n            }\n        } else {\n            if (!hasOwnProp(this, '_weekdaysMinRegex')) {\n                this._weekdaysMinRegex = defaultWeekdaysMinRegex;\n            }\n            return this._weekdaysMinStrictRegex && isStrict ?\n                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;\n        }\n    }\n\n\n    function computeWeekdaysParse () {\n        function cmpLenRev(a, b) {\n            return b.length - a.length;\n        }\n\n        var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],\n            i, mom, minp, shortp, longp;\n        for (i = 0; i < 7; i++) {\n            // make the regex if we don't have it already\n            mom = createUTC([2000, 1]).day(i);\n            minp = this.weekdaysMin(mom, '');\n            shortp = this.weekdaysShort(mom, '');\n            longp = this.weekdays(mom, '');\n            minPieces.push(minp);\n            shortPieces.push(shortp);\n            longPieces.push(longp);\n            mixedPieces.push(minp);\n            mixedPieces.push(shortp);\n            mixedPieces.push(longp);\n        }\n        // Sorting makes sure if one weekday (or abbr) is a prefix of another it\n        // will match the longer piece.\n        minPieces.sort(cmpLenRev);\n        shortPieces.sort(cmpLenRev);\n        longPieces.sort(cmpLenRev);\n        mixedPieces.sort(cmpLenRev);\n        for (i = 0; i < 7; i++) {\n            shortPieces[i] = regexEscape(shortPieces[i]);\n            longPieces[i] = regexEscape(longPieces[i]);\n            mixedPieces[i] = regexEscape(mixedPieces[i]);\n        }\n\n        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');\n        this._weekdaysShortRegex = this._weekdaysRegex;\n        this._weekdaysMinRegex = this._weekdaysRegex;\n\n        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');\n        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');\n        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');\n    }\n\n    // FORMATTING\n\n    function hFormat() {\n        return this.hours() % 12 || 12;\n    }\n\n    function kFormat() {\n        return this.hours() || 24;\n    }\n\n    addFormatToken('H', ['HH', 2], 0, 'hour');\n    addFormatToken('h', ['hh', 2], 0, hFormat);\n    addFormatToken('k', ['kk', 2], 0, kFormat);\n\n    addFormatToken('hmm', 0, 0, function () {\n        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);\n    });\n\n    addFormatToken('hmmss', 0, 0, function () {\n        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +\n            zeroFill(this.seconds(), 2);\n    });\n\n    addFormatToken('Hmm', 0, 0, function () {\n        return '' + this.hours() + zeroFill(this.minutes(), 2);\n    });\n\n    addFormatToken('Hmmss', 0, 0, function () {\n        return '' + this.hours() + zeroFill(this.minutes(), 2) +\n            zeroFill(this.seconds(), 2);\n    });\n\n    function meridiem (token, lowercase) {\n        addFormatToken(token, 0, 0, function () {\n            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n        });\n    }\n\n    meridiem('a', true);\n    meridiem('A', false);\n\n    // ALIASES\n\n    addUnitAlias('hour', 'h');\n\n    // PRIORITY\n    addUnitPriority('hour', 13);\n\n    // PARSING\n\n    function matchMeridiem (isStrict, locale) {\n        return locale._meridiemParse;\n    }\n\n    addRegexToken('a',  matchMeridiem);\n    addRegexToken('A',  matchMeridiem);\n    addRegexToken('H',  match1to2);\n    addRegexToken('h',  match1to2);\n    addRegexToken('k',  match1to2);\n    addRegexToken('HH', match1to2, match2);\n    addRegexToken('hh', match1to2, match2);\n    addRegexToken('kk', match1to2, match2);\n\n    addRegexToken('hmm', match3to4);\n    addRegexToken('hmmss', match5to6);\n    addRegexToken('Hmm', match3to4);\n    addRegexToken('Hmmss', match5to6);\n\n    addParseToken(['H', 'HH'], HOUR);\n    addParseToken(['k', 'kk'], function (input, array, config) {\n        var kInput = toInt(input);\n        array[HOUR] = kInput === 24 ? 0 : kInput;\n    });\n    addParseToken(['a', 'A'], function (input, array, config) {\n        config._isPm = config._locale.isPM(input);\n        config._meridiem = input;\n    });\n    addParseToken(['h', 'hh'], function (input, array, config) {\n        array[HOUR] = toInt(input);\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('hmm', function (input, array, config) {\n        var pos = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos));\n        array[MINUTE] = toInt(input.substr(pos));\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('hmmss', function (input, array, config) {\n        var pos1 = input.length - 4;\n        var pos2 = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos1));\n        array[MINUTE] = toInt(input.substr(pos1, 2));\n        array[SECOND] = toInt(input.substr(pos2));\n        getParsingFlags(config).bigHour = true;\n    });\n    addParseToken('Hmm', function (input, array, config) {\n        var pos = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos));\n        array[MINUTE] = toInt(input.substr(pos));\n    });\n    addParseToken('Hmmss', function (input, array, config) {\n        var pos1 = input.length - 4;\n        var pos2 = input.length - 2;\n        array[HOUR] = toInt(input.substr(0, pos1));\n        array[MINUTE] = toInt(input.substr(pos1, 2));\n        array[SECOND] = toInt(input.substr(pos2));\n    });\n\n    // LOCALES\n\n    function localeIsPM (input) {\n        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n        // Using charAt should be more compatible.\n        return ((input + '').toLowerCase().charAt(0) === 'p');\n    }\n\n    var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\n    function localeMeridiem (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'pm' : 'PM';\n        } else {\n            return isLower ? 'am' : 'AM';\n        }\n    }\n\n\n    // MOMENTS\n\n    // Setting the hour should keep the time, because the user explicitly\n    // specified which hour they want. So trying to maintain the same hour (in\n    // a new timezone) makes sense. Adding/subtracting hours does not follow\n    // this rule.\n    var getSetHour = makeGetSet('Hours', true);\n\n    var baseConfig = {\n        calendar: defaultCalendar,\n        longDateFormat: defaultLongDateFormat,\n        invalidDate: defaultInvalidDate,\n        ordinal: defaultOrdinal,\n        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,\n        relativeTime: defaultRelativeTime,\n\n        months: defaultLocaleMonths,\n        monthsShort: defaultLocaleMonthsShort,\n\n        week: defaultLocaleWeek,\n\n        weekdays: defaultLocaleWeekdays,\n        weekdaysMin: defaultLocaleWeekdaysMin,\n        weekdaysShort: defaultLocaleWeekdaysShort,\n\n        meridiemParse: defaultLocaleMeridiemParse\n    };\n\n    // internal storage for locale config files\n    var locales = {};\n    var localeFamilies = {};\n    var globalLocale;\n\n    function normalizeLocale(key) {\n        return key ? key.toLowerCase().replace('_', '-') : key;\n    }\n\n    // pick the locale from the array\n    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\n    function chooseLocale(names) {\n        var i = 0, j, next, locale, split;\n\n        while (i < names.length) {\n            split = normalizeLocale(names[i]).split('-');\n            j = split.length;\n            next = normalizeLocale(names[i + 1]);\n            next = next ? next.split('-') : null;\n            while (j > 0) {\n                locale = loadLocale(split.slice(0, j).join('-'));\n                if (locale) {\n                    return locale;\n                }\n                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                    //the next array item is better than a shallower substring of this one\n                    break;\n                }\n                j--;\n            }\n            i++;\n        }\n        return globalLocale;\n    }\n\n    function loadLocale(name) {\n        var oldLocale = null;\n        // TODO: Find a better way to register and load all the locales in Node\n        if (!locales[name] && (typeof module !== 'undefined') &&\n                module && module.exports) {\n            try {\n                oldLocale = globalLocale._abbr;\n                var aliasedRequire = require;\n                !(function webpackMissingModule() { var e = new Error(\"Cannot find module 'undefined'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }());\n                getSetGlobalLocale(oldLocale);\n            } catch (e) {}\n        }\n        return locales[name];\n    }\n\n    // This function will load locale and then set the global locale.  If\n    // no arguments are passed in, it will simply return the current global\n    // locale key.\n    function getSetGlobalLocale (key, values) {\n        var data;\n        if (key) {\n            if (isUndefined(values)) {\n                data = getLocale(key);\n            }\n            else {\n                data = defineLocale(key, values);\n            }\n\n            if (data) {\n                // moment.duration._locale = moment._locale = data;\n                globalLocale = data;\n            }\n            else {\n                if ((typeof console !==  'undefined') && console.warn) {\n                    //warn user if arguments are passed but the locale could not be set\n                    console.warn('Locale ' + key +  ' not found. Did you forget to load it?');\n                }\n            }\n        }\n\n        return globalLocale._abbr;\n    }\n\n    function defineLocale (name, config) {\n        if (config !== null) {\n            var locale, parentConfig = baseConfig;\n            config.abbr = name;\n            if (locales[name] != null) {\n                deprecateSimple('defineLocaleOverride',\n                        'use moment.updateLocale(localeName, config) to change ' +\n                        'an existing locale. moment.defineLocale(localeName, ' +\n                        'config) should only be used for creating a new locale ' +\n                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');\n                parentConfig = locales[name]._config;\n            } else if (config.parentLocale != null) {\n                if (locales[config.parentLocale] != null) {\n                    parentConfig = locales[config.parentLocale]._config;\n                } else {\n                    locale = loadLocale(config.parentLocale);\n                    if (locale != null) {\n                        parentConfig = locale._config;\n                    } else {\n                        if (!localeFamilies[config.parentLocale]) {\n                            localeFamilies[config.parentLocale] = [];\n                        }\n                        localeFamilies[config.parentLocale].push({\n                            name: name,\n                            config: config\n                        });\n                        return null;\n                    }\n                }\n            }\n            locales[name] = new Locale(mergeConfigs(parentConfig, config));\n\n            if (localeFamilies[name]) {\n                localeFamilies[name].forEach(function (x) {\n                    defineLocale(x.name, x.config);\n                });\n            }\n\n            // backwards compat for now: also set the locale\n            // make sure we set the locale AFTER all child locales have been\n            // created, so we won't end up with the child locale set.\n            getSetGlobalLocale(name);\n\n\n            return locales[name];\n        } else {\n            // useful for testing\n            delete locales[name];\n            return null;\n        }\n    }\n\n    function updateLocale(name, config) {\n        if (config != null) {\n            var locale, tmpLocale, parentConfig = baseConfig;\n            // MERGE\n            tmpLocale = loadLocale(name);\n            if (tmpLocale != null) {\n                parentConfig = tmpLocale._config;\n            }\n            config = mergeConfigs(parentConfig, config);\n            locale = new Locale(config);\n            locale.parentLocale = locales[name];\n            locales[name] = locale;\n\n            // backwards compat for now: also set the locale\n            getSetGlobalLocale(name);\n        } else {\n            // pass null for config to unupdate, useful for tests\n            if (locales[name] != null) {\n                if (locales[name].parentLocale != null) {\n                    locales[name] = locales[name].parentLocale;\n                } else if (locales[name] != null) {\n                    delete locales[name];\n                }\n            }\n        }\n        return locales[name];\n    }\n\n    // returns locale data\n    function getLocale (key) {\n        var locale;\n\n        if (key && key._locale && key._locale._abbr) {\n            key = key._locale._abbr;\n        }\n\n        if (!key) {\n            return globalLocale;\n        }\n\n        if (!isArray(key)) {\n            //short-circuit everything else\n            locale = loadLocale(key);\n            if (locale) {\n                return locale;\n            }\n            key = [key];\n        }\n\n        return chooseLocale(key);\n    }\n\n    function listLocales() {\n        return keys(locales);\n    }\n\n    function checkOverflow (m) {\n        var overflow;\n        var a = m._a;\n\n        if (a && getParsingFlags(m).overflow === -2) {\n            overflow =\n                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n                -1;\n\n            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n                overflow = DATE;\n            }\n            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {\n                overflow = WEEK;\n            }\n            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {\n                overflow = WEEKDAY;\n            }\n\n            getParsingFlags(m).overflow = overflow;\n        }\n\n        return m;\n    }\n\n    // Pick the first defined of two or three arguments.\n    function defaults(a, b, c) {\n        if (a != null) {\n            return a;\n        }\n        if (b != null) {\n            return b;\n        }\n        return c;\n    }\n\n    function currentDateArray(config) {\n        // hooks is actually the exported moment object\n        var nowValue = new Date(hooks.now());\n        if (config._useUTC) {\n            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];\n        }\n        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];\n    }\n\n    // convert an array to a date.\n    // the array should mirror the parameters below\n    // note: all values past the year are optional and will default to the lowest possible value.\n    // [year, month, day , hour, minute, second, millisecond]\n    function configFromArray (config) {\n        var i, date, input = [], currentDate, expectedWeekday, yearToUse;\n\n        if (config._d) {\n            return;\n        }\n\n        currentDate = currentDateArray(config);\n\n        //compute day of the year from weeks and weekdays\n        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n            dayOfYearFromWeekInfo(config);\n        }\n\n        //if the day of the year is set, figure out what it is\n        if (config._dayOfYear != null) {\n            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n            if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {\n                getParsingFlags(config)._overflowDayOfYear = true;\n            }\n\n            date = createUTCDate(yearToUse, 0, config._dayOfYear);\n            config._a[MONTH] = date.getUTCMonth();\n            config._a[DATE] = date.getUTCDate();\n        }\n\n        // Default to current date.\n        // * if no year, month, day of month are given, default to today\n        // * if day of month is given, default month and year\n        // * if month is given, default only year\n        // * if year is given, don't default anything\n        for (i = 0; i < 3 && config._a[i] == null; ++i) {\n            config._a[i] = input[i] = currentDate[i];\n        }\n\n        // Zero out whatever was not defaulted, including time\n        for (; i < 7; i++) {\n            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n        }\n\n        // Check for 24:00:00.000\n        if (config._a[HOUR] === 24 &&\n                config._a[MINUTE] === 0 &&\n                config._a[SECOND] === 0 &&\n                config._a[MILLISECOND] === 0) {\n            config._nextDay = true;\n            config._a[HOUR] = 0;\n        }\n\n        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n        expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();\n\n        // Apply timezone offset from input. The actual utcOffset can be changed\n        // with parseZone.\n        if (config._tzm != null) {\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n        }\n\n        if (config._nextDay) {\n            config._a[HOUR] = 24;\n        }\n\n        // check for mismatching day of week\n        if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {\n            getParsingFlags(config).weekdayMismatch = true;\n        }\n    }\n\n    function dayOfYearFromWeekInfo(config) {\n        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;\n\n        w = config._w;\n        if (w.GG != null || w.W != null || w.E != null) {\n            dow = 1;\n            doy = 4;\n\n            // TODO: We need to take the current isoWeekYear, but that depends on\n            // how we interpret now (local, utc, fixed offset). So create\n            // a now version of current config (take local/utc/offset flags, and\n            // create now).\n            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n            week = defaults(w.W, 1);\n            weekday = defaults(w.E, 1);\n            if (weekday < 1 || weekday > 7) {\n                weekdayOverflow = true;\n            }\n        } else {\n            dow = config._locale._week.dow;\n            doy = config._locale._week.doy;\n\n            var curWeek = weekOfYear(createLocal(), dow, doy);\n\n            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);\n\n            // Default to current week.\n            week = defaults(w.w, curWeek.week);\n\n            if (w.d != null) {\n                // weekday -- low day numbers are considered next week\n                weekday = w.d;\n                if (weekday < 0 || weekday > 6) {\n                    weekdayOverflow = true;\n                }\n            } else if (w.e != null) {\n                // local weekday -- counting starts from beginning of week\n                weekday = w.e + dow;\n                if (w.e < 0 || w.e > 6) {\n                    weekdayOverflow = true;\n                }\n            } else {\n                // default to beginning of week\n                weekday = dow;\n            }\n        }\n        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {\n            getParsingFlags(config)._overflowWeeks = true;\n        } else if (weekdayOverflow != null) {\n            getParsingFlags(config)._overflowWeekday = true;\n        } else {\n            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);\n            config._a[YEAR] = temp.year;\n            config._dayOfYear = temp.dayOfYear;\n        }\n    }\n\n    // iso 8601 regex\n    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\n    var extendedIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})-(?:\\d\\d-\\d\\d|W\\d\\d-\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?::\\d\\d(?::\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n    var basicIsoRegex = /^\\s*((?:[+-]\\d{6}|\\d{4})(?:\\d\\d\\d\\d|W\\d\\d\\d|W\\d\\d|\\d\\d\\d|\\d\\d))(?:(T| )(\\d\\d(?:\\d\\d(?:\\d\\d(?:[.,]\\d+)?)?)?)([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\n    var tzRegex = /Z|[+-]\\d\\d(?::?\\d\\d)?/;\n\n    var isoDates = [\n        ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d\\d-\\d\\d/],\n        ['YYYY-MM-DD', /\\d{4}-\\d\\d-\\d\\d/],\n        ['GGGG-[W]WW-E', /\\d{4}-W\\d\\d-\\d/],\n        ['GGGG-[W]WW', /\\d{4}-W\\d\\d/, false],\n        ['YYYY-DDD', /\\d{4}-\\d{3}/],\n        ['YYYY-MM', /\\d{4}-\\d\\d/, false],\n        ['YYYYYYMMDD', /[+-]\\d{10}/],\n        ['YYYYMMDD', /\\d{8}/],\n        // YYYYMM is NOT allowed by the standard\n        ['GGGG[W]WWE', /\\d{4}W\\d{3}/],\n        ['GGGG[W]WW', /\\d{4}W\\d{2}/, false],\n        ['YYYYDDD', /\\d{7}/]\n    ];\n\n    // iso time formats and regexes\n    var isoTimes = [\n        ['HH:mm:ss.SSSS', /\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n        ['HH:mm:ss,SSSS', /\\d\\d:\\d\\d:\\d\\d,\\d+/],\n        ['HH:mm:ss', /\\d\\d:\\d\\d:\\d\\d/],\n        ['HH:mm', /\\d\\d:\\d\\d/],\n        ['HHmmss.SSSS', /\\d\\d\\d\\d\\d\\d\\.\\d+/],\n        ['HHmmss,SSSS', /\\d\\d\\d\\d\\d\\d,\\d+/],\n        ['HHmmss', /\\d\\d\\d\\d\\d\\d/],\n        ['HHmm', /\\d\\d\\d\\d/],\n        ['HH', /\\d\\d/]\n    ];\n\n    var aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n\n    // date from iso format\n    function configFromISO(config) {\n        var i, l,\n            string = config._i,\n            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),\n            allowTime, dateFormat, timeFormat, tzFormat;\n\n        if (match) {\n            getParsingFlags(config).iso = true;\n\n            for (i = 0, l = isoDates.length; i < l; i++) {\n                if (isoDates[i][1].exec(match[1])) {\n                    dateFormat = isoDates[i][0];\n                    allowTime = isoDates[i][2] !== false;\n                    break;\n                }\n            }\n            if (dateFormat == null) {\n                config._isValid = false;\n                return;\n            }\n            if (match[3]) {\n                for (i = 0, l = isoTimes.length; i < l; i++) {\n                    if (isoTimes[i][1].exec(match[3])) {\n                        // match[2] should be 'T' or space\n                        timeFormat = (match[2] || ' ') + isoTimes[i][0];\n                        break;\n                    }\n                }\n                if (timeFormat == null) {\n                    config._isValid = false;\n                    return;\n                }\n            }\n            if (!allowTime && timeFormat != null) {\n                config._isValid = false;\n                return;\n            }\n            if (match[4]) {\n                if (tzRegex.exec(match[4])) {\n                    tzFormat = 'Z';\n                } else {\n                    config._isValid = false;\n                    return;\n                }\n            }\n            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');\n            configFromStringAndFormat(config);\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3\n    var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\\s)?(\\d{1,2})\\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s(\\d{2,4})\\s(\\d\\d):(\\d\\d)(?::(\\d\\d))?\\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\\d{4}))$/;\n\n    function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {\n        var result = [\n            untruncateYear(yearStr),\n            defaultLocaleMonthsShort.indexOf(monthStr),\n            parseInt(dayStr, 10),\n            parseInt(hourStr, 10),\n            parseInt(minuteStr, 10)\n        ];\n\n        if (secondStr) {\n            result.push(parseInt(secondStr, 10));\n        }\n\n        return result;\n    }\n\n    function untruncateYear(yearStr) {\n        var year = parseInt(yearStr, 10);\n        if (year <= 49) {\n            return 2000 + year;\n        } else if (year <= 999) {\n            return 1900 + year;\n        }\n        return year;\n    }\n\n    function preprocessRFC2822(s) {\n        // Remove comments and folding whitespace and replace multiple-spaces with a single space\n        return s.replace(/\\([^)]*\\)|[\\n\\t]/g, ' ').replace(/(\\s\\s+)/g, ' ').replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n    }\n\n    function checkWeekday(weekdayStr, parsedInput, config) {\n        if (weekdayStr) {\n            // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.\n            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),\n                weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();\n            if (weekdayProvided !== weekdayActual) {\n                getParsingFlags(config).weekdayMismatch = true;\n                config._isValid = false;\n                return false;\n            }\n        }\n        return true;\n    }\n\n    var obsOffsets = {\n        UT: 0,\n        GMT: 0,\n        EDT: -4 * 60,\n        EST: -5 * 60,\n        CDT: -5 * 60,\n        CST: -6 * 60,\n        MDT: -6 * 60,\n        MST: -7 * 60,\n        PDT: -7 * 60,\n        PST: -8 * 60\n    };\n\n    function calculateOffset(obsOffset, militaryOffset, numOffset) {\n        if (obsOffset) {\n            return obsOffsets[obsOffset];\n        } else if (militaryOffset) {\n            // the only allowed military tz is Z\n            return 0;\n        } else {\n            var hm = parseInt(numOffset, 10);\n            var m = hm % 100, h = (hm - m) / 100;\n            return h * 60 + m;\n        }\n    }\n\n    // date and time from ref 2822 format\n    function configFromRFC2822(config) {\n        var match = rfc2822.exec(preprocessRFC2822(config._i));\n        if (match) {\n            var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);\n            if (!checkWeekday(match[1], parsedArray, config)) {\n                return;\n            }\n\n            config._a = parsedArray;\n            config._tzm = calculateOffset(match[8], match[9], match[10]);\n\n            config._d = createUTCDate.apply(null, config._a);\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n\n            getParsingFlags(config).rfc2822 = true;\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // date from iso format or fallback\n    function configFromString(config) {\n        var matched = aspNetJsonRegex.exec(config._i);\n\n        if (matched !== null) {\n            config._d = new Date(+matched[1]);\n            return;\n        }\n\n        configFromISO(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n        } else {\n            return;\n        }\n\n        configFromRFC2822(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n        } else {\n            return;\n        }\n\n        // Final attempt, use Input Fallback\n        hooks.createFromInputFallback(config);\n    }\n\n    hooks.createFromInputFallback = deprecate(\n        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +\n        'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +\n        'discouraged and will be removed in an upcoming major release. Please refer to ' +\n        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',\n        function (config) {\n            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n        }\n    );\n\n    // constant that refers to the ISO standard\n    hooks.ISO_8601 = function () {};\n\n    // constant that refers to the RFC 2822 form\n    hooks.RFC_2822 = function () {};\n\n    // date from string and format string\n    function configFromStringAndFormat(config) {\n        // TODO: Move this to another part of the creation flow to prevent circular deps\n        if (config._f === hooks.ISO_8601) {\n            configFromISO(config);\n            return;\n        }\n        if (config._f === hooks.RFC_2822) {\n            configFromRFC2822(config);\n            return;\n        }\n        config._a = [];\n        getParsingFlags(config).empty = true;\n\n        // This array is used to make a Date, either with `new Date` or `Date.UTC`\n        var string = '' + config._i,\n            i, parsedInput, tokens, token, skipped,\n            stringLength = string.length,\n            totalParsedInputLength = 0;\n\n        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n        for (i = 0; i < tokens.length; i++) {\n            token = tokens[i];\n            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n            // console.log('token', token, 'parsedInput', parsedInput,\n            //         'regex', getParseRegexForToken(token, config));\n            if (parsedInput) {\n                skipped = string.substr(0, string.indexOf(parsedInput));\n                if (skipped.length > 0) {\n                    getParsingFlags(config).unusedInput.push(skipped);\n                }\n                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n                totalParsedInputLength += parsedInput.length;\n            }\n            // don't parse if it's not a known token\n            if (formatTokenFunctions[token]) {\n                if (parsedInput) {\n                    getParsingFlags(config).empty = false;\n                }\n                else {\n                    getParsingFlags(config).unusedTokens.push(token);\n                }\n                addTimeToArrayFromToken(token, parsedInput, config);\n            }\n            else if (config._strict && !parsedInput) {\n                getParsingFlags(config).unusedTokens.push(token);\n            }\n        }\n\n        // add remaining unparsed input length to the string\n        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;\n        if (string.length > 0) {\n            getParsingFlags(config).unusedInput.push(string);\n        }\n\n        // clear _12h flag if hour is <= 12\n        if (config._a[HOUR] <= 12 &&\n            getParsingFlags(config).bigHour === true &&\n            config._a[HOUR] > 0) {\n            getParsingFlags(config).bigHour = undefined;\n        }\n\n        getParsingFlags(config).parsedDateParts = config._a.slice(0);\n        getParsingFlags(config).meridiem = config._meridiem;\n        // handle meridiem\n        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n        configFromArray(config);\n        checkOverflow(config);\n    }\n\n\n    function meridiemFixWrap (locale, hour, meridiem) {\n        var isPm;\n\n        if (meridiem == null) {\n            // nothing to do\n            return hour;\n        }\n        if (locale.meridiemHour != null) {\n            return locale.meridiemHour(hour, meridiem);\n        } else if (locale.isPM != null) {\n            // Fallback\n            isPm = locale.isPM(meridiem);\n            if (isPm && hour < 12) {\n                hour += 12;\n            }\n            if (!isPm && hour === 12) {\n                hour = 0;\n            }\n            return hour;\n        } else {\n            // this is not supposed to happen\n            return hour;\n        }\n    }\n\n    // date from string and array of format strings\n    function configFromStringAndArray(config) {\n        var tempConfig,\n            bestMoment,\n\n            scoreToBeat,\n            i,\n            currentScore;\n\n        if (config._f.length === 0) {\n            getParsingFlags(config).invalidFormat = true;\n            config._d = new Date(NaN);\n            return;\n        }\n\n        for (i = 0; i < config._f.length; i++) {\n            currentScore = 0;\n            tempConfig = copyConfig({}, config);\n            if (config._useUTC != null) {\n                tempConfig._useUTC = config._useUTC;\n            }\n            tempConfig._f = config._f[i];\n            configFromStringAndFormat(tempConfig);\n\n            if (!isValid(tempConfig)) {\n                continue;\n            }\n\n            // if there is any input that was not parsed add a penalty for that format\n            currentScore += getParsingFlags(tempConfig).charsLeftOver;\n\n            //or tokens\n            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;\n\n            getParsingFlags(tempConfig).score = currentScore;\n\n            if (scoreToBeat == null || currentScore < scoreToBeat) {\n                scoreToBeat = currentScore;\n                bestMoment = tempConfig;\n            }\n        }\n\n        extend(config, bestMoment || tempConfig);\n    }\n\n    function configFromObject(config) {\n        if (config._d) {\n            return;\n        }\n\n        var i = normalizeObjectUnits(config._i);\n        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {\n            return obj && parseInt(obj, 10);\n        });\n\n        configFromArray(config);\n    }\n\n    function createFromConfig (config) {\n        var res = new Moment(checkOverflow(prepareConfig(config)));\n        if (res._nextDay) {\n            // Adding is smart enough around DST\n            res.add(1, 'd');\n            res._nextDay = undefined;\n        }\n\n        return res;\n    }\n\n    function prepareConfig (config) {\n        var input = config._i,\n            format = config._f;\n\n        config._locale = config._locale || getLocale(config._l);\n\n        if (input === null || (format === undefined && input === '')) {\n            return createInvalid({nullInput: true});\n        }\n\n        if (typeof input === 'string') {\n            config._i = input = config._locale.preparse(input);\n        }\n\n        if (isMoment(input)) {\n            return new Moment(checkOverflow(input));\n        } else if (isDate(input)) {\n            config._d = input;\n        } else if (isArray(format)) {\n            configFromStringAndArray(config);\n        } else if (format) {\n            configFromStringAndFormat(config);\n        }  else {\n            configFromInput(config);\n        }\n\n        if (!isValid(config)) {\n            config._d = null;\n        }\n\n        return config;\n    }\n\n    function configFromInput(config) {\n        var input = config._i;\n        if (isUndefined(input)) {\n            config._d = new Date(hooks.now());\n        } else if (isDate(input)) {\n            config._d = new Date(input.valueOf());\n        } else if (typeof input === 'string') {\n            configFromString(config);\n        } else if (isArray(input)) {\n            config._a = map(input.slice(0), function (obj) {\n                return parseInt(obj, 10);\n            });\n            configFromArray(config);\n        } else if (isObject(input)) {\n            configFromObject(config);\n        } else if (isNumber(input)) {\n            // from milliseconds\n            config._d = new Date(input);\n        } else {\n            hooks.createFromInputFallback(config);\n        }\n    }\n\n    function createLocalOrUTC (input, format, locale, strict, isUTC) {\n        var c = {};\n\n        if (locale === true || locale === false) {\n            strict = locale;\n            locale = undefined;\n        }\n\n        if ((isObject(input) && isObjectEmpty(input)) ||\n                (isArray(input) && input.length === 0)) {\n            input = undefined;\n        }\n        // object construction must be done this way.\n        // https://github.com/moment/moment/issues/1423\n        c._isAMomentObject = true;\n        c._useUTC = c._isUTC = isUTC;\n        c._l = locale;\n        c._i = input;\n        c._f = format;\n        c._strict = strict;\n\n        return createFromConfig(c);\n    }\n\n    function createLocal (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, false);\n    }\n\n    var prototypeMin = deprecate(\n        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',\n        function () {\n            var other = createLocal.apply(null, arguments);\n            if (this.isValid() && other.isValid()) {\n                return other < this ? this : other;\n            } else {\n                return createInvalid();\n            }\n        }\n    );\n\n    var prototypeMax = deprecate(\n        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',\n        function () {\n            var other = createLocal.apply(null, arguments);\n            if (this.isValid() && other.isValid()) {\n                return other > this ? this : other;\n            } else {\n                return createInvalid();\n            }\n        }\n    );\n\n    // Pick a moment m from moments so that m[fn](other) is true for all\n    // other. This relies on the function fn to be transitive.\n    //\n    // moments should either be an array of moment objects or an array, whose\n    // first element is an array of moment objects.\n    function pickBy(fn, moments) {\n        var res, i;\n        if (moments.length === 1 && isArray(moments[0])) {\n            moments = moments[0];\n        }\n        if (!moments.length) {\n            return createLocal();\n        }\n        res = moments[0];\n        for (i = 1; i < moments.length; ++i) {\n            if (!moments[i].isValid() || moments[i][fn](res)) {\n                res = moments[i];\n            }\n        }\n        return res;\n    }\n\n    // TODO: Use [].sort instead?\n    function min () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isBefore', args);\n    }\n\n    function max () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isAfter', args);\n    }\n\n    var now = function () {\n        return Date.now ? Date.now() : +(new Date());\n    };\n\n    var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];\n\n    function isDurationValid(m) {\n        for (var key in m) {\n            if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {\n                return false;\n            }\n        }\n\n        var unitHasDecimal = false;\n        for (var i = 0; i < ordering.length; ++i) {\n            if (m[ordering[i]]) {\n                if (unitHasDecimal) {\n                    return false; // only allow non-integers for smallest unit\n                }\n                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {\n                    unitHasDecimal = true;\n                }\n            }\n        }\n\n        return true;\n    }\n\n    function isValid$1() {\n        return this._isValid;\n    }\n\n    function createInvalid$1() {\n        return createDuration(NaN);\n    }\n\n    function Duration (duration) {\n        var normalizedInput = normalizeObjectUnits(duration),\n            years = normalizedInput.year || 0,\n            quarters = normalizedInput.quarter || 0,\n            months = normalizedInput.month || 0,\n            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,\n            days = normalizedInput.day || 0,\n            hours = normalizedInput.hour || 0,\n            minutes = normalizedInput.minute || 0,\n            seconds = normalizedInput.second || 0,\n            milliseconds = normalizedInput.millisecond || 0;\n\n        this._isValid = isDurationValid(normalizedInput);\n\n        // representation for dateAddRemove\n        this._milliseconds = +milliseconds +\n            seconds * 1e3 + // 1000\n            minutes * 6e4 + // 1000 * 60\n            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978\n        // Because of dateAddRemove treats 24 hours as different from a\n        // day when working around DST, we need to store them separately\n        this._days = +days +\n            weeks * 7;\n        // It is impossible to translate months into days without knowing\n        // which months you are are talking about, so we have to store\n        // it separately.\n        this._months = +months +\n            quarters * 3 +\n            years * 12;\n\n        this._data = {};\n\n        this._locale = getLocale();\n\n        this._bubble();\n    }\n\n    function isDuration (obj) {\n        return obj instanceof Duration;\n    }\n\n    function absRound (number) {\n        if (number < 0) {\n            return Math.round(-1 * number) * -1;\n        } else {\n            return Math.round(number);\n        }\n    }\n\n    // FORMATTING\n\n    function offset (token, separator) {\n        addFormatToken(token, 0, 0, function () {\n            var offset = this.utcOffset();\n            var sign = '+';\n            if (offset < 0) {\n                offset = -offset;\n                sign = '-';\n            }\n            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n        });\n    }\n\n    offset('Z', ':');\n    offset('ZZ', '');\n\n    // PARSING\n\n    addRegexToken('Z',  matchShortOffset);\n    addRegexToken('ZZ', matchShortOffset);\n    addParseToken(['Z', 'ZZ'], function (input, array, config) {\n        config._useUTC = true;\n        config._tzm = offsetFromString(matchShortOffset, input);\n    });\n\n    // HELPERS\n\n    // timezone chunker\n    // '+10:00' > ['10',  '00']\n    // '-1530'  > ['-15', '30']\n    var chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\n    function offsetFromString(matcher, string) {\n        var matches = (string || '').match(matcher);\n\n        if (matches === null) {\n            return null;\n        }\n\n        var chunk   = matches[matches.length - 1] || [];\n        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n        var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n        return minutes === 0 ?\n          0 :\n          parts[0] === '+' ? minutes : -minutes;\n    }\n\n    // Return a moment from input, that is local/utc/zone equivalent to model.\n    function cloneWithOffset(input, model) {\n        var res, diff;\n        if (model._isUTC) {\n            res = model.clone();\n            diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();\n            // Use low-level api, because this fn is low-level api.\n            res._d.setTime(res._d.valueOf() + diff);\n            hooks.updateOffset(res, false);\n            return res;\n        } else {\n            return createLocal(input).local();\n        }\n    }\n\n    function getDateOffset (m) {\n        // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n        // https://github.com/moment/moment/pull/1871\n        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n    }\n\n    // HOOKS\n\n    // This function will be called whenever a moment is mutated.\n    // It is intended to keep the offset in sync with the timezone.\n    hooks.updateOffset = function () {};\n\n    // MOMENTS\n\n    // keepLocalTime = true means only change the timezone, without\n    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--\x3e\n    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n    // +0200, so we adjust the time as needed, to be valid.\n    //\n    // Keeping the time actually adds/subtracts (one hour)\n    // from the actual represented time. That is why we call updateOffset\n    // a second time. In case it wants us to change the offset again\n    // _changeInProgress == true case, then we have to adjust, because\n    // there is no such time in the given timezone.\n    function getSetOffset (input, keepLocalTime, keepMinutes) {\n        var offset = this._offset || 0,\n            localAdjust;\n        if (!this.isValid()) {\n            return input != null ? this : NaN;\n        }\n        if (input != null) {\n            if (typeof input === 'string') {\n                input = offsetFromString(matchShortOffset, input);\n                if (input === null) {\n                    return this;\n                }\n            } else if (Math.abs(input) < 16 && !keepMinutes) {\n                input = input * 60;\n            }\n            if (!this._isUTC && keepLocalTime) {\n                localAdjust = getDateOffset(this);\n            }\n            this._offset = input;\n            this._isUTC = true;\n            if (localAdjust != null) {\n                this.add(localAdjust, 'm');\n            }\n            if (offset !== input) {\n                if (!keepLocalTime || this._changeInProgress) {\n                    addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n                } else if (!this._changeInProgress) {\n                    this._changeInProgress = true;\n                    hooks.updateOffset(this, true);\n                    this._changeInProgress = null;\n                }\n            }\n            return this;\n        } else {\n            return this._isUTC ? offset : getDateOffset(this);\n        }\n    }\n\n    function getSetZone (input, keepLocalTime) {\n        if (input != null) {\n            if (typeof input !== 'string') {\n                input = -input;\n            }\n\n            this.utcOffset(input, keepLocalTime);\n\n            return this;\n        } else {\n            return -this.utcOffset();\n        }\n    }\n\n    function setOffsetToUTC (keepLocalTime) {\n        return this.utcOffset(0, keepLocalTime);\n    }\n\n    function setOffsetToLocal (keepLocalTime) {\n        if (this._isUTC) {\n            this.utcOffset(0, keepLocalTime);\n            this._isUTC = false;\n\n            if (keepLocalTime) {\n                this.subtract(getDateOffset(this), 'm');\n            }\n        }\n        return this;\n    }\n\n    function setOffsetToParsedOffset () {\n        if (this._tzm != null) {\n            this.utcOffset(this._tzm, false, true);\n        } else if (typeof this._i === 'string') {\n            var tZone = offsetFromString(matchOffset, this._i);\n            if (tZone != null) {\n                this.utcOffset(tZone);\n            }\n            else {\n                this.utcOffset(0, true);\n            }\n        }\n        return this;\n    }\n\n    function hasAlignedHourOffset (input) {\n        if (!this.isValid()) {\n            return false;\n        }\n        input = input ? createLocal(input).utcOffset() : 0;\n\n        return (this.utcOffset() - input) % 60 === 0;\n    }\n\n    function isDaylightSavingTime () {\n        return (\n            this.utcOffset() > this.clone().month(0).utcOffset() ||\n            this.utcOffset() > this.clone().month(5).utcOffset()\n        );\n    }\n\n    function isDaylightSavingTimeShifted () {\n        if (!isUndefined(this._isDSTShifted)) {\n            return this._isDSTShifted;\n        }\n\n        var c = {};\n\n        copyConfig(c, this);\n        c = prepareConfig(c);\n\n        if (c._a) {\n            var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);\n            this._isDSTShifted = this.isValid() &&\n                compareArrays(c._a, other.toArray()) > 0;\n        } else {\n            this._isDSTShifted = false;\n        }\n\n        return this._isDSTShifted;\n    }\n\n    function isLocal () {\n        return this.isValid() ? !this._isUTC : false;\n    }\n\n    function isUtcOffset () {\n        return this.isValid() ? this._isUTC : false;\n    }\n\n    function isUtc () {\n        return this.isValid() ? this._isUTC && this._offset === 0 : false;\n    }\n\n    // ASP.NET json date format regex\n    var aspNetRegex = /^(\\-|\\+)?(?:(\\d*)[. ])?(\\d+)\\:(\\d+)(?:\\:(\\d+)(\\.\\d*)?)?$/;\n\n    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n    // and further modified to allow for strings containing both week and day\n    var isoRegex = /^(-|\\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;\n\n    function createDuration (input, key) {\n        var duration = input,\n            // matching against regexp is expensive, do it on demand\n            match = null,\n            sign,\n            ret,\n            diffRes;\n\n        if (isDuration(input)) {\n            duration = {\n                ms : input._milliseconds,\n                d  : input._days,\n                M  : input._months\n            };\n        } else if (isNumber(input)) {\n            duration = {};\n            if (key) {\n                duration[key] = input;\n            } else {\n                duration.milliseconds = input;\n            }\n        } else if (!!(match = aspNetRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y  : 0,\n                d  : toInt(match[DATE])                         * sign,\n                h  : toInt(match[HOUR])                         * sign,\n                m  : toInt(match[MINUTE])                       * sign,\n                s  : toInt(match[SECOND])                       * sign,\n                ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match\n            };\n        } else if (!!(match = isoRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y : parseIso(match[2], sign),\n                M : parseIso(match[3], sign),\n                w : parseIso(match[4], sign),\n                d : parseIso(match[5], sign),\n                h : parseIso(match[6], sign),\n                m : parseIso(match[7], sign),\n                s : parseIso(match[8], sign)\n            };\n        } else if (duration == null) {// checks for null or undefined\n            duration = {};\n        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n            diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n            duration = {};\n            duration.ms = diffRes.milliseconds;\n            duration.M = diffRes.months;\n        }\n\n        ret = new Duration(duration);\n\n        if (isDuration(input) && hasOwnProp(input, '_locale')) {\n            ret._locale = input._locale;\n        }\n\n        return ret;\n    }\n\n    createDuration.fn = Duration.prototype;\n    createDuration.invalid = createInvalid$1;\n\n    function parseIso (inp, sign) {\n        // We'd normally use ~~inp for this, but unfortunately it also\n        // converts floats to ints.\n        // inp may be undefined, so careful calling replace on it.\n        var res = inp && parseFloat(inp.replace(',', '.'));\n        // apply sign while we're at it\n        return (isNaN(res) ? 0 : res) * sign;\n    }\n\n    function positiveMomentsDifference(base, other) {\n        var res = {};\n\n        res.months = other.month() - base.month() +\n            (other.year() - base.year()) * 12;\n        if (base.clone().add(res.months, 'M').isAfter(other)) {\n            --res.months;\n        }\n\n        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n        return res;\n    }\n\n    function momentsDifference(base, other) {\n        var res;\n        if (!(base.isValid() && other.isValid())) {\n            return {milliseconds: 0, months: 0};\n        }\n\n        other = cloneWithOffset(other, base);\n        if (base.isBefore(other)) {\n            res = positiveMomentsDifference(base, other);\n        } else {\n            res = positiveMomentsDifference(other, base);\n            res.milliseconds = -res.milliseconds;\n            res.months = -res.months;\n        }\n\n        return res;\n    }\n\n    // TODO: remove 'name' arg after deprecation is removed\n    function createAdder(direction, name) {\n        return function (val, period) {\n            var dur, tmp;\n            //invert the arguments, but complain about it\n            if (period !== null && !isNaN(+period)) {\n                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +\n                'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');\n                tmp = val; val = period; period = tmp;\n            }\n\n            val = typeof val === 'string' ? +val : val;\n            dur = createDuration(val, period);\n            addSubtract(this, dur, direction);\n            return this;\n        };\n    }\n\n    function addSubtract (mom, duration, isAdding, updateOffset) {\n        var milliseconds = duration._milliseconds,\n            days = absRound(duration._days),\n            months = absRound(duration._months);\n\n        if (!mom.isValid()) {\n            // No op\n            return;\n        }\n\n        updateOffset = updateOffset == null ? true : updateOffset;\n\n        if (months) {\n            setMonth(mom, get(mom, 'Month') + months * isAdding);\n        }\n        if (days) {\n            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);\n        }\n        if (milliseconds) {\n            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);\n        }\n        if (updateOffset) {\n            hooks.updateOffset(mom, days || months);\n        }\n    }\n\n    var add      = createAdder(1, 'add');\n    var subtract = createAdder(-1, 'subtract');\n\n    function getCalendarFormat(myMoment, now) {\n        var diff = myMoment.diff(now, 'days', true);\n        return diff < -6 ? 'sameElse' :\n                diff < -1 ? 'lastWeek' :\n                diff < 0 ? 'lastDay' :\n                diff < 1 ? 'sameDay' :\n                diff < 2 ? 'nextDay' :\n                diff < 7 ? 'nextWeek' : 'sameElse';\n    }\n\n    function calendar$1 (time, formats) {\n        // We want to compare the start of today, vs this.\n        // Getting start-of-today depends on whether we're local/utc/offset or not.\n        var now = time || createLocal(),\n            sod = cloneWithOffset(now, this).startOf('day'),\n            format = hooks.calendarFormat(this, sod) || 'sameElse';\n\n        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);\n\n        return this.format(output || this.localeData().calendar(format, this, createLocal(now)));\n    }\n\n    function clone () {\n        return new Moment(this);\n    }\n\n    function isAfter (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input);\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() > localInput.valueOf();\n        } else {\n            return localInput.valueOf() < this.clone().startOf(units).valueOf();\n        }\n    }\n\n    function isBefore (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input);\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() < localInput.valueOf();\n        } else {\n            return this.clone().endOf(units).valueOf() < localInput.valueOf();\n        }\n    }\n\n    function isBetween (from, to, units, inclusivity) {\n        var localFrom = isMoment(from) ? from : createLocal(from),\n            localTo = isMoment(to) ? to : createLocal(to);\n        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {\n            return false;\n        }\n        inclusivity = inclusivity || '()';\n        return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) &&\n            (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));\n    }\n\n    function isSame (input, units) {\n        var localInput = isMoment(input) ? input : createLocal(input),\n            inputMs;\n        if (!(this.isValid() && localInput.isValid())) {\n            return false;\n        }\n        units = normalizeUnits(units) || 'millisecond';\n        if (units === 'millisecond') {\n            return this.valueOf() === localInput.valueOf();\n        } else {\n            inputMs = localInput.valueOf();\n            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();\n        }\n    }\n\n    function isSameOrAfter (input, units) {\n        return this.isSame(input, units) || this.isAfter(input, units);\n    }\n\n    function isSameOrBefore (input, units) {\n        return this.isSame(input, units) || this.isBefore(input, units);\n    }\n\n    function diff (input, units, asFloat) {\n        var that,\n            zoneDelta,\n            output;\n\n        if (!this.isValid()) {\n            return NaN;\n        }\n\n        that = cloneWithOffset(input, this);\n\n        if (!that.isValid()) {\n            return NaN;\n        }\n\n        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;\n\n        units = normalizeUnits(units);\n\n        switch (units) {\n            case 'year': output = monthDiff(this, that) / 12; break;\n            case 'month': output = monthDiff(this, that); break;\n            case 'quarter': output = monthDiff(this, that) / 3; break;\n            case 'second': output = (this - that) / 1e3; break; // 1000\n            case 'minute': output = (this - that) / 6e4; break; // 1000 * 60\n            case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60\n            case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst\n            case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst\n            default: output = this - that;\n        }\n\n        return asFloat ? output : absFloor(output);\n    }\n\n    function monthDiff (a, b) {\n        // difference in months\n        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n            // b is in (anchor - 1 month, anchor + 1 month)\n            anchor = a.clone().add(wholeMonthDiff, 'months'),\n            anchor2, adjust;\n\n        if (b - anchor < 0) {\n            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor - anchor2);\n        } else {\n            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor2 - anchor);\n        }\n\n        //check for negative zero, return zero if negative zero\n        return -(wholeMonthDiff + adjust) || 0;\n    }\n\n    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';\n\n    function toString () {\n        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n    }\n\n    function toISOString(keepOffset) {\n        if (!this.isValid()) {\n            return null;\n        }\n        var utc = keepOffset !== true;\n        var m = utc ? this.clone().utc() : this;\n        if (m.year() < 0 || m.year() > 9999) {\n            return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');\n        }\n        if (isFunction(Date.prototype.toISOString)) {\n            // native implementation is ~50x faster, use it when we can\n            if (utc) {\n                return this.toDate().toISOString();\n            } else {\n                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));\n            }\n        }\n        return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');\n    }\n\n    /**\n     * Return a human readable representation of a moment that can\n     * also be evaluated to get a new moment which is the same\n     *\n     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects\n     */\n    function inspect () {\n        if (!this.isValid()) {\n            return 'moment.invalid(/* ' + this._i + ' */)';\n        }\n        var func = 'moment';\n        var zone = '';\n        if (!this.isLocal()) {\n            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';\n            zone = 'Z';\n        }\n        var prefix = '[' + func + '(\"]';\n        var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';\n        var datetime = '-MM-DD[T]HH:mm:ss.SSS';\n        var suffix = zone + '[\")]';\n\n        return this.format(prefix + year + datetime + suffix);\n    }\n\n    function format (inputString) {\n        if (!inputString) {\n            inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;\n        }\n        var output = formatMoment(this, inputString);\n        return this.localeData().postformat(output);\n    }\n\n    function from (time, withoutSuffix) {\n        if (this.isValid() &&\n                ((isMoment(time) && time.isValid()) ||\n                 createLocal(time).isValid())) {\n            return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n        } else {\n            return this.localeData().invalidDate();\n        }\n    }\n\n    function fromNow (withoutSuffix) {\n        return this.from(createLocal(), withoutSuffix);\n    }\n\n    function to (time, withoutSuffix) {\n        if (this.isValid() &&\n                ((isMoment(time) && time.isValid()) ||\n                 createLocal(time).isValid())) {\n            return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);\n        } else {\n            return this.localeData().invalidDate();\n        }\n    }\n\n    function toNow (withoutSuffix) {\n        return this.to(createLocal(), withoutSuffix);\n    }\n\n    // If passed a locale key, it will set the locale for this\n    // instance.  Otherwise, it will return the locale configuration\n    // variables for this instance.\n    function locale (key) {\n        var newLocaleData;\n\n        if (key === undefined) {\n            return this._locale._abbr;\n        } else {\n            newLocaleData = getLocale(key);\n            if (newLocaleData != null) {\n                this._locale = newLocaleData;\n            }\n            return this;\n        }\n    }\n\n    var lang = deprecate(\n        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n        function (key) {\n            if (key === undefined) {\n                return this.localeData();\n            } else {\n                return this.locale(key);\n            }\n        }\n    );\n\n    function localeData () {\n        return this._locale;\n    }\n\n    var MS_PER_SECOND = 1000;\n    var MS_PER_MINUTE = 60 * MS_PER_SECOND;\n    var MS_PER_HOUR = 60 * MS_PER_MINUTE;\n    var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;\n\n    // actual modulo - handles negative numbers (for dates before 1970):\n    function mod$1(dividend, divisor) {\n        return (dividend % divisor + divisor) % divisor;\n    }\n\n    function localStartOfDate(y, m, d) {\n        // the date constructor remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            return new Date(y + 400, m, d) - MS_PER_400_YEARS;\n        } else {\n            return new Date(y, m, d).valueOf();\n        }\n    }\n\n    function utcStartOfDate(y, m, d) {\n        // Date.UTC remaps years 0-99 to 1900-1999\n        if (y < 100 && y >= 0) {\n            // preserve leap years using a full 400 year cycle, then reset\n            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;\n        } else {\n            return Date.UTC(y, m, d);\n        }\n    }\n\n    function startOf (units) {\n        var time;\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond' || !this.isValid()) {\n            return this;\n        }\n\n        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;\n\n        switch (units) {\n            case 'year':\n                time = startOfDate(this.year(), 0, 1);\n                break;\n            case 'quarter':\n                time = startOfDate(this.year(), this.month() - this.month() % 3, 1);\n                break;\n            case 'month':\n                time = startOfDate(this.year(), this.month(), 1);\n                break;\n            case 'week':\n                time = startOfDate(this.year(), this.month(), this.date() - this.weekday());\n                break;\n            case 'isoWeek':\n                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));\n                break;\n            case 'day':\n            case 'date':\n                time = startOfDate(this.year(), this.month(), this.date());\n                break;\n            case 'hour':\n                time = this._d.valueOf();\n                time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);\n                break;\n            case 'minute':\n                time = this._d.valueOf();\n                time -= mod$1(time, MS_PER_MINUTE);\n                break;\n            case 'second':\n                time = this._d.valueOf();\n                time -= mod$1(time, MS_PER_SECOND);\n                break;\n        }\n\n        this._d.setTime(time);\n        hooks.updateOffset(this, true);\n        return this;\n    }\n\n    function endOf (units) {\n        var time;\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond' || !this.isValid()) {\n            return this;\n        }\n\n        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;\n\n        switch (units) {\n            case 'year':\n                time = startOfDate(this.year() + 1, 0, 1) - 1;\n                break;\n            case 'quarter':\n                time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;\n                break;\n            case 'month':\n                time = startOfDate(this.year(), this.month() + 1, 1) - 1;\n                break;\n            case 'week':\n                time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;\n                break;\n            case 'isoWeek':\n                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;\n                break;\n            case 'day':\n            case 'date':\n                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;\n                break;\n            case 'hour':\n                time = this._d.valueOf();\n                time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;\n                break;\n            case 'minute':\n                time = this._d.valueOf();\n                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;\n                break;\n            case 'second':\n                time = this._d.valueOf();\n                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;\n                break;\n        }\n\n        this._d.setTime(time);\n        hooks.updateOffset(this, true);\n        return this;\n    }\n\n    function valueOf () {\n        return this._d.valueOf() - ((this._offset || 0) * 60000);\n    }\n\n    function unix () {\n        return Math.floor(this.valueOf() / 1000);\n    }\n\n    function toDate () {\n        return new Date(this.valueOf());\n    }\n\n    function toArray () {\n        var m = this;\n        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n    }\n\n    function toObject () {\n        var m = this;\n        return {\n            years: m.year(),\n            months: m.month(),\n            date: m.date(),\n            hours: m.hours(),\n            minutes: m.minutes(),\n            seconds: m.seconds(),\n            milliseconds: m.milliseconds()\n        };\n    }\n\n    function toJSON () {\n        // new Date(NaN).toJSON() === null\n        return this.isValid() ? this.toISOString() : null;\n    }\n\n    function isValid$2 () {\n        return isValid(this);\n    }\n\n    function parsingFlags () {\n        return extend({}, getParsingFlags(this));\n    }\n\n    function invalidAt () {\n        return getParsingFlags(this).overflow;\n    }\n\n    function creationData() {\n        return {\n            input: this._i,\n            format: this._f,\n            locale: this._locale,\n            isUTC: this._isUTC,\n            strict: this._strict\n        };\n    }\n\n    // FORMATTING\n\n    addFormatToken(0, ['gg', 2], 0, function () {\n        return this.weekYear() % 100;\n    });\n\n    addFormatToken(0, ['GG', 2], 0, function () {\n        return this.isoWeekYear() % 100;\n    });\n\n    function addWeekYearFormatToken (token, getter) {\n        addFormatToken(0, [token, token.length], 0, getter);\n    }\n\n    addWeekYearFormatToken('gggg',     'weekYear');\n    addWeekYearFormatToken('ggggg',    'weekYear');\n    addWeekYearFormatToken('GGGG',  'isoWeekYear');\n    addWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n    // ALIASES\n\n    addUnitAlias('weekYear', 'gg');\n    addUnitAlias('isoWeekYear', 'GG');\n\n    // PRIORITY\n\n    addUnitPriority('weekYear', 1);\n    addUnitPriority('isoWeekYear', 1);\n\n\n    // PARSING\n\n    addRegexToken('G',      matchSigned);\n    addRegexToken('g',      matchSigned);\n    addRegexToken('GG',     match1to2, match2);\n    addRegexToken('gg',     match1to2, match2);\n    addRegexToken('GGGG',   match1to4, match4);\n    addRegexToken('gggg',   match1to4, match4);\n    addRegexToken('GGGGG',  match1to6, match6);\n    addRegexToken('ggggg',  match1to6, match6);\n\n    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n        week[token.substr(0, 2)] = toInt(input);\n    });\n\n    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n        week[token] = hooks.parseTwoDigitYear(input);\n    });\n\n    // MOMENTS\n\n    function getSetWeekYear (input) {\n        return getSetWeekYearHelper.call(this,\n                input,\n                this.week(),\n                this.weekday(),\n                this.localeData()._week.dow,\n                this.localeData()._week.doy);\n    }\n\n    function getSetISOWeekYear (input) {\n        return getSetWeekYearHelper.call(this,\n                input, this.isoWeek(), this.isoWeekday(), 1, 4);\n    }\n\n    function getISOWeeksInYear () {\n        return weeksInYear(this.year(), 1, 4);\n    }\n\n    function getWeeksInYear () {\n        var weekInfo = this.localeData()._week;\n        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n    }\n\n    function getSetWeekYearHelper(input, week, weekday, dow, doy) {\n        var weeksTarget;\n        if (input == null) {\n            return weekOfYear(this, dow, doy).year;\n        } else {\n            weeksTarget = weeksInYear(input, dow, doy);\n            if (week > weeksTarget) {\n                week = weeksTarget;\n            }\n            return setWeekAll.call(this, input, week, weekday, dow, doy);\n        }\n    }\n\n    function setWeekAll(weekYear, week, weekday, dow, doy) {\n        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),\n            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);\n\n        this.year(date.getUTCFullYear());\n        this.month(date.getUTCMonth());\n        this.date(date.getUTCDate());\n        return this;\n    }\n\n    // FORMATTING\n\n    addFormatToken('Q', 0, 'Qo', 'quarter');\n\n    // ALIASES\n\n    addUnitAlias('quarter', 'Q');\n\n    // PRIORITY\n\n    addUnitPriority('quarter', 7);\n\n    // PARSING\n\n    addRegexToken('Q', match1);\n    addParseToken('Q', function (input, array) {\n        array[MONTH] = (toInt(input) - 1) * 3;\n    });\n\n    // MOMENTS\n\n    function getSetQuarter (input) {\n        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n    }\n\n    // FORMATTING\n\n    addFormatToken('D', ['DD', 2], 'Do', 'date');\n\n    // ALIASES\n\n    addUnitAlias('date', 'D');\n\n    // PRIORITY\n    addUnitPriority('date', 9);\n\n    // PARSING\n\n    addRegexToken('D',  match1to2);\n    addRegexToken('DD', match1to2, match2);\n    addRegexToken('Do', function (isStrict, locale) {\n        // TODO: Remove \"ordinalParse\" fallback in next major release.\n        return isStrict ?\n          (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :\n          locale._dayOfMonthOrdinalParseLenient;\n    });\n\n    addParseToken(['D', 'DD'], DATE);\n    addParseToken('Do', function (input, array) {\n        array[DATE] = toInt(input.match(match1to2)[0]);\n    });\n\n    // MOMENTS\n\n    var getSetDayOfMonth = makeGetSet('Date', true);\n\n    // FORMATTING\n\n    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n    // ALIASES\n\n    addUnitAlias('dayOfYear', 'DDD');\n\n    // PRIORITY\n    addUnitPriority('dayOfYear', 4);\n\n    // PARSING\n\n    addRegexToken('DDD',  match1to3);\n    addRegexToken('DDDD', match3);\n    addParseToken(['DDD', 'DDDD'], function (input, array, config) {\n        config._dayOfYear = toInt(input);\n    });\n\n    // HELPERS\n\n    // MOMENTS\n\n    function getSetDayOfYear (input) {\n        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n    }\n\n    // FORMATTING\n\n    addFormatToken('m', ['mm', 2], 0, 'minute');\n\n    // ALIASES\n\n    addUnitAlias('minute', 'm');\n\n    // PRIORITY\n\n    addUnitPriority('minute', 14);\n\n    // PARSING\n\n    addRegexToken('m',  match1to2);\n    addRegexToken('mm', match1to2, match2);\n    addParseToken(['m', 'mm'], MINUTE);\n\n    // MOMENTS\n\n    var getSetMinute = makeGetSet('Minutes', false);\n\n    // FORMATTING\n\n    addFormatToken('s', ['ss', 2], 0, 'second');\n\n    // ALIASES\n\n    addUnitAlias('second', 's');\n\n    // PRIORITY\n\n    addUnitPriority('second', 15);\n\n    // PARSING\n\n    addRegexToken('s',  match1to2);\n    addRegexToken('ss', match1to2, match2);\n    addParseToken(['s', 'ss'], SECOND);\n\n    // MOMENTS\n\n    var getSetSecond = makeGetSet('Seconds', false);\n\n    // FORMATTING\n\n    addFormatToken('S', 0, 0, function () {\n        return ~~(this.millisecond() / 100);\n    });\n\n    addFormatToken(0, ['SS', 2], 0, function () {\n        return ~~(this.millisecond() / 10);\n    });\n\n    addFormatToken(0, ['SSS', 3], 0, 'millisecond');\n    addFormatToken(0, ['SSSS', 4], 0, function () {\n        return this.millisecond() * 10;\n    });\n    addFormatToken(0, ['SSSSS', 5], 0, function () {\n        return this.millisecond() * 100;\n    });\n    addFormatToken(0, ['SSSSSS', 6], 0, function () {\n        return this.millisecond() * 1000;\n    });\n    addFormatToken(0, ['SSSSSSS', 7], 0, function () {\n        return this.millisecond() * 10000;\n    });\n    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {\n        return this.millisecond() * 100000;\n    });\n    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {\n        return this.millisecond() * 1000000;\n    });\n\n\n    // ALIASES\n\n    addUnitAlias('millisecond', 'ms');\n\n    // PRIORITY\n\n    addUnitPriority('millisecond', 16);\n\n    // PARSING\n\n    addRegexToken('S',    match1to3, match1);\n    addRegexToken('SS',   match1to3, match2);\n    addRegexToken('SSS',  match1to3, match3);\n\n    var token;\n    for (token = 'SSSS'; token.length <= 9; token += 'S') {\n        addRegexToken(token, matchUnsigned);\n    }\n\n    function parseMs(input, array) {\n        array[MILLISECOND] = toInt(('0.' + input) * 1000);\n    }\n\n    for (token = 'S'; token.length <= 9; token += 'S') {\n        addParseToken(token, parseMs);\n    }\n    // MOMENTS\n\n    var getSetMillisecond = makeGetSet('Milliseconds', false);\n\n    // FORMATTING\n\n    addFormatToken('z',  0, 0, 'zoneAbbr');\n    addFormatToken('zz', 0, 0, 'zoneName');\n\n    // MOMENTS\n\n    function getZoneAbbr () {\n        return this._isUTC ? 'UTC' : '';\n    }\n\n    function getZoneName () {\n        return this._isUTC ? 'Coordinated Universal Time' : '';\n    }\n\n    var proto = Moment.prototype;\n\n    proto.add               = add;\n    proto.calendar          = calendar$1;\n    proto.clone             = clone;\n    proto.diff              = diff;\n    proto.endOf             = endOf;\n    proto.format            = format;\n    proto.from              = from;\n    proto.fromNow           = fromNow;\n    proto.to                = to;\n    proto.toNow             = toNow;\n    proto.get               = stringGet;\n    proto.invalidAt         = invalidAt;\n    proto.isAfter           = isAfter;\n    proto.isBefore          = isBefore;\n    proto.isBetween         = isBetween;\n    proto.isSame            = isSame;\n    proto.isSameOrAfter     = isSameOrAfter;\n    proto.isSameOrBefore    = isSameOrBefore;\n    proto.isValid           = isValid$2;\n    proto.lang              = lang;\n    proto.locale            = locale;\n    proto.localeData        = localeData;\n    proto.max               = prototypeMax;\n    proto.min               = prototypeMin;\n    proto.parsingFlags      = parsingFlags;\n    proto.set               = stringSet;\n    proto.startOf           = startOf;\n    proto.subtract          = subtract;\n    proto.toArray           = toArray;\n    proto.toObject          = toObject;\n    proto.toDate            = toDate;\n    proto.toISOString       = toISOString;\n    proto.inspect           = inspect;\n    proto.toJSON            = toJSON;\n    proto.toString          = toString;\n    proto.unix              = unix;\n    proto.valueOf           = valueOf;\n    proto.creationData      = creationData;\n    proto.year       = getSetYear;\n    proto.isLeapYear = getIsLeapYear;\n    proto.weekYear    = getSetWeekYear;\n    proto.isoWeekYear = getSetISOWeekYear;\n    proto.quarter = proto.quarters = getSetQuarter;\n    proto.month       = getSetMonth;\n    proto.daysInMonth = getDaysInMonth;\n    proto.week           = proto.weeks        = getSetWeek;\n    proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\n    proto.weeksInYear    = getWeeksInYear;\n    proto.isoWeeksInYear = getISOWeeksInYear;\n    proto.date       = getSetDayOfMonth;\n    proto.day        = proto.days             = getSetDayOfWeek;\n    proto.weekday    = getSetLocaleDayOfWeek;\n    proto.isoWeekday = getSetISODayOfWeek;\n    proto.dayOfYear  = getSetDayOfYear;\n    proto.hour = proto.hours = getSetHour;\n    proto.minute = proto.minutes = getSetMinute;\n    proto.second = proto.seconds = getSetSecond;\n    proto.millisecond = proto.milliseconds = getSetMillisecond;\n    proto.utcOffset            = getSetOffset;\n    proto.utc                  = setOffsetToUTC;\n    proto.local                = setOffsetToLocal;\n    proto.parseZone            = setOffsetToParsedOffset;\n    proto.hasAlignedHourOffset = hasAlignedHourOffset;\n    proto.isDST                = isDaylightSavingTime;\n    proto.isLocal              = isLocal;\n    proto.isUtcOffset          = isUtcOffset;\n    proto.isUtc                = isUtc;\n    proto.isUTC                = isUtc;\n    proto.zoneAbbr = getZoneAbbr;\n    proto.zoneName = getZoneName;\n    proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\n    proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\n    proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\n    proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);\n    proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);\n\n    function createUnix (input) {\n        return createLocal(input * 1000);\n    }\n\n    function createInZone () {\n        return createLocal.apply(null, arguments).parseZone();\n    }\n\n    function preParsePostFormat (string) {\n        return string;\n    }\n\n    var proto$1 = Locale.prototype;\n\n    proto$1.calendar        = calendar;\n    proto$1.longDateFormat  = longDateFormat;\n    proto$1.invalidDate     = invalidDate;\n    proto$1.ordinal         = ordinal;\n    proto$1.preparse        = preParsePostFormat;\n    proto$1.postformat      = preParsePostFormat;\n    proto$1.relativeTime    = relativeTime;\n    proto$1.pastFuture      = pastFuture;\n    proto$1.set             = set;\n\n    proto$1.months            =        localeMonths;\n    proto$1.monthsShort       =        localeMonthsShort;\n    proto$1.monthsParse       =        localeMonthsParse;\n    proto$1.monthsRegex       = monthsRegex;\n    proto$1.monthsShortRegex  = monthsShortRegex;\n    proto$1.week = localeWeek;\n    proto$1.firstDayOfYear = localeFirstDayOfYear;\n    proto$1.firstDayOfWeek = localeFirstDayOfWeek;\n\n    proto$1.weekdays       =        localeWeekdays;\n    proto$1.weekdaysMin    =        localeWeekdaysMin;\n    proto$1.weekdaysShort  =        localeWeekdaysShort;\n    proto$1.weekdaysParse  =        localeWeekdaysParse;\n\n    proto$1.weekdaysRegex       =        weekdaysRegex;\n    proto$1.weekdaysShortRegex  =        weekdaysShortRegex;\n    proto$1.weekdaysMinRegex    =        weekdaysMinRegex;\n\n    proto$1.isPM = localeIsPM;\n    proto$1.meridiem = localeMeridiem;\n\n    function get$1 (format, index, field, setter) {\n        var locale = getLocale();\n        var utc = createUTC().set(setter, index);\n        return locale[field](utc, format);\n    }\n\n    function listMonthsImpl (format, index, field) {\n        if (isNumber(format)) {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n\n        if (index != null) {\n            return get$1(format, index, field, 'month');\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < 12; i++) {\n            out[i] = get$1(format, i, field, 'month');\n        }\n        return out;\n    }\n\n    // ()\n    // (5)\n    // (fmt, 5)\n    // (fmt)\n    // (true)\n    // (true, 5)\n    // (true, fmt, 5)\n    // (true, fmt)\n    function listWeekdaysImpl (localeSorted, format, index, field) {\n        if (typeof localeSorted === 'boolean') {\n            if (isNumber(format)) {\n                index = format;\n                format = undefined;\n            }\n\n            format = format || '';\n        } else {\n            format = localeSorted;\n            index = format;\n            localeSorted = false;\n\n            if (isNumber(format)) {\n                index = format;\n                format = undefined;\n            }\n\n            format = format || '';\n        }\n\n        var locale = getLocale(),\n            shift = localeSorted ? locale._week.dow : 0;\n\n        if (index != null) {\n            return get$1(format, (index + shift) % 7, field, 'day');\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < 7; i++) {\n            out[i] = get$1(format, (i + shift) % 7, field, 'day');\n        }\n        return out;\n    }\n\n    function listMonths (format, index) {\n        return listMonthsImpl(format, index, 'months');\n    }\n\n    function listMonthsShort (format, index) {\n        return listMonthsImpl(format, index, 'monthsShort');\n    }\n\n    function listWeekdays (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');\n    }\n\n    function listWeekdaysShort (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');\n    }\n\n    function listWeekdaysMin (localeSorted, format, index) {\n        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');\n    }\n\n    getSetGlobalLocale('en', {\n        dayOfMonthOrdinalParse: /\\d{1,2}(th|st|nd|rd)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (toInt(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    // Side effect imports\n\n    hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\n    hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\n    var mathAbs = Math.abs;\n\n    function abs () {\n        var data           = this._data;\n\n        this._milliseconds = mathAbs(this._milliseconds);\n        this._days         = mathAbs(this._days);\n        this._months       = mathAbs(this._months);\n\n        data.milliseconds  = mathAbs(data.milliseconds);\n        data.seconds       = mathAbs(data.seconds);\n        data.minutes       = mathAbs(data.minutes);\n        data.hours         = mathAbs(data.hours);\n        data.months        = mathAbs(data.months);\n        data.years         = mathAbs(data.years);\n\n        return this;\n    }\n\n    function addSubtract$1 (duration, input, value, direction) {\n        var other = createDuration(input, value);\n\n        duration._milliseconds += direction * other._milliseconds;\n        duration._days         += direction * other._days;\n        duration._months       += direction * other._months;\n\n        return duration._bubble();\n    }\n\n    // supports only 2.0-style add(1, 's') or add(duration)\n    function add$1 (input, value) {\n        return addSubtract$1(this, input, value, 1);\n    }\n\n    // supports only 2.0-style subtract(1, 's') or subtract(duration)\n    function subtract$1 (input, value) {\n        return addSubtract$1(this, input, value, -1);\n    }\n\n    function absCeil (number) {\n        if (number < 0) {\n            return Math.floor(number);\n        } else {\n            return Math.ceil(number);\n        }\n    }\n\n    function bubble () {\n        var milliseconds = this._milliseconds;\n        var days         = this._days;\n        var months       = this._months;\n        var data         = this._data;\n        var seconds, minutes, hours, years, monthsFromDays;\n\n        // if we have a mix of positive and negative values, bubble down first\n        // check: https://github.com/moment/moment/issues/2166\n        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||\n                (milliseconds <= 0 && days <= 0 && months <= 0))) {\n            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;\n            days = 0;\n            months = 0;\n        }\n\n        // The following code bubbles up values, see the tests for\n        // examples of what that means.\n        data.milliseconds = milliseconds % 1000;\n\n        seconds           = absFloor(milliseconds / 1000);\n        data.seconds      = seconds % 60;\n\n        minutes           = absFloor(seconds / 60);\n        data.minutes      = minutes % 60;\n\n        hours             = absFloor(minutes / 60);\n        data.hours        = hours % 24;\n\n        days += absFloor(hours / 24);\n\n        // convert days to months\n        monthsFromDays = absFloor(daysToMonths(days));\n        months += monthsFromDays;\n        days -= absCeil(monthsToDays(monthsFromDays));\n\n        // 12 months -> 1 year\n        years = absFloor(months / 12);\n        months %= 12;\n\n        data.days   = days;\n        data.months = months;\n        data.years  = years;\n\n        return this;\n    }\n\n    function daysToMonths (days) {\n        // 400 years have 146097 days (taking into account leap year rules)\n        // 400 years have 12 months === 4800\n        return days * 4800 / 146097;\n    }\n\n    function monthsToDays (months) {\n        // the reverse of daysToMonths\n        return months * 146097 / 4800;\n    }\n\n    function as (units) {\n        if (!this.isValid()) {\n            return NaN;\n        }\n        var days;\n        var months;\n        var milliseconds = this._milliseconds;\n\n        units = normalizeUnits(units);\n\n        if (units === 'month' || units === 'quarter' || units === 'year') {\n            days = this._days + milliseconds / 864e5;\n            months = this._months + daysToMonths(days);\n            switch (units) {\n                case 'month':   return months;\n                case 'quarter': return months / 3;\n                case 'year':    return months / 12;\n            }\n        } else {\n            // handle milliseconds separately because of floating point math errors (issue #1867)\n            days = this._days + Math.round(monthsToDays(this._months));\n            switch (units) {\n                case 'week'   : return days / 7     + milliseconds / 6048e5;\n                case 'day'    : return days         + milliseconds / 864e5;\n                case 'hour'   : return days * 24    + milliseconds / 36e5;\n                case 'minute' : return days * 1440  + milliseconds / 6e4;\n                case 'second' : return days * 86400 + milliseconds / 1000;\n                // Math.floor prevents floating point math errors here\n                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;\n                default: throw new Error('Unknown unit ' + units);\n            }\n        }\n    }\n\n    // TODO: Use this.as('ms')?\n    function valueOf$1 () {\n        if (!this.isValid()) {\n            return NaN;\n        }\n        return (\n            this._milliseconds +\n            this._days * 864e5 +\n            (this._months % 12) * 2592e6 +\n            toInt(this._months / 12) * 31536e6\n        );\n    }\n\n    function makeAs (alias) {\n        return function () {\n            return this.as(alias);\n        };\n    }\n\n    var asMilliseconds = makeAs('ms');\n    var asSeconds      = makeAs('s');\n    var asMinutes      = makeAs('m');\n    var asHours        = makeAs('h');\n    var asDays         = makeAs('d');\n    var asWeeks        = makeAs('w');\n    var asMonths       = makeAs('M');\n    var asQuarters     = makeAs('Q');\n    var asYears        = makeAs('y');\n\n    function clone$1 () {\n        return createDuration(this);\n    }\n\n    function get$2 (units) {\n        units = normalizeUnits(units);\n        return this.isValid() ? this[units + 's']() : NaN;\n    }\n\n    function makeGetter(name) {\n        return function () {\n            return this.isValid() ? this._data[name] : NaN;\n        };\n    }\n\n    var milliseconds = makeGetter('milliseconds');\n    var seconds      = makeGetter('seconds');\n    var minutes      = makeGetter('minutes');\n    var hours        = makeGetter('hours');\n    var days         = makeGetter('days');\n    var months       = makeGetter('months');\n    var years        = makeGetter('years');\n\n    function weeks () {\n        return absFloor(this.days() / 7);\n    }\n\n    var round = Math.round;\n    var thresholds = {\n        ss: 44,         // a few seconds to seconds\n        s : 45,         // seconds to minute\n        m : 45,         // minutes to hour\n        h : 22,         // hours to day\n        d : 26,         // days to month\n        M : 11          // months to year\n    };\n\n    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\n    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n    }\n\n    function relativeTime$1 (posNegDuration, withoutSuffix, locale) {\n        var duration = createDuration(posNegDuration).abs();\n        var seconds  = round(duration.as('s'));\n        var minutes  = round(duration.as('m'));\n        var hours    = round(duration.as('h'));\n        var days     = round(duration.as('d'));\n        var months   = round(duration.as('M'));\n        var years    = round(duration.as('y'));\n\n        var a = seconds <= thresholds.ss && ['s', seconds]  ||\n                seconds < thresholds.s   && ['ss', seconds] ||\n                minutes <= 1             && ['m']           ||\n                minutes < thresholds.m   && ['mm', minutes] ||\n                hours   <= 1             && ['h']           ||\n                hours   < thresholds.h   && ['hh', hours]   ||\n                days    <= 1             && ['d']           ||\n                days    < thresholds.d   && ['dd', days]    ||\n                months  <= 1             && ['M']           ||\n                months  < thresholds.M   && ['MM', months]  ||\n                years   <= 1             && ['y']           || ['yy', years];\n\n        a[2] = withoutSuffix;\n        a[3] = +posNegDuration > 0;\n        a[4] = locale;\n        return substituteTimeAgo.apply(null, a);\n    }\n\n    // This function allows you to set the rounding function for relative time strings\n    function getSetRelativeTimeRounding (roundingFunction) {\n        if (roundingFunction === undefined) {\n            return round;\n        }\n        if (typeof(roundingFunction) === 'function') {\n            round = roundingFunction;\n            return true;\n        }\n        return false;\n    }\n\n    // This function allows you to set a threshold for relative time strings\n    function getSetRelativeTimeThreshold (threshold, limit) {\n        if (thresholds[threshold] === undefined) {\n            return false;\n        }\n        if (limit === undefined) {\n            return thresholds[threshold];\n        }\n        thresholds[threshold] = limit;\n        if (threshold === 's') {\n            thresholds.ss = limit - 1;\n        }\n        return true;\n    }\n\n    function humanize (withSuffix) {\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n\n        var locale = this.localeData();\n        var output = relativeTime$1(this, !withSuffix, locale);\n\n        if (withSuffix) {\n            output = locale.pastFuture(+this, output);\n        }\n\n        return locale.postformat(output);\n    }\n\n    var abs$1 = Math.abs;\n\n    function sign(x) {\n        return ((x > 0) - (x < 0)) || +x;\n    }\n\n    function toISOString$1() {\n        // for ISO strings we do not use the normal bubbling rules:\n        //  * milliseconds bubble up until they become hours\n        //  * days do not bubble at all\n        //  * months bubble up until they become years\n        // This is because there is no context-free conversion between hours and days\n        // (think of clock changes)\n        // and also not between days and months (28-31 days per month)\n        if (!this.isValid()) {\n            return this.localeData().invalidDate();\n        }\n\n        var seconds = abs$1(this._milliseconds) / 1000;\n        var days         = abs$1(this._days);\n        var months       = abs$1(this._months);\n        var minutes, hours, years;\n\n        // 3600 seconds -> 60 minutes -> 1 hour\n        minutes           = absFloor(seconds / 60);\n        hours             = absFloor(minutes / 60);\n        seconds %= 60;\n        minutes %= 60;\n\n        // 12 months -> 1 year\n        years  = absFloor(months / 12);\n        months %= 12;\n\n\n        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n        var Y = years;\n        var M = months;\n        var D = days;\n        var h = hours;\n        var m = minutes;\n        var s = seconds ? seconds.toFixed(3).replace(/\\.?0+$/, '') : '';\n        var total = this.asSeconds();\n\n        if (!total) {\n            // this is the same as C#'s (Noda) and python (isodate)...\n            // but not other JS (goog.date)\n            return 'P0D';\n        }\n\n        var totalSign = total < 0 ? '-' : '';\n        var ymSign = sign(this._months) !== sign(total) ? '-' : '';\n        var daysSign = sign(this._days) !== sign(total) ? '-' : '';\n        var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';\n\n        return totalSign + 'P' +\n            (Y ? ymSign + Y + 'Y' : '') +\n            (M ? ymSign + M + 'M' : '') +\n            (D ? daysSign + D + 'D' : '') +\n            ((h || m || s) ? 'T' : '') +\n            (h ? hmsSign + h + 'H' : '') +\n            (m ? hmsSign + m + 'M' : '') +\n            (s ? hmsSign + s + 'S' : '');\n    }\n\n    var proto$2 = Duration.prototype;\n\n    proto$2.isValid        = isValid$1;\n    proto$2.abs            = abs;\n    proto$2.add            = add$1;\n    proto$2.subtract       = subtract$1;\n    proto$2.as             = as;\n    proto$2.asMilliseconds = asMilliseconds;\n    proto$2.asSeconds      = asSeconds;\n    proto$2.asMinutes      = asMinutes;\n    proto$2.asHours        = asHours;\n    proto$2.asDays         = asDays;\n    proto$2.asWeeks        = asWeeks;\n    proto$2.asMonths       = asMonths;\n    proto$2.asQuarters     = asQuarters;\n    proto$2.asYears        = asYears;\n    proto$2.valueOf        = valueOf$1;\n    proto$2._bubble        = bubble;\n    proto$2.clone          = clone$1;\n    proto$2.get            = get$2;\n    proto$2.milliseconds   = milliseconds;\n    proto$2.seconds        = seconds;\n    proto$2.minutes        = minutes;\n    proto$2.hours          = hours;\n    proto$2.days           = days;\n    proto$2.weeks          = weeks;\n    proto$2.months         = months;\n    proto$2.years          = years;\n    proto$2.humanize       = humanize;\n    proto$2.toISOString    = toISOString$1;\n    proto$2.toString       = toISOString$1;\n    proto$2.toJSON         = toISOString$1;\n    proto$2.locale         = locale;\n    proto$2.localeData     = localeData;\n\n    proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);\n    proto$2.lang = lang;\n\n    // Side effect imports\n\n    // FORMATTING\n\n    addFormatToken('X', 0, 0, 'unix');\n    addFormatToken('x', 0, 0, 'valueOf');\n\n    // PARSING\n\n    addRegexToken('x', matchSigned);\n    addRegexToken('X', matchTimestamp);\n    addParseToken('X', function (input, array, config) {\n        config._d = new Date(parseFloat(input, 10) * 1000);\n    });\n    addParseToken('x', function (input, array, config) {\n        config._d = new Date(toInt(input));\n    });\n\n    // Side effect imports\n\n\n    hooks.version = '2.24.0';\n\n    setHookCallback(createLocal);\n\n    hooks.fn                    = proto;\n    hooks.min                   = min;\n    hooks.max                   = max;\n    hooks.now                   = now;\n    hooks.utc                   = createUTC;\n    hooks.unix                  = createUnix;\n    hooks.months                = listMonths;\n    hooks.isDate                = isDate;\n    hooks.locale                = getSetGlobalLocale;\n    hooks.invalid               = createInvalid;\n    hooks.duration              = createDuration;\n    hooks.isMoment              = isMoment;\n    hooks.weekdays              = listWeekdays;\n    hooks.parseZone             = createInZone;\n    hooks.localeData            = getLocale;\n    hooks.isDuration            = isDuration;\n    hooks.monthsShort           = listMonthsShort;\n    hooks.weekdaysMin           = listWeekdaysMin;\n    hooks.defineLocale          = defineLocale;\n    hooks.updateLocale          = updateLocale;\n    hooks.locales               = listLocales;\n    hooks.weekdaysShort         = listWeekdaysShort;\n    hooks.normalizeUnits        = normalizeUnits;\n    hooks.relativeTimeRounding  = getSetRelativeTimeRounding;\n    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;\n    hooks.calendarFormat        = getCalendarFormat;\n    hooks.prototype             = proto;\n\n    // currently HTML5 input type only supports 24-hour formats\n    hooks.HTML5_FMT = {\n        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type=\"datetime-local\" />\n        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type=\"datetime-local\" step=\"1\" />\n        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type=\"datetime-local\" step=\"0.001\" />\n        DATE: 'YYYY-MM-DD',                             // <input type=\"date\" />\n        TIME: 'HH:mm',                                  // <input type=\"time\" />\n        TIME_SECONDS: 'HH:mm:ss',                       // <input type=\"time\" step=\"1\" />\n        TIME_MS: 'HH:mm:ss.SSS',                        // <input type=\"time\" step=\"0.001\" />\n        WEEK: 'GGGG-[W]WW',                             // <input type=\"week\" />\n        MONTH: 'YYYY-MM'                                // <input type=\"month\" />\n    };\n\n    return hooks;\n\n})));\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/module.js */ \"f586\")(module)))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGEwMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9tb21lbnQvbW9tZW50LmpzP2MxZGYiXSwic291cmNlc0NvbnRlbnQiOlsiLy8hIG1vbWVudC5qc1xuXG47KGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG4gICAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgICBnbG9iYWwubW9tZW50ID0gZmFjdG9yeSgpXG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuICAgIHZhciBob29rQ2FsbGJhY2s7XG5cbiAgICBmdW5jdGlvbiBob29rcyAoKSB7XG4gICAgICAgIHJldHVybiBob29rQ2FsbGJhY2suYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGlzIGRvbmUgdG8gcmVnaXN0ZXIgdGhlIG1ldGhvZCBjYWxsZWQgd2l0aCBtb21lbnQoKVxuICAgIC8vIHdpdGhvdXQgY3JlYXRpbmcgY2lyY3VsYXIgZGVwZW5kZW5jaWVzLlxuICAgIGZ1bmN0aW9uIHNldEhvb2tDYWxsYmFjayAoY2FsbGJhY2spIHtcbiAgICAgICAgaG9va0NhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBcnJheShpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXQgaW5zdGFuY2VvZiBBcnJheSB8fCBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaW5wdXQpID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzT2JqZWN0KGlucHV0KSB7XG4gICAgICAgIC8vIElFOCB3aWxsIHRyZWF0IHVuZGVmaW5lZCBhbmQgbnVsbCBhcyBvYmplY3QgaWYgaXQgd2Fzbid0IGZvclxuICAgICAgICAvLyBpbnB1dCAhPSBudWxsXG4gICAgICAgIHJldHVybiBpbnB1dCAhPSBudWxsICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IE9iamVjdF0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzT2JqZWN0RW1wdHkob2JqKSB7XG4gICAgICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcykge1xuICAgICAgICAgICAgcmV0dXJuIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLmxlbmd0aCA9PT0gMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaztcbiAgICAgICAgICAgIGZvciAoayBpbiBvYmopIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVW5kZWZpbmVkKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBpbnB1dCA9PT0gdm9pZCAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzTnVtYmVyKGlucHV0KSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IE51bWJlcl0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzRGF0ZShpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXQgaW5zdGFuY2VvZiBEYXRlIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IERhdGVdJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXAoYXJyLCBmbikge1xuICAgICAgICB2YXIgcmVzID0gW10sIGk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHJlcy5wdXNoKGZuKGFycltpXSwgaSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzT3duUHJvcChhLCBiKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSwgYik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXh0ZW5kKGEsIGIpIHtcbiAgICAgICAgZm9yICh2YXIgaSBpbiBiKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChiLCBpKSkge1xuICAgICAgICAgICAgICAgIGFbaV0gPSBiW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc093blByb3AoYiwgJ3RvU3RyaW5nJykpIHtcbiAgICAgICAgICAgIGEudG9TdHJpbmcgPSBiLnRvU3RyaW5nO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc093blByb3AoYiwgJ3ZhbHVlT2YnKSkge1xuICAgICAgICAgICAgYS52YWx1ZU9mID0gYi52YWx1ZU9mO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlVVRDIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWxPclVUQyhpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCwgdHJ1ZSkudXRjKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmYXVsdFBhcnNpbmdGbGFncygpIHtcbiAgICAgICAgLy8gV2UgbmVlZCB0byBkZWVwIGNsb25lIHRoaXMgb2JqZWN0LlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZW1wdHkgICAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICB1bnVzZWRUb2tlbnMgICAgOiBbXSxcbiAgICAgICAgICAgIHVudXNlZElucHV0ICAgICA6IFtdLFxuICAgICAgICAgICAgb3ZlcmZsb3cgICAgICAgIDogLTIsXG4gICAgICAgICAgICBjaGFyc0xlZnRPdmVyICAgOiAwLFxuICAgICAgICAgICAgbnVsbElucHV0ICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICBpbnZhbGlkTW9udGggICAgOiBudWxsLFxuICAgICAgICAgICAgaW52YWxpZEZvcm1hdCAgIDogZmFsc2UsXG4gICAgICAgICAgICB1c2VySW52YWxpZGF0ZWQgOiBmYWxzZSxcbiAgICAgICAgICAgIGlzbyAgICAgICAgICAgICA6IGZhbHNlLFxuICAgICAgICAgICAgcGFyc2VkRGF0ZVBhcnRzIDogW10sXG4gICAgICAgICAgICBtZXJpZGllbSAgICAgICAgOiBudWxsLFxuICAgICAgICAgICAgcmZjMjgyMiAgICAgICAgIDogZmFsc2UsXG4gICAgICAgICAgICB3ZWVrZGF5TWlzbWF0Y2ggOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFBhcnNpbmdGbGFncyhtKSB7XG4gICAgICAgIGlmIChtLl9wZiA9PSBudWxsKSB7XG4gICAgICAgICAgICBtLl9wZiA9IGRlZmF1bHRQYXJzaW5nRmxhZ3MoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbS5fcGY7XG4gICAgfVxuXG4gICAgdmFyIHNvbWU7XG4gICAgaWYgKEFycmF5LnByb3RvdHlwZS5zb21lKSB7XG4gICAgICAgIHNvbWUgPSBBcnJheS5wcm90b3R5cGUuc29tZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBzb21lID0gZnVuY3Rpb24gKGZ1bikge1xuICAgICAgICAgICAgdmFyIHQgPSBPYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgbGVuID0gdC5sZW5ndGggPj4+IDA7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiB0ICYmIGZ1bi5jYWxsKHRoaXMsIHRbaV0sIGksIHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVmFsaWQobSkge1xuICAgICAgICBpZiAobS5faXNWYWxpZCA9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgZmxhZ3MgPSBnZXRQYXJzaW5nRmxhZ3MobSk7XG4gICAgICAgICAgICB2YXIgcGFyc2VkUGFydHMgPSBzb21lLmNhbGwoZmxhZ3MucGFyc2VkRGF0ZVBhcnRzLCBmdW5jdGlvbiAoaSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpICE9IG51bGw7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhciBpc05vd1ZhbGlkID0gIWlzTmFOKG0uX2QuZ2V0VGltZSgpKSAmJlxuICAgICAgICAgICAgICAgIGZsYWdzLm92ZXJmbG93IDwgMCAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5lbXB0eSAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5pbnZhbGlkTW9udGggJiZcbiAgICAgICAgICAgICAgICAhZmxhZ3MuaW52YWxpZFdlZWtkYXkgJiZcbiAgICAgICAgICAgICAgICAhZmxhZ3Mud2Vla2RheU1pc21hdGNoICYmXG4gICAgICAgICAgICAgICAgIWZsYWdzLm51bGxJbnB1dCAmJlxuICAgICAgICAgICAgICAgICFmbGFncy5pbnZhbGlkRm9ybWF0ICYmXG4gICAgICAgICAgICAgICAgIWZsYWdzLnVzZXJJbnZhbGlkYXRlZCAmJlxuICAgICAgICAgICAgICAgICghZmxhZ3MubWVyaWRpZW0gfHwgKGZsYWdzLm1lcmlkaWVtICYmIHBhcnNlZFBhcnRzKSk7XG5cbiAgICAgICAgICAgIGlmIChtLl9zdHJpY3QpIHtcbiAgICAgICAgICAgICAgICBpc05vd1ZhbGlkID0gaXNOb3dWYWxpZCAmJlxuICAgICAgICAgICAgICAgICAgICBmbGFncy5jaGFyc0xlZnRPdmVyID09PSAwICYmXG4gICAgICAgICAgICAgICAgICAgIGZsYWdzLnVudXNlZFRva2Vucy5sZW5ndGggPT09IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgZmxhZ3MuYmlnSG91ciA9PT0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoT2JqZWN0LmlzRnJvemVuID09IG51bGwgfHwgIU9iamVjdC5pc0Zyb3plbihtKSkge1xuICAgICAgICAgICAgICAgIG0uX2lzVmFsaWQgPSBpc05vd1ZhbGlkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzTm93VmFsaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG0uX2lzVmFsaWQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlSW52YWxpZCAoZmxhZ3MpIHtcbiAgICAgICAgdmFyIG0gPSBjcmVhdGVVVEMoTmFOKTtcbiAgICAgICAgaWYgKGZsYWdzICE9IG51bGwpIHtcbiAgICAgICAgICAgIGV4dGVuZChnZXRQYXJzaW5nRmxhZ3MobSksIGZsYWdzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhtKS51c2VySW52YWxpZGF0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG07XG4gICAgfVxuXG4gICAgLy8gUGx1Z2lucyB0aGF0IGFkZCBwcm9wZXJ0aWVzIHNob3VsZCBhbHNvIGFkZCB0aGUga2V5IGhlcmUgKG51bGwgdmFsdWUpLFxuICAgIC8vIHNvIHdlIGNhbiBwcm9wZXJseSBjbG9uZSBvdXJzZWx2ZXMuXG4gICAgdmFyIG1vbWVudFByb3BlcnRpZXMgPSBob29rcy5tb21lbnRQcm9wZXJ0aWVzID0gW107XG5cbiAgICBmdW5jdGlvbiBjb3B5Q29uZmlnKHRvLCBmcm9tKSB7XG4gICAgICAgIHZhciBpLCBwcm9wLCB2YWw7XG5cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9pc0FNb21lbnRPYmplY3QpKSB7XG4gICAgICAgICAgICB0by5faXNBTW9tZW50T2JqZWN0ID0gZnJvbS5faXNBTW9tZW50T2JqZWN0O1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5faSkpIHtcbiAgICAgICAgICAgIHRvLl9pID0gZnJvbS5faTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX2YpKSB7XG4gICAgICAgICAgICB0by5fZiA9IGZyb20uX2Y7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9sKSkge1xuICAgICAgICAgICAgdG8uX2wgPSBmcm9tLl9sO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fc3RyaWN0KSkge1xuICAgICAgICAgICAgdG8uX3N0cmljdCA9IGZyb20uX3N0cmljdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX3R6bSkpIHtcbiAgICAgICAgICAgIHRvLl90em0gPSBmcm9tLl90em07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZChmcm9tLl9pc1VUQykpIHtcbiAgICAgICAgICAgIHRvLl9pc1VUQyA9IGZyb20uX2lzVVRDO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fb2Zmc2V0KSkge1xuICAgICAgICAgICAgdG8uX29mZnNldCA9IGZyb20uX29mZnNldDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKGZyb20uX3BmKSkge1xuICAgICAgICAgICAgdG8uX3BmID0gZ2V0UGFyc2luZ0ZsYWdzKGZyb20pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNVbmRlZmluZWQoZnJvbS5fbG9jYWxlKSkge1xuICAgICAgICAgICAgdG8uX2xvY2FsZSA9IGZyb20uX2xvY2FsZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtb21lbnRQcm9wZXJ0aWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBtb21lbnRQcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcHJvcCA9IG1vbWVudFByb3BlcnRpZXNbaV07XG4gICAgICAgICAgICAgICAgdmFsID0gZnJvbVtwcm9wXTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzVW5kZWZpbmVkKHZhbCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9bcHJvcF0gPSB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRvO1xuICAgIH1cblxuICAgIHZhciB1cGRhdGVJblByb2dyZXNzID0gZmFsc2U7XG5cbiAgICAvLyBNb21lbnQgcHJvdG90eXBlIG9iamVjdFxuICAgIGZ1bmN0aW9uIE1vbWVudChjb25maWcpIHtcbiAgICAgICAgY29weUNvbmZpZyh0aGlzLCBjb25maWcpO1xuICAgICAgICB0aGlzLl9kID0gbmV3IERhdGUoY29uZmlnLl9kICE9IG51bGwgPyBjb25maWcuX2QuZ2V0VGltZSgpIDogTmFOKTtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgdGhpcy5fZCA9IG5ldyBEYXRlKE5hTik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUHJldmVudCBpbmZpbml0ZSBsb29wIGluIGNhc2UgdXBkYXRlT2Zmc2V0IGNyZWF0ZXMgbmV3IG1vbWVudFxuICAgICAgICAvLyBvYmplY3RzLlxuICAgICAgICBpZiAodXBkYXRlSW5Qcm9ncmVzcyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHVwZGF0ZUluUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMpO1xuICAgICAgICAgICAgdXBkYXRlSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNNb21lbnQgKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgTW9tZW50IHx8IChvYmogIT0gbnVsbCAmJiBvYmouX2lzQU1vbWVudE9iamVjdCAhPSBudWxsKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhYnNGbG9vciAobnVtYmVyKSB7XG4gICAgICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICAgICAgICAvLyAtMCAtPiAwXG4gICAgICAgICAgICByZXR1cm4gTWF0aC5jZWlsKG51bWJlcikgfHwgMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKG51bWJlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0ludChhcmd1bWVudEZvckNvZXJjaW9uKSB7XG4gICAgICAgIHZhciBjb2VyY2VkTnVtYmVyID0gK2FyZ3VtZW50Rm9yQ29lcmNpb24sXG4gICAgICAgICAgICB2YWx1ZSA9IDA7XG5cbiAgICAgICAgaWYgKGNvZXJjZWROdW1iZXIgIT09IDAgJiYgaXNGaW5pdGUoY29lcmNlZE51bWJlcikpIHtcbiAgICAgICAgICAgIHZhbHVlID0gYWJzRmxvb3IoY29lcmNlZE51bWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gY29tcGFyZSB0d28gYXJyYXlzLCByZXR1cm4gdGhlIG51bWJlciBvZiBkaWZmZXJlbmNlc1xuICAgIGZ1bmN0aW9uIGNvbXBhcmVBcnJheXMoYXJyYXkxLCBhcnJheTIsIGRvbnRDb252ZXJ0KSB7XG4gICAgICAgIHZhciBsZW4gPSBNYXRoLm1pbihhcnJheTEubGVuZ3RoLCBhcnJheTIubGVuZ3RoKSxcbiAgICAgICAgICAgIGxlbmd0aERpZmYgPSBNYXRoLmFicyhhcnJheTEubGVuZ3RoIC0gYXJyYXkyLmxlbmd0aCksXG4gICAgICAgICAgICBkaWZmcyA9IDAsXG4gICAgICAgICAgICBpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmICgoZG9udENvbnZlcnQgJiYgYXJyYXkxW2ldICE9PSBhcnJheTJbaV0pIHx8XG4gICAgICAgICAgICAgICAgKCFkb250Q29udmVydCAmJiB0b0ludChhcnJheTFbaV0pICE9PSB0b0ludChhcnJheTJbaV0pKSkge1xuICAgICAgICAgICAgICAgIGRpZmZzKys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRpZmZzICsgbGVuZ3RoRGlmZjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3YXJuKG1zZykge1xuICAgICAgICBpZiAoaG9va3Muc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmdzID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgICh0eXBlb2YgY29uc29sZSAhPT0gICd1bmRlZmluZWQnKSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRGVwcmVjYXRpb24gd2FybmluZzogJyArIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkZXByZWNhdGUobXNnLCBmbikge1xuICAgICAgICB2YXIgZmlyc3RUaW1lID0gdHJ1ZTtcblxuICAgICAgICByZXR1cm4gZXh0ZW5kKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChob29rcy5kZXByZWNhdGlvbkhhbmRsZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGhvb2tzLmRlcHJlY2F0aW9uSGFuZGxlcihudWxsLCBtc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZpcnN0VGltZSkge1xuICAgICAgICAgICAgICAgIHZhciBhcmdzID0gW107XG4gICAgICAgICAgICAgICAgdmFyIGFyZztcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBhcmcgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbaV0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgKz0gJ1xcblsnICsgaSArICddICc7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gYXJndW1lbnRzWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnICs9IGtleSArICc6ICcgKyBhcmd1bWVudHNbMF1ba2V5XSArICcsICc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBhcmcuc2xpY2UoMCwgLTIpOyAvLyBSZW1vdmUgdHJhaWxpbmcgY29tbWEgYW5kIHNwYWNlXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKGFyZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdhcm4obXNnICsgJ1xcbkFyZ3VtZW50czogJyArIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MpLmpvaW4oJycpICsgJ1xcbicgKyAobmV3IEVycm9yKCkpLnN0YWNrKTtcbiAgICAgICAgICAgICAgICBmaXJzdFRpbWUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9LCBmbik7XG4gICAgfVxuXG4gICAgdmFyIGRlcHJlY2F0aW9ucyA9IHt9O1xuXG4gICAgZnVuY3Rpb24gZGVwcmVjYXRlU2ltcGxlKG5hbWUsIG1zZykge1xuICAgICAgICBpZiAoaG9va3MuZGVwcmVjYXRpb25IYW5kbGVyICE9IG51bGwpIHtcbiAgICAgICAgICAgIGhvb2tzLmRlcHJlY2F0aW9uSGFuZGxlcihuYW1lLCBtc2cpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZGVwcmVjYXRpb25zW25hbWVdKSB7XG4gICAgICAgICAgICB3YXJuKG1zZyk7XG4gICAgICAgICAgICBkZXByZWNhdGlvbnNbbmFtZV0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaG9va3Muc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmdzID0gZmFsc2U7XG4gICAgaG9va3MuZGVwcmVjYXRpb25IYW5kbGVyID0gbnVsbDtcblxuICAgIGZ1bmN0aW9uIGlzRnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0IGluc3RhbmNlb2YgRnVuY3Rpb24gfHwgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGlucHV0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXQgKGNvbmZpZykge1xuICAgICAgICB2YXIgcHJvcCwgaTtcbiAgICAgICAgZm9yIChpIGluIGNvbmZpZykge1xuICAgICAgICAgICAgcHJvcCA9IGNvbmZpZ1tpXTtcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHByb3ApKSB7XG4gICAgICAgICAgICAgICAgdGhpc1tpXSA9IHByb3A7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXNbJ18nICsgaV0gPSBwcm9wO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgLy8gTGVuaWVudCBvcmRpbmFsIHBhcnNpbmcgYWNjZXB0cyBqdXN0IGEgbnVtYmVyIGluIGFkZGl0aW9uIHRvXG4gICAgICAgIC8vIG51bWJlciArIChwb3NzaWJseSkgc3R1ZmYgY29taW5nIGZyb20gX2RheU9mTW9udGhPcmRpbmFsUGFyc2UuXG4gICAgICAgIC8vIFRPRE86IFJlbW92ZSBcIm9yZGluYWxQYXJzZVwiIGZhbGxiYWNrIGluIG5leHQgbWFqb3IgcmVsZWFzZS5cbiAgICAgICAgdGhpcy5fZGF5T2ZNb250aE9yZGluYWxQYXJzZUxlbmllbnQgPSBuZXcgUmVnRXhwKFxuICAgICAgICAgICAgKHRoaXMuX2RheU9mTW9udGhPcmRpbmFsUGFyc2Uuc291cmNlIHx8IHRoaXMuX29yZGluYWxQYXJzZS5zb3VyY2UpICtcbiAgICAgICAgICAgICAgICAnfCcgKyAoL1xcZHsxLDJ9Lykuc291cmNlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtZXJnZUNvbmZpZ3MocGFyZW50Q29uZmlnLCBjaGlsZENvbmZpZykge1xuICAgICAgICB2YXIgcmVzID0gZXh0ZW5kKHt9LCBwYXJlbnRDb25maWcpLCBwcm9wO1xuICAgICAgICBmb3IgKHByb3AgaW4gY2hpbGRDb25maWcpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd25Qcm9wKGNoaWxkQ29uZmlnLCBwcm9wKSkge1xuICAgICAgICAgICAgICAgIGlmIChpc09iamVjdChwYXJlbnRDb25maWdbcHJvcF0pICYmIGlzT2JqZWN0KGNoaWxkQ29uZmlnW3Byb3BdKSkge1xuICAgICAgICAgICAgICAgICAgICByZXNbcHJvcF0gPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kKHJlc1twcm9wXSwgcGFyZW50Q29uZmlnW3Byb3BdKTtcbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kKHJlc1twcm9wXSwgY2hpbGRDb25maWdbcHJvcF0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hpbGRDb25maWdbcHJvcF0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXNbcHJvcF0gPSBjaGlsZENvbmZpZ1twcm9wXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcmVzW3Byb3BdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKHByb3AgaW4gcGFyZW50Q29uZmlnKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChwYXJlbnRDb25maWcsIHByb3ApICYmXG4gICAgICAgICAgICAgICAgICAgICFoYXNPd25Qcm9wKGNoaWxkQ29uZmlnLCBwcm9wKSAmJlxuICAgICAgICAgICAgICAgICAgICBpc09iamVjdChwYXJlbnRDb25maWdbcHJvcF0pKSB7XG4gICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGNoYW5nZXMgdG8gcHJvcGVydGllcyBkb24ndCBtb2RpZnkgcGFyZW50IGNvbmZpZ1xuICAgICAgICAgICAgICAgIHJlc1twcm9wXSA9IGV4dGVuZCh7fSwgcmVzW3Byb3BdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIExvY2FsZShjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZyAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnNldChjb25maWcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGtleXM7XG5cbiAgICBpZiAoT2JqZWN0LmtleXMpIHtcbiAgICAgICAga2V5cyA9IE9iamVjdC5rZXlzO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGtleXMgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICB2YXIgaSwgcmVzID0gW107XG4gICAgICAgICAgICBmb3IgKGkgaW4gb2JqKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhc093blByb3Aob2JqLCBpKSkge1xuICAgICAgICAgICAgICAgICAgICByZXMucHVzaChpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0Q2FsZW5kYXIgPSB7XG4gICAgICAgIHNhbWVEYXkgOiAnW1RvZGF5IGF0XSBMVCcsXG4gICAgICAgIG5leHREYXkgOiAnW1RvbW9ycm93IGF0XSBMVCcsXG4gICAgICAgIG5leHRXZWVrIDogJ2RkZGQgW2F0XSBMVCcsXG4gICAgICAgIGxhc3REYXkgOiAnW1llc3RlcmRheSBhdF0gTFQnLFxuICAgICAgICBsYXN0V2VlayA6ICdbTGFzdF0gZGRkZCBbYXRdIExUJyxcbiAgICAgICAgc2FtZUVsc2UgOiAnTCdcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gY2FsZW5kYXIgKGtleSwgbW9tLCBub3cpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX2NhbGVuZGFyW2tleV0gfHwgdGhpcy5fY2FsZW5kYXJbJ3NhbWVFbHNlJ107XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKG91dHB1dCkgPyBvdXRwdXQuY2FsbChtb20sIG5vdykgOiBvdXRwdXQ7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb25nRGF0ZUZvcm1hdCA9IHtcbiAgICAgICAgTFRTICA6ICdoOm1tOnNzIEEnLFxuICAgICAgICBMVCAgIDogJ2g6bW0gQScsXG4gICAgICAgIEwgICAgOiAnTU0vREQvWVlZWScsXG4gICAgICAgIExMICAgOiAnTU1NTSBELCBZWVlZJyxcbiAgICAgICAgTExMICA6ICdNTU1NIEQsIFlZWVkgaDptbSBBJyxcbiAgICAgICAgTExMTCA6ICdkZGRkLCBNTU1NIEQsIFlZWVkgaDptbSBBJ1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb25nRGF0ZUZvcm1hdCAoa2V5KSB7XG4gICAgICAgIHZhciBmb3JtYXQgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldLFxuICAgICAgICAgICAgZm9ybWF0VXBwZXIgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXkudG9VcHBlckNhc2UoKV07XG5cbiAgICAgICAgaWYgKGZvcm1hdCB8fCAhZm9ybWF0VXBwZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldID0gZm9ybWF0VXBwZXIucmVwbGFjZSgvTU1NTXxNTXxERHxkZGRkL2csIGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWwuc2xpY2UoMSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0SW52YWxpZERhdGUgPSAnSW52YWxpZCBkYXRlJztcblxuICAgIGZ1bmN0aW9uIGludmFsaWREYXRlICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ludmFsaWREYXRlO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0T3JkaW5hbCA9ICclZCc7XG4gICAgdmFyIGRlZmF1bHREYXlPZk1vbnRoT3JkaW5hbFBhcnNlID0gL1xcZHsxLDJ9LztcblxuICAgIGZ1bmN0aW9uIG9yZGluYWwgKG51bWJlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3JkaW5hbC5yZXBsYWNlKCclZCcsIG51bWJlcik7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRSZWxhdGl2ZVRpbWUgPSB7XG4gICAgICAgIGZ1dHVyZSA6ICdpbiAlcycsXG4gICAgICAgIHBhc3QgICA6ICclcyBhZ28nLFxuICAgICAgICBzICA6ICdhIGZldyBzZWNvbmRzJyxcbiAgICAgICAgc3MgOiAnJWQgc2Vjb25kcycsXG4gICAgICAgIG0gIDogJ2EgbWludXRlJyxcbiAgICAgICAgbW0gOiAnJWQgbWludXRlcycsXG4gICAgICAgIGggIDogJ2FuIGhvdXInLFxuICAgICAgICBoaCA6ICclZCBob3VycycsXG4gICAgICAgIGQgIDogJ2EgZGF5JyxcbiAgICAgICAgZGQgOiAnJWQgZGF5cycsXG4gICAgICAgIE0gIDogJ2EgbW9udGgnLFxuICAgICAgICBNTSA6ICclZCBtb250aHMnLFxuICAgICAgICB5ICA6ICdhIHllYXInLFxuICAgICAgICB5eSA6ICclZCB5ZWFycydcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcmVsYXRpdmVUaW1lIChudW1iZXIsIHdpdGhvdXRTdWZmaXgsIHN0cmluZywgaXNGdXR1cmUpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX3JlbGF0aXZlVGltZVtzdHJpbmddO1xuICAgICAgICByZXR1cm4gKGlzRnVuY3Rpb24ob3V0cHV0KSkgP1xuICAgICAgICAgICAgb3V0cHV0KG51bWJlciwgd2l0aG91dFN1ZmZpeCwgc3RyaW5nLCBpc0Z1dHVyZSkgOlxuICAgICAgICAgICAgb3V0cHV0LnJlcGxhY2UoLyVkL2ksIG51bWJlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFzdEZ1dHVyZSAoZGlmZiwgb3V0cHV0KSB7XG4gICAgICAgIHZhciBmb3JtYXQgPSB0aGlzLl9yZWxhdGl2ZVRpbWVbZGlmZiA+IDAgPyAnZnV0dXJlJyA6ICdwYXN0J107XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKGZvcm1hdCkgPyBmb3JtYXQob3V0cHV0KSA6IGZvcm1hdC5yZXBsYWNlKC8lcy9pLCBvdXRwdXQpO1xuICAgIH1cblxuICAgIHZhciBhbGlhc2VzID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRVbml0QWxpYXMgKHVuaXQsIHNob3J0aGFuZCkge1xuICAgICAgICB2YXIgbG93ZXJDYXNlID0gdW5pdC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBhbGlhc2VzW2xvd2VyQ2FzZV0gPSBhbGlhc2VzW2xvd2VyQ2FzZSArICdzJ10gPSBhbGlhc2VzW3Nob3J0aGFuZF0gPSB1bml0O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdW5pdHMgPT09ICdzdHJpbmcnID8gYWxpYXNlc1t1bml0c10gfHwgYWxpYXNlc1t1bml0cy50b0xvd2VyQ2FzZSgpXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBub3JtYWxpemVPYmplY3RVbml0cyhpbnB1dE9iamVjdCkge1xuICAgICAgICB2YXIgbm9ybWFsaXplZElucHV0ID0ge30sXG4gICAgICAgICAgICBub3JtYWxpemVkUHJvcCxcbiAgICAgICAgICAgIHByb3A7XG5cbiAgICAgICAgZm9yIChwcm9wIGluIGlucHV0T2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChpbnB1dE9iamVjdCwgcHJvcCkpIHtcbiAgICAgICAgICAgICAgICBub3JtYWxpemVkUHJvcCA9IG5vcm1hbGl6ZVVuaXRzKHByb3ApO1xuICAgICAgICAgICAgICAgIGlmIChub3JtYWxpemVkUHJvcCkge1xuICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkSW5wdXRbbm9ybWFsaXplZFByb3BdID0gaW5wdXRPYmplY3RbcHJvcF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRJbnB1dDtcbiAgICB9XG5cbiAgICB2YXIgcHJpb3JpdGllcyA9IHt9O1xuXG4gICAgZnVuY3Rpb24gYWRkVW5pdFByaW9yaXR5KHVuaXQsIHByaW9yaXR5KSB7XG4gICAgICAgIHByaW9yaXRpZXNbdW5pdF0gPSBwcmlvcml0eTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRQcmlvcml0aXplZFVuaXRzKHVuaXRzT2JqKSB7XG4gICAgICAgIHZhciB1bml0cyA9IFtdO1xuICAgICAgICBmb3IgKHZhciB1IGluIHVuaXRzT2JqKSB7XG4gICAgICAgICAgICB1bml0cy5wdXNoKHt1bml0OiB1LCBwcmlvcml0eTogcHJpb3JpdGllc1t1XX0pO1xuICAgICAgICB9XG4gICAgICAgIHVuaXRzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgIHJldHVybiBhLnByaW9yaXR5IC0gYi5wcmlvcml0eTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB1bml0cztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB6ZXJvRmlsbChudW1iZXIsIHRhcmdldExlbmd0aCwgZm9yY2VTaWduKSB7XG4gICAgICAgIHZhciBhYnNOdW1iZXIgPSAnJyArIE1hdGguYWJzKG51bWJlciksXG4gICAgICAgICAgICB6ZXJvc1RvRmlsbCA9IHRhcmdldExlbmd0aCAtIGFic051bWJlci5sZW5ndGgsXG4gICAgICAgICAgICBzaWduID0gbnVtYmVyID49IDA7XG4gICAgICAgIHJldHVybiAoc2lnbiA/IChmb3JjZVNpZ24gPyAnKycgOiAnJykgOiAnLScpICtcbiAgICAgICAgICAgIE1hdGgucG93KDEwLCBNYXRoLm1heCgwLCB6ZXJvc1RvRmlsbCkpLnRvU3RyaW5nKCkuc3Vic3RyKDEpICsgYWJzTnVtYmVyO1xuICAgIH1cblxuICAgIHZhciBmb3JtYXR0aW5nVG9rZW5zID0gLyhcXFtbXlxcW10qXFxdKXwoXFxcXCk/KFtIaF1tbShzcyk/fE1vfE1NP00/TT98RG98REREb3xERD9EP0Q/fGRkZD9kP3xkbz98d1tvfHddP3xXW298V10/fFFvP3xZWVlZWVl8WVlZWVl8WVlZWXxZWXxnZyhnZ2c/KT98R0coR0dHPyk/fGV8RXxhfEF8aGg/fEhIP3xraz98bW0/fHNzP3xTezEsOX18eHxYfHp6P3xaWj98LikvZztcblxuICAgIHZhciBsb2NhbEZvcm1hdHRpbmdUb2tlbnMgPSAvKFxcW1teXFxbXSpcXF0pfChcXFxcKT8oTFRTfExUfExMP0w/TD98bHsxLDR9KS9nO1xuXG4gICAgdmFyIGZvcm1hdEZ1bmN0aW9ucyA9IHt9O1xuXG4gICAgdmFyIGZvcm1hdFRva2VuRnVuY3Rpb25zID0ge307XG5cbiAgICAvLyB0b2tlbjogICAgJ00nXG4gICAgLy8gcGFkZGVkOiAgIFsnTU0nLCAyXVxuICAgIC8vIG9yZGluYWw6ICAnTW8nXG4gICAgLy8gY2FsbGJhY2s6IGZ1bmN0aW9uICgpIHsgdGhpcy5tb250aCgpICsgMSB9XG4gICAgZnVuY3Rpb24gYWRkRm9ybWF0VG9rZW4gKHRva2VuLCBwYWRkZWQsIG9yZGluYWwsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBmdW5jID0gY2FsbGJhY2s7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBmdW5jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW2NhbGxiYWNrXSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodG9rZW4pIHtcbiAgICAgICAgICAgIGZvcm1hdFRva2VuRnVuY3Rpb25zW3Rva2VuXSA9IGZ1bmM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhZGRlZCkge1xuICAgICAgICAgICAgZm9ybWF0VG9rZW5GdW5jdGlvbnNbcGFkZGVkWzBdXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gemVyb0ZpbGwoZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpLCBwYWRkZWRbMV0sIHBhZGRlZFsyXSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcmRpbmFsKSB7XG4gICAgICAgICAgICBmb3JtYXRUb2tlbkZ1bmN0aW9uc1tvcmRpbmFsXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkub3JkaW5hbChmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIHRva2VuKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGlucHV0KSB7XG4gICAgICAgIGlmIChpbnB1dC5tYXRjaCgvXFxbW1xcc1xcU10vKSkge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL15cXFt8XFxdJC9nLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL1xcXFwvZywgJycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VGb3JtYXRGdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgICAgdmFyIGFycmF5ID0gZm9ybWF0Lm1hdGNoKGZvcm1hdHRpbmdUb2tlbnMpLCBpLCBsZW5ndGg7XG5cbiAgICAgICAgZm9yIChpID0gMCwgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXRUb2tlbkZ1bmN0aW9uc1thcnJheVtpXV0pIHtcbiAgICAgICAgICAgICAgICBhcnJheVtpXSA9IGZvcm1hdFRva2VuRnVuY3Rpb25zW2FycmF5W2ldXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXJyYXlbaV0gPSByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGFycmF5W2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAobW9tKSB7XG4gICAgICAgICAgICB2YXIgb3V0cHV0ID0gJycsIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gaXNGdW5jdGlvbihhcnJheVtpXSkgPyBhcnJheVtpXS5jYWxsKG1vbSwgZm9ybWF0KSA6IGFycmF5W2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBmb3JtYXQgZGF0ZSB1c2luZyBuYXRpdmUgZGF0ZSBvYmplY3RcbiAgICBmdW5jdGlvbiBmb3JtYXRNb21lbnQobSwgZm9ybWF0KSB7XG4gICAgICAgIGlmICghbS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBtLmxvY2FsZURhdGEoKS5pbnZhbGlkRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9ybWF0ID0gZXhwYW5kRm9ybWF0KGZvcm1hdCwgbS5sb2NhbGVEYXRhKCkpO1xuICAgICAgICBmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XSA9IGZvcm1hdEZ1bmN0aW9uc1tmb3JtYXRdIHx8IG1ha2VGb3JtYXRGdW5jdGlvbihmb3JtYXQpO1xuXG4gICAgICAgIHJldHVybiBmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XShtKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBleHBhbmRGb3JtYXQoZm9ybWF0LCBsb2NhbGUpIHtcbiAgICAgICAgdmFyIGkgPSA1O1xuXG4gICAgICAgIGZ1bmN0aW9uIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2VucyhpbnB1dCkge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS5sb25nRGF0ZUZvcm1hdChpbnB1dCkgfHwgaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPj0gMCAmJiBsb2NhbEZvcm1hdHRpbmdUb2tlbnMudGVzdChmb3JtYXQpKSB7XG4gICAgICAgICAgICBmb3JtYXQgPSBmb3JtYXQucmVwbGFjZShsb2NhbEZvcm1hdHRpbmdUb2tlbnMsIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2Vucyk7XG4gICAgICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgfVxuXG4gICAgdmFyIG1hdGNoMSAgICAgICAgID0gL1xcZC87ICAgICAgICAgICAgLy8gICAgICAgMCAtIDlcbiAgICB2YXIgbWF0Y2gyICAgICAgICAgPSAvXFxkXFxkLzsgICAgICAgICAgLy8gICAgICAwMCAtIDk5XG4gICAgdmFyIG1hdGNoMyAgICAgICAgID0gL1xcZHszfS87ICAgICAgICAgLy8gICAgIDAwMCAtIDk5OVxuICAgIHZhciBtYXRjaDQgICAgICAgICA9IC9cXGR7NH0vOyAgICAgICAgIC8vICAgIDAwMDAgLSA5OTk5XG4gICAgdmFyIG1hdGNoNiAgICAgICAgID0gL1srLV0/XFxkezZ9LzsgICAgLy8gLTk5OTk5OSAtIDk5OTk5OVxuICAgIHZhciBtYXRjaDF0bzIgICAgICA9IC9cXGRcXGQ/LzsgICAgICAgICAvLyAgICAgICAwIC0gOTlcbiAgICB2YXIgbWF0Y2gzdG80ICAgICAgPSAvXFxkXFxkXFxkXFxkPy87ICAgICAvLyAgICAgOTk5IC0gOTk5OVxuICAgIHZhciBtYXRjaDV0bzYgICAgICA9IC9cXGRcXGRcXGRcXGRcXGRcXGQ/LzsgLy8gICA5OTk5OSAtIDk5OTk5OVxuICAgIHZhciBtYXRjaDF0bzMgICAgICA9IC9cXGR7MSwzfS87ICAgICAgIC8vICAgICAgIDAgLSA5OTlcbiAgICB2YXIgbWF0Y2gxdG80ICAgICAgPSAvXFxkezEsNH0vOyAgICAgICAvLyAgICAgICAwIC0gOTk5OVxuICAgIHZhciBtYXRjaDF0bzYgICAgICA9IC9bKy1dP1xcZHsxLDZ9LzsgIC8vIC05OTk5OTkgLSA5OTk5OTlcblxuICAgIHZhciBtYXRjaFVuc2lnbmVkICA9IC9cXGQrLzsgICAgICAgICAgIC8vICAgICAgIDAgLSBpbmZcbiAgICB2YXIgbWF0Y2hTaWduZWQgICAgPSAvWystXT9cXGQrLzsgICAgICAvLyAgICAtaW5mIC0gaW5mXG5cbiAgICB2YXIgbWF0Y2hPZmZzZXQgICAgPSAvWnxbKy1dXFxkXFxkOj9cXGRcXGQvZ2k7IC8vICswMDowMCAtMDA6MDAgKzAwMDAgLTAwMDAgb3IgWlxuICAgIHZhciBtYXRjaFNob3J0T2Zmc2V0ID0gL1p8WystXVxcZFxcZCg/Ojo/XFxkXFxkKT8vZ2k7IC8vICswMCAtMDAgKzAwOjAwIC0wMDowMCArMDAwMCAtMDAwMCBvciBaXG5cbiAgICB2YXIgbWF0Y2hUaW1lc3RhbXAgPSAvWystXT9cXGQrKFxcLlxcZHsxLDN9KT8vOyAvLyAxMjM0NTY3ODkgMTIzNDU2Nzg5LjEyM1xuXG4gICAgLy8gYW55IHdvcmQgKG9yIHR3bykgY2hhcmFjdGVycyBvciBudW1iZXJzIGluY2x1ZGluZyB0d28vdGhyZWUgd29yZCBtb250aCBpbiBhcmFiaWMuXG4gICAgLy8gaW5jbHVkZXMgc2NvdHRpc2ggZ2FlbGljIHR3byB3b3JkIGFuZCBoeXBoZW5hdGVkIG1vbnRoc1xuICAgIHZhciBtYXRjaFdvcmQgPSAvWzAtOV17MCwyNTZ9WydhLXpcXHUwMEEwLVxcdTA1RkZcXHUwNzAwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGMDdcXHVGRjEwLVxcdUZGRUZdezEsMjU2fXxbXFx1MDYwMC1cXHUwNkZGXFwvXXsxLDI1Nn0oXFxzKj9bXFx1MDYwMC1cXHUwNkZGXXsxLDI1Nn0pezEsMn0vaTtcblxuICAgIHZhciByZWdleGVzID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRSZWdleFRva2VuICh0b2tlbiwgcmVnZXgsIHN0cmljdFJlZ2V4KSB7XG4gICAgICAgIHJlZ2V4ZXNbdG9rZW5dID0gaXNGdW5jdGlvbihyZWdleCkgPyByZWdleCA6IGZ1bmN0aW9uIChpc1N0cmljdCwgbG9jYWxlRGF0YSkge1xuICAgICAgICAgICAgcmV0dXJuIChpc1N0cmljdCAmJiBzdHJpY3RSZWdleCkgPyBzdHJpY3RSZWdleCA6IHJlZ2V4O1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFBhcnNlUmVnZXhGb3JUb2tlbiAodG9rZW4sIGNvbmZpZykge1xuICAgICAgICBpZiAoIWhhc093blByb3AocmVnZXhlcywgdG9rZW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cCh1bmVzY2FwZUZvcm1hdCh0b2tlbikpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlZ2V4ZXNbdG9rZW5dKGNvbmZpZy5fc3RyaWN0LCBjb25maWcuX2xvY2FsZSk7XG4gICAgfVxuXG4gICAgLy8gQ29kZSBmcm9tIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzU2MTQ5My9pcy10aGVyZS1hLXJlZ2V4cC1lc2NhcGUtZnVuY3Rpb24taW4tamF2YXNjcmlwdFxuICAgIGZ1bmN0aW9uIHVuZXNjYXBlRm9ybWF0KHMpIHtcbiAgICAgICAgcmV0dXJuIHJlZ2V4RXNjYXBlKHMucmVwbGFjZSgnXFxcXCcsICcnKS5yZXBsYWNlKC9cXFxcKFxcWyl8XFxcXChcXF0pfFxcWyhbXlxcXVxcW10qKVxcXXxcXFxcKC4pL2csIGZ1bmN0aW9uIChtYXRjaGVkLCBwMSwgcDIsIHAzLCBwNCkge1xuICAgICAgICAgICAgcmV0dXJuIHAxIHx8IHAyIHx8IHAzIHx8IHA0O1xuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVnZXhFc2NhcGUocykge1xuICAgICAgICByZXR1cm4gcy5yZXBsYWNlKC9bLVxcL1xcXFxeJCorPy4oKXxbXFxde31dL2csICdcXFxcJCYnKTtcbiAgICB9XG5cbiAgICB2YXIgdG9rZW5zID0ge307XG5cbiAgICBmdW5jdGlvbiBhZGRQYXJzZVRva2VuICh0b2tlbiwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGksIGZ1bmMgPSBjYWxsYmFjaztcbiAgICAgICAgaWYgKHR5cGVvZiB0b2tlbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRva2VuID0gW3Rva2VuXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNOdW1iZXIoY2FsbGJhY2spKSB7XG4gICAgICAgICAgICBmdW5jID0gZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICAgICAgICAgIGFycmF5W2NhbGxiYWNrXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRva2VuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0b2tlbnNbdG9rZW5baV1dID0gZnVuYztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFdlZWtQYXJzZVRva2VuICh0b2tlbiwgY2FsbGJhY2spIHtcbiAgICAgICAgYWRkUGFyc2VUb2tlbih0b2tlbiwgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnLCB0b2tlbikge1xuICAgICAgICAgICAgY29uZmlnLl93ID0gY29uZmlnLl93IHx8IHt9O1xuICAgICAgICAgICAgY2FsbGJhY2soaW5wdXQsIGNvbmZpZy5fdywgY29uZmlnLCB0b2tlbik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFRpbWVUb0FycmF5RnJvbVRva2VuKHRva2VuLCBpbnB1dCwgY29uZmlnKSB7XG4gICAgICAgIGlmIChpbnB1dCAhPSBudWxsICYmIGhhc093blByb3AodG9rZW5zLCB0b2tlbikpIHtcbiAgICAgICAgICAgIHRva2Vuc1t0b2tlbl0oaW5wdXQsIGNvbmZpZy5fYSwgY29uZmlnLCB0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgWUVBUiA9IDA7XG4gICAgdmFyIE1PTlRIID0gMTtcbiAgICB2YXIgREFURSA9IDI7XG4gICAgdmFyIEhPVVIgPSAzO1xuICAgIHZhciBNSU5VVEUgPSA0O1xuICAgIHZhciBTRUNPTkQgPSA1O1xuICAgIHZhciBNSUxMSVNFQ09ORCA9IDY7XG4gICAgdmFyIFdFRUsgPSA3O1xuICAgIHZhciBXRUVLREFZID0gODtcblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdZJywgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgeSA9IHRoaXMueWVhcigpO1xuICAgICAgICByZXR1cm4geSA8PSA5OTk5ID8gJycgKyB5IDogJysnICsgeTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnWVknLCAyXSwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy55ZWFyKCkgJSAxMDA7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1lZWVknLCAgIDRdLCAgICAgICAwLCAneWVhcicpO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnWVlZWVknLCAgNV0sICAgICAgIDAsICd5ZWFyJyk7XG4gICAgYWRkRm9ybWF0VG9rZW4oMCwgWydZWVlZWVknLCA2LCB0cnVlXSwgMCwgJ3llYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygneWVhcicsICd5Jyk7XG5cbiAgICAvLyBQUklPUklUSUVTXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ3llYXInLCAxKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1knLCAgICAgIG1hdGNoU2lnbmVkKTtcbiAgICBhZGRSZWdleFRva2VuKCdZWScsICAgICBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignWVlZWScsICAgbWF0Y2gxdG80LCBtYXRjaDQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1lZWVlZJywgIG1hdGNoMXRvNiwgbWF0Y2g2KTtcbiAgICBhZGRSZWdleFRva2VuKCdZWVlZWVknLCBtYXRjaDF0bzYsIG1hdGNoNik7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnWVlZWVknLCAnWVlZWVlZJ10sIFlFQVIpO1xuICAgIGFkZFBhcnNlVG9rZW4oJ1lZWVknLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5KSB7XG4gICAgICAgIGFycmF5W1lFQVJdID0gaW5wdXQubGVuZ3RoID09PSAyID8gaG9va3MucGFyc2VUd29EaWdpdFllYXIoaW5wdXQpIDogdG9JbnQoaW5wdXQpO1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oJ1lZJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtZRUFSXSA9IGhvb2tzLnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCdZJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtZRUFSXSA9IHBhcnNlSW50KGlucHV0LCAxMCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICBmdW5jdGlvbiBkYXlzSW5ZZWFyKHllYXIpIHtcbiAgICAgICAgcmV0dXJuIGlzTGVhcFllYXIoeWVhcikgPyAzNjYgOiAzNjU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNMZWFwWWVhcih5ZWFyKSB7XG4gICAgICAgIHJldHVybiAoeWVhciAlIDQgPT09IDAgJiYgeWVhciAlIDEwMCAhPT0gMCkgfHwgeWVhciAlIDQwMCA9PT0gMDtcbiAgICB9XG5cbiAgICAvLyBIT09LU1xuXG4gICAgaG9va3MucGFyc2VUd29EaWdpdFllYXIgPSBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHRvSW50KGlucHV0KSArICh0b0ludChpbnB1dCkgPiA2OCA/IDE5MDAgOiAyMDAwKTtcbiAgICB9O1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgdmFyIGdldFNldFllYXIgPSBtYWtlR2V0U2V0KCdGdWxsWWVhcicsIHRydWUpO1xuXG4gICAgZnVuY3Rpb24gZ2V0SXNMZWFwWWVhciAoKSB7XG4gICAgICAgIHJldHVybiBpc0xlYXBZZWFyKHRoaXMueWVhcigpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlR2V0U2V0ICh1bml0LCBrZWVwVGltZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHNldCQxKHRoaXMsIHVuaXQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywga2VlcFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0KHRoaXMsIHVuaXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldCAobW9tLCB1bml0KSB7XG4gICAgICAgIHJldHVybiBtb20uaXNWYWxpZCgpID9cbiAgICAgICAgICAgIG1vbS5fZFsnZ2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyB1bml0XSgpIDogTmFOO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldCQxIChtb20sIHVuaXQsIHZhbHVlKSB7XG4gICAgICAgIGlmIChtb20uaXNWYWxpZCgpICYmICFpc05hTih2YWx1ZSkpIHtcbiAgICAgICAgICAgIGlmICh1bml0ID09PSAnRnVsbFllYXInICYmIGlzTGVhcFllYXIobW9tLnllYXIoKSkgJiYgbW9tLm1vbnRoKCkgPT09IDEgJiYgbW9tLmRhdGUoKSA9PT0gMjkpIHtcbiAgICAgICAgICAgICAgICBtb20uX2RbJ3NldCcgKyAobW9tLl9pc1VUQyA/ICdVVEMnIDogJycpICsgdW5pdF0odmFsdWUsIG1vbS5tb250aCgpLCBkYXlzSW5Nb250aCh2YWx1ZSwgbW9tLm1vbnRoKCkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyB1bml0XSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBzdHJpbmdHZXQgKHVuaXRzKSB7XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICBpZiAoaXNGdW5jdGlvbih0aGlzW3VuaXRzXSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzXSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gc3RyaW5nU2V0ICh1bml0cywgdmFsdWUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB1bml0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHVuaXRzID0gbm9ybWFsaXplT2JqZWN0VW5pdHModW5pdHMpO1xuICAgICAgICAgICAgdmFyIHByaW9yaXRpemVkID0gZ2V0UHJpb3JpdGl6ZWRVbml0cyh1bml0cyk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByaW9yaXRpemVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpc1twcmlvcml0aXplZFtpXS51bml0XSh1bml0c1twcmlvcml0aXplZFtpXS51bml0XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHRoaXNbdW5pdHNdKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzXSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbW9kKG4sIHgpIHtcbiAgICAgICAgcmV0dXJuICgobiAlIHgpICsgeCkgJSB4O1xuICAgIH1cblxuICAgIHZhciBpbmRleE9mO1xuXG4gICAgaWYgKEFycmF5LnByb3RvdHlwZS5pbmRleE9mKSB7XG4gICAgICAgIGluZGV4T2YgPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZjtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpbmRleE9mID0gZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgICAgIC8vIEkga25vd1xuICAgICAgICAgICAgdmFyIGk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSBvKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlzSW5Nb250aCh5ZWFyLCBtb250aCkge1xuICAgICAgICBpZiAoaXNOYU4oeWVhcikgfHwgaXNOYU4obW9udGgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtb2RNb250aCA9IG1vZChtb250aCwgMTIpO1xuICAgICAgICB5ZWFyICs9IChtb250aCAtIG1vZE1vbnRoKSAvIDEyO1xuICAgICAgICByZXR1cm4gbW9kTW9udGggPT09IDEgPyAoaXNMZWFwWWVhcih5ZWFyKSA/IDI5IDogMjgpIDogKDMxIC0gbW9kTW9udGggJSA3ICUgMik7XG4gICAgfVxuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ00nLCBbJ01NJywgMl0sICdNbycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9udGgoKSArIDE7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignTU1NJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzU2hvcnQodGhpcywgZm9ybWF0KTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdNTU1NJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzKHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21vbnRoJywgJ00nKTtcblxuICAgIC8vIFBSSU9SSVRZXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ21vbnRoJywgOCk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdNJywgICAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdNTScsICAgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ01NTScsICBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLm1vbnRoc1Nob3J0UmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ01NTU0nLCBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLm1vbnRoc1JlZ2V4KGlzU3RyaWN0KTtcbiAgICB9KTtcblxuICAgIGFkZFBhcnNlVG9rZW4oWydNJywgJ01NJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbTU9OVEhdID0gdG9JbnQoaW5wdXQpIC0gMTtcbiAgICB9KTtcblxuICAgIGFkZFBhcnNlVG9rZW4oWydNTU0nLCAnTU1NTSddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcsIHRva2VuKSB7XG4gICAgICAgIHZhciBtb250aCA9IGNvbmZpZy5fbG9jYWxlLm1vbnRoc1BhcnNlKGlucHV0LCB0b2tlbiwgY29uZmlnLl9zdHJpY3QpO1xuICAgICAgICAvLyBpZiB3ZSBkaWRuJ3QgZmluZCBhIG1vbnRoIG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZC5cbiAgICAgICAgaWYgKG1vbnRoICE9IG51bGwpIHtcbiAgICAgICAgICAgIGFycmF5W01PTlRIXSA9IG1vbnRoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuaW52YWxpZE1vbnRoID0gaW5wdXQ7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIExPQ0FMRVNcblxuICAgIHZhciBNT05USFNfSU5fRk9STUFUID0gL0Rbb0RdPyhcXFtbXlxcW1xcXV0qXFxdfFxccykrTU1NTT8vO1xuICAgIHZhciBkZWZhdWx0TG9jYWxlTW9udGhzID0gJ0phbnVhcnlfRmVicnVhcnlfTWFyY2hfQXByaWxfTWF5X0p1bmVfSnVseV9BdWd1c3RfU2VwdGVtYmVyX09jdG9iZXJfTm92ZW1iZXJfRGVjZW1iZXInLnNwbGl0KCdfJyk7XG4gICAgZnVuY3Rpb24gbG9jYWxlTW9udGhzIChtLCBmb3JtYXQpIHtcbiAgICAgICAgaWYgKCFtKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNBcnJheSh0aGlzLl9tb250aHMpID8gdGhpcy5fbW9udGhzIDpcbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNbJ3N0YW5kYWxvbmUnXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNBcnJheSh0aGlzLl9tb250aHMpID8gdGhpcy5fbW9udGhzW20ubW9udGgoKV0gOlxuICAgICAgICAgICAgdGhpcy5fbW9udGhzWyh0aGlzLl9tb250aHMuaXNGb3JtYXQgfHwgTU9OVEhTX0lOX0ZPUk1BVCkudGVzdChmb3JtYXQpID8gJ2Zvcm1hdCcgOiAnc3RhbmRhbG9uZSddW20ubW9udGgoKV07XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb2NhbGVNb250aHNTaG9ydCA9ICdKYW5fRmViX01hcl9BcHJfTWF5X0p1bl9KdWxfQXVnX1NlcF9PY3RfTm92X0RlYycuc3BsaXQoJ18nKTtcbiAgICBmdW5jdGlvbiBsb2NhbGVNb250aHNTaG9ydCAobSwgZm9ybWF0KSB7XG4gICAgICAgIGlmICghbSkge1xuICAgICAgICAgICAgcmV0dXJuIGlzQXJyYXkodGhpcy5fbW9udGhzU2hvcnQpID8gdGhpcy5fbW9udGhzU2hvcnQgOlxuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1Nob3J0WydzdGFuZGFsb25lJ107XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlzQXJyYXkodGhpcy5fbW9udGhzU2hvcnQpID8gdGhpcy5fbW9udGhzU2hvcnRbbS5tb250aCgpXSA6XG4gICAgICAgICAgICB0aGlzLl9tb250aHNTaG9ydFtNT05USFNfSU5fRk9STUFULnRlc3QoZm9ybWF0KSA/ICdmb3JtYXQnIDogJ3N0YW5kYWxvbmUnXVttLm1vbnRoKCldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZVN0cmljdFBhcnNlKG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGksIGlpLCBtb20sIGxsYyA9IG1vbnRoTmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoIXRoaXMuX21vbnRoc1BhcnNlKSB7XG4gICAgICAgICAgICAvLyB0aGlzIGlzIG5vdCB1c2VkXG4gICAgICAgICAgICB0aGlzLl9tb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTI7ICsraSkge1xuICAgICAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgaV0pO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Nob3J0TW9udGhzUGFyc2VbaV0gPSB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldID0gdGhpcy5tb250aHMobW9tLCAnJykudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdNTU0nKSB7XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9sb25nTW9udGhzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdNTU0nKSB7XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fbG9uZ01vbnRoc1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpaSAhPT0gLTEgPyBpaSA6IG51bGw7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX2xvbmdNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fc2hvcnRNb250aHNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9jYWxlTW9udGhzUGFyc2UgKG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGksIG1vbSwgcmVnZXg7XG5cbiAgICAgICAgaWYgKHRoaXMuX21vbnRoc1BhcnNlRXhhY3QpIHtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVTdHJpY3RQYXJzZS5jYWxsKHRoaXMsIG1vbnRoTmFtZSwgZm9ybWF0LCBzdHJpY3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLl9tb250aHNQYXJzZSkge1xuICAgICAgICAgICAgdGhpcy5fbW9udGhzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX2xvbmdNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVE9ETzogYWRkIHNvcnRpbmdcbiAgICAgICAgLy8gU29ydGluZyBtYWtlcyBzdXJlIGlmIG9uZSBtb250aCAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlclxuICAgICAgICAvLyBzZWUgc29ydGluZyBpbiBjb21wdXRlTW9udGhzUGFyc2VcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuICAgICAgICAgICAgbW9tID0gY3JlYXRlVVRDKFsyMDAwLCBpXSk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmICF0aGlzLl9sb25nTW9udGhzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb25nTW9udGhzUGFyc2VbaV0gPSBuZXcgUmVnRXhwKCdeJyArIHRoaXMubW9udGhzKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnJykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZVtpXSA9IG5ldyBSZWdFeHAoJ14nICsgdGhpcy5tb250aHNTaG9ydChtb20sICcnKS5yZXBsYWNlKCcuJywgJycpICsgJyQnLCAnaScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFzdHJpY3QgJiYgIXRoaXMuX21vbnRoc1BhcnNlW2ldKSB7XG4gICAgICAgICAgICAgICAgcmVnZXggPSAnXicgKyB0aGlzLm1vbnRocyhtb20sICcnKSArICd8XicgKyB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1BhcnNlW2ldID0gbmV3IFJlZ0V4cChyZWdleC5yZXBsYWNlKCcuJywgJycpLCAnaScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdGVzdCB0aGUgcmVnZXhcbiAgICAgICAgICAgIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NTScgJiYgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NJyAmJiB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghc3RyaWN0ICYmIHRoaXMuX21vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgZnVuY3Rpb24gc2V0TW9udGggKG1vbSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIGRheU9mTW9udGg7XG5cbiAgICAgICAgaWYgKCFtb20uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICAvLyBObyBvcFxuICAgICAgICAgICAgcmV0dXJuIG1vbTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAoL15cXGQrJC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRvSW50KHZhbHVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBtb20ubG9jYWxlRGF0YSgpLm1vbnRoc1BhcnNlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBBbm90aGVyIHNpbGVudCBmYWlsdXJlP1xuICAgICAgICAgICAgICAgIGlmICghaXNOdW1iZXIodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtb207XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZGF5T2ZNb250aCA9IE1hdGgubWluKG1vbS5kYXRlKCksIGRheXNJbk1vbnRoKG1vbS55ZWFyKCksIHZhbHVlKSk7XG4gICAgICAgIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyAnTW9udGgnXSh2YWx1ZSwgZGF5T2ZNb250aCk7XG4gICAgICAgIHJldHVybiBtb207XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2V0TW9udGggKHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBzZXRNb250aCh0aGlzLCB2YWx1ZSk7XG4gICAgICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBnZXQodGhpcywgJ01vbnRoJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXREYXlzSW5Nb250aCAoKSB7XG4gICAgICAgIHJldHVybiBkYXlzSW5Nb250aCh0aGlzLnllYXIoKSwgdGhpcy5tb250aCgpKTtcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdE1vbnRoc1Nob3J0UmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gbW9udGhzU2hvcnRSZWdleCAoaXNTdHJpY3QpIHtcbiAgICAgICAgaWYgKHRoaXMuX21vbnRoc1BhcnNlRXhhY3QpIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlTW9udGhzUGFyc2UuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1N0cmljdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1Nob3J0UmVnZXgnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1Nob3J0UmVnZXggPSBkZWZhdWx0TW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4ICYmIGlzU3RyaWN0ID9cbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNTaG9ydFN0cmljdFJlZ2V4IDogdGhpcy5fbW9udGhzU2hvcnRSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TW9udGhzUmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gbW9udGhzUmVnZXggKGlzU3RyaWN0KSB7XG4gICAgICAgIGlmICh0aGlzLl9tb250aHNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ19tb250aHNSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgY29tcHV0ZU1vbnRoc1BhcnNlLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNTdHJpY3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX21vbnRoc1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNSZWdleCA9IGRlZmF1bHRNb250aHNSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb250aHNTdHJpY3RSZWdleCAmJiBpc1N0cmljdCA/XG4gICAgICAgICAgICAgICAgdGhpcy5fbW9udGhzU3RyaWN0UmVnZXggOiB0aGlzLl9tb250aHNSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbXB1dGVNb250aHNQYXJzZSAoKSB7XG4gICAgICAgIGZ1bmN0aW9uIGNtcExlblJldihhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi5sZW5ndGggLSBhLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzaG9ydFBpZWNlcyA9IFtdLCBsb25nUGllY2VzID0gW10sIG1peGVkUGllY2VzID0gW10sXG4gICAgICAgICAgICBpLCBtb207XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG4gICAgICAgICAgICAvLyBtYWtlIHRoZSByZWdleCBpZiB3ZSBkb24ndCBoYXZlIGl0IGFscmVhZHlcbiAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgaV0pO1xuICAgICAgICAgICAgc2hvcnRQaWVjZXMucHVzaCh0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpKTtcbiAgICAgICAgICAgIGxvbmdQaWVjZXMucHVzaCh0aGlzLm1vbnRocyhtb20sICcnKSk7XG4gICAgICAgICAgICBtaXhlZFBpZWNlcy5wdXNoKHRoaXMubW9udGhzKG1vbSwgJycpKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2godGhpcy5tb250aHNTaG9ydChtb20sICcnKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU29ydGluZyBtYWtlcyBzdXJlIGlmIG9uZSBtb250aCAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlciBpdFxuICAgICAgICAvLyB3aWxsIG1hdGNoIHRoZSBsb25nZXIgcGllY2UuXG4gICAgICAgIHNob3J0UGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgbG9uZ1BpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIG1peGVkUGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgIHNob3J0UGllY2VzW2ldID0gcmVnZXhFc2NhcGUoc2hvcnRQaWVjZXNbaV0pO1xuICAgICAgICAgICAgbG9uZ1BpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKGxvbmdQaWVjZXNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNDsgaSsrKSB7XG4gICAgICAgICAgICBtaXhlZFBpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKG1peGVkUGllY2VzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX21vbnRoc1JlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbWl4ZWRQaWVjZXMuam9pbignfCcpICsgJyknLCAnaScpO1xuICAgICAgICB0aGlzLl9tb250aHNTaG9ydFJlZ2V4ID0gdGhpcy5fbW9udGhzUmVnZXg7XG4gICAgICAgIHRoaXMuX21vbnRoc1N0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbG9uZ1BpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgICAgIHRoaXMuX21vbnRoc1Nob3J0U3RyaWN0UmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBzaG9ydFBpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlRGF0ZSAoeSwgbSwgZCwgaCwgTSwgcywgbXMpIHtcbiAgICAgICAgLy8gY2FuJ3QganVzdCBhcHBseSgpIHRvIGNyZWF0ZSBhIGRhdGU6XG4gICAgICAgIC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcS8xODEzNDhcbiAgICAgICAgdmFyIGRhdGU7XG4gICAgICAgIC8vIHRoZSBkYXRlIGNvbnN0cnVjdG9yIHJlbWFwcyB5ZWFycyAwLTk5IHRvIDE5MDAtMTk5OVxuICAgICAgICBpZiAoeSA8IDEwMCAmJiB5ID49IDApIHtcbiAgICAgICAgICAgIC8vIHByZXNlcnZlIGxlYXAgeWVhcnMgdXNpbmcgYSBmdWxsIDQwMCB5ZWFyIGN5Y2xlLCB0aGVuIHJlc2V0XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoeSArIDQwMCwgbSwgZCwgaCwgTSwgcywgbXMpO1xuICAgICAgICAgICAgaWYgKGlzRmluaXRlKGRhdGUuZ2V0RnVsbFllYXIoKSkpIHtcbiAgICAgICAgICAgICAgICBkYXRlLnNldEZ1bGxZZWFyKHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKHksIG0sIGQsIGgsIE0sIHMsIG1zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkYXRlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZVVUQ0RhdGUgKHkpIHtcbiAgICAgICAgdmFyIGRhdGU7XG4gICAgICAgIC8vIHRoZSBEYXRlLlVUQyBmdW5jdGlvbiByZW1hcHMgeWVhcnMgMC05OSB0byAxOTAwLTE5OTlcbiAgICAgICAgaWYgKHkgPCAxMDAgJiYgeSA+PSAwKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAvLyBwcmVzZXJ2ZSBsZWFwIHllYXJzIHVzaW5nIGEgZnVsbCA0MDAgeWVhciBjeWNsZSwgdGhlbiByZXNldFxuICAgICAgICAgICAgYXJnc1swXSA9IHkgKyA0MDA7XG4gICAgICAgICAgICBkYXRlID0gbmV3IERhdGUoRGF0ZS5VVEMuYXBwbHkobnVsbCwgYXJncykpO1xuICAgICAgICAgICAgaWYgKGlzRmluaXRlKGRhdGUuZ2V0VVRDRnVsbFllYXIoKSkpIHtcbiAgICAgICAgICAgICAgICBkYXRlLnNldFVUQ0Z1bGxZZWFyKHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDLmFwcGx5KG51bGwsIGFyZ3VtZW50cykpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgLy8gc3RhcnQtb2YtZmlyc3Qtd2VlayAtIHN0YXJ0LW9mLXllYXJcbiAgICBmdW5jdGlvbiBmaXJzdFdlZWtPZmZzZXQoeWVhciwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIC8vIGZpcnN0LXdlZWsgZGF5IC0tIHdoaWNoIGphbnVhcnkgaXMgYWx3YXlzIGluIHRoZSBmaXJzdCB3ZWVrICg0IGZvciBpc28sIDEgZm9yIG90aGVyKVxuICAgICAgICAgICAgZndkID0gNyArIGRvdyAtIGRveSxcbiAgICAgICAgICAgIC8vIGZpcnN0LXdlZWsgZGF5IGxvY2FsIHdlZWtkYXkgLS0gd2hpY2ggbG9jYWwgd2Vla2RheSBpcyBmd2RcbiAgICAgICAgICAgIGZ3ZGx3ID0gKDcgKyBjcmVhdGVVVENEYXRlKHllYXIsIDAsIGZ3ZCkuZ2V0VVRDRGF5KCkgLSBkb3cpICUgNztcblxuICAgICAgICByZXR1cm4gLWZ3ZGx3ICsgZndkIC0gMTtcbiAgICB9XG5cbiAgICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlI0NhbGN1bGF0aW5nX2FfZGF0ZV9naXZlbl90aGVfeWVhci4yQ193ZWVrX251bWJlcl9hbmRfd2Vla2RheVxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrcyh5ZWFyLCB3ZWVrLCB3ZWVrZGF5LCBkb3csIGRveSkge1xuICAgICAgICB2YXIgbG9jYWxXZWVrZGF5ID0gKDcgKyB3ZWVrZGF5IC0gZG93KSAlIDcsXG4gICAgICAgICAgICB3ZWVrT2Zmc2V0ID0gZmlyc3RXZWVrT2Zmc2V0KHllYXIsIGRvdywgZG95KSxcbiAgICAgICAgICAgIGRheU9mWWVhciA9IDEgKyA3ICogKHdlZWsgLSAxKSArIGxvY2FsV2Vla2RheSArIHdlZWtPZmZzZXQsXG4gICAgICAgICAgICByZXNZZWFyLCByZXNEYXlPZlllYXI7XG5cbiAgICAgICAgaWYgKGRheU9mWWVhciA8PSAwKSB7XG4gICAgICAgICAgICByZXNZZWFyID0geWVhciAtIDE7XG4gICAgICAgICAgICByZXNEYXlPZlllYXIgPSBkYXlzSW5ZZWFyKHJlc1llYXIpICsgZGF5T2ZZZWFyO1xuICAgICAgICB9IGVsc2UgaWYgKGRheU9mWWVhciA+IGRheXNJblllYXIoeWVhcikpIHtcbiAgICAgICAgICAgIHJlc1llYXIgPSB5ZWFyICsgMTtcbiAgICAgICAgICAgIHJlc0RheU9mWWVhciA9IGRheU9mWWVhciAtIGRheXNJblllYXIoeWVhcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNZZWFyID0geWVhcjtcbiAgICAgICAgICAgIHJlc0RheU9mWWVhciA9IGRheU9mWWVhcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB5ZWFyOiByZXNZZWFyLFxuICAgICAgICAgICAgZGF5T2ZZZWFyOiByZXNEYXlPZlllYXJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3ZWVrT2ZZZWFyKG1vbSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIHdlZWtPZmZzZXQgPSBmaXJzdFdlZWtPZmZzZXQobW9tLnllYXIoKSwgZG93LCBkb3kpLFxuICAgICAgICAgICAgd2VlayA9IE1hdGguZmxvb3IoKG1vbS5kYXlPZlllYXIoKSAtIHdlZWtPZmZzZXQgLSAxKSAvIDcpICsgMSxcbiAgICAgICAgICAgIHJlc1dlZWssIHJlc1llYXI7XG5cbiAgICAgICAgaWYgKHdlZWsgPCAxKSB7XG4gICAgICAgICAgICByZXNZZWFyID0gbW9tLnllYXIoKSAtIDE7XG4gICAgICAgICAgICByZXNXZWVrID0gd2VlayArIHdlZWtzSW5ZZWFyKHJlc1llYXIsIGRvdywgZG95KTtcbiAgICAgICAgfSBlbHNlIGlmICh3ZWVrID4gd2Vla3NJblllYXIobW9tLnllYXIoKSwgZG93LCBkb3kpKSB7XG4gICAgICAgICAgICByZXNXZWVrID0gd2VlayAtIHdlZWtzSW5ZZWFyKG1vbS55ZWFyKCksIGRvdywgZG95KTtcbiAgICAgICAgICAgIHJlc1llYXIgPSBtb20ueWVhcigpICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc1llYXIgPSBtb20ueWVhcigpO1xuICAgICAgICAgICAgcmVzV2VlayA9IHdlZWs7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgd2VlazogcmVzV2VlayxcbiAgICAgICAgICAgIHllYXI6IHJlc1llYXJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3ZWVrc0luWWVhcih5ZWFyLCBkb3csIGRveSkge1xuICAgICAgICB2YXIgd2Vla09mZnNldCA9IGZpcnN0V2Vla09mZnNldCh5ZWFyLCBkb3csIGRveSksXG4gICAgICAgICAgICB3ZWVrT2Zmc2V0TmV4dCA9IGZpcnN0V2Vla09mZnNldCh5ZWFyICsgMSwgZG93LCBkb3kpO1xuICAgICAgICByZXR1cm4gKGRheXNJblllYXIoeWVhcikgLSB3ZWVrT2Zmc2V0ICsgd2Vla09mZnNldE5leHQpIC8gNztcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigndycsIFsnd3cnLCAyXSwgJ3dvJywgJ3dlZWsnKTtcbiAgICBhZGRGb3JtYXRUb2tlbignVycsIFsnV1cnLCAyXSwgJ1dvJywgJ2lzb1dlZWsnKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnd2VlaycsICd3Jyk7XG4gICAgYWRkVW5pdEFsaWFzKCdpc29XZWVrJywgJ1cnKTtcblxuICAgIC8vIFBSSU9SSVRJRVNcblxuICAgIGFkZFVuaXRQcmlvcml0eSgnd2VlaycsIDUpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2VlaycsIDUpO1xuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbigndycsICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ3d3JywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1cnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdXVycsIG1hdGNoMXRvMiwgbWF0Y2gyKTtcblxuICAgIGFkZFdlZWtQYXJzZVRva2VuKFsndycsICd3dycsICdXJywgJ1dXJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuLnN1YnN0cigwLCAxKV0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICAvLyBMT0NBTEVTXG5cbiAgICBmdW5jdGlvbiBsb2NhbGVXZWVrIChtb20pIHtcbiAgICAgICAgcmV0dXJuIHdlZWtPZlllYXIobW9tLCB0aGlzLl93ZWVrLmRvdywgdGhpcy5fd2Vlay5kb3kpLndlZWs7XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRMb2NhbGVXZWVrID0ge1xuICAgICAgICBkb3cgOiAwLCAvLyBTdW5kYXkgaXMgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2Vlay5cbiAgICAgICAgZG95IDogNiAgLy8gVGhlIHdlZWsgdGhhdCBjb250YWlucyBKYW4gNnRoIGlzIHRoZSBmaXJzdCB3ZWVrIG9mIHRoZSB5ZWFyLlxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsb2NhbGVGaXJzdERheU9mV2VlayAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93ZWVrLmRvdztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsb2NhbGVGaXJzdERheU9mWWVhciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93ZWVrLmRveTtcbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBnZXRTZXRXZWVrIChpbnB1dCkge1xuICAgICAgICB2YXIgd2VlayA9IHRoaXMubG9jYWxlRGF0YSgpLndlZWsodGhpcyk7XG4gICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8gd2VlayA6IHRoaXMuYWRkKChpbnB1dCAtIHdlZWspICogNywgJ2QnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRJU09XZWVrIChpbnB1dCkge1xuICAgICAgICB2YXIgd2VlayA9IHdlZWtPZlllYXIodGhpcywgMSwgNCkud2VlaztcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrIDogdGhpcy5hZGQoKGlucHV0IC0gd2VlaykgKiA3LCAnZCcpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdkJywgMCwgJ2RvJywgJ2RheScpO1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ2RkJywgMCwgMCwgZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkud2Vla2RheXNNaW4odGhpcywgZm9ybWF0KTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdkZGQnLCAwLCAwLCBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS53ZWVrZGF5c1Nob3J0KHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignZGRkZCcsIDAsIDAsIGZ1bmN0aW9uIChmb3JtYXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLndlZWtkYXlzKHRoaXMsIGZvcm1hdCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignZScsIDAsIDAsICd3ZWVrZGF5Jyk7XG4gICAgYWRkRm9ybWF0VG9rZW4oJ0UnLCAwLCAwLCAnaXNvV2Vla2RheScpO1xuXG4gICAgLy8gQUxJQVNFU1xuXG4gICAgYWRkVW5pdEFsaWFzKCdkYXknLCAnZCcpO1xuICAgIGFkZFVuaXRBbGlhcygnd2Vla2RheScsICdlJyk7XG4gICAgYWRkVW5pdEFsaWFzKCdpc29XZWVrZGF5JywgJ0UnKTtcblxuICAgIC8vIFBSSU9SSVRZXG4gICAgYWRkVW5pdFByaW9yaXR5KCdkYXknLCAxMSk7XG4gICAgYWRkVW5pdFByaW9yaXR5KCd3ZWVrZGF5JywgMTEpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2Vla2RheScsIDExKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ2QnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2UnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0UnLCAgICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkJywgICBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLndlZWtkYXlzTWluUmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkZCcsICAgZnVuY3Rpb24gKGlzU3RyaWN0LCBsb2NhbGUpIHtcbiAgICAgICAgcmV0dXJuIGxvY2FsZS53ZWVrZGF5c1Nob3J0UmVnZXgoaXNTdHJpY3QpO1xuICAgIH0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2RkZGQnLCAgIGZ1bmN0aW9uIChpc1N0cmljdCwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUud2Vla2RheXNSZWdleChpc1N0cmljdCk7XG4gICAgfSk7XG5cbiAgICBhZGRXZWVrUGFyc2VUb2tlbihbJ2RkJywgJ2RkZCcsICdkZGRkJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB2YXIgd2Vla2RheSA9IGNvbmZpZy5fbG9jYWxlLndlZWtkYXlzUGFyc2UoaW5wdXQsIHRva2VuLCBjb25maWcuX3N0cmljdCk7XG4gICAgICAgIC8vIGlmIHdlIGRpZG4ndCBnZXQgYSB3ZWVrZGF5IG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZFxuICAgICAgICBpZiAod2Vla2RheSAhPSBudWxsKSB7XG4gICAgICAgICAgICB3ZWVrLmQgPSB3ZWVrZGF5O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuaW52YWxpZFdlZWtkYXkgPSBpbnB1dDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgYWRkV2Vla1BhcnNlVG9rZW4oWydkJywgJ2UnLCAnRSddLCBmdW5jdGlvbiAoaW5wdXQsIHdlZWssIGNvbmZpZywgdG9rZW4pIHtcbiAgICAgICAgd2Vla1t0b2tlbl0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICAvLyBIRUxQRVJTXG5cbiAgICBmdW5jdGlvbiBwYXJzZVdlZWtkYXkoaW5wdXQsIGxvY2FsZSkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc05hTihpbnB1dCkpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUludChpbnB1dCwgMTApO1xuICAgICAgICB9XG5cbiAgICAgICAgaW5wdXQgPSBsb2NhbGUud2Vla2RheXNQYXJzZShpbnB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZUlzb1dlZWtkYXkoaW5wdXQsIGxvY2FsZSkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS53ZWVrZGF5c1BhcnNlKGlucHV0KSAlIDcgfHwgNztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNOYU4oaW5wdXQpID8gbnVsbCA6IGlucHV0O1xuICAgIH1cblxuICAgIC8vIExPQ0FMRVNcbiAgICBmdW5jdGlvbiBzaGlmdFdlZWtkYXlzICh3cywgbikge1xuICAgICAgICByZXR1cm4gd3Muc2xpY2UobiwgNykuY29uY2F0KHdzLnNsaWNlKDAsIG4pKTtcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdExvY2FsZVdlZWtkYXlzID0gJ1N1bmRheV9Nb25kYXlfVHVlc2RheV9XZWRuZXNkYXlfVGh1cnNkYXlfRnJpZGF5X1NhdHVyZGF5Jy5zcGxpdCgnXycpO1xuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzIChtLCBmb3JtYXQpIHtcbiAgICAgICAgdmFyIHdlZWtkYXlzID0gaXNBcnJheSh0aGlzLl93ZWVrZGF5cykgPyB0aGlzLl93ZWVrZGF5cyA6XG4gICAgICAgICAgICB0aGlzLl93ZWVrZGF5c1sobSAmJiBtICE9PSB0cnVlICYmIHRoaXMuX3dlZWtkYXlzLmlzRm9ybWF0LnRlc3QoZm9ybWF0KSkgPyAnZm9ybWF0JyA6ICdzdGFuZGFsb25lJ107XG4gICAgICAgIHJldHVybiAobSA9PT0gdHJ1ZSkgPyBzaGlmdFdlZWtkYXlzKHdlZWtkYXlzLCB0aGlzLl93ZWVrLmRvdylcbiAgICAgICAgICAgIDogKG0pID8gd2Vla2RheXNbbS5kYXkoKV0gOiB3ZWVrZGF5cztcbiAgICB9XG5cbiAgICB2YXIgZGVmYXVsdExvY2FsZVdlZWtkYXlzU2hvcnQgPSAnU3VuX01vbl9UdWVfV2VkX1RodV9GcmlfU2F0Jy5zcGxpdCgnXycpO1xuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzU2hvcnQgKG0pIHtcbiAgICAgICAgcmV0dXJuIChtID09PSB0cnVlKSA/IHNoaWZ0V2Vla2RheXModGhpcy5fd2Vla2RheXNTaG9ydCwgdGhpcy5fd2Vlay5kb3cpXG4gICAgICAgICAgICA6IChtKSA/IHRoaXMuX3dlZWtkYXlzU2hvcnRbbS5kYXkoKV0gOiB0aGlzLl93ZWVrZGF5c1Nob3J0O1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TG9jYWxlV2Vla2RheXNNaW4gPSAnU3VfTW9fVHVfV2VfVGhfRnJfU2EnLnNwbGl0KCdfJyk7XG4gICAgZnVuY3Rpb24gbG9jYWxlV2Vla2RheXNNaW4gKG0pIHtcbiAgICAgICAgcmV0dXJuIChtID09PSB0cnVlKSA/IHNoaWZ0V2Vla2RheXModGhpcy5fd2Vla2RheXNNaW4sIHRoaXMuX3dlZWsuZG93KVxuICAgICAgICAgICAgOiAobSkgPyB0aGlzLl93ZWVrZGF5c01pblttLmRheSgpXSA6IHRoaXMuX3dlZWtkYXlzTWluO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZVN0cmljdFBhcnNlJDEod2Vla2RheU5hbWUsIGZvcm1hdCwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBpLCBpaSwgbW9tLCBsbGMgPSB3ZWVrZGF5TmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fbWluV2Vla2RheXNQYXJzZSA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNzsgKytpKSB7XG4gICAgICAgICAgICAgICAgbW9tID0gY3JlYXRlVVRDKFsyMDAwLCAxXSkuZGF5KGkpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21pbldlZWtkYXlzUGFyc2VbaV0gPSB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRXZWVrZGF5c1BhcnNlW2ldID0gdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZVtpXSA9IHRoaXMud2Vla2RheXMobW9tLCAnJykudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXQgPT09ICdkZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3dlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9taW5XZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpaSAhPT0gLTEgPyBpaSA6IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoZm9ybWF0ID09PSAnZGRkZCcpIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl93ZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9zaG9ydFdlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgaWYgKGlpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX21pbldlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGRkJykge1xuICAgICAgICAgICAgICAgIGlpID0gaW5kZXhPZi5jYWxsKHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fd2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICBpZiAoaWkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWkgPSBpbmRleE9mLmNhbGwodGhpcy5fbWluV2Vla2RheXNQYXJzZSwgbGxjKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWkgIT09IC0xID8gaWkgOiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9taW5XZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl93ZWVrZGF5c1BhcnNlLCBsbGMpO1xuICAgICAgICAgICAgICAgIGlmIChpaSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpaSA9IGluZGV4T2YuY2FsbCh0aGlzLl9zaG9ydFdlZWtkYXlzUGFyc2UsIGxsYyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlpICE9PSAtMSA/IGlpIDogbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxvY2FsZVdlZWtkYXlzUGFyc2UgKHdlZWtkYXlOYW1lLCBmb3JtYXQsIHN0cmljdCkge1xuICAgICAgICB2YXIgaSwgbW9tLCByZWdleDtcblxuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlU3RyaWN0UGFyc2UkMS5jYWxsKHRoaXMsIHdlZWtkYXlOYW1lLCBmb3JtYXQsIHN0cmljdCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX21pbldlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fZnVsbFdlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuXG4gICAgICAgICAgICBtb20gPSBjcmVhdGVVVEMoWzIwMDAsIDFdKS5kYXkoaSk7XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmICF0aGlzLl9mdWxsV2Vla2RheXNQYXJzZVtpXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2Z1bGxXZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnXFxcXC4/JykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRXZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzU2hvcnQobW9tLCAnJykucmVwbGFjZSgnLicsICdcXFxcLj8nKSArICckJywgJ2knKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9taW5XZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnXFxcXC4/JykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3dlZWtkYXlzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICByZWdleCA9ICdeJyArIHRoaXMud2Vla2RheXMobW9tLCAnJykgKyAnfF4nICsgdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpICsgJ3xeJyArIHRoaXMud2Vla2RheXNNaW4obW9tLCAnJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZVtpXSA9IG5ldyBSZWdFeHAocmVnZXgucmVwbGFjZSgnLicsICcnKSwgJ2knKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHRlc3QgdGhlIHJlZ2V4XG4gICAgICAgICAgICBpZiAoc3RyaWN0ICYmIGZvcm1hdCA9PT0gJ2RkZGQnICYmIHRoaXMuX2Z1bGxXZWVrZGF5c1BhcnNlW2ldLnRlc3Qod2Vla2RheU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmljdCAmJiBmb3JtYXQgPT09ICdkZGQnICYmIHRoaXMuX3Nob3J0V2Vla2RheXNQYXJzZVtpXS50ZXN0KHdlZWtkYXlOYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnZGQnICYmIHRoaXMuX21pbldlZWtkYXlzUGFyc2VbaV0udGVzdCh3ZWVrZGF5TmFtZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXN0cmljdCAmJiB0aGlzLl93ZWVrZGF5c1BhcnNlW2ldLnRlc3Qod2Vla2RheU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNT01FTlRTXG5cbiAgICBmdW5jdGlvbiBnZXRTZXREYXlPZldlZWsgKGlucHV0KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnB1dCAhPSBudWxsID8gdGhpcyA6IE5hTjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF5ID0gdGhpcy5faXNVVEMgPyB0aGlzLl9kLmdldFVUQ0RheSgpIDogdGhpcy5fZC5nZXREYXkoKTtcbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlucHV0ID0gcGFyc2VXZWVrZGF5KGlucHV0LCB0aGlzLmxvY2FsZURhdGEoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGQoaW5wdXQgLSBkYXksICdkJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZGF5O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2V0TG9jYWxlRGF5T2ZXZWVrIChpbnB1dCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgIT0gbnVsbCA/IHRoaXMgOiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHdlZWtkYXkgPSAodGhpcy5kYXkoKSArIDcgLSB0aGlzLmxvY2FsZURhdGEoKS5fd2Vlay5kb3cpICUgNztcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrZGF5IDogdGhpcy5hZGQoaW5wdXQgLSB3ZWVrZGF5LCAnZCcpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNldElTT0RheU9mV2VlayAoaW5wdXQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0ICE9IG51bGwgPyB0aGlzIDogTmFOO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gYmVoYXZlcyB0aGUgc2FtZSBhcyBtb21lbnQjZGF5IGV4Y2VwdFxuICAgICAgICAvLyBhcyBhIGdldHRlciwgcmV0dXJucyA3IGluc3RlYWQgb2YgMCAoMS03IHJhbmdlIGluc3RlYWQgb2YgMC02KVxuICAgICAgICAvLyBhcyBhIHNldHRlciwgc3VuZGF5IHNob3VsZCBiZWxvbmcgdG8gdGhlIHByZXZpb3VzIHdlZWsuXG5cbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhciB3ZWVrZGF5ID0gcGFyc2VJc29XZWVrZGF5KGlucHV0LCB0aGlzLmxvY2FsZURhdGEoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kYXkodGhpcy5kYXkoKSAlIDcgPyB3ZWVrZGF5IDogd2Vla2RheSAtIDcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF5KCkgfHwgNztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0V2Vla2RheXNSZWdleCA9IG1hdGNoV29yZDtcbiAgICBmdW5jdGlvbiB3ZWVrZGF5c1JlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wKHRoaXMsICdfd2Vla2RheXNSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNSZWdleCA9IGRlZmF1bHRXZWVrZGF5c1JlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggOiB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGRlZmF1bHRXZWVrZGF5c1Nob3J0UmVnZXggPSBtYXRjaFdvcmQ7XG4gICAgZnVuY3Rpb24gd2Vla2RheXNTaG9ydFJlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU2hvcnRTdHJpY3RSZWdleDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaGFzT3duUHJvcCh0aGlzLCAnX3dlZWtkYXlzU2hvcnRSZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNTaG9ydFJlZ2V4ID0gZGVmYXVsdFdlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c1Nob3J0U3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzU2hvcnRTdHJpY3RSZWdleCA6IHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0V2Vla2RheXNNaW5SZWdleCA9IG1hdGNoV29yZDtcbiAgICBmdW5jdGlvbiB3ZWVrZGF5c01pblJlZ2V4IChpc1N0cmljdCkge1xuICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZUV4YWN0KSB7XG4gICAgICAgICAgICBpZiAoIWhhc093blByb3AodGhpcywgJ193ZWVrZGF5c1JlZ2V4JykpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlV2Vla2RheXNQYXJzZS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFoYXNPd25Qcm9wKHRoaXMsICdfd2Vla2RheXNNaW5SZWdleCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNNaW5SZWdleCA9IGRlZmF1bHRXZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXggJiYgaXNTdHJpY3QgP1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzTWluU3RyaWN0UmVnZXggOiB0aGlzLl93ZWVrZGF5c01pblJlZ2V4O1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjb21wdXRlV2Vla2RheXNQYXJzZSAoKSB7XG4gICAgICAgIGZ1bmN0aW9uIGNtcExlblJldihhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi5sZW5ndGggLSBhLmxlbmd0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtaW5QaWVjZXMgPSBbXSwgc2hvcnRQaWVjZXMgPSBbXSwgbG9uZ1BpZWNlcyA9IFtdLCBtaXhlZFBpZWNlcyA9IFtdLFxuICAgICAgICAgICAgaSwgbW9tLCBtaW5wLCBzaG9ydHAsIGxvbmdwO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNzsgaSsrKSB7XG4gICAgICAgICAgICAvLyBtYWtlIHRoZSByZWdleCBpZiB3ZSBkb24ndCBoYXZlIGl0IGFscmVhZHlcbiAgICAgICAgICAgIG1vbSA9IGNyZWF0ZVVUQyhbMjAwMCwgMV0pLmRheShpKTtcbiAgICAgICAgICAgIG1pbnAgPSB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpO1xuICAgICAgICAgICAgc2hvcnRwID0gdGhpcy53ZWVrZGF5c1Nob3J0KG1vbSwgJycpO1xuICAgICAgICAgICAgbG9uZ3AgPSB0aGlzLndlZWtkYXlzKG1vbSwgJycpO1xuICAgICAgICAgICAgbWluUGllY2VzLnB1c2gobWlucCk7XG4gICAgICAgICAgICBzaG9ydFBpZWNlcy5wdXNoKHNob3J0cCk7XG4gICAgICAgICAgICBsb25nUGllY2VzLnB1c2gobG9uZ3ApO1xuICAgICAgICAgICAgbWl4ZWRQaWVjZXMucHVzaChtaW5wKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2goc2hvcnRwKTtcbiAgICAgICAgICAgIG1peGVkUGllY2VzLnB1c2gobG9uZ3ApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNvcnRpbmcgbWFrZXMgc3VyZSBpZiBvbmUgd2Vla2RheSAob3IgYWJicikgaXMgYSBwcmVmaXggb2YgYW5vdGhlciBpdFxuICAgICAgICAvLyB3aWxsIG1hdGNoIHRoZSBsb25nZXIgcGllY2UuXG4gICAgICAgIG1pblBpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIHNob3J0UGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgbG9uZ1BpZWNlcy5zb3J0KGNtcExlblJldik7XG4gICAgICAgIG1peGVkUGllY2VzLnNvcnQoY21wTGVuUmV2KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDc7IGkrKykge1xuICAgICAgICAgICAgc2hvcnRQaWVjZXNbaV0gPSByZWdleEVzY2FwZShzaG9ydFBpZWNlc1tpXSk7XG4gICAgICAgICAgICBsb25nUGllY2VzW2ldID0gcmVnZXhFc2NhcGUobG9uZ1BpZWNlc1tpXSk7XG4gICAgICAgICAgICBtaXhlZFBpZWNlc1tpXSA9IHJlZ2V4RXNjYXBlKG1peGVkUGllY2VzW2ldKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3dlZWtkYXlzUmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBtaXhlZFBpZWNlcy5qb2luKCd8JykgKyAnKScsICdpJyk7XG4gICAgICAgIHRoaXMuX3dlZWtkYXlzU2hvcnRSZWdleCA9IHRoaXMuX3dlZWtkYXlzUmVnZXg7XG4gICAgICAgIHRoaXMuX3dlZWtkYXlzTWluUmVnZXggPSB0aGlzLl93ZWVrZGF5c1JlZ2V4O1xuXG4gICAgICAgIHRoaXMuX3dlZWtkYXlzU3RyaWN0UmVnZXggPSBuZXcgUmVnRXhwKCdeKCcgKyBsb25nUGllY2VzLmpvaW4oJ3wnKSArICcpJywgJ2knKTtcbiAgICAgICAgdGhpcy5fd2Vla2RheXNTaG9ydFN0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgc2hvcnRQaWVjZXMuam9pbignfCcpICsgJyknLCAnaScpO1xuICAgICAgICB0aGlzLl93ZWVrZGF5c01pblN0cmljdFJlZ2V4ID0gbmV3IFJlZ0V4cCgnXignICsgbWluUGllY2VzLmpvaW4oJ3wnKSArICcpJywgJ2knKTtcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBmdW5jdGlvbiBoRm9ybWF0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ob3VycygpICUgMTIgfHwgMTI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24ga0Zvcm1hdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaG91cnMoKSB8fCAyNDtcbiAgICB9XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSCcsIFsnSEgnLCAyXSwgMCwgJ2hvdXInKTtcbiAgICBhZGRGb3JtYXRUb2tlbignaCcsIFsnaGgnLCAyXSwgMCwgaEZvcm1hdCk7XG4gICAgYWRkRm9ybWF0VG9rZW4oJ2snLCBbJ2trJywgMl0sIDAsIGtGb3JtYXQpO1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ2htbScsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnICsgaEZvcm1hdC5hcHBseSh0aGlzKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKCdobW1zcycsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnICsgaEZvcm1hdC5hcHBseSh0aGlzKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKSArXG4gICAgICAgICAgICB6ZXJvRmlsbCh0aGlzLnNlY29uZHMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSG1tJywgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gJycgKyB0aGlzLmhvdXJzKCkgKyB6ZXJvRmlsbCh0aGlzLm1pbnV0ZXMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbignSG1tc3MnLCAwLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAnJyArIHRoaXMuaG91cnMoKSArIHplcm9GaWxsKHRoaXMubWludXRlcygpLCAyKSArXG4gICAgICAgICAgICB6ZXJvRmlsbCh0aGlzLnNlY29uZHMoKSwgMik7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBtZXJpZGllbSAodG9rZW4sIGxvd2VyY2FzZSkge1xuICAgICAgICBhZGRGb3JtYXRUb2tlbih0b2tlbiwgMCwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLm1lcmlkaWVtKHRoaXMuaG91cnMoKSwgdGhpcy5taW51dGVzKCksIGxvd2VyY2FzZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG1lcmlkaWVtKCdhJywgdHJ1ZSk7XG4gICAgbWVyaWRpZW0oJ0EnLCBmYWxzZSk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ2hvdXInLCAnaCcpO1xuXG4gICAgLy8gUFJJT1JJVFlcbiAgICBhZGRVbml0UHJpb3JpdHkoJ2hvdXInLCAxMyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBmdW5jdGlvbiBtYXRjaE1lcmlkaWVtIChpc1N0cmljdCwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUuX21lcmlkaWVtUGFyc2U7XG4gICAgfVxuXG4gICAgYWRkUmVnZXhUb2tlbignYScsICBtYXRjaE1lcmlkaWVtKTtcbiAgICBhZGRSZWdleFRva2VuKCdBJywgIG1hdGNoTWVyaWRpZW0pO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0gnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdoJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignaycsICBtYXRjaDF0bzIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0hIJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2hoJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2trJywgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuXG4gICAgYWRkUmVnZXhUb2tlbignaG1tJywgbWF0Y2gzdG80KTtcbiAgICBhZGRSZWdleFRva2VuKCdobW1zcycsIG1hdGNoNXRvNik7XG4gICAgYWRkUmVnZXhUb2tlbignSG1tJywgbWF0Y2gzdG80KTtcbiAgICBhZGRSZWdleFRva2VuKCdIbW1zcycsIG1hdGNoNXRvNik7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnSCcsICdISCddLCBIT1VSKTtcbiAgICBhZGRQYXJzZVRva2VuKFsnaycsICdrayddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIGtJbnB1dCA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgYXJyYXlbSE9VUl0gPSBrSW5wdXQgPT09IDI0ID8gMCA6IGtJbnB1dDtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKFsnYScsICdBJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2lzUG0gPSBjb25maWcuX2xvY2FsZS5pc1BNKGlucHV0KTtcbiAgICAgICAgY29uZmlnLl9tZXJpZGllbSA9IGlucHV0O1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oWydoJywgJ2hoJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuYmlnSG91ciA9IHRydWU7XG4gICAgfSk7XG4gICAgYWRkUGFyc2VUb2tlbignaG1tJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIHZhciBwb3MgPSBpbnB1dC5sZW5ndGggLSAyO1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0LnN1YnN0cigwLCBwb3MpKTtcbiAgICAgICAgYXJyYXlbTUlOVVRFXSA9IHRvSW50KGlucHV0LnN1YnN0cihwb3MpKTtcbiAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuYmlnSG91ciA9IHRydWU7XG4gICAgfSk7XG4gICAgYWRkUGFyc2VUb2tlbignaG1tc3MnLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIHBvczEgPSBpbnB1dC5sZW5ndGggLSA0O1xuICAgICAgICB2YXIgcG9zMiA9IGlucHV0Lmxlbmd0aCAtIDI7XG4gICAgICAgIGFycmF5W0hPVVJdID0gdG9JbnQoaW5wdXQuc3Vic3RyKDAsIHBvczEpKTtcbiAgICAgICAgYXJyYXlbTUlOVVRFXSA9IHRvSW50KGlucHV0LnN1YnN0cihwb3MxLCAyKSk7XG4gICAgICAgIGFycmF5W1NFQ09ORF0gPSB0b0ludChpbnB1dC5zdWJzdHIocG9zMikpO1xuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5iaWdIb3VyID0gdHJ1ZTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCdIbW0nLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgdmFyIHBvcyA9IGlucHV0Lmxlbmd0aCAtIDI7XG4gICAgICAgIGFycmF5W0hPVVJdID0gdG9JbnQoaW5wdXQuc3Vic3RyKDAsIHBvcykpO1xuICAgICAgICBhcnJheVtNSU5VVEVdID0gdG9JbnQoaW5wdXQuc3Vic3RyKHBvcykpO1xuICAgIH0pO1xuICAgIGFkZFBhcnNlVG9rZW4oJ0htbXNzJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIHZhciBwb3MxID0gaW5wdXQubGVuZ3RoIC0gNDtcbiAgICAgICAgdmFyIHBvczIgPSBpbnB1dC5sZW5ndGggLSAyO1xuICAgICAgICBhcnJheVtIT1VSXSA9IHRvSW50KGlucHV0LnN1YnN0cigwLCBwb3MxKSk7XG4gICAgICAgIGFycmF5W01JTlVURV0gPSB0b0ludChpbnB1dC5zdWJzdHIocG9zMSwgMikpO1xuICAgICAgICBhcnJheVtTRUNPTkRdID0gdG9JbnQoaW5wdXQuc3Vic3RyKHBvczIpKTtcbiAgICB9KTtcblxuICAgIC8vIExPQ0FMRVNcblxuICAgIGZ1bmN0aW9uIGxvY2FsZUlzUE0gKGlucHV0KSB7XG4gICAgICAgIC8vIElFOCBRdWlya3MgTW9kZSAmIElFNyBTdGFuZGFyZHMgTW9kZSBkbyBub3QgYWxsb3cgYWNjZXNzaW5nIHN0cmluZ3MgbGlrZSBhcnJheXNcbiAgICAgICAgLy8gVXNpbmcgY2hhckF0IHNob3VsZCBiZSBtb3JlIGNvbXBhdGlibGUuXG4gICAgICAgIHJldHVybiAoKGlucHV0ICsgJycpLnRvTG93ZXJDYXNlKCkuY2hhckF0KDApID09PSAncCcpO1xuICAgIH1cblxuICAgIHZhciBkZWZhdWx0TG9jYWxlTWVyaWRpZW1QYXJzZSA9IC9bYXBdXFwuP20/XFwuPy9pO1xuICAgIGZ1bmN0aW9uIGxvY2FsZU1lcmlkaWVtIChob3VycywgbWludXRlcywgaXNMb3dlcikge1xuICAgICAgICBpZiAoaG91cnMgPiAxMSkge1xuICAgICAgICAgICAgcmV0dXJuIGlzTG93ZXIgPyAncG0nIDogJ1BNJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBpc0xvd2VyID8gJ2FtJyA6ICdBTSc7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8vIE1PTUVOVFNcblxuICAgIC8vIFNldHRpbmcgdGhlIGhvdXIgc2hvdWxkIGtlZXAgdGhlIHRpbWUsIGJlY2F1c2UgdGhlIHVzZXIgZXhwbGljaXRseVxuICAgIC8vIHNwZWNpZmllZCB3aGljaCBob3VyIHRoZXkgd2FudC4gU28gdHJ5aW5nIHRvIG1haW50YWluIHRoZSBzYW1lIGhvdXIgKGluXG4gICAgLy8gYSBuZXcgdGltZXpvbmUpIG1ha2VzIHNlbnNlLiBBZGRpbmcvc3VidHJhY3RpbmcgaG91cnMgZG9lcyBub3QgZm9sbG93XG4gICAgLy8gdGhpcyBydWxlLlxuICAgIHZhciBnZXRTZXRIb3VyID0gbWFrZUdldFNldCgnSG91cnMnLCB0cnVlKTtcblxuICAgIHZhciBiYXNlQ29uZmlnID0ge1xuICAgICAgICBjYWxlbmRhcjogZGVmYXVsdENhbGVuZGFyLFxuICAgICAgICBsb25nRGF0ZUZvcm1hdDogZGVmYXVsdExvbmdEYXRlRm9ybWF0LFxuICAgICAgICBpbnZhbGlkRGF0ZTogZGVmYXVsdEludmFsaWREYXRlLFxuICAgICAgICBvcmRpbmFsOiBkZWZhdWx0T3JkaW5hbCxcbiAgICAgICAgZGF5T2ZNb250aE9yZGluYWxQYXJzZTogZGVmYXVsdERheU9mTW9udGhPcmRpbmFsUGFyc2UsXG4gICAgICAgIHJlbGF0aXZlVGltZTogZGVmYXVsdFJlbGF0aXZlVGltZSxcblxuICAgICAgICBtb250aHM6IGRlZmF1bHRMb2NhbGVNb250aHMsXG4gICAgICAgIG1vbnRoc1Nob3J0OiBkZWZhdWx0TG9jYWxlTW9udGhzU2hvcnQsXG5cbiAgICAgICAgd2VlazogZGVmYXVsdExvY2FsZVdlZWssXG5cbiAgICAgICAgd2Vla2RheXM6IGRlZmF1bHRMb2NhbGVXZWVrZGF5cyxcbiAgICAgICAgd2Vla2RheXNNaW46IGRlZmF1bHRMb2NhbGVXZWVrZGF5c01pbixcbiAgICAgICAgd2Vla2RheXNTaG9ydDogZGVmYXVsdExvY2FsZVdlZWtkYXlzU2hvcnQsXG5cbiAgICAgICAgbWVyaWRpZW1QYXJzZTogZGVmYXVsdExvY2FsZU1lcmlkaWVtUGFyc2VcbiAgICB9O1xuXG4gICAgLy8gaW50ZXJuYWwgc3RvcmFnZSBmb3IgbG9jYWxlIGNvbmZpZyBmaWxlc1xuICAgIHZhciBsb2NhbGVzID0ge307XG4gICAgdmFyIGxvY2FsZUZhbWlsaWVzID0ge307XG4gICAgdmFyIGdsb2JhbExvY2FsZTtcblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZUxvY2FsZShrZXkpIHtcbiAgICAgICAgcmV0dXJuIGtleSA/IGtleS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoJ18nLCAnLScpIDoga2V5O1xuICAgIH1cblxuICAgIC8vIHBpY2sgdGhlIGxvY2FsZSBmcm9tIHRoZSBhcnJheVxuICAgIC8vIHRyeSBbJ2VuLWF1JywgJ2VuLWdiJ10gYXMgJ2VuLWF1JywgJ2VuLWdiJywgJ2VuJywgYXMgaW4gbW92ZSB0aHJvdWdoIHRoZSBsaXN0IHRyeWluZyBlYWNoXG4gICAgLy8gc3Vic3RyaW5nIGZyb20gbW9zdCBzcGVjaWZpYyB0byBsZWFzdCwgYnV0IG1vdmUgdG8gdGhlIG5leHQgYXJyYXkgaXRlbSBpZiBpdCdzIGEgbW9yZSBzcGVjaWZpYyB2YXJpYW50IHRoYW4gdGhlIGN1cnJlbnQgcm9vdFxuICAgIGZ1bmN0aW9uIGNob29zZUxvY2FsZShuYW1lcykge1xuICAgICAgICB2YXIgaSA9IDAsIGosIG5leHQsIGxvY2FsZSwgc3BsaXQ7XG5cbiAgICAgICAgd2hpbGUgKGkgPCBuYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHNwbGl0ID0gbm9ybWFsaXplTG9jYWxlKG5hbWVzW2ldKS5zcGxpdCgnLScpO1xuICAgICAgICAgICAgaiA9IHNwbGl0Lmxlbmd0aDtcbiAgICAgICAgICAgIG5leHQgPSBub3JtYWxpemVMb2NhbGUobmFtZXNbaSArIDFdKTtcbiAgICAgICAgICAgIG5leHQgPSBuZXh0ID8gbmV4dC5zcGxpdCgnLScpIDogbnVsbDtcbiAgICAgICAgICAgIHdoaWxlIChqID4gMCkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGxvYWRMb2NhbGUoc3BsaXQuc2xpY2UoMCwgaikuam9pbignLScpKTtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChuZXh0ICYmIG5leHQubGVuZ3RoID49IGogJiYgY29tcGFyZUFycmF5cyhzcGxpdCwgbmV4dCwgdHJ1ZSkgPj0gaiAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgLy90aGUgbmV4dCBhcnJheSBpdGVtIGlzIGJldHRlciB0aGFuIGEgc2hhbGxvd2VyIHN1YnN0cmluZyBvZiB0aGlzIG9uZVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgai0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9hZExvY2FsZShuYW1lKSB7XG4gICAgICAgIHZhciBvbGRMb2NhbGUgPSBudWxsO1xuICAgICAgICAvLyBUT0RPOiBGaW5kIGEgYmV0dGVyIHdheSB0byByZWdpc3RlciBhbmQgbG9hZCBhbGwgdGhlIGxvY2FsZXMgaW4gTm9kZVxuICAgICAgICBpZiAoIWxvY2FsZXNbbmFtZV0gJiYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgICAgICAgICAgIG1vZHVsZSAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBvbGRMb2NhbGUgPSBnbG9iYWxMb2NhbGUuX2FiYnI7XG4gICAgICAgICAgICAgICAgdmFyIGFsaWFzZWRSZXF1aXJlID0gcmVxdWlyZTtcbiAgICAgICAgICAgICAgICBhbGlhc2VkUmVxdWlyZSgnLi9sb2NhbGUvJyArIG5hbWUpO1xuICAgICAgICAgICAgICAgIGdldFNldEdsb2JhbExvY2FsZShvbGRMb2NhbGUpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbG9jYWxlc1tuYW1lXTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgbG9hZCBsb2NhbGUgYW5kIHRoZW4gc2V0IHRoZSBnbG9iYWwgbG9jYWxlLiAgSWZcbiAgICAvLyBubyBhcmd1bWVudHMgYXJlIHBhc3NlZCBpbiwgaXQgd2lsbCBzaW1wbHkgcmV0dXJuIHRoZSBjdXJyZW50IGdsb2JhbFxuICAgIC8vIGxvY2FsZSBrZXkuXG4gICAgZnVuY3Rpb24gZ2V0U2V0R2xvYmFsTG9jYWxlIChrZXksIHZhbHVlcykge1xuICAgICAgICB2YXIgZGF0YTtcbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlcykpIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZ2V0TG9jYWxlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZGVmaW5lTG9jYWxlKGtleSwgdmFsdWVzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAvLyBtb21lbnQuZHVyYXRpb24uX2xvY2FsZSA9IG1vbWVudC5fbG9jYWxlID0gZGF0YTtcbiAgICAgICAgICAgICAgICBnbG9iYWxMb2NhbGUgPSBkYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKCh0eXBlb2YgY29uc29sZSAhPT0gICd1bmRlZmluZWQnKSAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICAgICAgICAgICAgLy93YXJuIHVzZXIgaWYgYXJndW1lbnRzIGFyZSBwYXNzZWQgYnV0IHRoZSBsb2NhbGUgY291bGQgbm90IGJlIHNldFxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0xvY2FsZSAnICsga2V5ICsgICcgbm90IGZvdW5kLiBEaWQgeW91IGZvcmdldCB0byBsb2FkIGl0PycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGUuX2FiYnI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmaW5lTG9jYWxlIChuYW1lLCBjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxvY2FsZSwgcGFyZW50Q29uZmlnID0gYmFzZUNvbmZpZztcbiAgICAgICAgICAgIGNvbmZpZy5hYmJyID0gbmFtZTtcbiAgICAgICAgICAgIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkZXByZWNhdGVTaW1wbGUoJ2RlZmluZUxvY2FsZU92ZXJyaWRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICd1c2UgbW9tZW50LnVwZGF0ZUxvY2FsZShsb2NhbGVOYW1lLCBjb25maWcpIHRvIGNoYW5nZSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdhbiBleGlzdGluZyBsb2NhbGUuIG1vbWVudC5kZWZpbmVMb2NhbGUobG9jYWxlTmFtZSwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnY29uZmlnKSBzaG91bGQgb25seSBiZSB1c2VkIGZvciBjcmVhdGluZyBhIG5ldyBsb2NhbGUgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnU2VlIGh0dHA6Ly9tb21lbnRqcy5jb20vZ3VpZGVzLyMvd2FybmluZ3MvZGVmaW5lLWxvY2FsZS8gZm9yIG1vcmUgaW5mby4nKTtcbiAgICAgICAgICAgICAgICBwYXJlbnRDb25maWcgPSBsb2NhbGVzW25hbWVdLl9jb25maWc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNvbmZpZy5wYXJlbnRMb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChsb2NhbGVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29uZmlnID0gbG9jYWxlc1tjb25maWcucGFyZW50TG9jYWxlXS5fY29uZmlnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvY2FsZSA9IGxvYWRMb2NhbGUoY29uZmlnLnBhcmVudExvY2FsZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Q29uZmlnID0gbG9jYWxlLl9jb25maWc7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWxvY2FsZUZhbWlsaWVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlRmFtaWxpZXNbY29uZmlnLnBhcmVudExvY2FsZV0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsZUZhbWlsaWVzW2NvbmZpZy5wYXJlbnRMb2NhbGVdLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnOiBjb25maWdcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhbGVzW25hbWVdID0gbmV3IExvY2FsZShtZXJnZUNvbmZpZ3MocGFyZW50Q29uZmlnLCBjb25maWcpKTtcblxuICAgICAgICAgICAgaWYgKGxvY2FsZUZhbWlsaWVzW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgbG9jYWxlRmFtaWxpZXNbbmFtZV0uZm9yRWFjaChmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgICAgICAgICBkZWZpbmVMb2NhbGUoeC5uYW1lLCB4LmNvbmZpZyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgZm9yIG5vdzogYWxzbyBzZXQgdGhlIGxvY2FsZVxuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHdlIHNldCB0aGUgbG9jYWxlIEFGVEVSIGFsbCBjaGlsZCBsb2NhbGVzIGhhdmUgYmVlblxuICAgICAgICAgICAgLy8gY3JlYXRlZCwgc28gd2Ugd29uJ3QgZW5kIHVwIHdpdGggdGhlIGNoaWxkIGxvY2FsZSBzZXQuXG4gICAgICAgICAgICBnZXRTZXRHbG9iYWxMb2NhbGUobmFtZSk7XG5cblxuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZXNbbmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyB1c2VmdWwgZm9yIHRlc3RpbmdcbiAgICAgICAgICAgIGRlbGV0ZSBsb2NhbGVzW25hbWVdO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1cGRhdGVMb2NhbGUobmFtZSwgY29uZmlnKSB7XG4gICAgICAgIGlmIChjb25maWcgIT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxvY2FsZSwgdG1wTG9jYWxlLCBwYXJlbnRDb25maWcgPSBiYXNlQ29uZmlnO1xuICAgICAgICAgICAgLy8gTUVSR0VcbiAgICAgICAgICAgIHRtcExvY2FsZSA9IGxvYWRMb2NhbGUobmFtZSk7XG4gICAgICAgICAgICBpZiAodG1wTG9jYWxlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnRDb25maWcgPSB0bXBMb2NhbGUuX2NvbmZpZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbmZpZyA9IG1lcmdlQ29uZmlncyhwYXJlbnRDb25maWcsIGNvbmZpZyk7XG4gICAgICAgICAgICBsb2NhbGUgPSBuZXcgTG9jYWxlKGNvbmZpZyk7XG4gICAgICAgICAgICBsb2NhbGUucGFyZW50TG9jYWxlID0gbG9jYWxlc1tuYW1lXTtcbiAgICAgICAgICAgIGxvY2FsZXNbbmFtZV0gPSBsb2NhbGU7XG5cbiAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgZm9yIG5vdzogYWxzbyBzZXQgdGhlIGxvY2FsZVxuICAgICAgICAgICAgZ2V0U2V0R2xvYmFsTG9jYWxlKG5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gcGFzcyBudWxsIGZvciBjb25maWcgdG8gdW51cGRhdGUsIHVzZWZ1bCBmb3IgdGVzdHNcbiAgICAgICAgICAgIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxlc1tuYW1lXS5wYXJlbnRMb2NhbGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBsb2NhbGVzW25hbWVdID0gbG9jYWxlc1tuYW1lXS5wYXJlbnRMb2NhbGU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsb2NhbGVzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGxvY2FsZXNbbmFtZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsb2NhbGVzW25hbWVdO1xuICAgIH1cblxuICAgIC8vIHJldHVybnMgbG9jYWxlIGRhdGFcbiAgICBmdW5jdGlvbiBnZXRMb2NhbGUgKGtleSkge1xuICAgICAgICB2YXIgbG9jYWxlO1xuXG4gICAgICAgIGlmIChrZXkgJiYga2V5Ll9sb2NhbGUgJiYga2V5Ll9sb2NhbGUuX2FiYnIpIHtcbiAgICAgICAgICAgIGtleSA9IGtleS5fbG9jYWxlLl9hYmJyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFrZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBnbG9iYWxMb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzQXJyYXkoa2V5KSkge1xuICAgICAgICAgICAgLy9zaG9ydC1jaXJjdWl0IGV2ZXJ5dGhpbmcgZWxzZVxuICAgICAgICAgICAgbG9jYWxlID0gbG9hZExvY2FsZShrZXkpO1xuICAgICAgICAgICAgaWYgKGxvY2FsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBrZXkgPSBba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjaG9vc2VMb2NhbGUoa2V5KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0TG9jYWxlcygpIHtcbiAgICAgICAgcmV0dXJuIGtleXMobG9jYWxlcyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2tPdmVyZmxvdyAobSkge1xuICAgICAgICB2YXIgb3ZlcmZsb3c7XG4gICAgICAgIHZhciBhID0gbS5fYTtcblxuICAgICAgICBpZiAoYSAmJiBnZXRQYXJzaW5nRmxhZ3MobSkub3ZlcmZsb3cgPT09IC0yKSB7XG4gICAgICAgICAgICBvdmVyZmxvdyA9XG4gICAgICAgICAgICAgICAgYVtNT05USF0gICAgICAgPCAwIHx8IGFbTU9OVEhdICAgICAgID4gMTEgID8gTU9OVEggOlxuICAgICAgICAgICAgICAgIGFbREFURV0gICAgICAgIDwgMSB8fCBhW0RBVEVdICAgICAgICA+IGRheXNJbk1vbnRoKGFbWUVBUl0sIGFbTU9OVEhdKSA/IERBVEUgOlxuICAgICAgICAgICAgICAgIGFbSE9VUl0gICAgICAgIDwgMCB8fCBhW0hPVVJdICAgICAgICA+IDI0IHx8IChhW0hPVVJdID09PSAyNCAmJiAoYVtNSU5VVEVdICE9PSAwIHx8IGFbU0VDT05EXSAhPT0gMCB8fCBhW01JTExJU0VDT05EXSAhPT0gMCkpID8gSE9VUiA6XG4gICAgICAgICAgICAgICAgYVtNSU5VVEVdICAgICAgPCAwIHx8IGFbTUlOVVRFXSAgICAgID4gNTkgID8gTUlOVVRFIDpcbiAgICAgICAgICAgICAgICBhW1NFQ09ORF0gICAgICA8IDAgfHwgYVtTRUNPTkRdICAgICAgPiA1OSAgPyBTRUNPTkQgOlxuICAgICAgICAgICAgICAgIGFbTUlMTElTRUNPTkRdIDwgMCB8fCBhW01JTExJU0VDT05EXSA+IDk5OSA/IE1JTExJU0VDT05EIDpcbiAgICAgICAgICAgICAgICAtMTtcblxuICAgICAgICAgICAgaWYgKGdldFBhcnNpbmdGbGFncyhtKS5fb3ZlcmZsb3dEYXlPZlllYXIgJiYgKG92ZXJmbG93IDwgWUVBUiB8fCBvdmVyZmxvdyA+IERBVEUpKSB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3cgPSBEQVRFO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGdldFBhcnNpbmdGbGFncyhtKS5fb3ZlcmZsb3dXZWVrcyAmJiBvdmVyZmxvdyA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBvdmVyZmxvdyA9IFdFRUs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZ2V0UGFyc2luZ0ZsYWdzKG0pLl9vdmVyZmxvd1dlZWtkYXkgJiYgb3ZlcmZsb3cgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3cgPSBXRUVLREFZO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MobSkub3ZlcmZsb3cgPSBvdmVyZmxvdztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtO1xuICAgIH1cblxuICAgIC8vIFBpY2sgdGhlIGZpcnN0IGRlZmluZWQgb2YgdHdvIG9yIHRocmVlIGFyZ3VtZW50cy5cbiAgICBmdW5jdGlvbiBkZWZhdWx0cyhhLCBiLCBjKSB7XG4gICAgICAgIGlmIChhICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBhO1xuICAgICAgICB9XG4gICAgICAgIGlmIChiICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKSB7XG4gICAgICAgIC8vIGhvb2tzIGlzIGFjdHVhbGx5IHRoZSBleHBvcnRlZCBtb21lbnQgb2JqZWN0XG4gICAgICAgIHZhciBub3dWYWx1ZSA9IG5ldyBEYXRlKGhvb2tzLm5vdygpKTtcbiAgICAgICAgaWYgKGNvbmZpZy5fdXNlVVRDKSB7XG4gICAgICAgICAgICByZXR1cm4gW25vd1ZhbHVlLmdldFVUQ0Z1bGxZZWFyKCksIG5vd1ZhbHVlLmdldFVUQ01vbnRoKCksIG5vd1ZhbHVlLmdldFVUQ0RhdGUoKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtub3dWYWx1ZS5nZXRGdWxsWWVhcigpLCBub3dWYWx1ZS5nZXRNb250aCgpLCBub3dWYWx1ZS5nZXREYXRlKCldO1xuICAgIH1cblxuICAgIC8vIGNvbnZlcnQgYW4gYXJyYXkgdG8gYSBkYXRlLlxuICAgIC8vIHRoZSBhcnJheSBzaG91bGQgbWlycm9yIHRoZSBwYXJhbWV0ZXJzIGJlbG93XG4gICAgLy8gbm90ZTogYWxsIHZhbHVlcyBwYXN0IHRoZSB5ZWFyIGFyZSBvcHRpb25hbCBhbmQgd2lsbCBkZWZhdWx0IHRvIHRoZSBsb3dlc3QgcG9zc2libGUgdmFsdWUuXG4gICAgLy8gW3llYXIsIG1vbnRoLCBkYXkgLCBob3VyLCBtaW51dGUsIHNlY29uZCwgbWlsbGlzZWNvbmRdXG4gICAgZnVuY3Rpb24gY29uZmlnRnJvbUFycmF5IChjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGRhdGUsIGlucHV0ID0gW10sIGN1cnJlbnREYXRlLCBleHBlY3RlZFdlZWtkYXksIHllYXJUb1VzZTtcblxuICAgICAgICBpZiAoY29uZmlnLl9kKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50RGF0ZSA9IGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKTtcblxuICAgICAgICAvL2NvbXB1dGUgZGF5IG9mIHRoZSB5ZWFyIGZyb20gd2Vla3MgYW5kIHdlZWtkYXlzXG4gICAgICAgIGlmIChjb25maWcuX3cgJiYgY29uZmlnLl9hW0RBVEVdID09IG51bGwgJiYgY29uZmlnLl9hW01PTlRIXSA9PSBudWxsKSB7XG4gICAgICAgICAgICBkYXlPZlllYXJGcm9tV2Vla0luZm8oY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vaWYgdGhlIGRheSBvZiB0aGUgeWVhciBpcyBzZXQsIGZpZ3VyZSBvdXQgd2hhdCBpdCBpc1xuICAgICAgICBpZiAoY29uZmlnLl9kYXlPZlllYXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgeWVhclRvVXNlID0gZGVmYXVsdHMoY29uZmlnLl9hW1lFQVJdLCBjdXJyZW50RGF0ZVtZRUFSXSk7XG5cbiAgICAgICAgICAgIGlmIChjb25maWcuX2RheU9mWWVhciA+IGRheXNJblllYXIoeWVhclRvVXNlKSB8fCBjb25maWcuX2RheU9mWWVhciA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLl9vdmVyZmxvd0RheU9mWWVhciA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRhdGUgPSBjcmVhdGVVVENEYXRlKHllYXJUb1VzZSwgMCwgY29uZmlnLl9kYXlPZlllYXIpO1xuICAgICAgICAgICAgY29uZmlnLl9hW01PTlRIXSA9IGRhdGUuZ2V0VVRDTW9udGgoKTtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtEQVRFXSA9IGRhdGUuZ2V0VVRDRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGVmYXVsdCB0byBjdXJyZW50IGRhdGUuXG4gICAgICAgIC8vICogaWYgbm8geWVhciwgbW9udGgsIGRheSBvZiBtb250aCBhcmUgZ2l2ZW4sIGRlZmF1bHQgdG8gdG9kYXlcbiAgICAgICAgLy8gKiBpZiBkYXkgb2YgbW9udGggaXMgZ2l2ZW4sIGRlZmF1bHQgbW9udGggYW5kIHllYXJcbiAgICAgICAgLy8gKiBpZiBtb250aCBpcyBnaXZlbiwgZGVmYXVsdCBvbmx5IHllYXJcbiAgICAgICAgLy8gKiBpZiB5ZWFyIGlzIGdpdmVuLCBkb24ndCBkZWZhdWx0IGFueXRoaW5nXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAzICYmIGNvbmZpZy5fYVtpXSA9PSBudWxsOyArK2kpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gY3VycmVudERhdGVbaV07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBaZXJvIG91dCB3aGF0ZXZlciB3YXMgbm90IGRlZmF1bHRlZCwgaW5jbHVkaW5nIHRpbWVcbiAgICAgICAgZm9yICg7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gKGNvbmZpZy5fYVtpXSA9PSBudWxsKSA/IChpID09PSAyID8gMSA6IDApIDogY29uZmlnLl9hW2ldO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIDI0OjAwOjAwLjAwMFxuICAgICAgICBpZiAoY29uZmlnLl9hW0hPVVJdID09PSAyNCAmJlxuICAgICAgICAgICAgICAgIGNvbmZpZy5fYVtNSU5VVEVdID09PSAwICYmXG4gICAgICAgICAgICAgICAgY29uZmlnLl9hW1NFQ09ORF0gPT09IDAgJiZcbiAgICAgICAgICAgICAgICBjb25maWcuX2FbTUlMTElTRUNPTkRdID09PSAwKSB7XG4gICAgICAgICAgICBjb25maWcuX25leHREYXkgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9hW0hPVVJdID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZy5fZCA9IChjb25maWcuX3VzZVVUQyA/IGNyZWF0ZVVUQ0RhdGUgOiBjcmVhdGVEYXRlKS5hcHBseShudWxsLCBpbnB1dCk7XG4gICAgICAgIGV4cGVjdGVkV2Vla2RheSA9IGNvbmZpZy5fdXNlVVRDID8gY29uZmlnLl9kLmdldFVUQ0RheSgpIDogY29uZmlnLl9kLmdldERheSgpO1xuXG4gICAgICAgIC8vIEFwcGx5IHRpbWV6b25lIG9mZnNldCBmcm9tIGlucHV0LiBUaGUgYWN0dWFsIHV0Y09mZnNldCBjYW4gYmUgY2hhbmdlZFxuICAgICAgICAvLyB3aXRoIHBhcnNlWm9uZS5cbiAgICAgICAgaWYgKGNvbmZpZy5fdHptICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZC5zZXRVVENNaW51dGVzKGNvbmZpZy5fZC5nZXRVVENNaW51dGVzKCkgLSBjb25maWcuX3R6bSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLl9uZXh0RGF5KSB7XG4gICAgICAgICAgICBjb25maWcuX2FbSE9VUl0gPSAyNDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGZvciBtaXNtYXRjaGluZyBkYXkgb2Ygd2Vla1xuICAgICAgICBpZiAoY29uZmlnLl93ICYmIHR5cGVvZiBjb25maWcuX3cuZCAhPT0gJ3VuZGVmaW5lZCcgJiYgY29uZmlnLl93LmQgIT09IGV4cGVjdGVkV2Vla2RheSkge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykud2Vla2RheU1pc21hdGNoID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrSW5mbyhjb25maWcpIHtcbiAgICAgICAgdmFyIHcsIHdlZWtZZWFyLCB3ZWVrLCB3ZWVrZGF5LCBkb3csIGRveSwgdGVtcCwgd2Vla2RheU92ZXJmbG93O1xuXG4gICAgICAgIHcgPSBjb25maWcuX3c7XG4gICAgICAgIGlmICh3LkdHICE9IG51bGwgfHwgdy5XICE9IG51bGwgfHwgdy5FICE9IG51bGwpIHtcbiAgICAgICAgICAgIGRvdyA9IDE7XG4gICAgICAgICAgICBkb3kgPSA0O1xuXG4gICAgICAgICAgICAvLyBUT0RPOiBXZSBuZWVkIHRvIHRha2UgdGhlIGN1cnJlbnQgaXNvV2Vla1llYXIsIGJ1dCB0aGF0IGRlcGVuZHMgb25cbiAgICAgICAgICAgIC8vIGhvdyB3ZSBpbnRlcnByZXQgbm93IChsb2NhbCwgdXRjLCBmaXhlZCBvZmZzZXQpLiBTbyBjcmVhdGVcbiAgICAgICAgICAgIC8vIGEgbm93IHZlcnNpb24gb2YgY3VycmVudCBjb25maWcgKHRha2UgbG9jYWwvdXRjL29mZnNldCBmbGFncywgYW5kXG4gICAgICAgICAgICAvLyBjcmVhdGUgbm93KS5cbiAgICAgICAgICAgIHdlZWtZZWFyID0gZGVmYXVsdHMody5HRywgY29uZmlnLl9hW1lFQVJdLCB3ZWVrT2ZZZWFyKGNyZWF0ZUxvY2FsKCksIDEsIDQpLnllYXIpO1xuICAgICAgICAgICAgd2VlayA9IGRlZmF1bHRzKHcuVywgMSk7XG4gICAgICAgICAgICB3ZWVrZGF5ID0gZGVmYXVsdHMody5FLCAxKTtcbiAgICAgICAgICAgIGlmICh3ZWVrZGF5IDwgMSB8fCB3ZWVrZGF5ID4gNykge1xuICAgICAgICAgICAgICAgIHdlZWtkYXlPdmVyZmxvdyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkb3cgPSBjb25maWcuX2xvY2FsZS5fd2Vlay5kb3c7XG4gICAgICAgICAgICBkb3kgPSBjb25maWcuX2xvY2FsZS5fd2Vlay5kb3k7XG5cbiAgICAgICAgICAgIHZhciBjdXJXZWVrID0gd2Vla09mWWVhcihjcmVhdGVMb2NhbCgpLCBkb3csIGRveSk7XG5cbiAgICAgICAgICAgIHdlZWtZZWFyID0gZGVmYXVsdHMody5nZywgY29uZmlnLl9hW1lFQVJdLCBjdXJXZWVrLnllYXIpO1xuXG4gICAgICAgICAgICAvLyBEZWZhdWx0IHRvIGN1cnJlbnQgd2Vlay5cbiAgICAgICAgICAgIHdlZWsgPSBkZWZhdWx0cyh3LncsIGN1cldlZWsud2Vlayk7XG5cbiAgICAgICAgICAgIGlmICh3LmQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIHdlZWtkYXkgLS0gbG93IGRheSBudW1iZXJzIGFyZSBjb25zaWRlcmVkIG5leHQgd2Vla1xuICAgICAgICAgICAgICAgIHdlZWtkYXkgPSB3LmQ7XG4gICAgICAgICAgICAgICAgaWYgKHdlZWtkYXkgPCAwIHx8IHdlZWtkYXkgPiA2KSB7XG4gICAgICAgICAgICAgICAgICAgIHdlZWtkYXlPdmVyZmxvdyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh3LmUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIGxvY2FsIHdlZWtkYXkgLS0gY291bnRpbmcgc3RhcnRzIGZyb20gYmVnaW5uaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gdy5lICsgZG93O1xuICAgICAgICAgICAgICAgIGlmICh3LmUgPCAwIHx8IHcuZSA+IDYpIHtcbiAgICAgICAgICAgICAgICAgICAgd2Vla2RheU92ZXJmbG93ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGRlZmF1bHQgdG8gYmVnaW5uaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gZG93O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh3ZWVrIDwgMSB8fCB3ZWVrID4gd2Vla3NJblllYXIod2Vla1llYXIsIGRvdywgZG95KSkge1xuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykuX292ZXJmbG93V2Vla3MgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHdlZWtkYXlPdmVyZmxvdyAhPSBudWxsKSB7XG4gICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5fb3ZlcmZsb3dXZWVrZGF5ID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRlbXAgPSBkYXlPZlllYXJGcm9tV2Vla3Mod2Vla1llYXIsIHdlZWssIHdlZWtkYXksIGRvdywgZG95KTtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtZRUFSXSA9IHRlbXAueWVhcjtcbiAgICAgICAgICAgIGNvbmZpZy5fZGF5T2ZZZWFyID0gdGVtcC5kYXlPZlllYXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpc28gODYwMSByZWdleFxuICAgIC8vIDAwMDAtMDAtMDAgMDAwMC1XMDAgb3IgMDAwMC1XMDAtMCArIFQgKyAwMCBvciAwMDowMCBvciAwMDowMDowMCBvciAwMDowMDowMC4wMDAgKyArMDA6MDAgb3IgKzAwMDAgb3IgKzAwKVxuICAgIHZhciBleHRlbmRlZElzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KS0oPzpcXGRcXGQtXFxkXFxkfFdcXGRcXGQtXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86OlxcZFxcZCg/OjpcXGRcXGQoPzpbLixdXFxkKyk/KT8pPykoW1xcK1xcLV1cXGRcXGQoPzo6P1xcZFxcZCk/fFxccypaKT8pPyQvO1xuICAgIHZhciBiYXNpY0lzb1JlZ2V4ID0gL15cXHMqKCg/OlsrLV1cXGR7Nn18XFxkezR9KSg/OlxcZFxcZFxcZFxcZHxXXFxkXFxkXFxkfFdcXGRcXGR8XFxkXFxkXFxkfFxcZFxcZCkpKD86KFR8ICkoXFxkXFxkKD86XFxkXFxkKD86XFxkXFxkKD86Wy4sXVxcZCspPyk/KT8pKFtcXCtcXC1dXFxkXFxkKD86Oj9cXGRcXGQpP3xcXHMqWik/KT8kLztcblxuICAgIHZhciB0elJlZ2V4ID0gL1p8WystXVxcZFxcZCg/Ojo/XFxkXFxkKT8vO1xuXG4gICAgdmFyIGlzb0RhdGVzID0gW1xuICAgICAgICBbJ1lZWVlZWS1NTS1ERCcsIC9bKy1dXFxkezZ9LVxcZFxcZC1cXGRcXGQvXSxcbiAgICAgICAgWydZWVlZLU1NLUREJywgL1xcZHs0fS1cXGRcXGQtXFxkXFxkL10sXG4gICAgICAgIFsnR0dHRy1bV11XVy1FJywgL1xcZHs0fS1XXFxkXFxkLVxcZC9dLFxuICAgICAgICBbJ0dHR0ctW1ddV1cnLCAvXFxkezR9LVdcXGRcXGQvLCBmYWxzZV0sXG4gICAgICAgIFsnWVlZWS1EREQnLCAvXFxkezR9LVxcZHszfS9dLFxuICAgICAgICBbJ1lZWVktTU0nLCAvXFxkezR9LVxcZFxcZC8sIGZhbHNlXSxcbiAgICAgICAgWydZWVlZWVlNTUREJywgL1srLV1cXGR7MTB9L10sXG4gICAgICAgIFsnWVlZWU1NREQnLCAvXFxkezh9L10sXG4gICAgICAgIC8vIFlZWVlNTSBpcyBOT1QgYWxsb3dlZCBieSB0aGUgc3RhbmRhcmRcbiAgICAgICAgWydHR0dHW1ddV1dFJywgL1xcZHs0fVdcXGR7M30vXSxcbiAgICAgICAgWydHR0dHW1ddV1cnLCAvXFxkezR9V1xcZHsyfS8sIGZhbHNlXSxcbiAgICAgICAgWydZWVlZREREJywgL1xcZHs3fS9dXG4gICAgXTtcblxuICAgIC8vIGlzbyB0aW1lIGZvcm1hdHMgYW5kIHJlZ2V4ZXNcbiAgICB2YXIgaXNvVGltZXMgPSBbXG4gICAgICAgIFsnSEg6bW06c3MuU1NTUycsIC9cXGRcXGQ6XFxkXFxkOlxcZFxcZFxcLlxcZCsvXSxcbiAgICAgICAgWydISDptbTpzcyxTU1NTJywgL1xcZFxcZDpcXGRcXGQ6XFxkXFxkLFxcZCsvXSxcbiAgICAgICAgWydISDptbTpzcycsIC9cXGRcXGQ6XFxkXFxkOlxcZFxcZC9dLFxuICAgICAgICBbJ0hIOm1tJywgL1xcZFxcZDpcXGRcXGQvXSxcbiAgICAgICAgWydISG1tc3MuU1NTUycsIC9cXGRcXGRcXGRcXGRcXGRcXGRcXC5cXGQrL10sXG4gICAgICAgIFsnSEhtbXNzLFNTU1MnLCAvXFxkXFxkXFxkXFxkXFxkXFxkLFxcZCsvXSxcbiAgICAgICAgWydISG1tc3MnLCAvXFxkXFxkXFxkXFxkXFxkXFxkL10sXG4gICAgICAgIFsnSEhtbScsIC9cXGRcXGRcXGRcXGQvXSxcbiAgICAgICAgWydISCcsIC9cXGRcXGQvXVxuICAgIF07XG5cbiAgICB2YXIgYXNwTmV0SnNvblJlZ2V4ID0gL15cXC8/RGF0ZVxcKChcXC0/XFxkKykvaTtcblxuICAgIC8vIGRhdGUgZnJvbSBpc28gZm9ybWF0XG4gICAgZnVuY3Rpb24gY29uZmlnRnJvbUlTTyhjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGwsXG4gICAgICAgICAgICBzdHJpbmcgPSBjb25maWcuX2ksXG4gICAgICAgICAgICBtYXRjaCA9IGV4dGVuZGVkSXNvUmVnZXguZXhlYyhzdHJpbmcpIHx8IGJhc2ljSXNvUmVnZXguZXhlYyhzdHJpbmcpLFxuICAgICAgICAgICAgYWxsb3dUaW1lLCBkYXRlRm9ybWF0LCB0aW1lRm9ybWF0LCB0ekZvcm1hdDtcblxuICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmlzbyA9IHRydWU7XG5cbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBpc29EYXRlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNvRGF0ZXNbaV1bMV0uZXhlYyhtYXRjaFsxXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0ZUZvcm1hdCA9IGlzb0RhdGVzW2ldWzBdO1xuICAgICAgICAgICAgICAgICAgICBhbGxvd1RpbWUgPSBpc29EYXRlc1tpXVsyXSAhPT0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkYXRlRm9ybWF0ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25maWcuX2lzVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWF0Y2hbM10pIHtcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gaXNvVGltZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc29UaW1lc1tpXVsxXS5leGVjKG1hdGNoWzNdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWF0Y2hbMl0gc2hvdWxkIGJlICdUJyBvciBzcGFjZVxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZUZvcm1hdCA9IChtYXRjaFsyXSB8fCAnICcpICsgaXNvVGltZXNbaV1bMF07XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGltZUZvcm1hdCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFhbGxvd1RpbWUgJiYgdGltZUZvcm1hdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1hdGNoWzRdKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR6UmVnZXguZXhlYyhtYXRjaFs0XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHpGb3JtYXQgPSAnWic7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25maWcuX2YgPSBkYXRlRm9ybWF0ICsgKHRpbWVGb3JtYXQgfHwgJycpICsgKHR6Rm9ybWF0IHx8ICcnKTtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUkZDIDI4MjIgcmVnZXg6IEZvciBkZXRhaWxzIHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMjgyMiNzZWN0aW9uLTMuM1xuICAgIHZhciByZmMyODIyID0gL14oPzooTW9ufFR1ZXxXZWR8VGh1fEZyaXxTYXR8U3VuKSw/XFxzKT8oXFxkezEsMn0pXFxzKEphbnxGZWJ8TWFyfEFwcnxNYXl8SnVufEp1bHxBdWd8U2VwfE9jdHxOb3Z8RGVjKVxccyhcXGR7Miw0fSlcXHMoXFxkXFxkKTooXFxkXFxkKSg/OjooXFxkXFxkKSk/XFxzKD86KFVUfEdNVHxbRUNNUF1bU0RdVCl8KFtael0pfChbKy1dXFxkezR9KSkkLztcblxuICAgIGZ1bmN0aW9uIGV4dHJhY3RGcm9tUkZDMjgyMlN0cmluZ3MoeWVhclN0ciwgbW9udGhTdHIsIGRheVN0ciwgaG91clN0ciwgbWludXRlU3RyLCBzZWNvbmRTdHIpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtcbiAgICAgICAgICAgIHVudHJ1bmNhdGVZZWFyKHllYXJTdHIpLFxuICAgICAgICAgICAgZGVmYXVsdExvY2FsZU1vbnRoc1Nob3J0LmluZGV4T2YobW9udGhTdHIpLFxuICAgICAgICAgICAgcGFyc2VJbnQoZGF5U3RyLCAxMCksXG4gICAgICAgICAgICBwYXJzZUludChob3VyU3RyLCAxMCksXG4gICAgICAgICAgICBwYXJzZUludChtaW51dGVTdHIsIDEwKVxuICAgICAgICBdO1xuXG4gICAgICAgIGlmIChzZWNvbmRTdHIpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBhcnNlSW50KHNlY29uZFN0ciwgMTApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdW50cnVuY2F0ZVllYXIoeWVhclN0cikge1xuICAgICAgICB2YXIgeWVhciA9IHBhcnNlSW50KHllYXJTdHIsIDEwKTtcbiAgICAgICAgaWYgKHllYXIgPD0gNDkpIHtcbiAgICAgICAgICAgIHJldHVybiAyMDAwICsgeWVhcjtcbiAgICAgICAgfSBlbHNlIGlmICh5ZWFyIDw9IDk5OSkge1xuICAgICAgICAgICAgcmV0dXJuIDE5MDAgKyB5ZWFyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB5ZWFyO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByZXByb2Nlc3NSRkMyODIyKHMpIHtcbiAgICAgICAgLy8gUmVtb3ZlIGNvbW1lbnRzIGFuZCBmb2xkaW5nIHdoaXRlc3BhY2UgYW5kIHJlcGxhY2UgbXVsdGlwbGUtc3BhY2VzIHdpdGggYSBzaW5nbGUgc3BhY2VcbiAgICAgICAgcmV0dXJuIHMucmVwbGFjZSgvXFwoW14pXSpcXCl8W1xcblxcdF0vZywgJyAnKS5yZXBsYWNlKC8oXFxzXFxzKykvZywgJyAnKS5yZXBsYWNlKC9eXFxzXFxzKi8sICcnKS5yZXBsYWNlKC9cXHNcXHMqJC8sICcnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja1dlZWtkYXkod2Vla2RheVN0ciwgcGFyc2VkSW5wdXQsIGNvbmZpZykge1xuICAgICAgICBpZiAod2Vla2RheVN0cikge1xuICAgICAgICAgICAgLy8gVE9ETzogUmVwbGFjZSB0aGUgdmFuaWxsYSBKUyBEYXRlIG9iamVjdCB3aXRoIGFuIGluZGVwZW50ZW50IGRheS1vZi13ZWVrIGNoZWNrLlxuICAgICAgICAgICAgdmFyIHdlZWtkYXlQcm92aWRlZCA9IGRlZmF1bHRMb2NhbGVXZWVrZGF5c1Nob3J0LmluZGV4T2Yod2Vla2RheVN0ciksXG4gICAgICAgICAgICAgICAgd2Vla2RheUFjdHVhbCA9IG5ldyBEYXRlKHBhcnNlZElucHV0WzBdLCBwYXJzZWRJbnB1dFsxXSwgcGFyc2VkSW5wdXRbMl0pLmdldERheSgpO1xuICAgICAgICAgICAgaWYgKHdlZWtkYXlQcm92aWRlZCAhPT0gd2Vla2RheUFjdHVhbCkge1xuICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLndlZWtkYXlNaXNtYXRjaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciBvYnNPZmZzZXRzID0ge1xuICAgICAgICBVVDogMCxcbiAgICAgICAgR01UOiAwLFxuICAgICAgICBFRFQ6IC00ICogNjAsXG4gICAgICAgIEVTVDogLTUgKiA2MCxcbiAgICAgICAgQ0RUOiAtNSAqIDYwLFxuICAgICAgICBDU1Q6IC02ICogNjAsXG4gICAgICAgIE1EVDogLTYgKiA2MCxcbiAgICAgICAgTVNUOiAtNyAqIDYwLFxuICAgICAgICBQRFQ6IC03ICogNjAsXG4gICAgICAgIFBTVDogLTggKiA2MFxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBjYWxjdWxhdGVPZmZzZXQob2JzT2Zmc2V0LCBtaWxpdGFyeU9mZnNldCwgbnVtT2Zmc2V0KSB7XG4gICAgICAgIGlmIChvYnNPZmZzZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBvYnNPZmZzZXRzW29ic09mZnNldF07XG4gICAgICAgIH0gZWxzZSBpZiAobWlsaXRhcnlPZmZzZXQpIHtcbiAgICAgICAgICAgIC8vIHRoZSBvbmx5IGFsbG93ZWQgbWlsaXRhcnkgdHogaXMgWlxuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaG0gPSBwYXJzZUludChudW1PZmZzZXQsIDEwKTtcbiAgICAgICAgICAgIHZhciBtID0gaG0gJSAxMDAsIGggPSAoaG0gLSBtKSAvIDEwMDtcbiAgICAgICAgICAgIHJldHVybiBoICogNjAgKyBtO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZGF0ZSBhbmQgdGltZSBmcm9tIHJlZiAyODIyIGZvcm1hdFxuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21SRkMyODIyKGNvbmZpZykge1xuICAgICAgICB2YXIgbWF0Y2ggPSByZmMyODIyLmV4ZWMocHJlcHJvY2Vzc1JGQzI4MjIoY29uZmlnLl9pKSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgdmFyIHBhcnNlZEFycmF5ID0gZXh0cmFjdEZyb21SRkMyODIyU3RyaW5ncyhtYXRjaFs0XSwgbWF0Y2hbM10sIG1hdGNoWzJdLCBtYXRjaFs1XSwgbWF0Y2hbNl0sIG1hdGNoWzddKTtcbiAgICAgICAgICAgIGlmICghY2hlY2tXZWVrZGF5KG1hdGNoWzFdLCBwYXJzZWRBcnJheSwgY29uZmlnKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uZmlnLl9hID0gcGFyc2VkQXJyYXk7XG4gICAgICAgICAgICBjb25maWcuX3R6bSA9IGNhbGN1bGF0ZU9mZnNldChtYXRjaFs4XSwgbWF0Y2hbOV0sIG1hdGNoWzEwXSk7XG5cbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IGNyZWF0ZVVUQ0RhdGUuYXBwbHkobnVsbCwgY29uZmlnLl9hKTtcbiAgICAgICAgICAgIGNvbmZpZy5fZC5zZXRVVENNaW51dGVzKGNvbmZpZy5fZC5nZXRVVENNaW51dGVzKCkgLSBjb25maWcuX3R6bSk7XG5cbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnJmYzI4MjIgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gaXNvIGZvcm1hdCBvciBmYWxsYmFja1xuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21TdHJpbmcoY29uZmlnKSB7XG4gICAgICAgIHZhciBtYXRjaGVkID0gYXNwTmV0SnNvblJlZ2V4LmV4ZWMoY29uZmlnLl9pKTtcblxuICAgICAgICBpZiAobWF0Y2hlZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoK21hdGNoZWRbMV0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uZmlnRnJvbUlTTyhjb25maWcpO1xuICAgICAgICBpZiAoY29uZmlnLl9pc1ZhbGlkID09PSBmYWxzZSkge1xuICAgICAgICAgICAgZGVsZXRlIGNvbmZpZy5faXNWYWxpZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZ0Zyb21SRkMyODIyKGNvbmZpZyk7XG4gICAgICAgIGlmIChjb25maWcuX2lzVmFsaWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBkZWxldGUgY29uZmlnLl9pc1ZhbGlkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluYWwgYXR0ZW1wdCwgdXNlIElucHV0IEZhbGxiYWNrXG4gICAgICAgIGhvb2tzLmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgfVxuXG4gICAgaG9va3MuY3JlYXRlRnJvbUlucHV0RmFsbGJhY2sgPSBkZXByZWNhdGUoXG4gICAgICAgICd2YWx1ZSBwcm92aWRlZCBpcyBub3QgaW4gYSByZWNvZ25pemVkIFJGQzI4MjIgb3IgSVNPIGZvcm1hdC4gbW9tZW50IGNvbnN0cnVjdGlvbiBmYWxscyBiYWNrIHRvIGpzIERhdGUoKSwgJyArXG4gICAgICAgICd3aGljaCBpcyBub3QgcmVsaWFibGUgYWNyb3NzIGFsbCBicm93c2VycyBhbmQgdmVyc2lvbnMuIE5vbiBSRkMyODIyL0lTTyBkYXRlIGZvcm1hdHMgYXJlICcgK1xuICAgICAgICAnZGlzY291cmFnZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhbiB1cGNvbWluZyBtYWpvciByZWxlYXNlLiBQbGVhc2UgcmVmZXIgdG8gJyArXG4gICAgICAgICdodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2pzLWRhdGUvIGZvciBtb3JlIGluZm8uJyxcbiAgICAgICAgZnVuY3Rpb24gKGNvbmZpZykge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoY29uZmlnLl9pICsgKGNvbmZpZy5fdXNlVVRDID8gJyBVVEMnIDogJycpKTtcbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBjb25zdGFudCB0aGF0IHJlZmVycyB0byB0aGUgSVNPIHN0YW5kYXJkXG4gICAgaG9va3MuSVNPXzg2MDEgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIGNvbnN0YW50IHRoYXQgcmVmZXJzIHRvIHRoZSBSRkMgMjgyMiBmb3JtXG4gICAgaG9va3MuUkZDXzI4MjIgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIGRhdGUgZnJvbSBzdHJpbmcgYW5kIGZvcm1hdCBzdHJpbmdcbiAgICBmdW5jdGlvbiBjb25maWdGcm9tU3RyaW5nQW5kRm9ybWF0KGNvbmZpZykge1xuICAgICAgICAvLyBUT0RPOiBNb3ZlIHRoaXMgdG8gYW5vdGhlciBwYXJ0IG9mIHRoZSBjcmVhdGlvbiBmbG93IHRvIHByZXZlbnQgY2lyY3VsYXIgZGVwc1xuICAgICAgICBpZiAoY29uZmlnLl9mID09PSBob29rcy5JU09fODYwMSkge1xuICAgICAgICAgICAgY29uZmlnRnJvbUlTTyhjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25maWcuX2YgPT09IGhvb2tzLlJGQ18yODIyKSB7XG4gICAgICAgICAgICBjb25maWdGcm9tUkZDMjgyMihjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbmZpZy5fYSA9IFtdO1xuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5lbXB0eSA9IHRydWU7XG5cbiAgICAgICAgLy8gVGhpcyBhcnJheSBpcyB1c2VkIHRvIG1ha2UgYSBEYXRlLCBlaXRoZXIgd2l0aCBgbmV3IERhdGVgIG9yIGBEYXRlLlVUQ2BcbiAgICAgICAgdmFyIHN0cmluZyA9ICcnICsgY29uZmlnLl9pLFxuICAgICAgICAgICAgaSwgcGFyc2VkSW5wdXQsIHRva2VucywgdG9rZW4sIHNraXBwZWQsXG4gICAgICAgICAgICBzdHJpbmdMZW5ndGggPSBzdHJpbmcubGVuZ3RoLFxuICAgICAgICAgICAgdG90YWxQYXJzZWRJbnB1dExlbmd0aCA9IDA7XG5cbiAgICAgICAgdG9rZW5zID0gZXhwYW5kRm9ybWF0KGNvbmZpZy5fZiwgY29uZmlnLl9sb2NhbGUpLm1hdGNoKGZvcm1hdHRpbmdUb2tlbnMpIHx8IFtdO1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRva2VuID0gdG9rZW5zW2ldO1xuICAgICAgICAgICAgcGFyc2VkSW5wdXQgPSAoc3RyaW5nLm1hdGNoKGdldFBhcnNlUmVnZXhGb3JUb2tlbih0b2tlbiwgY29uZmlnKSkgfHwgW10pWzBdO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ3Rva2VuJywgdG9rZW4sICdwYXJzZWRJbnB1dCcsIHBhcnNlZElucHV0LFxuICAgICAgICAgICAgLy8gICAgICAgICAncmVnZXgnLCBnZXRQYXJzZVJlZ2V4Rm9yVG9rZW4odG9rZW4sIGNvbmZpZykpO1xuICAgICAgICAgICAgaWYgKHBhcnNlZElucHV0KSB7XG4gICAgICAgICAgICAgICAgc2tpcHBlZCA9IHN0cmluZy5zdWJzdHIoMCwgc3RyaW5nLmluZGV4T2YocGFyc2VkSW5wdXQpKTtcbiAgICAgICAgICAgICAgICBpZiAoc2tpcHBlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnVudXNlZElucHV0LnB1c2goc2tpcHBlZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN0cmluZyA9IHN0cmluZy5zbGljZShzdHJpbmcuaW5kZXhPZihwYXJzZWRJbnB1dCkgKyBwYXJzZWRJbnB1dC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIHRvdGFsUGFyc2VkSW5wdXRMZW5ndGggKz0gcGFyc2VkSW5wdXQubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZG9uJ3QgcGFyc2UgaWYgaXQncyBub3QgYSBrbm93biB0b2tlblxuICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuRnVuY3Rpb25zW3Rva2VuXSkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZWRJbnB1dCkge1xuICAgICAgICAgICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5lbXB0eSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKGNvbmZpZykudW51c2VkVG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhZGRUaW1lVG9BcnJheUZyb21Ub2tlbih0b2tlbiwgcGFyc2VkSW5wdXQsIGNvbmZpZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb25maWcuX3N0cmljdCAmJiAhcGFyc2VkSW5wdXQpIHtcbiAgICAgICAgICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS51bnVzZWRUb2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGQgcmVtYWluaW5nIHVucGFyc2VkIGlucHV0IGxlbmd0aCB0byB0aGUgc3RyaW5nXG4gICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmNoYXJzTGVmdE92ZXIgPSBzdHJpbmdMZW5ndGggLSB0b3RhbFBhcnNlZElucHV0TGVuZ3RoO1xuICAgICAgICBpZiAoc3RyaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLnVudXNlZElucHV0LnB1c2goc3RyaW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNsZWFyIF8xMmggZmxhZyBpZiBob3VyIGlzIDw9IDEyXG4gICAgICAgIGlmIChjb25maWcuX2FbSE9VUl0gPD0gMTIgJiZcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmJpZ0hvdXIgPT09IHRydWUgJiZcbiAgICAgICAgICAgIGNvbmZpZy5fYVtIT1VSXSA+IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmJpZ0hvdXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBnZXRQYXJzaW5nRmxhZ3MoY29uZmlnKS5wYXJzZWREYXRlUGFydHMgPSBjb25maWcuX2Euc2xpY2UoMCk7XG4gICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLm1lcmlkaWVtID0gY29uZmlnLl9tZXJpZGllbTtcbiAgICAgICAgLy8gaGFuZGxlIG1lcmlkaWVtXG4gICAgICAgIGNvbmZpZy5fYVtIT1VSXSA9IG1lcmlkaWVtRml4V3JhcChjb25maWcuX2xvY2FsZSwgY29uZmlnLl9hW0hPVVJdLCBjb25maWcuX21lcmlkaWVtKTtcblxuICAgICAgICBjb25maWdGcm9tQXJyYXkoY29uZmlnKTtcbiAgICAgICAgY2hlY2tPdmVyZmxvdyhjb25maWcpO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gbWVyaWRpZW1GaXhXcmFwIChsb2NhbGUsIGhvdXIsIG1lcmlkaWVtKSB7XG4gICAgICAgIHZhciBpc1BtO1xuXG4gICAgICAgIGlmIChtZXJpZGllbSA9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBub3RoaW5nIHRvIGRvXG4gICAgICAgICAgICByZXR1cm4gaG91cjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobG9jYWxlLm1lcmlkaWVtSG91ciAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbG9jYWxlLm1lcmlkaWVtSG91cihob3VyLCBtZXJpZGllbSk7XG4gICAgICAgIH0gZWxzZSBpZiAobG9jYWxlLmlzUE0gIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gRmFsbGJhY2tcbiAgICAgICAgICAgIGlzUG0gPSBsb2NhbGUuaXNQTShtZXJpZGllbSk7XG4gICAgICAgICAgICBpZiAoaXNQbSAmJiBob3VyIDwgMTIpIHtcbiAgICAgICAgICAgICAgICBob3VyICs9IDEyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc1BtICYmIGhvdXIgPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgaG91ciA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaG91cjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgbm90IHN1cHBvc2VkIHRvIGhhcHBlblxuICAgICAgICAgICAgcmV0dXJuIGhvdXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gc3RyaW5nIGFuZCBhcnJheSBvZiBmb3JtYXQgc3RyaW5nc1xuICAgIGZ1bmN0aW9uIGNvbmZpZ0Zyb21TdHJpbmdBbmRBcnJheShjb25maWcpIHtcbiAgICAgICAgdmFyIHRlbXBDb25maWcsXG4gICAgICAgICAgICBiZXN0TW9tZW50LFxuXG4gICAgICAgICAgICBzY29yZVRvQmVhdCxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBjdXJyZW50U2NvcmU7XG5cbiAgICAgICAgaWYgKGNvbmZpZy5fZi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGdldFBhcnNpbmdGbGFncyhjb25maWcpLmludmFsaWRGb3JtYXQgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoTmFOKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb25maWcuX2YubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGN1cnJlbnRTY29yZSA9IDA7XG4gICAgICAgICAgICB0ZW1wQ29uZmlnID0gY29weUNvbmZpZyh7fSwgY29uZmlnKTtcbiAgICAgICAgICAgIGlmIChjb25maWcuX3VzZVVUQyAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGVtcENvbmZpZy5fdXNlVVRDID0gY29uZmlnLl91c2VVVEM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZW1wQ29uZmlnLl9mID0gY29uZmlnLl9mW2ldO1xuICAgICAgICAgICAgY29uZmlnRnJvbVN0cmluZ0FuZEZvcm1hdCh0ZW1wQ29uZmlnKTtcblxuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKHRlbXBDb25maWcpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFueSBpbnB1dCB0aGF0IHdhcyBub3QgcGFyc2VkIGFkZCBhIHBlbmFsdHkgZm9yIHRoYXQgZm9ybWF0XG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgKz0gZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLmNoYXJzTGVmdE92ZXI7XG5cbiAgICAgICAgICAgIC8vb3IgdG9rZW5zXG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgKz0gZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLnVudXNlZFRva2Vucy5sZW5ndGggKiAxMDtcblxuICAgICAgICAgICAgZ2V0UGFyc2luZ0ZsYWdzKHRlbXBDb25maWcpLnNjb3JlID0gY3VycmVudFNjb3JlO1xuXG4gICAgICAgICAgICBpZiAoc2NvcmVUb0JlYXQgPT0gbnVsbCB8fCBjdXJyZW50U2NvcmUgPCBzY29yZVRvQmVhdCkge1xuICAgICAgICAgICAgICAgIHNjb3JlVG9CZWF0ID0gY3VycmVudFNjb3JlO1xuICAgICAgICAgICAgICAgIGJlc3RNb21lbnQgPSB0ZW1wQ29uZmlnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZXh0ZW5kKGNvbmZpZywgYmVzdE1vbWVudCB8fCB0ZW1wQ29uZmlnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb25maWdGcm9tT2JqZWN0KGNvbmZpZykge1xuICAgICAgICBpZiAoY29uZmlnLl9kKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaSA9IG5vcm1hbGl6ZU9iamVjdFVuaXRzKGNvbmZpZy5faSk7XG4gICAgICAgIGNvbmZpZy5fYSA9IG1hcChbaS55ZWFyLCBpLm1vbnRoLCBpLmRheSB8fCBpLmRhdGUsIGkuaG91ciwgaS5taW51dGUsIGkuc2Vjb25kLCBpLm1pbGxpc2Vjb25kXSwgZnVuY3Rpb24gKG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIG9iaiAmJiBwYXJzZUludChvYmosIDEwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uZmlnRnJvbUFycmF5KGNvbmZpZyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlRnJvbUNvbmZpZyAoY29uZmlnKSB7XG4gICAgICAgIHZhciByZXMgPSBuZXcgTW9tZW50KGNoZWNrT3ZlcmZsb3cocHJlcGFyZUNvbmZpZyhjb25maWcpKSk7XG4gICAgICAgIGlmIChyZXMuX25leHREYXkpIHtcbiAgICAgICAgICAgIC8vIEFkZGluZyBpcyBzbWFydCBlbm91Z2ggYXJvdW5kIERTVFxuICAgICAgICAgICAgcmVzLmFkZCgxLCAnZCcpO1xuICAgICAgICAgICAgcmVzLl9uZXh0RGF5ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVwYXJlQ29uZmlnIChjb25maWcpIHtcbiAgICAgICAgdmFyIGlucHV0ID0gY29uZmlnLl9pLFxuICAgICAgICAgICAgZm9ybWF0ID0gY29uZmlnLl9mO1xuXG4gICAgICAgIGNvbmZpZy5fbG9jYWxlID0gY29uZmlnLl9sb2NhbGUgfHwgZ2V0TG9jYWxlKGNvbmZpZy5fbCk7XG5cbiAgICAgICAgaWYgKGlucHV0ID09PSBudWxsIHx8IChmb3JtYXQgPT09IHVuZGVmaW5lZCAmJiBpbnB1dCA9PT0gJycpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlSW52YWxpZCh7bnVsbElucHV0OiB0cnVlfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uZmlnLl9pID0gaW5wdXQgPSBjb25maWcuX2xvY2FsZS5wcmVwYXJzZShpbnB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNNb21lbnQoaW5wdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE1vbWVudChjaGVja092ZXJmbG93KGlucHV0KSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNEYXRlKGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gaW5wdXQ7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNBcnJheShmb3JtYXQpKSB7XG4gICAgICAgICAgICBjb25maWdGcm9tU3RyaW5nQW5kQXJyYXkoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQpIHtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgfSAgZWxzZSB7XG4gICAgICAgICAgICBjb25maWdGcm9tSW5wdXQoY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNWYWxpZChjb25maWcpKSB7XG4gICAgICAgICAgICBjb25maWcuX2QgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb25maWdGcm9tSW5wdXQoY29uZmlnKSB7XG4gICAgICAgIHZhciBpbnB1dCA9IGNvbmZpZy5faTtcbiAgICAgICAgaWYgKGlzVW5kZWZpbmVkKGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoaG9va3Mubm93KCkpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzRGF0ZShpbnB1dCkpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKGlucHV0LnZhbHVlT2YoKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uZmlnRnJvbVN0cmluZyhjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkoaW5wdXQpKSB7XG4gICAgICAgICAgICBjb25maWcuX2EgPSBtYXAoaW5wdXQuc2xpY2UoMCksIGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQob2JqLCAxMCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbmZpZ0Zyb21BcnJheShjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnRnJvbU9iamVjdChjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKGlucHV0KSkge1xuICAgICAgICAgICAgLy8gZnJvbSBtaWxsaXNlY29uZHNcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKGlucHV0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhvb2tzLmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVMb2NhbE9yVVRDIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCwgaXNVVEMpIHtcbiAgICAgICAgdmFyIGMgPSB7fTtcblxuICAgICAgICBpZiAobG9jYWxlID09PSB0cnVlIHx8IGxvY2FsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHN0cmljdCA9IGxvY2FsZTtcbiAgICAgICAgICAgIGxvY2FsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgoaXNPYmplY3QoaW5wdXQpICYmIGlzT2JqZWN0RW1wdHkoaW5wdXQpKSB8fFxuICAgICAgICAgICAgICAgIChpc0FycmF5KGlucHV0KSAmJiBpbnB1dC5sZW5ndGggPT09IDApKSB7XG4gICAgICAgICAgICBpbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBvYmplY3QgY29uc3RydWN0aW9uIG11c3QgYmUgZG9uZSB0aGlzIHdheS5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzE0MjNcbiAgICAgICAgYy5faXNBTW9tZW50T2JqZWN0ID0gdHJ1ZTtcbiAgICAgICAgYy5fdXNlVVRDID0gYy5faXNVVEMgPSBpc1VUQztcbiAgICAgICAgYy5fbCA9IGxvY2FsZTtcbiAgICAgICAgYy5faSA9IGlucHV0O1xuICAgICAgICBjLl9mID0gZm9ybWF0O1xuICAgICAgICBjLl9zdHJpY3QgPSBzdHJpY3Q7XG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZyb21Db25maWcoYyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlTG9jYWwgKGlucHV0LCBmb3JtYXQsIGxvY2FsZSwgc3RyaWN0KSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVMb2NhbE9yVVRDKGlucHV0LCBmb3JtYXQsIGxvY2FsZSwgc3RyaWN0LCBmYWxzZSk7XG4gICAgfVxuXG4gICAgdmFyIHByb3RvdHlwZU1pbiA9IGRlcHJlY2F0ZShcbiAgICAgICAgJ21vbWVudCgpLm1pbiBpcyBkZXByZWNhdGVkLCB1c2UgbW9tZW50Lm1heCBpbnN0ZWFkLiBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL21pbi1tYXgvJyxcbiAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIG90aGVyID0gY3JlYXRlTG9jYWwuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzVmFsaWQoKSAmJiBvdGhlci5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3RoZXIgPCB0aGlzID8gdGhpcyA6IG90aGVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlSW52YWxpZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIHZhciBwcm90b3R5cGVNYXggPSBkZXByZWNhdGUoXG4gICAgICAgICdtb21lbnQoKS5tYXggaXMgZGVwcmVjYXRlZCwgdXNlIG1vbWVudC5taW4gaW5zdGVhZC4gaHR0cDovL21vbWVudGpzLmNvbS9ndWlkZXMvIy93YXJuaW5ncy9taW4tbWF4LycsXG4gICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBvdGhlciA9IGNyZWF0ZUxvY2FsLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICBpZiAodGhpcy5pc1ZhbGlkKCkgJiYgb3RoZXIuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG90aGVyID4gdGhpcyA/IHRoaXMgOiBvdGhlcjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUludmFsaWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBQaWNrIGEgbW9tZW50IG0gZnJvbSBtb21lbnRzIHNvIHRoYXQgbVtmbl0ob3RoZXIpIGlzIHRydWUgZm9yIGFsbFxuICAgIC8vIG90aGVyLiBUaGlzIHJlbGllcyBvbiB0aGUgZnVuY3Rpb24gZm4gdG8gYmUgdHJhbnNpdGl2ZS5cbiAgICAvL1xuICAgIC8vIG1vbWVudHMgc2hvdWxkIGVpdGhlciBiZSBhbiBhcnJheSBvZiBtb21lbnQgb2JqZWN0cyBvciBhbiBhcnJheSwgd2hvc2VcbiAgICAvLyBmaXJzdCBlbGVtZW50IGlzIGFuIGFycmF5IG9mIG1vbWVudCBvYmplY3RzLlxuICAgIGZ1bmN0aW9uIHBpY2tCeShmbiwgbW9tZW50cykge1xuICAgICAgICB2YXIgcmVzLCBpO1xuICAgICAgICBpZiAobW9tZW50cy5sZW5ndGggPT09IDEgJiYgaXNBcnJheShtb21lbnRzWzBdKSkge1xuICAgICAgICAgICAgbW9tZW50cyA9IG1vbWVudHNbMF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtb21lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUxvY2FsKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzID0gbW9tZW50c1swXTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IG1vbWVudHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmICghbW9tZW50c1tpXS5pc1ZhbGlkKCkgfHwgbW9tZW50c1tpXVtmbl0ocmVzKSkge1xuICAgICAgICAgICAgICAgIHJlcyA9IG1vbWVudHNbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBVc2UgW10uc29ydCBpbnN0ZWFkP1xuICAgIGZ1bmN0aW9uIG1pbiAoKSB7XG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuXG4gICAgICAgIHJldHVybiBwaWNrQnkoJ2lzQmVmb3JlJywgYXJncyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF4ICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG5cbiAgICAgICAgcmV0dXJuIHBpY2tCeSgnaXNBZnRlcicsIGFyZ3MpO1xuICAgIH1cblxuICAgIHZhciBub3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBEYXRlLm5vdyA/IERhdGUubm93KCkgOiArKG5ldyBEYXRlKCkpO1xuICAgIH07XG5cbiAgICB2YXIgb3JkZXJpbmcgPSBbJ3llYXInLCAncXVhcnRlcicsICdtb250aCcsICd3ZWVrJywgJ2RheScsICdob3VyJywgJ21pbnV0ZScsICdzZWNvbmQnLCAnbWlsbGlzZWNvbmQnXTtcblxuICAgIGZ1bmN0aW9uIGlzRHVyYXRpb25WYWxpZChtKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBtKSB7XG4gICAgICAgICAgICBpZiAoIShpbmRleE9mLmNhbGwob3JkZXJpbmcsIGtleSkgIT09IC0xICYmIChtW2tleV0gPT0gbnVsbCB8fCAhaXNOYU4obVtrZXldKSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHVuaXRIYXNEZWNpbWFsID0gZmFsc2U7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3JkZXJpbmcubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChtW29yZGVyaW5nW2ldXSkge1xuICAgICAgICAgICAgICAgIGlmICh1bml0SGFzRGVjaW1hbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG9ubHkgYWxsb3cgbm9uLWludGVnZXJzIGZvciBzbWFsbGVzdCB1bml0XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChwYXJzZUZsb2F0KG1bb3JkZXJpbmdbaV1dKSAhPT0gdG9JbnQobVtvcmRlcmluZ1tpXV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHVuaXRIYXNEZWNpbWFsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkJDEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1ZhbGlkO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUludmFsaWQkMSgpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKE5hTik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gRHVyYXRpb24gKGR1cmF0aW9uKSB7XG4gICAgICAgIHZhciBub3JtYWxpemVkSW5wdXQgPSBub3JtYWxpemVPYmplY3RVbml0cyhkdXJhdGlvbiksXG4gICAgICAgICAgICB5ZWFycyA9IG5vcm1hbGl6ZWRJbnB1dC55ZWFyIHx8IDAsXG4gICAgICAgICAgICBxdWFydGVycyA9IG5vcm1hbGl6ZWRJbnB1dC5xdWFydGVyIHx8IDAsXG4gICAgICAgICAgICBtb250aHMgPSBub3JtYWxpemVkSW5wdXQubW9udGggfHwgMCxcbiAgICAgICAgICAgIHdlZWtzID0gbm9ybWFsaXplZElucHV0LndlZWsgfHwgbm9ybWFsaXplZElucHV0Lmlzb1dlZWsgfHwgMCxcbiAgICAgICAgICAgIGRheXMgPSBub3JtYWxpemVkSW5wdXQuZGF5IHx8IDAsXG4gICAgICAgICAgICBob3VycyA9IG5vcm1hbGl6ZWRJbnB1dC5ob3VyIHx8IDAsXG4gICAgICAgICAgICBtaW51dGVzID0gbm9ybWFsaXplZElucHV0Lm1pbnV0ZSB8fCAwLFxuICAgICAgICAgICAgc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5zZWNvbmQgfHwgMCxcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5taWxsaXNlY29uZCB8fCAwO1xuXG4gICAgICAgIHRoaXMuX2lzVmFsaWQgPSBpc0R1cmF0aW9uVmFsaWQobm9ybWFsaXplZElucHV0KTtcblxuICAgICAgICAvLyByZXByZXNlbnRhdGlvbiBmb3IgZGF0ZUFkZFJlbW92ZVxuICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgPSArbWlsbGlzZWNvbmRzICtcbiAgICAgICAgICAgIHNlY29uZHMgKiAxZTMgKyAvLyAxMDAwXG4gICAgICAgICAgICBtaW51dGVzICogNmU0ICsgLy8gMTAwMCAqIDYwXG4gICAgICAgICAgICBob3VycyAqIDEwMDAgKiA2MCAqIDYwOyAvL3VzaW5nIDEwMDAgKiA2MCAqIDYwIGluc3RlYWQgb2YgMzZlNSB0byBhdm9pZCBmbG9hdGluZyBwb2ludCByb3VuZGluZyBlcnJvcnMgaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzI5NzhcbiAgICAgICAgLy8gQmVjYXVzZSBvZiBkYXRlQWRkUmVtb3ZlIHRyZWF0cyAyNCBob3VycyBhcyBkaWZmZXJlbnQgZnJvbSBhXG4gICAgICAgIC8vIGRheSB3aGVuIHdvcmtpbmcgYXJvdW5kIERTVCwgd2UgbmVlZCB0byBzdG9yZSB0aGVtIHNlcGFyYXRlbHlcbiAgICAgICAgdGhpcy5fZGF5cyA9ICtkYXlzICtcbiAgICAgICAgICAgIHdlZWtzICogNztcbiAgICAgICAgLy8gSXQgaXMgaW1wb3NzaWJsZSB0byB0cmFuc2xhdGUgbW9udGhzIGludG8gZGF5cyB3aXRob3V0IGtub3dpbmdcbiAgICAgICAgLy8gd2hpY2ggbW9udGhzIHlvdSBhcmUgYXJlIHRhbGtpbmcgYWJvdXQsIHNvIHdlIGhhdmUgdG8gc3RvcmVcbiAgICAgICAgLy8gaXQgc2VwYXJhdGVseS5cbiAgICAgICAgdGhpcy5fbW9udGhzID0gK21vbnRocyArXG4gICAgICAgICAgICBxdWFydGVycyAqIDMgK1xuICAgICAgICAgICAgeWVhcnMgKiAxMjtcblxuICAgICAgICB0aGlzLl9kYXRhID0ge307XG5cbiAgICAgICAgdGhpcy5fbG9jYWxlID0gZ2V0TG9jYWxlKCk7XG5cbiAgICAgICAgdGhpcy5fYnViYmxlKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEdXJhdGlvbiAob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmogaW5zdGFuY2VvZiBEdXJhdGlvbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhYnNSb3VuZCAobnVtYmVyKSB7XG4gICAgICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCgtMSAqIG51bWJlcikgKiAtMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKG51bWJlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBmdW5jdGlvbiBvZmZzZXQgKHRva2VuLCBzZXBhcmF0b3IpIHtcbiAgICAgICAgYWRkRm9ybWF0VG9rZW4odG9rZW4sIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLnV0Y09mZnNldCgpO1xuICAgICAgICAgICAgdmFyIHNpZ24gPSAnKyc7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IC1vZmZzZXQ7XG4gICAgICAgICAgICAgICAgc2lnbiA9ICctJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzaWduICsgemVyb0ZpbGwofn4ob2Zmc2V0IC8gNjApLCAyKSArIHNlcGFyYXRvciArIHplcm9GaWxsKH5+KG9mZnNldCkgJSA2MCwgMik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9mZnNldCgnWicsICc6Jyk7XG4gICAgb2Zmc2V0KCdaWicsICcnKTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1onLCAgbWF0Y2hTaG9ydE9mZnNldCk7XG4gICAgYWRkUmVnZXhUb2tlbignWlonLCBtYXRjaFNob3J0T2Zmc2V0KTtcbiAgICBhZGRQYXJzZVRva2VuKFsnWicsICdaWiddLCBmdW5jdGlvbiAoaW5wdXQsIGFycmF5LCBjb25maWcpIHtcbiAgICAgICAgY29uZmlnLl91c2VVVEMgPSB0cnVlO1xuICAgICAgICBjb25maWcuX3R6bSA9IG9mZnNldEZyb21TdHJpbmcobWF0Y2hTaG9ydE9mZnNldCwgaW5wdXQpO1xuICAgIH0pO1xuXG4gICAgLy8gSEVMUEVSU1xuXG4gICAgLy8gdGltZXpvbmUgY2h1bmtlclxuICAgIC8vICcrMTA6MDAnID4gWycxMCcsICAnMDAnXVxuICAgIC8vICctMTUzMCcgID4gWyctMTUnLCAnMzAnXVxuICAgIHZhciBjaHVua09mZnNldCA9IC8oW1xcK1xcLV18XFxkXFxkKS9naTtcblxuICAgIGZ1bmN0aW9uIG9mZnNldEZyb21TdHJpbmcobWF0Y2hlciwgc3RyaW5nKSB7XG4gICAgICAgIHZhciBtYXRjaGVzID0gKHN0cmluZyB8fCAnJykubWF0Y2gobWF0Y2hlcik7XG5cbiAgICAgICAgaWYgKG1hdGNoZXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNodW5rICAgPSBtYXRjaGVzW21hdGNoZXMubGVuZ3RoIC0gMV0gfHwgW107XG4gICAgICAgIHZhciBwYXJ0cyAgID0gKGNodW5rICsgJycpLm1hdGNoKGNodW5rT2Zmc2V0KSB8fCBbJy0nLCAwLCAwXTtcbiAgICAgICAgdmFyIG1pbnV0ZXMgPSArKHBhcnRzWzFdICogNjApICsgdG9JbnQocGFydHNbMl0pO1xuXG4gICAgICAgIHJldHVybiBtaW51dGVzID09PSAwID9cbiAgICAgICAgICAwIDpcbiAgICAgICAgICBwYXJ0c1swXSA9PT0gJysnID8gbWludXRlcyA6IC1taW51dGVzO1xuICAgIH1cblxuICAgIC8vIFJldHVybiBhIG1vbWVudCBmcm9tIGlucHV0LCB0aGF0IGlzIGxvY2FsL3V0Yy96b25lIGVxdWl2YWxlbnQgdG8gbW9kZWwuXG4gICAgZnVuY3Rpb24gY2xvbmVXaXRoT2Zmc2V0KGlucHV0LCBtb2RlbCkge1xuICAgICAgICB2YXIgcmVzLCBkaWZmO1xuICAgICAgICBpZiAobW9kZWwuX2lzVVRDKSB7XG4gICAgICAgICAgICByZXMgPSBtb2RlbC5jbG9uZSgpO1xuICAgICAgICAgICAgZGlmZiA9IChpc01vbWVudChpbnB1dCkgfHwgaXNEYXRlKGlucHV0KSA/IGlucHV0LnZhbHVlT2YoKSA6IGNyZWF0ZUxvY2FsKGlucHV0KS52YWx1ZU9mKCkpIC0gcmVzLnZhbHVlT2YoKTtcbiAgICAgICAgICAgIC8vIFVzZSBsb3ctbGV2ZWwgYXBpLCBiZWNhdXNlIHRoaXMgZm4gaXMgbG93LWxldmVsIGFwaS5cbiAgICAgICAgICAgIHJlcy5fZC5zZXRUaW1lKHJlcy5fZC52YWx1ZU9mKCkgKyBkaWZmKTtcbiAgICAgICAgICAgIGhvb2tzLnVwZGF0ZU9mZnNldChyZXMsIGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwoaW5wdXQpLmxvY2FsKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXREYXRlT2Zmc2V0IChtKSB7XG4gICAgICAgIC8vIE9uIEZpcmVmb3guMjQgRGF0ZSNnZXRUaW1lem9uZU9mZnNldCByZXR1cm5zIGEgZmxvYXRpbmcgcG9pbnQuXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tb21lbnQvbW9tZW50L3B1bGwvMTg3MVxuICAgICAgICByZXR1cm4gLU1hdGgucm91bmQobS5fZC5nZXRUaW1lem9uZU9mZnNldCgpIC8gMTUpICogMTU7XG4gICAgfVxuXG4gICAgLy8gSE9PS1NcblxuICAgIC8vIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgd2hlbmV2ZXIgYSBtb21lbnQgaXMgbXV0YXRlZC5cbiAgICAvLyBJdCBpcyBpbnRlbmRlZCB0byBrZWVwIHRoZSBvZmZzZXQgaW4gc3luYyB3aXRoIHRoZSB0aW1lem9uZS5cbiAgICBob29rcy51cGRhdGVPZmZzZXQgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIC8vIGtlZXBMb2NhbFRpbWUgPSB0cnVlIG1lYW5zIG9ubHkgY2hhbmdlIHRoZSB0aW1lem9uZSwgd2l0aG91dFxuICAgIC8vIGFmZmVjdGluZyB0aGUgbG9jYWwgaG91ci4gU28gNTozMToyNiArMDMwMCAtLVt1dGNPZmZzZXQoMiwgdHJ1ZSldLS0+XG4gICAgLy8gNTozMToyNiArMDIwMCBJdCBpcyBwb3NzaWJsZSB0aGF0IDU6MzE6MjYgZG9lc24ndCBleGlzdCB3aXRoIG9mZnNldFxuICAgIC8vICswMjAwLCBzbyB3ZSBhZGp1c3QgdGhlIHRpbWUgYXMgbmVlZGVkLCB0byBiZSB2YWxpZC5cbiAgICAvL1xuICAgIC8vIEtlZXBpbmcgdGhlIHRpbWUgYWN0dWFsbHkgYWRkcy9zdWJ0cmFjdHMgKG9uZSBob3VyKVxuICAgIC8vIGZyb20gdGhlIGFjdHVhbCByZXByZXNlbnRlZCB0aW1lLiBUaGF0IGlzIHdoeSB3ZSBjYWxsIHVwZGF0ZU9mZnNldFxuICAgIC8vIGEgc2Vjb25kIHRpbWUuIEluIGNhc2UgaXQgd2FudHMgdXMgdG8gY2hhbmdlIHRoZSBvZmZzZXQgYWdhaW5cbiAgICAvLyBfY2hhbmdlSW5Qcm9ncmVzcyA9PSB0cnVlIGNhc2UsIHRoZW4gd2UgaGF2ZSB0byBhZGp1c3QsIGJlY2F1c2VcbiAgICAvLyB0aGVyZSBpcyBubyBzdWNoIHRpbWUgaW4gdGhlIGdpdmVuIHRpbWV6b25lLlxuICAgIGZ1bmN0aW9uIGdldFNldE9mZnNldCAoaW5wdXQsIGtlZXBMb2NhbFRpbWUsIGtlZXBNaW51dGVzKSB7XG4gICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLl9vZmZzZXQgfHwgMCxcbiAgICAgICAgICAgIGxvY2FsQWRqdXN0O1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgIT0gbnVsbCA/IHRoaXMgOiBOYU47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSBvZmZzZXRGcm9tU3RyaW5nKG1hdGNoU2hvcnRPZmZzZXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChNYXRoLmFicyhpbnB1dCkgPCAxNiAmJiAha2VlcE1pbnV0ZXMpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IGlucHV0ICogNjA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuX2lzVVRDICYmIGtlZXBMb2NhbFRpbWUpIHtcbiAgICAgICAgICAgICAgICBsb2NhbEFkanVzdCA9IGdldERhdGVPZmZzZXQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9vZmZzZXQgPSBpbnB1dDtcbiAgICAgICAgICAgIHRoaXMuX2lzVVRDID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChsb2NhbEFkanVzdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGQobG9jYWxBZGp1c3QsICdtJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2Zmc2V0ICE9PSBpbnB1dCkge1xuICAgICAgICAgICAgICAgIGlmICgha2VlcExvY2FsVGltZSB8fCB0aGlzLl9jaGFuZ2VJblByb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZFN1YnRyYWN0KHRoaXMsIGNyZWF0ZUR1cmF0aW9uKGlucHV0IC0gb2Zmc2V0LCAnbScpLCAxLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5fY2hhbmdlSW5Qcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/IG9mZnNldCA6IGdldERhdGVPZmZzZXQodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRab25lIChpbnB1dCwga2VlcExvY2FsVGltZSkge1xuICAgICAgICBpZiAoaW5wdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IC1pbnB1dDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoaW5wdXQsIGtlZXBMb2NhbFRpbWUpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAtdGhpcy51dGNPZmZzZXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldE9mZnNldFRvVVRDIChrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnV0Y09mZnNldCgwLCBrZWVwTG9jYWxUaW1lKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRPZmZzZXRUb0xvY2FsIChrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9pc1VUQykge1xuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoMCwga2VlcExvY2FsVGltZSk7XG4gICAgICAgICAgICB0aGlzLl9pc1VUQyA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoa2VlcExvY2FsVGltZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3VidHJhY3QoZ2V0RGF0ZU9mZnNldCh0aGlzKSwgJ20nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRPZmZzZXRUb1BhcnNlZE9mZnNldCAoKSB7XG4gICAgICAgIGlmICh0aGlzLl90em0gIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQodGhpcy5fdHptLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuX2kgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB2YXIgdFpvbmUgPSBvZmZzZXRGcm9tU3RyaW5nKG1hdGNoT2Zmc2V0LCB0aGlzLl9pKTtcbiAgICAgICAgICAgIGlmICh0Wm9uZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQodFpvbmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy51dGNPZmZzZXQoMCwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzQWxpZ25lZEhvdXJPZmZzZXQgKGlucHV0KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dCA9IGlucHV0ID8gY3JlYXRlTG9jYWwoaW5wdXQpLnV0Y09mZnNldCgpIDogMDtcblxuICAgICAgICByZXR1cm4gKHRoaXMudXRjT2Zmc2V0KCkgLSBpbnB1dCkgJSA2MCA9PT0gMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0RheWxpZ2h0U2F2aW5nVGltZSAoKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLnV0Y09mZnNldCgpID4gdGhpcy5jbG9uZSgpLm1vbnRoKDApLnV0Y09mZnNldCgpIHx8XG4gICAgICAgICAgICB0aGlzLnV0Y09mZnNldCgpID4gdGhpcy5jbG9uZSgpLm1vbnRoKDUpLnV0Y09mZnNldCgpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEYXlsaWdodFNhdmluZ1RpbWVTaGlmdGVkICgpIHtcbiAgICAgICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9pc0RTVFNoaWZ0ZWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faXNEU1RTaGlmdGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGMgPSB7fTtcblxuICAgICAgICBjb3B5Q29uZmlnKGMsIHRoaXMpO1xuICAgICAgICBjID0gcHJlcGFyZUNvbmZpZyhjKTtcblxuICAgICAgICBpZiAoYy5fYSkge1xuICAgICAgICAgICAgdmFyIG90aGVyID0gYy5faXNVVEMgPyBjcmVhdGVVVEMoYy5fYSkgOiBjcmVhdGVMb2NhbChjLl9hKTtcbiAgICAgICAgICAgIHRoaXMuX2lzRFNUU2hpZnRlZCA9IHRoaXMuaXNWYWxpZCgpICYmXG4gICAgICAgICAgICAgICAgY29tcGFyZUFycmF5cyhjLl9hLCBvdGhlci50b0FycmF5KCkpID4gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2lzRFNUU2hpZnRlZCA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzRFNUU2hpZnRlZDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0xvY2FsICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gIXRoaXMuX2lzVVRDIDogZmFsc2U7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNVdGNPZmZzZXQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1ZhbGlkKCkgPyB0aGlzLl9pc1VUQyA6IGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVXRjICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpcy5faXNVVEMgJiYgdGhpcy5fb2Zmc2V0ID09PSAwIDogZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQVNQLk5FVCBqc29uIGRhdGUgZm9ybWF0IHJlZ2V4XG4gICAgdmFyIGFzcE5ldFJlZ2V4ID0gL14oXFwtfFxcKyk/KD86KFxcZCopWy4gXSk/KFxcZCspXFw6KFxcZCspKD86XFw6KFxcZCspKFxcLlxcZCopPyk/JC87XG5cbiAgICAvLyBmcm9tIGh0dHA6Ly9kb2NzLmNsb3N1cmUtbGlicmFyeS5nb29nbGVjb2RlLmNvbS9naXQvY2xvc3VyZV9nb29nX2RhdGVfZGF0ZS5qcy5zb3VyY2UuaHRtbFxuICAgIC8vIHNvbWV3aGF0IG1vcmUgaW4gbGluZSB3aXRoIDQuNC4zLjIgMjAwNCBzcGVjLCBidXQgYWxsb3dzIGRlY2ltYWwgYW55d2hlcmVcbiAgICAvLyBhbmQgZnVydGhlciBtb2RpZmllZCB0byBhbGxvdyBmb3Igc3RyaW5ncyBjb250YWluaW5nIGJvdGggd2VlayBhbmQgZGF5XG4gICAgdmFyIGlzb1JlZ2V4ID0gL14oLXxcXCspP1AoPzooWy0rXT9bMC05LC5dKilZKT8oPzooWy0rXT9bMC05LC5dKilNKT8oPzooWy0rXT9bMC05LC5dKilXKT8oPzooWy0rXT9bMC05LC5dKilEKT8oPzpUKD86KFstK10/WzAtOSwuXSopSCk/KD86KFstK10/WzAtOSwuXSopTSk/KD86KFstK10/WzAtOSwuXSopUyk/KT8kLztcblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUR1cmF0aW9uIChpbnB1dCwga2V5KSB7XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IGlucHV0LFxuICAgICAgICAgICAgLy8gbWF0Y2hpbmcgYWdhaW5zdCByZWdleHAgaXMgZXhwZW5zaXZlLCBkbyBpdCBvbiBkZW1hbmRcbiAgICAgICAgICAgIG1hdGNoID0gbnVsbCxcbiAgICAgICAgICAgIHNpZ24sXG4gICAgICAgICAgICByZXQsXG4gICAgICAgICAgICBkaWZmUmVzO1xuXG4gICAgICAgIGlmIChpc0R1cmF0aW9uKGlucHV0KSkge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgbXMgOiBpbnB1dC5fbWlsbGlzZWNvbmRzLFxuICAgICAgICAgICAgICAgIGQgIDogaW5wdXQuX2RheXMsXG4gICAgICAgICAgICAgICAgTSAgOiBpbnB1dC5fbW9udGhzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKGlzTnVtYmVyKGlucHV0KSkge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbltrZXldID0gaW5wdXQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uLm1pbGxpc2Vjb25kcyA9IGlucHV0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEhKG1hdGNoID0gYXNwTmV0UmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeSAgOiAwLFxuICAgICAgICAgICAgICAgIGQgIDogdG9JbnQobWF0Y2hbREFURV0pICAgICAgICAgICAgICAgICAgICAgICAgICogc2lnbixcbiAgICAgICAgICAgICAgICBoICA6IHRvSW50KG1hdGNoW0hPVVJdKSAgICAgICAgICAgICAgICAgICAgICAgICAqIHNpZ24sXG4gICAgICAgICAgICAgICAgbSAgOiB0b0ludChtYXRjaFtNSU5VVEVdKSAgICAgICAgICAgICAgICAgICAgICAgKiBzaWduLFxuICAgICAgICAgICAgICAgIHMgIDogdG9JbnQobWF0Y2hbU0VDT05EXSkgICAgICAgICAgICAgICAgICAgICAgICogc2lnbixcbiAgICAgICAgICAgICAgICBtcyA6IHRvSW50KGFic1JvdW5kKG1hdGNoW01JTExJU0VDT05EXSAqIDEwMDApKSAqIHNpZ24gLy8gdGhlIG1pbGxpc2Vjb25kIGRlY2ltYWwgcG9pbnQgaXMgaW5jbHVkZWQgaW4gdGhlIG1hdGNoXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKCEhKG1hdGNoID0gaXNvUmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeSA6IHBhcnNlSXNvKG1hdGNoWzJdLCBzaWduKSxcbiAgICAgICAgICAgICAgICBNIDogcGFyc2VJc28obWF0Y2hbM10sIHNpZ24pLFxuICAgICAgICAgICAgICAgIHcgOiBwYXJzZUlzbyhtYXRjaFs0XSwgc2lnbiksXG4gICAgICAgICAgICAgICAgZCA6IHBhcnNlSXNvKG1hdGNoWzVdLCBzaWduKSxcbiAgICAgICAgICAgICAgICBoIDogcGFyc2VJc28obWF0Y2hbNl0sIHNpZ24pLFxuICAgICAgICAgICAgICAgIG0gOiBwYXJzZUlzbyhtYXRjaFs3XSwgc2lnbiksXG4gICAgICAgICAgICAgICAgcyA6IHBhcnNlSXNvKG1hdGNoWzhdLCBzaWduKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmIChkdXJhdGlvbiA9PSBudWxsKSB7Ly8gY2hlY2tzIGZvciBudWxsIG9yIHVuZGVmaW5lZFxuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZHVyYXRpb24gPT09ICdvYmplY3QnICYmICgnZnJvbScgaW4gZHVyYXRpb24gfHwgJ3RvJyBpbiBkdXJhdGlvbikpIHtcbiAgICAgICAgICAgIGRpZmZSZXMgPSBtb21lbnRzRGlmZmVyZW5jZShjcmVhdGVMb2NhbChkdXJhdGlvbi5mcm9tKSwgY3JlYXRlTG9jYWwoZHVyYXRpb24udG8pKTtcblxuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGR1cmF0aW9uLm1zID0gZGlmZlJlcy5taWxsaXNlY29uZHM7XG4gICAgICAgICAgICBkdXJhdGlvbi5NID0gZGlmZlJlcy5tb250aHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXQgPSBuZXcgRHVyYXRpb24oZHVyYXRpb24pO1xuXG4gICAgICAgIGlmIChpc0R1cmF0aW9uKGlucHV0KSAmJiBoYXNPd25Qcm9wKGlucHV0LCAnX2xvY2FsZScpKSB7XG4gICAgICAgICAgICByZXQuX2xvY2FsZSA9IGlucHV0Ll9sb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIGNyZWF0ZUR1cmF0aW9uLmZuID0gRHVyYXRpb24ucHJvdG90eXBlO1xuICAgIGNyZWF0ZUR1cmF0aW9uLmludmFsaWQgPSBjcmVhdGVJbnZhbGlkJDE7XG5cbiAgICBmdW5jdGlvbiBwYXJzZUlzbyAoaW5wLCBzaWduKSB7XG4gICAgICAgIC8vIFdlJ2Qgbm9ybWFsbHkgdXNlIH5+aW5wIGZvciB0aGlzLCBidXQgdW5mb3J0dW5hdGVseSBpdCBhbHNvXG4gICAgICAgIC8vIGNvbnZlcnRzIGZsb2F0cyB0byBpbnRzLlxuICAgICAgICAvLyBpbnAgbWF5IGJlIHVuZGVmaW5lZCwgc28gY2FyZWZ1bCBjYWxsaW5nIHJlcGxhY2Ugb24gaXQuXG4gICAgICAgIHZhciByZXMgPSBpbnAgJiYgcGFyc2VGbG9hdChpbnAucmVwbGFjZSgnLCcsICcuJykpO1xuICAgICAgICAvLyBhcHBseSBzaWduIHdoaWxlIHdlJ3JlIGF0IGl0XG4gICAgICAgIHJldHVybiAoaXNOYU4ocmVzKSA/IDAgOiByZXMpICogc2lnbjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKSB7XG4gICAgICAgIHZhciByZXMgPSB7fTtcblxuICAgICAgICByZXMubW9udGhzID0gb3RoZXIubW9udGgoKSAtIGJhc2UubW9udGgoKSArXG4gICAgICAgICAgICAob3RoZXIueWVhcigpIC0gYmFzZS55ZWFyKCkpICogMTI7XG4gICAgICAgIGlmIChiYXNlLmNsb25lKCkuYWRkKHJlcy5tb250aHMsICdNJykuaXNBZnRlcihvdGhlcikpIHtcbiAgICAgICAgICAgIC0tcmVzLm1vbnRocztcbiAgICAgICAgfVxuXG4gICAgICAgIHJlcy5taWxsaXNlY29uZHMgPSArb3RoZXIgLSArKGJhc2UuY2xvbmUoKS5hZGQocmVzLm1vbnRocywgJ00nKSk7XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb21lbnRzRGlmZmVyZW5jZShiYXNlLCBvdGhlcikge1xuICAgICAgICB2YXIgcmVzO1xuICAgICAgICBpZiAoIShiYXNlLmlzVmFsaWQoKSAmJiBvdGhlci5pc1ZhbGlkKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4ge21pbGxpc2Vjb25kczogMCwgbW9udGhzOiAwfTtcbiAgICAgICAgfVxuXG4gICAgICAgIG90aGVyID0gY2xvbmVXaXRoT2Zmc2V0KG90aGVyLCBiYXNlKTtcbiAgICAgICAgaWYgKGJhc2UuaXNCZWZvcmUob3RoZXIpKSB7XG4gICAgICAgICAgICByZXMgPSBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcyA9IHBvc2l0aXZlTW9tZW50c0RpZmZlcmVuY2Uob3RoZXIsIGJhc2UpO1xuICAgICAgICAgICAgcmVzLm1pbGxpc2Vjb25kcyA9IC1yZXMubWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgcmVzLm1vbnRocyA9IC1yZXMubW9udGhzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvLyBUT0RPOiByZW1vdmUgJ25hbWUnIGFyZyBhZnRlciBkZXByZWNhdGlvbiBpcyByZW1vdmVkXG4gICAgZnVuY3Rpb24gY3JlYXRlQWRkZXIoZGlyZWN0aW9uLCBuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsLCBwZXJpb2QpIHtcbiAgICAgICAgICAgIHZhciBkdXIsIHRtcDtcbiAgICAgICAgICAgIC8vaW52ZXJ0IHRoZSBhcmd1bWVudHMsIGJ1dCBjb21wbGFpbiBhYm91dCBpdFxuICAgICAgICAgICAgaWYgKHBlcmlvZCAhPT0gbnVsbCAmJiAhaXNOYU4oK3BlcmlvZCkpIHtcbiAgICAgICAgICAgICAgICBkZXByZWNhdGVTaW1wbGUobmFtZSwgJ21vbWVudCgpLicgKyBuYW1lICArICcocGVyaW9kLCBudW1iZXIpIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgbW9tZW50KCkuJyArIG5hbWUgKyAnKG51bWJlciwgcGVyaW9kKS4gJyArXG4gICAgICAgICAgICAgICAgJ1NlZSBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2FkZC1pbnZlcnRlZC1wYXJhbS8gZm9yIG1vcmUgaW5mby4nKTtcbiAgICAgICAgICAgICAgICB0bXAgPSB2YWw7IHZhbCA9IHBlcmlvZDsgcGVyaW9kID0gdG1wO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YWwgPSB0eXBlb2YgdmFsID09PSAnc3RyaW5nJyA/ICt2YWwgOiB2YWw7XG4gICAgICAgICAgICBkdXIgPSBjcmVhdGVEdXJhdGlvbih2YWwsIHBlcmlvZCk7XG4gICAgICAgICAgICBhZGRTdWJ0cmFjdCh0aGlzLCBkdXIsIGRpcmVjdGlvbik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRTdWJ0cmFjdCAobW9tLCBkdXJhdGlvbiwgaXNBZGRpbmcsIHVwZGF0ZU9mZnNldCkge1xuICAgICAgICB2YXIgbWlsbGlzZWNvbmRzID0gZHVyYXRpb24uX21pbGxpc2Vjb25kcyxcbiAgICAgICAgICAgIGRheXMgPSBhYnNSb3VuZChkdXJhdGlvbi5fZGF5cyksXG4gICAgICAgICAgICBtb250aHMgPSBhYnNSb3VuZChkdXJhdGlvbi5fbW9udGhzKTtcblxuICAgICAgICBpZiAoIW1vbS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIC8vIE5vIG9wXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB1cGRhdGVPZmZzZXQgPSB1cGRhdGVPZmZzZXQgPT0gbnVsbCA/IHRydWUgOiB1cGRhdGVPZmZzZXQ7XG5cbiAgICAgICAgaWYgKG1vbnRocykge1xuICAgICAgICAgICAgc2V0TW9udGgobW9tLCBnZXQobW9tLCAnTW9udGgnKSArIG1vbnRocyAqIGlzQWRkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF5cykge1xuICAgICAgICAgICAgc2V0JDEobW9tLCAnRGF0ZScsIGdldChtb20sICdEYXRlJykgKyBkYXlzICogaXNBZGRpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtaWxsaXNlY29uZHMpIHtcbiAgICAgICAgICAgIG1vbS5fZC5zZXRUaW1lKG1vbS5fZC52YWx1ZU9mKCkgKyBtaWxsaXNlY29uZHMgKiBpc0FkZGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVwZGF0ZU9mZnNldCkge1xuICAgICAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KG1vbSwgZGF5cyB8fCBtb250aHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGFkZCAgICAgID0gY3JlYXRlQWRkZXIoMSwgJ2FkZCcpO1xuICAgIHZhciBzdWJ0cmFjdCA9IGNyZWF0ZUFkZGVyKC0xLCAnc3VidHJhY3QnKTtcblxuICAgIGZ1bmN0aW9uIGdldENhbGVuZGFyRm9ybWF0KG15TW9tZW50LCBub3cpIHtcbiAgICAgICAgdmFyIGRpZmYgPSBteU1vbWVudC5kaWZmKG5vdywgJ2RheXMnLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuIGRpZmYgPCAtNiA/ICdzYW1lRWxzZScgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCAtMSA/ICdsYXN0V2VlaycgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCAwID8gJ2xhc3REYXknIDpcbiAgICAgICAgICAgICAgICBkaWZmIDwgMSA/ICdzYW1lRGF5JyA6XG4gICAgICAgICAgICAgICAgZGlmZiA8IDIgPyAnbmV4dERheScgOlxuICAgICAgICAgICAgICAgIGRpZmYgPCA3ID8gJ25leHRXZWVrJyA6ICdzYW1lRWxzZSc7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsZW5kYXIkMSAodGltZSwgZm9ybWF0cykge1xuICAgICAgICAvLyBXZSB3YW50IHRvIGNvbXBhcmUgdGhlIHN0YXJ0IG9mIHRvZGF5LCB2cyB0aGlzLlxuICAgICAgICAvLyBHZXR0aW5nIHN0YXJ0LW9mLXRvZGF5IGRlcGVuZHMgb24gd2hldGhlciB3ZSdyZSBsb2NhbC91dGMvb2Zmc2V0IG9yIG5vdC5cbiAgICAgICAgdmFyIG5vdyA9IHRpbWUgfHwgY3JlYXRlTG9jYWwoKSxcbiAgICAgICAgICAgIHNvZCA9IGNsb25lV2l0aE9mZnNldChub3csIHRoaXMpLnN0YXJ0T2YoJ2RheScpLFxuICAgICAgICAgICAgZm9ybWF0ID0gaG9va3MuY2FsZW5kYXJGb3JtYXQodGhpcywgc29kKSB8fCAnc2FtZUVsc2UnO1xuXG4gICAgICAgIHZhciBvdXRwdXQgPSBmb3JtYXRzICYmIChpc0Z1bmN0aW9uKGZvcm1hdHNbZm9ybWF0XSkgPyBmb3JtYXRzW2Zvcm1hdF0uY2FsbCh0aGlzLCBub3cpIDogZm9ybWF0c1tmb3JtYXRdKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXQob3V0cHV0IHx8IHRoaXMubG9jYWxlRGF0YSgpLmNhbGVuZGFyKGZvcm1hdCwgdGhpcywgY3JlYXRlTG9jYWwobm93KSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsb25lICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBNb21lbnQodGhpcyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNBZnRlciAoaW5wdXQsIHVuaXRzKSB7XG4gICAgICAgIHZhciBsb2NhbElucHV0ID0gaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBjcmVhdGVMb2NhbChpbnB1dCk7XG4gICAgICAgIGlmICghKHRoaXMuaXNWYWxpZCgpICYmIGxvY2FsSW5wdXQuaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpIHx8ICdtaWxsaXNlY29uZCc7XG4gICAgICAgIGlmICh1bml0cyA9PT0gJ21pbGxpc2Vjb25kJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpID4gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbG9jYWxJbnB1dC52YWx1ZU9mKCkgPCB0aGlzLmNsb25lKCkuc3RhcnRPZih1bml0cykudmFsdWVPZigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNCZWZvcmUgKGlucHV0LCB1bml0cykge1xuICAgICAgICB2YXIgbG9jYWxJbnB1dCA9IGlzTW9tZW50KGlucHV0KSA/IGlucHV0IDogY3JlYXRlTG9jYWwoaW5wdXQpO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbElucHV0LmlzVmFsaWQoKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB8fCAnbWlsbGlzZWNvbmQnO1xuICAgICAgICBpZiAodW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKSA8IGxvY2FsSW5wdXQudmFsdWVPZigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmRPZih1bml0cykudmFsdWVPZigpIDwgbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0JldHdlZW4gKGZyb20sIHRvLCB1bml0cywgaW5jbHVzaXZpdHkpIHtcbiAgICAgICAgdmFyIGxvY2FsRnJvbSA9IGlzTW9tZW50KGZyb20pID8gZnJvbSA6IGNyZWF0ZUxvY2FsKGZyb20pLFxuICAgICAgICAgICAgbG9jYWxUbyA9IGlzTW9tZW50KHRvKSA/IHRvIDogY3JlYXRlTG9jYWwodG8pO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbEZyb20uaXNWYWxpZCgpICYmIGxvY2FsVG8uaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGluY2x1c2l2aXR5ID0gaW5jbHVzaXZpdHkgfHwgJygpJztcbiAgICAgICAgcmV0dXJuIChpbmNsdXNpdml0eVswXSA9PT0gJygnID8gdGhpcy5pc0FmdGVyKGxvY2FsRnJvbSwgdW5pdHMpIDogIXRoaXMuaXNCZWZvcmUobG9jYWxGcm9tLCB1bml0cykpICYmXG4gICAgICAgICAgICAoaW5jbHVzaXZpdHlbMV0gPT09ICcpJyA/IHRoaXMuaXNCZWZvcmUobG9jYWxUbywgdW5pdHMpIDogIXRoaXMuaXNBZnRlcihsb2NhbFRvLCB1bml0cykpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzU2FtZSAoaW5wdXQsIHVuaXRzKSB7XG4gICAgICAgIHZhciBsb2NhbElucHV0ID0gaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBjcmVhdGVMb2NhbChpbnB1dCksXG4gICAgICAgICAgICBpbnB1dE1zO1xuICAgICAgICBpZiAoISh0aGlzLmlzVmFsaWQoKSAmJiBsb2NhbElucHV0LmlzVmFsaWQoKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB8fCAnbWlsbGlzZWNvbmQnO1xuICAgICAgICBpZiAodW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKSA9PT0gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbnB1dE1zID0gbG9jYWxJbnB1dC52YWx1ZU9mKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jbG9uZSgpLnN0YXJ0T2YodW5pdHMpLnZhbHVlT2YoKSA8PSBpbnB1dE1zICYmIGlucHV0TXMgPD0gdGhpcy5jbG9uZSgpLmVuZE9mKHVuaXRzKS52YWx1ZU9mKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1NhbWVPckFmdGVyIChpbnB1dCwgdW5pdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNTYW1lKGlucHV0LCB1bml0cykgfHwgdGhpcy5pc0FmdGVyKGlucHV0LCB1bml0cyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNTYW1lT3JCZWZvcmUgKGlucHV0LCB1bml0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1NhbWUoaW5wdXQsIHVuaXRzKSB8fCB0aGlzLmlzQmVmb3JlKGlucHV0LCB1bml0cyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGlmZiAoaW5wdXQsIHVuaXRzLCBhc0Zsb2F0KSB7XG4gICAgICAgIHZhciB0aGF0LFxuICAgICAgICAgICAgem9uZURlbHRhLFxuICAgICAgICAgICAgb3V0cHV0O1xuXG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgIH1cblxuICAgICAgICB0aGF0ID0gY2xvbmVXaXRoT2Zmc2V0KGlucHV0LCB0aGlzKTtcblxuICAgICAgICBpZiAoIXRoYXQuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG5cbiAgICAgICAgem9uZURlbHRhID0gKHRoYXQudXRjT2Zmc2V0KCkgLSB0aGlzLnV0Y09mZnNldCgpKSAqIDZlNDtcblxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzogb3V0cHV0ID0gbW9udGhEaWZmKHRoaXMsIHRoYXQpIC8gMTI7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOiBvdXRwdXQgPSBtb250aERpZmYodGhpcywgdGhhdCk7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6IG91dHB1dCA9IG1vbnRoRGlmZih0aGlzLCB0aGF0KSAvIDM7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzogb3V0cHV0ID0gKHRoaXMgLSB0aGF0KSAvIDFlMzsgYnJlYWs7IC8vIDEwMDBcbiAgICAgICAgICAgIGNhc2UgJ21pbnV0ZSc6IG91dHB1dCA9ICh0aGlzIC0gdGhhdCkgLyA2ZTQ7IGJyZWFrOyAvLyAxMDAwICogNjBcbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOiBvdXRwdXQgPSAodGhpcyAtIHRoYXQpIC8gMzZlNTsgYnJlYWs7IC8vIDEwMDAgKiA2MCAqIDYwXG4gICAgICAgICAgICBjYXNlICdkYXknOiBvdXRwdXQgPSAodGhpcyAtIHRoYXQgLSB6b25lRGVsdGEpIC8gODY0ZTU7IGJyZWFrOyAvLyAxMDAwICogNjAgKiA2MCAqIDI0LCBuZWdhdGUgZHN0XG4gICAgICAgICAgICBjYXNlICd3ZWVrJzogb3V0cHV0ID0gKHRoaXMgLSB0aGF0IC0gem9uZURlbHRhKSAvIDYwNDhlNTsgYnJlYWs7IC8vIDEwMDAgKiA2MCAqIDYwICogMjQgKiA3LCBuZWdhdGUgZHN0XG4gICAgICAgICAgICBkZWZhdWx0OiBvdXRwdXQgPSB0aGlzIC0gdGhhdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhc0Zsb2F0ID8gb3V0cHV0IDogYWJzRmxvb3Iob3V0cHV0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb250aERpZmYgKGEsIGIpIHtcbiAgICAgICAgLy8gZGlmZmVyZW5jZSBpbiBtb250aHNcbiAgICAgICAgdmFyIHdob2xlTW9udGhEaWZmID0gKChiLnllYXIoKSAtIGEueWVhcigpKSAqIDEyKSArIChiLm1vbnRoKCkgLSBhLm1vbnRoKCkpLFxuICAgICAgICAgICAgLy8gYiBpcyBpbiAoYW5jaG9yIC0gMSBtb250aCwgYW5jaG9yICsgMSBtb250aClcbiAgICAgICAgICAgIGFuY2hvciA9IGEuY2xvbmUoKS5hZGQod2hvbGVNb250aERpZmYsICdtb250aHMnKSxcbiAgICAgICAgICAgIGFuY2hvcjIsIGFkanVzdDtcblxuICAgICAgICBpZiAoYiAtIGFuY2hvciA8IDApIHtcbiAgICAgICAgICAgIGFuY2hvcjIgPSBhLmNsb25lKCkuYWRkKHdob2xlTW9udGhEaWZmIC0gMSwgJ21vbnRocycpO1xuICAgICAgICAgICAgLy8gbGluZWFyIGFjcm9zcyB0aGUgbW9udGhcbiAgICAgICAgICAgIGFkanVzdCA9IChiIC0gYW5jaG9yKSAvIChhbmNob3IgLSBhbmNob3IyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFuY2hvcjIgPSBhLmNsb25lKCkuYWRkKHdob2xlTW9udGhEaWZmICsgMSwgJ21vbnRocycpO1xuICAgICAgICAgICAgLy8gbGluZWFyIGFjcm9zcyB0aGUgbW9udGhcbiAgICAgICAgICAgIGFkanVzdCA9IChiIC0gYW5jaG9yKSAvIChhbmNob3IyIC0gYW5jaG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vY2hlY2sgZm9yIG5lZ2F0aXZlIHplcm8sIHJldHVybiB6ZXJvIGlmIG5lZ2F0aXZlIHplcm9cbiAgICAgICAgcmV0dXJuIC0od2hvbGVNb250aERpZmYgKyBhZGp1c3QpIHx8IDA7XG4gICAgfVxuXG4gICAgaG9va3MuZGVmYXVsdEZvcm1hdCA9ICdZWVlZLU1NLUREVEhIOm1tOnNzWic7XG4gICAgaG9va3MuZGVmYXVsdEZvcm1hdFV0YyA9ICdZWVlZLU1NLUREVEhIOm1tOnNzW1pdJztcblxuICAgIGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5sb2NhbGUoJ2VuJykuZm9ybWF0KCdkZGQgTU1NIEREIFlZWVkgSEg6bW06c3MgW0dNVF1aWicpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvSVNPU3RyaW5nKGtlZXBPZmZzZXQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHV0YyA9IGtlZXBPZmZzZXQgIT09IHRydWU7XG4gICAgICAgIHZhciBtID0gdXRjID8gdGhpcy5jbG9uZSgpLnV0YygpIDogdGhpcztcbiAgICAgICAgaWYgKG0ueWVhcigpIDwgMCB8fCBtLnllYXIoKSA+IDk5OTkpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXRNb21lbnQobSwgdXRjID8gJ1lZWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1taXScgOiAnWVlZWVlZLU1NLUREW1RdSEg6bW06c3MuU1NTWicpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nKSkge1xuICAgICAgICAgICAgLy8gbmF0aXZlIGltcGxlbWVudGF0aW9uIGlzIH41MHggZmFzdGVyLCB1c2UgaXQgd2hlbiB3ZSBjYW5cbiAgICAgICAgICAgIGlmICh1dGMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0RhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkgKyB0aGlzLnV0Y09mZnNldCgpICogNjAgKiAxMDAwKS50b0lTT1N0cmluZygpLnJlcGxhY2UoJ1onLCBmb3JtYXRNb21lbnQobSwgJ1onKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdE1vbWVudChtLCB1dGMgPyAnWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1taXScgOiAnWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1onKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gYSBodW1hbiByZWFkYWJsZSByZXByZXNlbnRhdGlvbiBvZiBhIG1vbWVudCB0aGF0IGNhblxuICAgICAqIGFsc28gYmUgZXZhbHVhdGVkIHRvIGdldCBhIG5ldyBtb21lbnQgd2hpY2ggaXMgdGhlIHNhbWVcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHBzOi8vbm9kZWpzLm9yZy9kaXN0L2xhdGVzdC9kb2NzL2FwaS91dGlsLmh0bWwjdXRpbF9jdXN0b21faW5zcGVjdF9mdW5jdGlvbl9vbl9vYmplY3RzXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiAnbW9tZW50LmludmFsaWQoLyogJyArIHRoaXMuX2kgKyAnICovKSc7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZ1bmMgPSAnbW9tZW50JztcbiAgICAgICAgdmFyIHpvbmUgPSAnJztcbiAgICAgICAgaWYgKCF0aGlzLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgZnVuYyA9IHRoaXMudXRjT2Zmc2V0KCkgPT09IDAgPyAnbW9tZW50LnV0YycgOiAnbW9tZW50LnBhcnNlWm9uZSc7XG4gICAgICAgICAgICB6b25lID0gJ1onO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcmVmaXggPSAnWycgKyBmdW5jICsgJyhcIl0nO1xuICAgICAgICB2YXIgeWVhciA9ICgwIDw9IHRoaXMueWVhcigpICYmIHRoaXMueWVhcigpIDw9IDk5OTkpID8gJ1lZWVknIDogJ1lZWVlZWSc7XG4gICAgICAgIHZhciBkYXRldGltZSA9ICctTU0tRERbVF1ISDptbTpzcy5TU1MnO1xuICAgICAgICB2YXIgc3VmZml4ID0gem9uZSArICdbXCIpXSc7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0KHByZWZpeCArIHllYXIgKyBkYXRldGltZSArIHN1ZmZpeCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZm9ybWF0IChpbnB1dFN0cmluZykge1xuICAgICAgICBpZiAoIWlucHV0U3RyaW5nKSB7XG4gICAgICAgICAgICBpbnB1dFN0cmluZyA9IHRoaXMuaXNVdGMoKSA/IGhvb2tzLmRlZmF1bHRGb3JtYXRVdGMgOiBob29rcy5kZWZhdWx0Rm9ybWF0O1xuICAgICAgICB9XG4gICAgICAgIHZhciBvdXRwdXQgPSBmb3JtYXRNb21lbnQodGhpcywgaW5wdXRTdHJpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkucG9zdGZvcm1hdChvdXRwdXQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZyb20gKHRpbWUsIHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNWYWxpZCgpICYmXG4gICAgICAgICAgICAgICAgKChpc01vbWVudCh0aW1lKSAmJiB0aW1lLmlzVmFsaWQoKSkgfHxcbiAgICAgICAgICAgICAgICAgY3JlYXRlTG9jYWwodGltZSkuaXNWYWxpZCgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKHt0bzogdGhpcywgZnJvbTogdGltZX0pLmxvY2FsZSh0aGlzLmxvY2FsZSgpKS5odW1hbml6ZSghd2l0aG91dFN1ZmZpeCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkuaW52YWxpZERhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZyb21Ob3cgKHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJvbShjcmVhdGVMb2NhbCgpLCB3aXRob3V0U3VmZml4KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0byAodGltZSwgd2l0aG91dFN1ZmZpeCkge1xuICAgICAgICBpZiAodGhpcy5pc1ZhbGlkKCkgJiZcbiAgICAgICAgICAgICAgICAoKGlzTW9tZW50KHRpbWUpICYmIHRpbWUuaXNWYWxpZCgpKSB8fFxuICAgICAgICAgICAgICAgICBjcmVhdGVMb2NhbCh0aW1lKS5pc1ZhbGlkKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlRHVyYXRpb24oe2Zyb206IHRoaXMsIHRvOiB0aW1lfSkubG9jYWxlKHRoaXMubG9jYWxlKCkpLmh1bWFuaXplKCF3aXRob3V0U3VmZml4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS5pbnZhbGlkRGF0ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9Ob3cgKHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG8oY3JlYXRlTG9jYWwoKSwgd2l0aG91dFN1ZmZpeCk7XG4gICAgfVxuXG4gICAgLy8gSWYgcGFzc2VkIGEgbG9jYWxlIGtleSwgaXQgd2lsbCBzZXQgdGhlIGxvY2FsZSBmb3IgdGhpc1xuICAgIC8vIGluc3RhbmNlLiAgT3RoZXJ3aXNlLCBpdCB3aWxsIHJldHVybiB0aGUgbG9jYWxlIGNvbmZpZ3VyYXRpb25cbiAgICAvLyB2YXJpYWJsZXMgZm9yIHRoaXMgaW5zdGFuY2UuXG4gICAgZnVuY3Rpb24gbG9jYWxlIChrZXkpIHtcbiAgICAgICAgdmFyIG5ld0xvY2FsZURhdGE7XG5cbiAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlLl9hYmJyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3TG9jYWxlRGF0YSA9IGdldExvY2FsZShrZXkpO1xuICAgICAgICAgICAgaWYgKG5ld0xvY2FsZURhdGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvY2FsZSA9IG5ld0xvY2FsZURhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBsYW5nID0gZGVwcmVjYXRlKFxuICAgICAgICAnbW9tZW50KCkubGFuZygpIGlzIGRlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZSBtb21lbnQoKS5sb2NhbGVEYXRhKCkgdG8gZ2V0IHRoZSBsYW5ndWFnZSBjb25maWd1cmF0aW9uLiBVc2UgbW9tZW50KCkubG9jYWxlKCkgdG8gY2hhbmdlIGxhbmd1YWdlcy4nLFxuICAgICAgICBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZShrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIGZ1bmN0aW9uIGxvY2FsZURhdGEgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlO1xuICAgIH1cblxuICAgIHZhciBNU19QRVJfU0VDT05EID0gMTAwMDtcbiAgICB2YXIgTVNfUEVSX01JTlVURSA9IDYwICogTVNfUEVSX1NFQ09ORDtcbiAgICB2YXIgTVNfUEVSX0hPVVIgPSA2MCAqIE1TX1BFUl9NSU5VVEU7XG4gICAgdmFyIE1TX1BFUl80MDBfWUVBUlMgPSAoMzY1ICogNDAwICsgOTcpICogMjQgKiBNU19QRVJfSE9VUjtcblxuICAgIC8vIGFjdHVhbCBtb2R1bG8gLSBoYW5kbGVzIG5lZ2F0aXZlIG51bWJlcnMgKGZvciBkYXRlcyBiZWZvcmUgMTk3MCk6XG4gICAgZnVuY3Rpb24gbW9kJDEoZGl2aWRlbmQsIGRpdmlzb3IpIHtcbiAgICAgICAgcmV0dXJuIChkaXZpZGVuZCAlIGRpdmlzb3IgKyBkaXZpc29yKSAlIGRpdmlzb3I7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9jYWxTdGFydE9mRGF0ZSh5LCBtLCBkKSB7XG4gICAgICAgIC8vIHRoZSBkYXRlIGNvbnN0cnVjdG9yIHJlbWFwcyB5ZWFycyAwLTk5IHRvIDE5MDAtMTk5OVxuICAgICAgICBpZiAoeSA8IDEwMCAmJiB5ID49IDApIHtcbiAgICAgICAgICAgIC8vIHByZXNlcnZlIGxlYXAgeWVhcnMgdXNpbmcgYSBmdWxsIDQwMCB5ZWFyIGN5Y2xlLCB0aGVuIHJlc2V0XG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoeSArIDQwMCwgbSwgZCkgLSBNU19QRVJfNDAwX1lFQVJTO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHksIG0sIGQpLnZhbHVlT2YoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHV0Y1N0YXJ0T2ZEYXRlKHksIG0sIGQpIHtcbiAgICAgICAgLy8gRGF0ZS5VVEMgcmVtYXBzIHllYXJzIDAtOTkgdG8gMTkwMC0xOTk5XG4gICAgICAgIGlmICh5IDwgMTAwICYmIHkgPj0gMCkge1xuICAgICAgICAgICAgLy8gcHJlc2VydmUgbGVhcCB5ZWFycyB1c2luZyBhIGZ1bGwgNDAwIHllYXIgY3ljbGUsIHRoZW4gcmVzZXRcbiAgICAgICAgICAgIHJldHVybiBEYXRlLlVUQyh5ICsgNDAwLCBtLCBkKSAtIE1TX1BFUl80MDBfWUVBUlM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gRGF0ZS5VVEMoeSwgbSwgZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdGFydE9mICh1bml0cykge1xuICAgICAgICB2YXIgdGltZTtcbiAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh1bml0cyk7XG4gICAgICAgIGlmICh1bml0cyA9PT0gdW5kZWZpbmVkIHx8IHVuaXRzID09PSAnbWlsbGlzZWNvbmQnIHx8ICF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc3RhcnRPZkRhdGUgPSB0aGlzLl9pc1VUQyA/IHV0Y1N0YXJ0T2ZEYXRlIDogbG9jYWxTdGFydE9mRGF0ZTtcblxuICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIDAsIDEpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCkgLSB0aGlzLm1vbnRoKCkgJSAzLCAxKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgMSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSB0aGlzLndlZWtkYXkoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdpc29XZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSAodGhpcy5pc29XZWVrZGF5KCkgLSAxKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdkYXknOlxuICAgICAgICAgICAgY2FzZSAnZGF0ZSc6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCksIHRoaXMuZGF0ZSgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOlxuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLl9kLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB0aW1lIC09IG1vZCQxKHRpbWUgKyAodGhpcy5faXNVVEMgPyAwIDogdGhpcy51dGNPZmZzZXQoKSAqIE1TX1BFUl9NSU5VVEUpLCBNU19QRVJfSE9VUik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLl9kLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB0aW1lIC09IG1vZCQxKHRpbWUsIE1TX1BFUl9NSU5VVEUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSAtPSBtb2QkMSh0aW1lLCBNU19QRVJfU0VDT05EKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2Quc2V0VGltZSh0aW1lKTtcbiAgICAgICAgaG9va3MudXBkYXRlT2Zmc2V0KHRoaXMsIHRydWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBlbmRPZiAodW5pdHMpIHtcbiAgICAgICAgdmFyIHRpbWU7XG4gICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICBpZiAodW5pdHMgPT09IHVuZGVmaW5lZCB8fCB1bml0cyA9PT0gJ21pbGxpc2Vjb25kJyB8fCAhdGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHN0YXJ0T2ZEYXRlID0gdGhpcy5faXNVVEMgPyB1dGNTdGFydE9mRGF0ZSA6IGxvY2FsU3RhcnRPZkRhdGU7XG5cbiAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpICsgMSwgMCwgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCkgLSB0aGlzLm1vbnRoKCkgJSAzICsgMywgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOlxuICAgICAgICAgICAgICAgIHRpbWUgPSBzdGFydE9mRGF0ZSh0aGlzLnllYXIoKSwgdGhpcy5tb250aCgpICsgMSwgMSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgICAgICAgICAgdGltZSA9IHN0YXJ0T2ZEYXRlKHRoaXMueWVhcigpLCB0aGlzLm1vbnRoKCksIHRoaXMuZGF0ZSgpIC0gdGhpcy53ZWVrZGF5KCkgKyA3KSAtIDE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdpc29XZWVrJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgLSAodGhpcy5pc29XZWVrZGF5KCkgLSAxKSArIDcpIC0gMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2RheSc6XG4gICAgICAgICAgICBjYXNlICdkYXRlJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gc3RhcnRPZkRhdGUodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSwgdGhpcy5kYXRlKCkgKyAxKSAtIDE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfSE9VUiAtIG1vZCQxKHRpbWUgKyAodGhpcy5faXNVVEMgPyAwIDogdGhpcy51dGNPZmZzZXQoKSAqIE1TX1BFUl9NSU5VVEUpLCBNU19QRVJfSE9VUikgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbWludXRlJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfTUlOVVRFIC0gbW9kJDEodGltZSwgTVNfUEVSX01JTlVURSkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy5fZC52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgdGltZSArPSBNU19QRVJfU0VDT05EIC0gbW9kJDEodGltZSwgTVNfUEVSX1NFQ09ORCkgLSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fZC5zZXRUaW1lKHRpbWUpO1xuICAgICAgICBob29rcy51cGRhdGVPZmZzZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbHVlT2YgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZC52YWx1ZU9mKCkgLSAoKHRoaXMuX29mZnNldCB8fCAwKSAqIDYwMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1bml4ICgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IodGhpcy52YWx1ZU9mKCkgLyAxMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0RhdGUgKCkge1xuICAgICAgICByZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvQXJyYXkgKCkge1xuICAgICAgICB2YXIgbSA9IHRoaXM7XG4gICAgICAgIHJldHVybiBbbS55ZWFyKCksIG0ubW9udGgoKSwgbS5kYXRlKCksIG0uaG91cigpLCBtLm1pbnV0ZSgpLCBtLnNlY29uZCgpLCBtLm1pbGxpc2Vjb25kKCldO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvT2JqZWN0ICgpIHtcbiAgICAgICAgdmFyIG0gPSB0aGlzO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeWVhcnM6IG0ueWVhcigpLFxuICAgICAgICAgICAgbW9udGhzOiBtLm1vbnRoKCksXG4gICAgICAgICAgICBkYXRlOiBtLmRhdGUoKSxcbiAgICAgICAgICAgIGhvdXJzOiBtLmhvdXJzKCksXG4gICAgICAgICAgICBtaW51dGVzOiBtLm1pbnV0ZXMoKSxcbiAgICAgICAgICAgIHNlY29uZHM6IG0uc2Vjb25kcygpLFxuICAgICAgICAgICAgbWlsbGlzZWNvbmRzOiBtLm1pbGxpc2Vjb25kcygpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgICAgICAgLy8gbmV3IERhdGUoTmFOKS50b0pTT04oKSA9PT0gbnVsbFxuICAgICAgICByZXR1cm4gdGhpcy5pc1ZhbGlkKCkgPyB0aGlzLnRvSVNPU3RyaW5nKCkgOiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzVmFsaWQkMiAoKSB7XG4gICAgICAgIHJldHVybiBpc1ZhbGlkKHRoaXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhcnNpbmdGbGFncyAoKSB7XG4gICAgICAgIHJldHVybiBleHRlbmQoe30sIGdldFBhcnNpbmdGbGFncyh0aGlzKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW52YWxpZEF0ICgpIHtcbiAgICAgICAgcmV0dXJuIGdldFBhcnNpbmdGbGFncyh0aGlzKS5vdmVyZmxvdztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGlvbkRhdGEoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpbnB1dDogdGhpcy5faSxcbiAgICAgICAgICAgIGZvcm1hdDogdGhpcy5fZixcbiAgICAgICAgICAgIGxvY2FsZTogdGhpcy5fbG9jYWxlLFxuICAgICAgICAgICAgaXNVVEM6IHRoaXMuX2lzVVRDLFxuICAgICAgICAgICAgc3RyaWN0OiB0aGlzLl9zdHJpY3RcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ2dnJywgMl0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2Vla1llYXIoKSAlIDEwMDtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnR0cnLCAyXSwgMCwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc29XZWVrWWVhcigpICUgMTAwO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYWRkV2Vla1llYXJGb3JtYXRUb2tlbiAodG9rZW4sIGdldHRlcikge1xuICAgICAgICBhZGRGb3JtYXRUb2tlbigwLCBbdG9rZW4sIHRva2VuLmxlbmd0aF0sIDAsIGdldHRlcik7XG4gICAgfVxuXG4gICAgYWRkV2Vla1llYXJGb3JtYXRUb2tlbignZ2dnZycsICAgICAnd2Vla1llYXInKTtcbiAgICBhZGRXZWVrWWVhckZvcm1hdFRva2VuKCdnZ2dnZycsICAgICd3ZWVrWWVhcicpO1xuICAgIGFkZFdlZWtZZWFyRm9ybWF0VG9rZW4oJ0dHR0cnLCAgJ2lzb1dlZWtZZWFyJyk7XG4gICAgYWRkV2Vla1llYXJGb3JtYXRUb2tlbignR0dHR0cnLCAnaXNvV2Vla1llYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnd2Vla1llYXInLCAnZ2cnKTtcbiAgICBhZGRVbml0QWxpYXMoJ2lzb1dlZWtZZWFyJywgJ0dHJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCd3ZWVrWWVhcicsIDEpO1xuICAgIGFkZFVuaXRQcmlvcml0eSgnaXNvV2Vla1llYXInLCAxKTtcblxuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbignRycsICAgICAgbWF0Y2hTaWduZWQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2cnLCAgICAgIG1hdGNoU2lnbmVkKTtcbiAgICBhZGRSZWdleFRva2VuKCdHRycsICAgICBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignZ2cnLCAgICAgbWF0Y2gxdG8yLCBtYXRjaDIpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ0dHR0cnLCAgIG1hdGNoMXRvNCwgbWF0Y2g0KTtcbiAgICBhZGRSZWdleFRva2VuKCdnZ2dnJywgICBtYXRjaDF0bzQsIG1hdGNoNCk7XG4gICAgYWRkUmVnZXhUb2tlbignR0dHR0cnLCAgbWF0Y2gxdG82LCBtYXRjaDYpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ2dnZ2dnJywgIG1hdGNoMXRvNiwgbWF0Y2g2KTtcblxuICAgIGFkZFdlZWtQYXJzZVRva2VuKFsnZ2dnZycsICdnZ2dnZycsICdHR0dHJywgJ0dHR0dHJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuLnN1YnN0cigwLCAyKV0gPSB0b0ludChpbnB1dCk7XG4gICAgfSk7XG5cbiAgICBhZGRXZWVrUGFyc2VUb2tlbihbJ2dnJywgJ0dHJ10sIGZ1bmN0aW9uIChpbnB1dCwgd2VlaywgY29uZmlnLCB0b2tlbikge1xuICAgICAgICB3ZWVrW3Rva2VuXSA9IGhvb2tzLnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICB9KTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFNldFdlZWtZZWFyIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gZ2V0U2V0V2Vla1llYXJIZWxwZXIuY2FsbCh0aGlzLFxuICAgICAgICAgICAgICAgIGlucHV0LFxuICAgICAgICAgICAgICAgIHRoaXMud2VlaygpLFxuICAgICAgICAgICAgICAgIHRoaXMud2Vla2RheSgpLFxuICAgICAgICAgICAgICAgIHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrLmRvdyxcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsZURhdGEoKS5fd2Vlay5kb3kpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFNldElTT1dlZWtZZWFyIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gZ2V0U2V0V2Vla1llYXJIZWxwZXIuY2FsbCh0aGlzLFxuICAgICAgICAgICAgICAgIGlucHV0LCB0aGlzLmlzb1dlZWsoKSwgdGhpcy5pc29XZWVrZGF5KCksIDEsIDQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldElTT1dlZWtzSW5ZZWFyICgpIHtcbiAgICAgICAgcmV0dXJuIHdlZWtzSW5ZZWFyKHRoaXMueWVhcigpLCAxLCA0KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRXZWVrc0luWWVhciAoKSB7XG4gICAgICAgIHZhciB3ZWVrSW5mbyA9IHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrO1xuICAgICAgICByZXR1cm4gd2Vla3NJblllYXIodGhpcy55ZWFyKCksIHdlZWtJbmZvLmRvdywgd2Vla0luZm8uZG95KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZXRXZWVrWWVhckhlbHBlcihpbnB1dCwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIHdlZWtzVGFyZ2V0O1xuICAgICAgICBpZiAoaW5wdXQgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHdlZWtPZlllYXIodGhpcywgZG93LCBkb3kpLnllYXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3ZWVrc1RhcmdldCA9IHdlZWtzSW5ZZWFyKGlucHV0LCBkb3csIGRveSk7XG4gICAgICAgICAgICBpZiAod2VlayA+IHdlZWtzVGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgd2VlayA9IHdlZWtzVGFyZ2V0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNldFdlZWtBbGwuY2FsbCh0aGlzLCBpbnB1dCwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0V2Vla0FsbCh3ZWVrWWVhciwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3kpIHtcbiAgICAgICAgdmFyIGRheU9mWWVhckRhdGEgPSBkYXlPZlllYXJGcm9tV2Vla3Mod2Vla1llYXIsIHdlZWssIHdlZWtkYXksIGRvdywgZG95KSxcbiAgICAgICAgICAgIGRhdGUgPSBjcmVhdGVVVENEYXRlKGRheU9mWWVhckRhdGEueWVhciwgMCwgZGF5T2ZZZWFyRGF0YS5kYXlPZlllYXIpO1xuXG4gICAgICAgIHRoaXMueWVhcihkYXRlLmdldFVUQ0Z1bGxZZWFyKCkpO1xuICAgICAgICB0aGlzLm1vbnRoKGRhdGUuZ2V0VVRDTW9udGgoKSk7XG4gICAgICAgIHRoaXMuZGF0ZShkYXRlLmdldFVUQ0RhdGUoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdRJywgMCwgJ1FvJywgJ3F1YXJ0ZXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygncXVhcnRlcicsICdRJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdxdWFydGVyJywgNyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdRJywgbWF0Y2gxKTtcbiAgICBhZGRQYXJzZVRva2VuKCdRJywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSkge1xuICAgICAgICBhcnJheVtNT05USF0gPSAodG9JbnQoaW5wdXQpIC0gMSkgKiAzO1xuICAgIH0pO1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgZnVuY3Rpb24gZ2V0U2V0UXVhcnRlciAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyBNYXRoLmNlaWwoKHRoaXMubW9udGgoKSArIDEpIC8gMykgOiB0aGlzLm1vbnRoKChpbnB1dCAtIDEpICogMyArIHRoaXMubW9udGgoKSAlIDMpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdEJywgWydERCcsIDJdLCAnRG8nLCAnZGF0ZScpO1xuXG4gICAgLy8gQUxJQVNFU1xuXG4gICAgYWRkVW5pdEFsaWFzKCdkYXRlJywgJ0QnKTtcblxuICAgIC8vIFBSSU9SSVRZXG4gICAgYWRkVW5pdFByaW9yaXR5KCdkYXRlJywgOSk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdEJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignREQnLCBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUmVnZXhUb2tlbignRG8nLCBmdW5jdGlvbiAoaXNTdHJpY3QsIGxvY2FsZSkge1xuICAgICAgICAvLyBUT0RPOiBSZW1vdmUgXCJvcmRpbmFsUGFyc2VcIiBmYWxsYmFjayBpbiBuZXh0IG1ham9yIHJlbGVhc2UuXG4gICAgICAgIHJldHVybiBpc1N0cmljdCA/XG4gICAgICAgICAgKGxvY2FsZS5fZGF5T2ZNb250aE9yZGluYWxQYXJzZSB8fCBsb2NhbGUuX29yZGluYWxQYXJzZSkgOlxuICAgICAgICAgIGxvY2FsZS5fZGF5T2ZNb250aE9yZGluYWxQYXJzZUxlbmllbnQ7XG4gICAgfSk7XG5cbiAgICBhZGRQYXJzZVRva2VuKFsnRCcsICdERCddLCBEQVRFKTtcbiAgICBhZGRQYXJzZVRva2VuKCdEbycsIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbREFURV0gPSB0b0ludChpbnB1dC5tYXRjaChtYXRjaDF0bzIpWzBdKTtcbiAgICB9KTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIHZhciBnZXRTZXREYXlPZk1vbnRoID0gbWFrZUdldFNldCgnRGF0ZScsIHRydWUpO1xuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ0RERCcsIFsnRERERCcsIDNdLCAnREREbycsICdkYXlPZlllYXInKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnZGF5T2ZZZWFyJywgJ0RERCcpO1xuXG4gICAgLy8gUFJJT1JJVFlcbiAgICBhZGRVbml0UHJpb3JpdHkoJ2RheU9mWWVhcicsIDQpO1xuXG4gICAgLy8gUEFSU0lOR1xuXG4gICAgYWRkUmVnZXhUb2tlbignREREJywgIG1hdGNoMXRvMyk7XG4gICAgYWRkUmVnZXhUb2tlbignRERERCcsIG1hdGNoMyk7XG4gICAgYWRkUGFyc2VUb2tlbihbJ0RERCcsICdEREREJ10sIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2RheU9mWWVhciA9IHRvSW50KGlucHV0KTtcbiAgICB9KTtcblxuICAgIC8vIEhFTFBFUlNcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFNldERheU9mWWVhciAoaW5wdXQpIHtcbiAgICAgICAgdmFyIGRheU9mWWVhciA9IE1hdGgucm91bmQoKHRoaXMuY2xvbmUoKS5zdGFydE9mKCdkYXknKSAtIHRoaXMuY2xvbmUoKS5zdGFydE9mKCd5ZWFyJykpIC8gODY0ZTUpICsgMTtcbiAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyBkYXlPZlllYXIgOiB0aGlzLmFkZCgoaW5wdXQgLSBkYXlPZlllYXIpLCAnZCcpO1xuICAgIH1cblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdtJywgWydtbScsIDJdLCAwLCAnbWludXRlJyk7XG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21pbnV0ZScsICdtJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdtaW51dGUnLCAxNCk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCdtJywgIG1hdGNoMXRvMik7XG4gICAgYWRkUmVnZXhUb2tlbignbW0nLCBtYXRjaDF0bzIsIG1hdGNoMik7XG4gICAgYWRkUGFyc2VUb2tlbihbJ20nLCAnbW0nXSwgTUlOVVRFKTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIHZhciBnZXRTZXRNaW51dGUgPSBtYWtlR2V0U2V0KCdNaW51dGVzJywgZmFsc2UpO1xuXG4gICAgLy8gRk9STUFUVElOR1xuXG4gICAgYWRkRm9ybWF0VG9rZW4oJ3MnLCBbJ3NzJywgMl0sIDAsICdzZWNvbmQnKTtcblxuICAgIC8vIEFMSUFTRVNcblxuICAgIGFkZFVuaXRBbGlhcygnc2Vjb25kJywgJ3MnKTtcblxuICAgIC8vIFBSSU9SSVRZXG5cbiAgICBhZGRVbml0UHJpb3JpdHkoJ3NlY29uZCcsIDE1KTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ3MnLCAgbWF0Y2gxdG8yKTtcbiAgICBhZGRSZWdleFRva2VuKCdzcycsIG1hdGNoMXRvMiwgbWF0Y2gyKTtcbiAgICBhZGRQYXJzZVRva2VuKFsncycsICdzcyddLCBTRUNPTkQpO1xuXG4gICAgLy8gTU9NRU5UU1xuXG4gICAgdmFyIGdldFNldFNlY29uZCA9IG1ha2VHZXRTZXQoJ1NlY29uZHMnLCBmYWxzZSk7XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbignUycsIDAsIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIH5+KHRoaXMubWlsbGlzZWNvbmQoKSAvIDEwMCk7XG4gICAgfSk7XG5cbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTJywgMl0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIH5+KHRoaXMubWlsbGlzZWNvbmQoKSAvIDEwKTtcbiAgICB9KTtcblxuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTJywgM10sIDAsICdtaWxsaXNlY29uZCcpO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTUycsIDRdLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTJywgNV0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWlsbGlzZWNvbmQoKSAqIDEwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTUycsIDZdLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwO1xuICAgIH0pO1xuICAgIGFkZEZvcm1hdFRva2VuKDAsIFsnU1NTU1NTUycsIDddLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTU1NTJywgOF0sIDAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWlsbGlzZWNvbmQoKSAqIDEwMDAwMDtcbiAgICB9KTtcbiAgICBhZGRGb3JtYXRUb2tlbigwLCBbJ1NTU1NTU1NTUycsIDldLCAwLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1pbGxpc2Vjb25kKCkgKiAxMDAwMDAwO1xuICAgIH0pO1xuXG5cbiAgICAvLyBBTElBU0VTXG5cbiAgICBhZGRVbml0QWxpYXMoJ21pbGxpc2Vjb25kJywgJ21zJyk7XG5cbiAgICAvLyBQUklPUklUWVxuXG4gICAgYWRkVW5pdFByaW9yaXR5KCdtaWxsaXNlY29uZCcsIDE2KTtcblxuICAgIC8vIFBBUlNJTkdcblxuICAgIGFkZFJlZ2V4VG9rZW4oJ1MnLCAgICBtYXRjaDF0bzMsIG1hdGNoMSk7XG4gICAgYWRkUmVnZXhUb2tlbignU1MnLCAgIG1hdGNoMXRvMywgbWF0Y2gyKTtcbiAgICBhZGRSZWdleFRva2VuKCdTU1MnLCAgbWF0Y2gxdG8zLCBtYXRjaDMpO1xuXG4gICAgdmFyIHRva2VuO1xuICAgIGZvciAodG9rZW4gPSAnU1NTUyc7IHRva2VuLmxlbmd0aCA8PSA5OyB0b2tlbiArPSAnUycpIHtcbiAgICAgICAgYWRkUmVnZXhUb2tlbih0b2tlbiwgbWF0Y2hVbnNpZ25lZCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VNcyhpbnB1dCwgYXJyYXkpIHtcbiAgICAgICAgYXJyYXlbTUlMTElTRUNPTkRdID0gdG9JbnQoKCcwLicgKyBpbnB1dCkgKiAxMDAwKTtcbiAgICB9XG5cbiAgICBmb3IgKHRva2VuID0gJ1MnOyB0b2tlbi5sZW5ndGggPD0gOTsgdG9rZW4gKz0gJ1MnKSB7XG4gICAgICAgIGFkZFBhcnNlVG9rZW4odG9rZW4sIHBhcnNlTXMpO1xuICAgIH1cbiAgICAvLyBNT01FTlRTXG5cbiAgICB2YXIgZ2V0U2V0TWlsbGlzZWNvbmQgPSBtYWtlR2V0U2V0KCdNaWxsaXNlY29uZHMnLCBmYWxzZSk7XG5cbiAgICAvLyBGT1JNQVRUSU5HXG5cbiAgICBhZGRGb3JtYXRUb2tlbigneicsICAwLCAwLCAnem9uZUFiYnInKTtcbiAgICBhZGRGb3JtYXRUb2tlbignenonLCAwLCAwLCAnem9uZU5hbWUnKTtcblxuICAgIC8vIE1PTUVOVFNcblxuICAgIGZ1bmN0aW9uIGdldFpvbmVBYmJyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzVVRDID8gJ1VUQycgOiAnJztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRab25lTmFtZSAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/ICdDb29yZGluYXRlZCBVbml2ZXJzYWwgVGltZScgOiAnJztcbiAgICB9XG5cbiAgICB2YXIgcHJvdG8gPSBNb21lbnQucHJvdG90eXBlO1xuXG4gICAgcHJvdG8uYWRkICAgICAgICAgICAgICAgPSBhZGQ7XG4gICAgcHJvdG8uY2FsZW5kYXIgICAgICAgICAgPSBjYWxlbmRhciQxO1xuICAgIHByb3RvLmNsb25lICAgICAgICAgICAgID0gY2xvbmU7XG4gICAgcHJvdG8uZGlmZiAgICAgICAgICAgICAgPSBkaWZmO1xuICAgIHByb3RvLmVuZE9mICAgICAgICAgICAgID0gZW5kT2Y7XG4gICAgcHJvdG8uZm9ybWF0ICAgICAgICAgICAgPSBmb3JtYXQ7XG4gICAgcHJvdG8uZnJvbSAgICAgICAgICAgICAgPSBmcm9tO1xuICAgIHByb3RvLmZyb21Ob3cgICAgICAgICAgID0gZnJvbU5vdztcbiAgICBwcm90by50byAgICAgICAgICAgICAgICA9IHRvO1xuICAgIHByb3RvLnRvTm93ICAgICAgICAgICAgID0gdG9Ob3c7XG4gICAgcHJvdG8uZ2V0ICAgICAgICAgICAgICAgPSBzdHJpbmdHZXQ7XG4gICAgcHJvdG8uaW52YWxpZEF0ICAgICAgICAgPSBpbnZhbGlkQXQ7XG4gICAgcHJvdG8uaXNBZnRlciAgICAgICAgICAgPSBpc0FmdGVyO1xuICAgIHByb3RvLmlzQmVmb3JlICAgICAgICAgID0gaXNCZWZvcmU7XG4gICAgcHJvdG8uaXNCZXR3ZWVuICAgICAgICAgPSBpc0JldHdlZW47XG4gICAgcHJvdG8uaXNTYW1lICAgICAgICAgICAgPSBpc1NhbWU7XG4gICAgcHJvdG8uaXNTYW1lT3JBZnRlciAgICAgPSBpc1NhbWVPckFmdGVyO1xuICAgIHByb3RvLmlzU2FtZU9yQmVmb3JlICAgID0gaXNTYW1lT3JCZWZvcmU7XG4gICAgcHJvdG8uaXNWYWxpZCAgICAgICAgICAgPSBpc1ZhbGlkJDI7XG4gICAgcHJvdG8ubGFuZyAgICAgICAgICAgICAgPSBsYW5nO1xuICAgIHByb3RvLmxvY2FsZSAgICAgICAgICAgID0gbG9jYWxlO1xuICAgIHByb3RvLmxvY2FsZURhdGEgICAgICAgID0gbG9jYWxlRGF0YTtcbiAgICBwcm90by5tYXggICAgICAgICAgICAgICA9IHByb3RvdHlwZU1heDtcbiAgICBwcm90by5taW4gICAgICAgICAgICAgICA9IHByb3RvdHlwZU1pbjtcbiAgICBwcm90by5wYXJzaW5nRmxhZ3MgICAgICA9IHBhcnNpbmdGbGFncztcbiAgICBwcm90by5zZXQgICAgICAgICAgICAgICA9IHN0cmluZ1NldDtcbiAgICBwcm90by5zdGFydE9mICAgICAgICAgICA9IHN0YXJ0T2Y7XG4gICAgcHJvdG8uc3VidHJhY3QgICAgICAgICAgPSBzdWJ0cmFjdDtcbiAgICBwcm90by50b0FycmF5ICAgICAgICAgICA9IHRvQXJyYXk7XG4gICAgcHJvdG8udG9PYmplY3QgICAgICAgICAgPSB0b09iamVjdDtcbiAgICBwcm90by50b0RhdGUgICAgICAgICAgICA9IHRvRGF0ZTtcbiAgICBwcm90by50b0lTT1N0cmluZyAgICAgICA9IHRvSVNPU3RyaW5nO1xuICAgIHByb3RvLmluc3BlY3QgICAgICAgICAgID0gaW5zcGVjdDtcbiAgICBwcm90by50b0pTT04gICAgICAgICAgICA9IHRvSlNPTjtcbiAgICBwcm90by50b1N0cmluZyAgICAgICAgICA9IHRvU3RyaW5nO1xuICAgIHByb3RvLnVuaXggICAgICAgICAgICAgID0gdW5peDtcbiAgICBwcm90by52YWx1ZU9mICAgICAgICAgICA9IHZhbHVlT2Y7XG4gICAgcHJvdG8uY3JlYXRpb25EYXRhICAgICAgPSBjcmVhdGlvbkRhdGE7XG4gICAgcHJvdG8ueWVhciAgICAgICA9IGdldFNldFllYXI7XG4gICAgcHJvdG8uaXNMZWFwWWVhciA9IGdldElzTGVhcFllYXI7XG4gICAgcHJvdG8ud2Vla1llYXIgICAgPSBnZXRTZXRXZWVrWWVhcjtcbiAgICBwcm90by5pc29XZWVrWWVhciA9IGdldFNldElTT1dlZWtZZWFyO1xuICAgIHByb3RvLnF1YXJ0ZXIgPSBwcm90by5xdWFydGVycyA9IGdldFNldFF1YXJ0ZXI7XG4gICAgcHJvdG8ubW9udGggICAgICAgPSBnZXRTZXRNb250aDtcbiAgICBwcm90by5kYXlzSW5Nb250aCA9IGdldERheXNJbk1vbnRoO1xuICAgIHByb3RvLndlZWsgICAgICAgICAgID0gcHJvdG8ud2Vla3MgICAgICAgID0gZ2V0U2V0V2VlaztcbiAgICBwcm90by5pc29XZWVrICAgICAgICA9IHByb3RvLmlzb1dlZWtzICAgICA9IGdldFNldElTT1dlZWs7XG4gICAgcHJvdG8ud2Vla3NJblllYXIgICAgPSBnZXRXZWVrc0luWWVhcjtcbiAgICBwcm90by5pc29XZWVrc0luWWVhciA9IGdldElTT1dlZWtzSW5ZZWFyO1xuICAgIHByb3RvLmRhdGUgICAgICAgPSBnZXRTZXREYXlPZk1vbnRoO1xuICAgIHByb3RvLmRheSAgICAgICAgPSBwcm90by5kYXlzICAgICAgICAgICAgID0gZ2V0U2V0RGF5T2ZXZWVrO1xuICAgIHByb3RvLndlZWtkYXkgICAgPSBnZXRTZXRMb2NhbGVEYXlPZldlZWs7XG4gICAgcHJvdG8uaXNvV2Vla2RheSA9IGdldFNldElTT0RheU9mV2VlaztcbiAgICBwcm90by5kYXlPZlllYXIgID0gZ2V0U2V0RGF5T2ZZZWFyO1xuICAgIHByb3RvLmhvdXIgPSBwcm90by5ob3VycyA9IGdldFNldEhvdXI7XG4gICAgcHJvdG8ubWludXRlID0gcHJvdG8ubWludXRlcyA9IGdldFNldE1pbnV0ZTtcbiAgICBwcm90by5zZWNvbmQgPSBwcm90by5zZWNvbmRzID0gZ2V0U2V0U2Vjb25kO1xuICAgIHByb3RvLm1pbGxpc2Vjb25kID0gcHJvdG8ubWlsbGlzZWNvbmRzID0gZ2V0U2V0TWlsbGlzZWNvbmQ7XG4gICAgcHJvdG8udXRjT2Zmc2V0ICAgICAgICAgICAgPSBnZXRTZXRPZmZzZXQ7XG4gICAgcHJvdG8udXRjICAgICAgICAgICAgICAgICAgPSBzZXRPZmZzZXRUb1VUQztcbiAgICBwcm90by5sb2NhbCAgICAgICAgICAgICAgICA9IHNldE9mZnNldFRvTG9jYWw7XG4gICAgcHJvdG8ucGFyc2Vab25lICAgICAgICAgICAgPSBzZXRPZmZzZXRUb1BhcnNlZE9mZnNldDtcbiAgICBwcm90by5oYXNBbGlnbmVkSG91ck9mZnNldCA9IGhhc0FsaWduZWRIb3VyT2Zmc2V0O1xuICAgIHByb3RvLmlzRFNUICAgICAgICAgICAgICAgID0gaXNEYXlsaWdodFNhdmluZ1RpbWU7XG4gICAgcHJvdG8uaXNMb2NhbCAgICAgICAgICAgICAgPSBpc0xvY2FsO1xuICAgIHByb3RvLmlzVXRjT2Zmc2V0ICAgICAgICAgID0gaXNVdGNPZmZzZXQ7XG4gICAgcHJvdG8uaXNVdGMgICAgICAgICAgICAgICAgPSBpc1V0YztcbiAgICBwcm90by5pc1VUQyAgICAgICAgICAgICAgICA9IGlzVXRjO1xuICAgIHByb3RvLnpvbmVBYmJyID0gZ2V0Wm9uZUFiYnI7XG4gICAgcHJvdG8uem9uZU5hbWUgPSBnZXRab25lTmFtZTtcbiAgICBwcm90by5kYXRlcyAgPSBkZXByZWNhdGUoJ2RhdGVzIGFjY2Vzc29yIGlzIGRlcHJlY2F0ZWQuIFVzZSBkYXRlIGluc3RlYWQuJywgZ2V0U2V0RGF5T2ZNb250aCk7XG4gICAgcHJvdG8ubW9udGhzID0gZGVwcmVjYXRlKCdtb250aHMgYWNjZXNzb3IgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbnRoIGluc3RlYWQnLCBnZXRTZXRNb250aCk7XG4gICAgcHJvdG8ueWVhcnMgID0gZGVwcmVjYXRlKCd5ZWFycyBhY2Nlc3NvciBpcyBkZXByZWNhdGVkLiBVc2UgeWVhciBpbnN0ZWFkJywgZ2V0U2V0WWVhcik7XG4gICAgcHJvdG8uem9uZSAgID0gZGVwcmVjYXRlKCdtb21lbnQoKS56b25lIGlzIGRlcHJlY2F0ZWQsIHVzZSBtb21lbnQoKS51dGNPZmZzZXQgaW5zdGVhZC4gaHR0cDovL21vbWVudGpzLmNvbS9ndWlkZXMvIy93YXJuaW5ncy96b25lLycsIGdldFNldFpvbmUpO1xuICAgIHByb3RvLmlzRFNUU2hpZnRlZCA9IGRlcHJlY2F0ZSgnaXNEU1RTaGlmdGVkIGlzIGRlcHJlY2F0ZWQuIFNlZSBodHRwOi8vbW9tZW50anMuY29tL2d1aWRlcy8jL3dhcm5pbmdzL2RzdC1zaGlmdGVkLyBmb3IgbW9yZSBpbmZvcm1hdGlvbicsIGlzRGF5bGlnaHRTYXZpbmdUaW1lU2hpZnRlZCk7XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVVbml4IChpbnB1dCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwoaW5wdXQgKiAxMDAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVJblpvbmUgKCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlTG9jYWwuYXBwbHkobnVsbCwgYXJndW1lbnRzKS5wYXJzZVpvbmUoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmVQYXJzZVBvc3RGb3JtYXQgKHN0cmluZykge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgIH1cblxuICAgIHZhciBwcm90byQxID0gTG9jYWxlLnByb3RvdHlwZTtcblxuICAgIHByb3RvJDEuY2FsZW5kYXIgICAgICAgID0gY2FsZW5kYXI7XG4gICAgcHJvdG8kMS5sb25nRGF0ZUZvcm1hdCAgPSBsb25nRGF0ZUZvcm1hdDtcbiAgICBwcm90byQxLmludmFsaWREYXRlICAgICA9IGludmFsaWREYXRlO1xuICAgIHByb3RvJDEub3JkaW5hbCAgICAgICAgID0gb3JkaW5hbDtcbiAgICBwcm90byQxLnByZXBhcnNlICAgICAgICA9IHByZVBhcnNlUG9zdEZvcm1hdDtcbiAgICBwcm90byQxLnBvc3Rmb3JtYXQgICAgICA9IHByZVBhcnNlUG9zdEZvcm1hdDtcbiAgICBwcm90byQxLnJlbGF0aXZlVGltZSAgICA9IHJlbGF0aXZlVGltZTtcbiAgICBwcm90byQxLnBhc3RGdXR1cmUgICAgICA9IHBhc3RGdXR1cmU7XG4gICAgcHJvdG8kMS5zZXQgICAgICAgICAgICAgPSBzZXQ7XG5cbiAgICBwcm90byQxLm1vbnRocyAgICAgICAgICAgID0gICAgICAgIGxvY2FsZU1vbnRocztcbiAgICBwcm90byQxLm1vbnRoc1Nob3J0ICAgICAgID0gICAgICAgIGxvY2FsZU1vbnRoc1Nob3J0O1xuICAgIHByb3RvJDEubW9udGhzUGFyc2UgICAgICAgPSAgICAgICAgbG9jYWxlTW9udGhzUGFyc2U7XG4gICAgcHJvdG8kMS5tb250aHNSZWdleCAgICAgICA9IG1vbnRoc1JlZ2V4O1xuICAgIHByb3RvJDEubW9udGhzU2hvcnRSZWdleCAgPSBtb250aHNTaG9ydFJlZ2V4O1xuICAgIHByb3RvJDEud2VlayA9IGxvY2FsZVdlZWs7XG4gICAgcHJvdG8kMS5maXJzdERheU9mWWVhciA9IGxvY2FsZUZpcnN0RGF5T2ZZZWFyO1xuICAgIHByb3RvJDEuZmlyc3REYXlPZldlZWsgPSBsb2NhbGVGaXJzdERheU9mV2VlaztcblxuICAgIHByb3RvJDEud2Vla2RheXMgICAgICAgPSAgICAgICAgbG9jYWxlV2Vla2RheXM7XG4gICAgcHJvdG8kMS53ZWVrZGF5c01pbiAgICA9ICAgICAgICBsb2NhbGVXZWVrZGF5c01pbjtcbiAgICBwcm90byQxLndlZWtkYXlzU2hvcnQgID0gICAgICAgIGxvY2FsZVdlZWtkYXlzU2hvcnQ7XG4gICAgcHJvdG8kMS53ZWVrZGF5c1BhcnNlICA9ICAgICAgICBsb2NhbGVXZWVrZGF5c1BhcnNlO1xuXG4gICAgcHJvdG8kMS53ZWVrZGF5c1JlZ2V4ICAgICAgID0gICAgICAgIHdlZWtkYXlzUmVnZXg7XG4gICAgcHJvdG8kMS53ZWVrZGF5c1Nob3J0UmVnZXggID0gICAgICAgIHdlZWtkYXlzU2hvcnRSZWdleDtcbiAgICBwcm90byQxLndlZWtkYXlzTWluUmVnZXggICAgPSAgICAgICAgd2Vla2RheXNNaW5SZWdleDtcblxuICAgIHByb3RvJDEuaXNQTSA9IGxvY2FsZUlzUE07XG4gICAgcHJvdG8kMS5tZXJpZGllbSA9IGxvY2FsZU1lcmlkaWVtO1xuXG4gICAgZnVuY3Rpb24gZ2V0JDEgKGZvcm1hdCwgaW5kZXgsIGZpZWxkLCBzZXR0ZXIpIHtcbiAgICAgICAgdmFyIGxvY2FsZSA9IGdldExvY2FsZSgpO1xuICAgICAgICB2YXIgdXRjID0gY3JlYXRlVVRDKCkuc2V0KHNldHRlciwgaW5kZXgpO1xuICAgICAgICByZXR1cm4gbG9jYWxlW2ZpZWxkXSh1dGMsIGZvcm1hdCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdE1vbnRoc0ltcGwgKGZvcm1hdCwgaW5kZXgsIGZpZWxkKSB7XG4gICAgICAgIGlmIChpc051bWJlcihmb3JtYXQpKSB7XG4gICAgICAgICAgICBpbmRleCA9IGZvcm1hdDtcbiAgICAgICAgICAgIGZvcm1hdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvcm1hdCA9IGZvcm1hdCB8fCAnJztcblxuICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldCQxKGZvcm1hdCwgaW5kZXgsIGZpZWxkLCAnbW9udGgnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgb3V0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAxMjsgaSsrKSB7XG4gICAgICAgICAgICBvdXRbaV0gPSBnZXQkMShmb3JtYXQsIGksIGZpZWxkLCAnbW9udGgnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH1cblxuICAgIC8vICgpXG4gICAgLy8gKDUpXG4gICAgLy8gKGZtdCwgNSlcbiAgICAvLyAoZm10KVxuICAgIC8vICh0cnVlKVxuICAgIC8vICh0cnVlLCA1KVxuICAgIC8vICh0cnVlLCBmbXQsIDUpXG4gICAgLy8gKHRydWUsIGZtdClcbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNJbXBsIChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgsIGZpZWxkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbG9jYWxlU29ydGVkID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIGlmIChpc051bWJlcihmb3JtYXQpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBmb3JtYXQ7XG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3JtYXQgPSBmb3JtYXQgfHwgJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3JtYXQgPSBsb2NhbGVTb3J0ZWQ7XG4gICAgICAgICAgICBpbmRleCA9IGZvcm1hdDtcbiAgICAgICAgICAgIGxvY2FsZVNvcnRlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoaXNOdW1iZXIoZm9ybWF0KSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gZm9ybWF0O1xuICAgICAgICAgICAgICAgIGZvcm1hdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9ybWF0ID0gZm9ybWF0IHx8ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGxvY2FsZSA9IGdldExvY2FsZSgpLFxuICAgICAgICAgICAgc2hpZnQgPSBsb2NhbGVTb3J0ZWQgPyBsb2NhbGUuX3dlZWsuZG93IDogMDtcblxuICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldCQxKGZvcm1hdCwgKGluZGV4ICsgc2hpZnQpICUgNywgZmllbGQsICdkYXknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpO1xuICAgICAgICB2YXIgb3V0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIG91dFtpXSA9IGdldCQxKGZvcm1hdCwgKGkgKyBzaGlmdCkgJSA3LCBmaWVsZCwgJ2RheScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdE1vbnRocyAoZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdE1vbnRoc0ltcGwoZm9ybWF0LCBpbmRleCwgJ21vbnRocycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpc3RNb250aHNTaG9ydCAoZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdE1vbnRoc0ltcGwoZm9ybWF0LCBpbmRleCwgJ21vbnRoc1Nob3J0Jyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlzdFdlZWtkYXlzIChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGxpc3RXZWVrZGF5c0ltcGwobG9jYWxlU29ydGVkLCBmb3JtYXQsIGluZGV4LCAnd2Vla2RheXMnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNTaG9ydCAobG9jYWxlU29ydGVkLCBmb3JtYXQsIGluZGV4KSB7XG4gICAgICAgIHJldHVybiBsaXN0V2Vla2RheXNJbXBsKGxvY2FsZVNvcnRlZCwgZm9ybWF0LCBpbmRleCwgJ3dlZWtkYXlzU2hvcnQnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0V2Vla2RheXNNaW4gKGxvY2FsZVNvcnRlZCwgZm9ybWF0LCBpbmRleCkge1xuICAgICAgICByZXR1cm4gbGlzdFdlZWtkYXlzSW1wbChsb2NhbGVTb3J0ZWQsIGZvcm1hdCwgaW5kZXgsICd3ZWVrZGF5c01pbicpO1xuICAgIH1cblxuICAgIGdldFNldEdsb2JhbExvY2FsZSgnZW4nLCB7XG4gICAgICAgIGRheU9mTW9udGhPcmRpbmFsUGFyc2U6IC9cXGR7MSwyfSh0aHxzdHxuZHxyZCkvLFxuICAgICAgICBvcmRpbmFsIDogZnVuY3Rpb24gKG51bWJlcikge1xuICAgICAgICAgICAgdmFyIGIgPSBudW1iZXIgJSAxMCxcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSAodG9JbnQobnVtYmVyICUgMTAwIC8gMTApID09PSAxKSA/ICd0aCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAxKSA/ICdzdCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAyKSA/ICduZCcgOlxuICAgICAgICAgICAgICAgIChiID09PSAzKSA/ICdyZCcgOiAndGgnO1xuICAgICAgICAgICAgcmV0dXJuIG51bWJlciArIG91dHB1dDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gU2lkZSBlZmZlY3QgaW1wb3J0c1xuXG4gICAgaG9va3MubGFuZyA9IGRlcHJlY2F0ZSgnbW9tZW50LmxhbmcgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGUgaW5zdGVhZC4nLCBnZXRTZXRHbG9iYWxMb2NhbGUpO1xuICAgIGhvb2tzLmxhbmdEYXRhID0gZGVwcmVjYXRlKCdtb21lbnQubGFuZ0RhdGEgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGVEYXRhIGluc3RlYWQuJywgZ2V0TG9jYWxlKTtcblxuICAgIHZhciBtYXRoQWJzID0gTWF0aC5hYnM7XG5cbiAgICBmdW5jdGlvbiBhYnMgKCkge1xuICAgICAgICB2YXIgZGF0YSAgICAgICAgICAgPSB0aGlzLl9kYXRhO1xuXG4gICAgICAgIHRoaXMuX21pbGxpc2Vjb25kcyA9IG1hdGhBYnModGhpcy5fbWlsbGlzZWNvbmRzKTtcbiAgICAgICAgdGhpcy5fZGF5cyAgICAgICAgID0gbWF0aEFicyh0aGlzLl9kYXlzKTtcbiAgICAgICAgdGhpcy5fbW9udGhzICAgICAgID0gbWF0aEFicyh0aGlzLl9tb250aHMpO1xuXG4gICAgICAgIGRhdGEubWlsbGlzZWNvbmRzICA9IG1hdGhBYnMoZGF0YS5taWxsaXNlY29uZHMpO1xuICAgICAgICBkYXRhLnNlY29uZHMgICAgICAgPSBtYXRoQWJzKGRhdGEuc2Vjb25kcyk7XG4gICAgICAgIGRhdGEubWludXRlcyAgICAgICA9IG1hdGhBYnMoZGF0YS5taW51dGVzKTtcbiAgICAgICAgZGF0YS5ob3VycyAgICAgICAgID0gbWF0aEFicyhkYXRhLmhvdXJzKTtcbiAgICAgICAgZGF0YS5tb250aHMgICAgICAgID0gbWF0aEFicyhkYXRhLm1vbnRocyk7XG4gICAgICAgIGRhdGEueWVhcnMgICAgICAgICA9IG1hdGhBYnMoZGF0YS55ZWFycyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWRkU3VidHJhY3QkMSAoZHVyYXRpb24sIGlucHV0LCB2YWx1ZSwgZGlyZWN0aW9uKSB7XG4gICAgICAgIHZhciBvdGhlciA9IGNyZWF0ZUR1cmF0aW9uKGlucHV0LCB2YWx1ZSk7XG5cbiAgICAgICAgZHVyYXRpb24uX21pbGxpc2Vjb25kcyArPSBkaXJlY3Rpb24gKiBvdGhlci5fbWlsbGlzZWNvbmRzO1xuICAgICAgICBkdXJhdGlvbi5fZGF5cyAgICAgICAgICs9IGRpcmVjdGlvbiAqIG90aGVyLl9kYXlzO1xuICAgICAgICBkdXJhdGlvbi5fbW9udGhzICAgICAgICs9IGRpcmVjdGlvbiAqIG90aGVyLl9tb250aHM7XG5cbiAgICAgICAgcmV0dXJuIGR1cmF0aW9uLl9idWJibGUoKTtcbiAgICB9XG5cbiAgICAvLyBzdXBwb3J0cyBvbmx5IDIuMC1zdHlsZSBhZGQoMSwgJ3MnKSBvciBhZGQoZHVyYXRpb24pXG4gICAgZnVuY3Rpb24gYWRkJDEgKGlucHV0LCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gYWRkU3VidHJhY3QkMSh0aGlzLCBpbnB1dCwgdmFsdWUsIDEpO1xuICAgIH1cblxuICAgIC8vIHN1cHBvcnRzIG9ubHkgMi4wLXN0eWxlIHN1YnRyYWN0KDEsICdzJykgb3Igc3VidHJhY3QoZHVyYXRpb24pXG4gICAgZnVuY3Rpb24gc3VidHJhY3QkMSAoaW5wdXQsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBhZGRTdWJ0cmFjdCQxKHRoaXMsIGlucHV0LCB2YWx1ZSwgLTEpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFic0NlaWwgKG51bWJlcikge1xuICAgICAgICBpZiAobnVtYmVyIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IobnVtYmVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmNlaWwobnVtYmVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJ1YmJsZSAoKSB7XG4gICAgICAgIHZhciBtaWxsaXNlY29uZHMgPSB0aGlzLl9taWxsaXNlY29uZHM7XG4gICAgICAgIHZhciBkYXlzICAgICAgICAgPSB0aGlzLl9kYXlzO1xuICAgICAgICB2YXIgbW9udGhzICAgICAgID0gdGhpcy5fbW9udGhzO1xuICAgICAgICB2YXIgZGF0YSAgICAgICAgID0gdGhpcy5fZGF0YTtcbiAgICAgICAgdmFyIHNlY29uZHMsIG1pbnV0ZXMsIGhvdXJzLCB5ZWFycywgbW9udGhzRnJvbURheXM7XG5cbiAgICAgICAgLy8gaWYgd2UgaGF2ZSBhIG1peCBvZiBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgdmFsdWVzLCBidWJibGUgZG93biBmaXJzdFxuICAgICAgICAvLyBjaGVjazogaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzIxNjZcbiAgICAgICAgaWYgKCEoKG1pbGxpc2Vjb25kcyA+PSAwICYmIGRheXMgPj0gMCAmJiBtb250aHMgPj0gMCkgfHxcbiAgICAgICAgICAgICAgICAobWlsbGlzZWNvbmRzIDw9IDAgJiYgZGF5cyA8PSAwICYmIG1vbnRocyA8PSAwKSkpIHtcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kcyArPSBhYnNDZWlsKG1vbnRoc1RvRGF5cyhtb250aHMpICsgZGF5cykgKiA4NjRlNTtcbiAgICAgICAgICAgIGRheXMgPSAwO1xuICAgICAgICAgICAgbW9udGhzID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgY29kZSBidWJibGVzIHVwIHZhbHVlcywgc2VlIHRoZSB0ZXN0cyBmb3JcbiAgICAgICAgLy8gZXhhbXBsZXMgb2Ygd2hhdCB0aGF0IG1lYW5zLlxuICAgICAgICBkYXRhLm1pbGxpc2Vjb25kcyA9IG1pbGxpc2Vjb25kcyAlIDEwMDA7XG5cbiAgICAgICAgc2Vjb25kcyAgICAgICAgICAgPSBhYnNGbG9vcihtaWxsaXNlY29uZHMgLyAxMDAwKTtcbiAgICAgICAgZGF0YS5zZWNvbmRzICAgICAgPSBzZWNvbmRzICUgNjA7XG5cbiAgICAgICAgbWludXRlcyAgICAgICAgICAgPSBhYnNGbG9vcihzZWNvbmRzIC8gNjApO1xuICAgICAgICBkYXRhLm1pbnV0ZXMgICAgICA9IG1pbnV0ZXMgJSA2MDtcblxuICAgICAgICBob3VycyAgICAgICAgICAgICA9IGFic0Zsb29yKG1pbnV0ZXMgLyA2MCk7XG4gICAgICAgIGRhdGEuaG91cnMgICAgICAgID0gaG91cnMgJSAyNDtcblxuICAgICAgICBkYXlzICs9IGFic0Zsb29yKGhvdXJzIC8gMjQpO1xuXG4gICAgICAgIC8vIGNvbnZlcnQgZGF5cyB0byBtb250aHNcbiAgICAgICAgbW9udGhzRnJvbURheXMgPSBhYnNGbG9vcihkYXlzVG9Nb250aHMoZGF5cykpO1xuICAgICAgICBtb250aHMgKz0gbW9udGhzRnJvbURheXM7XG4gICAgICAgIGRheXMgLT0gYWJzQ2VpbChtb250aHNUb0RheXMobW9udGhzRnJvbURheXMpKTtcblxuICAgICAgICAvLyAxMiBtb250aHMgLT4gMSB5ZWFyXG4gICAgICAgIHllYXJzID0gYWJzRmxvb3IobW9udGhzIC8gMTIpO1xuICAgICAgICBtb250aHMgJT0gMTI7XG5cbiAgICAgICAgZGF0YS5kYXlzICAgPSBkYXlzO1xuICAgICAgICBkYXRhLm1vbnRocyA9IG1vbnRocztcbiAgICAgICAgZGF0YS55ZWFycyAgPSB5ZWFycztcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlzVG9Nb250aHMgKGRheXMpIHtcbiAgICAgICAgLy8gNDAwIHllYXJzIGhhdmUgMTQ2MDk3IGRheXMgKHRha2luZyBpbnRvIGFjY291bnQgbGVhcCB5ZWFyIHJ1bGVzKVxuICAgICAgICAvLyA0MDAgeWVhcnMgaGF2ZSAxMiBtb250aHMgPT09IDQ4MDBcbiAgICAgICAgcmV0dXJuIGRheXMgKiA0ODAwIC8gMTQ2MDk3O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1vbnRoc1RvRGF5cyAobW9udGhzKSB7XG4gICAgICAgIC8vIHRoZSByZXZlcnNlIG9mIGRheXNUb01vbnRoc1xuICAgICAgICByZXR1cm4gbW9udGhzICogMTQ2MDk3IC8gNDgwMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhcyAodW5pdHMpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIE5hTjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGF5cztcbiAgICAgICAgdmFyIG1vbnRocztcbiAgICAgICAgdmFyIG1pbGxpc2Vjb25kcyA9IHRoaXMuX21pbGxpc2Vjb25kcztcblxuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICBpZiAodW5pdHMgPT09ICdtb250aCcgfHwgdW5pdHMgPT09ICdxdWFydGVyJyB8fCB1bml0cyA9PT0gJ3llYXInKSB7XG4gICAgICAgICAgICBkYXlzID0gdGhpcy5fZGF5cyArIG1pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgbW9udGhzID0gdGhpcy5fbW9udGhzICsgZGF5c1RvTW9udGhzKGRheXMpO1xuICAgICAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgICAgIGNhc2UgJ21vbnRoJzogICByZXR1cm4gbW9udGhzO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3F1YXJ0ZXInOiByZXR1cm4gbW9udGhzIC8gMztcbiAgICAgICAgICAgICAgICBjYXNlICd5ZWFyJzogICAgcmV0dXJuIG1vbnRocyAvIDEyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaGFuZGxlIG1pbGxpc2Vjb25kcyBzZXBhcmF0ZWx5IGJlY2F1c2Ugb2YgZmxvYXRpbmcgcG9pbnQgbWF0aCBlcnJvcnMgKGlzc3VlICMxODY3KVxuICAgICAgICAgICAgZGF5cyA9IHRoaXMuX2RheXMgKyBNYXRoLnJvdW5kKG1vbnRoc1RvRGF5cyh0aGlzLl9tb250aHMpKTtcbiAgICAgICAgICAgIHN3aXRjaCAodW5pdHMpIHtcbiAgICAgICAgICAgICAgICBjYXNlICd3ZWVrJyAgIDogcmV0dXJuIGRheXMgLyA3ICAgICArIG1pbGxpc2Vjb25kcyAvIDYwNDhlNTtcbiAgICAgICAgICAgICAgICBjYXNlICdkYXknICAgIDogcmV0dXJuIGRheXMgICAgICAgICArIG1pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgICAgIGNhc2UgJ2hvdXInICAgOiByZXR1cm4gZGF5cyAqIDI0ICAgICsgbWlsbGlzZWNvbmRzIC8gMzZlNTtcbiAgICAgICAgICAgICAgICBjYXNlICdtaW51dGUnIDogcmV0dXJuIGRheXMgKiAxNDQwICArIG1pbGxpc2Vjb25kcyAvIDZlNDtcbiAgICAgICAgICAgICAgICBjYXNlICdzZWNvbmQnIDogcmV0dXJuIGRheXMgKiA4NjQwMCArIG1pbGxpc2Vjb25kcyAvIDEwMDA7XG4gICAgICAgICAgICAgICAgLy8gTWF0aC5mbG9vciBwcmV2ZW50cyBmbG9hdGluZyBwb2ludCBtYXRoIGVycm9ycyBoZXJlXG4gICAgICAgICAgICAgICAgY2FzZSAnbWlsbGlzZWNvbmQnOiByZXR1cm4gTWF0aC5mbG9vcihkYXlzICogODY0ZTUpICsgbWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcignVW5rbm93biB1bml0ICcgKyB1bml0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPOiBVc2UgdGhpcy5hcygnbXMnKT9cbiAgICBmdW5jdGlvbiB2YWx1ZU9mJDEgKCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICByZXR1cm4gTmFOO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgK1xuICAgICAgICAgICAgdGhpcy5fZGF5cyAqIDg2NGU1ICtcbiAgICAgICAgICAgICh0aGlzLl9tb250aHMgJSAxMikgKiAyNTkyZTYgK1xuICAgICAgICAgICAgdG9JbnQodGhpcy5fbW9udGhzIC8gMTIpICogMzE1MzZlNlxuICAgICAgICApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VBcyAoYWxpYXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFzKGFsaWFzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgYXNNaWxsaXNlY29uZHMgPSBtYWtlQXMoJ21zJyk7XG4gICAgdmFyIGFzU2Vjb25kcyAgICAgID0gbWFrZUFzKCdzJyk7XG4gICAgdmFyIGFzTWludXRlcyAgICAgID0gbWFrZUFzKCdtJyk7XG4gICAgdmFyIGFzSG91cnMgICAgICAgID0gbWFrZUFzKCdoJyk7XG4gICAgdmFyIGFzRGF5cyAgICAgICAgID0gbWFrZUFzKCdkJyk7XG4gICAgdmFyIGFzV2Vla3MgICAgICAgID0gbWFrZUFzKCd3Jyk7XG4gICAgdmFyIGFzTW9udGhzICAgICAgID0gbWFrZUFzKCdNJyk7XG4gICAgdmFyIGFzUXVhcnRlcnMgICAgID0gbWFrZUFzKCdRJyk7XG4gICAgdmFyIGFzWWVhcnMgICAgICAgID0gbWFrZUFzKCd5Jyk7XG5cbiAgICBmdW5jdGlvbiBjbG9uZSQxICgpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKHRoaXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldCQyICh1bml0cykge1xuICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpc1t1bml0cyArICdzJ10oKSA6IE5hTjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlR2V0dGVyKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmlzVmFsaWQoKSA/IHRoaXMuX2RhdGFbbmFtZV0gOiBOYU47XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIG1pbGxpc2Vjb25kcyA9IG1ha2VHZXR0ZXIoJ21pbGxpc2Vjb25kcycpO1xuICAgIHZhciBzZWNvbmRzICAgICAgPSBtYWtlR2V0dGVyKCdzZWNvbmRzJyk7XG4gICAgdmFyIG1pbnV0ZXMgICAgICA9IG1ha2VHZXR0ZXIoJ21pbnV0ZXMnKTtcbiAgICB2YXIgaG91cnMgICAgICAgID0gbWFrZUdldHRlcignaG91cnMnKTtcbiAgICB2YXIgZGF5cyAgICAgICAgID0gbWFrZUdldHRlcignZGF5cycpO1xuICAgIHZhciBtb250aHMgICAgICAgPSBtYWtlR2V0dGVyKCdtb250aHMnKTtcbiAgICB2YXIgeWVhcnMgICAgICAgID0gbWFrZUdldHRlcigneWVhcnMnKTtcblxuICAgIGZ1bmN0aW9uIHdlZWtzICgpIHtcbiAgICAgICAgcmV0dXJuIGFic0Zsb29yKHRoaXMuZGF5cygpIC8gNyk7XG4gICAgfVxuXG4gICAgdmFyIHJvdW5kID0gTWF0aC5yb3VuZDtcbiAgICB2YXIgdGhyZXNob2xkcyA9IHtcbiAgICAgICAgc3M6IDQ0LCAgICAgICAgIC8vIGEgZmV3IHNlY29uZHMgdG8gc2Vjb25kc1xuICAgICAgICBzIDogNDUsICAgICAgICAgLy8gc2Vjb25kcyB0byBtaW51dGVcbiAgICAgICAgbSA6IDQ1LCAgICAgICAgIC8vIG1pbnV0ZXMgdG8gaG91clxuICAgICAgICBoIDogMjIsICAgICAgICAgLy8gaG91cnMgdG8gZGF5XG4gICAgICAgIGQgOiAyNiwgICAgICAgICAvLyBkYXlzIHRvIG1vbnRoXG4gICAgICAgIE0gOiAxMSAgICAgICAgICAvLyBtb250aHMgdG8geWVhclxuICAgIH07XG5cbiAgICAvLyBoZWxwZXIgZnVuY3Rpb24gZm9yIG1vbWVudC5mbi5mcm9tLCBtb21lbnQuZm4uZnJvbU5vdywgYW5kIG1vbWVudC5kdXJhdGlvbi5mbi5odW1hbml6ZVxuICAgIGZ1bmN0aW9uIHN1YnN0aXR1dGVUaW1lQWdvKHN0cmluZywgbnVtYmVyLCB3aXRob3V0U3VmZml4LCBpc0Z1dHVyZSwgbG9jYWxlKSB7XG4gICAgICAgIHJldHVybiBsb2NhbGUucmVsYXRpdmVUaW1lKG51bWJlciB8fCAxLCAhIXdpdGhvdXRTdWZmaXgsIHN0cmluZywgaXNGdXR1cmUpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbGF0aXZlVGltZSQxIChwb3NOZWdEdXJhdGlvbiwgd2l0aG91dFN1ZmZpeCwgbG9jYWxlKSB7XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IGNyZWF0ZUR1cmF0aW9uKHBvc05lZ0R1cmF0aW9uKS5hYnMoKTtcbiAgICAgICAgdmFyIHNlY29uZHMgID0gcm91bmQoZHVyYXRpb24uYXMoJ3MnKSk7XG4gICAgICAgIHZhciBtaW51dGVzICA9IHJvdW5kKGR1cmF0aW9uLmFzKCdtJykpO1xuICAgICAgICB2YXIgaG91cnMgICAgPSByb3VuZChkdXJhdGlvbi5hcygnaCcpKTtcbiAgICAgICAgdmFyIGRheXMgICAgID0gcm91bmQoZHVyYXRpb24uYXMoJ2QnKSk7XG4gICAgICAgIHZhciBtb250aHMgICA9IHJvdW5kKGR1cmF0aW9uLmFzKCdNJykpO1xuICAgICAgICB2YXIgeWVhcnMgICAgPSByb3VuZChkdXJhdGlvbi5hcygneScpKTtcblxuICAgICAgICB2YXIgYSA9IHNlY29uZHMgPD0gdGhyZXNob2xkcy5zcyAmJiBbJ3MnLCBzZWNvbmRzXSAgfHxcbiAgICAgICAgICAgICAgICBzZWNvbmRzIDwgdGhyZXNob2xkcy5zICAgJiYgWydzcycsIHNlY29uZHNdIHx8XG4gICAgICAgICAgICAgICAgbWludXRlcyA8PSAxICAgICAgICAgICAgICYmIFsnbSddICAgICAgICAgICB8fFxuICAgICAgICAgICAgICAgIG1pbnV0ZXMgPCB0aHJlc2hvbGRzLm0gICAmJiBbJ21tJywgbWludXRlc10gfHxcbiAgICAgICAgICAgICAgICBob3VycyAgIDw9IDEgICAgICAgICAgICAgJiYgWydoJ10gICAgICAgICAgIHx8XG4gICAgICAgICAgICAgICAgaG91cnMgICA8IHRocmVzaG9sZHMuaCAgICYmIFsnaGgnLCBob3Vyc10gICB8fFxuICAgICAgICAgICAgICAgIGRheXMgICAgPD0gMSAgICAgICAgICAgICAmJiBbJ2QnXSAgICAgICAgICAgfHxcbiAgICAgICAgICAgICAgICBkYXlzICAgIDwgdGhyZXNob2xkcy5kICAgJiYgWydkZCcsIGRheXNdICAgIHx8XG4gICAgICAgICAgICAgICAgbW9udGhzICA8PSAxICAgICAgICAgICAgICYmIFsnTSddICAgICAgICAgICB8fFxuICAgICAgICAgICAgICAgIG1vbnRocyAgPCB0aHJlc2hvbGRzLk0gICAmJiBbJ01NJywgbW9udGhzXSAgfHxcbiAgICAgICAgICAgICAgICB5ZWFycyAgIDw9IDEgICAgICAgICAgICAgJiYgWyd5J10gICAgICAgICAgIHx8IFsneXknLCB5ZWFyc107XG5cbiAgICAgICAgYVsyXSA9IHdpdGhvdXRTdWZmaXg7XG4gICAgICAgIGFbM10gPSArcG9zTmVnRHVyYXRpb24gPiAwO1xuICAgICAgICBhWzRdID0gbG9jYWxlO1xuICAgICAgICByZXR1cm4gc3Vic3RpdHV0ZVRpbWVBZ28uYXBwbHkobnVsbCwgYSk7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHNldCB0aGUgcm91bmRpbmcgZnVuY3Rpb24gZm9yIHJlbGF0aXZlIHRpbWUgc3RyaW5nc1xuICAgIGZ1bmN0aW9uIGdldFNldFJlbGF0aXZlVGltZVJvdW5kaW5nIChyb3VuZGluZ0Z1bmN0aW9uKSB7XG4gICAgICAgIGlmIChyb3VuZGluZ0Z1bmN0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiByb3VuZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mKHJvdW5kaW5nRnVuY3Rpb24pID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByb3VuZCA9IHJvdW5kaW5nRnVuY3Rpb247XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHNldCBhIHRocmVzaG9sZCBmb3IgcmVsYXRpdmUgdGltZSBzdHJpbmdzXG4gICAgZnVuY3Rpb24gZ2V0U2V0UmVsYXRpdmVUaW1lVGhyZXNob2xkICh0aHJlc2hvbGQsIGxpbWl0KSB7XG4gICAgICAgIGlmICh0aHJlc2hvbGRzW3RocmVzaG9sZF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW1pdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhyZXNob2xkc1t0aHJlc2hvbGRdO1xuICAgICAgICB9XG4gICAgICAgIHRocmVzaG9sZHNbdGhyZXNob2xkXSA9IGxpbWl0O1xuICAgICAgICBpZiAodGhyZXNob2xkID09PSAncycpIHtcbiAgICAgICAgICAgIHRocmVzaG9sZHMuc3MgPSBsaW1pdCAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaHVtYW5pemUgKHdpdGhTdWZmaXgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLmludmFsaWREYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbG9jYWxlID0gdGhpcy5sb2NhbGVEYXRhKCk7XG4gICAgICAgIHZhciBvdXRwdXQgPSByZWxhdGl2ZVRpbWUkMSh0aGlzLCAhd2l0aFN1ZmZpeCwgbG9jYWxlKTtcblxuICAgICAgICBpZiAod2l0aFN1ZmZpeCkge1xuICAgICAgICAgICAgb3V0cHV0ID0gbG9jYWxlLnBhc3RGdXR1cmUoK3RoaXMsIG91dHB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbG9jYWxlLnBvc3Rmb3JtYXQob3V0cHV0KTtcbiAgICB9XG5cbiAgICB2YXIgYWJzJDEgPSBNYXRoLmFicztcblxuICAgIGZ1bmN0aW9uIHNpZ24oeCkge1xuICAgICAgICByZXR1cm4gKCh4ID4gMCkgLSAoeCA8IDApKSB8fCAreDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0lTT1N0cmluZyQxKCkge1xuICAgICAgICAvLyBmb3IgSVNPIHN0cmluZ3Mgd2UgZG8gbm90IHVzZSB0aGUgbm9ybWFsIGJ1YmJsaW5nIHJ1bGVzOlxuICAgICAgICAvLyAgKiBtaWxsaXNlY29uZHMgYnViYmxlIHVwIHVudGlsIHRoZXkgYmVjb21lIGhvdXJzXG4gICAgICAgIC8vICAqIGRheXMgZG8gbm90IGJ1YmJsZSBhdCBhbGxcbiAgICAgICAgLy8gICogbW9udGhzIGJ1YmJsZSB1cCB1bnRpbCB0aGV5IGJlY29tZSB5ZWFyc1xuICAgICAgICAvLyBUaGlzIGlzIGJlY2F1c2UgdGhlcmUgaXMgbm8gY29udGV4dC1mcmVlIGNvbnZlcnNpb24gYmV0d2VlbiBob3VycyBhbmQgZGF5c1xuICAgICAgICAvLyAodGhpbmsgb2YgY2xvY2sgY2hhbmdlcylcbiAgICAgICAgLy8gYW5kIGFsc28gbm90IGJldHdlZW4gZGF5cyBhbmQgbW9udGhzICgyOC0zMSBkYXlzIHBlciBtb250aClcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLmludmFsaWREYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc2Vjb25kcyA9IGFicyQxKHRoaXMuX21pbGxpc2Vjb25kcykgLyAxMDAwO1xuICAgICAgICB2YXIgZGF5cyAgICAgICAgID0gYWJzJDEodGhpcy5fZGF5cyk7XG4gICAgICAgIHZhciBtb250aHMgICAgICAgPSBhYnMkMSh0aGlzLl9tb250aHMpO1xuICAgICAgICB2YXIgbWludXRlcywgaG91cnMsIHllYXJzO1xuXG4gICAgICAgIC8vIDM2MDAgc2Vjb25kcyAtPiA2MCBtaW51dGVzIC0+IDEgaG91clxuICAgICAgICBtaW51dGVzICAgICAgICAgICA9IGFic0Zsb29yKHNlY29uZHMgLyA2MCk7XG4gICAgICAgIGhvdXJzICAgICAgICAgICAgID0gYWJzRmxvb3IobWludXRlcyAvIDYwKTtcbiAgICAgICAgc2Vjb25kcyAlPSA2MDtcbiAgICAgICAgbWludXRlcyAlPSA2MDtcblxuICAgICAgICAvLyAxMiBtb250aHMgLT4gMSB5ZWFyXG4gICAgICAgIHllYXJzICA9IGFic0Zsb29yKG1vbnRocyAvIDEyKTtcbiAgICAgICAgbW9udGhzICU9IDEyO1xuXG5cbiAgICAgICAgLy8gaW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2RvcmRpbGxlL21vbWVudC1pc29kdXJhdGlvbi9ibG9iL21hc3Rlci9tb21lbnQuaXNvZHVyYXRpb24uanNcbiAgICAgICAgdmFyIFkgPSB5ZWFycztcbiAgICAgICAgdmFyIE0gPSBtb250aHM7XG4gICAgICAgIHZhciBEID0gZGF5cztcbiAgICAgICAgdmFyIGggPSBob3VycztcbiAgICAgICAgdmFyIG0gPSBtaW51dGVzO1xuICAgICAgICB2YXIgcyA9IHNlY29uZHMgPyBzZWNvbmRzLnRvRml4ZWQoMykucmVwbGFjZSgvXFwuPzArJC8sICcnKSA6ICcnO1xuICAgICAgICB2YXIgdG90YWwgPSB0aGlzLmFzU2Vjb25kcygpO1xuXG4gICAgICAgIGlmICghdG90YWwpIHtcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgdGhlIHNhbWUgYXMgQyMncyAoTm9kYSkgYW5kIHB5dGhvbiAoaXNvZGF0ZSkuLi5cbiAgICAgICAgICAgIC8vIGJ1dCBub3Qgb3RoZXIgSlMgKGdvb2cuZGF0ZSlcbiAgICAgICAgICAgIHJldHVybiAnUDBEJztcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0b3RhbFNpZ24gPSB0b3RhbCA8IDAgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIHltU2lnbiA9IHNpZ24odGhpcy5fbW9udGhzKSAhPT0gc2lnbih0b3RhbCkgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIGRheXNTaWduID0gc2lnbih0aGlzLl9kYXlzKSAhPT0gc2lnbih0b3RhbCkgPyAnLScgOiAnJztcbiAgICAgICAgdmFyIGhtc1NpZ24gPSBzaWduKHRoaXMuX21pbGxpc2Vjb25kcykgIT09IHNpZ24odG90YWwpID8gJy0nIDogJyc7XG5cbiAgICAgICAgcmV0dXJuIHRvdGFsU2lnbiArICdQJyArXG4gICAgICAgICAgICAoWSA/IHltU2lnbiArIFkgKyAnWScgOiAnJykgK1xuICAgICAgICAgICAgKE0gPyB5bVNpZ24gKyBNICsgJ00nIDogJycpICtcbiAgICAgICAgICAgIChEID8gZGF5c1NpZ24gKyBEICsgJ0QnIDogJycpICtcbiAgICAgICAgICAgICgoaCB8fCBtIHx8IHMpID8gJ1QnIDogJycpICtcbiAgICAgICAgICAgIChoID8gaG1zU2lnbiArIGggKyAnSCcgOiAnJykgK1xuICAgICAgICAgICAgKG0gPyBobXNTaWduICsgbSArICdNJyA6ICcnKSArXG4gICAgICAgICAgICAocyA/IGhtc1NpZ24gKyBzICsgJ1MnIDogJycpO1xuICAgIH1cblxuICAgIHZhciBwcm90byQyID0gRHVyYXRpb24ucHJvdG90eXBlO1xuXG4gICAgcHJvdG8kMi5pc1ZhbGlkICAgICAgICA9IGlzVmFsaWQkMTtcbiAgICBwcm90byQyLmFicyAgICAgICAgICAgID0gYWJzO1xuICAgIHByb3RvJDIuYWRkICAgICAgICAgICAgPSBhZGQkMTtcbiAgICBwcm90byQyLnN1YnRyYWN0ICAgICAgID0gc3VidHJhY3QkMTtcbiAgICBwcm90byQyLmFzICAgICAgICAgICAgID0gYXM7XG4gICAgcHJvdG8kMi5hc01pbGxpc2Vjb25kcyA9IGFzTWlsbGlzZWNvbmRzO1xuICAgIHByb3RvJDIuYXNTZWNvbmRzICAgICAgPSBhc1NlY29uZHM7XG4gICAgcHJvdG8kMi5hc01pbnV0ZXMgICAgICA9IGFzTWludXRlcztcbiAgICBwcm90byQyLmFzSG91cnMgICAgICAgID0gYXNIb3VycztcbiAgICBwcm90byQyLmFzRGF5cyAgICAgICAgID0gYXNEYXlzO1xuICAgIHByb3RvJDIuYXNXZWVrcyAgICAgICAgPSBhc1dlZWtzO1xuICAgIHByb3RvJDIuYXNNb250aHMgICAgICAgPSBhc01vbnRocztcbiAgICBwcm90byQyLmFzUXVhcnRlcnMgICAgID0gYXNRdWFydGVycztcbiAgICBwcm90byQyLmFzWWVhcnMgICAgICAgID0gYXNZZWFycztcbiAgICBwcm90byQyLnZhbHVlT2YgICAgICAgID0gdmFsdWVPZiQxO1xuICAgIHByb3RvJDIuX2J1YmJsZSAgICAgICAgPSBidWJibGU7XG4gICAgcHJvdG8kMi5jbG9uZSAgICAgICAgICA9IGNsb25lJDE7XG4gICAgcHJvdG8kMi5nZXQgICAgICAgICAgICA9IGdldCQyO1xuICAgIHByb3RvJDIubWlsbGlzZWNvbmRzICAgPSBtaWxsaXNlY29uZHM7XG4gICAgcHJvdG8kMi5zZWNvbmRzICAgICAgICA9IHNlY29uZHM7XG4gICAgcHJvdG8kMi5taW51dGVzICAgICAgICA9IG1pbnV0ZXM7XG4gICAgcHJvdG8kMi5ob3VycyAgICAgICAgICA9IGhvdXJzO1xuICAgIHByb3RvJDIuZGF5cyAgICAgICAgICAgPSBkYXlzO1xuICAgIHByb3RvJDIud2Vla3MgICAgICAgICAgPSB3ZWVrcztcbiAgICBwcm90byQyLm1vbnRocyAgICAgICAgID0gbW9udGhzO1xuICAgIHByb3RvJDIueWVhcnMgICAgICAgICAgPSB5ZWFycztcbiAgICBwcm90byQyLmh1bWFuaXplICAgICAgID0gaHVtYW5pemU7XG4gICAgcHJvdG8kMi50b0lTT1N0cmluZyAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi50b1N0cmluZyAgICAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi50b0pTT04gICAgICAgICA9IHRvSVNPU3RyaW5nJDE7XG4gICAgcHJvdG8kMi5sb2NhbGUgICAgICAgICA9IGxvY2FsZTtcbiAgICBwcm90byQyLmxvY2FsZURhdGEgICAgID0gbG9jYWxlRGF0YTtcblxuICAgIHByb3RvJDIudG9Jc29TdHJpbmcgPSBkZXByZWNhdGUoJ3RvSXNvU3RyaW5nKCkgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSB0b0lTT1N0cmluZygpIGluc3RlYWQgKG5vdGljZSB0aGUgY2FwaXRhbHMpJywgdG9JU09TdHJpbmckMSk7XG4gICAgcHJvdG8kMi5sYW5nID0gbGFuZztcblxuICAgIC8vIFNpZGUgZWZmZWN0IGltcG9ydHNcblxuICAgIC8vIEZPUk1BVFRJTkdcblxuICAgIGFkZEZvcm1hdFRva2VuKCdYJywgMCwgMCwgJ3VuaXgnKTtcbiAgICBhZGRGb3JtYXRUb2tlbigneCcsIDAsIDAsICd2YWx1ZU9mJyk7XG5cbiAgICAvLyBQQVJTSU5HXG5cbiAgICBhZGRSZWdleFRva2VuKCd4JywgbWF0Y2hTaWduZWQpO1xuICAgIGFkZFJlZ2V4VG9rZW4oJ1gnLCBtYXRjaFRpbWVzdGFtcCk7XG4gICAgYWRkUGFyc2VUb2tlbignWCcsIGZ1bmN0aW9uIChpbnB1dCwgYXJyYXksIGNvbmZpZykge1xuICAgICAgICBjb25maWcuX2QgPSBuZXcgRGF0ZShwYXJzZUZsb2F0KGlucHV0LCAxMCkgKiAxMDAwKTtcbiAgICB9KTtcbiAgICBhZGRQYXJzZVRva2VuKCd4JywgZnVuY3Rpb24gKGlucHV0LCBhcnJheSwgY29uZmlnKSB7XG4gICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKHRvSW50KGlucHV0KSk7XG4gICAgfSk7XG5cbiAgICAvLyBTaWRlIGVmZmVjdCBpbXBvcnRzXG5cblxuICAgIGhvb2tzLnZlcnNpb24gPSAnMi4yNC4wJztcblxuICAgIHNldEhvb2tDYWxsYmFjayhjcmVhdGVMb2NhbCk7XG5cbiAgICBob29rcy5mbiAgICAgICAgICAgICAgICAgICAgPSBwcm90bztcbiAgICBob29rcy5taW4gICAgICAgICAgICAgICAgICAgPSBtaW47XG4gICAgaG9va3MubWF4ICAgICAgICAgICAgICAgICAgID0gbWF4O1xuICAgIGhvb2tzLm5vdyAgICAgICAgICAgICAgICAgICA9IG5vdztcbiAgICBob29rcy51dGMgICAgICAgICAgICAgICAgICAgPSBjcmVhdGVVVEM7XG4gICAgaG9va3MudW5peCAgICAgICAgICAgICAgICAgID0gY3JlYXRlVW5peDtcbiAgICBob29rcy5tb250aHMgICAgICAgICAgICAgICAgPSBsaXN0TW9udGhzO1xuICAgIGhvb2tzLmlzRGF0ZSAgICAgICAgICAgICAgICA9IGlzRGF0ZTtcbiAgICBob29rcy5sb2NhbGUgICAgICAgICAgICAgICAgPSBnZXRTZXRHbG9iYWxMb2NhbGU7XG4gICAgaG9va3MuaW52YWxpZCAgICAgICAgICAgICAgID0gY3JlYXRlSW52YWxpZDtcbiAgICBob29rcy5kdXJhdGlvbiAgICAgICAgICAgICAgPSBjcmVhdGVEdXJhdGlvbjtcbiAgICBob29rcy5pc01vbWVudCAgICAgICAgICAgICAgPSBpc01vbWVudDtcbiAgICBob29rcy53ZWVrZGF5cyAgICAgICAgICAgICAgPSBsaXN0V2Vla2RheXM7XG4gICAgaG9va3MucGFyc2Vab25lICAgICAgICAgICAgID0gY3JlYXRlSW5ab25lO1xuICAgIGhvb2tzLmxvY2FsZURhdGEgICAgICAgICAgICA9IGdldExvY2FsZTtcbiAgICBob29rcy5pc0R1cmF0aW9uICAgICAgICAgICAgPSBpc0R1cmF0aW9uO1xuICAgIGhvb2tzLm1vbnRoc1Nob3J0ICAgICAgICAgICA9IGxpc3RNb250aHNTaG9ydDtcbiAgICBob29rcy53ZWVrZGF5c01pbiAgICAgICAgICAgPSBsaXN0V2Vla2RheXNNaW47XG4gICAgaG9va3MuZGVmaW5lTG9jYWxlICAgICAgICAgID0gZGVmaW5lTG9jYWxlO1xuICAgIGhvb2tzLnVwZGF0ZUxvY2FsZSAgICAgICAgICA9IHVwZGF0ZUxvY2FsZTtcbiAgICBob29rcy5sb2NhbGVzICAgICAgICAgICAgICAgPSBsaXN0TG9jYWxlcztcbiAgICBob29rcy53ZWVrZGF5c1Nob3J0ICAgICAgICAgPSBsaXN0V2Vla2RheXNTaG9ydDtcbiAgICBob29rcy5ub3JtYWxpemVVbml0cyAgICAgICAgPSBub3JtYWxpemVVbml0cztcbiAgICBob29rcy5yZWxhdGl2ZVRpbWVSb3VuZGluZyAgPSBnZXRTZXRSZWxhdGl2ZVRpbWVSb3VuZGluZztcbiAgICBob29rcy5yZWxhdGl2ZVRpbWVUaHJlc2hvbGQgPSBnZXRTZXRSZWxhdGl2ZVRpbWVUaHJlc2hvbGQ7XG4gICAgaG9va3MuY2FsZW5kYXJGb3JtYXQgICAgICAgID0gZ2V0Q2FsZW5kYXJGb3JtYXQ7XG4gICAgaG9va3MucHJvdG90eXBlICAgICAgICAgICAgID0gcHJvdG87XG5cbiAgICAvLyBjdXJyZW50bHkgSFRNTDUgaW5wdXQgdHlwZSBvbmx5IHN1cHBvcnRzIDI0LWhvdXIgZm9ybWF0c1xuICAgIGhvb2tzLkhUTUw1X0ZNVCA9IHtcbiAgICAgICAgREFURVRJTUVfTE9DQUw6ICdZWVlZLU1NLUREVEhIOm1tJywgICAgICAgICAgICAgLy8gPGlucHV0IHR5cGU9XCJkYXRldGltZS1sb2NhbFwiIC8+XG4gICAgICAgIERBVEVUSU1FX0xPQ0FMX1NFQ09ORFM6ICdZWVlZLU1NLUREVEhIOm1tOnNzJywgIC8vIDxpbnB1dCB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIiBzdGVwPVwiMVwiIC8+XG4gICAgICAgIERBVEVUSU1FX0xPQ0FMX01TOiAnWVlZWS1NTS1ERFRISDptbTpzcy5TU1MnLCAgIC8vIDxpbnB1dCB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIiBzdGVwPVwiMC4wMDFcIiAvPlxuICAgICAgICBEQVRFOiAnWVlZWS1NTS1ERCcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cImRhdGVcIiAvPlxuICAgICAgICBUSU1FOiAnSEg6bW0nLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cInRpbWVcIiAvPlxuICAgICAgICBUSU1FX1NFQ09ORFM6ICdISDptbTpzcycsICAgICAgICAgICAgICAgICAgICAgICAvLyA8aW5wdXQgdHlwZT1cInRpbWVcIiBzdGVwPVwiMVwiIC8+XG4gICAgICAgIFRJTUVfTVM6ICdISDptbTpzcy5TU1MnLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwidGltZVwiIHN0ZXA9XCIwLjAwMVwiIC8+XG4gICAgICAgIFdFRUs6ICdHR0dHLVtXXVdXJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwid2Vla1wiIC8+XG4gICAgICAgIE1PTlRIOiAnWVlZWS1NTScgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDxpbnB1dCB0eXBlPVwibW9udGhcIiAvPlxuICAgIH07XG5cbiAgICByZXR1cm4gaG9va3M7XG5cbn0pKSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///da01\n")}}]);

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.buffer"],{"3be6":function(module,exports,__webpack_require__){"use strict";eval("/* WEBPACK VAR INJECTION */(function(global) {/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n\n\nvar base64 = __webpack_require__(/*! base64-js */ \"9711\")\nvar ieee754 = __webpack_require__(/*! ieee754 */ \"4a62\")\nvar isArray = __webpack_require__(/*! isarray */ \"5b56\")\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiM2JlNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanM/YjYzOSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuXG4ndXNlIHN0cmljdCdcblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUICE9PSB1bmRlZmluZWRcbiAgPyBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVFxuICA6IHR5cGVkQXJyYXlTdXBwb3J0KClcblxuLypcbiAqIEV4cG9ydCBrTWF4TGVuZ3RoIGFmdGVyIHR5cGVkIGFycmF5IHN1cHBvcnQgaXMgZGV0ZXJtaW5lZC5cbiAqL1xuZXhwb3J0cy5rTWF4TGVuZ3RoID0ga01heExlbmd0aCgpXG5cbmZ1bmN0aW9uIHR5cGVkQXJyYXlTdXBwb3J0ICgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuX19wcm90b19fID0ge19fcHJvdG9fXzogVWludDhBcnJheS5wcm90b3R5cGUsIGZvbzogZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfX1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MiAmJiAvLyB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG5mdW5jdGlvbiBjcmVhdGVCdWZmZXIgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoa01heExlbmd0aCgpIDwgbGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgdHlwZWQgYXJyYXkgbGVuZ3RoJylcbiAgfVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICBpZiAodGhhdCA9PT0gbnVsbCkge1xuICAgICAgdGhhdCA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICAgIH1cbiAgICB0aGF0Lmxlbmd0aCA9IGxlbmd0aFxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGhhdmUgdGhlaXJcbiAqIHByb3RvdHlwZSBjaGFuZ2VkIHRvIGBCdWZmZXIucHJvdG90eXBlYC4gRnVydGhlcm1vcmUsIGBCdWZmZXJgIGlzIGEgc3ViY2xhc3Mgb2ZcbiAqIGBVaW50OEFycmF5YCwgc28gdGhlIHJldHVybmVkIGluc3RhbmNlcyB3aWxsIGhhdmUgYWxsIHRoZSBub2RlIGBCdWZmZXJgIG1ldGhvZHNcbiAqIGFuZCB0aGUgYFVpbnQ4QXJyYXlgIG1ldGhvZHMuIFNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0XG4gKiByZXR1cm5zIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIFRoZSBgVWludDhBcnJheWAgcHJvdG90eXBlIHJlbWFpbnMgdW5tb2RpZmllZC5cbiAqL1xuXG5mdW5jdGlvbiBCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0lmIGVuY29kaW5nIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUodGhpcywgYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKHRoaXMsIGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuLy8gVE9ETzogTGVnYWN5LCBub3QgbmVlZGVkIGFueW1vcmUuIFJlbW92ZSBpbiBuZXh0IG1ham9yIHZlcnNpb24uXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIGFyci5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gZnJvbSAodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldClcbiAgfVxuXG4gIHJldHVybiBmcm9tT2JqZWN0KHRoYXQsIHZhbHVlKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKG51bGwsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbmlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICBCdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG4gIEJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG4gIGlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAmJlxuICAgICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gICAgLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLCBTeW1ib2wuc3BlY2llcywge1xuICAgICAgdmFsdWU6IG51bGwsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9IGVsc2UgaWYgKHNpemUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG5lZ2F0aXZlJylcbiAgfVxufVxuXG5mdW5jdGlvbiBhbGxvYyAodGhhdCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxuICB9XG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPbmx5IHBheSBhdHRlbnRpb24gdG8gZW5jb2RpbmcgaWYgaXQncyBhIHN0cmluZy4gVGhpc1xuICAgIC8vIHByZXZlbnRzIGFjY2lkZW50YWxseSBzZW5kaW5nIGluIGEgbnVtYmVyIHRoYXQgd291bGRcbiAgICAvLyBiZSBpbnRlcnByZXR0ZWQgYXMgYSBzdGFydCBvZmZzZXQuXG4gICAgcmV0dXJuIHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZydcbiAgICAgID8gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgICA6IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKS5maWxsKGZpbGwpXG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIGFsbG9jKHNpemVbLCBmaWxsWywgZW5jb2RpbmddXSlcbiAqKi9cbkJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICByZXR1cm4gYWxsb2MobnVsbCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpXG59XG5cbmZ1bmN0aW9uIGFsbG9jVW5zYWZlICh0aGF0LCBzaXplKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplIDwgMCA/IDAgOiBjaGVja2VkKHNpemUpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7XG4gICAgICB0aGF0W2ldID0gMFxuICAgIH1cbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gQnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gU2xvd0J1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICovXG5CdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgfVxuXG4gIGlmICghQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJlbmNvZGluZ1wiIG11c3QgYmUgYSB2YWxpZCBzdHJpbmcgZW5jb2RpbmcnKVxuICB9XG5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuXG4gIHZhciBhY3R1YWwgPSB0aGF0LndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG5cbiAgaWYgKGFjdHVhbCAhPT0gbGVuZ3RoKSB7XG4gICAgLy8gV3JpdGluZyBhIGhleCBzdHJpbmcsIGZvciBleGFtcGxlLCB0aGF0IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVycyB3aWxsXG4gICAgLy8gY2F1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgZmlyc3QgaW52YWxpZCBjaGFyYWN0ZXIgdG8gYmUgaWdub3JlZC4gKGUuZy5cbiAgICAvLyAnYWJ4eGNkJyB3aWxsIGJlIHRyZWF0ZWQgYXMgJ2FiJylcbiAgICB0aGF0ID0gdGhhdC5zbGljZSgwLCBhY3R1YWwpXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyICh0aGF0LCBhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gIGFycmF5LmJ5dGVMZW5ndGggLy8gdGhpcyB0aHJvd3MgaWYgYGFycmF5YCBpcyBub3QgYSB2YWxpZCBBcnJheUJ1ZmZlclxuXG4gIGlmIChieXRlT2Zmc2V0IDwgMCB8fCBhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdvZmZzZXRcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQgKyAobGVuZ3RoIHx8IDApKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ2xlbmd0aFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChieXRlT2Zmc2V0ID09PSB1bmRlZmluZWQgJiYgbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5KVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldClcbiAgfSBlbHNlIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gYXJyYXlcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgdGhhdCA9IGZyb21BcnJheUxpa2UodGhhdCwgYXJyYXkpXG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbU9iamVjdCAodGhhdCwgb2JqKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIob2JqKSkge1xuICAgIHZhciBsZW4gPSBjaGVja2VkKG9iai5sZW5ndGgpIHwgMFxuICAgIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuKVxuXG4gICAgaWYgKHRoYXQubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdGhhdFxuICAgIH1cblxuICAgIG9iai5jb3B5KHRoYXQsIDAsIDAsIGxlbilcbiAgICByZXR1cm4gdGhhdFxuICB9XG5cbiAgaWYgKG9iaikge1xuICAgIGlmICgodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICBvYmouYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHx8ICdsZW5ndGgnIGluIG9iaikge1xuICAgICAgaWYgKHR5cGVvZiBvYmoubGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBpc25hbihvYmoubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIDApXG4gICAgICB9XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmopXG4gICAgfVxuXG4gICAgaWYgKG9iai50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iai5kYXRhKSkge1xuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCwgb2JqLmRhdGEpXG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LicpXG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBrTWF4TGVuZ3RoKClgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0ga01heExlbmd0aCgpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIGtNYXhMZW5ndGgoKS50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKCtsZW5ndGggIT0gbGVuZ3RoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG4gICAgbGVuZ3RoID0gMFxuICB9XG4gIHJldHVybiBCdWZmZXIuYWxsb2MoK2xlbmd0aClcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldXG4gICAgICB5ID0gYltpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnbGF0aW4xJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYnVmID0gbGlzdFtpXVxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gICAgfVxuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKVxuICAgIHBvcyArPSBidWYubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmcubGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldyA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpIHx8IHN0cmluZyBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xuICAgIHJldHVybiBzdHJpbmcuYnl0ZUxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgIHN0cmluZyA9ICcnICsgc3RyaW5nXG4gIH1cblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgY2FzZSB1bmRlZmluZWQ6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuQnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICAvLyBObyBuZWVkIHRvIHZlcmlmeSB0aGF0IFwidGhpcy5sZW5ndGggPD0gTUFYX1VJTlQzMlwiIHNpbmNlIGl0J3MgYSByZWFkLW9ubHlcbiAgLy8gcHJvcGVydHkgb2YgYSB0eXBlZCBhcnJheS5cblxuICAvLyBUaGlzIGJlaGF2ZXMgbmVpdGhlciBsaWtlIFN0cmluZyBub3IgVWludDhBcnJheSBpbiB0aGF0IHdlIHNldCBzdGFydC9lbmRcbiAgLy8gdG8gdGhlaXIgdXBwZXIvbG93ZXIgYm91bmRzIGlmIHRoZSB2YWx1ZSBwYXNzZWQgaXMgb3V0IG9mIHJhbmdlLlxuICAvLyB1bmRlZmluZWQgaXMgaGFuZGxlZCBzcGVjaWFsbHkgYXMgcGVyIEVDTUEtMjYyIDZ0aCBFZGl0aW9uLFxuICAvLyBTZWN0aW9uIDEzLjMuMy43IFJ1bnRpbWUgU2VtYW50aWNzOiBLZXllZEJpbmRpbmdJbml0aWFsaXphdGlvbi5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQgfHwgc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgLy8gUmV0dXJuIGVhcmx5IGlmIHN0YXJ0ID4gdGhpcy5sZW5ndGguIERvbmUgaGVyZSB0byBwcmV2ZW50IHBvdGVudGlhbCB1aW50MzJcbiAgLy8gY29lcmNpb24gZmFpbCBiZWxvdy5cbiAgaWYgKHN0YXJ0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoZW5kIDw9IDApIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIC8vIEZvcmNlIGNvZXJzaW9uIHRvIHVpbnQzMi4gVGhpcyB3aWxsIGFsc28gY29lcmNlIGZhbHNleS9OYU4gdmFsdWVzIHRvIDAuXG4gIGVuZCA+Pj49IDBcbiAgc3RhcnQgPj4+PSAwXG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbi8vIFRoZSBwcm9wZXJ0eSBpcyB1c2VkIGJ5IGBCdWZmZXIuaXNCdWZmZXJgIGFuZCBgaXMtYnVmZmVyYCAoaW4gU2FmYXJpIDUtNykgdG8gZGV0ZWN0XG4vLyBCdWZmZXIgaW5zdGFuY2VzLlxuQnVmZmVyLnByb3RvdHlwZS5faXNCdWZmZXIgPSB0cnVlXG5cbmZ1bmN0aW9uIHN3YXAgKGIsIG4sIG0pIHtcbiAgdmFyIGkgPSBiW25dXG4gIGJbbl0gPSBiW21dXG4gIGJbbV0gPSBpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDE2ID0gZnVuY3Rpb24gc3dhcDE2ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSAyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMSlcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAzMiA9IGZ1bmN0aW9uIHN3YXAzMiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgNCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMzItYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDMpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDIpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwNjQgPSBmdW5jdGlvbiBzd2FwNjQgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDggIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDY0LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDgpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyA3KVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyA2KVxuICAgIHN3YXAodGhpcywgaSArIDIsIGkgKyA1KVxuICAgIHN3YXAodGhpcywgaSArIDMsIGkgKyA0KVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlICh0YXJnZXQsIHN0YXJ0LCBlbmQsIHRoaXNTdGFydCwgdGhpc0VuZCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIH1cblxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuZCA9IHRhcmdldCA/IHRhcmdldC5sZW5ndGggOiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc1N0YXJ0ID0gMFxuICB9XG4gIGlmICh0aGlzRW5kID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzRW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChzdGFydCA8IDAgfHwgZW5kID4gdGFyZ2V0Lmxlbmd0aCB8fCB0aGlzU3RhcnQgPCAwIHx8IHRoaXNFbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdvdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kICYmIHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kKSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cbiAgaWYgKHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAxXG4gIH1cblxuICBzdGFydCA+Pj49IDBcbiAgZW5kID4+Pj0gMFxuICB0aGlzU3RhcnQgPj4+PSAwXG4gIHRoaXNFbmQgPj4+PSAwXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCkgcmV0dXJuIDBcblxuICB2YXIgeCA9IHRoaXNFbmQgLSB0aGlzU3RhcnRcbiAgdmFyIHkgPSBlbmQgLSBzdGFydFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcblxuICB2YXIgdGhpc0NvcHkgPSB0aGlzLnNsaWNlKHRoaXNTdGFydCwgdGhpc0VuZClcbiAgdmFyIHRhcmdldENvcHkgPSB0YXJnZXQuc2xpY2Uoc3RhcnQsIGVuZClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKHRoaXNDb3B5W2ldICE9PSB0YXJnZXRDb3B5W2ldKSB7XG4gICAgICB4ID0gdGhpc0NvcHlbaV1cbiAgICAgIHkgPSB0YXJnZXRDb3B5W2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuLy8gRmluZHMgZWl0aGVyIHRoZSBmaXJzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPj0gYGJ5dGVPZmZzZXRgLFxuLy8gT1IgdGhlIGxhc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0IDw9IGBieXRlT2Zmc2V0YC5cbi8vXG4vLyBBcmd1bWVudHM6XG4vLyAtIGJ1ZmZlciAtIGEgQnVmZmVyIHRvIHNlYXJjaFxuLy8gLSB2YWwgLSBhIHN0cmluZywgQnVmZmVyLCBvciBudW1iZXJcbi8vIC0gYnl0ZU9mZnNldCAtIGFuIGluZGV4IGludG8gYGJ1ZmZlcmA7IHdpbGwgYmUgY2xhbXBlZCB0byBhbiBpbnQzMlxuLy8gLSBlbmNvZGluZyAtIGFuIG9wdGlvbmFsIGVuY29kaW5nLCByZWxldmFudCBpcyB2YWwgaXMgYSBzdHJpbmdcbi8vIC0gZGlyIC0gdHJ1ZSBmb3IgaW5kZXhPZiwgZmFsc2UgZm9yIGxhc3RJbmRleE9mXG5mdW5jdGlvbiBiaWRpcmVjdGlvbmFsSW5kZXhPZiAoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgLy8gRW1wdHkgYnVmZmVyIG1lYW5zIG5vIG1hdGNoXG4gIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldFxuICBpZiAodHlwZW9mIGJ5dGVPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBieXRlT2Zmc2V0XG4gICAgYnl0ZU9mZnNldCA9IDBcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0ID4gMHg3ZmZmZmZmZikge1xuICAgIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IC0weDgwMDAwMDAwKSB7XG4gICAgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIH1cbiAgYnl0ZU9mZnNldCA9ICtieXRlT2Zmc2V0ICAvLyBDb2VyY2UgdG8gTnVtYmVyLlxuICBpZiAoaXNOYU4oYnl0ZU9mZnNldCkpIHtcbiAgICAvLyBieXRlT2Zmc2V0OiBpdCBpdCdzIHVuZGVmaW5lZCwgbnVsbCwgTmFOLCBcImZvb1wiLCBldGMsIHNlYXJjaCB3aG9sZSBidWZmZXJcbiAgICBieXRlT2Zmc2V0ID0gZGlyID8gMCA6IChidWZmZXIubGVuZ3RoIC0gMSlcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0OiBuZWdhdGl2ZSBvZmZzZXRzIHN0YXJ0IGZyb20gdGhlIGVuZCBvZiB0aGUgYnVmZmVyXG4gIGlmIChieXRlT2Zmc2V0IDwgMCkgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggKyBieXRlT2Zmc2V0XG4gIGlmIChieXRlT2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICBpZiAoZGlyKSByZXR1cm4gLTFcbiAgICBlbHNlIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoIC0gMVxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAwKSB7XG4gICAgaWYgKGRpcikgYnl0ZU9mZnNldCA9IDBcbiAgICBlbHNlIHJldHVybiAtMVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIHZhbFxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWwgPSBCdWZmZXIuZnJvbSh2YWwsIGVuY29kaW5nKVxuICB9XG5cbiAgLy8gRmluYWxseSwgc2VhcmNoIGVpdGhlciBpbmRleE9mIChpZiBkaXIgaXMgdHJ1ZSkgb3IgbGFzdEluZGV4T2ZcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWwpKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcvYnVmZmVyIGFsd2F5cyBmYWlsc1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDB4RkYgLy8gU2VhcmNoIGZvciBhIGJ5dGUgdmFsdWUgWzAtMjU1XVxuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJlxuICAgICAgICB0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKGRpcikge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCBbIHZhbCBdLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICB2YXIgaW5kZXhTaXplID0gMVxuICB2YXIgYXJyTGVuZ3RoID0gYXJyLmxlbmd0aFxuICB2YXIgdmFsTGVuZ3RoID0gdmFsLmxlbmd0aFxuXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICBpZiAoZW5jb2RpbmcgPT09ICd1Y3MyJyB8fCBlbmNvZGluZyA9PT0gJ3Vjcy0yJyB8fFxuICAgICAgICBlbmNvZGluZyA9PT0gJ3V0ZjE2bGUnIHx8IGVuY29kaW5nID09PSAndXRmLTE2bGUnKSB7XG4gICAgICBpZiAoYXJyLmxlbmd0aCA8IDIgfHwgdmFsLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9XG4gICAgICBpbmRleFNpemUgPSAyXG4gICAgICBhcnJMZW5ndGggLz0gMlxuICAgICAgdmFsTGVuZ3RoIC89IDJcbiAgICAgIGJ5dGVPZmZzZXQgLz0gMlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWQgKGJ1ZiwgaSkge1xuICAgIGlmIChpbmRleFNpemUgPT09IDEpIHtcbiAgICAgIHJldHVybiBidWZbaV1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJ1Zi5yZWFkVUludDE2QkUoaSAqIGluZGV4U2l6ZSlcbiAgICB9XG4gIH1cblxuICB2YXIgaVxuICBpZiAoZGlyKSB7XG4gICAgdmFyIGZvdW5kSW5kZXggPSAtMVxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPCBhcnJMZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHJlYWQoYXJyLCBpKSA9PT0gcmVhZCh2YWwsIGZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4KSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbExlbmd0aCkgcmV0dXJuIGZvdW5kSW5kZXggKiBpbmRleFNpemVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ICE9PSAtMSkgaSAtPSBpIC0gZm91bmRJbmRleFxuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGJ5dGVPZmZzZXQgKyB2YWxMZW5ndGggPiBhcnJMZW5ndGgpIGJ5dGVPZmZzZXQgPSBhcnJMZW5ndGggLSB2YWxMZW5ndGhcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIGZvdW5kID0gdHJ1ZVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWxMZW5ndGg7IGorKykge1xuICAgICAgICBpZiAocmVhZChhcnIsIGkgKyBqKSAhPT0gcmVhZCh2YWwsIGopKSB7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uIGluY2x1ZGVzICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiB0aGlzLmluZGV4T2YodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykgIT09IC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIHRydWUpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUubGFzdEluZGV4T2YgPSBmdW5jdGlvbiBsYXN0SW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgaWYgKGlzTmFOKHBhcnNlZCkpIHJldHVybiBpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBsYXRpbjFXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICAvLyBsZWdhY3kgd3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpIC0gcmVtb3ZlIGluIHYwLjEzXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0J1ZmZlci53cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXRbLCBsZW5ndGhdKSBpcyBubyBsb25nZXIgc3VwcG9ydGVkJ1xuICAgIClcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gbGF0aW4xU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIG5ld0J1ZiA9IHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZClcbiAgICBuZXdCdWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47ICsraSkge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKVxuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDIpOyBpIDwgajsgKytpKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7ICsraSkge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSAtIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSArIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcbiAgdmFyIGlcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSBpZiAobGVuIDwgMTAwMCB8fCAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBhc2NlbmRpbmcgY29weSBmcm9tIHN0YXJ0XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbChcbiAgICAgIHRhcmdldCxcbiAgICAgIHRoaXMuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ICsgbGVuKSxcbiAgICAgIHRhcmdldFN0YXJ0XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBVc2FnZTpcbi8vICAgIGJ1ZmZlci5maWxsKG51bWJlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoYnVmZmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChzdHJpbmdbLCBvZmZzZXRbLCBlbmRdXVssIGVuY29kaW5nXSlcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbCwgc3RhcnQsIGVuZCwgZW5jb2RpbmcpIHtcbiAgLy8gSGFuZGxlIHN0cmluZyBjYXNlczpcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHR5cGVvZiBzdGFydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gc3RhcnRcbiAgICAgIHN0YXJ0ID0gMFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbmQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuZFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBjb2RlID0gdmFsLmNoYXJDb2RlQXQoMClcbiAgICAgIGlmIChjb2RlIDwgMjU2KSB7XG4gICAgICAgIHZhbCA9IGNvZGVcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAyNTVcbiAgfVxuXG4gIC8vIEludmFsaWQgcmFuZ2VzIGFyZSBub3Qgc2V0IHRvIGEgZGVmYXVsdCwgc28gY2FuIHJhbmdlIGNoZWNrIGVhcmx5LlxuICBpZiAoc3RhcnQgPCAwIHx8IHRoaXMubGVuZ3RoIDwgc3RhcnQgfHwgdGhpcy5sZW5ndGggPCBlbmQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgc3RhcnQgPSBzdGFydCA+Pj4gMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IHRoaXMubGVuZ3RoIDogZW5kID4+PiAwXG5cbiAgaWYgKCF2YWwpIHZhbCA9IDBcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICB0aGlzW2ldID0gdmFsXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBieXRlcyA9IEJ1ZmZlci5pc0J1ZmZlcih2YWwpXG4gICAgICA/IHZhbFxuICAgICAgOiB1dGY4VG9CeXRlcyhuZXcgQnVmZmVyKHZhbCwgZW5jb2RpbmcpLnRvU3RyaW5nKCkpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGZvciAoaSA9IDA7IGkgPCBlbmQgLSBzdGFydDsgKytpKSB7XG4gICAgICB0aGlzW2kgKyBzdGFydF0gPSBieXRlc1tpICUgbGVuXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teK1xcLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gKGxlYWRTdXJyb2dhdGUgLSAweEQ4MDAgPDwgMTAgfCBjb2RlUG9pbnQgLSAweERDMDApICsgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIGlzbmFuICh2YWwpIHtcbiAgcmV0dXJuIHZhbCAhPT0gdmFsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3be6\n")}}]);

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.chart.js"],{"0687":function(module,exports,__webpack_require__){"use strict";eval('\n\nmodule.exports = {};\nmodule.exports.Arc = __webpack_require__(/*! ./element.arc */ "cec9");\nmodule.exports.Line = __webpack_require__(/*! ./element.line */ "9905");\nmodule.exports.Point = __webpack_require__(/*! ./element.point */ "ff98");\nmodule.exports.Rectangle = __webpack_require__(/*! ./element.rectangle */ "24eb");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDY4Ny5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvZWxlbWVudHMvaW5kZXguanM/YmVmMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0ge307XG5tb2R1bGUuZXhwb3J0cy5BcmMgPSByZXF1aXJlKCcuL2VsZW1lbnQuYXJjJyk7XG5tb2R1bGUuZXhwb3J0cy5MaW5lID0gcmVxdWlyZSgnLi9lbGVtZW50LmxpbmUnKTtcbm1vZHVsZS5leHBvcnRzLlBvaW50ID0gcmVxdWlyZSgnLi9lbGVtZW50LnBvaW50Jyk7XG5tb2R1bGUuZXhwb3J0cy5SZWN0YW5nbGUgPSByZXF1aXJlKCcuL2VsZW1lbnQucmVjdGFuZ2xlJyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0687\n')},"0953":function(module,exports,__webpack_require__){"use strict";eval('\n\nmodule.exports = {};\nmodule.exports.filler = __webpack_require__(/*! ./plugin.filler */ "707c");\nmodule.exports.legend = __webpack_require__(/*! ./plugin.legend */ "675a");\nmodule.exports.title = __webpack_require__(/*! ./plugin.title */ "bd74");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDk1My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9pbmRleC5qcz84ZDcyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSB7fTtcbm1vZHVsZS5leHBvcnRzLmZpbGxlciA9IHJlcXVpcmUoJy4vcGx1Z2luLmZpbGxlcicpO1xubW9kdWxlLmV4cG9ydHMubGVnZW5kID0gcmVxdWlyZSgnLi9wbHVnaW4ubGVnZW5kJyk7XG5tb2R1bGUuZXhwb3J0cy50aXRsZSA9IHJlcXVpcmUoJy4vcGx1Z2luLnRpdGxlJyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///0953\n')},1220:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\n/**\n * Namespace to hold static tick generation functions\n * @namespace Chart.Ticks\n */\nmodule.exports = {\n\t/**\n\t * Namespace to hold formatters for different types of ticks\n\t * @namespace Chart.Ticks.formatters\n\t */\n\tformatters: {\n\t\t/**\n\t\t * Formatter for value labels\n\t\t * @method Chart.Ticks.formatters.values\n\t\t * @param value the value to display\n\t\t * @return {String|Array} the label to display\n\t\t */\n\t\tvalues: function(value) {\n\t\t\treturn helpers.isArray(value) ? value : '' + value;\n\t\t},\n\n\t\t/**\n\t\t * Formatter for linear numeric ticks\n\t\t * @method Chart.Ticks.formatters.linear\n\t\t * @param tickValue {Number} the value to be formatted\n\t\t * @param index {Number} the position of the tickValue parameter in the ticks array\n\t\t * @param ticks {Array<Number>} the list of ticks being converted\n\t\t * @return {String} string representation of the tickValue parameter\n\t\t */\n\t\tlinear: function(tickValue, index, ticks) {\n\t\t\t// If we have lots of ticks, don't use the ones\n\t\t\tvar delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];\n\n\t\t\t// If we have a number like 2.5 as the delta, figure out how many decimal places we need\n\t\t\tif (Math.abs(delta) > 1) {\n\t\t\t\tif (tickValue !== Math.floor(tickValue)) {\n\t\t\t\t\t// not an integer\n\t\t\t\t\tdelta = tickValue - Math.floor(tickValue);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar logDelta = helpers.log10(Math.abs(delta));\n\t\t\tvar tickString = '';\n\n\t\t\tif (tickValue !== 0) {\n\t\t\t\tvar maxTick = Math.max(Math.abs(ticks[0]), Math.abs(ticks[ticks.length - 1]));\n\t\t\t\tif (maxTick < 1e-4) { // all ticks are small numbers; use scientific notation\n\t\t\t\t\tvar logTick = helpers.log10(Math.abs(tickValue));\n\t\t\t\t\ttickString = tickValue.toExponential(Math.floor(logTick) - Math.floor(logDelta));\n\t\t\t\t} else {\n\t\t\t\t\tvar numDecimal = -1 * Math.floor(logDelta);\n\t\t\t\t\tnumDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places\n\t\t\t\t\ttickString = tickValue.toFixed(numDecimal);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttickString = '0'; // never show decimal places for 0\n\t\t\t}\n\n\t\t\treturn tickString;\n\t\t},\n\n\t\tlogarithmic: function(tickValue, index, ticks) {\n\t\t\tvar remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));\n\n\t\t\tif (tickValue === 0) {\n\t\t\t\treturn '0';\n\t\t\t} else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {\n\t\t\t\treturn tickValue.toExponential();\n\t\t\t}\n\t\t\treturn '';\n\t\t}\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTIyMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLnRpY2tzLmpzPzgzY2IiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcblxuLyoqXG4gKiBOYW1lc3BhY2UgdG8gaG9sZCBzdGF0aWMgdGljayBnZW5lcmF0aW9uIGZ1bmN0aW9uc1xuICogQG5hbWVzcGFjZSBDaGFydC5UaWNrc1xuICovXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0LyoqXG5cdCAqIE5hbWVzcGFjZSB0byBob2xkIGZvcm1hdHRlcnMgZm9yIGRpZmZlcmVudCB0eXBlcyBvZiB0aWNrc1xuXHQgKiBAbmFtZXNwYWNlIENoYXJ0LlRpY2tzLmZvcm1hdHRlcnNcblx0ICovXG5cdGZvcm1hdHRlcnM6IHtcblx0XHQvKipcblx0XHQgKiBGb3JtYXR0ZXIgZm9yIHZhbHVlIGxhYmVsc1xuXHRcdCAqIEBtZXRob2QgQ2hhcnQuVGlja3MuZm9ybWF0dGVycy52YWx1ZXNcblx0XHQgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIHRvIGRpc3BsYXlcblx0XHQgKiBAcmV0dXJuIHtTdHJpbmd8QXJyYXl9IHRoZSBsYWJlbCB0byBkaXNwbGF5XG5cdFx0ICovXG5cdFx0dmFsdWVzOiBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdFx0cmV0dXJuIGhlbHBlcnMuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZSA6ICcnICsgdmFsdWU7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEZvcm1hdHRlciBmb3IgbGluZWFyIG51bWVyaWMgdGlja3Ncblx0XHQgKiBAbWV0aG9kIENoYXJ0LlRpY2tzLmZvcm1hdHRlcnMubGluZWFyXG5cdFx0ICogQHBhcmFtIHRpY2tWYWx1ZSB7TnVtYmVyfSB0aGUgdmFsdWUgdG8gYmUgZm9ybWF0dGVkXG5cdFx0ICogQHBhcmFtIGluZGV4IHtOdW1iZXJ9IHRoZSBwb3NpdGlvbiBvZiB0aGUgdGlja1ZhbHVlIHBhcmFtZXRlciBpbiB0aGUgdGlja3MgYXJyYXlcblx0XHQgKiBAcGFyYW0gdGlja3Mge0FycmF5PE51bWJlcj59IHRoZSBsaXN0IG9mIHRpY2tzIGJlaW5nIGNvbnZlcnRlZFxuXHRcdCAqIEByZXR1cm4ge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0aWNrVmFsdWUgcGFyYW1ldGVyXG5cdFx0ICovXG5cdFx0bGluZWFyOiBmdW5jdGlvbih0aWNrVmFsdWUsIGluZGV4LCB0aWNrcykge1xuXHRcdFx0Ly8gSWYgd2UgaGF2ZSBsb3RzIG9mIHRpY2tzLCBkb24ndCB1c2UgdGhlIG9uZXNcblx0XHRcdHZhciBkZWx0YSA9IHRpY2tzLmxlbmd0aCA+IDMgPyB0aWNrc1syXSAtIHRpY2tzWzFdIDogdGlja3NbMV0gLSB0aWNrc1swXTtcblxuXHRcdFx0Ly8gSWYgd2UgaGF2ZSBhIG51bWJlciBsaWtlIDIuNSBhcyB0aGUgZGVsdGEsIGZpZ3VyZSBvdXQgaG93IG1hbnkgZGVjaW1hbCBwbGFjZXMgd2UgbmVlZFxuXHRcdFx0aWYgKE1hdGguYWJzKGRlbHRhKSA+IDEpIHtcblx0XHRcdFx0aWYgKHRpY2tWYWx1ZSAhPT0gTWF0aC5mbG9vcih0aWNrVmFsdWUpKSB7XG5cdFx0XHRcdFx0Ly8gbm90IGFuIGludGVnZXJcblx0XHRcdFx0XHRkZWx0YSA9IHRpY2tWYWx1ZSAtIE1hdGguZmxvb3IodGlja1ZhbHVlKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgbG9nRGVsdGEgPSBoZWxwZXJzLmxvZzEwKE1hdGguYWJzKGRlbHRhKSk7XG5cdFx0XHR2YXIgdGlja1N0cmluZyA9ICcnO1xuXG5cdFx0XHRpZiAodGlja1ZhbHVlICE9PSAwKSB7XG5cdFx0XHRcdHZhciBtYXhUaWNrID0gTWF0aC5tYXgoTWF0aC5hYnModGlja3NbMF0pLCBNYXRoLmFicyh0aWNrc1t0aWNrcy5sZW5ndGggLSAxXSkpO1xuXHRcdFx0XHRpZiAobWF4VGljayA8IDFlLTQpIHsgLy8gYWxsIHRpY2tzIGFyZSBzbWFsbCBudW1iZXJzOyB1c2Ugc2NpZW50aWZpYyBub3RhdGlvblxuXHRcdFx0XHRcdHZhciBsb2dUaWNrID0gaGVscGVycy5sb2cxMChNYXRoLmFicyh0aWNrVmFsdWUpKTtcblx0XHRcdFx0XHR0aWNrU3RyaW5nID0gdGlja1ZhbHVlLnRvRXhwb25lbnRpYWwoTWF0aC5mbG9vcihsb2dUaWNrKSAtIE1hdGguZmxvb3IobG9nRGVsdGEpKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YXIgbnVtRGVjaW1hbCA9IC0xICogTWF0aC5mbG9vcihsb2dEZWx0YSk7XG5cdFx0XHRcdFx0bnVtRGVjaW1hbCA9IE1hdGgubWF4KE1hdGgubWluKG51bURlY2ltYWwsIDIwKSwgMCk7IC8vIHRvRml4ZWQgaGFzIGEgbWF4IG9mIDIwIGRlY2ltYWwgcGxhY2VzXG5cdFx0XHRcdFx0dGlja1N0cmluZyA9IHRpY2tWYWx1ZS50b0ZpeGVkKG51bURlY2ltYWwpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aWNrU3RyaW5nID0gJzAnOyAvLyBuZXZlciBzaG93IGRlY2ltYWwgcGxhY2VzIGZvciAwXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0aWNrU3RyaW5nO1xuXHRcdH0sXG5cblx0XHRsb2dhcml0aG1pYzogZnVuY3Rpb24odGlja1ZhbHVlLCBpbmRleCwgdGlja3MpIHtcblx0XHRcdHZhciByZW1haW4gPSB0aWNrVmFsdWUgLyAoTWF0aC5wb3coMTAsIE1hdGguZmxvb3IoaGVscGVycy5sb2cxMCh0aWNrVmFsdWUpKSkpO1xuXG5cdFx0XHRpZiAodGlja1ZhbHVlID09PSAwKSB7XG5cdFx0XHRcdHJldHVybiAnMCc7XG5cdFx0XHR9IGVsc2UgaWYgKHJlbWFpbiA9PT0gMSB8fCByZW1haW4gPT09IDIgfHwgcmVtYWluID09PSA1IHx8IGluZGV4ID09PSAwIHx8IGluZGV4ID09PSB0aWNrcy5sZW5ndGggLSAxKSB7XG5cdFx0XHRcdHJldHVybiB0aWNrVmFsdWUudG9FeHBvbmVudGlhbCgpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuICcnO1xuXHRcdH1cblx0fVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1220\n")},"1fc5":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar elements = __webpack_require__(/*! ../elements/index */ \"0687\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\ndefaults._set('polarArea', {\n\tscale: {\n\t\ttype: 'radialLinear',\n\t\tangleLines: {\n\t\t\tdisplay: false\n\t\t},\n\t\tgridLines: {\n\t\t\tcircular: true\n\t\t},\n\t\tpointLabels: {\n\t\t\tdisplay: false\n\t\t},\n\t\tticks: {\n\t\t\tbeginAtZero: true\n\t\t}\n\t},\n\n\t// Boolean - Whether to animate the rotation of the chart\n\tanimation: {\n\t\tanimateRotate: true,\n\t\tanimateScale: true\n\t},\n\n\tstartAngle: -0.5 * Math.PI,\n\tlegendCallback: function(chart) {\n\t\tvar text = [];\n\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\n\t\tvar data = chart.data;\n\t\tvar datasets = data.datasets;\n\t\tvar labels = data.labels;\n\n\t\tif (datasets.length) {\n\t\t\tfor (var i = 0; i < datasets[0].data.length; ++i) {\n\t\t\t\ttext.push('<li><span style=\"background-color:' + datasets[0].backgroundColor[i] + '\"></span>');\n\t\t\t\tif (labels[i]) {\n\t\t\t\t\ttext.push(labels[i]);\n\t\t\t\t}\n\t\t\t\ttext.push('</li>');\n\t\t\t}\n\t\t}\n\n\t\ttext.push('</ul>');\n\t\treturn text.join('');\n\t},\n\tlegend: {\n\t\tlabels: {\n\t\t\tgenerateLabels: function(chart) {\n\t\t\t\tvar data = chart.data;\n\t\t\t\tif (data.labels.length && data.datasets.length) {\n\t\t\t\t\treturn data.labels.map(function(label, i) {\n\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\t\t\t\tvar ds = data.datasets[0];\n\t\t\t\t\t\tvar arc = meta.data[i];\n\t\t\t\t\t\tvar custom = arc.custom || {};\n\t\t\t\t\t\tvar valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;\n\t\t\t\t\t\tvar arcOpts = chart.options.elements.arc;\n\t\t\t\t\t\tvar fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\n\t\t\t\t\t\tvar stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\n\t\t\t\t\t\tvar bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttext: label,\n\t\t\t\t\t\t\tfillStyle: fill,\n\t\t\t\t\t\t\tstrokeStyle: stroke,\n\t\t\t\t\t\t\tlineWidth: bw,\n\t\t\t\t\t\t\thidden: isNaN(ds.data[i]) || meta.data[i].hidden,\n\n\t\t\t\t\t\t\t// Extra data used for toggling the correct item\n\t\t\t\t\t\t\tindex: i\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\n\t\tonClick: function(e, legendItem) {\n\t\t\tvar index = legendItem.index;\n\t\t\tvar chart = this.chart;\n\t\t\tvar i, ilen, meta;\n\n\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\n\t\t\t}\n\n\t\t\tchart.update();\n\t\t}\n\t},\n\n\t// Need to override these to give a nice default\n\ttooltips: {\n\t\tcallbacks: {\n\t\t\ttitle: function() {\n\t\t\t\treturn '';\n\t\t\t},\n\t\t\tlabel: function(item, data) {\n\t\t\t\treturn data.labels[item.index] + ': ' + item.yLabel;\n\t\t\t}\n\t\t}\n\t}\n});\n\nmodule.exports = function(Chart) {\n\n\tChart.controllers.polarArea = Chart.DatasetController.extend({\n\n\t\tdataElementType: elements.Arc,\n\n\t\tlinkScales: helpers.noop,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar start = me.chart.options.startAngle || 0;\n\t\t\tvar starts = me._starts = [];\n\t\t\tvar angles = me._angles = [];\n\t\t\tvar i, ilen, angle;\n\n\t\t\tme._updateRadius();\n\n\t\t\tmeta.count = me.countVisibleElements();\n\n\t\t\tfor (i = 0, ilen = dataset.data.length; i < ilen; i++) {\n\t\t\t\tstarts[i] = start;\n\t\t\t\tangle = me._computeAngle(i);\n\t\t\t\tangles[i] = angle;\n\t\t\t\tstart += angle;\n\t\t\t}\n\n\t\t\thelpers.each(meta.data, function(arc, index) {\n\t\t\t\tme.updateElement(arc, index, reset);\n\t\t\t});\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\t_updateRadius: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar chartArea = chart.chartArea;\n\t\t\tvar opts = chart.options;\n\t\t\tvar arcOpts = opts.elements.arc;\n\t\t\tvar minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);\n\n\t\t\tchart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);\n\t\t\tchart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);\n\t\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\n\n\t\t\tme.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);\n\t\t\tme.innerRadius = me.outerRadius - chart.radiusLength;\n\t\t},\n\n\t\tupdateElement: function(arc, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar opts = chart.options;\n\t\t\tvar animationOpts = opts.animation;\n\t\t\tvar scale = chart.scale;\n\t\t\tvar labels = chart.data.labels;\n\n\t\t\tvar centerX = scale.xCenter;\n\t\t\tvar centerY = scale.yCenter;\n\n\t\t\t// var negHalfPI = -0.5 * Math.PI;\n\t\t\tvar datasetStartAngle = opts.startAngle;\n\t\t\tvar distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\n\t\t\tvar startAngle = me._starts[index];\n\t\t\tvar endAngle = startAngle + (arc.hidden ? 0 : me._angles[index]);\n\n\t\t\tvar resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\n\n\t\t\thelpers.extend(arc, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\t\t\t\t_scale: scale,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: centerX,\n\t\t\t\t\ty: centerY,\n\t\t\t\t\tinnerRadius: 0,\n\t\t\t\t\touterRadius: reset ? resetRadius : distance,\n\t\t\t\t\tstartAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,\n\t\t\t\t\tendAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,\n\t\t\t\t\tlabel: helpers.valueAtIndexOrDefault(labels, index, labels[index])\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Apply border and fill style\n\t\t\tvar elementOpts = this.chart.options.elements.arc;\n\t\t\tvar custom = arc.custom || {};\n\t\t\tvar valueOrDefault = helpers.valueAtIndexOrDefault;\n\t\t\tvar model = arc._model;\n\n\t\t\tmodel.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);\n\t\t\tmodel.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);\n\t\t\tmodel.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);\n\n\t\t\tarc.pivot();\n\t\t},\n\n\t\tcountVisibleElements: function() {\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar count = 0;\n\n\t\t\thelpers.each(meta.data, function(element, index) {\n\t\t\t\tif (!isNaN(dataset.data[index]) && !element.hidden) {\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn count;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\t_computeAngle: function(index) {\n\t\t\tvar me = this;\n\t\t\tvar count = this.getMeta().count;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar meta = me.getMeta();\n\n\t\t\tif (isNaN(dataset.data[index]) || meta.data[index].hidden) {\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\t// Scriptable options\n\t\t\tvar context = {\n\t\t\t\tchart: me.chart,\n\t\t\t\tdataIndex: index,\n\t\t\t\tdataset: dataset,\n\t\t\t\tdatasetIndex: me.index\n\t\t\t};\n\n\t\t\treturn helpers.options.resolve([\n\t\t\t\tme.chart.options.elements.arc.angle,\n\t\t\t\t(2 * Math.PI) / count\n\t\t\t], context, index);\n\t\t}\n\t});\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMWZjNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5wb2xhckFyZWEuanM/ZTU5NiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5kZWZhdWx0cycpO1xudmFyIGVsZW1lbnRzID0gcmVxdWlyZSgnLi4vZWxlbWVudHMvaW5kZXgnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xuXG5kZWZhdWx0cy5fc2V0KCdwb2xhckFyZWEnLCB7XG5cdHNjYWxlOiB7XG5cdFx0dHlwZTogJ3JhZGlhbExpbmVhcicsXG5cdFx0YW5nbGVMaW5lczoge1xuXHRcdFx0ZGlzcGxheTogZmFsc2Vcblx0XHR9LFxuXHRcdGdyaWRMaW5lczoge1xuXHRcdFx0Y2lyY3VsYXI6IHRydWVcblx0XHR9LFxuXHRcdHBvaW50TGFiZWxzOiB7XG5cdFx0XHRkaXNwbGF5OiBmYWxzZVxuXHRcdH0sXG5cdFx0dGlja3M6IHtcblx0XHRcdGJlZ2luQXRaZXJvOiB0cnVlXG5cdFx0fVxuXHR9LFxuXG5cdC8vIEJvb2xlYW4gLSBXaGV0aGVyIHRvIGFuaW1hdGUgdGhlIHJvdGF0aW9uIG9mIHRoZSBjaGFydFxuXHRhbmltYXRpb246IHtcblx0XHRhbmltYXRlUm90YXRlOiB0cnVlLFxuXHRcdGFuaW1hdGVTY2FsZTogdHJ1ZVxuXHR9LFxuXG5cdHN0YXJ0QW5nbGU6IC0wLjUgKiBNYXRoLlBJLFxuXHRsZWdlbmRDYWxsYmFjazogZnVuY3Rpb24oY2hhcnQpIHtcblx0XHR2YXIgdGV4dCA9IFtdO1xuXHRcdHRleHQucHVzaCgnPHVsIGNsYXNzPVwiJyArIGNoYXJ0LmlkICsgJy1sZWdlbmRcIj4nKTtcblxuXHRcdHZhciBkYXRhID0gY2hhcnQuZGF0YTtcblx0XHR2YXIgZGF0YXNldHMgPSBkYXRhLmRhdGFzZXRzO1xuXHRcdHZhciBsYWJlbHMgPSBkYXRhLmxhYmVscztcblxuXHRcdGlmIChkYXRhc2V0cy5sZW5ndGgpIHtcblx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YXNldHNbMF0uZGF0YS5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHR0ZXh0LnB1c2goJzxsaT48c3BhbiBzdHlsZT1cImJhY2tncm91bmQtY29sb3I6JyArIGRhdGFzZXRzWzBdLmJhY2tncm91bmRDb2xvcltpXSArICdcIj48L3NwYW4+Jyk7XG5cdFx0XHRcdGlmIChsYWJlbHNbaV0pIHtcblx0XHRcdFx0XHR0ZXh0LnB1c2gobGFiZWxzW2ldKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0ZXh0LnB1c2goJzwvbGk+Jyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGV4dC5wdXNoKCc8L3VsPicpO1xuXHRcdHJldHVybiB0ZXh0LmpvaW4oJycpO1xuXHR9LFxuXHRsZWdlbmQ6IHtcblx0XHRsYWJlbHM6IHtcblx0XHRcdGdlbmVyYXRlTGFiZWxzOiBmdW5jdGlvbihjaGFydCkge1xuXHRcdFx0XHR2YXIgZGF0YSA9IGNoYXJ0LmRhdGE7XG5cdFx0XHRcdGlmIChkYXRhLmxhYmVscy5sZW5ndGggJiYgZGF0YS5kYXRhc2V0cy5sZW5ndGgpIHtcblx0XHRcdFx0XHRyZXR1cm4gZGF0YS5sYWJlbHMubWFwKGZ1bmN0aW9uKGxhYmVsLCBpKSB7XG5cdFx0XHRcdFx0XHR2YXIgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKDApO1xuXHRcdFx0XHRcdFx0dmFyIGRzID0gZGF0YS5kYXRhc2V0c1swXTtcblx0XHRcdFx0XHRcdHZhciBhcmMgPSBtZXRhLmRhdGFbaV07XG5cdFx0XHRcdFx0XHR2YXIgY3VzdG9tID0gYXJjLmN1c3RvbSB8fCB7fTtcblx0XHRcdFx0XHRcdHZhciB2YWx1ZUF0SW5kZXhPckRlZmF1bHQgPSBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdDtcblx0XHRcdFx0XHRcdHZhciBhcmNPcHRzID0gY2hhcnQub3B0aW9ucy5lbGVtZW50cy5hcmM7XG5cdFx0XHRcdFx0XHR2YXIgZmlsbCA9IGN1c3RvbS5iYWNrZ3JvdW5kQ29sb3IgPyBjdXN0b20uYmFja2dyb3VuZENvbG9yIDogdmFsdWVBdEluZGV4T3JEZWZhdWx0KGRzLmJhY2tncm91bmRDb2xvciwgaSwgYXJjT3B0cy5iYWNrZ3JvdW5kQ29sb3IpO1xuXHRcdFx0XHRcdFx0dmFyIHN0cm9rZSA9IGN1c3RvbS5ib3JkZXJDb2xvciA/IGN1c3RvbS5ib3JkZXJDb2xvciA6IHZhbHVlQXRJbmRleE9yRGVmYXVsdChkcy5ib3JkZXJDb2xvciwgaSwgYXJjT3B0cy5ib3JkZXJDb2xvcik7XG5cdFx0XHRcdFx0XHR2YXIgYncgPSBjdXN0b20uYm9yZGVyV2lkdGggPyBjdXN0b20uYm9yZGVyV2lkdGggOiB2YWx1ZUF0SW5kZXhPckRlZmF1bHQoZHMuYm9yZGVyV2lkdGgsIGksIGFyY09wdHMuYm9yZGVyV2lkdGgpO1xuXG5cdFx0XHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdFx0XHR0ZXh0OiBsYWJlbCxcblx0XHRcdFx0XHRcdFx0ZmlsbFN0eWxlOiBmaWxsLFxuXHRcdFx0XHRcdFx0XHRzdHJva2VTdHlsZTogc3Ryb2tlLFxuXHRcdFx0XHRcdFx0XHRsaW5lV2lkdGg6IGJ3LFxuXHRcdFx0XHRcdFx0XHRoaWRkZW46IGlzTmFOKGRzLmRhdGFbaV0pIHx8IG1ldGEuZGF0YVtpXS5oaWRkZW4sXG5cblx0XHRcdFx0XHRcdFx0Ly8gRXh0cmEgZGF0YSB1c2VkIGZvciB0b2dnbGluZyB0aGUgY29ycmVjdCBpdGVtXG5cdFx0XHRcdFx0XHRcdGluZGV4OiBpXG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBbXTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0b25DbGljazogZnVuY3Rpb24oZSwgbGVnZW5kSXRlbSkge1xuXHRcdFx0dmFyIGluZGV4ID0gbGVnZW5kSXRlbS5pbmRleDtcblx0XHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQ7XG5cdFx0XHR2YXIgaSwgaWxlbiwgbWV0YTtcblxuXHRcdFx0Zm9yIChpID0gMCwgaWxlbiA9IChjaGFydC5kYXRhLmRhdGFzZXRzIHx8IFtdKS5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdFx0bWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGkpO1xuXHRcdFx0XHRtZXRhLmRhdGFbaW5kZXhdLmhpZGRlbiA9ICFtZXRhLmRhdGFbaW5kZXhdLmhpZGRlbjtcblx0XHRcdH1cblxuXHRcdFx0Y2hhcnQudXBkYXRlKCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8vIE5lZWQgdG8gb3ZlcnJpZGUgdGhlc2UgdG8gZ2l2ZSBhIG5pY2UgZGVmYXVsdFxuXHR0b29sdGlwczoge1xuXHRcdGNhbGxiYWNrczoge1xuXHRcdFx0dGl0bGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gJyc7XG5cdFx0XHR9LFxuXHRcdFx0bGFiZWw6IGZ1bmN0aW9uKGl0ZW0sIGRhdGEpIHtcblx0XHRcdFx0cmV0dXJuIGRhdGEubGFiZWxzW2l0ZW0uaW5kZXhdICsgJzogJyArIGl0ZW0ueUxhYmVsO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oQ2hhcnQpIHtcblxuXHRDaGFydC5jb250cm9sbGVycy5wb2xhckFyZWEgPSBDaGFydC5EYXRhc2V0Q29udHJvbGxlci5leHRlbmQoe1xuXG5cdFx0ZGF0YUVsZW1lbnRUeXBlOiBlbGVtZW50cy5BcmMsXG5cblx0XHRsaW5rU2NhbGVzOiBoZWxwZXJzLm5vb3AsXG5cblx0XHR1cGRhdGU6IGZ1bmN0aW9uKHJlc2V0KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIGRhdGFzZXQgPSBtZS5nZXREYXRhc2V0KCk7XG5cdFx0XHR2YXIgbWV0YSA9IG1lLmdldE1ldGEoKTtcblx0XHRcdHZhciBzdGFydCA9IG1lLmNoYXJ0Lm9wdGlvbnMuc3RhcnRBbmdsZSB8fCAwO1xuXHRcdFx0dmFyIHN0YXJ0cyA9IG1lLl9zdGFydHMgPSBbXTtcblx0XHRcdHZhciBhbmdsZXMgPSBtZS5fYW5nbGVzID0gW107XG5cdFx0XHR2YXIgaSwgaWxlbiwgYW5nbGU7XG5cblx0XHRcdG1lLl91cGRhdGVSYWRpdXMoKTtcblxuXHRcdFx0bWV0YS5jb3VudCA9IG1lLmNvdW50VmlzaWJsZUVsZW1lbnRzKCk7XG5cblx0XHRcdGZvciAoaSA9IDAsIGlsZW4gPSBkYXRhc2V0LmRhdGEubGVuZ3RoOyBpIDwgaWxlbjsgaSsrKSB7XG5cdFx0XHRcdHN0YXJ0c1tpXSA9IHN0YXJ0O1xuXHRcdFx0XHRhbmdsZSA9IG1lLl9jb21wdXRlQW5nbGUoaSk7XG5cdFx0XHRcdGFuZ2xlc1tpXSA9IGFuZ2xlO1xuXHRcdFx0XHRzdGFydCArPSBhbmdsZTtcblx0XHRcdH1cblxuXHRcdFx0aGVscGVycy5lYWNoKG1ldGEuZGF0YSwgZnVuY3Rpb24oYXJjLCBpbmRleCkge1xuXHRcdFx0XHRtZS51cGRhdGVFbGVtZW50KGFyYywgaW5kZXgsIHJlc2V0KTtcblx0XHRcdH0pO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdF91cGRhdGVSYWRpdXM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBjaGFydCA9IG1lLmNoYXJ0O1xuXHRcdFx0dmFyIGNoYXJ0QXJlYSA9IGNoYXJ0LmNoYXJ0QXJlYTtcblx0XHRcdHZhciBvcHRzID0gY2hhcnQub3B0aW9ucztcblx0XHRcdHZhciBhcmNPcHRzID0gb3B0cy5lbGVtZW50cy5hcmM7XG5cdFx0XHR2YXIgbWluU2l6ZSA9IE1hdGgubWluKGNoYXJ0QXJlYS5yaWdodCAtIGNoYXJ0QXJlYS5sZWZ0LCBjaGFydEFyZWEuYm90dG9tIC0gY2hhcnRBcmVhLnRvcCk7XG5cblx0XHRcdGNoYXJ0Lm91dGVyUmFkaXVzID0gTWF0aC5tYXgoKG1pblNpemUgLSBhcmNPcHRzLmJvcmRlcldpZHRoIC8gMikgLyAyLCAwKTtcblx0XHRcdGNoYXJ0LmlubmVyUmFkaXVzID0gTWF0aC5tYXgob3B0cy5jdXRvdXRQZXJjZW50YWdlID8gKGNoYXJ0Lm91dGVyUmFkaXVzIC8gMTAwKSAqIChvcHRzLmN1dG91dFBlcmNlbnRhZ2UpIDogMSwgMCk7XG5cdFx0XHRjaGFydC5yYWRpdXNMZW5ndGggPSAoY2hhcnQub3V0ZXJSYWRpdXMgLSBjaGFydC5pbm5lclJhZGl1cykgLyBjaGFydC5nZXRWaXNpYmxlRGF0YXNldENvdW50KCk7XG5cblx0XHRcdG1lLm91dGVyUmFkaXVzID0gY2hhcnQub3V0ZXJSYWRpdXMgLSAoY2hhcnQucmFkaXVzTGVuZ3RoICogbWUuaW5kZXgpO1xuXHRcdFx0bWUuaW5uZXJSYWRpdXMgPSBtZS5vdXRlclJhZGl1cyAtIGNoYXJ0LnJhZGl1c0xlbmd0aDtcblx0XHR9LFxuXG5cdFx0dXBkYXRlRWxlbWVudDogZnVuY3Rpb24oYXJjLCBpbmRleCwgcmVzZXQpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcblx0XHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xuXHRcdFx0dmFyIG9wdHMgPSBjaGFydC5vcHRpb25zO1xuXHRcdFx0dmFyIGFuaW1hdGlvbk9wdHMgPSBvcHRzLmFuaW1hdGlvbjtcblx0XHRcdHZhciBzY2FsZSA9IGNoYXJ0LnNjYWxlO1xuXHRcdFx0dmFyIGxhYmVscyA9IGNoYXJ0LmRhdGEubGFiZWxzO1xuXG5cdFx0XHR2YXIgY2VudGVyWCA9IHNjYWxlLnhDZW50ZXI7XG5cdFx0XHR2YXIgY2VudGVyWSA9IHNjYWxlLnlDZW50ZXI7XG5cblx0XHRcdC8vIHZhciBuZWdIYWxmUEkgPSAtMC41ICogTWF0aC5QSTtcblx0XHRcdHZhciBkYXRhc2V0U3RhcnRBbmdsZSA9IG9wdHMuc3RhcnRBbmdsZTtcblx0XHRcdHZhciBkaXN0YW5jZSA9IGFyYy5oaWRkZW4gPyAwIDogc2NhbGUuZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUoZGF0YXNldC5kYXRhW2luZGV4XSk7XG5cdFx0XHR2YXIgc3RhcnRBbmdsZSA9IG1lLl9zdGFydHNbaW5kZXhdO1xuXHRcdFx0dmFyIGVuZEFuZ2xlID0gc3RhcnRBbmdsZSArIChhcmMuaGlkZGVuID8gMCA6IG1lLl9hbmdsZXNbaW5kZXhdKTtcblxuXHRcdFx0dmFyIHJlc2V0UmFkaXVzID0gYW5pbWF0aW9uT3B0cy5hbmltYXRlU2NhbGUgPyAwIDogc2NhbGUuZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUoZGF0YXNldC5kYXRhW2luZGV4XSk7XG5cblx0XHRcdGhlbHBlcnMuZXh0ZW5kKGFyYywge1xuXHRcdFx0XHQvLyBVdGlsaXR5XG5cdFx0XHRcdF9kYXRhc2V0SW5kZXg6IG1lLmluZGV4LFxuXHRcdFx0XHRfaW5kZXg6IGluZGV4LFxuXHRcdFx0XHRfc2NhbGU6IHNjYWxlLFxuXG5cdFx0XHRcdC8vIERlc2lyZWQgdmlldyBwcm9wZXJ0aWVzXG5cdFx0XHRcdF9tb2RlbDoge1xuXHRcdFx0XHRcdHg6IGNlbnRlclgsXG5cdFx0XHRcdFx0eTogY2VudGVyWSxcblx0XHRcdFx0XHRpbm5lclJhZGl1czogMCxcblx0XHRcdFx0XHRvdXRlclJhZGl1czogcmVzZXQgPyByZXNldFJhZGl1cyA6IGRpc3RhbmNlLFxuXHRcdFx0XHRcdHN0YXJ0QW5nbGU6IHJlc2V0ICYmIGFuaW1hdGlvbk9wdHMuYW5pbWF0ZVJvdGF0ZSA/IGRhdGFzZXRTdGFydEFuZ2xlIDogc3RhcnRBbmdsZSxcblx0XHRcdFx0XHRlbmRBbmdsZTogcmVzZXQgJiYgYW5pbWF0aW9uT3B0cy5hbmltYXRlUm90YXRlID8gZGF0YXNldFN0YXJ0QW5nbGUgOiBlbmRBbmdsZSxcblx0XHRcdFx0XHRsYWJlbDogaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQobGFiZWxzLCBpbmRleCwgbGFiZWxzW2luZGV4XSlcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdC8vIEFwcGx5IGJvcmRlciBhbmQgZmlsbCBzdHlsZVxuXHRcdFx0dmFyIGVsZW1lbnRPcHRzID0gdGhpcy5jaGFydC5vcHRpb25zLmVsZW1lbnRzLmFyYztcblx0XHRcdHZhciBjdXN0b20gPSBhcmMuY3VzdG9tIHx8IHt9O1xuXHRcdFx0dmFyIHZhbHVlT3JEZWZhdWx0ID0gaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQ7XG5cdFx0XHR2YXIgbW9kZWwgPSBhcmMuX21vZGVsO1xuXG5cdFx0XHRtb2RlbC5iYWNrZ3JvdW5kQ29sb3IgPSBjdXN0b20uYmFja2dyb3VuZENvbG9yID8gY3VzdG9tLmJhY2tncm91bmRDb2xvciA6IHZhbHVlT3JEZWZhdWx0KGRhdGFzZXQuYmFja2dyb3VuZENvbG9yLCBpbmRleCwgZWxlbWVudE9wdHMuYmFja2dyb3VuZENvbG9yKTtcblx0XHRcdG1vZGVsLmJvcmRlckNvbG9yID0gY3VzdG9tLmJvcmRlckNvbG9yID8gY3VzdG9tLmJvcmRlckNvbG9yIDogdmFsdWVPckRlZmF1bHQoZGF0YXNldC5ib3JkZXJDb2xvciwgaW5kZXgsIGVsZW1lbnRPcHRzLmJvcmRlckNvbG9yKTtcblx0XHRcdG1vZGVsLmJvcmRlcldpZHRoID0gY3VzdG9tLmJvcmRlcldpZHRoID8gY3VzdG9tLmJvcmRlcldpZHRoIDogdmFsdWVPckRlZmF1bHQoZGF0YXNldC5ib3JkZXJXaWR0aCwgaW5kZXgsIGVsZW1lbnRPcHRzLmJvcmRlcldpZHRoKTtcblxuXHRcdFx0YXJjLnBpdm90KCk7XG5cdFx0fSxcblxuXHRcdGNvdW50VmlzaWJsZUVsZW1lbnRzOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBkYXRhc2V0ID0gdGhpcy5nZXREYXRhc2V0KCk7XG5cdFx0XHR2YXIgbWV0YSA9IHRoaXMuZ2V0TWV0YSgpO1xuXHRcdFx0dmFyIGNvdW50ID0gMDtcblxuXHRcdFx0aGVscGVycy5lYWNoKG1ldGEuZGF0YSwgZnVuY3Rpb24oZWxlbWVudCwgaW5kZXgpIHtcblx0XHRcdFx0aWYgKCFpc05hTihkYXRhc2V0LmRhdGFbaW5kZXhdKSAmJiAhZWxlbWVudC5oaWRkZW4pIHtcblx0XHRcdFx0XHRjb3VudCsrO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0cmV0dXJuIGNvdW50O1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdF9jb21wdXRlQW5nbGU6IGZ1bmN0aW9uKGluZGV4KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIGNvdW50ID0gdGhpcy5nZXRNZXRhKCkuY291bnQ7XG5cdFx0XHR2YXIgZGF0YXNldCA9IG1lLmdldERhdGFzZXQoKTtcblx0XHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xuXG5cdFx0XHRpZiAoaXNOYU4oZGF0YXNldC5kYXRhW2luZGV4XSkgfHwgbWV0YS5kYXRhW2luZGV4XS5oaWRkZW4pIHtcblx0XHRcdFx0cmV0dXJuIDA7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNjcmlwdGFibGUgb3B0aW9uc1xuXHRcdFx0dmFyIGNvbnRleHQgPSB7XG5cdFx0XHRcdGNoYXJ0OiBtZS5jaGFydCxcblx0XHRcdFx0ZGF0YUluZGV4OiBpbmRleCxcblx0XHRcdFx0ZGF0YXNldDogZGF0YXNldCxcblx0XHRcdFx0ZGF0YXNldEluZGV4OiBtZS5pbmRleFxuXHRcdFx0fTtcblxuXHRcdFx0cmV0dXJuIGhlbHBlcnMub3B0aW9ucy5yZXNvbHZlKFtcblx0XHRcdFx0bWUuY2hhcnQub3B0aW9ucy5lbGVtZW50cy5hcmMuYW5nbGUsXG5cdFx0XHRcdCgyICogTWF0aC5QSSkgLyBjb3VudFxuXHRcdFx0XSwgY29udGV4dCwgaW5kZXgpO1xuXHRcdH1cblx0fSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1fc5\n")},"23a9":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar Animation = __webpack_require__(/*! ./core.animation */ \"65bb\");\nvar animations = __webpack_require__(/*! ./core.animations */ \"6a4a\");\nvar defaults = __webpack_require__(/*! ./core.defaults */ \"beaa\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\nvar Interaction = __webpack_require__(/*! ./core.interaction */ \"6701\");\nvar layouts = __webpack_require__(/*! ./core.layouts */ \"6705\");\nvar platform = __webpack_require__(/*! ../platforms/platform */ \"8507\");\nvar plugins = __webpack_require__(/*! ./core.plugins */ \"cb9d\");\nvar scaleService = __webpack_require__(/*! ../core/core.scaleService */ \"7c56\");\nvar Tooltip = __webpack_require__(/*! ./core.tooltip */ \"9af9\");\n\nmodule.exports = function(Chart) {\n\n\t// Create a dictionary of chart types, to allow for extension of existing types\n\tChart.types = {};\n\n\t// Store a reference to each instance - allowing us to globally resize chart instances on window resize.\n\t// Destroy method on the chart will remove the instance of the chart from this reference.\n\tChart.instances = {};\n\n\t// Controllers available for dataset visualization eg. bar, line, slice, etc.\n\tChart.controllers = {};\n\n\t/**\n\t * Initializes the given config with global and chart default values.\n\t */\n\tfunction initConfig(config) {\n\t\tconfig = config || {};\n\n\t\t// Do NOT use configMerge() for the data object because this method merges arrays\n\t\t// and so would change references to labels and datasets, preventing data updates.\n\t\tvar data = config.data = config.data || {};\n\t\tdata.datasets = data.datasets || [];\n\t\tdata.labels = data.labels || [];\n\n\t\tconfig.options = helpers.configMerge(\n\t\t\tdefaults.global,\n\t\t\tdefaults[config.type],\n\t\t\tconfig.options || {});\n\n\t\treturn config;\n\t}\n\n\t/**\n\t * Updates the config of the chart\n\t * @param chart {Chart} chart to update the options for\n\t */\n\tfunction updateConfig(chart) {\n\t\tvar newOptions = chart.options;\n\n\t\thelpers.each(chart.scales, function(scale) {\n\t\t\tlayouts.removeBox(chart, scale);\n\t\t});\n\n\t\tnewOptions = helpers.configMerge(\n\t\t\tChart.defaults.global,\n\t\t\tChart.defaults[chart.config.type],\n\t\t\tnewOptions);\n\n\t\tchart.options = chart.config.options = newOptions;\n\t\tchart.ensureScalesHaveIDs();\n\t\tchart.buildOrUpdateScales();\n\t\t// Tooltip\n\t\tchart.tooltip._options = newOptions.tooltips;\n\t\tchart.tooltip.initialize();\n\t}\n\n\tfunction positionIsHorizontal(position) {\n\t\treturn position === 'top' || position === 'bottom';\n\t}\n\n\thelpers.extend(Chart.prototype, /** @lends Chart */ {\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tconstruct: function(item, config) {\n\t\t\tvar me = this;\n\n\t\t\tconfig = initConfig(config);\n\n\t\t\tvar context = platform.acquireContext(item, config);\n\t\t\tvar canvas = context && context.canvas;\n\t\t\tvar height = canvas && canvas.height;\n\t\t\tvar width = canvas && canvas.width;\n\n\t\t\tme.id = helpers.uid();\n\t\t\tme.ctx = context;\n\t\t\tme.canvas = canvas;\n\t\t\tme.config = config;\n\t\t\tme.width = width;\n\t\t\tme.height = height;\n\t\t\tme.aspectRatio = height ? width / height : null;\n\t\t\tme.options = config.options;\n\t\t\tme._bufferedRender = false;\n\n\t\t\t/**\n\t\t\t * Provided for backward compatibility, Chart and Chart.Controller have been merged,\n\t\t\t * the \"instance\" still need to be defined since it might be called from plugins.\n\t\t\t * @prop Chart#chart\n\t\t\t * @deprecated since version 2.6.0\n\t\t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\tme.chart = me;\n\t\t\tme.controller = me; // chart.chart.controller #inception\n\n\t\t\t// Add the chart instance to the global namespace\n\t\t\tChart.instances[me.id] = me;\n\n\t\t\t// Define alias to the config data: `chart.data === chart.config.data`\n\t\t\tObject.defineProperty(me, 'data', {\n\t\t\t\tget: function() {\n\t\t\t\t\treturn me.config.data;\n\t\t\t\t},\n\t\t\t\tset: function(value) {\n\t\t\t\t\tme.config.data = value;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (!context || !canvas) {\n\t\t\t\t// The given item is not a compatible context2d element, let's return before finalizing\n\t\t\t\t// the chart initialization but after setting basic chart / controller properties that\n\t\t\t\t// can help to figure out that the chart is not valid (e.g chart.canvas !== null);\n\t\t\t\t// https://github.com/chartjs/Chart.js/issues/2807\n\t\t\t\tconsole.error(\"Failed to create chart: can't acquire context from the given item\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tme.initialize();\n\t\t\tme.update();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tinitialize: function() {\n\t\t\tvar me = this;\n\n\t\t\t// Before init plugin notification\n\t\t\tplugins.notify(me, 'beforeInit');\n\n\t\t\thelpers.retinaScale(me, me.options.devicePixelRatio);\n\n\t\t\tme.bindEvents();\n\n\t\t\tif (me.options.responsive) {\n\t\t\t\t// Initial resize before chart draws (must be silent to preserve initial animations).\n\t\t\t\tme.resize(true);\n\t\t\t}\n\n\t\t\t// Make sure scales have IDs and are built before we build any controllers.\n\t\t\tme.ensureScalesHaveIDs();\n\t\t\tme.buildOrUpdateScales();\n\t\t\tme.initToolTip();\n\n\t\t\t// After init plugin notification\n\t\t\tplugins.notify(me, 'afterInit');\n\n\t\t\treturn me;\n\t\t},\n\n\t\tclear: function() {\n\t\t\thelpers.canvas.clear(this);\n\t\t\treturn this;\n\t\t},\n\n\t\tstop: function() {\n\t\t\t// Stops any current animation loop occurring\n\t\t\tanimations.cancelAnimation(this);\n\t\t\treturn this;\n\t\t},\n\n\t\tresize: function(silent) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tvar canvas = me.canvas;\n\t\t\tvar aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;\n\n\t\t\t// the canvas render width and height will be casted to integers so make sure that\n\t\t\t// the canvas display style uses the same integer values to avoid blurring effect.\n\n\t\t\t// Set to 0 instead of canvas.size because the size defaults to 300x150 if the element is collapsed\n\t\t\tvar newWidth = Math.max(0, Math.floor(helpers.getMaximumWidth(canvas)));\n\t\t\tvar newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas)));\n\n\t\t\tif (me.width === newWidth && me.height === newHeight) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcanvas.width = me.width = newWidth;\n\t\t\tcanvas.height = me.height = newHeight;\n\t\t\tcanvas.style.width = newWidth + 'px';\n\t\t\tcanvas.style.height = newHeight + 'px';\n\n\t\t\thelpers.retinaScale(me, options.devicePixelRatio);\n\n\t\t\tif (!silent) {\n\t\t\t\t// Notify any plugins about the resize\n\t\t\t\tvar newSize = {width: newWidth, height: newHeight};\n\t\t\t\tplugins.notify(me, 'resize', [newSize]);\n\n\t\t\t\t// Notify of resize\n\t\t\t\tif (me.options.onResize) {\n\t\t\t\t\tme.options.onResize(me, newSize);\n\t\t\t\t}\n\n\t\t\t\tme.stop();\n\t\t\t\tme.update({\n\t\t\t\t\tduration: me.options.responsiveAnimationDuration\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\tensureScalesHaveIDs: function() {\n\t\t\tvar options = this.options;\n\t\t\tvar scalesOptions = options.scales || {};\n\t\t\tvar scaleOptions = options.scale;\n\n\t\t\thelpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {\n\t\t\t\txAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);\n\t\t\t});\n\n\t\t\thelpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {\n\t\t\t\tyAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);\n\t\t\t});\n\n\t\t\tif (scaleOptions) {\n\t\t\t\tscaleOptions.id = scaleOptions.id || 'scale';\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Builds a map of scale ID to scale object for future lookup.\n\t\t */\n\t\tbuildOrUpdateScales: function() {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tvar scales = me.scales || {};\n\t\t\tvar items = [];\n\t\t\tvar updated = Object.keys(scales).reduce(function(obj, id) {\n\t\t\t\tobj[id] = false;\n\t\t\t\treturn obj;\n\t\t\t}, {});\n\n\t\t\tif (options.scales) {\n\t\t\t\titems = items.concat(\n\t\t\t\t\t(options.scales.xAxes || []).map(function(xAxisOptions) {\n\t\t\t\t\t\treturn {options: xAxisOptions, dtype: 'category', dposition: 'bottom'};\n\t\t\t\t\t}),\n\t\t\t\t\t(options.scales.yAxes || []).map(function(yAxisOptions) {\n\t\t\t\t\t\treturn {options: yAxisOptions, dtype: 'linear', dposition: 'left'};\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (options.scale) {\n\t\t\t\titems.push({\n\t\t\t\t\toptions: options.scale,\n\t\t\t\t\tdtype: 'radialLinear',\n\t\t\t\t\tisDefault: true,\n\t\t\t\t\tdposition: 'chartArea'\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thelpers.each(items, function(item) {\n\t\t\t\tvar scaleOptions = item.options;\n\t\t\t\tvar id = scaleOptions.id;\n\t\t\t\tvar scaleType = helpers.valueOrDefault(scaleOptions.type, item.dtype);\n\n\t\t\t\tif (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {\n\t\t\t\t\tscaleOptions.position = item.dposition;\n\t\t\t\t}\n\n\t\t\t\tupdated[id] = true;\n\t\t\t\tvar scale = null;\n\t\t\t\tif (id in scales && scales[id].type === scaleType) {\n\t\t\t\t\tscale = scales[id];\n\t\t\t\t\tscale.options = scaleOptions;\n\t\t\t\t\tscale.ctx = me.ctx;\n\t\t\t\t\tscale.chart = me;\n\t\t\t\t} else {\n\t\t\t\t\tvar scaleClass = scaleService.getScaleConstructor(scaleType);\n\t\t\t\t\tif (!scaleClass) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tscale = new scaleClass({\n\t\t\t\t\t\tid: id,\n\t\t\t\t\t\ttype: scaleType,\n\t\t\t\t\t\toptions: scaleOptions,\n\t\t\t\t\t\tctx: me.ctx,\n\t\t\t\t\t\tchart: me\n\t\t\t\t\t});\n\t\t\t\t\tscales[scale.id] = scale;\n\t\t\t\t}\n\n\t\t\t\tscale.mergeTicksOptions();\n\n\t\t\t\t// TODO(SB): I think we should be able to remove this custom case (options.scale)\n\t\t\t\t// and consider it as a regular scale part of the \"scales\"\" map only! This would\n\t\t\t\t// make the logic easier and remove some useless? custom code.\n\t\t\t\tif (item.isDefault) {\n\t\t\t\t\tme.scale = scale;\n\t\t\t\t}\n\t\t\t});\n\t\t\t// clear up discarded scales\n\t\t\thelpers.each(updated, function(hasUpdated, id) {\n\t\t\t\tif (!hasUpdated) {\n\t\t\t\t\tdelete scales[id];\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tme.scales = scales;\n\n\t\t\tscaleService.addScalesToLayout(this);\n\t\t},\n\n\t\tbuildOrUpdateControllers: function() {\n\t\t\tvar me = this;\n\t\t\tvar types = [];\n\t\t\tvar newControllers = [];\n\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tvar meta = me.getDatasetMeta(datasetIndex);\n\t\t\t\tvar type = dataset.type || me.config.type;\n\n\t\t\t\tif (meta.type && meta.type !== type) {\n\t\t\t\t\tme.destroyDatasetMeta(datasetIndex);\n\t\t\t\t\tmeta = me.getDatasetMeta(datasetIndex);\n\t\t\t\t}\n\t\t\t\tmeta.type = type;\n\n\t\t\t\ttypes.push(meta.type);\n\n\t\t\t\tif (meta.controller) {\n\t\t\t\t\tmeta.controller.updateIndex(datasetIndex);\n\t\t\t\t\tmeta.controller.linkScales();\n\t\t\t\t} else {\n\t\t\t\t\tvar ControllerClass = Chart.controllers[meta.type];\n\t\t\t\t\tif (ControllerClass === undefined) {\n\t\t\t\t\t\tthrow new Error('\"' + meta.type + '\" is not a chart type.');\n\t\t\t\t\t}\n\n\t\t\t\t\tmeta.controller = new ControllerClass(me, datasetIndex);\n\t\t\t\t\tnewControllers.push(meta.controller);\n\t\t\t\t}\n\t\t\t}, me);\n\n\t\t\treturn newControllers;\n\t\t},\n\n\t\t/**\n\t\t * Reset the elements of all datasets\n\t\t * @private\n\t\t */\n\t\tresetElements: function() {\n\t\t\tvar me = this;\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tme.getDatasetMeta(datasetIndex).controller.reset();\n\t\t\t}, me);\n\t\t},\n\n\t\t/**\n\t\t* Resets the chart back to it's state before the initial animation\n\t\t*/\n\t\treset: function() {\n\t\t\tthis.resetElements();\n\t\t\tthis.tooltip.initialize();\n\t\t},\n\n\t\tupdate: function(config) {\n\t\t\tvar me = this;\n\n\t\t\tif (!config || typeof config !== 'object') {\n\t\t\t\t// backwards compatibility\n\t\t\t\tconfig = {\n\t\t\t\t\tduration: config,\n\t\t\t\t\tlazy: arguments[1]\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tupdateConfig(me);\n\n\t\t\t// plugins options references might have change, let's invalidate the cache\n\t\t\t// https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167\n\t\t\tplugins._invalidate(me);\n\n\t\t\tif (plugins.notify(me, 'beforeUpdate') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// In case the entire data object changed\n\t\t\tme.tooltip._data = me.data;\n\n\t\t\t// Make sure dataset controllers are updated and new controllers are reset\n\t\t\tvar newControllers = me.buildOrUpdateControllers();\n\n\t\t\t// Make sure all dataset controllers have correct meta data counts\n\t\t\thelpers.each(me.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tme.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();\n\t\t\t}, me);\n\n\t\t\tme.updateLayout();\n\n\t\t\t// Can only reset the new controllers after the scales have been updated\n\t\t\tif (me.options.animation && me.options.animation.duration) {\n\t\t\t\thelpers.each(newControllers, function(controller) {\n\t\t\t\t\tcontroller.reset();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tme.updateDatasets();\n\n\t\t\t// Need to reset tooltip in case it is displayed with elements that are removed\n\t\t\t// after update.\n\t\t\tme.tooltip.initialize();\n\n\t\t\t// Last active contains items that were previously in the tooltip.\n\t\t\t// When we reset the tooltip, we need to clear it\n\t\t\tme.lastActive = [];\n\n\t\t\t// Do this before render so that any plugins that need final scale updates can use it\n\t\t\tplugins.notify(me, 'afterUpdate');\n\n\t\t\tif (me._bufferedRender) {\n\t\t\t\tme._bufferedRequest = {\n\t\t\t\t\tduration: config.duration,\n\t\t\t\t\teasing: config.easing,\n\t\t\t\t\tlazy: config.lazy\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tme.render(config);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Updates the chart layout unless a plugin returns `false` to the `beforeLayout`\n\t\t * hook, in which case, plugins will not be called on `afterLayout`.\n\t\t * @private\n\t\t */\n\t\tupdateLayout: function() {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeLayout') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlayouts.update(this, this.width, this.height);\n\n\t\t\t/**\n\t\t\t * Provided for backward compatibility, use `afterLayout` instead.\n\t\t\t * @method IPlugin#afterScaleUpdate\n\t\t\t * @deprecated since version 2.5.0\n\t\t\t * @todo remove at version 3\n\t\t\t * @private\n\t\t\t */\n\t\t\tplugins.notify(me, 'afterScaleUpdate');\n\t\t\tplugins.notify(me, 'afterLayout');\n\t\t},\n\n\t\t/**\n\t\t * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetsUpdate`.\n\t\t * @private\n\t\t */\n\t\tupdateDatasets: function() {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetsUpdate') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\n\t\t\t\tme.updateDataset(i);\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'afterDatasetsUpdate');\n\t\t},\n\n\t\t/**\n\t\t * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetUpdate`.\n\t\t * @private\n\t\t */\n\t\tupdateDataset: function(index) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getDatasetMeta(index);\n\t\t\tvar args = {\n\t\t\t\tmeta: meta,\n\t\t\t\tindex: index\n\t\t\t};\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmeta.controller.update();\n\n\t\t\tplugins.notify(me, 'afterDatasetUpdate', [args]);\n\t\t},\n\n\t\trender: function(config) {\n\t\t\tvar me = this;\n\n\t\t\tif (!config || typeof config !== 'object') {\n\t\t\t\t// backwards compatibility\n\t\t\t\tconfig = {\n\t\t\t\t\tduration: config,\n\t\t\t\t\tlazy: arguments[1]\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tvar duration = config.duration;\n\t\t\tvar lazy = config.lazy;\n\n\t\t\tif (plugins.notify(me, 'beforeRender') === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar animationOptions = me.options.animation;\n\t\t\tvar onComplete = function(animation) {\n\t\t\t\tplugins.notify(me, 'afterRender');\n\t\t\t\thelpers.callback(animationOptions && animationOptions.onComplete, [animation], me);\n\t\t\t};\n\n\t\t\tif (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {\n\t\t\t\tvar animation = new Animation({\n\t\t\t\t\tnumSteps: (duration || animationOptions.duration) / 16.66, // 60 fps\n\t\t\t\t\teasing: config.easing || animationOptions.easing,\n\n\t\t\t\t\trender: function(chart, animationObject) {\n\t\t\t\t\t\tvar easingFunction = helpers.easing.effects[animationObject.easing];\n\t\t\t\t\t\tvar currentStep = animationObject.currentStep;\n\t\t\t\t\t\tvar stepDecimal = currentStep / animationObject.numSteps;\n\n\t\t\t\t\t\tchart.draw(easingFunction(stepDecimal), stepDecimal, currentStep);\n\t\t\t\t\t},\n\n\t\t\t\t\tonAnimationProgress: animationOptions.onProgress,\n\t\t\t\t\tonAnimationComplete: onComplete\n\t\t\t\t});\n\n\t\t\t\tanimations.addAnimation(me, animation, duration, lazy);\n\t\t\t} else {\n\t\t\t\tme.draw();\n\n\t\t\t\t// See https://github.com/chartjs/Chart.js/issues/3781\n\t\t\t\tonComplete(new Animation({numSteps: 0, chart: me}));\n\t\t\t}\n\n\t\t\treturn me;\n\t\t},\n\n\t\tdraw: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tme.clear();\n\n\t\t\tif (helpers.isNullOrUndef(easingValue)) {\n\t\t\t\teasingValue = 1;\n\t\t\t}\n\n\t\t\tme.transition(easingValue);\n\n\t\t\tif (me.width <= 0 || me.height <= 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (plugins.notify(me, 'beforeDraw', [easingValue]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Draw all the scales\n\t\t\thelpers.each(me.boxes, function(box) {\n\t\t\t\tbox.draw(me.chartArea);\n\t\t\t}, me);\n\n\t\t\tif (me.scale) {\n\t\t\t\tme.scale.draw();\n\t\t\t}\n\n\t\t\tme.drawDatasets(easingValue);\n\t\t\tme._drawTooltip(easingValue);\n\n\t\t\tplugins.notify(me, 'afterDraw', [easingValue]);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\ttransition: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tfor (var i = 0, ilen = (me.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\tif (me.isDatasetVisible(i)) {\n\t\t\t\t\tme.getDatasetMeta(i).controller.transition(easingValue);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.tooltip.transition(easingValue);\n\t\t},\n\n\t\t/**\n\t\t * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetsDraw`.\n\t\t * @private\n\t\t */\n\t\tdrawDatasets: function(easingValue) {\n\t\t\tvar me = this;\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Draw datasets reversed to support proper line stacking\n\t\t\tfor (var i = (me.data.datasets || []).length - 1; i >= 0; --i) {\n\t\t\t\tif (me.isDatasetVisible(i)) {\n\t\t\t\t\tme.drawDataset(i, easingValue);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'afterDatasetsDraw', [easingValue]);\n\t\t},\n\n\t\t/**\n\t\t * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw`\n\t\t * hook, in which case, plugins will not be called on `afterDatasetDraw`.\n\t\t * @private\n\t\t */\n\t\tdrawDataset: function(index, easingValue) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getDatasetMeta(index);\n\t\t\tvar args = {\n\t\t\t\tmeta: meta,\n\t\t\t\tindex: index,\n\t\t\t\teasingValue: easingValue\n\t\t\t};\n\n\t\t\tif (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmeta.controller.draw(easingValue);\n\n\t\t\tplugins.notify(me, 'afterDatasetDraw', [args]);\n\t\t},\n\n\t\t/**\n\t\t * Draws tooltip unless a plugin returns `false` to the `beforeTooltipDraw`\n\t\t * hook, in which case, plugins will not be called on `afterTooltipDraw`.\n\t\t * @private\n\t\t */\n\t\t_drawTooltip: function(easingValue) {\n\t\t\tvar me = this;\n\t\t\tvar tooltip = me.tooltip;\n\t\t\tvar args = {\n\t\t\t\ttooltip: tooltip,\n\t\t\t\teasingValue: easingValue\n\t\t\t};\n\n\t\t\tif (plugins.notify(me, 'beforeTooltipDraw', [args]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttooltip.draw();\n\n\t\t\tplugins.notify(me, 'afterTooltipDraw', [args]);\n\t\t},\n\n\t\t// Get the single element that was clicked on\n\t\t// @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw\n\t\tgetElementAtEvent: function(e) {\n\t\t\treturn Interaction.modes.single(this, e);\n\t\t},\n\n\t\tgetElementsAtEvent: function(e) {\n\t\t\treturn Interaction.modes.label(this, e, {intersect: true});\n\t\t},\n\n\t\tgetElementsAtXAxis: function(e) {\n\t\t\treturn Interaction.modes['x-axis'](this, e, {intersect: true});\n\t\t},\n\n\t\tgetElementsAtEventForMode: function(e, mode, options) {\n\t\t\tvar method = Interaction.modes[mode];\n\t\t\tif (typeof method === 'function') {\n\t\t\t\treturn method(this, e, options);\n\t\t\t}\n\n\t\t\treturn [];\n\t\t},\n\n\t\tgetDatasetAtEvent: function(e) {\n\t\t\treturn Interaction.modes.dataset(this, e, {intersect: true});\n\t\t},\n\n\t\tgetDatasetMeta: function(datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.data.datasets[datasetIndex];\n\t\t\tif (!dataset._meta) {\n\t\t\t\tdataset._meta = {};\n\t\t\t}\n\n\t\t\tvar meta = dataset._meta[me.id];\n\t\t\tif (!meta) {\n\t\t\t\tmeta = dataset._meta[me.id] = {\n\t\t\t\t\ttype: null,\n\t\t\t\t\tdata: [],\n\t\t\t\t\tdataset: null,\n\t\t\t\t\tcontroller: null,\n\t\t\t\t\thidden: null,\t\t\t// See isDatasetVisible() comment\n\t\t\t\t\txAxisID: null,\n\t\t\t\t\tyAxisID: null\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn meta;\n\t\t},\n\n\t\tgetVisibleDatasetCount: function() {\n\t\t\tvar count = 0;\n\t\t\tfor (var i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {\n\t\t\t\tif (this.isDatasetVisible(i)) {\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn count;\n\t\t},\n\n\t\tisDatasetVisible: function(datasetIndex) {\n\t\t\tvar meta = this.getDatasetMeta(datasetIndex);\n\n\t\t\t// meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,\n\t\t\t// the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.\n\t\t\treturn typeof meta.hidden === 'boolean' ? !meta.hidden : !this.data.datasets[datasetIndex].hidden;\n\t\t},\n\n\t\tgenerateLegend: function() {\n\t\t\treturn this.options.legendCallback(this);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tdestroyDatasetMeta: function(datasetIndex) {\n\t\t\tvar id = this.id;\n\t\t\tvar dataset = this.data.datasets[datasetIndex];\n\t\t\tvar meta = dataset._meta && dataset._meta[id];\n\n\t\t\tif (meta) {\n\t\t\t\tmeta.controller.destroy();\n\t\t\t\tdelete dataset._meta[id];\n\t\t\t}\n\t\t},\n\n\t\tdestroy: function() {\n\t\t\tvar me = this;\n\t\t\tvar canvas = me.canvas;\n\t\t\tvar i, ilen;\n\n\t\t\tme.stop();\n\n\t\t\t// dataset controllers need to cleanup associated data\n\t\t\tfor (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\n\t\t\t\tme.destroyDatasetMeta(i);\n\t\t\t}\n\n\t\t\tif (canvas) {\n\t\t\t\tme.unbindEvents();\n\t\t\t\thelpers.canvas.clear(me);\n\t\t\t\tplatform.releaseContext(me.ctx);\n\t\t\t\tme.canvas = null;\n\t\t\t\tme.ctx = null;\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'destroy');\n\n\t\t\tdelete Chart.instances[me.id];\n\t\t},\n\n\t\ttoBase64Image: function() {\n\t\t\treturn this.canvas.toDataURL.apply(this.canvas, arguments);\n\t\t},\n\n\t\tinitToolTip: function() {\n\t\t\tvar me = this;\n\t\t\tme.tooltip = new Tooltip({\n\t\t\t\t_chart: me,\n\t\t\t\t_chartInstance: me, // deprecated, backward compatibility\n\t\t\t\t_data: me.data,\n\t\t\t\t_options: me.options.tooltips\n\t\t\t}, me);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tbindEvents: function() {\n\t\t\tvar me = this;\n\t\t\tvar listeners = me._listeners = {};\n\t\t\tvar listener = function() {\n\t\t\t\tme.eventHandler.apply(me, arguments);\n\t\t\t};\n\n\t\t\thelpers.each(me.options.events, function(type) {\n\t\t\t\tplatform.addEventListener(me, type, listener);\n\t\t\t\tlisteners[type] = listener;\n\t\t\t});\n\n\t\t\t// Elements used to detect size change should not be injected for non responsive charts.\n\t\t\t// See https://github.com/chartjs/Chart.js/issues/2210\n\t\t\tif (me.options.responsive) {\n\t\t\t\tlistener = function() {\n\t\t\t\t\tme.resize();\n\t\t\t\t};\n\n\t\t\t\tplatform.addEventListener(me, 'resize', listener);\n\t\t\t\tlisteners.resize = listener;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tunbindEvents: function() {\n\t\t\tvar me = this;\n\t\t\tvar listeners = me._listeners;\n\t\t\tif (!listeners) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdelete me._listeners;\n\t\t\thelpers.each(listeners, function(listener, type) {\n\t\t\t\tplatform.removeEventListener(me, type, listener);\n\t\t\t});\n\t\t},\n\n\t\tupdateHoverStyle: function(elements, mode, enabled) {\n\t\t\tvar method = enabled ? 'setHoverStyle' : 'removeHoverStyle';\n\t\t\tvar element, i, ilen;\n\n\t\t\tfor (i = 0, ilen = elements.length; i < ilen; ++i) {\n\t\t\t\telement = elements[i];\n\t\t\t\tif (element) {\n\t\t\t\t\tthis.getDatasetMeta(element._datasetIndex).controller[method](element);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\teventHandler: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar tooltip = me.tooltip;\n\n\t\t\tif (plugins.notify(me, 'beforeEvent', [e]) === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Buffer any update calls so that renders do not occur\n\t\t\tme._bufferedRender = true;\n\t\t\tme._bufferedRequest = null;\n\n\t\t\tvar changed = me.handleEvent(e);\n\t\t\t// for smooth tooltip animations issue #4989\n\t\t\t// the tooltip should be the source of change\n\t\t\t// Animation check workaround:\n\t\t\t// tooltip._start will be null when tooltip isn't animating\n\t\t\tif (tooltip) {\n\t\t\t\tchanged = tooltip._start\n\t\t\t\t\t? tooltip.handleEvent(e)\n\t\t\t\t\t: changed | tooltip.handleEvent(e);\n\t\t\t}\n\n\t\t\tplugins.notify(me, 'afterEvent', [e]);\n\n\t\t\tvar bufferedRequest = me._bufferedRequest;\n\t\t\tif (bufferedRequest) {\n\t\t\t\t// If we have an update that was triggered, we need to do a normal render\n\t\t\t\tme.render(bufferedRequest);\n\t\t\t} else if (changed && !me.animating) {\n\t\t\t\t// If entering, leaving, or changing elements, animate the change via pivot\n\t\t\t\tme.stop();\n\n\t\t\t\t// We only need to render at this point. Updating will cause scales to be\n\t\t\t\t// recomputed generating flicker & using more memory than necessary.\n\t\t\t\tme.render({\n\t\t\t\t\tduration: me.options.hover.animationDuration,\n\t\t\t\t\tlazy: true\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tme._bufferedRender = false;\n\t\t\tme._bufferedRequest = null;\n\n\t\t\treturn me;\n\t\t},\n\n\t\t/**\n\t\t * Handle an event\n\t\t * @private\n\t\t * @param {IEvent} event the event to handle\n\t\t * @return {Boolean} true if the chart needs to re-render\n\t\t */\n\t\thandleEvent: function(e) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options || {};\n\t\t\tvar hoverOptions = options.hover;\n\t\t\tvar changed = false;\n\n\t\t\tme.lastActive = me.lastActive || [];\n\n\t\t\t// Find Active Elements for hover and tooltips\n\t\t\tif (e.type === 'mouseout') {\n\t\t\t\tme.active = [];\n\t\t\t} else {\n\t\t\t\tme.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);\n\t\t\t}\n\n\t\t\t// Invoke onHover hook\n\t\t\t// Need to call with native event here to not break backwards compatibility\n\t\t\thelpers.callback(options.onHover || options.hover.onHover, [e.native, me.active], me);\n\n\t\t\tif (e.type === 'mouseup' || e.type === 'click') {\n\t\t\t\tif (options.onClick) {\n\t\t\t\t\t// Use e.native here for backwards compatibility\n\t\t\t\t\toptions.onClick.call(me, e.native, me.active);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove styling for last active (even if it may still be active)\n\t\t\tif (me.lastActive.length) {\n\t\t\t\tme.updateHoverStyle(me.lastActive, hoverOptions.mode, false);\n\t\t\t}\n\n\t\t\t// Built in hover styling\n\t\t\tif (me.active.length && hoverOptions.mode) {\n\t\t\t\tme.updateHoverStyle(me.active, hoverOptions.mode, true);\n\t\t\t}\n\n\t\t\tchanged = !helpers.arrayEquals(me.active, me.lastActive);\n\n\t\t\t// Remember Last Actives\n\t\t\tme.lastActive = me.active;\n\n\t\t\treturn changed;\n\t\t}\n\t});\n\n\t/**\n\t * Provided for backward compatibility, use Chart instead.\n\t * @class Chart.Controller\n\t * @deprecated since version 2.6.0\n\t * @todo remove at version 3\n\t * @private\n\t */\n\tChart.Controller = Chart;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjNhOS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmNvbnRyb2xsZXIuanM/ZWFiYSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBBbmltYXRpb24gPSByZXF1aXJlKCcuL2NvcmUuYW5pbWF0aW9uJyk7XG52YXIgYW5pbWF0aW9ucyA9IHJlcXVpcmUoJy4vY29yZS5hbmltYXRpb25zJyk7XG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2NvcmUuZGVmYXVsdHMnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi9jb3JlLmludGVyYWN0aW9uJyk7XG52YXIgbGF5b3V0cyA9IHJlcXVpcmUoJy4vY29yZS5sYXlvdXRzJyk7XG52YXIgcGxhdGZvcm0gPSByZXF1aXJlKCcuLi9wbGF0Zm9ybXMvcGxhdGZvcm0nKTtcbnZhciBwbHVnaW5zID0gcmVxdWlyZSgnLi9jb3JlLnBsdWdpbnMnKTtcbnZhciBzY2FsZVNlcnZpY2UgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuc2NhbGVTZXJ2aWNlJyk7XG52YXIgVG9vbHRpcCA9IHJlcXVpcmUoJy4vY29yZS50b29sdGlwJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oQ2hhcnQpIHtcblxuXHQvLyBDcmVhdGUgYSBkaWN0aW9uYXJ5IG9mIGNoYXJ0IHR5cGVzLCB0byBhbGxvdyBmb3IgZXh0ZW5zaW9uIG9mIGV4aXN0aW5nIHR5cGVzXG5cdENoYXJ0LnR5cGVzID0ge307XG5cblx0Ly8gU3RvcmUgYSByZWZlcmVuY2UgdG8gZWFjaCBpbnN0YW5jZSAtIGFsbG93aW5nIHVzIHRvIGdsb2JhbGx5IHJlc2l6ZSBjaGFydCBpbnN0YW5jZXMgb24gd2luZG93IHJlc2l6ZS5cblx0Ly8gRGVzdHJveSBtZXRob2Qgb24gdGhlIGNoYXJ0IHdpbGwgcmVtb3ZlIHRoZSBpbnN0YW5jZSBvZiB0aGUgY2hhcnQgZnJvbSB0aGlzIHJlZmVyZW5jZS5cblx0Q2hhcnQuaW5zdGFuY2VzID0ge307XG5cblx0Ly8gQ29udHJvbGxlcnMgYXZhaWxhYmxlIGZvciBkYXRhc2V0IHZpc3VhbGl6YXRpb24gZWcuIGJhciwgbGluZSwgc2xpY2UsIGV0Yy5cblx0Q2hhcnQuY29udHJvbGxlcnMgPSB7fTtcblxuXHQvKipcblx0ICogSW5pdGlhbGl6ZXMgdGhlIGdpdmVuIGNvbmZpZyB3aXRoIGdsb2JhbCBhbmQgY2hhcnQgZGVmYXVsdCB2YWx1ZXMuXG5cdCAqL1xuXHRmdW5jdGlvbiBpbml0Q29uZmlnKGNvbmZpZykge1xuXHRcdGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcblxuXHRcdC8vIERvIE5PVCB1c2UgY29uZmlnTWVyZ2UoKSBmb3IgdGhlIGRhdGEgb2JqZWN0IGJlY2F1c2UgdGhpcyBtZXRob2QgbWVyZ2VzIGFycmF5c1xuXHRcdC8vIGFuZCBzbyB3b3VsZCBjaGFuZ2UgcmVmZXJlbmNlcyB0byBsYWJlbHMgYW5kIGRhdGFzZXRzLCBwcmV2ZW50aW5nIGRhdGEgdXBkYXRlcy5cblx0XHR2YXIgZGF0YSA9IGNvbmZpZy5kYXRhID0gY29uZmlnLmRhdGEgfHwge307XG5cdFx0ZGF0YS5kYXRhc2V0cyA9IGRhdGEuZGF0YXNldHMgfHwgW107XG5cdFx0ZGF0YS5sYWJlbHMgPSBkYXRhLmxhYmVscyB8fCBbXTtcblxuXHRcdGNvbmZpZy5vcHRpb25zID0gaGVscGVycy5jb25maWdNZXJnZShcblx0XHRcdGRlZmF1bHRzLmdsb2JhbCxcblx0XHRcdGRlZmF1bHRzW2NvbmZpZy50eXBlXSxcblx0XHRcdGNvbmZpZy5vcHRpb25zIHx8IHt9KTtcblxuXHRcdHJldHVybiBjb25maWc7XG5cdH1cblxuXHQvKipcblx0ICogVXBkYXRlcyB0aGUgY29uZmlnIG9mIHRoZSBjaGFydFxuXHQgKiBAcGFyYW0gY2hhcnQge0NoYXJ0fSBjaGFydCB0byB1cGRhdGUgdGhlIG9wdGlvbnMgZm9yXG5cdCAqL1xuXHRmdW5jdGlvbiB1cGRhdGVDb25maWcoY2hhcnQpIHtcblx0XHR2YXIgbmV3T3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnM7XG5cblx0XHRoZWxwZXJzLmVhY2goY2hhcnQuc2NhbGVzLCBmdW5jdGlvbihzY2FsZSkge1xuXHRcdFx0bGF5b3V0cy5yZW1vdmVCb3goY2hhcnQsIHNjYWxlKTtcblx0XHR9KTtcblxuXHRcdG5ld09wdGlvbnMgPSBoZWxwZXJzLmNvbmZpZ01lcmdlKFxuXHRcdFx0Q2hhcnQuZGVmYXVsdHMuZ2xvYmFsLFxuXHRcdFx0Q2hhcnQuZGVmYXVsdHNbY2hhcnQuY29uZmlnLnR5cGVdLFxuXHRcdFx0bmV3T3B0aW9ucyk7XG5cblx0XHRjaGFydC5vcHRpb25zID0gY2hhcnQuY29uZmlnLm9wdGlvbnMgPSBuZXdPcHRpb25zO1xuXHRcdGNoYXJ0LmVuc3VyZVNjYWxlc0hhdmVJRHMoKTtcblx0XHRjaGFydC5idWlsZE9yVXBkYXRlU2NhbGVzKCk7XG5cdFx0Ly8gVG9vbHRpcFxuXHRcdGNoYXJ0LnRvb2x0aXAuX29wdGlvbnMgPSBuZXdPcHRpb25zLnRvb2x0aXBzO1xuXHRcdGNoYXJ0LnRvb2x0aXAuaW5pdGlhbGl6ZSgpO1xuXHR9XG5cblx0ZnVuY3Rpb24gcG9zaXRpb25Jc0hvcml6b250YWwocG9zaXRpb24pIHtcblx0XHRyZXR1cm4gcG9zaXRpb24gPT09ICd0b3AnIHx8IHBvc2l0aW9uID09PSAnYm90dG9tJztcblx0fVxuXG5cdGhlbHBlcnMuZXh0ZW5kKENoYXJ0LnByb3RvdHlwZSwgLyoqIEBsZW5kcyBDaGFydCAqLyB7XG5cdFx0LyoqXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRjb25zdHJ1Y3Q6IGZ1bmN0aW9uKGl0ZW0sIGNvbmZpZykge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblxuXHRcdFx0Y29uZmlnID0gaW5pdENvbmZpZyhjb25maWcpO1xuXG5cdFx0XHR2YXIgY29udGV4dCA9IHBsYXRmb3JtLmFjcXVpcmVDb250ZXh0KGl0ZW0sIGNvbmZpZyk7XG5cdFx0XHR2YXIgY2FudmFzID0gY29udGV4dCAmJiBjb250ZXh0LmNhbnZhcztcblx0XHRcdHZhciBoZWlnaHQgPSBjYW52YXMgJiYgY2FudmFzLmhlaWdodDtcblx0XHRcdHZhciB3aWR0aCA9IGNhbnZhcyAmJiBjYW52YXMud2lkdGg7XG5cblx0XHRcdG1lLmlkID0gaGVscGVycy51aWQoKTtcblx0XHRcdG1lLmN0eCA9IGNvbnRleHQ7XG5cdFx0XHRtZS5jYW52YXMgPSBjYW52YXM7XG5cdFx0XHRtZS5jb25maWcgPSBjb25maWc7XG5cdFx0XHRtZS53aWR0aCA9IHdpZHRoO1xuXHRcdFx0bWUuaGVpZ2h0ID0gaGVpZ2h0O1xuXHRcdFx0bWUuYXNwZWN0UmF0aW8gPSBoZWlnaHQgPyB3aWR0aCAvIGhlaWdodCA6IG51bGw7XG5cdFx0XHRtZS5vcHRpb25zID0gY29uZmlnLm9wdGlvbnM7XG5cdFx0XHRtZS5fYnVmZmVyZWRSZW5kZXIgPSBmYWxzZTtcblxuXHRcdFx0LyoqXG5cdFx0XHQgKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgQ2hhcnQgYW5kIENoYXJ0LkNvbnRyb2xsZXIgaGF2ZSBiZWVuIG1lcmdlZCxcblx0XHRcdCAqIHRoZSBcImluc3RhbmNlXCIgc3RpbGwgbmVlZCB0byBiZSBkZWZpbmVkIHNpbmNlIGl0IG1pZ2h0IGJlIGNhbGxlZCBmcm9tIHBsdWdpbnMuXG5cdFx0XHQgKiBAcHJvcCBDaGFydCNjaGFydFxuXHRcdFx0ICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjYuMFxuXHRcdFx0ICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHRcdFx0bWUuY2hhcnQgPSBtZTtcblx0XHRcdG1lLmNvbnRyb2xsZXIgPSBtZTsgLy8gY2hhcnQuY2hhcnQuY29udHJvbGxlciAjaW5jZXB0aW9uXG5cblx0XHRcdC8vIEFkZCB0aGUgY2hhcnQgaW5zdGFuY2UgdG8gdGhlIGdsb2JhbCBuYW1lc3BhY2Vcblx0XHRcdENoYXJ0Lmluc3RhbmNlc1ttZS5pZF0gPSBtZTtcblxuXHRcdFx0Ly8gRGVmaW5lIGFsaWFzIHRvIHRoZSBjb25maWcgZGF0YTogYGNoYXJ0LmRhdGEgPT09IGNoYXJ0LmNvbmZpZy5kYXRhYFxuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1lLCAnZGF0YScsIHtcblx0XHRcdFx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gbWUuY29uZmlnLmRhdGE7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHNldDogZnVuY3Rpb24odmFsdWUpIHtcblx0XHRcdFx0XHRtZS5jb25maWcuZGF0YSA9IHZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0aWYgKCFjb250ZXh0IHx8ICFjYW52YXMpIHtcblx0XHRcdFx0Ly8gVGhlIGdpdmVuIGl0ZW0gaXMgbm90IGEgY29tcGF0aWJsZSBjb250ZXh0MmQgZWxlbWVudCwgbGV0J3MgcmV0dXJuIGJlZm9yZSBmaW5hbGl6aW5nXG5cdFx0XHRcdC8vIHRoZSBjaGFydCBpbml0aWFsaXphdGlvbiBidXQgYWZ0ZXIgc2V0dGluZyBiYXNpYyBjaGFydCAvIGNvbnRyb2xsZXIgcHJvcGVydGllcyB0aGF0XG5cdFx0XHRcdC8vIGNhbiBoZWxwIHRvIGZpZ3VyZSBvdXQgdGhhdCB0aGUgY2hhcnQgaXMgbm90IHZhbGlkIChlLmcgY2hhcnQuY2FudmFzICE9PSBudWxsKTtcblx0XHRcdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzI4MDdcblx0XHRcdFx0Y29uc29sZS5lcnJvcihcIkZhaWxlZCB0byBjcmVhdGUgY2hhcnQ6IGNhbid0IGFjcXVpcmUgY29udGV4dCBmcm9tIHRoZSBnaXZlbiBpdGVtXCIpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdG1lLmluaXRpYWxpemUoKTtcblx0XHRcdG1lLnVwZGF0ZSgpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdGluaXRpYWxpemU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblxuXHRcdFx0Ly8gQmVmb3JlIGluaXQgcGx1Z2luIG5vdGlmaWNhdGlvblxuXHRcdFx0cGx1Z2lucy5ub3RpZnkobWUsICdiZWZvcmVJbml0Jyk7XG5cblx0XHRcdGhlbHBlcnMucmV0aW5hU2NhbGUobWUsIG1lLm9wdGlvbnMuZGV2aWNlUGl4ZWxSYXRpbyk7XG5cblx0XHRcdG1lLmJpbmRFdmVudHMoKTtcblxuXHRcdFx0aWYgKG1lLm9wdGlvbnMucmVzcG9uc2l2ZSkge1xuXHRcdFx0XHQvLyBJbml0aWFsIHJlc2l6ZSBiZWZvcmUgY2hhcnQgZHJhd3MgKG11c3QgYmUgc2lsZW50IHRvIHByZXNlcnZlIGluaXRpYWwgYW5pbWF0aW9ucykuXG5cdFx0XHRcdG1lLnJlc2l6ZSh0cnVlKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHNjYWxlcyBoYXZlIElEcyBhbmQgYXJlIGJ1aWx0IGJlZm9yZSB3ZSBidWlsZCBhbnkgY29udHJvbGxlcnMuXG5cdFx0XHRtZS5lbnN1cmVTY2FsZXNIYXZlSURzKCk7XG5cdFx0XHRtZS5idWlsZE9yVXBkYXRlU2NhbGVzKCk7XG5cdFx0XHRtZS5pbml0VG9vbFRpcCgpO1xuXG5cdFx0XHQvLyBBZnRlciBpbml0IHBsdWdpbiBub3RpZmljYXRpb25cblx0XHRcdHBsdWdpbnMubm90aWZ5KG1lLCAnYWZ0ZXJJbml0Jyk7XG5cblx0XHRcdHJldHVybiBtZTtcblx0XHR9LFxuXG5cdFx0Y2xlYXI6IGZ1bmN0aW9uKCkge1xuXHRcdFx0aGVscGVycy5jYW52YXMuY2xlYXIodGhpcyk7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9LFxuXG5cdFx0c3RvcDogZnVuY3Rpb24oKSB7XG5cdFx0XHQvLyBTdG9wcyBhbnkgY3VycmVudCBhbmltYXRpb24gbG9vcCBvY2N1cnJpbmdcblx0XHRcdGFuaW1hdGlvbnMuY2FuY2VsQW5pbWF0aW9uKHRoaXMpO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fSxcblxuXHRcdHJlc2l6ZTogZnVuY3Rpb24oc2lsZW50KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG9wdGlvbnMgPSBtZS5vcHRpb25zO1xuXHRcdFx0dmFyIGNhbnZhcyA9IG1lLmNhbnZhcztcblx0XHRcdHZhciBhc3BlY3RSYXRpbyA9IChvcHRpb25zLm1haW50YWluQXNwZWN0UmF0aW8gJiYgbWUuYXNwZWN0UmF0aW8pIHx8IG51bGw7XG5cblx0XHRcdC8vIHRoZSBjYW52YXMgcmVuZGVyIHdpZHRoIGFuZCBoZWlnaHQgd2lsbCBiZSBjYXN0ZWQgdG8gaW50ZWdlcnMgc28gbWFrZSBzdXJlIHRoYXRcblx0XHRcdC8vIHRoZSBjYW52YXMgZGlzcGxheSBzdHlsZSB1c2VzIHRoZSBzYW1lIGludGVnZXIgdmFsdWVzIHRvIGF2b2lkIGJsdXJyaW5nIGVmZmVjdC5cblxuXHRcdFx0Ly8gU2V0IHRvIDAgaW5zdGVhZCBvZiBjYW52YXMuc2l6ZSBiZWNhdXNlIHRoZSBzaXplIGRlZmF1bHRzIHRvIDMwMHgxNTAgaWYgdGhlIGVsZW1lbnQgaXMgY29sbGFwc2VkXG5cdFx0XHR2YXIgbmV3V2lkdGggPSBNYXRoLm1heCgwLCBNYXRoLmZsb29yKGhlbHBlcnMuZ2V0TWF4aW11bVdpZHRoKGNhbnZhcykpKTtcblx0XHRcdHZhciBuZXdIZWlnaHQgPSBNYXRoLm1heCgwLCBNYXRoLmZsb29yKGFzcGVjdFJhdGlvID8gbmV3V2lkdGggLyBhc3BlY3RSYXRpbyA6IGhlbHBlcnMuZ2V0TWF4aW11bUhlaWdodChjYW52YXMpKSk7XG5cblx0XHRcdGlmIChtZS53aWR0aCA9PT0gbmV3V2lkdGggJiYgbWUuaGVpZ2h0ID09PSBuZXdIZWlnaHQpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRjYW52YXMud2lkdGggPSBtZS53aWR0aCA9IG5ld1dpZHRoO1xuXHRcdFx0Y2FudmFzLmhlaWdodCA9IG1lLmhlaWdodCA9IG5ld0hlaWdodDtcblx0XHRcdGNhbnZhcy5zdHlsZS53aWR0aCA9IG5ld1dpZHRoICsgJ3B4Jztcblx0XHRcdGNhbnZhcy5zdHlsZS5oZWlnaHQgPSBuZXdIZWlnaHQgKyAncHgnO1xuXG5cdFx0XHRoZWxwZXJzLnJldGluYVNjYWxlKG1lLCBvcHRpb25zLmRldmljZVBpeGVsUmF0aW8pO1xuXG5cdFx0XHRpZiAoIXNpbGVudCkge1xuXHRcdFx0XHQvLyBOb3RpZnkgYW55IHBsdWdpbnMgYWJvdXQgdGhlIHJlc2l6ZVxuXHRcdFx0XHR2YXIgbmV3U2l6ZSA9IHt3aWR0aDogbmV3V2lkdGgsIGhlaWdodDogbmV3SGVpZ2h0fTtcblx0XHRcdFx0cGx1Z2lucy5ub3RpZnkobWUsICdyZXNpemUnLCBbbmV3U2l6ZV0pO1xuXG5cdFx0XHRcdC8vIE5vdGlmeSBvZiByZXNpemVcblx0XHRcdFx0aWYgKG1lLm9wdGlvbnMub25SZXNpemUpIHtcblx0XHRcdFx0XHRtZS5vcHRpb25zLm9uUmVzaXplKG1lLCBuZXdTaXplKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdG1lLnN0b3AoKTtcblx0XHRcdFx0bWUudXBkYXRlKHtcblx0XHRcdFx0XHRkdXJhdGlvbjogbWUub3B0aW9ucy5yZXNwb25zaXZlQW5pbWF0aW9uRHVyYXRpb25cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdGVuc3VyZVNjYWxlc0hhdmVJRHM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG5cdFx0XHR2YXIgc2NhbGVzT3B0aW9ucyA9IG9wdGlvbnMuc2NhbGVzIHx8IHt9O1xuXHRcdFx0dmFyIHNjYWxlT3B0aW9ucyA9IG9wdGlvbnMuc2NhbGU7XG5cblx0XHRcdGhlbHBlcnMuZWFjaChzY2FsZXNPcHRpb25zLnhBeGVzLCBmdW5jdGlvbih4QXhpc09wdGlvbnMsIGluZGV4KSB7XG5cdFx0XHRcdHhBeGlzT3B0aW9ucy5pZCA9IHhBeGlzT3B0aW9ucy5pZCB8fCAoJ3gtYXhpcy0nICsgaW5kZXgpO1xuXHRcdFx0fSk7XG5cblx0XHRcdGhlbHBlcnMuZWFjaChzY2FsZXNPcHRpb25zLnlBeGVzLCBmdW5jdGlvbih5QXhpc09wdGlvbnMsIGluZGV4KSB7XG5cdFx0XHRcdHlBeGlzT3B0aW9ucy5pZCA9IHlBeGlzT3B0aW9ucy5pZCB8fCAoJ3ktYXhpcy0nICsgaW5kZXgpO1xuXHRcdFx0fSk7XG5cblx0XHRcdGlmIChzY2FsZU9wdGlvbnMpIHtcblx0XHRcdFx0c2NhbGVPcHRpb25zLmlkID0gc2NhbGVPcHRpb25zLmlkIHx8ICdzY2FsZSc7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEJ1aWxkcyBhIG1hcCBvZiBzY2FsZSBJRCB0byBzY2FsZSBvYmplY3QgZm9yIGZ1dHVyZSBsb29rdXAuXG5cdFx0ICovXG5cdFx0YnVpbGRPclVwZGF0ZVNjYWxlczogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG9wdGlvbnMgPSBtZS5vcHRpb25zO1xuXHRcdFx0dmFyIHNjYWxlcyA9IG1lLnNjYWxlcyB8fCB7fTtcblx0XHRcdHZhciBpdGVtcyA9IFtdO1xuXHRcdFx0dmFyIHVwZGF0ZWQgPSBPYmplY3Qua2V5cyhzY2FsZXMpLnJlZHVjZShmdW5jdGlvbihvYmosIGlkKSB7XG5cdFx0XHRcdG9ialtpZF0gPSBmYWxzZTtcblx0XHRcdFx0cmV0dXJuIG9iajtcblx0XHRcdH0sIHt9KTtcblxuXHRcdFx0aWYgKG9wdGlvbnMuc2NhbGVzKSB7XG5cdFx0XHRcdGl0ZW1zID0gaXRlbXMuY29uY2F0KFxuXHRcdFx0XHRcdChvcHRpb25zLnNjYWxlcy54QXhlcyB8fCBbXSkubWFwKGZ1bmN0aW9uKHhBeGlzT3B0aW9ucykge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHtvcHRpb25zOiB4QXhpc09wdGlvbnMsIGR0eXBlOiAnY2F0ZWdvcnknLCBkcG9zaXRpb246ICdib3R0b20nfTtcblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHQob3B0aW9ucy5zY2FsZXMueUF4ZXMgfHwgW10pLm1hcChmdW5jdGlvbih5QXhpc09wdGlvbnMpIHtcblx0XHRcdFx0XHRcdHJldHVybiB7b3B0aW9uczogeUF4aXNPcHRpb25zLCBkdHlwZTogJ2xpbmVhcicsIGRwb3NpdGlvbjogJ2xlZnQnfTtcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAob3B0aW9ucy5zY2FsZSkge1xuXHRcdFx0XHRpdGVtcy5wdXNoKHtcblx0XHRcdFx0XHRvcHRpb25zOiBvcHRpb25zLnNjYWxlLFxuXHRcdFx0XHRcdGR0eXBlOiAncmFkaWFsTGluZWFyJyxcblx0XHRcdFx0XHRpc0RlZmF1bHQ6IHRydWUsXG5cdFx0XHRcdFx0ZHBvc2l0aW9uOiAnY2hhcnRBcmVhJ1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0aGVscGVycy5lYWNoKGl0ZW1zLCBmdW5jdGlvbihpdGVtKSB7XG5cdFx0XHRcdHZhciBzY2FsZU9wdGlvbnMgPSBpdGVtLm9wdGlvbnM7XG5cdFx0XHRcdHZhciBpZCA9IHNjYWxlT3B0aW9ucy5pZDtcblx0XHRcdFx0dmFyIHNjYWxlVHlwZSA9IGhlbHBlcnMudmFsdWVPckRlZmF1bHQoc2NhbGVPcHRpb25zLnR5cGUsIGl0ZW0uZHR5cGUpO1xuXG5cdFx0XHRcdGlmIChwb3NpdGlvbklzSG9yaXpvbnRhbChzY2FsZU9wdGlvbnMucG9zaXRpb24pICE9PSBwb3NpdGlvbklzSG9yaXpvbnRhbChpdGVtLmRwb3NpdGlvbikpIHtcblx0XHRcdFx0XHRzY2FsZU9wdGlvbnMucG9zaXRpb24gPSBpdGVtLmRwb3NpdGlvbjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHVwZGF0ZWRbaWRdID0gdHJ1ZTtcblx0XHRcdFx0dmFyIHNjYWxlID0gbnVsbDtcblx0XHRcdFx0aWYgKGlkIGluIHNjYWxlcyAmJiBzY2FsZXNbaWRdLnR5cGUgPT09IHNjYWxlVHlwZSkge1xuXHRcdFx0XHRcdHNjYWxlID0gc2NhbGVzW2lkXTtcblx0XHRcdFx0XHRzY2FsZS5vcHRpb25zID0gc2NhbGVPcHRpb25zO1xuXHRcdFx0XHRcdHNjYWxlLmN0eCA9IG1lLmN0eDtcblx0XHRcdFx0XHRzY2FsZS5jaGFydCA9IG1lO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHZhciBzY2FsZUNsYXNzID0gc2NhbGVTZXJ2aWNlLmdldFNjYWxlQ29uc3RydWN0b3Ioc2NhbGVUeXBlKTtcblx0XHRcdFx0XHRpZiAoIXNjYWxlQ2xhc3MpIHtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0c2NhbGUgPSBuZXcgc2NhbGVDbGFzcyh7XG5cdFx0XHRcdFx0XHRpZDogaWQsXG5cdFx0XHRcdFx0XHR0eXBlOiBzY2FsZVR5cGUsXG5cdFx0XHRcdFx0XHRvcHRpb25zOiBzY2FsZU9wdGlvbnMsXG5cdFx0XHRcdFx0XHRjdHg6IG1lLmN0eCxcblx0XHRcdFx0XHRcdGNoYXJ0OiBtZVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdHNjYWxlc1tzY2FsZS5pZF0gPSBzY2FsZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHNjYWxlLm1lcmdlVGlja3NPcHRpb25zKCk7XG5cblx0XHRcdFx0Ly8gVE9ETyhTQik6IEkgdGhpbmsgd2Ugc2hvdWxkIGJlIGFibGUgdG8gcmVtb3ZlIHRoaXMgY3VzdG9tIGNhc2UgKG9wdGlvbnMuc2NhbGUpXG5cdFx0XHRcdC8vIGFuZCBjb25zaWRlciBpdCBhcyBhIHJlZ3VsYXIgc2NhbGUgcGFydCBvZiB0aGUgXCJzY2FsZXNcIlwiIG1hcCBvbmx5ISBUaGlzIHdvdWxkXG5cdFx0XHRcdC8vIG1ha2UgdGhlIGxvZ2ljIGVhc2llciBhbmQgcmVtb3ZlIHNvbWUgdXNlbGVzcz8gY3VzdG9tIGNvZGUuXG5cdFx0XHRcdGlmIChpdGVtLmlzRGVmYXVsdCkge1xuXHRcdFx0XHRcdG1lLnNjYWxlID0gc2NhbGU7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0Ly8gY2xlYXIgdXAgZGlzY2FyZGVkIHNjYWxlc1xuXHRcdFx0aGVscGVycy5lYWNoKHVwZGF0ZWQsIGZ1bmN0aW9uKGhhc1VwZGF0ZWQsIGlkKSB7XG5cdFx0XHRcdGlmICghaGFzVXBkYXRlZCkge1xuXHRcdFx0XHRcdGRlbGV0ZSBzY2FsZXNbaWRdO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0bWUuc2NhbGVzID0gc2NhbGVzO1xuXG5cdFx0XHRzY2FsZVNlcnZpY2UuYWRkU2NhbGVzVG9MYXlvdXQodGhpcyk7XG5cdFx0fSxcblxuXHRcdGJ1aWxkT3JVcGRhdGVDb250cm9sbGVyczogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIHR5cGVzID0gW107XG5cdFx0XHR2YXIgbmV3Q29udHJvbGxlcnMgPSBbXTtcblxuXHRcdFx0aGVscGVycy5lYWNoKG1lLmRhdGEuZGF0YXNldHMsIGZ1bmN0aW9uKGRhdGFzZXQsIGRhdGFzZXRJbmRleCkge1xuXHRcdFx0XHR2YXIgbWV0YSA9IG1lLmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XG5cdFx0XHRcdHZhciB0eXBlID0gZGF0YXNldC50eXBlIHx8IG1lLmNvbmZpZy50eXBlO1xuXG5cdFx0XHRcdGlmIChtZXRhLnR5cGUgJiYgbWV0YS50eXBlICE9PSB0eXBlKSB7XG5cdFx0XHRcdFx0bWUuZGVzdHJveURhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XG5cdFx0XHRcdFx0bWV0YSA9IG1lLmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0bWV0YS50eXBlID0gdHlwZTtcblxuXHRcdFx0XHR0eXBlcy5wdXNoKG1ldGEudHlwZSk7XG5cblx0XHRcdFx0aWYgKG1ldGEuY29udHJvbGxlcikge1xuXHRcdFx0XHRcdG1ldGEuY29udHJvbGxlci51cGRhdGVJbmRleChkYXRhc2V0SW5kZXgpO1xuXHRcdFx0XHRcdG1ldGEuY29udHJvbGxlci5saW5rU2NhbGVzKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dmFyIENvbnRyb2xsZXJDbGFzcyA9IENoYXJ0LmNvbnRyb2xsZXJzW21ldGEudHlwZV07XG5cdFx0XHRcdFx0aWYgKENvbnRyb2xsZXJDbGFzcyA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1wiJyArIG1ldGEudHlwZSArICdcIiBpcyBub3QgYSBjaGFydCB0eXBlLicpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdG1ldGEuY29udHJvbGxlciA9IG5ldyBDb250cm9sbGVyQ2xhc3MobWUsIGRhdGFzZXRJbmRleCk7XG5cdFx0XHRcdFx0bmV3Q29udHJvbGxlcnMucHVzaChtZXRhLmNvbnRyb2xsZXIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LCBtZSk7XG5cblx0XHRcdHJldHVybiBuZXdDb250cm9sbGVycztcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogUmVzZXQgdGhlIGVsZW1lbnRzIG9mIGFsbCBkYXRhc2V0c1xuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0cmVzZXRFbGVtZW50czogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0aGVscGVycy5lYWNoKG1lLmRhdGEuZGF0YXNldHMsIGZ1bmN0aW9uKGRhdGFzZXQsIGRhdGFzZXRJbmRleCkge1xuXHRcdFx0XHRtZS5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpLmNvbnRyb2xsZXIucmVzZXQoKTtcblx0XHRcdH0sIG1lKTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0KiBSZXNldHMgdGhlIGNoYXJ0IGJhY2sgdG8gaXQncyBzdGF0ZSBiZWZvcmUgdGhlIGluaXRpYWwgYW5pbWF0aW9uXG5cdFx0Ki9cblx0XHRyZXNldDogZnVuY3Rpb24oKSB7XG5cdFx0XHR0aGlzLnJlc2V0RWxlbWVudHMoKTtcblx0XHRcdHRoaXMudG9vbHRpcC5pbml0aWFsaXplKCk7XG5cdFx0fSxcblxuXHRcdHVwZGF0ZTogZnVuY3Rpb24oY29uZmlnKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXG5cdFx0XHRpZiAoIWNvbmZpZyB8fCB0eXBlb2YgY29uZmlnICE9PSAnb2JqZWN0Jykge1xuXHRcdFx0XHQvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuXHRcdFx0XHRjb25maWcgPSB7XG5cdFx0XHRcdFx0ZHVyYXRpb246IGNvbmZpZyxcblx0XHRcdFx0XHRsYXp5OiBhcmd1bWVudHNbMV1cblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0dXBkYXRlQ29uZmlnKG1lKTtcblxuXHRcdFx0Ly8gcGx1Z2lucyBvcHRpb25zIHJlZmVyZW5jZXMgbWlnaHQgaGF2ZSBjaGFuZ2UsIGxldCdzIGludmFsaWRhdGUgdGhlIGNhY2hlXG5cdFx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvNTExMSNpc3N1ZWNvbW1lbnQtMzU1OTM0MTY3XG5cdFx0XHRwbHVnaW5zLl9pbnZhbGlkYXRlKG1lKTtcblxuXHRcdFx0aWYgKHBsdWdpbnMubm90aWZ5KG1lLCAnYmVmb3JlVXBkYXRlJykgPT09IGZhbHNlKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSW4gY2FzZSB0aGUgZW50aXJlIGRhdGEgb2JqZWN0IGNoYW5nZWRcblx0XHRcdG1lLnRvb2x0aXAuX2RhdGEgPSBtZS5kYXRhO1xuXG5cdFx0XHQvLyBNYWtlIHN1cmUgZGF0YXNldCBjb250cm9sbGVycyBhcmUgdXBkYXRlZCBhbmQgbmV3IGNvbnRyb2xsZXJzIGFyZSByZXNldFxuXHRcdFx0dmFyIG5ld0NvbnRyb2xsZXJzID0gbWUuYnVpbGRPclVwZGF0ZUNvbnRyb2xsZXJzKCk7XG5cblx0XHRcdC8vIE1ha2Ugc3VyZSBhbGwgZGF0YXNldCBjb250cm9sbGVycyBoYXZlIGNvcnJlY3QgbWV0YSBkYXRhIGNvdW50c1xuXHRcdFx0aGVscGVycy5lYWNoKG1lLmRhdGEuZGF0YXNldHMsIGZ1bmN0aW9uKGRhdGFzZXQsIGRhdGFzZXRJbmRleCkge1xuXHRcdFx0XHRtZS5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpLmNvbnRyb2xsZXIuYnVpbGRPclVwZGF0ZUVsZW1lbnRzKCk7XG5cdFx0XHR9LCBtZSk7XG5cblx0XHRcdG1lLnVwZGF0ZUxheW91dCgpO1xuXG5cdFx0XHQvLyBDYW4gb25seSByZXNldCB0aGUgbmV3IGNvbnRyb2xsZXJzIGFmdGVyIHRoZSBzY2FsZXMgaGF2ZSBiZWVuIHVwZGF0ZWRcblx0XHRcdGlmIChtZS5vcHRpb25zLmFuaW1hdGlvbiAmJiBtZS5vcHRpb25zLmFuaW1hdGlvbi5kdXJhdGlvbikge1xuXHRcdFx0XHRoZWxwZXJzLmVhY2gobmV3Q29udHJvbGxlcnMsIGZ1bmN0aW9uKGNvbnRyb2xsZXIpIHtcblx0XHRcdFx0XHRjb250cm9sbGVyLnJlc2V0KCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHRtZS51cGRhdGVEYXRhc2V0cygpO1xuXG5cdFx0XHQvLyBOZWVkIHRvIHJlc2V0IHRvb2x0aXAgaW4gY2FzZSBpdCBpcyBkaXNwbGF5ZWQgd2l0aCBlbGVtZW50cyB0aGF0IGFyZSByZW1vdmVkXG5cdFx0XHQvLyBhZnRlciB1cGRhdGUuXG5cdFx0XHRtZS50b29sdGlwLmluaXRpYWxpemUoKTtcblxuXHRcdFx0Ly8gTGFzdCBhY3RpdmUgY29udGFpbnMgaXRlbXMgdGhhdCB3ZXJlIHByZXZpb3VzbHkgaW4gdGhlIHRvb2x0aXAuXG5cdFx0XHQvLyBXaGVuIHdlIHJlc2V0IHRoZSB0b29sdGlwLCB3ZSBuZWVkIHRvIGNsZWFyIGl0XG5cdFx0XHRtZS5sYXN0QWN0aXZlID0gW107XG5cblx0XHRcdC8vIERvIHRoaXMgYmVmb3JlIHJlbmRlciBzbyB0aGF0IGFueSBwbHVnaW5zIHRoYXQgbmVlZCBmaW5hbCBzY2FsZSB1cGRhdGVzIGNhbiB1c2UgaXRcblx0XHRcdHBsdWdpbnMubm90aWZ5KG1lLCAnYWZ0ZXJVcGRhdGUnKTtcblxuXHRcdFx0aWYgKG1lLl9idWZmZXJlZFJlbmRlcikge1xuXHRcdFx0XHRtZS5fYnVmZmVyZWRSZXF1ZXN0ID0ge1xuXHRcdFx0XHRcdGR1cmF0aW9uOiBjb25maWcuZHVyYXRpb24sXG5cdFx0XHRcdFx0ZWFzaW5nOiBjb25maWcuZWFzaW5nLFxuXHRcdFx0XHRcdGxhenk6IGNvbmZpZy5sYXp5XG5cdFx0XHRcdH07XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtZS5yZW5kZXIoY29uZmlnKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogVXBkYXRlcyB0aGUgY2hhcnQgbGF5b3V0IHVubGVzcyBhIHBsdWdpbiByZXR1cm5zIGBmYWxzZWAgdG8gdGhlIGBiZWZvcmVMYXlvdXRgXG5cdFx0ICogaG9vaywgaW4gd2hpY2ggY2FzZSwgcGx1Z2lucyB3aWxsIG5vdCBiZSBjYWxsZWQgb24gYGFmdGVyTGF5b3V0YC5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdHVwZGF0ZUxheW91dDogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXG5cdFx0XHRpZiAocGx1Z2lucy5ub3RpZnkobWUsICdiZWZvcmVMYXlvdXQnKSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRsYXlvdXRzLnVwZGF0ZSh0aGlzLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XG5cblx0XHRcdC8qKlxuXHRcdFx0ICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHVzZSBgYWZ0ZXJMYXlvdXRgIGluc3RlYWQuXG5cdFx0XHQgKiBAbWV0aG9kIElQbHVnaW4jYWZ0ZXJTY2FsZVVwZGF0ZVxuXHRcdFx0ICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjUuMFxuXHRcdFx0ICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xuXHRcdFx0ICogQHByaXZhdGVcblx0XHRcdCAqL1xuXHRcdFx0cGx1Z2lucy5ub3RpZnkobWUsICdhZnRlclNjYWxlVXBkYXRlJyk7XG5cdFx0XHRwbHVnaW5zLm5vdGlmeShtZSwgJ2FmdGVyTGF5b3V0Jyk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFVwZGF0ZXMgYWxsIGRhdGFzZXRzIHVubGVzcyBhIHBsdWdpbiByZXR1cm5zIGBmYWxzZWAgdG8gdGhlIGBiZWZvcmVEYXRhc2V0c1VwZGF0ZWBcblx0XHQgKiBob29rLCBpbiB3aGljaCBjYXNlLCBwbHVnaW5zIHdpbGwgbm90IGJlIGNhbGxlZCBvbiBgYWZ0ZXJEYXRhc2V0c1VwZGF0ZWAuXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHR1cGRhdGVEYXRhc2V0czogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXG5cdFx0XHRpZiAocGx1Z2lucy5ub3RpZnkobWUsICdiZWZvcmVEYXRhc2V0c1VwZGF0ZScpID09PSBmYWxzZSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGZvciAodmFyIGkgPSAwLCBpbGVuID0gbWUuZGF0YS5kYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdFx0bWUudXBkYXRlRGF0YXNldChpKTtcblx0XHRcdH1cblxuXHRcdFx0cGx1Z2lucy5ub3RpZnkobWUsICdhZnRlckRhdGFzZXRzVXBkYXRlJyk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFVwZGF0ZXMgZGF0YXNldCBhdCBpbmRleCB1bmxlc3MgYSBwbHVnaW4gcmV0dXJucyBgZmFsc2VgIHRvIHRoZSBgYmVmb3JlRGF0YXNldFVwZGF0ZWBcblx0XHQgKiBob29rLCBpbiB3aGljaCBjYXNlLCBwbHVnaW5zIHdpbGwgbm90IGJlIGNhbGxlZCBvbiBgYWZ0ZXJEYXRhc2V0VXBkYXRlYC5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdHVwZGF0ZURhdGFzZXQ6IGZ1bmN0aW9uKGluZGV4KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG1ldGEgPSBtZS5nZXREYXRhc2V0TWV0YShpbmRleCk7XG5cdFx0XHR2YXIgYXJncyA9IHtcblx0XHRcdFx0bWV0YTogbWV0YSxcblx0XHRcdFx0aW5kZXg6IGluZGV4XG5cdFx0XHR9O1xuXG5cdFx0XHRpZiAocGx1Z2lucy5ub3RpZnkobWUsICdiZWZvcmVEYXRhc2V0VXBkYXRlJywgW2FyZ3NdKSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRtZXRhLmNvbnRyb2xsZXIudXBkYXRlKCk7XG5cblx0XHRcdHBsdWdpbnMubm90aWZ5KG1lLCAnYWZ0ZXJEYXRhc2V0VXBkYXRlJywgW2FyZ3NdKTtcblx0XHR9LFxuXG5cdFx0cmVuZGVyOiBmdW5jdGlvbihjb25maWcpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cblx0XHRcdGlmICghY29uZmlnIHx8IHR5cGVvZiBjb25maWcgIT09ICdvYmplY3QnKSB7XG5cdFx0XHRcdC8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5cdFx0XHRcdGNvbmZpZyA9IHtcblx0XHRcdFx0XHRkdXJhdGlvbjogY29uZmlnLFxuXHRcdFx0XHRcdGxhenk6IGFyZ3VtZW50c1sxXVxuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgZHVyYXRpb24gPSBjb25maWcuZHVyYXRpb247XG5cdFx0XHR2YXIgbGF6eSA9IGNvbmZpZy5sYXp5O1xuXG5cdFx0XHRpZiAocGx1Z2lucy5ub3RpZnkobWUsICdiZWZvcmVSZW5kZXInKSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgYW5pbWF0aW9uT3B0aW9ucyA9IG1lLm9wdGlvbnMuYW5pbWF0aW9uO1xuXHRcdFx0dmFyIG9uQ29tcGxldGUgPSBmdW5jdGlvbihhbmltYXRpb24pIHtcblx0XHRcdFx0cGx1Z2lucy5ub3RpZnkobWUsICdhZnRlclJlbmRlcicpO1xuXHRcdFx0XHRoZWxwZXJzLmNhbGxiYWNrKGFuaW1hdGlvbk9wdGlvbnMgJiYgYW5pbWF0aW9uT3B0aW9ucy5vbkNvbXBsZXRlLCBbYW5pbWF0aW9uXSwgbWUpO1xuXHRcdFx0fTtcblxuXHRcdFx0aWYgKGFuaW1hdGlvbk9wdGlvbnMgJiYgKCh0eXBlb2YgZHVyYXRpb24gIT09ICd1bmRlZmluZWQnICYmIGR1cmF0aW9uICE9PSAwKSB8fCAodHlwZW9mIGR1cmF0aW9uID09PSAndW5kZWZpbmVkJyAmJiBhbmltYXRpb25PcHRpb25zLmR1cmF0aW9uICE9PSAwKSkpIHtcblx0XHRcdFx0dmFyIGFuaW1hdGlvbiA9IG5ldyBBbmltYXRpb24oe1xuXHRcdFx0XHRcdG51bVN0ZXBzOiAoZHVyYXRpb24gfHwgYW5pbWF0aW9uT3B0aW9ucy5kdXJhdGlvbikgLyAxNi42NiwgLy8gNjAgZnBzXG5cdFx0XHRcdFx0ZWFzaW5nOiBjb25maWcuZWFzaW5nIHx8IGFuaW1hdGlvbk9wdGlvbnMuZWFzaW5nLFxuXG5cdFx0XHRcdFx0cmVuZGVyOiBmdW5jdGlvbihjaGFydCwgYW5pbWF0aW9uT2JqZWN0KSB7XG5cdFx0XHRcdFx0XHR2YXIgZWFzaW5nRnVuY3Rpb24gPSBoZWxwZXJzLmVhc2luZy5lZmZlY3RzW2FuaW1hdGlvbk9iamVjdC5lYXNpbmddO1xuXHRcdFx0XHRcdFx0dmFyIGN1cnJlbnRTdGVwID0gYW5pbWF0aW9uT2JqZWN0LmN1cnJlbnRTdGVwO1xuXHRcdFx0XHRcdFx0dmFyIHN0ZXBEZWNpbWFsID0gY3VycmVudFN0ZXAgLyBhbmltYXRpb25PYmplY3QubnVtU3RlcHM7XG5cblx0XHRcdFx0XHRcdGNoYXJ0LmRyYXcoZWFzaW5nRnVuY3Rpb24oc3RlcERlY2ltYWwpLCBzdGVwRGVjaW1hbCwgY3VycmVudFN0ZXApO1xuXHRcdFx0XHRcdH0sXG5cblx0XHRcdFx0XHRvbkFuaW1hdGlvblByb2dyZXNzOiBhbmltYXRpb25PcHRpb25zLm9uUHJvZ3Jlc3MsXG5cdFx0XHRcdFx0b25BbmltYXRpb25Db21wbGV0ZTogb25Db21wbGV0ZVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHRhbmltYXRpb25zLmFkZEFuaW1hdGlvbihtZSwgYW5pbWF0aW9uLCBkdXJhdGlvbiwgbGF6eSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtZS5kcmF3KCk7XG5cblx0XHRcdFx0Ly8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8zNzgxXG5cdFx0XHRcdG9uQ29tcGxldGUobmV3IEFuaW1hdGlvbih7bnVtU3RlcHM6IDAsIGNoYXJ0OiBtZX0pKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1lO1xuXHRcdH0sXG5cblx0XHRkcmF3OiBmdW5jdGlvbihlYXNpbmdWYWx1ZSkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblxuXHRcdFx0bWUuY2xlYXIoKTtcblxuXHRcdFx0aWYgKGhlbHBlcnMuaXNOdWxsT3JVbmRlZihlYXNpbmdWYWx1ZSkpIHtcblx0XHRcdFx0ZWFzaW5nVmFsdWUgPSAxO1xuXHRcdFx0fVxuXG5cdFx0XHRtZS50cmFuc2l0aW9uKGVhc2luZ1ZhbHVlKTtcblxuXHRcdFx0aWYgKG1lLndpZHRoIDw9IDAgfHwgbWUuaGVpZ2h0IDw9IDApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAocGx1Z2lucy5ub3RpZnkobWUsICdiZWZvcmVEcmF3JywgW2Vhc2luZ1ZhbHVlXSkgPT09IGZhbHNlKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRHJhdyBhbGwgdGhlIHNjYWxlc1xuXHRcdFx0aGVscGVycy5lYWNoKG1lLmJveGVzLCBmdW5jdGlvbihib3gpIHtcblx0XHRcdFx0Ym94LmRyYXcobWUuY2hhcnRBcmVhKTtcblx0XHRcdH0sIG1lKTtcblxuXHRcdFx0aWYgKG1lLnNjYWxlKSB7XG5cdFx0XHRcdG1lLnNjYWxlLmRyYXcoKTtcblx0XHRcdH1cblxuXHRcdFx0bWUuZHJhd0RhdGFzZXRzKGVhc2luZ1ZhbHVlKTtcblx0XHRcdG1lLl9kcmF3VG9vbHRpcChlYXNpbmdWYWx1ZSk7XG5cblx0XHRcdHBsdWdpbnMubm90aWZ5KG1lLCAnYWZ0ZXJEcmF3JywgW2Vhc2luZ1ZhbHVlXSk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0dHJhbnNpdGlvbjogZnVuY3Rpb24oZWFzaW5nVmFsdWUpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cblx0XHRcdGZvciAodmFyIGkgPSAwLCBpbGVuID0gKG1lLmRhdGEuZGF0YXNldHMgfHwgW10pLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdFx0XHRpZiAobWUuaXNEYXRhc2V0VmlzaWJsZShpKSkge1xuXHRcdFx0XHRcdG1lLmdldERhdGFzZXRNZXRhKGkpLmNvbnRyb2xsZXIudHJhbnNpdGlvbihlYXNpbmdWYWx1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0bWUudG9vbHRpcC50cmFuc2l0aW9uKGVhc2luZ1ZhbHVlKTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogRHJhd3MgYWxsIGRhdGFzZXRzIHVubGVzcyBhIHBsdWdpbiByZXR1cm5zIGBmYWxzZWAgdG8gdGhlIGBiZWZvcmVEYXRhc2V0c0RyYXdgXG5cdFx0ICogaG9vaywgaW4gd2hpY2ggY2FzZSwgcGx1Z2lucyB3aWxsIG5vdCBiZSBjYWxsZWQgb24gYGFmdGVyRGF0YXNldHNEcmF3YC5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdGRyYXdEYXRhc2V0czogZnVuY3Rpb24oZWFzaW5nVmFsdWUpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cblx0XHRcdGlmIChwbHVnaW5zLm5vdGlmeShtZSwgJ2JlZm9yZURhdGFzZXRzRHJhdycsIFtlYXNpbmdWYWx1ZV0pID09PSBmYWxzZSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIERyYXcgZGF0YXNldHMgcmV2ZXJzZWQgdG8gc3VwcG9ydCBwcm9wZXIgbGluZSBzdGFja2luZ1xuXHRcdFx0Zm9yICh2YXIgaSA9IChtZS5kYXRhLmRhdGFzZXRzIHx8IFtdKS5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuXHRcdFx0XHRpZiAobWUuaXNEYXRhc2V0VmlzaWJsZShpKSkge1xuXHRcdFx0XHRcdG1lLmRyYXdEYXRhc2V0KGksIGVhc2luZ1ZhbHVlKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRwbHVnaW5zLm5vdGlmeShtZSwgJ2FmdGVyRGF0YXNldHNEcmF3JywgW2Vhc2luZ1ZhbHVlXSk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIERyYXdzIGRhdGFzZXQgYXQgaW5kZXggdW5sZXNzIGEgcGx1Z2luIHJldHVybnMgYGZhbHNlYCB0byB0aGUgYGJlZm9yZURhdGFzZXREcmF3YFxuXHRcdCAqIGhvb2ssIGluIHdoaWNoIGNhc2UsIHBsdWdpbnMgd2lsbCBub3QgYmUgY2FsbGVkIG9uIGBhZnRlckRhdGFzZXREcmF3YC5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdGRyYXdEYXRhc2V0OiBmdW5jdGlvbihpbmRleCwgZWFzaW5nVmFsdWUpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgbWV0YSA9IG1lLmdldERhdGFzZXRNZXRhKGluZGV4KTtcblx0XHRcdHZhciBhcmdzID0ge1xuXHRcdFx0XHRtZXRhOiBtZXRhLFxuXHRcdFx0XHRpbmRleDogaW5kZXgsXG5cdFx0XHRcdGVhc2luZ1ZhbHVlOiBlYXNpbmdWYWx1ZVxuXHRcdFx0fTtcblxuXHRcdFx0aWYgKHBsdWdpbnMubm90aWZ5KG1lLCAnYmVmb3JlRGF0YXNldERyYXcnLCBbYXJnc10pID09PSBmYWxzZSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdG1ldGEuY29udHJvbGxlci5kcmF3KGVhc2luZ1ZhbHVlKTtcblxuXHRcdFx0cGx1Z2lucy5ub3RpZnkobWUsICdhZnRlckRhdGFzZXREcmF3JywgW2FyZ3NdKTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogRHJhd3MgdG9vbHRpcCB1bmxlc3MgYSBwbHVnaW4gcmV0dXJucyBgZmFsc2VgIHRvIHRoZSBgYmVmb3JlVG9vbHRpcERyYXdgXG5cdFx0ICogaG9vaywgaW4gd2hpY2ggY2FzZSwgcGx1Z2lucyB3aWxsIG5vdCBiZSBjYWxsZWQgb24gYGFmdGVyVG9vbHRpcERyYXdgLlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0X2RyYXdUb29sdGlwOiBmdW5jdGlvbihlYXNpbmdWYWx1ZSkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciB0b29sdGlwID0gbWUudG9vbHRpcDtcblx0XHRcdHZhciBhcmdzID0ge1xuXHRcdFx0XHR0b29sdGlwOiB0b29sdGlwLFxuXHRcdFx0XHRlYXNpbmdWYWx1ZTogZWFzaW5nVmFsdWVcblx0XHRcdH07XG5cblx0XHRcdGlmIChwbHVnaW5zLm5vdGlmeShtZSwgJ2JlZm9yZVRvb2x0aXBEcmF3JywgW2FyZ3NdKSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR0b29sdGlwLmRyYXcoKTtcblxuXHRcdFx0cGx1Z2lucy5ub3RpZnkobWUsICdhZnRlclRvb2x0aXBEcmF3JywgW2FyZ3NdKTtcblx0XHR9LFxuXG5cdFx0Ly8gR2V0IHRoZSBzaW5nbGUgZWxlbWVudCB0aGF0IHdhcyBjbGlja2VkIG9uXG5cdFx0Ly8gQHJldHVybiA6IEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBkYXRhc2V0IGluZGV4IGFuZCBlbGVtZW50IGluZGV4IG9mIHRoZSBtYXRjaGluZyBlbGVtZW50LiBBbHNvIGNvbnRhaW5zIHRoZSByZWN0YW5nbGUgdGhhdCB3YXMgZHJhd1xuXHRcdGdldEVsZW1lbnRBdEV2ZW50OiBmdW5jdGlvbihlKSB7XG5cdFx0XHRyZXR1cm4gSW50ZXJhY3Rpb24ubW9kZXMuc2luZ2xlKHRoaXMsIGUpO1xuXHRcdH0sXG5cblx0XHRnZXRFbGVtZW50c0F0RXZlbnQ6IGZ1bmN0aW9uKGUpIHtcblx0XHRcdHJldHVybiBJbnRlcmFjdGlvbi5tb2Rlcy5sYWJlbCh0aGlzLCBlLCB7aW50ZXJzZWN0OiB0cnVlfSk7XG5cdFx0fSxcblxuXHRcdGdldEVsZW1lbnRzQXRYQXhpczogZnVuY3Rpb24oZSkge1xuXHRcdFx0cmV0dXJuIEludGVyYWN0aW9uLm1vZGVzWyd4LWF4aXMnXSh0aGlzLCBlLCB7aW50ZXJzZWN0OiB0cnVlfSk7XG5cdFx0fSxcblxuXHRcdGdldEVsZW1lbnRzQXRFdmVudEZvck1vZGU6IGZ1bmN0aW9uKGUsIG1vZGUsIG9wdGlvbnMpIHtcblx0XHRcdHZhciBtZXRob2QgPSBJbnRlcmFjdGlvbi5tb2Rlc1ttb2RlXTtcblx0XHRcdGlmICh0eXBlb2YgbWV0aG9kID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRcdHJldHVybiBtZXRob2QodGhpcywgZSwgb3B0aW9ucyk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBbXTtcblx0XHR9LFxuXG5cdFx0Z2V0RGF0YXNldEF0RXZlbnQ6IGZ1bmN0aW9uKGUpIHtcblx0XHRcdHJldHVybiBJbnRlcmFjdGlvbi5tb2Rlcy5kYXRhc2V0KHRoaXMsIGUsIHtpbnRlcnNlY3Q6IHRydWV9KTtcblx0XHR9LFxuXG5cdFx0Z2V0RGF0YXNldE1ldGE6IGZ1bmN0aW9uKGRhdGFzZXRJbmRleCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBkYXRhc2V0ID0gbWUuZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdO1xuXHRcdFx0aWYgKCFkYXRhc2V0Ll9tZXRhKSB7XG5cdFx0XHRcdGRhdGFzZXQuX21ldGEgPSB7fTtcblx0XHRcdH1cblxuXHRcdFx0dmFyIG1ldGEgPSBkYXRhc2V0Ll9tZXRhW21lLmlkXTtcblx0XHRcdGlmICghbWV0YSkge1xuXHRcdFx0XHRtZXRhID0gZGF0YXNldC5fbWV0YVttZS5pZF0gPSB7XG5cdFx0XHRcdFx0dHlwZTogbnVsbCxcblx0XHRcdFx0XHRkYXRhOiBbXSxcblx0XHRcdFx0XHRkYXRhc2V0OiBudWxsLFxuXHRcdFx0XHRcdGNvbnRyb2xsZXI6IG51bGwsXG5cdFx0XHRcdFx0aGlkZGVuOiBudWxsLFx0XHRcdC8vIFNlZSBpc0RhdGFzZXRWaXNpYmxlKCkgY29tbWVudFxuXHRcdFx0XHRcdHhBeGlzSUQ6IG51bGwsXG5cdFx0XHRcdFx0eUF4aXNJRDogbnVsbFxuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbWV0YTtcblx0XHR9LFxuXG5cdFx0Z2V0VmlzaWJsZURhdGFzZXRDb3VudDogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgY291bnQgPSAwO1xuXHRcdFx0Zm9yICh2YXIgaSA9IDAsIGlsZW4gPSB0aGlzLmRhdGEuZGF0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG5cdFx0XHRcdGlmICh0aGlzLmlzRGF0YXNldFZpc2libGUoaSkpIHtcblx0XHRcdFx0XHRjb3VudCsrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gY291bnQ7XG5cdFx0fSxcblxuXHRcdGlzRGF0YXNldFZpc2libGU6IGZ1bmN0aW9uKGRhdGFzZXRJbmRleCkge1xuXHRcdFx0dmFyIG1ldGEgPSB0aGlzLmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XG5cblx0XHRcdC8vIG1ldGEuaGlkZGVuIGlzIGEgcGVyIGNoYXJ0IGRhdGFzZXQgaGlkZGVuIGZsYWcgb3ZlcnJpZGUgd2l0aCAzIHN0YXRlczogaWYgdHJ1ZSBvciBmYWxzZSxcblx0XHRcdC8vIHRoZSBkYXRhc2V0LmhpZGRlbiB2YWx1ZSBpcyBpZ25vcmVkLCBlbHNlIGlmIG51bGwsIHRoZSBkYXRhc2V0IGhpZGRlbiBzdGF0ZSBpcyByZXR1cm5lZC5cblx0XHRcdHJldHVybiB0eXBlb2YgbWV0YS5oaWRkZW4gPT09ICdib29sZWFuJyA/ICFtZXRhLmhpZGRlbiA6ICF0aGlzLmRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XS5oaWRkZW47XG5cdFx0fSxcblxuXHRcdGdlbmVyYXRlTGVnZW5kOiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB0aGlzLm9wdGlvbnMubGVnZW5kQ2FsbGJhY2sodGhpcyk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0ZGVzdHJveURhdGFzZXRNZXRhOiBmdW5jdGlvbihkYXRhc2V0SW5kZXgpIHtcblx0XHRcdHZhciBpZCA9IHRoaXMuaWQ7XG5cdFx0XHR2YXIgZGF0YXNldCA9IHRoaXMuZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdO1xuXHRcdFx0dmFyIG1ldGEgPSBkYXRhc2V0Ll9tZXRhICYmIGRhdGFzZXQuX21ldGFbaWRdO1xuXG5cdFx0XHRpZiAobWV0YSkge1xuXHRcdFx0XHRtZXRhLmNvbnRyb2xsZXIuZGVzdHJveSgpO1xuXHRcdFx0XHRkZWxldGUgZGF0YXNldC5fbWV0YVtpZF07XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdGRlc3Ryb3k6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBjYW52YXMgPSBtZS5jYW52YXM7XG5cdFx0XHR2YXIgaSwgaWxlbjtcblxuXHRcdFx0bWUuc3RvcCgpO1xuXG5cdFx0XHQvLyBkYXRhc2V0IGNvbnRyb2xsZXJzIG5lZWQgdG8gY2xlYW51cCBhc3NvY2lhdGVkIGRhdGFcblx0XHRcdGZvciAoaSA9IDAsIGlsZW4gPSBtZS5kYXRhLmRhdGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdFx0XHRtZS5kZXN0cm95RGF0YXNldE1ldGEoaSk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChjYW52YXMpIHtcblx0XHRcdFx0bWUudW5iaW5kRXZlbnRzKCk7XG5cdFx0XHRcdGhlbHBlcnMuY2FudmFzLmNsZWFyKG1lKTtcblx0XHRcdFx0cGxhdGZvcm0ucmVsZWFzZUNvbnRleHQobWUuY3R4KTtcblx0XHRcdFx0bWUuY2FudmFzID0gbnVsbDtcblx0XHRcdFx0bWUuY3R4ID0gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0cGx1Z2lucy5ub3RpZnkobWUsICdkZXN0cm95Jyk7XG5cblx0XHRcdGRlbGV0ZSBDaGFydC5pbnN0YW5jZXNbbWUuaWRdO1xuXHRcdH0sXG5cblx0XHR0b0Jhc2U2NEltYWdlOiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB0aGlzLmNhbnZhcy50b0RhdGFVUkwuYXBwbHkodGhpcy5jYW52YXMsIGFyZ3VtZW50cyk7XG5cdFx0fSxcblxuXHRcdGluaXRUb29sVGlwOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHRtZS50b29sdGlwID0gbmV3IFRvb2x0aXAoe1xuXHRcdFx0XHRfY2hhcnQ6IG1lLFxuXHRcdFx0XHRfY2hhcnRJbnN0YW5jZTogbWUsIC8vIGRlcHJlY2F0ZWQsIGJhY2t3YXJkIGNvbXBhdGliaWxpdHlcblx0XHRcdFx0X2RhdGE6IG1lLmRhdGEsXG5cdFx0XHRcdF9vcHRpb25zOiBtZS5vcHRpb25zLnRvb2x0aXBzXG5cdFx0XHR9LCBtZSk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0YmluZEV2ZW50czogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIGxpc3RlbmVycyA9IG1lLl9saXN0ZW5lcnMgPSB7fTtcblx0XHRcdHZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRtZS5ldmVudEhhbmRsZXIuYXBwbHkobWUsIGFyZ3VtZW50cyk7XG5cdFx0XHR9O1xuXG5cdFx0XHRoZWxwZXJzLmVhY2gobWUub3B0aW9ucy5ldmVudHMsIGZ1bmN0aW9uKHR5cGUpIHtcblx0XHRcdFx0cGxhdGZvcm0uYWRkRXZlbnRMaXN0ZW5lcihtZSwgdHlwZSwgbGlzdGVuZXIpO1xuXHRcdFx0XHRsaXN0ZW5lcnNbdHlwZV0gPSBsaXN0ZW5lcjtcblx0XHRcdH0pO1xuXG5cdFx0XHQvLyBFbGVtZW50cyB1c2VkIHRvIGRldGVjdCBzaXplIGNoYW5nZSBzaG91bGQgbm90IGJlIGluamVjdGVkIGZvciBub24gcmVzcG9uc2l2ZSBjaGFydHMuXG5cdFx0XHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzIyMTBcblx0XHRcdGlmIChtZS5vcHRpb25zLnJlc3BvbnNpdmUpIHtcblx0XHRcdFx0bGlzdGVuZXIgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRtZS5yZXNpemUoKTtcblx0XHRcdFx0fTtcblxuXHRcdFx0XHRwbGF0Zm9ybS5hZGRFdmVudExpc3RlbmVyKG1lLCAncmVzaXplJywgbGlzdGVuZXIpO1xuXHRcdFx0XHRsaXN0ZW5lcnMucmVzaXplID0gbGlzdGVuZXI7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0dW5iaW5kRXZlbnRzOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgbGlzdGVuZXJzID0gbWUuX2xpc3RlbmVycztcblx0XHRcdGlmICghbGlzdGVuZXJzKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0ZGVsZXRlIG1lLl9saXN0ZW5lcnM7XG5cdFx0XHRoZWxwZXJzLmVhY2gobGlzdGVuZXJzLCBmdW5jdGlvbihsaXN0ZW5lciwgdHlwZSkge1xuXHRcdFx0XHRwbGF0Zm9ybS5yZW1vdmVFdmVudExpc3RlbmVyKG1lLCB0eXBlLCBsaXN0ZW5lcik7XG5cdFx0XHR9KTtcblx0XHR9LFxuXG5cdFx0dXBkYXRlSG92ZXJTdHlsZTogZnVuY3Rpb24oZWxlbWVudHMsIG1vZGUsIGVuYWJsZWQpIHtcblx0XHRcdHZhciBtZXRob2QgPSBlbmFibGVkID8gJ3NldEhvdmVyU3R5bGUnIDogJ3JlbW92ZUhvdmVyU3R5bGUnO1xuXHRcdFx0dmFyIGVsZW1lbnQsIGksIGlsZW47XG5cblx0XHRcdGZvciAoaSA9IDAsIGlsZW4gPSBlbGVtZW50cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdFx0ZWxlbWVudCA9IGVsZW1lbnRzW2ldO1xuXHRcdFx0XHRpZiAoZWxlbWVudCkge1xuXHRcdFx0XHRcdHRoaXMuZ2V0RGF0YXNldE1ldGEoZWxlbWVudC5fZGF0YXNldEluZGV4KS5jb250cm9sbGVyW21ldGhvZF0oZWxlbWVudCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRldmVudEhhbmRsZXI6IGZ1bmN0aW9uKGUpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgdG9vbHRpcCA9IG1lLnRvb2x0aXA7XG5cblx0XHRcdGlmIChwbHVnaW5zLm5vdGlmeShtZSwgJ2JlZm9yZUV2ZW50JywgW2VdKSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBCdWZmZXIgYW55IHVwZGF0ZSBjYWxscyBzbyB0aGF0IHJlbmRlcnMgZG8gbm90IG9jY3VyXG5cdFx0XHRtZS5fYnVmZmVyZWRSZW5kZXIgPSB0cnVlO1xuXHRcdFx0bWUuX2J1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cblx0XHRcdHZhciBjaGFuZ2VkID0gbWUuaGFuZGxlRXZlbnQoZSk7XG5cdFx0XHQvLyBmb3Igc21vb3RoIHRvb2x0aXAgYW5pbWF0aW9ucyBpc3N1ZSAjNDk4OVxuXHRcdFx0Ly8gdGhlIHRvb2x0aXAgc2hvdWxkIGJlIHRoZSBzb3VyY2Ugb2YgY2hhbmdlXG5cdFx0XHQvLyBBbmltYXRpb24gY2hlY2sgd29ya2Fyb3VuZDpcblx0XHRcdC8vIHRvb2x0aXAuX3N0YXJ0IHdpbGwgYmUgbnVsbCB3aGVuIHRvb2x0aXAgaXNuJ3QgYW5pbWF0aW5nXG5cdFx0XHRpZiAodG9vbHRpcCkge1xuXHRcdFx0XHRjaGFuZ2VkID0gdG9vbHRpcC5fc3RhcnRcblx0XHRcdFx0XHQ/IHRvb2x0aXAuaGFuZGxlRXZlbnQoZSlcblx0XHRcdFx0XHQ6IGNoYW5nZWQgfCB0b29sdGlwLmhhbmRsZUV2ZW50KGUpO1xuXHRcdFx0fVxuXG5cdFx0XHRwbHVnaW5zLm5vdGlmeShtZSwgJ2FmdGVyRXZlbnQnLCBbZV0pO1xuXG5cdFx0XHR2YXIgYnVmZmVyZWRSZXF1ZXN0ID0gbWUuX2J1ZmZlcmVkUmVxdWVzdDtcblx0XHRcdGlmIChidWZmZXJlZFJlcXVlc3QpIHtcblx0XHRcdFx0Ly8gSWYgd2UgaGF2ZSBhbiB1cGRhdGUgdGhhdCB3YXMgdHJpZ2dlcmVkLCB3ZSBuZWVkIHRvIGRvIGEgbm9ybWFsIHJlbmRlclxuXHRcdFx0XHRtZS5yZW5kZXIoYnVmZmVyZWRSZXF1ZXN0KTtcblx0XHRcdH0gZWxzZSBpZiAoY2hhbmdlZCAmJiAhbWUuYW5pbWF0aW5nKSB7XG5cdFx0XHRcdC8vIElmIGVudGVyaW5nLCBsZWF2aW5nLCBvciBjaGFuZ2luZyBlbGVtZW50cywgYW5pbWF0ZSB0aGUgY2hhbmdlIHZpYSBwaXZvdFxuXHRcdFx0XHRtZS5zdG9wKCk7XG5cblx0XHRcdFx0Ly8gV2Ugb25seSBuZWVkIHRvIHJlbmRlciBhdCB0aGlzIHBvaW50LiBVcGRhdGluZyB3aWxsIGNhdXNlIHNjYWxlcyB0byBiZVxuXHRcdFx0XHQvLyByZWNvbXB1dGVkIGdlbmVyYXRpbmcgZmxpY2tlciAmIHVzaW5nIG1vcmUgbWVtb3J5IHRoYW4gbmVjZXNzYXJ5LlxuXHRcdFx0XHRtZS5yZW5kZXIoe1xuXHRcdFx0XHRcdGR1cmF0aW9uOiBtZS5vcHRpb25zLmhvdmVyLmFuaW1hdGlvbkR1cmF0aW9uLFxuXHRcdFx0XHRcdGxhenk6IHRydWVcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdG1lLl9idWZmZXJlZFJlbmRlciA9IGZhbHNlO1xuXHRcdFx0bWUuX2J1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cblx0XHRcdHJldHVybiBtZTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogSGFuZGxlIGFuIGV2ZW50XG5cdFx0ICogQHByaXZhdGVcblx0XHQgKiBAcGFyYW0ge0lFdmVudH0gZXZlbnQgdGhlIGV2ZW50IHRvIGhhbmRsZVxuXHRcdCAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgdGhlIGNoYXJ0IG5lZWRzIHRvIHJlLXJlbmRlclxuXHRcdCAqL1xuXHRcdGhhbmRsZUV2ZW50OiBmdW5jdGlvbihlKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG9wdGlvbnMgPSBtZS5vcHRpb25zIHx8IHt9O1xuXHRcdFx0dmFyIGhvdmVyT3B0aW9ucyA9IG9wdGlvbnMuaG92ZXI7XG5cdFx0XHR2YXIgY2hhbmdlZCA9IGZhbHNlO1xuXG5cdFx0XHRtZS5sYXN0QWN0aXZlID0gbWUubGFzdEFjdGl2ZSB8fCBbXTtcblxuXHRcdFx0Ly8gRmluZCBBY3RpdmUgRWxlbWVudHMgZm9yIGhvdmVyIGFuZCB0b29sdGlwc1xuXHRcdFx0aWYgKGUudHlwZSA9PT0gJ21vdXNlb3V0Jykge1xuXHRcdFx0XHRtZS5hY3RpdmUgPSBbXTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG1lLmFjdGl2ZSA9IG1lLmdldEVsZW1lbnRzQXRFdmVudEZvck1vZGUoZSwgaG92ZXJPcHRpb25zLm1vZGUsIGhvdmVyT3B0aW9ucyk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEludm9rZSBvbkhvdmVyIGhvb2tcblx0XHRcdC8vIE5lZWQgdG8gY2FsbCB3aXRoIG5hdGl2ZSBldmVudCBoZXJlIHRvIG5vdCBicmVhayBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuXHRcdFx0aGVscGVycy5jYWxsYmFjayhvcHRpb25zLm9uSG92ZXIgfHwgb3B0aW9ucy5ob3Zlci5vbkhvdmVyLCBbZS5uYXRpdmUsIG1lLmFjdGl2ZV0sIG1lKTtcblxuXHRcdFx0aWYgKGUudHlwZSA9PT0gJ21vdXNldXAnIHx8IGUudHlwZSA9PT0gJ2NsaWNrJykge1xuXHRcdFx0XHRpZiAob3B0aW9ucy5vbkNsaWNrKSB7XG5cdFx0XHRcdFx0Ly8gVXNlIGUubmF0aXZlIGhlcmUgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5cdFx0XHRcdFx0b3B0aW9ucy5vbkNsaWNrLmNhbGwobWUsIGUubmF0aXZlLCBtZS5hY3RpdmUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlbW92ZSBzdHlsaW5nIGZvciBsYXN0IGFjdGl2ZSAoZXZlbiBpZiBpdCBtYXkgc3RpbGwgYmUgYWN0aXZlKVxuXHRcdFx0aWYgKG1lLmxhc3RBY3RpdmUubGVuZ3RoKSB7XG5cdFx0XHRcdG1lLnVwZGF0ZUhvdmVyU3R5bGUobWUubGFzdEFjdGl2ZSwgaG92ZXJPcHRpb25zLm1vZGUsIGZhbHNlKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQnVpbHQgaW4gaG92ZXIgc3R5bGluZ1xuXHRcdFx0aWYgKG1lLmFjdGl2ZS5sZW5ndGggJiYgaG92ZXJPcHRpb25zLm1vZGUpIHtcblx0XHRcdFx0bWUudXBkYXRlSG92ZXJTdHlsZShtZS5hY3RpdmUsIGhvdmVyT3B0aW9ucy5tb2RlLCB0cnVlKTtcblx0XHRcdH1cblxuXHRcdFx0Y2hhbmdlZCA9ICFoZWxwZXJzLmFycmF5RXF1YWxzKG1lLmFjdGl2ZSwgbWUubGFzdEFjdGl2ZSk7XG5cblx0XHRcdC8vIFJlbWVtYmVyIExhc3QgQWN0aXZlc1xuXHRcdFx0bWUubGFzdEFjdGl2ZSA9IG1lLmFjdGl2ZTtcblxuXHRcdFx0cmV0dXJuIGNoYW5nZWQ7XG5cdFx0fVxuXHR9KTtcblxuXHQvKipcblx0ICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHVzZSBDaGFydCBpbnN0ZWFkLlxuXHQgKiBAY2xhc3MgQ2hhcnQuQ29udHJvbGxlclxuXHQgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNi4wXG5cdCAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcblx0ICogQHByaXZhdGVcblx0ICovXG5cdENoYXJ0LkNvbnRyb2xsZXIgPSBDaGFydDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///23a9\n")},"241a":function(module,exports,__webpack_require__){"use strict";eval('\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ "beaa");\nvar elements = __webpack_require__(/*! ../elements/index */ "0687");\nvar helpers = __webpack_require__(/*! ../helpers/index */ "66c8");\n\ndefaults._set(\'radar\', {\n\tscale: {\n\t\ttype: \'radialLinear\'\n\t},\n\telements: {\n\t\tline: {\n\t\t\ttension: 0 // no bezier in radar\n\t\t}\n\t}\n});\n\nmodule.exports = function(Chart) {\n\n\tChart.controllers.radar = Chart.DatasetController.extend({\n\n\t\tdatasetElementType: elements.Line,\n\n\t\tdataElementType: elements.Point,\n\n\t\tlinkScales: helpers.noop,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar line = meta.dataset;\n\t\t\tvar points = meta.data;\n\t\t\tvar custom = line.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar lineElementOptions = me.chart.options.elements.line;\n\t\t\tvar scale = me.chart.scale;\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\n\t\t\t\tdataset.lineTension = dataset.tension;\n\t\t\t}\n\n\t\t\thelpers.extend(meta.dataset, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_scale: scale,\n\t\t\t\t// Data\n\t\t\t\t_children: points,\n\t\t\t\t_loop: true,\n\t\t\t\t// Model\n\t\t\t\t_model: {\n\t\t\t\t\t// Appearance\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\n\t\t\t\t\tfill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\n\t\t\t\t\tborderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\n\t\t\t\t\tborderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\n\t\t\t\t\tborderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\n\t\t\t\t\tborderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmeta.dataset.pivot();\n\n\t\t\t// Update Points\n\t\t\thelpers.each(points, function(point, index) {\n\t\t\t\tme.updateElement(point, index, reset);\n\t\t\t}, me);\n\n\t\t\t// Update bezier control points\n\t\t\tme.updateBezierControlPoints();\n\t\t},\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar scale = me.chart.scale;\n\t\t\tvar pointElementOptions = me.chart.options.elements.point;\n\t\t\tvar pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\n\t\t\t\tdataset.pointRadius = dataset.radius;\n\t\t\t}\n\t\t\tif ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {\n\t\t\t\tdataset.pointHitRadius = dataset.hitRadius;\n\t\t\t}\n\n\t\t\thelpers.extend(point, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\t\t\t\t_scale: scale,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales\n\t\t\t\t\ty: reset ? scale.yCenter : pointPosition.y,\n\n\t\t\t\t\t// Appearance\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, me.chart.options.elements.line.tension),\n\t\t\t\t\tradius: custom.radius ? custom.radius : helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),\n\t\t\t\t\tpointStyle: custom.pointStyle ? custom.pointStyle : helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),\n\t\t\t\t\trotation: custom.rotation ? custom.rotation : helpers.valueAtIndexOrDefault(dataset.pointRotation, index, pointElementOptions.rotation),\n\n\t\t\t\t\t// Tooltip\n\t\t\t\t\thitRadius: custom.hitRadius ? custom.hitRadius : helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius)\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tpoint._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));\n\t\t},\n\t\tupdateBezierControlPoints: function() {\n\t\t\tvar chartArea = this.chart.chartArea;\n\t\t\tvar meta = this.getMeta();\n\n\t\t\thelpers.each(meta.data, function(point, index) {\n\t\t\t\tvar model = point._model;\n\t\t\t\tvar controlPoints = helpers.splineCurve(\n\t\t\t\t\thelpers.previousItem(meta.data, index, true)._model,\n\t\t\t\t\tmodel,\n\t\t\t\t\thelpers.nextItem(meta.data, index, true)._model,\n\t\t\t\t\tmodel.tension\n\t\t\t\t);\n\n\t\t\t\t// Prevent the bezier going outside of the bounds of the graph\n\t\t\t\tmodel.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);\n\t\t\t\tmodel.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);\n\n\t\t\t\tmodel.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);\n\t\t\t\tmodel.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);\n\n\t\t\t\t// Now pivot the point for animation\n\t\t\t\tpoint.pivot();\n\t\t\t});\n\t\t},\n\n\t\tsetHoverStyle: function(point) {\n\t\t\t// Point\n\t\t\tvar dataset = this.chart.data.datasets[point._datasetIndex];\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar index = point._index;\n\t\t\tvar model = point._model;\n\n\t\t\tpoint.$previousStyle = {\n\t\t\t\tbackgroundColor: model.backgroundColor,\n\t\t\t\tborderColor: model.borderColor,\n\t\t\t\tborderWidth: model.borderWidth,\n\t\t\t\tradius: model.radius\n\t\t\t};\n\n\t\t\tmodel.radius = custom.hoverRadius ? custom.hoverRadius : helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\n\t\t},\n\t});\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjQxYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5yYWRhci5qcz82ODFkIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmF1bHRzID0gcmVxdWlyZSgnLi4vY29yZS9jb3JlLmRlZmF1bHRzJyk7XG52YXIgZWxlbWVudHMgPSByZXF1aXJlKCcuLi9lbGVtZW50cy9pbmRleCcpO1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2luZGV4Jyk7XG5cbmRlZmF1bHRzLl9zZXQoJ3JhZGFyJywge1xuXHRzY2FsZToge1xuXHRcdHR5cGU6ICdyYWRpYWxMaW5lYXInXG5cdH0sXG5cdGVsZW1lbnRzOiB7XG5cdFx0bGluZToge1xuXHRcdFx0dGVuc2lvbjogMCAvLyBubyBiZXppZXIgaW4gcmFkYXJcblx0XHR9XG5cdH1cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKENoYXJ0KSB7XG5cblx0Q2hhcnQuY29udHJvbGxlcnMucmFkYXIgPSBDaGFydC5EYXRhc2V0Q29udHJvbGxlci5leHRlbmQoe1xuXG5cdFx0ZGF0YXNldEVsZW1lbnRUeXBlOiBlbGVtZW50cy5MaW5lLFxuXG5cdFx0ZGF0YUVsZW1lbnRUeXBlOiBlbGVtZW50cy5Qb2ludCxcblxuXHRcdGxpbmtTY2FsZXM6IGhlbHBlcnMubm9vcCxcblxuXHRcdHVwZGF0ZTogZnVuY3Rpb24ocmVzZXQpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgbWV0YSA9IG1lLmdldE1ldGEoKTtcblx0XHRcdHZhciBsaW5lID0gbWV0YS5kYXRhc2V0O1xuXHRcdFx0dmFyIHBvaW50cyA9IG1ldGEuZGF0YTtcblx0XHRcdHZhciBjdXN0b20gPSBsaW5lLmN1c3RvbSB8fCB7fTtcblx0XHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xuXHRcdFx0dmFyIGxpbmVFbGVtZW50T3B0aW9ucyA9IG1lLmNoYXJ0Lm9wdGlvbnMuZWxlbWVudHMubGluZTtcblx0XHRcdHZhciBzY2FsZSA9IG1lLmNoYXJ0LnNjYWxlO1xuXG5cdFx0XHQvLyBDb21wYXRpYmlsaXR5OiBJZiB0aGUgcHJvcGVydGllcyBhcmUgZGVmaW5lZCB3aXRoIG9ubHkgdGhlIG9sZCBuYW1lLCB1c2UgdGhvc2UgdmFsdWVzXG5cdFx0XHRpZiAoKGRhdGFzZXQudGVuc2lvbiAhPT0gdW5kZWZpbmVkKSAmJiAoZGF0YXNldC5saW5lVGVuc2lvbiA9PT0gdW5kZWZpbmVkKSkge1xuXHRcdFx0XHRkYXRhc2V0LmxpbmVUZW5zaW9uID0gZGF0YXNldC50ZW5zaW9uO1xuXHRcdFx0fVxuXG5cdFx0XHRoZWxwZXJzLmV4dGVuZChtZXRhLmRhdGFzZXQsIHtcblx0XHRcdFx0Ly8gVXRpbGl0eVxuXHRcdFx0XHRfZGF0YXNldEluZGV4OiBtZS5pbmRleCxcblx0XHRcdFx0X3NjYWxlOiBzY2FsZSxcblx0XHRcdFx0Ly8gRGF0YVxuXHRcdFx0XHRfY2hpbGRyZW46IHBvaW50cyxcblx0XHRcdFx0X2xvb3A6IHRydWUsXG5cdFx0XHRcdC8vIE1vZGVsXG5cdFx0XHRcdF9tb2RlbDoge1xuXHRcdFx0XHRcdC8vIEFwcGVhcmFuY2Vcblx0XHRcdFx0XHR0ZW5zaW9uOiBjdXN0b20udGVuc2lvbiA/IGN1c3RvbS50ZW5zaW9uIDogaGVscGVycy52YWx1ZU9yRGVmYXVsdChkYXRhc2V0LmxpbmVUZW5zaW9uLCBsaW5lRWxlbWVudE9wdGlvbnMudGVuc2lvbiksXG5cdFx0XHRcdFx0YmFja2dyb3VuZENvbG9yOiBjdXN0b20uYmFja2dyb3VuZENvbG9yID8gY3VzdG9tLmJhY2tncm91bmRDb2xvciA6IChkYXRhc2V0LmJhY2tncm91bmRDb2xvciB8fCBsaW5lRWxlbWVudE9wdGlvbnMuYmFja2dyb3VuZENvbG9yKSxcblx0XHRcdFx0XHRib3JkZXJXaWR0aDogY3VzdG9tLmJvcmRlcldpZHRoID8gY3VzdG9tLmJvcmRlcldpZHRoIDogKGRhdGFzZXQuYm9yZGVyV2lkdGggfHwgbGluZUVsZW1lbnRPcHRpb25zLmJvcmRlcldpZHRoKSxcblx0XHRcdFx0XHRib3JkZXJDb2xvcjogY3VzdG9tLmJvcmRlckNvbG9yID8gY3VzdG9tLmJvcmRlckNvbG9yIDogKGRhdGFzZXQuYm9yZGVyQ29sb3IgfHwgbGluZUVsZW1lbnRPcHRpb25zLmJvcmRlckNvbG9yKSxcblx0XHRcdFx0XHRmaWxsOiBjdXN0b20uZmlsbCA/IGN1c3RvbS5maWxsIDogKGRhdGFzZXQuZmlsbCAhPT0gdW5kZWZpbmVkID8gZGF0YXNldC5maWxsIDogbGluZUVsZW1lbnRPcHRpb25zLmZpbGwpLFxuXHRcdFx0XHRcdGJvcmRlckNhcFN0eWxlOiBjdXN0b20uYm9yZGVyQ2FwU3R5bGUgPyBjdXN0b20uYm9yZGVyQ2FwU3R5bGUgOiAoZGF0YXNldC5ib3JkZXJDYXBTdHlsZSB8fCBsaW5lRWxlbWVudE9wdGlvbnMuYm9yZGVyQ2FwU3R5bGUpLFxuXHRcdFx0XHRcdGJvcmRlckRhc2g6IGN1c3RvbS5ib3JkZXJEYXNoID8gY3VzdG9tLmJvcmRlckRhc2ggOiAoZGF0YXNldC5ib3JkZXJEYXNoIHx8IGxpbmVFbGVtZW50T3B0aW9ucy5ib3JkZXJEYXNoKSxcblx0XHRcdFx0XHRib3JkZXJEYXNoT2Zmc2V0OiBjdXN0b20uYm9yZGVyRGFzaE9mZnNldCA/IGN1c3RvbS5ib3JkZXJEYXNoT2Zmc2V0IDogKGRhdGFzZXQuYm9yZGVyRGFzaE9mZnNldCB8fCBsaW5lRWxlbWVudE9wdGlvbnMuYm9yZGVyRGFzaE9mZnNldCksXG5cdFx0XHRcdFx0Ym9yZGVySm9pblN0eWxlOiBjdXN0b20uYm9yZGVySm9pblN0eWxlID8gY3VzdG9tLmJvcmRlckpvaW5TdHlsZSA6IChkYXRhc2V0LmJvcmRlckpvaW5TdHlsZSB8fCBsaW5lRWxlbWVudE9wdGlvbnMuYm9yZGVySm9pblN0eWxlKSxcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdG1ldGEuZGF0YXNldC5waXZvdCgpO1xuXG5cdFx0XHQvLyBVcGRhdGUgUG9pbnRzXG5cdFx0XHRoZWxwZXJzLmVhY2gocG9pbnRzLCBmdW5jdGlvbihwb2ludCwgaW5kZXgpIHtcblx0XHRcdFx0bWUudXBkYXRlRWxlbWVudChwb2ludCwgaW5kZXgsIHJlc2V0KTtcblx0XHRcdH0sIG1lKTtcblxuXHRcdFx0Ly8gVXBkYXRlIGJlemllciBjb250cm9sIHBvaW50c1xuXHRcdFx0bWUudXBkYXRlQmV6aWVyQ29udHJvbFBvaW50cygpO1xuXHRcdH0sXG5cdFx0dXBkYXRlRWxlbWVudDogZnVuY3Rpb24ocG9pbnQsIGluZGV4LCByZXNldCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBjdXN0b20gPSBwb2ludC5jdXN0b20gfHwge307XG5cdFx0XHR2YXIgZGF0YXNldCA9IG1lLmdldERhdGFzZXQoKTtcblx0XHRcdHZhciBzY2FsZSA9IG1lLmNoYXJ0LnNjYWxlO1xuXHRcdFx0dmFyIHBvaW50RWxlbWVudE9wdGlvbnMgPSBtZS5jaGFydC5vcHRpb25zLmVsZW1lbnRzLnBvaW50O1xuXHRcdFx0dmFyIHBvaW50UG9zaXRpb24gPSBzY2FsZS5nZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUoaW5kZXgsIGRhdGFzZXQuZGF0YVtpbmRleF0pO1xuXG5cdFx0XHQvLyBDb21wYXRpYmlsaXR5OiBJZiB0aGUgcHJvcGVydGllcyBhcmUgZGVmaW5lZCB3aXRoIG9ubHkgdGhlIG9sZCBuYW1lLCB1c2UgdGhvc2UgdmFsdWVzXG5cdFx0XHRpZiAoKGRhdGFzZXQucmFkaXVzICE9PSB1bmRlZmluZWQpICYmIChkYXRhc2V0LnBvaW50UmFkaXVzID09PSB1bmRlZmluZWQpKSB7XG5cdFx0XHRcdGRhdGFzZXQucG9pbnRSYWRpdXMgPSBkYXRhc2V0LnJhZGl1cztcblx0XHRcdH1cblx0XHRcdGlmICgoZGF0YXNldC5oaXRSYWRpdXMgIT09IHVuZGVmaW5lZCkgJiYgKGRhdGFzZXQucG9pbnRIaXRSYWRpdXMgPT09IHVuZGVmaW5lZCkpIHtcblx0XHRcdFx0ZGF0YXNldC5wb2ludEhpdFJhZGl1cyA9IGRhdGFzZXQuaGl0UmFkaXVzO1xuXHRcdFx0fVxuXG5cdFx0XHRoZWxwZXJzLmV4dGVuZChwb2ludCwge1xuXHRcdFx0XHQvLyBVdGlsaXR5XG5cdFx0XHRcdF9kYXRhc2V0SW5kZXg6IG1lLmluZGV4LFxuXHRcdFx0XHRfaW5kZXg6IGluZGV4LFxuXHRcdFx0XHRfc2NhbGU6IHNjYWxlLFxuXG5cdFx0XHRcdC8vIERlc2lyZWQgdmlldyBwcm9wZXJ0aWVzXG5cdFx0XHRcdF9tb2RlbDoge1xuXHRcdFx0XHRcdHg6IHJlc2V0ID8gc2NhbGUueENlbnRlciA6IHBvaW50UG9zaXRpb24ueCwgLy8gdmFsdWUgbm90IHVzZWQgaW4gZGF0YXNldCBzY2FsZSwgYnV0IHdlIHdhbnQgYSBjb25zaXN0ZW50IEFQSSBiZXR3ZWVuIHNjYWxlc1xuXHRcdFx0XHRcdHk6IHJlc2V0ID8gc2NhbGUueUNlbnRlciA6IHBvaW50UG9zaXRpb24ueSxcblxuXHRcdFx0XHRcdC8vIEFwcGVhcmFuY2Vcblx0XHRcdFx0XHR0ZW5zaW9uOiBjdXN0b20udGVuc2lvbiA/IGN1c3RvbS50ZW5zaW9uIDogaGVscGVycy52YWx1ZU9yRGVmYXVsdChkYXRhc2V0LmxpbmVUZW5zaW9uLCBtZS5jaGFydC5vcHRpb25zLmVsZW1lbnRzLmxpbmUudGVuc2lvbiksXG5cdFx0XHRcdFx0cmFkaXVzOiBjdXN0b20ucmFkaXVzID8gY3VzdG9tLnJhZGl1cyA6IGhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0KGRhdGFzZXQucG9pbnRSYWRpdXMsIGluZGV4LCBwb2ludEVsZW1lbnRPcHRpb25zLnJhZGl1cyksXG5cdFx0XHRcdFx0YmFja2dyb3VuZENvbG9yOiBjdXN0b20uYmFja2dyb3VuZENvbG9yID8gY3VzdG9tLmJhY2tncm91bmRDb2xvciA6IGhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0KGRhdGFzZXQucG9pbnRCYWNrZ3JvdW5kQ29sb3IsIGluZGV4LCBwb2ludEVsZW1lbnRPcHRpb25zLmJhY2tncm91bmRDb2xvciksXG5cdFx0XHRcdFx0Ym9yZGVyQ29sb3I6IGN1c3RvbS5ib3JkZXJDb2xvciA/IGN1c3RvbS5ib3JkZXJDb2xvciA6IGhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0KGRhdGFzZXQucG9pbnRCb3JkZXJDb2xvciwgaW5kZXgsIHBvaW50RWxlbWVudE9wdGlvbnMuYm9yZGVyQ29sb3IpLFxuXHRcdFx0XHRcdGJvcmRlcldpZHRoOiBjdXN0b20uYm9yZGVyV2lkdGggPyBjdXN0b20uYm9yZGVyV2lkdGggOiBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdChkYXRhc2V0LnBvaW50Qm9yZGVyV2lkdGgsIGluZGV4LCBwb2ludEVsZW1lbnRPcHRpb25zLmJvcmRlcldpZHRoKSxcblx0XHRcdFx0XHRwb2ludFN0eWxlOiBjdXN0b20ucG9pbnRTdHlsZSA/IGN1c3RvbS5wb2ludFN0eWxlIDogaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZGF0YXNldC5wb2ludFN0eWxlLCBpbmRleCwgcG9pbnRFbGVtZW50T3B0aW9ucy5wb2ludFN0eWxlKSxcblx0XHRcdFx0XHRyb3RhdGlvbjogY3VzdG9tLnJvdGF0aW9uID8gY3VzdG9tLnJvdGF0aW9uIDogaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZGF0YXNldC5wb2ludFJvdGF0aW9uLCBpbmRleCwgcG9pbnRFbGVtZW50T3B0aW9ucy5yb3RhdGlvbiksXG5cblx0XHRcdFx0XHQvLyBUb29sdGlwXG5cdFx0XHRcdFx0aGl0UmFkaXVzOiBjdXN0b20uaGl0UmFkaXVzID8gY3VzdG9tLmhpdFJhZGl1cyA6IGhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0KGRhdGFzZXQucG9pbnRIaXRSYWRpdXMsIGluZGV4LCBwb2ludEVsZW1lbnRPcHRpb25zLmhpdFJhZGl1cylcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdHBvaW50Ll9tb2RlbC5za2lwID0gY3VzdG9tLnNraXAgPyBjdXN0b20uc2tpcCA6IChpc05hTihwb2ludC5fbW9kZWwueCkgfHwgaXNOYU4ocG9pbnQuX21vZGVsLnkpKTtcblx0XHR9LFxuXHRcdHVwZGF0ZUJlemllckNvbnRyb2xQb2ludHM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGNoYXJ0QXJlYSA9IHRoaXMuY2hhcnQuY2hhcnRBcmVhO1xuXHRcdFx0dmFyIG1ldGEgPSB0aGlzLmdldE1ldGEoKTtcblxuXHRcdFx0aGVscGVycy5lYWNoKG1ldGEuZGF0YSwgZnVuY3Rpb24ocG9pbnQsIGluZGV4KSB7XG5cdFx0XHRcdHZhciBtb2RlbCA9IHBvaW50Ll9tb2RlbDtcblx0XHRcdFx0dmFyIGNvbnRyb2xQb2ludHMgPSBoZWxwZXJzLnNwbGluZUN1cnZlKFxuXHRcdFx0XHRcdGhlbHBlcnMucHJldmlvdXNJdGVtKG1ldGEuZGF0YSwgaW5kZXgsIHRydWUpLl9tb2RlbCxcblx0XHRcdFx0XHRtb2RlbCxcblx0XHRcdFx0XHRoZWxwZXJzLm5leHRJdGVtKG1ldGEuZGF0YSwgaW5kZXgsIHRydWUpLl9tb2RlbCxcblx0XHRcdFx0XHRtb2RlbC50ZW5zaW9uXG5cdFx0XHRcdCk7XG5cblx0XHRcdFx0Ly8gUHJldmVudCB0aGUgYmV6aWVyIGdvaW5nIG91dHNpZGUgb2YgdGhlIGJvdW5kcyBvZiB0aGUgZ3JhcGhcblx0XHRcdFx0bW9kZWwuY29udHJvbFBvaW50UHJldmlvdXNYID0gTWF0aC5tYXgoTWF0aC5taW4oY29udHJvbFBvaW50cy5wcmV2aW91cy54LCBjaGFydEFyZWEucmlnaHQpLCBjaGFydEFyZWEubGVmdCk7XG5cdFx0XHRcdG1vZGVsLmNvbnRyb2xQb2ludFByZXZpb3VzWSA9IE1hdGgubWF4KE1hdGgubWluKGNvbnRyb2xQb2ludHMucHJldmlvdXMueSwgY2hhcnRBcmVhLmJvdHRvbSksIGNoYXJ0QXJlYS50b3ApO1xuXG5cdFx0XHRcdG1vZGVsLmNvbnRyb2xQb2ludE5leHRYID0gTWF0aC5tYXgoTWF0aC5taW4oY29udHJvbFBvaW50cy5uZXh0LngsIGNoYXJ0QXJlYS5yaWdodCksIGNoYXJ0QXJlYS5sZWZ0KTtcblx0XHRcdFx0bW9kZWwuY29udHJvbFBvaW50TmV4dFkgPSBNYXRoLm1heChNYXRoLm1pbihjb250cm9sUG9pbnRzLm5leHQueSwgY2hhcnRBcmVhLmJvdHRvbSksIGNoYXJ0QXJlYS50b3ApO1xuXG5cdFx0XHRcdC8vIE5vdyBwaXZvdCB0aGUgcG9pbnQgZm9yIGFuaW1hdGlvblxuXHRcdFx0XHRwb2ludC5waXZvdCgpO1xuXHRcdFx0fSk7XG5cdFx0fSxcblxuXHRcdHNldEhvdmVyU3R5bGU6IGZ1bmN0aW9uKHBvaW50KSB7XG5cdFx0XHQvLyBQb2ludFxuXHRcdFx0dmFyIGRhdGFzZXQgPSB0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbcG9pbnQuX2RhdGFzZXRJbmRleF07XG5cdFx0XHR2YXIgY3VzdG9tID0gcG9pbnQuY3VzdG9tIHx8IHt9O1xuXHRcdFx0dmFyIGluZGV4ID0gcG9pbnQuX2luZGV4O1xuXHRcdFx0dmFyIG1vZGVsID0gcG9pbnQuX21vZGVsO1xuXG5cdFx0XHRwb2ludC4kcHJldmlvdXNTdHlsZSA9IHtcblx0XHRcdFx0YmFja2dyb3VuZENvbG9yOiBtb2RlbC5iYWNrZ3JvdW5kQ29sb3IsXG5cdFx0XHRcdGJvcmRlckNvbG9yOiBtb2RlbC5ib3JkZXJDb2xvcixcblx0XHRcdFx0Ym9yZGVyV2lkdGg6IG1vZGVsLmJvcmRlcldpZHRoLFxuXHRcdFx0XHRyYWRpdXM6IG1vZGVsLnJhZGl1c1xuXHRcdFx0fTtcblxuXHRcdFx0bW9kZWwucmFkaXVzID0gY3VzdG9tLmhvdmVyUmFkaXVzID8gY3VzdG9tLmhvdmVyUmFkaXVzIDogaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZGF0YXNldC5wb2ludEhvdmVyUmFkaXVzLCBpbmRleCwgdGhpcy5jaGFydC5vcHRpb25zLmVsZW1lbnRzLnBvaW50LmhvdmVyUmFkaXVzKTtcblx0XHRcdG1vZGVsLmJhY2tncm91bmRDb2xvciA9IGN1c3RvbS5ob3ZlckJhY2tncm91bmRDb2xvciA/IGN1c3RvbS5ob3ZlckJhY2tncm91bmRDb2xvciA6IGhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0KGRhdGFzZXQucG9pbnRIb3ZlckJhY2tncm91bmRDb2xvciwgaW5kZXgsIGhlbHBlcnMuZ2V0SG92ZXJDb2xvcihtb2RlbC5iYWNrZ3JvdW5kQ29sb3IpKTtcblx0XHRcdG1vZGVsLmJvcmRlckNvbG9yID0gY3VzdG9tLmhvdmVyQm9yZGVyQ29sb3IgPyBjdXN0b20uaG92ZXJCb3JkZXJDb2xvciA6IGhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0KGRhdGFzZXQucG9pbnRIb3ZlckJvcmRlckNvbG9yLCBpbmRleCwgaGVscGVycy5nZXRIb3ZlckNvbG9yKG1vZGVsLmJvcmRlckNvbG9yKSk7XG5cdFx0XHRtb2RlbC5ib3JkZXJXaWR0aCA9IGN1c3RvbS5ob3ZlckJvcmRlcldpZHRoID8gY3VzdG9tLmhvdmVyQm9yZGVyV2lkdGggOiBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdChkYXRhc2V0LnBvaW50SG92ZXJCb3JkZXJXaWR0aCwgaW5kZXgsIG1vZGVsLmJvcmRlcldpZHRoKTtcblx0XHR9LFxuXHR9KTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///241a\n')},"24eb":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar Element = __webpack_require__(/*! ../core/core.element */ \"4a45\");\n\ndefaults._set('global', {\n\telements: {\n\t\trectangle: {\n\t\t\tbackgroundColor: defaults.global.defaultColor,\n\t\t\tborderColor: defaults.global.defaultColor,\n\t\t\tborderSkipped: 'bottom',\n\t\t\tborderWidth: 0\n\t\t}\n\t}\n});\n\nfunction isVertical(bar) {\n\treturn bar._view.width !== undefined;\n}\n\n/**\n * Helper function to get the bounds of the bar regardless of the orientation\n * @param bar {Chart.Element.Rectangle} the bar\n * @return {Bounds} bounds of the bar\n * @private\n */\nfunction getBarBounds(bar) {\n\tvar vm = bar._view;\n\tvar x1, x2, y1, y2;\n\n\tif (isVertical(bar)) {\n\t\t// vertical\n\t\tvar halfWidth = vm.width / 2;\n\t\tx1 = vm.x - halfWidth;\n\t\tx2 = vm.x + halfWidth;\n\t\ty1 = Math.min(vm.y, vm.base);\n\t\ty2 = Math.max(vm.y, vm.base);\n\t} else {\n\t\t// horizontal bar\n\t\tvar halfHeight = vm.height / 2;\n\t\tx1 = Math.min(vm.x, vm.base);\n\t\tx2 = Math.max(vm.x, vm.base);\n\t\ty1 = vm.y - halfHeight;\n\t\ty2 = vm.y + halfHeight;\n\t}\n\n\treturn {\n\t\tleft: x1,\n\t\ttop: y1,\n\t\tright: x2,\n\t\tbottom: y2\n\t};\n}\n\nmodule.exports = Element.extend({\n\tdraw: function() {\n\t\tvar ctx = this._chart.ctx;\n\t\tvar vm = this._view;\n\t\tvar left, right, top, bottom, signX, signY, borderSkipped;\n\t\tvar borderWidth = vm.borderWidth;\n\n\t\tif (!vm.horizontal) {\n\t\t\t// bar\n\t\t\tleft = vm.x - vm.width / 2;\n\t\t\tright = vm.x + vm.width / 2;\n\t\t\ttop = vm.y;\n\t\t\tbottom = vm.base;\n\t\t\tsignX = 1;\n\t\t\tsignY = bottom > top ? 1 : -1;\n\t\t\tborderSkipped = vm.borderSkipped || 'bottom';\n\t\t} else {\n\t\t\t// horizontal bar\n\t\t\tleft = vm.base;\n\t\t\tright = vm.x;\n\t\t\ttop = vm.y - vm.height / 2;\n\t\t\tbottom = vm.y + vm.height / 2;\n\t\t\tsignX = right > left ? 1 : -1;\n\t\t\tsignY = 1;\n\t\t\tborderSkipped = vm.borderSkipped || 'left';\n\t\t}\n\n\t\t// Canvas doesn't allow us to stroke inside the width so we can\n\t\t// adjust the sizes to fit if we're setting a stroke on the line\n\t\tif (borderWidth) {\n\t\t\t// borderWidth shold be less than bar width and bar height.\n\t\t\tvar barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));\n\t\t\tborderWidth = borderWidth > barSize ? barSize : borderWidth;\n\t\t\tvar halfStroke = borderWidth / 2;\n\t\t\t// Adjust borderWidth when bar top position is near vm.base(zero).\n\t\t\tvar borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0);\n\t\t\tvar borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0);\n\t\t\tvar borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0);\n\t\t\tvar borderBottom = bottom + (borderSkipped !== 'bottom' ? -halfStroke * signY : 0);\n\t\t\t// not become a vertical line?\n\t\t\tif (borderLeft !== borderRight) {\n\t\t\t\ttop = borderTop;\n\t\t\t\tbottom = borderBottom;\n\t\t\t}\n\t\t\t// not become a horizontal line?\n\t\t\tif (borderTop !== borderBottom) {\n\t\t\t\tleft = borderLeft;\n\t\t\t\tright = borderRight;\n\t\t\t}\n\t\t}\n\n\t\tctx.beginPath();\n\t\tctx.fillStyle = vm.backgroundColor;\n\t\tctx.strokeStyle = vm.borderColor;\n\t\tctx.lineWidth = borderWidth;\n\n\t\t// Corner points, from bottom-left to bottom-right clockwise\n\t\t// | 1 2 |\n\t\t// | 0 3 |\n\t\tvar corners = [\n\t\t\t[left, bottom],\n\t\t\t[left, top],\n\t\t\t[right, top],\n\t\t\t[right, bottom]\n\t\t];\n\n\t\t// Find first (starting) corner with fallback to 'bottom'\n\t\tvar borders = ['bottom', 'left', 'top', 'right'];\n\t\tvar startCorner = borders.indexOf(borderSkipped, 0);\n\t\tif (startCorner === -1) {\n\t\t\tstartCorner = 0;\n\t\t}\n\n\t\tfunction cornerAt(index) {\n\t\t\treturn corners[(startCorner + index) % 4];\n\t\t}\n\n\t\t// Draw rectangle from 'startCorner'\n\t\tvar corner = cornerAt(0);\n\t\tctx.moveTo(corner[0], corner[1]);\n\n\t\tfor (var i = 1; i < 4; i++) {\n\t\t\tcorner = cornerAt(i);\n\t\t\tctx.lineTo(corner[0], corner[1]);\n\t\t}\n\n\t\tctx.fill();\n\t\tif (borderWidth) {\n\t\t\tctx.stroke();\n\t\t}\n\t},\n\n\theight: function() {\n\t\tvar vm = this._view;\n\t\treturn vm.base - vm.y;\n\t},\n\n\tinRange: function(mouseX, mouseY) {\n\t\tvar inRange = false;\n\n\t\tif (this._view) {\n\t\t\tvar bounds = getBarBounds(this);\n\t\t\tinRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t\t}\n\n\t\treturn inRange;\n\t},\n\n\tinLabelRange: function(mouseX, mouseY) {\n\t\tvar me = this;\n\t\tif (!me._view) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar inRange = false;\n\t\tvar bounds = getBarBounds(me);\n\n\t\tif (isVertical(me)) {\n\t\t\tinRange = mouseX >= bounds.left && mouseX <= bounds.right;\n\t\t} else {\n\t\t\tinRange = mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t\t}\n\n\t\treturn inRange;\n\t},\n\n\tinXRange: function(mouseX) {\n\t\tvar bounds = getBarBounds(this);\n\t\treturn mouseX >= bounds.left && mouseX <= bounds.right;\n\t},\n\n\tinYRange: function(mouseY) {\n\t\tvar bounds = getBarBounds(this);\n\t\treturn mouseY >= bounds.top && mouseY <= bounds.bottom;\n\t},\n\n\tgetCenterPoint: function() {\n\t\tvar vm = this._view;\n\t\tvar x, y;\n\t\tif (isVertical(this)) {\n\t\t\tx = vm.x;\n\t\t\ty = (vm.y + vm.base) / 2;\n\t\t} else {\n\t\t\tx = (vm.x + vm.base) / 2;\n\t\t\ty = vm.y;\n\t\t}\n\n\t\treturn {x: x, y: y};\n\t},\n\n\tgetArea: function() {\n\t\tvar vm = this._view;\n\t\treturn vm.width * Math.abs(vm.y - vm.base);\n\t},\n\n\ttooltipPosition: function() {\n\t\tvar vm = this._view;\n\t\treturn {\n\t\t\tx: vm.x,\n\t\t\ty: vm.y\n\t\t};\n\t}\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjRlYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvZWxlbWVudHMvZWxlbWVudC5yZWN0YW5nbGUuanM/ZDk0NSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5kZWZhdWx0cycpO1xudmFyIEVsZW1lbnQgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuZWxlbWVudCcpO1xuXG5kZWZhdWx0cy5fc2V0KCdnbG9iYWwnLCB7XG5cdGVsZW1lbnRzOiB7XG5cdFx0cmVjdGFuZ2xlOiB7XG5cdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IGRlZmF1bHRzLmdsb2JhbC5kZWZhdWx0Q29sb3IsXG5cdFx0XHRib3JkZXJDb2xvcjogZGVmYXVsdHMuZ2xvYmFsLmRlZmF1bHRDb2xvcixcblx0XHRcdGJvcmRlclNraXBwZWQ6ICdib3R0b20nLFxuXHRcdFx0Ym9yZGVyV2lkdGg6IDBcblx0XHR9XG5cdH1cbn0pO1xuXG5mdW5jdGlvbiBpc1ZlcnRpY2FsKGJhcikge1xuXHRyZXR1cm4gYmFyLl92aWV3LndpZHRoICE9PSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGdldCB0aGUgYm91bmRzIG9mIHRoZSBiYXIgcmVnYXJkbGVzcyBvZiB0aGUgb3JpZW50YXRpb25cbiAqIEBwYXJhbSBiYXIge0NoYXJ0LkVsZW1lbnQuUmVjdGFuZ2xlfSB0aGUgYmFyXG4gKiBAcmV0dXJuIHtCb3VuZHN9IGJvdW5kcyBvZiB0aGUgYmFyXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBnZXRCYXJCb3VuZHMoYmFyKSB7XG5cdHZhciB2bSA9IGJhci5fdmlldztcblx0dmFyIHgxLCB4MiwgeTEsIHkyO1xuXG5cdGlmIChpc1ZlcnRpY2FsKGJhcikpIHtcblx0XHQvLyB2ZXJ0aWNhbFxuXHRcdHZhciBoYWxmV2lkdGggPSB2bS53aWR0aCAvIDI7XG5cdFx0eDEgPSB2bS54IC0gaGFsZldpZHRoO1xuXHRcdHgyID0gdm0ueCArIGhhbGZXaWR0aDtcblx0XHR5MSA9IE1hdGgubWluKHZtLnksIHZtLmJhc2UpO1xuXHRcdHkyID0gTWF0aC5tYXgodm0ueSwgdm0uYmFzZSk7XG5cdH0gZWxzZSB7XG5cdFx0Ly8gaG9yaXpvbnRhbCBiYXJcblx0XHR2YXIgaGFsZkhlaWdodCA9IHZtLmhlaWdodCAvIDI7XG5cdFx0eDEgPSBNYXRoLm1pbih2bS54LCB2bS5iYXNlKTtcblx0XHR4MiA9IE1hdGgubWF4KHZtLngsIHZtLmJhc2UpO1xuXHRcdHkxID0gdm0ueSAtIGhhbGZIZWlnaHQ7XG5cdFx0eTIgPSB2bS55ICsgaGFsZkhlaWdodDtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0bGVmdDogeDEsXG5cdFx0dG9wOiB5MSxcblx0XHRyaWdodDogeDIsXG5cdFx0Ym90dG9tOiB5MlxuXHR9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEVsZW1lbnQuZXh0ZW5kKHtcblx0ZHJhdzogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGN0eCA9IHRoaXMuX2NoYXJ0LmN0eDtcblx0XHR2YXIgdm0gPSB0aGlzLl92aWV3O1xuXHRcdHZhciBsZWZ0LCByaWdodCwgdG9wLCBib3R0b20sIHNpZ25YLCBzaWduWSwgYm9yZGVyU2tpcHBlZDtcblx0XHR2YXIgYm9yZGVyV2lkdGggPSB2bS5ib3JkZXJXaWR0aDtcblxuXHRcdGlmICghdm0uaG9yaXpvbnRhbCkge1xuXHRcdFx0Ly8gYmFyXG5cdFx0XHRsZWZ0ID0gdm0ueCAtIHZtLndpZHRoIC8gMjtcblx0XHRcdHJpZ2h0ID0gdm0ueCArIHZtLndpZHRoIC8gMjtcblx0XHRcdHRvcCA9IHZtLnk7XG5cdFx0XHRib3R0b20gPSB2bS5iYXNlO1xuXHRcdFx0c2lnblggPSAxO1xuXHRcdFx0c2lnblkgPSBib3R0b20gPiB0b3AgPyAxIDogLTE7XG5cdFx0XHRib3JkZXJTa2lwcGVkID0gdm0uYm9yZGVyU2tpcHBlZCB8fCAnYm90dG9tJztcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gaG9yaXpvbnRhbCBiYXJcblx0XHRcdGxlZnQgPSB2bS5iYXNlO1xuXHRcdFx0cmlnaHQgPSB2bS54O1xuXHRcdFx0dG9wID0gdm0ueSAtIHZtLmhlaWdodCAvIDI7XG5cdFx0XHRib3R0b20gPSB2bS55ICsgdm0uaGVpZ2h0IC8gMjtcblx0XHRcdHNpZ25YID0gcmlnaHQgPiBsZWZ0ID8gMSA6IC0xO1xuXHRcdFx0c2lnblkgPSAxO1xuXHRcdFx0Ym9yZGVyU2tpcHBlZCA9IHZtLmJvcmRlclNraXBwZWQgfHwgJ2xlZnQnO1xuXHRcdH1cblxuXHRcdC8vIENhbnZhcyBkb2Vzbid0IGFsbG93IHVzIHRvIHN0cm9rZSBpbnNpZGUgdGhlIHdpZHRoIHNvIHdlIGNhblxuXHRcdC8vIGFkanVzdCB0aGUgc2l6ZXMgdG8gZml0IGlmIHdlJ3JlIHNldHRpbmcgYSBzdHJva2Ugb24gdGhlIGxpbmVcblx0XHRpZiAoYm9yZGVyV2lkdGgpIHtcblx0XHRcdC8vIGJvcmRlcldpZHRoIHNob2xkIGJlIGxlc3MgdGhhbiBiYXIgd2lkdGggYW5kIGJhciBoZWlnaHQuXG5cdFx0XHR2YXIgYmFyU2l6ZSA9IE1hdGgubWluKE1hdGguYWJzKGxlZnQgLSByaWdodCksIE1hdGguYWJzKHRvcCAtIGJvdHRvbSkpO1xuXHRcdFx0Ym9yZGVyV2lkdGggPSBib3JkZXJXaWR0aCA+IGJhclNpemUgPyBiYXJTaXplIDogYm9yZGVyV2lkdGg7XG5cdFx0XHR2YXIgaGFsZlN0cm9rZSA9IGJvcmRlcldpZHRoIC8gMjtcblx0XHRcdC8vIEFkanVzdCBib3JkZXJXaWR0aCB3aGVuIGJhciB0b3AgcG9zaXRpb24gaXMgbmVhciB2bS5iYXNlKHplcm8pLlxuXHRcdFx0dmFyIGJvcmRlckxlZnQgPSBsZWZ0ICsgKGJvcmRlclNraXBwZWQgIT09ICdsZWZ0JyA/IGhhbGZTdHJva2UgKiBzaWduWCA6IDApO1xuXHRcdFx0dmFyIGJvcmRlclJpZ2h0ID0gcmlnaHQgKyAoYm9yZGVyU2tpcHBlZCAhPT0gJ3JpZ2h0JyA/IC1oYWxmU3Ryb2tlICogc2lnblggOiAwKTtcblx0XHRcdHZhciBib3JkZXJUb3AgPSB0b3AgKyAoYm9yZGVyU2tpcHBlZCAhPT0gJ3RvcCcgPyBoYWxmU3Ryb2tlICogc2lnblkgOiAwKTtcblx0XHRcdHZhciBib3JkZXJCb3R0b20gPSBib3R0b20gKyAoYm9yZGVyU2tpcHBlZCAhPT0gJ2JvdHRvbScgPyAtaGFsZlN0cm9rZSAqIHNpZ25ZIDogMCk7XG5cdFx0XHQvLyBub3QgYmVjb21lIGEgdmVydGljYWwgbGluZT9cblx0XHRcdGlmIChib3JkZXJMZWZ0ICE9PSBib3JkZXJSaWdodCkge1xuXHRcdFx0XHR0b3AgPSBib3JkZXJUb3A7XG5cdFx0XHRcdGJvdHRvbSA9IGJvcmRlckJvdHRvbTtcblx0XHRcdH1cblx0XHRcdC8vIG5vdCBiZWNvbWUgYSBob3Jpem9udGFsIGxpbmU/XG5cdFx0XHRpZiAoYm9yZGVyVG9wICE9PSBib3JkZXJCb3R0b20pIHtcblx0XHRcdFx0bGVmdCA9IGJvcmRlckxlZnQ7XG5cdFx0XHRcdHJpZ2h0ID0gYm9yZGVyUmlnaHQ7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Y3R4LmJlZ2luUGF0aCgpO1xuXHRcdGN0eC5maWxsU3R5bGUgPSB2bS5iYWNrZ3JvdW5kQ29sb3I7XG5cdFx0Y3R4LnN0cm9rZVN0eWxlID0gdm0uYm9yZGVyQ29sb3I7XG5cdFx0Y3R4LmxpbmVXaWR0aCA9IGJvcmRlcldpZHRoO1xuXG5cdFx0Ly8gQ29ybmVyIHBvaW50cywgZnJvbSBib3R0b20tbGVmdCB0byBib3R0b20tcmlnaHQgY2xvY2t3aXNlXG5cdFx0Ly8gfCAxIDIgfFxuXHRcdC8vIHwgMCAzIHxcblx0XHR2YXIgY29ybmVycyA9IFtcblx0XHRcdFtsZWZ0LCBib3R0b21dLFxuXHRcdFx0W2xlZnQsIHRvcF0sXG5cdFx0XHRbcmlnaHQsIHRvcF0sXG5cdFx0XHRbcmlnaHQsIGJvdHRvbV1cblx0XHRdO1xuXG5cdFx0Ly8gRmluZCBmaXJzdCAoc3RhcnRpbmcpIGNvcm5lciB3aXRoIGZhbGxiYWNrIHRvICdib3R0b20nXG5cdFx0dmFyIGJvcmRlcnMgPSBbJ2JvdHRvbScsICdsZWZ0JywgJ3RvcCcsICdyaWdodCddO1xuXHRcdHZhciBzdGFydENvcm5lciA9IGJvcmRlcnMuaW5kZXhPZihib3JkZXJTa2lwcGVkLCAwKTtcblx0XHRpZiAoc3RhcnRDb3JuZXIgPT09IC0xKSB7XG5cdFx0XHRzdGFydENvcm5lciA9IDA7XG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gY29ybmVyQXQoaW5kZXgpIHtcblx0XHRcdHJldHVybiBjb3JuZXJzWyhzdGFydENvcm5lciArIGluZGV4KSAlIDRdO1xuXHRcdH1cblxuXHRcdC8vIERyYXcgcmVjdGFuZ2xlIGZyb20gJ3N0YXJ0Q29ybmVyJ1xuXHRcdHZhciBjb3JuZXIgPSBjb3JuZXJBdCgwKTtcblx0XHRjdHgubW92ZVRvKGNvcm5lclswXSwgY29ybmVyWzFdKTtcblxuXHRcdGZvciAodmFyIGkgPSAxOyBpIDwgNDsgaSsrKSB7XG5cdFx0XHRjb3JuZXIgPSBjb3JuZXJBdChpKTtcblx0XHRcdGN0eC5saW5lVG8oY29ybmVyWzBdLCBjb3JuZXJbMV0pO1xuXHRcdH1cblxuXHRcdGN0eC5maWxsKCk7XG5cdFx0aWYgKGJvcmRlcldpZHRoKSB7XG5cdFx0XHRjdHguc3Ryb2tlKCk7XG5cdFx0fVxuXHR9LFxuXG5cdGhlaWdodDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIHZtID0gdGhpcy5fdmlldztcblx0XHRyZXR1cm4gdm0uYmFzZSAtIHZtLnk7XG5cdH0sXG5cblx0aW5SYW5nZTogZnVuY3Rpb24obW91c2VYLCBtb3VzZVkpIHtcblx0XHR2YXIgaW5SYW5nZSA9IGZhbHNlO1xuXG5cdFx0aWYgKHRoaXMuX3ZpZXcpIHtcblx0XHRcdHZhciBib3VuZHMgPSBnZXRCYXJCb3VuZHModGhpcyk7XG5cdFx0XHRpblJhbmdlID0gbW91c2VYID49IGJvdW5kcy5sZWZ0ICYmIG1vdXNlWCA8PSBib3VuZHMucmlnaHQgJiYgbW91c2VZID49IGJvdW5kcy50b3AgJiYgbW91c2VZIDw9IGJvdW5kcy5ib3R0b207XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGluUmFuZ2U7XG5cdH0sXG5cblx0aW5MYWJlbFJhbmdlOiBmdW5jdGlvbihtb3VzZVgsIG1vdXNlWSkge1xuXHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0aWYgKCFtZS5fdmlldykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHZhciBpblJhbmdlID0gZmFsc2U7XG5cdFx0dmFyIGJvdW5kcyA9IGdldEJhckJvdW5kcyhtZSk7XG5cblx0XHRpZiAoaXNWZXJ0aWNhbChtZSkpIHtcblx0XHRcdGluUmFuZ2UgPSBtb3VzZVggPj0gYm91bmRzLmxlZnQgJiYgbW91c2VYIDw9IGJvdW5kcy5yaWdodDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0aW5SYW5nZSA9IG1vdXNlWSA+PSBib3VuZHMudG9wICYmIG1vdXNlWSA8PSBib3VuZHMuYm90dG9tO1xuXHRcdH1cblxuXHRcdHJldHVybiBpblJhbmdlO1xuXHR9LFxuXG5cdGluWFJhbmdlOiBmdW5jdGlvbihtb3VzZVgpIHtcblx0XHR2YXIgYm91bmRzID0gZ2V0QmFyQm91bmRzKHRoaXMpO1xuXHRcdHJldHVybiBtb3VzZVggPj0gYm91bmRzLmxlZnQgJiYgbW91c2VYIDw9IGJvdW5kcy5yaWdodDtcblx0fSxcblxuXHRpbllSYW5nZTogZnVuY3Rpb24obW91c2VZKSB7XG5cdFx0dmFyIGJvdW5kcyA9IGdldEJhckJvdW5kcyh0aGlzKTtcblx0XHRyZXR1cm4gbW91c2VZID49IGJvdW5kcy50b3AgJiYgbW91c2VZIDw9IGJvdW5kcy5ib3R0b207XG5cdH0sXG5cblx0Z2V0Q2VudGVyUG9pbnQ6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XG5cdFx0dmFyIHgsIHk7XG5cdFx0aWYgKGlzVmVydGljYWwodGhpcykpIHtcblx0XHRcdHggPSB2bS54O1xuXHRcdFx0eSA9ICh2bS55ICsgdm0uYmFzZSkgLyAyO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR4ID0gKHZtLnggKyB2bS5iYXNlKSAvIDI7XG5cdFx0XHR5ID0gdm0ueTtcblx0XHR9XG5cblx0XHRyZXR1cm4ge3g6IHgsIHk6IHl9O1xuXHR9LFxuXG5cdGdldEFyZWE6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XG5cdFx0cmV0dXJuIHZtLndpZHRoICogTWF0aC5hYnModm0ueSAtIHZtLmJhc2UpO1xuXHR9LFxuXG5cdHRvb2x0aXBQb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIHZtID0gdGhpcy5fdmlldztcblx0XHRyZXR1cm4ge1xuXHRcdFx0eDogdm0ueCxcblx0XHRcdHk6IHZtLnlcblx0XHR9O1xuXHR9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///24eb\n")},"2bea":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar elements = __webpack_require__(/*! ../elements/index */ \"0687\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\ndefaults._set('bar', {\n\thover: {\n\t\tmode: 'label'\n\t},\n\n\tscales: {\n\t\txAxes: [{\n\t\t\ttype: 'category',\n\n\t\t\t// Specific to Bar Controller\n\t\t\tcategoryPercentage: 0.8,\n\t\t\tbarPercentage: 0.9,\n\n\t\t\t// offset settings\n\t\t\toffset: true,\n\n\t\t\t// grid line settings\n\t\t\tgridLines: {\n\t\t\t\toffsetGridLines: true\n\t\t\t}\n\t\t}],\n\n\t\tyAxes: [{\n\t\t\ttype: 'linear'\n\t\t}]\n\t}\n});\n\ndefaults._set('horizontalBar', {\n\thover: {\n\t\tmode: 'index',\n\t\taxis: 'y'\n\t},\n\n\tscales: {\n\t\txAxes: [{\n\t\t\ttype: 'linear',\n\t\t\tposition: 'bottom'\n\t\t}],\n\n\t\tyAxes: [{\n\t\t\tposition: 'left',\n\t\t\ttype: 'category',\n\n\t\t\t// Specific to Horizontal Bar Controller\n\t\t\tcategoryPercentage: 0.8,\n\t\t\tbarPercentage: 0.9,\n\n\t\t\t// offset settings\n\t\t\toffset: true,\n\n\t\t\t// grid line settings\n\t\t\tgridLines: {\n\t\t\t\toffsetGridLines: true\n\t\t\t}\n\t\t}]\n\t},\n\n\telements: {\n\t\trectangle: {\n\t\t\tborderSkipped: 'left'\n\t\t}\n\t},\n\n\ttooltips: {\n\t\tcallbacks: {\n\t\t\ttitle: function(item, data) {\n\t\t\t\t// Pick first xLabel for now\n\t\t\t\tvar title = '';\n\n\t\t\t\tif (item.length > 0) {\n\t\t\t\t\tif (item[0].yLabel) {\n\t\t\t\t\t\ttitle = item[0].yLabel;\n\t\t\t\t\t} else if (data.labels.length > 0 && item[0].index < data.labels.length) {\n\t\t\t\t\t\ttitle = data.labels[item[0].index];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn title;\n\t\t\t},\n\n\t\t\tlabel: function(item, data) {\n\t\t\t\tvar datasetLabel = data.datasets[item.datasetIndex].label || '';\n\t\t\t\treturn datasetLabel + ': ' + item.xLabel;\n\t\t\t}\n\t\t},\n\t\tmode: 'index',\n\t\taxis: 'y'\n\t}\n});\n\n/**\n * Computes the \"optimal\" sample size to maintain bars equally sized while preventing overlap.\n * @private\n */\nfunction computeMinSampleSize(scale, pixels) {\n\tvar min = scale.isHorizontal() ? scale.width : scale.height;\n\tvar ticks = scale.getTicks();\n\tvar prev, curr, i, ilen;\n\n\tfor (i = 1, ilen = pixels.length; i < ilen; ++i) {\n\t\tmin = Math.min(min, pixels[i] - pixels[i - 1]);\n\t}\n\n\tfor (i = 0, ilen = ticks.length; i < ilen; ++i) {\n\t\tcurr = scale.getPixelForTick(i);\n\t\tmin = i > 0 ? Math.min(min, curr - prev) : min;\n\t\tprev = curr;\n\t}\n\n\treturn min;\n}\n\n/**\n * Computes an \"ideal\" category based on the absolute bar thickness or, if undefined or null,\n * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This\n * mode currently always generates bars equally sized (until we introduce scriptable options?).\n * @private\n */\nfunction computeFitCategoryTraits(index, ruler, options) {\n\tvar thickness = options.barThickness;\n\tvar count = ruler.stackCount;\n\tvar curr = ruler.pixels[index];\n\tvar size, ratio;\n\n\tif (helpers.isNullOrUndef(thickness)) {\n\t\tsize = ruler.min * options.categoryPercentage;\n\t\tratio = options.barPercentage;\n\t} else {\n\t\t// When bar thickness is enforced, category and bar percentages are ignored.\n\t\t// Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%')\n\t\t// and deprecate barPercentage since this value is ignored when thickness is absolute.\n\t\tsize = thickness * count;\n\t\tratio = 1;\n\t}\n\n\treturn {\n\t\tchunk: size / count,\n\t\tratio: ratio,\n\t\tstart: curr - (size / 2)\n\t};\n}\n\n/**\n * Computes an \"optimal\" category that globally arranges bars side by side (no gap when\n * percentage options are 1), based on the previous and following categories. This mode\n * generates bars with different widths when data are not evenly spaced.\n * @private\n */\nfunction computeFlexCategoryTraits(index, ruler, options) {\n\tvar pixels = ruler.pixels;\n\tvar curr = pixels[index];\n\tvar prev = index > 0 ? pixels[index - 1] : null;\n\tvar next = index < pixels.length - 1 ? pixels[index + 1] : null;\n\tvar percent = options.categoryPercentage;\n\tvar start, size;\n\n\tif (prev === null) {\n\t\t// first data: its size is double based on the next point or,\n\t\t// if it's also the last data, we use the scale end extremity.\n\t\tprev = curr - (next === null ? ruler.end - curr : next - curr);\n\t}\n\n\tif (next === null) {\n\t\t// last data: its size is also double based on the previous point.\n\t\tnext = curr + curr - prev;\n\t}\n\n\tstart = curr - ((curr - prev) / 2) * percent;\n\tsize = ((next - prev) / 2) * percent;\n\n\treturn {\n\t\tchunk: size / ruler.stackCount,\n\t\tratio: options.barPercentage,\n\t\tstart: start\n\t};\n}\n\nmodule.exports = function(Chart) {\n\n\tChart.controllers.bar = Chart.DatasetController.extend({\n\n\t\tdataElementType: elements.Rectangle,\n\n\t\tinitialize: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta;\n\n\t\t\tChart.DatasetController.prototype.initialize.apply(me, arguments);\n\n\t\t\tmeta = me.getMeta();\n\t\t\tmeta.stack = me.getDataset().stack;\n\t\t\tmeta.bar = true;\n\t\t},\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar rects = me.getMeta().data;\n\t\t\tvar i, ilen;\n\n\t\t\tme._ruler = me.getRuler();\n\n\t\t\tfor (i = 0, ilen = rects.length; i < ilen; ++i) {\n\t\t\t\tme.updateElement(rects[i], i, reset);\n\t\t\t}\n\t\t},\n\n\t\tupdateElement: function(rectangle, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar custom = rectangle.custom || {};\n\t\t\tvar rectangleOptions = chart.options.elements.rectangle;\n\n\t\t\trectangle._xScale = me.getScaleForId(meta.xAxisID);\n\t\t\trectangle._yScale = me.getScaleForId(meta.yAxisID);\n\t\t\trectangle._datasetIndex = me.index;\n\t\t\trectangle._index = index;\n\n\t\t\trectangle._model = {\n\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\tlabel: chart.data.labels[index],\n\t\t\t\tborderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped,\n\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, rectangleOptions.backgroundColor),\n\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor),\n\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth)\n\t\t\t};\n\n\t\t\tme.updateElementGeometry(rectangle, index, reset);\n\n\t\t\trectangle.pivot();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tupdateElementGeometry: function(rectangle, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar model = rectangle._model;\n\t\t\tvar vscale = me.getValueScale();\n\t\t\tvar base = vscale.getBasePixel();\n\t\t\tvar horizontal = vscale.isHorizontal();\n\t\t\tvar ruler = me._ruler || me.getRuler();\n\t\t\tvar vpixels = me.calculateBarValuePixels(me.index, index);\n\t\t\tvar ipixels = me.calculateBarIndexPixels(me.index, index, ruler);\n\n\t\t\tmodel.horizontal = horizontal;\n\t\t\tmodel.base = reset ? base : vpixels.base;\n\t\t\tmodel.x = horizontal ? reset ? base : vpixels.head : ipixels.center;\n\t\t\tmodel.y = horizontal ? ipixels.center : reset ? base : vpixels.head;\n\t\t\tmodel.height = horizontal ? ipixels.size : undefined;\n\t\t\tmodel.width = horizontal ? undefined : ipixels.size;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScaleId: function() {\n\t\t\treturn this.getMeta().yAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScaleId: function() {\n\t\t\treturn this.getMeta().xAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScale: function() {\n\t\t\treturn this.getScaleForId(this.getValueScaleId());\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScale: function() {\n\t\t\treturn this.getScaleForId(this.getIndexScaleId());\n\t\t},\n\n\t\t/**\n\t\t * Returns the stacks based on groups and bar visibility.\n\t\t * @param {Number} [last] - The dataset index\n\t\t * @returns {Array} The stack list\n\t\t * @private\n\t\t */\n\t\t_getStacks: function(last) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar scale = me.getIndexScale();\n\t\t\tvar stacked = scale.options.stacked;\n\t\t\tvar ilen = last === undefined ? chart.data.datasets.length : last + 1;\n\t\t\tvar stacks = [];\n\t\t\tvar i, meta;\n\n\t\t\tfor (i = 0; i < ilen; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\tif (meta.bar && chart.isDatasetVisible(i) &&\n\t\t\t\t\t(stacked === false ||\n\t\t\t\t\t(stacked === true && stacks.indexOf(meta.stack) === -1) ||\n\t\t\t\t\t(stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) {\n\t\t\t\t\tstacks.push(meta.stack);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn stacks;\n\t\t},\n\n\t\t/**\n\t\t * Returns the effective number of stacks based on groups and bar visibility.\n\t\t * @private\n\t\t */\n\t\tgetStackCount: function() {\n\t\t\treturn this._getStacks().length;\n\t\t},\n\n\t\t/**\n\t\t * Returns the stack index for the given dataset based on groups and bar visibility.\n\t\t * @param {Number} [datasetIndex] - The dataset index\n\t\t * @param {String} [name] - The stack name to find\n\t\t * @returns {Number} The stack index\n\t\t * @private\n\t\t */\n\t\tgetStackIndex: function(datasetIndex, name) {\n\t\t\tvar stacks = this._getStacks(datasetIndex);\n\t\t\tvar index = (name !== undefined)\n\t\t\t\t? stacks.indexOf(name)\n\t\t\t\t: -1; // indexOf returns -1 if element is not present\n\n\t\t\treturn (index === -1)\n\t\t\t\t? stacks.length - 1\n\t\t\t\t: index;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetRuler: function() {\n\t\t\tvar me = this;\n\t\t\tvar scale = me.getIndexScale();\n\t\t\tvar stackCount = me.getStackCount();\n\t\t\tvar datasetIndex = me.index;\n\t\t\tvar isHorizontal = scale.isHorizontal();\n\t\t\tvar start = isHorizontal ? scale.left : scale.top;\n\t\t\tvar end = start + (isHorizontal ? scale.width : scale.height);\n\t\t\tvar pixels = [];\n\t\t\tvar i, ilen, min;\n\n\t\t\tfor (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) {\n\t\t\t\tpixels.push(scale.getPixelForValue(null, i, datasetIndex));\n\t\t\t}\n\n\t\t\tmin = helpers.isNullOrUndef(scale.options.barThickness)\n\t\t\t\t? computeMinSampleSize(scale, pixels)\n\t\t\t\t: -1;\n\n\t\t\treturn {\n\t\t\t\tmin: min,\n\t\t\t\tpixels: pixels,\n\t\t\t\tstart: start,\n\t\t\t\tend: end,\n\t\t\t\tstackCount: stackCount,\n\t\t\t\tscale: scale\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Note: pixel values are not clamped to the scale area.\n\t\t * @private\n\t\t */\n\t\tcalculateBarValuePixels: function(datasetIndex, index) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar scale = me.getValueScale();\n\t\t\tvar datasets = chart.data.datasets;\n\t\t\tvar value = scale.getRightValue(datasets[datasetIndex].data[index]);\n\t\t\tvar stacked = scale.options.stacked;\n\t\t\tvar stack = meta.stack;\n\t\t\tvar start = 0;\n\t\t\tvar i, imeta, ivalue, base, head, size;\n\n\t\t\tif (stacked || (stacked === undefined && stack !== undefined)) {\n\t\t\t\tfor (i = 0; i < datasetIndex; ++i) {\n\t\t\t\t\timeta = chart.getDatasetMeta(i);\n\n\t\t\t\t\tif (imeta.bar &&\n\t\t\t\t\t\timeta.stack === stack &&\n\t\t\t\t\t\timeta.controller.getValueScaleId() === scale.id &&\n\t\t\t\t\t\tchart.isDatasetVisible(i)) {\n\n\t\t\t\t\t\tivalue = scale.getRightValue(datasets[i].data[index]);\n\t\t\t\t\t\tif ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) {\n\t\t\t\t\t\t\tstart += ivalue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbase = scale.getPixelForValue(start);\n\t\t\thead = scale.getPixelForValue(start + value);\n\t\t\tsize = (head - base) / 2;\n\n\t\t\treturn {\n\t\t\t\tsize: size,\n\t\t\t\tbase: base,\n\t\t\t\thead: head,\n\t\t\t\tcenter: head + size / 2\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tcalculateBarIndexPixels: function(datasetIndex, index, ruler) {\n\t\t\tvar me = this;\n\t\t\tvar options = ruler.scale.options;\n\t\t\tvar range = options.barThickness === 'flex'\n\t\t\t\t? computeFlexCategoryTraits(index, ruler, options)\n\t\t\t\t: computeFitCategoryTraits(index, ruler, options);\n\n\t\t\tvar stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack);\n\t\t\tvar center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);\n\t\t\tvar size = Math.min(\n\t\t\t\thelpers.valueOrDefault(options.maxBarThickness, Infinity),\n\t\t\t\trange.chunk * range.ratio);\n\n\t\t\treturn {\n\t\t\t\tbase: center - size / 2,\n\t\t\t\thead: center + size / 2,\n\t\t\t\tcenter: center,\n\t\t\t\tsize: size\n\t\t\t};\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar scale = me.getValueScale();\n\t\t\tvar rects = me.getMeta().data;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar ilen = rects.length;\n\t\t\tvar i = 0;\n\n\t\t\thelpers.canvas.clipArea(chart.ctx, chart.chartArea);\n\n\t\t\tfor (; i < ilen; ++i) {\n\t\t\t\tif (!isNaN(scale.getRightValue(dataset.data[i]))) {\n\t\t\t\t\trects[i].draw();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\thelpers.canvas.unclipArea(chart.ctx);\n\t\t},\n\t});\n\n\tChart.controllers.horizontalBar = Chart.controllers.bar.extend({\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetValueScaleId: function() {\n\t\t\treturn this.getMeta().xAxisID;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetIndexScaleId: function() {\n\t\t\treturn this.getMeta().yAxisID;\n\t\t}\n\t});\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMmJlYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5iYXIuanM/NjQwMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5kZWZhdWx0cycpO1xudmFyIGVsZW1lbnRzID0gcmVxdWlyZSgnLi4vZWxlbWVudHMvaW5kZXgnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xuXG5kZWZhdWx0cy5fc2V0KCdiYXInLCB7XG5cdGhvdmVyOiB7XG5cdFx0bW9kZTogJ2xhYmVsJ1xuXHR9LFxuXG5cdHNjYWxlczoge1xuXHRcdHhBeGVzOiBbe1xuXHRcdFx0dHlwZTogJ2NhdGVnb3J5JyxcblxuXHRcdFx0Ly8gU3BlY2lmaWMgdG8gQmFyIENvbnRyb2xsZXJcblx0XHRcdGNhdGVnb3J5UGVyY2VudGFnZTogMC44LFxuXHRcdFx0YmFyUGVyY2VudGFnZTogMC45LFxuXG5cdFx0XHQvLyBvZmZzZXQgc2V0dGluZ3Ncblx0XHRcdG9mZnNldDogdHJ1ZSxcblxuXHRcdFx0Ly8gZ3JpZCBsaW5lIHNldHRpbmdzXG5cdFx0XHRncmlkTGluZXM6IHtcblx0XHRcdFx0b2Zmc2V0R3JpZExpbmVzOiB0cnVlXG5cdFx0XHR9XG5cdFx0fV0sXG5cblx0XHR5QXhlczogW3tcblx0XHRcdHR5cGU6ICdsaW5lYXInXG5cdFx0fV1cblx0fVxufSk7XG5cbmRlZmF1bHRzLl9zZXQoJ2hvcml6b250YWxCYXInLCB7XG5cdGhvdmVyOiB7XG5cdFx0bW9kZTogJ2luZGV4Jyxcblx0XHRheGlzOiAneSdcblx0fSxcblxuXHRzY2FsZXM6IHtcblx0XHR4QXhlczogW3tcblx0XHRcdHR5cGU6ICdsaW5lYXInLFxuXHRcdFx0cG9zaXRpb246ICdib3R0b20nXG5cdFx0fV0sXG5cblx0XHR5QXhlczogW3tcblx0XHRcdHBvc2l0aW9uOiAnbGVmdCcsXG5cdFx0XHR0eXBlOiAnY2F0ZWdvcnknLFxuXG5cdFx0XHQvLyBTcGVjaWZpYyB0byBIb3Jpem9udGFsIEJhciBDb250cm9sbGVyXG5cdFx0XHRjYXRlZ29yeVBlcmNlbnRhZ2U6IDAuOCxcblx0XHRcdGJhclBlcmNlbnRhZ2U6IDAuOSxcblxuXHRcdFx0Ly8gb2Zmc2V0IHNldHRpbmdzXG5cdFx0XHRvZmZzZXQ6IHRydWUsXG5cblx0XHRcdC8vIGdyaWQgbGluZSBzZXR0aW5nc1xuXHRcdFx0Z3JpZExpbmVzOiB7XG5cdFx0XHRcdG9mZnNldEdyaWRMaW5lczogdHJ1ZVxuXHRcdFx0fVxuXHRcdH1dXG5cdH0sXG5cblx0ZWxlbWVudHM6IHtcblx0XHRyZWN0YW5nbGU6IHtcblx0XHRcdGJvcmRlclNraXBwZWQ6ICdsZWZ0J1xuXHRcdH1cblx0fSxcblxuXHR0b29sdGlwczoge1xuXHRcdGNhbGxiYWNrczoge1xuXHRcdFx0dGl0bGU6IGZ1bmN0aW9uKGl0ZW0sIGRhdGEpIHtcblx0XHRcdFx0Ly8gUGljayBmaXJzdCB4TGFiZWwgZm9yIG5vd1xuXHRcdFx0XHR2YXIgdGl0bGUgPSAnJztcblxuXHRcdFx0XHRpZiAoaXRlbS5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0aWYgKGl0ZW1bMF0ueUxhYmVsKSB7XG5cdFx0XHRcdFx0XHR0aXRsZSA9IGl0ZW1bMF0ueUxhYmVsO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoZGF0YS5sYWJlbHMubGVuZ3RoID4gMCAmJiBpdGVtWzBdLmluZGV4IDwgZGF0YS5sYWJlbHMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHR0aXRsZSA9IGRhdGEubGFiZWxzW2l0ZW1bMF0uaW5kZXhdO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB0aXRsZTtcblx0XHRcdH0sXG5cblx0XHRcdGxhYmVsOiBmdW5jdGlvbihpdGVtLCBkYXRhKSB7XG5cdFx0XHRcdHZhciBkYXRhc2V0TGFiZWwgPSBkYXRhLmRhdGFzZXRzW2l0ZW0uZGF0YXNldEluZGV4XS5sYWJlbCB8fCAnJztcblx0XHRcdFx0cmV0dXJuIGRhdGFzZXRMYWJlbCArICc6ICcgKyBpdGVtLnhMYWJlbDtcblx0XHRcdH1cblx0XHR9LFxuXHRcdG1vZGU6ICdpbmRleCcsXG5cdFx0YXhpczogJ3knXG5cdH1cbn0pO1xuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBcIm9wdGltYWxcIiBzYW1wbGUgc2l6ZSB0byBtYWludGFpbiBiYXJzIGVxdWFsbHkgc2l6ZWQgd2hpbGUgcHJldmVudGluZyBvdmVybGFwLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY29tcHV0ZU1pblNhbXBsZVNpemUoc2NhbGUsIHBpeGVscykge1xuXHR2YXIgbWluID0gc2NhbGUuaXNIb3Jpem9udGFsKCkgPyBzY2FsZS53aWR0aCA6IHNjYWxlLmhlaWdodDtcblx0dmFyIHRpY2tzID0gc2NhbGUuZ2V0VGlja3MoKTtcblx0dmFyIHByZXYsIGN1cnIsIGksIGlsZW47XG5cblx0Zm9yIChpID0gMSwgaWxlbiA9IHBpeGVscy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRtaW4gPSBNYXRoLm1pbihtaW4sIHBpeGVsc1tpXSAtIHBpeGVsc1tpIC0gMV0pO1xuXHR9XG5cblx0Zm9yIChpID0gMCwgaWxlbiA9IHRpY2tzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdGN1cnIgPSBzY2FsZS5nZXRQaXhlbEZvclRpY2soaSk7XG5cdFx0bWluID0gaSA+IDAgPyBNYXRoLm1pbihtaW4sIGN1cnIgLSBwcmV2KSA6IG1pbjtcblx0XHRwcmV2ID0gY3Vycjtcblx0fVxuXG5cdHJldHVybiBtaW47XG59XG5cbi8qKlxuICogQ29tcHV0ZXMgYW4gXCJpZGVhbFwiIGNhdGVnb3J5IGJhc2VkIG9uIHRoZSBhYnNvbHV0ZSBiYXIgdGhpY2tuZXNzIG9yLCBpZiB1bmRlZmluZWQgb3IgbnVsbCxcbiAqIHVzZXMgdGhlIHNtYWxsZXN0IGludGVydmFsIChzZWUgY29tcHV0ZU1pblNhbXBsZVNpemUpIHRoYXQgcHJldmVudHMgYmFyIG92ZXJsYXBwaW5nLiBUaGlzXG4gKiBtb2RlIGN1cnJlbnRseSBhbHdheXMgZ2VuZXJhdGVzIGJhcnMgZXF1YWxseSBzaXplZCAodW50aWwgd2UgaW50cm9kdWNlIHNjcmlwdGFibGUgb3B0aW9ucz8pLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY29tcHV0ZUZpdENhdGVnb3J5VHJhaXRzKGluZGV4LCBydWxlciwgb3B0aW9ucykge1xuXHR2YXIgdGhpY2tuZXNzID0gb3B0aW9ucy5iYXJUaGlja25lc3M7XG5cdHZhciBjb3VudCA9IHJ1bGVyLnN0YWNrQ291bnQ7XG5cdHZhciBjdXJyID0gcnVsZXIucGl4ZWxzW2luZGV4XTtcblx0dmFyIHNpemUsIHJhdGlvO1xuXG5cdGlmIChoZWxwZXJzLmlzTnVsbE9yVW5kZWYodGhpY2tuZXNzKSkge1xuXHRcdHNpemUgPSBydWxlci5taW4gKiBvcHRpb25zLmNhdGVnb3J5UGVyY2VudGFnZTtcblx0XHRyYXRpbyA9IG9wdGlvbnMuYmFyUGVyY2VudGFnZTtcblx0fSBlbHNlIHtcblx0XHQvLyBXaGVuIGJhciB0aGlja25lc3MgaXMgZW5mb3JjZWQsIGNhdGVnb3J5IGFuZCBiYXIgcGVyY2VudGFnZXMgYXJlIGlnbm9yZWQuXG5cdFx0Ly8gTm90ZShTQik6IHdlIGNvdWxkIGFkZCBzdXBwb3J0IGZvciByZWxhdGl2ZSBiYXIgdGhpY2tuZXNzIChlLmcuIGJhclRoaWNrbmVzczogJzUwJScpXG5cdFx0Ly8gYW5kIGRlcHJlY2F0ZSBiYXJQZXJjZW50YWdlIHNpbmNlIHRoaXMgdmFsdWUgaXMgaWdub3JlZCB3aGVuIHRoaWNrbmVzcyBpcyBhYnNvbHV0ZS5cblx0XHRzaXplID0gdGhpY2tuZXNzICogY291bnQ7XG5cdFx0cmF0aW8gPSAxO1xuXHR9XG5cblx0cmV0dXJuIHtcblx0XHRjaHVuazogc2l6ZSAvIGNvdW50LFxuXHRcdHJhdGlvOiByYXRpbyxcblx0XHRzdGFydDogY3VyciAtIChzaXplIC8gMilcblx0fTtcbn1cblxuLyoqXG4gKiBDb21wdXRlcyBhbiBcIm9wdGltYWxcIiBjYXRlZ29yeSB0aGF0IGdsb2JhbGx5IGFycmFuZ2VzIGJhcnMgc2lkZSBieSBzaWRlIChubyBnYXAgd2hlblxuICogcGVyY2VudGFnZSBvcHRpb25zIGFyZSAxKSwgYmFzZWQgb24gdGhlIHByZXZpb3VzIGFuZCBmb2xsb3dpbmcgY2F0ZWdvcmllcy4gVGhpcyBtb2RlXG4gKiBnZW5lcmF0ZXMgYmFycyB3aXRoIGRpZmZlcmVudCB3aWR0aHMgd2hlbiBkYXRhIGFyZSBub3QgZXZlbmx5IHNwYWNlZC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGNvbXB1dGVGbGV4Q2F0ZWdvcnlUcmFpdHMoaW5kZXgsIHJ1bGVyLCBvcHRpb25zKSB7XG5cdHZhciBwaXhlbHMgPSBydWxlci5waXhlbHM7XG5cdHZhciBjdXJyID0gcGl4ZWxzW2luZGV4XTtcblx0dmFyIHByZXYgPSBpbmRleCA+IDAgPyBwaXhlbHNbaW5kZXggLSAxXSA6IG51bGw7XG5cdHZhciBuZXh0ID0gaW5kZXggPCBwaXhlbHMubGVuZ3RoIC0gMSA/IHBpeGVsc1tpbmRleCArIDFdIDogbnVsbDtcblx0dmFyIHBlcmNlbnQgPSBvcHRpb25zLmNhdGVnb3J5UGVyY2VudGFnZTtcblx0dmFyIHN0YXJ0LCBzaXplO1xuXG5cdGlmIChwcmV2ID09PSBudWxsKSB7XG5cdFx0Ly8gZmlyc3QgZGF0YTogaXRzIHNpemUgaXMgZG91YmxlIGJhc2VkIG9uIHRoZSBuZXh0IHBvaW50IG9yLFxuXHRcdC8vIGlmIGl0J3MgYWxzbyB0aGUgbGFzdCBkYXRhLCB3ZSB1c2UgdGhlIHNjYWxlIGVuZCBleHRyZW1pdHkuXG5cdFx0cHJldiA9IGN1cnIgLSAobmV4dCA9PT0gbnVsbCA/IHJ1bGVyLmVuZCAtIGN1cnIgOiBuZXh0IC0gY3Vycik7XG5cdH1cblxuXHRpZiAobmV4dCA9PT0gbnVsbCkge1xuXHRcdC8vIGxhc3QgZGF0YTogaXRzIHNpemUgaXMgYWxzbyBkb3VibGUgYmFzZWQgb24gdGhlIHByZXZpb3VzIHBvaW50LlxuXHRcdG5leHQgPSBjdXJyICsgY3VyciAtIHByZXY7XG5cdH1cblxuXHRzdGFydCA9IGN1cnIgLSAoKGN1cnIgLSBwcmV2KSAvIDIpICogcGVyY2VudDtcblx0c2l6ZSA9ICgobmV4dCAtIHByZXYpIC8gMikgKiBwZXJjZW50O1xuXG5cdHJldHVybiB7XG5cdFx0Y2h1bms6IHNpemUgLyBydWxlci5zdGFja0NvdW50LFxuXHRcdHJhdGlvOiBvcHRpb25zLmJhclBlcmNlbnRhZ2UsXG5cdFx0c3RhcnQ6IHN0YXJ0XG5cdH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oQ2hhcnQpIHtcblxuXHRDaGFydC5jb250cm9sbGVycy5iYXIgPSBDaGFydC5EYXRhc2V0Q29udHJvbGxlci5leHRlbmQoe1xuXG5cdFx0ZGF0YUVsZW1lbnRUeXBlOiBlbGVtZW50cy5SZWN0YW5nbGUsXG5cblx0XHRpbml0aWFsaXplOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgbWV0YTtcblxuXHRcdFx0Q2hhcnQuRGF0YXNldENvbnRyb2xsZXIucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkobWUsIGFyZ3VtZW50cyk7XG5cblx0XHRcdG1ldGEgPSBtZS5nZXRNZXRhKCk7XG5cdFx0XHRtZXRhLnN0YWNrID0gbWUuZ2V0RGF0YXNldCgpLnN0YWNrO1xuXHRcdFx0bWV0YS5iYXIgPSB0cnVlO1xuXHRcdH0sXG5cblx0XHR1cGRhdGU6IGZ1bmN0aW9uKHJlc2V0KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIHJlY3RzID0gbWUuZ2V0TWV0YSgpLmRhdGE7XG5cdFx0XHR2YXIgaSwgaWxlbjtcblxuXHRcdFx0bWUuX3J1bGVyID0gbWUuZ2V0UnVsZXIoKTtcblxuXHRcdFx0Zm9yIChpID0gMCwgaWxlbiA9IHJlY3RzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdFx0XHRtZS51cGRhdGVFbGVtZW50KHJlY3RzW2ldLCBpLCByZXNldCk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdHVwZGF0ZUVsZW1lbnQ6IGZ1bmN0aW9uKHJlY3RhbmdsZSwgaW5kZXgsIHJlc2V0KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XG5cdFx0XHR2YXIgbWV0YSA9IG1lLmdldE1ldGEoKTtcblx0XHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xuXHRcdFx0dmFyIGN1c3RvbSA9IHJlY3RhbmdsZS5jdXN0b20gfHwge307XG5cdFx0XHR2YXIgcmVjdGFuZ2xlT3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnMuZWxlbWVudHMucmVjdGFuZ2xlO1xuXG5cdFx0XHRyZWN0YW5nbGUuX3hTY2FsZSA9IG1lLmdldFNjYWxlRm9ySWQobWV0YS54QXhpc0lEKTtcblx0XHRcdHJlY3RhbmdsZS5feVNjYWxlID0gbWUuZ2V0U2NhbGVGb3JJZChtZXRhLnlBeGlzSUQpO1xuXHRcdFx0cmVjdGFuZ2xlLl9kYXRhc2V0SW5kZXggPSBtZS5pbmRleDtcblx0XHRcdHJlY3RhbmdsZS5faW5kZXggPSBpbmRleDtcblxuXHRcdFx0cmVjdGFuZ2xlLl9tb2RlbCA9IHtcblx0XHRcdFx0ZGF0YXNldExhYmVsOiBkYXRhc2V0LmxhYmVsLFxuXHRcdFx0XHRsYWJlbDogY2hhcnQuZGF0YS5sYWJlbHNbaW5kZXhdLFxuXHRcdFx0XHRib3JkZXJTa2lwcGVkOiBjdXN0b20uYm9yZGVyU2tpcHBlZCA/IGN1c3RvbS5ib3JkZXJTa2lwcGVkIDogcmVjdGFuZ2xlT3B0aW9ucy5ib3JkZXJTa2lwcGVkLFxuXHRcdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IGN1c3RvbS5iYWNrZ3JvdW5kQ29sb3IgPyBjdXN0b20uYmFja2dyb3VuZENvbG9yIDogaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZGF0YXNldC5iYWNrZ3JvdW5kQ29sb3IsIGluZGV4LCByZWN0YW5nbGVPcHRpb25zLmJhY2tncm91bmRDb2xvciksXG5cdFx0XHRcdGJvcmRlckNvbG9yOiBjdXN0b20uYm9yZGVyQ29sb3IgPyBjdXN0b20uYm9yZGVyQ29sb3IgOiBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdChkYXRhc2V0LmJvcmRlckNvbG9yLCBpbmRleCwgcmVjdGFuZ2xlT3B0aW9ucy5ib3JkZXJDb2xvciksXG5cdFx0XHRcdGJvcmRlcldpZHRoOiBjdXN0b20uYm9yZGVyV2lkdGggPyBjdXN0b20uYm9yZGVyV2lkdGggOiBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdChkYXRhc2V0LmJvcmRlcldpZHRoLCBpbmRleCwgcmVjdGFuZ2xlT3B0aW9ucy5ib3JkZXJXaWR0aClcblx0XHRcdH07XG5cblx0XHRcdG1lLnVwZGF0ZUVsZW1lbnRHZW9tZXRyeShyZWN0YW5nbGUsIGluZGV4LCByZXNldCk7XG5cblx0XHRcdHJlY3RhbmdsZS5waXZvdCgpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdHVwZGF0ZUVsZW1lbnRHZW9tZXRyeTogZnVuY3Rpb24ocmVjdGFuZ2xlLCBpbmRleCwgcmVzZXQpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgbW9kZWwgPSByZWN0YW5nbGUuX21vZGVsO1xuXHRcdFx0dmFyIHZzY2FsZSA9IG1lLmdldFZhbHVlU2NhbGUoKTtcblx0XHRcdHZhciBiYXNlID0gdnNjYWxlLmdldEJhc2VQaXhlbCgpO1xuXHRcdFx0dmFyIGhvcml6b250YWwgPSB2c2NhbGUuaXNIb3Jpem9udGFsKCk7XG5cdFx0XHR2YXIgcnVsZXIgPSBtZS5fcnVsZXIgfHwgbWUuZ2V0UnVsZXIoKTtcblx0XHRcdHZhciB2cGl4ZWxzID0gbWUuY2FsY3VsYXRlQmFyVmFsdWVQaXhlbHMobWUuaW5kZXgsIGluZGV4KTtcblx0XHRcdHZhciBpcGl4ZWxzID0gbWUuY2FsY3VsYXRlQmFySW5kZXhQaXhlbHMobWUuaW5kZXgsIGluZGV4LCBydWxlcik7XG5cblx0XHRcdG1vZGVsLmhvcml6b250YWwgPSBob3Jpem9udGFsO1xuXHRcdFx0bW9kZWwuYmFzZSA9IHJlc2V0ID8gYmFzZSA6IHZwaXhlbHMuYmFzZTtcblx0XHRcdG1vZGVsLnggPSBob3Jpem9udGFsID8gcmVzZXQgPyBiYXNlIDogdnBpeGVscy5oZWFkIDogaXBpeGVscy5jZW50ZXI7XG5cdFx0XHRtb2RlbC55ID0gaG9yaXpvbnRhbCA/IGlwaXhlbHMuY2VudGVyIDogcmVzZXQgPyBiYXNlIDogdnBpeGVscy5oZWFkO1xuXHRcdFx0bW9kZWwuaGVpZ2h0ID0gaG9yaXpvbnRhbCA/IGlwaXhlbHMuc2l6ZSA6IHVuZGVmaW5lZDtcblx0XHRcdG1vZGVsLndpZHRoID0gaG9yaXpvbnRhbCA/IHVuZGVmaW5lZCA6IGlwaXhlbHMuc2l6ZTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRnZXRWYWx1ZVNjYWxlSWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZ2V0TWV0YSgpLnlBeGlzSUQ7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0Z2V0SW5kZXhTY2FsZUlkOiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB0aGlzLmdldE1ldGEoKS54QXhpc0lEO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdGdldFZhbHVlU2NhbGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZ2V0U2NhbGVGb3JJZCh0aGlzLmdldFZhbHVlU2NhbGVJZCgpKTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRnZXRJbmRleFNjYWxlOiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB0aGlzLmdldFNjYWxlRm9ySWQodGhpcy5nZXRJbmRleFNjYWxlSWQoKSk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFJldHVybnMgdGhlIHN0YWNrcyBiYXNlZCBvbiBncm91cHMgYW5kIGJhciB2aXNpYmlsaXR5LlxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfSBbbGFzdF0gLSBUaGUgZGF0YXNldCBpbmRleFxuXHRcdCAqIEByZXR1cm5zIHtBcnJheX0gVGhlIHN0YWNrIGxpc3Rcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdF9nZXRTdGFja3M6IGZ1bmN0aW9uKGxhc3QpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcblx0XHRcdHZhciBzY2FsZSA9IG1lLmdldEluZGV4U2NhbGUoKTtcblx0XHRcdHZhciBzdGFja2VkID0gc2NhbGUub3B0aW9ucy5zdGFja2VkO1xuXHRcdFx0dmFyIGlsZW4gPSBsYXN0ID09PSB1bmRlZmluZWQgPyBjaGFydC5kYXRhLmRhdGFzZXRzLmxlbmd0aCA6IGxhc3QgKyAxO1xuXHRcdFx0dmFyIHN0YWNrcyA9IFtdO1xuXHRcdFx0dmFyIGksIG1ldGE7XG5cblx0XHRcdGZvciAoaSA9IDA7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdFx0bWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGkpO1xuXHRcdFx0XHRpZiAobWV0YS5iYXIgJiYgY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShpKSAmJlxuXHRcdFx0XHRcdChzdGFja2VkID09PSBmYWxzZSB8fFxuXHRcdFx0XHRcdChzdGFja2VkID09PSB0cnVlICYmIHN0YWNrcy5pbmRleE9mKG1ldGEuc3RhY2spID09PSAtMSkgfHxcblx0XHRcdFx0XHQoc3RhY2tlZCA9PT0gdW5kZWZpbmVkICYmIChtZXRhLnN0YWNrID09PSB1bmRlZmluZWQgfHwgc3RhY2tzLmluZGV4T2YobWV0YS5zdGFjaykgPT09IC0xKSkpKSB7XG5cdFx0XHRcdFx0c3RhY2tzLnB1c2gobWV0YS5zdGFjayk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHN0YWNrcztcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogUmV0dXJucyB0aGUgZWZmZWN0aXZlIG51bWJlciBvZiBzdGFja3MgYmFzZWQgb24gZ3JvdXBzIGFuZCBiYXIgdmlzaWJpbGl0eS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdGdldFN0YWNrQ291bnQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHRoaXMuX2dldFN0YWNrcygpLmxlbmd0aDtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogUmV0dXJucyB0aGUgc3RhY2sgaW5kZXggZm9yIHRoZSBnaXZlbiBkYXRhc2V0IGJhc2VkIG9uIGdyb3VwcyBhbmQgYmFyIHZpc2liaWxpdHkuXG5cdFx0ICogQHBhcmFtIHtOdW1iZXJ9IFtkYXRhc2V0SW5kZXhdIC0gVGhlIGRhdGFzZXQgaW5kZXhcblx0XHQgKiBAcGFyYW0ge1N0cmluZ30gW25hbWVdIC0gVGhlIHN0YWNrIG5hbWUgdG8gZmluZFxuXHRcdCAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBzdGFjayBpbmRleFxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0Z2V0U3RhY2tJbmRleDogZnVuY3Rpb24oZGF0YXNldEluZGV4LCBuYW1lKSB7XG5cdFx0XHR2YXIgc3RhY2tzID0gdGhpcy5fZ2V0U3RhY2tzKGRhdGFzZXRJbmRleCk7XG5cdFx0XHR2YXIgaW5kZXggPSAobmFtZSAhPT0gdW5kZWZpbmVkKVxuXHRcdFx0XHQ/IHN0YWNrcy5pbmRleE9mKG5hbWUpXG5cdFx0XHRcdDogLTE7IC8vIGluZGV4T2YgcmV0dXJucyAtMSBpZiBlbGVtZW50IGlzIG5vdCBwcmVzZW50XG5cblx0XHRcdHJldHVybiAoaW5kZXggPT09IC0xKVxuXHRcdFx0XHQ/IHN0YWNrcy5sZW5ndGggLSAxXG5cdFx0XHRcdDogaW5kZXg7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0Z2V0UnVsZXI6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBzY2FsZSA9IG1lLmdldEluZGV4U2NhbGUoKTtcblx0XHRcdHZhciBzdGFja0NvdW50ID0gbWUuZ2V0U3RhY2tDb3VudCgpO1xuXHRcdFx0dmFyIGRhdGFzZXRJbmRleCA9IG1lLmluZGV4O1xuXHRcdFx0dmFyIGlzSG9yaXpvbnRhbCA9IHNjYWxlLmlzSG9yaXpvbnRhbCgpO1xuXHRcdFx0dmFyIHN0YXJ0ID0gaXNIb3Jpem9udGFsID8gc2NhbGUubGVmdCA6IHNjYWxlLnRvcDtcblx0XHRcdHZhciBlbmQgPSBzdGFydCArIChpc0hvcml6b250YWwgPyBzY2FsZS53aWR0aCA6IHNjYWxlLmhlaWdodCk7XG5cdFx0XHR2YXIgcGl4ZWxzID0gW107XG5cdFx0XHR2YXIgaSwgaWxlbiwgbWluO1xuXG5cdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0gbWUuZ2V0TWV0YSgpLmRhdGEubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG5cdFx0XHRcdHBpeGVscy5wdXNoKHNjYWxlLmdldFBpeGVsRm9yVmFsdWUobnVsbCwgaSwgZGF0YXNldEluZGV4KSk7XG5cdFx0XHR9XG5cblx0XHRcdG1pbiA9IGhlbHBlcnMuaXNOdWxsT3JVbmRlZihzY2FsZS5vcHRpb25zLmJhclRoaWNrbmVzcylcblx0XHRcdFx0PyBjb21wdXRlTWluU2FtcGxlU2l6ZShzY2FsZSwgcGl4ZWxzKVxuXHRcdFx0XHQ6IC0xO1xuXG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRtaW46IG1pbixcblx0XHRcdFx0cGl4ZWxzOiBwaXhlbHMsXG5cdFx0XHRcdHN0YXJ0OiBzdGFydCxcblx0XHRcdFx0ZW5kOiBlbmQsXG5cdFx0XHRcdHN0YWNrQ291bnQ6IHN0YWNrQ291bnQsXG5cdFx0XHRcdHNjYWxlOiBzY2FsZVxuXHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogTm90ZTogcGl4ZWwgdmFsdWVzIGFyZSBub3QgY2xhbXBlZCB0byB0aGUgc2NhbGUgYXJlYS5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdGNhbGN1bGF0ZUJhclZhbHVlUGl4ZWxzOiBmdW5jdGlvbihkYXRhc2V0SW5kZXgsIGluZGV4KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XG5cdFx0XHR2YXIgbWV0YSA9IG1lLmdldE1ldGEoKTtcblx0XHRcdHZhciBzY2FsZSA9IG1lLmdldFZhbHVlU2NhbGUoKTtcblx0XHRcdHZhciBkYXRhc2V0cyA9IGNoYXJ0LmRhdGEuZGF0YXNldHM7XG5cdFx0XHR2YXIgdmFsdWUgPSBzY2FsZS5nZXRSaWdodFZhbHVlKGRhdGFzZXRzW2RhdGFzZXRJbmRleF0uZGF0YVtpbmRleF0pO1xuXHRcdFx0dmFyIHN0YWNrZWQgPSBzY2FsZS5vcHRpb25zLnN0YWNrZWQ7XG5cdFx0XHR2YXIgc3RhY2sgPSBtZXRhLnN0YWNrO1xuXHRcdFx0dmFyIHN0YXJ0ID0gMDtcblx0XHRcdHZhciBpLCBpbWV0YSwgaXZhbHVlLCBiYXNlLCBoZWFkLCBzaXplO1xuXG5cdFx0XHRpZiAoc3RhY2tlZCB8fCAoc3RhY2tlZCA9PT0gdW5kZWZpbmVkICYmIHN0YWNrICE9PSB1bmRlZmluZWQpKSB7XG5cdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBkYXRhc2V0SW5kZXg7ICsraSkge1xuXHRcdFx0XHRcdGltZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoaSk7XG5cblx0XHRcdFx0XHRpZiAoaW1ldGEuYmFyICYmXG5cdFx0XHRcdFx0XHRpbWV0YS5zdGFjayA9PT0gc3RhY2sgJiZcblx0XHRcdFx0XHRcdGltZXRhLmNvbnRyb2xsZXIuZ2V0VmFsdWVTY2FsZUlkKCkgPT09IHNjYWxlLmlkICYmXG5cdFx0XHRcdFx0XHRjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGkpKSB7XG5cblx0XHRcdFx0XHRcdGl2YWx1ZSA9IHNjYWxlLmdldFJpZ2h0VmFsdWUoZGF0YXNldHNbaV0uZGF0YVtpbmRleF0pO1xuXHRcdFx0XHRcdFx0aWYgKCh2YWx1ZSA8IDAgJiYgaXZhbHVlIDwgMCkgfHwgKHZhbHVlID49IDAgJiYgaXZhbHVlID4gMCkpIHtcblx0XHRcdFx0XHRcdFx0c3RhcnQgKz0gaXZhbHVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRiYXNlID0gc2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShzdGFydCk7XG5cdFx0XHRoZWFkID0gc2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShzdGFydCArIHZhbHVlKTtcblx0XHRcdHNpemUgPSAoaGVhZCAtIGJhc2UpIC8gMjtcblxuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0c2l6ZTogc2l6ZSxcblx0XHRcdFx0YmFzZTogYmFzZSxcblx0XHRcdFx0aGVhZDogaGVhZCxcblx0XHRcdFx0Y2VudGVyOiBoZWFkICsgc2l6ZSAvIDJcblx0XHRcdH07XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0Y2FsY3VsYXRlQmFySW5kZXhQaXhlbHM6IGZ1bmN0aW9uKGRhdGFzZXRJbmRleCwgaW5kZXgsIHJ1bGVyKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG9wdGlvbnMgPSBydWxlci5zY2FsZS5vcHRpb25zO1xuXHRcdFx0dmFyIHJhbmdlID0gb3B0aW9ucy5iYXJUaGlja25lc3MgPT09ICdmbGV4J1xuXHRcdFx0XHQ/IGNvbXB1dGVGbGV4Q2F0ZWdvcnlUcmFpdHMoaW5kZXgsIHJ1bGVyLCBvcHRpb25zKVxuXHRcdFx0XHQ6IGNvbXB1dGVGaXRDYXRlZ29yeVRyYWl0cyhpbmRleCwgcnVsZXIsIG9wdGlvbnMpO1xuXG5cdFx0XHR2YXIgc3RhY2tJbmRleCA9IG1lLmdldFN0YWNrSW5kZXgoZGF0YXNldEluZGV4LCBtZS5nZXRNZXRhKCkuc3RhY2spO1xuXHRcdFx0dmFyIGNlbnRlciA9IHJhbmdlLnN0YXJ0ICsgKHJhbmdlLmNodW5rICogc3RhY2tJbmRleCkgKyAocmFuZ2UuY2h1bmsgLyAyKTtcblx0XHRcdHZhciBzaXplID0gTWF0aC5taW4oXG5cdFx0XHRcdGhlbHBlcnMudmFsdWVPckRlZmF1bHQob3B0aW9ucy5tYXhCYXJUaGlja25lc3MsIEluZmluaXR5KSxcblx0XHRcdFx0cmFuZ2UuY2h1bmsgKiByYW5nZS5yYXRpbyk7XG5cblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdGJhc2U6IGNlbnRlciAtIHNpemUgLyAyLFxuXHRcdFx0XHRoZWFkOiBjZW50ZXIgKyBzaXplIC8gMixcblx0XHRcdFx0Y2VudGVyOiBjZW50ZXIsXG5cdFx0XHRcdHNpemU6IHNpemVcblx0XHRcdH07XG5cdFx0fSxcblxuXHRcdGRyYXc6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBjaGFydCA9IG1lLmNoYXJ0O1xuXHRcdFx0dmFyIHNjYWxlID0gbWUuZ2V0VmFsdWVTY2FsZSgpO1xuXHRcdFx0dmFyIHJlY3RzID0gbWUuZ2V0TWV0YSgpLmRhdGE7XG5cdFx0XHR2YXIgZGF0YXNldCA9IG1lLmdldERhdGFzZXQoKTtcblx0XHRcdHZhciBpbGVuID0gcmVjdHMubGVuZ3RoO1xuXHRcdFx0dmFyIGkgPSAwO1xuXG5cdFx0XHRoZWxwZXJzLmNhbnZhcy5jbGlwQXJlYShjaGFydC5jdHgsIGNoYXJ0LmNoYXJ0QXJlYSk7XG5cblx0XHRcdGZvciAoOyBpIDwgaWxlbjsgKytpKSB7XG5cdFx0XHRcdGlmICghaXNOYU4oc2NhbGUuZ2V0UmlnaHRWYWx1ZShkYXRhc2V0LmRhdGFbaV0pKSkge1xuXHRcdFx0XHRcdHJlY3RzW2ldLmRyYXcoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRoZWxwZXJzLmNhbnZhcy51bmNsaXBBcmVhKGNoYXJ0LmN0eCk7XG5cdFx0fSxcblx0fSk7XG5cblx0Q2hhcnQuY29udHJvbGxlcnMuaG9yaXpvbnRhbEJhciA9IENoYXJ0LmNvbnRyb2xsZXJzLmJhci5leHRlbmQoe1xuXHRcdC8qKlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0Z2V0VmFsdWVTY2FsZUlkOiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB0aGlzLmdldE1ldGEoKS54QXhpc0lEO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdGdldEluZGV4U2NhbGVJZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5nZXRNZXRhKCkueUF4aXNJRDtcblx0XHR9XG5cdH0pO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2bea\n")},"2e15":function(module,exports,__webpack_require__){"use strict";eval('\n\nvar helpers = __webpack_require__(/*! ../helpers/index */ "66c8");\nvar Scale = __webpack_require__(/*! ../core/core.scale */ "d1b4");\n\n/**\n * Generate a set of linear ticks\n * @param generationOptions the options used to generate the ticks\n * @param dataRange the range of the data\n * @returns {Array<Number>} array of tick values\n */\nfunction generateTicks(generationOptions, dataRange) {\n\tvar ticks = [];\n\t// To get a "nice" value for the tick spacing, we will use the appropriately named\n\t// "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks\n\t// for details.\n\n\tvar factor;\n\tvar precision;\n\tvar spacing;\n\n\tif (generationOptions.stepSize && generationOptions.stepSize > 0) {\n\t\tspacing = generationOptions.stepSize;\n\t} else {\n\t\tvar niceRange = helpers.niceNum(dataRange.max - dataRange.min, false);\n\t\tspacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true);\n\n\t\tprecision = generationOptions.precision;\n\t\tif (precision !== undefined) {\n\t\t\t// If the user specified a precision, round to that number of decimal places\n\t\t\tfactor = Math.pow(10, precision);\n\t\t\tspacing = Math.ceil(spacing * factor) / factor;\n\t\t}\n\t}\n\tvar niceMin = Math.floor(dataRange.min / spacing) * spacing;\n\tvar niceMax = Math.ceil(dataRange.max / spacing) * spacing;\n\n\t// If min, max and stepSize is set and they make an evenly spaced scale use it.\n\tif (!helpers.isNullOrUndef(generationOptions.min) && !helpers.isNullOrUndef(generationOptions.max) && generationOptions.stepSize) {\n\t\t// If very close to our whole number, use it.\n\t\tif (helpers.almostWhole((generationOptions.max - generationOptions.min) / generationOptions.stepSize, spacing / 1000)) {\n\t\t\tniceMin = generationOptions.min;\n\t\t\tniceMax = generationOptions.max;\n\t\t}\n\t}\n\n\tvar numSpaces = (niceMax - niceMin) / spacing;\n\t// If very close to our rounded value, use it.\n\tif (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {\n\t\tnumSpaces = Math.round(numSpaces);\n\t} else {\n\t\tnumSpaces = Math.ceil(numSpaces);\n\t}\n\n\tprecision = 1;\n\tif (spacing < 1) {\n\t\tprecision = Math.pow(10, 1 - Math.floor(helpers.log10(spacing)));\n\t\tniceMin = Math.round(niceMin * precision) / precision;\n\t\tniceMax = Math.round(niceMax * precision) / precision;\n\t}\n\tticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin);\n\tfor (var j = 1; j < numSpaces; ++j) {\n\t\tticks.push(Math.round((niceMin + j * spacing) * precision) / precision);\n\t}\n\tticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax);\n\n\treturn ticks;\n}\n\nmodule.exports = function(Chart) {\n\n\tvar noop = helpers.noop;\n\n\tChart.LinearScaleBase = Scale.extend({\n\t\tgetRightValue: function(value) {\n\t\t\tif (typeof value === \'string\') {\n\t\t\t\treturn +value;\n\t\t\t}\n\t\t\treturn Scale.prototype.getRightValue.call(this, value);\n\t\t},\n\n\t\thandleTickRangeOptions: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\t// If we are forcing it to begin at 0, but 0 will already be rendered on the chart,\n\t\t\t// do nothing since that would make the chart weird. If the user really wants a weird chart\n\t\t\t// axis, they can manually override it\n\t\t\tif (tickOpts.beginAtZero) {\n\t\t\t\tvar minSign = helpers.sign(me.min);\n\t\t\t\tvar maxSign = helpers.sign(me.max);\n\n\t\t\t\tif (minSign < 0 && maxSign < 0) {\n\t\t\t\t\t// move the top up to 0\n\t\t\t\t\tme.max = 0;\n\t\t\t\t} else if (minSign > 0 && maxSign > 0) {\n\t\t\t\t\t// move the bottom down to 0\n\t\t\t\t\tme.min = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar setMin = tickOpts.min !== undefined || tickOpts.suggestedMin !== undefined;\n\t\t\tvar setMax = tickOpts.max !== undefined || tickOpts.suggestedMax !== undefined;\n\n\t\t\tif (tickOpts.min !== undefined) {\n\t\t\t\tme.min = tickOpts.min;\n\t\t\t} else if (tickOpts.suggestedMin !== undefined) {\n\t\t\t\tif (me.min === null) {\n\t\t\t\t\tme.min = tickOpts.suggestedMin;\n\t\t\t\t} else {\n\t\t\t\t\tme.min = Math.min(me.min, tickOpts.suggestedMin);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (tickOpts.max !== undefined) {\n\t\t\t\tme.max = tickOpts.max;\n\t\t\t} else if (tickOpts.suggestedMax !== undefined) {\n\t\t\t\tif (me.max === null) {\n\t\t\t\t\tme.max = tickOpts.suggestedMax;\n\t\t\t\t} else {\n\t\t\t\t\tme.max = Math.max(me.max, tickOpts.suggestedMax);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (setMin !== setMax) {\n\t\t\t\t// We set the min or the max but not both.\n\t\t\t\t// So ensure that our range is good\n\t\t\t\t// Inverted or 0 length range can happen when\n\t\t\t\t// ticks.min is set, and no datasets are visible\n\t\t\t\tif (me.min >= me.max) {\n\t\t\t\t\tif (setMin) {\n\t\t\t\t\t\tme.max = me.min + 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tme.min = me.max - 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (me.min === me.max) {\n\t\t\t\tme.max++;\n\n\t\t\t\tif (!tickOpts.beginAtZero) {\n\t\t\t\t\tme.min--;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tgetTickLimit: noop,\n\t\thandleDirectionalChanges: noop,\n\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\n\t\t\t// Figure out what the max number of ticks we can support it is based on the size of\n\t\t\t// the axis area. For now, we say that the minimum tick spacing in pixels must be 50\n\t\t\t// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\n\t\t\t// the graph. Make sure we always have at least 2 ticks\n\t\t\tvar maxTicks = me.getTickLimit();\n\t\t\tmaxTicks = Math.max(2, maxTicks);\n\n\t\t\tvar numericGeneratorOptions = {\n\t\t\t\tmaxTicks: maxTicks,\n\t\t\t\tmin: tickOpts.min,\n\t\t\t\tmax: tickOpts.max,\n\t\t\t\tprecision: tickOpts.precision,\n\t\t\t\tstepSize: helpers.valueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize)\n\t\t\t};\n\t\t\tvar ticks = me.ticks = generateTicks(numericGeneratorOptions, me);\n\n\t\t\tme.handleDirectionalChanges();\n\n\t\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\n\t\t\t// range of the scale\n\t\t\tme.max = helpers.max(ticks);\n\t\t\tme.min = helpers.min(ticks);\n\n\t\t\tif (tickOpts.reverse) {\n\t\t\t\tticks.reverse();\n\n\t\t\t\tme.start = me.max;\n\t\t\t\tme.end = me.min;\n\t\t\t} else {\n\t\t\t\tme.start = me.min;\n\t\t\t\tme.end = me.max;\n\t\t\t}\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\t\t\tme.ticksAsNumbers = me.ticks.slice();\n\t\t\tme.zeroLineIndex = me.ticks.indexOf(0);\n\n\t\t\tScale.prototype.convertTicksToLabels.call(me);\n\t\t}\n\t});\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMmUxNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvc2NhbGVzL3NjYWxlLmxpbmVhcmJhc2UuanM/YTVhMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xudmFyIFNjYWxlID0gcmVxdWlyZSgnLi4vY29yZS9jb3JlLnNjYWxlJyk7XG5cbi8qKlxuICogR2VuZXJhdGUgYSBzZXQgb2YgbGluZWFyIHRpY2tzXG4gKiBAcGFyYW0gZ2VuZXJhdGlvbk9wdGlvbnMgdGhlIG9wdGlvbnMgdXNlZCB0byBnZW5lcmF0ZSB0aGUgdGlja3NcbiAqIEBwYXJhbSBkYXRhUmFuZ2UgdGhlIHJhbmdlIG9mIHRoZSBkYXRhXG4gKiBAcmV0dXJucyB7QXJyYXk8TnVtYmVyPn0gYXJyYXkgb2YgdGljayB2YWx1ZXNcbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVUaWNrcyhnZW5lcmF0aW9uT3B0aW9ucywgZGF0YVJhbmdlKSB7XG5cdHZhciB0aWNrcyA9IFtdO1xuXHQvLyBUbyBnZXQgYSBcIm5pY2VcIiB2YWx1ZSBmb3IgdGhlIHRpY2sgc3BhY2luZywgd2Ugd2lsbCB1c2UgdGhlIGFwcHJvcHJpYXRlbHkgbmFtZWRcblx0Ly8gXCJuaWNlIG51bWJlclwiIGFsZ29yaXRobS4gU2VlIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvODUwNjg4MS9uaWNlLWxhYmVsLWFsZ29yaXRobS1mb3ItY2hhcnRzLXdpdGgtbWluaW11bS10aWNrc1xuXHQvLyBmb3IgZGV0YWlscy5cblxuXHR2YXIgZmFjdG9yO1xuXHR2YXIgcHJlY2lzaW9uO1xuXHR2YXIgc3BhY2luZztcblxuXHRpZiAoZ2VuZXJhdGlvbk9wdGlvbnMuc3RlcFNpemUgJiYgZ2VuZXJhdGlvbk9wdGlvbnMuc3RlcFNpemUgPiAwKSB7XG5cdFx0c3BhY2luZyA9IGdlbmVyYXRpb25PcHRpb25zLnN0ZXBTaXplO1xuXHR9IGVsc2Uge1xuXHRcdHZhciBuaWNlUmFuZ2UgPSBoZWxwZXJzLm5pY2VOdW0oZGF0YVJhbmdlLm1heCAtIGRhdGFSYW5nZS5taW4sIGZhbHNlKTtcblx0XHRzcGFjaW5nID0gaGVscGVycy5uaWNlTnVtKG5pY2VSYW5nZSAvIChnZW5lcmF0aW9uT3B0aW9ucy5tYXhUaWNrcyAtIDEpLCB0cnVlKTtcblxuXHRcdHByZWNpc2lvbiA9IGdlbmVyYXRpb25PcHRpb25zLnByZWNpc2lvbjtcblx0XHRpZiAocHJlY2lzaW9uICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdC8vIElmIHRoZSB1c2VyIHNwZWNpZmllZCBhIHByZWNpc2lvbiwgcm91bmQgdG8gdGhhdCBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXNcblx0XHRcdGZhY3RvciA9IE1hdGgucG93KDEwLCBwcmVjaXNpb24pO1xuXHRcdFx0c3BhY2luZyA9IE1hdGguY2VpbChzcGFjaW5nICogZmFjdG9yKSAvIGZhY3Rvcjtcblx0XHR9XG5cdH1cblx0dmFyIG5pY2VNaW4gPSBNYXRoLmZsb29yKGRhdGFSYW5nZS5taW4gLyBzcGFjaW5nKSAqIHNwYWNpbmc7XG5cdHZhciBuaWNlTWF4ID0gTWF0aC5jZWlsKGRhdGFSYW5nZS5tYXggLyBzcGFjaW5nKSAqIHNwYWNpbmc7XG5cblx0Ly8gSWYgbWluLCBtYXggYW5kIHN0ZXBTaXplIGlzIHNldCBhbmQgdGhleSBtYWtlIGFuIGV2ZW5seSBzcGFjZWQgc2NhbGUgdXNlIGl0LlxuXHRpZiAoIWhlbHBlcnMuaXNOdWxsT3JVbmRlZihnZW5lcmF0aW9uT3B0aW9ucy5taW4pICYmICFoZWxwZXJzLmlzTnVsbE9yVW5kZWYoZ2VuZXJhdGlvbk9wdGlvbnMubWF4KSAmJiBnZW5lcmF0aW9uT3B0aW9ucy5zdGVwU2l6ZSkge1xuXHRcdC8vIElmIHZlcnkgY2xvc2UgdG8gb3VyIHdob2xlIG51bWJlciwgdXNlIGl0LlxuXHRcdGlmIChoZWxwZXJzLmFsbW9zdFdob2xlKChnZW5lcmF0aW9uT3B0aW9ucy5tYXggLSBnZW5lcmF0aW9uT3B0aW9ucy5taW4pIC8gZ2VuZXJhdGlvbk9wdGlvbnMuc3RlcFNpemUsIHNwYWNpbmcgLyAxMDAwKSkge1xuXHRcdFx0bmljZU1pbiA9IGdlbmVyYXRpb25PcHRpb25zLm1pbjtcblx0XHRcdG5pY2VNYXggPSBnZW5lcmF0aW9uT3B0aW9ucy5tYXg7XG5cdFx0fVxuXHR9XG5cblx0dmFyIG51bVNwYWNlcyA9IChuaWNlTWF4IC0gbmljZU1pbikgLyBzcGFjaW5nO1xuXHQvLyBJZiB2ZXJ5IGNsb3NlIHRvIG91ciByb3VuZGVkIHZhbHVlLCB1c2UgaXQuXG5cdGlmIChoZWxwZXJzLmFsbW9zdEVxdWFscyhudW1TcGFjZXMsIE1hdGgucm91bmQobnVtU3BhY2VzKSwgc3BhY2luZyAvIDEwMDApKSB7XG5cdFx0bnVtU3BhY2VzID0gTWF0aC5yb3VuZChudW1TcGFjZXMpO1xuXHR9IGVsc2Uge1xuXHRcdG51bVNwYWNlcyA9IE1hdGguY2VpbChudW1TcGFjZXMpO1xuXHR9XG5cblx0cHJlY2lzaW9uID0gMTtcblx0aWYgKHNwYWNpbmcgPCAxKSB7XG5cdFx0cHJlY2lzaW9uID0gTWF0aC5wb3coMTAsIDEgLSBNYXRoLmZsb29yKGhlbHBlcnMubG9nMTAoc3BhY2luZykpKTtcblx0XHRuaWNlTWluID0gTWF0aC5yb3VuZChuaWNlTWluICogcHJlY2lzaW9uKSAvIHByZWNpc2lvbjtcblx0XHRuaWNlTWF4ID0gTWF0aC5yb3VuZChuaWNlTWF4ICogcHJlY2lzaW9uKSAvIHByZWNpc2lvbjtcblx0fVxuXHR0aWNrcy5wdXNoKGdlbmVyYXRpb25PcHRpb25zLm1pbiAhPT0gdW5kZWZpbmVkID8gZ2VuZXJhdGlvbk9wdGlvbnMubWluIDogbmljZU1pbik7XG5cdGZvciAodmFyIGogPSAxOyBqIDwgbnVtU3BhY2VzOyArK2opIHtcblx0XHR0aWNrcy5wdXNoKE1hdGgucm91bmQoKG5pY2VNaW4gKyBqICogc3BhY2luZykgKiBwcmVjaXNpb24pIC8gcHJlY2lzaW9uKTtcblx0fVxuXHR0aWNrcy5wdXNoKGdlbmVyYXRpb25PcHRpb25zLm1heCAhPT0gdW5kZWZpbmVkID8gZ2VuZXJhdGlvbk9wdGlvbnMubWF4IDogbmljZU1heCk7XG5cblx0cmV0dXJuIHRpY2tzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKENoYXJ0KSB7XG5cblx0dmFyIG5vb3AgPSBoZWxwZXJzLm5vb3A7XG5cblx0Q2hhcnQuTGluZWFyU2NhbGVCYXNlID0gU2NhbGUuZXh0ZW5kKHtcblx0XHRnZXRSaWdodFZhbHVlOiBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0XHRcdFx0cmV0dXJuICt2YWx1ZTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBTY2FsZS5wcm90b3R5cGUuZ2V0UmlnaHRWYWx1ZS5jYWxsKHRoaXMsIHZhbHVlKTtcblx0XHR9LFxuXG5cdFx0aGFuZGxlVGlja1JhbmdlT3B0aW9uczogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG9wdHMgPSBtZS5vcHRpb25zO1xuXHRcdFx0dmFyIHRpY2tPcHRzID0gb3B0cy50aWNrcztcblxuXHRcdFx0Ly8gSWYgd2UgYXJlIGZvcmNpbmcgaXQgdG8gYmVnaW4gYXQgMCwgYnV0IDAgd2lsbCBhbHJlYWR5IGJlIHJlbmRlcmVkIG9uIHRoZSBjaGFydCxcblx0XHRcdC8vIGRvIG5vdGhpbmcgc2luY2UgdGhhdCB3b3VsZCBtYWtlIHRoZSBjaGFydCB3ZWlyZC4gSWYgdGhlIHVzZXIgcmVhbGx5IHdhbnRzIGEgd2VpcmQgY2hhcnRcblx0XHRcdC8vIGF4aXMsIHRoZXkgY2FuIG1hbnVhbGx5IG92ZXJyaWRlIGl0XG5cdFx0XHRpZiAodGlja09wdHMuYmVnaW5BdFplcm8pIHtcblx0XHRcdFx0dmFyIG1pblNpZ24gPSBoZWxwZXJzLnNpZ24obWUubWluKTtcblx0XHRcdFx0dmFyIG1heFNpZ24gPSBoZWxwZXJzLnNpZ24obWUubWF4KTtcblxuXHRcdFx0XHRpZiAobWluU2lnbiA8IDAgJiYgbWF4U2lnbiA8IDApIHtcblx0XHRcdFx0XHQvLyBtb3ZlIHRoZSB0b3AgdXAgdG8gMFxuXHRcdFx0XHRcdG1lLm1heCA9IDA7XG5cdFx0XHRcdH0gZWxzZSBpZiAobWluU2lnbiA+IDAgJiYgbWF4U2lnbiA+IDApIHtcblx0XHRcdFx0XHQvLyBtb3ZlIHRoZSBib3R0b20gZG93biB0byAwXG5cdFx0XHRcdFx0bWUubWluID0gMDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHR2YXIgc2V0TWluID0gdGlja09wdHMubWluICE9PSB1bmRlZmluZWQgfHwgdGlja09wdHMuc3VnZ2VzdGVkTWluICE9PSB1bmRlZmluZWQ7XG5cdFx0XHR2YXIgc2V0TWF4ID0gdGlja09wdHMubWF4ICE9PSB1bmRlZmluZWQgfHwgdGlja09wdHMuc3VnZ2VzdGVkTWF4ICE9PSB1bmRlZmluZWQ7XG5cblx0XHRcdGlmICh0aWNrT3B0cy5taW4gIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRtZS5taW4gPSB0aWNrT3B0cy5taW47XG5cdFx0XHR9IGVsc2UgaWYgKHRpY2tPcHRzLnN1Z2dlc3RlZE1pbiAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdGlmIChtZS5taW4gPT09IG51bGwpIHtcblx0XHRcdFx0XHRtZS5taW4gPSB0aWNrT3B0cy5zdWdnZXN0ZWRNaW47XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bWUubWluID0gTWF0aC5taW4obWUubWluLCB0aWNrT3B0cy5zdWdnZXN0ZWRNaW4pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aWNrT3B0cy5tYXggIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRtZS5tYXggPSB0aWNrT3B0cy5tYXg7XG5cdFx0XHR9IGVsc2UgaWYgKHRpY2tPcHRzLnN1Z2dlc3RlZE1heCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdGlmIChtZS5tYXggPT09IG51bGwpIHtcblx0XHRcdFx0XHRtZS5tYXggPSB0aWNrT3B0cy5zdWdnZXN0ZWRNYXg7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bWUubWF4ID0gTWF0aC5tYXgobWUubWF4LCB0aWNrT3B0cy5zdWdnZXN0ZWRNYXgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmIChzZXRNaW4gIT09IHNldE1heCkge1xuXHRcdFx0XHQvLyBXZSBzZXQgdGhlIG1pbiBvciB0aGUgbWF4IGJ1dCBub3QgYm90aC5cblx0XHRcdFx0Ly8gU28gZW5zdXJlIHRoYXQgb3VyIHJhbmdlIGlzIGdvb2Rcblx0XHRcdFx0Ly8gSW52ZXJ0ZWQgb3IgMCBsZW5ndGggcmFuZ2UgY2FuIGhhcHBlbiB3aGVuXG5cdFx0XHRcdC8vIHRpY2tzLm1pbiBpcyBzZXQsIGFuZCBubyBkYXRhc2V0cyBhcmUgdmlzaWJsZVxuXHRcdFx0XHRpZiAobWUubWluID49IG1lLm1heCkge1xuXHRcdFx0XHRcdGlmIChzZXRNaW4pIHtcblx0XHRcdFx0XHRcdG1lLm1heCA9IG1lLm1pbiArIDE7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdG1lLm1pbiA9IG1lLm1heCAtIDE7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmIChtZS5taW4gPT09IG1lLm1heCkge1xuXHRcdFx0XHRtZS5tYXgrKztcblxuXHRcdFx0XHRpZiAoIXRpY2tPcHRzLmJlZ2luQXRaZXJvKSB7XG5cdFx0XHRcdFx0bWUubWluLS07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXHRcdGdldFRpY2tMaW1pdDogbm9vcCxcblx0XHRoYW5kbGVEaXJlY3Rpb25hbENoYW5nZXM6IG5vb3AsXG5cblx0XHRidWlsZFRpY2tzOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgb3B0cyA9IG1lLm9wdGlvbnM7XG5cdFx0XHR2YXIgdGlja09wdHMgPSBvcHRzLnRpY2tzO1xuXG5cdFx0XHQvLyBGaWd1cmUgb3V0IHdoYXQgdGhlIG1heCBudW1iZXIgb2YgdGlja3Mgd2UgY2FuIHN1cHBvcnQgaXQgaXMgYmFzZWQgb24gdGhlIHNpemUgb2Zcblx0XHRcdC8vIHRoZSBheGlzIGFyZWEuIEZvciBub3csIHdlIHNheSB0aGF0IHRoZSBtaW5pbXVtIHRpY2sgc3BhY2luZyBpbiBwaXhlbHMgbXVzdCBiZSA1MFxuXHRcdFx0Ly8gV2UgYWxzbyBsaW1pdCB0aGUgbWF4aW11bSBudW1iZXIgb2YgdGlja3MgdG8gMTEgd2hpY2ggZ2l2ZXMgYSBuaWNlIDEwIHNxdWFyZXMgb25cblx0XHRcdC8vIHRoZSBncmFwaC4gTWFrZSBzdXJlIHdlIGFsd2F5cyBoYXZlIGF0IGxlYXN0IDIgdGlja3Ncblx0XHRcdHZhciBtYXhUaWNrcyA9IG1lLmdldFRpY2tMaW1pdCgpO1xuXHRcdFx0bWF4VGlja3MgPSBNYXRoLm1heCgyLCBtYXhUaWNrcyk7XG5cblx0XHRcdHZhciBudW1lcmljR2VuZXJhdG9yT3B0aW9ucyA9IHtcblx0XHRcdFx0bWF4VGlja3M6IG1heFRpY2tzLFxuXHRcdFx0XHRtaW46IHRpY2tPcHRzLm1pbixcblx0XHRcdFx0bWF4OiB0aWNrT3B0cy5tYXgsXG5cdFx0XHRcdHByZWNpc2lvbjogdGlja09wdHMucHJlY2lzaW9uLFxuXHRcdFx0XHRzdGVwU2l6ZTogaGVscGVycy52YWx1ZU9yRGVmYXVsdCh0aWNrT3B0cy5maXhlZFN0ZXBTaXplLCB0aWNrT3B0cy5zdGVwU2l6ZSlcblx0XHRcdH07XG5cdFx0XHR2YXIgdGlja3MgPSBtZS50aWNrcyA9IGdlbmVyYXRlVGlja3MobnVtZXJpY0dlbmVyYXRvck9wdGlvbnMsIG1lKTtcblxuXHRcdFx0bWUuaGFuZGxlRGlyZWN0aW9uYWxDaGFuZ2VzKCk7XG5cblx0XHRcdC8vIEF0IHRoaXMgcG9pbnQsIHdlIG5lZWQgdG8gdXBkYXRlIG91ciBtYXggYW5kIG1pbiBnaXZlbiB0aGUgdGljayB2YWx1ZXMgc2luY2Ugd2UgaGF2ZSBleHBhbmRlZCB0aGVcblx0XHRcdC8vIHJhbmdlIG9mIHRoZSBzY2FsZVxuXHRcdFx0bWUubWF4ID0gaGVscGVycy5tYXgodGlja3MpO1xuXHRcdFx0bWUubWluID0gaGVscGVycy5taW4odGlja3MpO1xuXG5cdFx0XHRpZiAodGlja09wdHMucmV2ZXJzZSkge1xuXHRcdFx0XHR0aWNrcy5yZXZlcnNlKCk7XG5cblx0XHRcdFx0bWUuc3RhcnQgPSBtZS5tYXg7XG5cdFx0XHRcdG1lLmVuZCA9IG1lLm1pbjtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG1lLnN0YXJ0ID0gbWUubWluO1xuXHRcdFx0XHRtZS5lbmQgPSBtZS5tYXg7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRjb252ZXJ0VGlja3NUb0xhYmVsczogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0bWUudGlja3NBc051bWJlcnMgPSBtZS50aWNrcy5zbGljZSgpO1xuXHRcdFx0bWUuemVyb0xpbmVJbmRleCA9IG1lLnRpY2tzLmluZGV4T2YoMCk7XG5cblx0XHRcdFNjYWxlLnByb3RvdHlwZS5jb252ZXJ0VGlja3NUb0xhYmVscy5jYWxsKG1lKTtcblx0XHR9XG5cdH0pO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2e15\n')},"314a":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\n\ndefaults._set('scatter', {\n\thover: {\n\t\tmode: 'single'\n\t},\n\n\tscales: {\n\t\txAxes: [{\n\t\t\tid: 'x-axis-1',    // need an ID so datasets can reference the scale\n\t\t\ttype: 'linear',    // scatter should not use a category axis\n\t\t\tposition: 'bottom'\n\t\t}],\n\t\tyAxes: [{\n\t\t\tid: 'y-axis-1',\n\t\t\ttype: 'linear',\n\t\t\tposition: 'left'\n\t\t}]\n\t},\n\n\tshowLines: false,\n\n\ttooltips: {\n\t\tcallbacks: {\n\t\t\ttitle: function() {\n\t\t\t\treturn '';     // doesn't make sense for scatter since data are formatted as a point\n\t\t\t},\n\t\t\tlabel: function(item) {\n\t\t\t\treturn '(' + item.xLabel + ', ' + item.yLabel + ')';\n\t\t\t}\n\t\t}\n\t}\n});\n\nmodule.exports = function(Chart) {\n\n\t// Scatter charts use line controllers\n\tChart.controllers.scatter = Chart.controllers.line;\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzE0YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5zY2F0dGVyLmpzP2RmOWMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuZGVmYXVsdHMnKTtcblxuZGVmYXVsdHMuX3NldCgnc2NhdHRlcicsIHtcblx0aG92ZXI6IHtcblx0XHRtb2RlOiAnc2luZ2xlJ1xuXHR9LFxuXG5cdHNjYWxlczoge1xuXHRcdHhBeGVzOiBbe1xuXHRcdFx0aWQ6ICd4LWF4aXMtMScsICAgIC8vIG5lZWQgYW4gSUQgc28gZGF0YXNldHMgY2FuIHJlZmVyZW5jZSB0aGUgc2NhbGVcblx0XHRcdHR5cGU6ICdsaW5lYXInLCAgICAvLyBzY2F0dGVyIHNob3VsZCBub3QgdXNlIGEgY2F0ZWdvcnkgYXhpc1xuXHRcdFx0cG9zaXRpb246ICdib3R0b20nXG5cdFx0fV0sXG5cdFx0eUF4ZXM6IFt7XG5cdFx0XHRpZDogJ3ktYXhpcy0xJyxcblx0XHRcdHR5cGU6ICdsaW5lYXInLFxuXHRcdFx0cG9zaXRpb246ICdsZWZ0J1xuXHRcdH1dXG5cdH0sXG5cblx0c2hvd0xpbmVzOiBmYWxzZSxcblxuXHR0b29sdGlwczoge1xuXHRcdGNhbGxiYWNrczoge1xuXHRcdFx0dGl0bGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gJyc7ICAgICAvLyBkb2Vzbid0IG1ha2Ugc2Vuc2UgZm9yIHNjYXR0ZXIgc2luY2UgZGF0YSBhcmUgZm9ybWF0dGVkIGFzIGEgcG9pbnRcblx0XHRcdH0sXG5cdFx0XHRsYWJlbDogZnVuY3Rpb24oaXRlbSkge1xuXHRcdFx0XHRyZXR1cm4gJygnICsgaXRlbS54TGFiZWwgKyAnLCAnICsgaXRlbS55TGFiZWwgKyAnKSc7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDaGFydCkge1xuXG5cdC8vIFNjYXR0ZXIgY2hhcnRzIHVzZSBsaW5lIGNvbnRyb2xsZXJzXG5cdENoYXJ0LmNvbnRyb2xsZXJzLnNjYXR0ZXIgPSBDaGFydC5jb250cm9sbGVycy5saW5lO1xuXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///314a\n")},"318e":function(module,exports){eval("/**\n * Platform fallback implementation (minimal).\n * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939\n */\n\nmodule.exports = {\n\tacquireContext: function(item) {\n\t\tif (item && item.canvas) {\n\t\t\t// Support for any object associated to a canvas (including a context2d)\n\t\t\titem = item.canvas;\n\t\t}\n\n\t\treturn item && item.getContext('2d') || null;\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzE4ZS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGxhdGZvcm1zL3BsYXRmb3JtLmJhc2ljLmpzPzFlMGUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQbGF0Zm9ybSBmYWxsYmFjayBpbXBsZW1lbnRhdGlvbiAobWluaW1hbCkuXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL3B1bGwvNDU5MSNpc3N1ZWNvbW1lbnQtMzE5NTc1OTM5XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdGFjcXVpcmVDb250ZXh0OiBmdW5jdGlvbihpdGVtKSB7XG5cdFx0aWYgKGl0ZW0gJiYgaXRlbS5jYW52YXMpIHtcblx0XHRcdC8vIFN1cHBvcnQgZm9yIGFueSBvYmplY3QgYXNzb2NpYXRlZCB0byBhIGNhbnZhcyAoaW5jbHVkaW5nIGEgY29udGV4dDJkKVxuXHRcdFx0aXRlbSA9IGl0ZW0uY2FudmFzO1xuXHRcdH1cblxuXHRcdHJldHVybiBpdGVtICYmIGl0ZW0uZ2V0Q29udGV4dCgnMmQnKSB8fCBudWxsO1xuXHR9XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///318e\n")},"4a45":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar color = __webpack_require__(/*! chartjs-color */ \"f02b\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\nfunction interpolate(start, view, model, ease) {\n\tvar keys = Object.keys(model);\n\tvar i, ilen, key, actual, origin, target, type, c0, c1;\n\n\tfor (i = 0, ilen = keys.length; i < ilen; ++i) {\n\t\tkey = keys[i];\n\n\t\ttarget = model[key];\n\n\t\t// if a value is added to the model after pivot() has been called, the view\n\t\t// doesn't contain it, so let's initialize the view to the target value.\n\t\tif (!view.hasOwnProperty(key)) {\n\t\t\tview[key] = target;\n\t\t}\n\n\t\tactual = view[key];\n\n\t\tif (actual === target || key[0] === '_') {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!start.hasOwnProperty(key)) {\n\t\t\tstart[key] = actual;\n\t\t}\n\n\t\torigin = start[key];\n\n\t\ttype = typeof target;\n\n\t\tif (type === typeof origin) {\n\t\t\tif (type === 'string') {\n\t\t\t\tc0 = color(origin);\n\t\t\t\tif (c0.valid) {\n\t\t\t\t\tc1 = color(target);\n\t\t\t\t\tif (c1.valid) {\n\t\t\t\t\t\tview[key] = c1.mix(c0, ease).rgbString();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (type === 'number' && isFinite(origin) && isFinite(target)) {\n\t\t\t\tview[key] = origin + (target - origin) * ease;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tview[key] = target;\n\t}\n}\n\nvar Element = function(configuration) {\n\thelpers.extend(this, configuration);\n\tthis.initialize.apply(this, arguments);\n};\n\nhelpers.extend(Element.prototype, {\n\n\tinitialize: function() {\n\t\tthis.hidden = false;\n\t},\n\n\tpivot: function() {\n\t\tvar me = this;\n\t\tif (!me._view) {\n\t\t\tme._view = helpers.clone(me._model);\n\t\t}\n\t\tme._start = {};\n\t\treturn me;\n\t},\n\n\ttransition: function(ease) {\n\t\tvar me = this;\n\t\tvar model = me._model;\n\t\tvar start = me._start;\n\t\tvar view = me._view;\n\n\t\t// No animation -> No Transition\n\t\tif (!model || ease === 1) {\n\t\t\tme._view = model;\n\t\t\tme._start = null;\n\t\t\treturn me;\n\t\t}\n\n\t\tif (!view) {\n\t\t\tview = me._view = {};\n\t\t}\n\n\t\tif (!start) {\n\t\t\tstart = me._start = {};\n\t\t}\n\n\t\tinterpolate(start, view, model, ease);\n\n\t\treturn me;\n\t},\n\n\ttooltipPosition: function() {\n\t\treturn {\n\t\t\tx: this._model.x,\n\t\t\ty: this._model.y\n\t\t};\n\t},\n\n\thasValue: function() {\n\t\treturn helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);\n\t}\n});\n\nElement.extend = helpers.inherits;\n\nmodule.exports = Element;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNGE0NS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmVsZW1lbnQuanM/MmI2MSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBjb2xvciA9IHJlcXVpcmUoJ2NoYXJ0anMtY29sb3InKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xuXG5mdW5jdGlvbiBpbnRlcnBvbGF0ZShzdGFydCwgdmlldywgbW9kZWwsIGVhc2UpIHtcblx0dmFyIGtleXMgPSBPYmplY3Qua2V5cyhtb2RlbCk7XG5cdHZhciBpLCBpbGVuLCBrZXksIGFjdHVhbCwgb3JpZ2luLCB0YXJnZXQsIHR5cGUsIGMwLCBjMTtcblxuXHRmb3IgKGkgPSAwLCBpbGVuID0ga2V5cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRrZXkgPSBrZXlzW2ldO1xuXG5cdFx0dGFyZ2V0ID0gbW9kZWxba2V5XTtcblxuXHRcdC8vIGlmIGEgdmFsdWUgaXMgYWRkZWQgdG8gdGhlIG1vZGVsIGFmdGVyIHBpdm90KCkgaGFzIGJlZW4gY2FsbGVkLCB0aGUgdmlld1xuXHRcdC8vIGRvZXNuJ3QgY29udGFpbiBpdCwgc28gbGV0J3MgaW5pdGlhbGl6ZSB0aGUgdmlldyB0byB0aGUgdGFyZ2V0IHZhbHVlLlxuXHRcdGlmICghdmlldy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0XHR2aWV3W2tleV0gPSB0YXJnZXQ7XG5cdFx0fVxuXG5cdFx0YWN0dWFsID0gdmlld1trZXldO1xuXG5cdFx0aWYgKGFjdHVhbCA9PT0gdGFyZ2V0IHx8IGtleVswXSA9PT0gJ18nKSB7XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cblx0XHRpZiAoIXN0YXJ0Lmhhc093blByb3BlcnR5KGtleSkpIHtcblx0XHRcdHN0YXJ0W2tleV0gPSBhY3R1YWw7XG5cdFx0fVxuXG5cdFx0b3JpZ2luID0gc3RhcnRba2V5XTtcblxuXHRcdHR5cGUgPSB0eXBlb2YgdGFyZ2V0O1xuXG5cdFx0aWYgKHR5cGUgPT09IHR5cGVvZiBvcmlnaW4pIHtcblx0XHRcdGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuXHRcdFx0XHRjMCA9IGNvbG9yKG9yaWdpbik7XG5cdFx0XHRcdGlmIChjMC52YWxpZCkge1xuXHRcdFx0XHRcdGMxID0gY29sb3IodGFyZ2V0KTtcblx0XHRcdFx0XHRpZiAoYzEudmFsaWQpIHtcblx0XHRcdFx0XHRcdHZpZXdba2V5XSA9IGMxLm1peChjMCwgZWFzZSkucmdiU3RyaW5nKCk7XG5cdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgaXNGaW5pdGUob3JpZ2luKSAmJiBpc0Zpbml0ZSh0YXJnZXQpKSB7XG5cdFx0XHRcdHZpZXdba2V5XSA9IG9yaWdpbiArICh0YXJnZXQgLSBvcmlnaW4pICogZWFzZTtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dmlld1trZXldID0gdGFyZ2V0O1xuXHR9XG59XG5cbnZhciBFbGVtZW50ID0gZnVuY3Rpb24oY29uZmlndXJhdGlvbikge1xuXHRoZWxwZXJzLmV4dGVuZCh0aGlzLCBjb25maWd1cmF0aW9uKTtcblx0dGhpcy5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59O1xuXG5oZWxwZXJzLmV4dGVuZChFbGVtZW50LnByb3RvdHlwZSwge1xuXG5cdGluaXRpYWxpemU6IGZ1bmN0aW9uKCkge1xuXHRcdHRoaXMuaGlkZGVuID0gZmFsc2U7XG5cdH0sXG5cblx0cGl2b3Q6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0aWYgKCFtZS5fdmlldykge1xuXHRcdFx0bWUuX3ZpZXcgPSBoZWxwZXJzLmNsb25lKG1lLl9tb2RlbCk7XG5cdFx0fVxuXHRcdG1lLl9zdGFydCA9IHt9O1xuXHRcdHJldHVybiBtZTtcblx0fSxcblxuXHR0cmFuc2l0aW9uOiBmdW5jdGlvbihlYXNlKSB7XG5cdFx0dmFyIG1lID0gdGhpcztcblx0XHR2YXIgbW9kZWwgPSBtZS5fbW9kZWw7XG5cdFx0dmFyIHN0YXJ0ID0gbWUuX3N0YXJ0O1xuXHRcdHZhciB2aWV3ID0gbWUuX3ZpZXc7XG5cblx0XHQvLyBObyBhbmltYXRpb24gLT4gTm8gVHJhbnNpdGlvblxuXHRcdGlmICghbW9kZWwgfHwgZWFzZSA9PT0gMSkge1xuXHRcdFx0bWUuX3ZpZXcgPSBtb2RlbDtcblx0XHRcdG1lLl9zdGFydCA9IG51bGw7XG5cdFx0XHRyZXR1cm4gbWU7XG5cdFx0fVxuXG5cdFx0aWYgKCF2aWV3KSB7XG5cdFx0XHR2aWV3ID0gbWUuX3ZpZXcgPSB7fTtcblx0XHR9XG5cblx0XHRpZiAoIXN0YXJ0KSB7XG5cdFx0XHRzdGFydCA9IG1lLl9zdGFydCA9IHt9O1xuXHRcdH1cblxuXHRcdGludGVycG9sYXRlKHN0YXJ0LCB2aWV3LCBtb2RlbCwgZWFzZSk7XG5cblx0XHRyZXR1cm4gbWU7XG5cdH0sXG5cblx0dG9vbHRpcFBvc2l0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0eDogdGhpcy5fbW9kZWwueCxcblx0XHRcdHk6IHRoaXMuX21vZGVsLnlcblx0XHR9O1xuXHR9LFxuXG5cdGhhc1ZhbHVlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gaGVscGVycy5pc051bWJlcih0aGlzLl9tb2RlbC54KSAmJiBoZWxwZXJzLmlzTnVtYmVyKHRoaXMuX21vZGVsLnkpO1xuXHR9XG59KTtcblxuRWxlbWVudC5leHRlbmQgPSBoZWxwZXJzLmluaGVyaXRzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVsZW1lbnQ7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4a45\n")},"57b3":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar Scale = __webpack_require__(/*! ../core/core.scale */ \"d1b4\");\nvar scaleService = __webpack_require__(/*! ../core/core.scaleService */ \"7c56\");\n\nmodule.exports = function() {\n\n\t// Default config for a category scale\n\tvar defaultConfig = {\n\t\tposition: 'bottom'\n\t};\n\n\tvar DatasetScale = Scale.extend({\n\t\t/**\n\t\t* Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those\n\t\t* else fall back to data.labels\n\t\t* @private\n\t\t*/\n\t\tgetLabels: function() {\n\t\t\tvar data = this.chart.data;\n\t\t\treturn this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;\n\t\t},\n\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar labels = me.getLabels();\n\t\t\tme.minIndex = 0;\n\t\t\tme.maxIndex = labels.length - 1;\n\t\t\tvar findIndex;\n\n\t\t\tif (me.options.ticks.min !== undefined) {\n\t\t\t\t// user specified min value\n\t\t\t\tfindIndex = labels.indexOf(me.options.ticks.min);\n\t\t\t\tme.minIndex = findIndex !== -1 ? findIndex : me.minIndex;\n\t\t\t}\n\n\t\t\tif (me.options.ticks.max !== undefined) {\n\t\t\t\t// user specified max value\n\t\t\t\tfindIndex = labels.indexOf(me.options.ticks.max);\n\t\t\t\tme.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;\n\t\t\t}\n\n\t\t\tme.min = labels[me.minIndex];\n\t\t\tme.max = labels[me.maxIndex];\n\t\t},\n\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar labels = me.getLabels();\n\t\t\t// If we are viewing some subset of labels, slice the original array\n\t\t\tme.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);\n\t\t},\n\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar data = me.chart.data;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\n\t\t\tif (data.yLabels && !isHorizontal) {\n\t\t\t\treturn me.getRightValue(data.datasets[datasetIndex].data[index]);\n\t\t\t}\n\t\t\treturn me.ticks[index - me.minIndex];\n\t\t},\n\n\t\t// Used to get data value locations.  Value can either be an index or a numerical value\n\t\tgetPixelForValue: function(value, index) {\n\t\t\tvar me = this;\n\t\t\tvar offset = me.options.offset;\n\t\t\t// 1 is added because we need the length but we have the indexes\n\t\t\tvar offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - (offset ? 0 : 1)), 1);\n\n\t\t\t// If value is a data object, then index is the index in the data array,\n\t\t\t// not the index of the scale. We need to change that.\n\t\t\tvar valueCategory;\n\t\t\tif (value !== undefined && value !== null) {\n\t\t\t\tvalueCategory = me.isHorizontal() ? value.x : value.y;\n\t\t\t}\n\t\t\tif (valueCategory !== undefined || (value !== undefined && isNaN(index))) {\n\t\t\t\tvar labels = me.getLabels();\n\t\t\t\tvalue = valueCategory || value;\n\t\t\t\tvar idx = labels.indexOf(value);\n\t\t\t\tindex = idx !== -1 ? idx : index;\n\t\t\t}\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tvar valueWidth = me.width / offsetAmt;\n\t\t\t\tvar widthOffset = (valueWidth * (index - me.minIndex));\n\n\t\t\t\tif (offset) {\n\t\t\t\t\twidthOffset += (valueWidth / 2);\n\t\t\t\t}\n\n\t\t\t\treturn me.left + Math.round(widthOffset);\n\t\t\t}\n\t\t\tvar valueHeight = me.height / offsetAmt;\n\t\t\tvar heightOffset = (valueHeight * (index - me.minIndex));\n\n\t\t\tif (offset) {\n\t\t\t\theightOffset += (valueHeight / 2);\n\t\t\t}\n\n\t\t\treturn me.top + Math.round(heightOffset);\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForValue(this.ticks[index], index + this.minIndex, null);\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar offset = me.options.offset;\n\t\t\tvar value;\n\t\t\tvar offsetAmt = Math.max((me._ticks.length - (offset ? 0 : 1)), 1);\n\t\t\tvar horz = me.isHorizontal();\n\t\t\tvar valueDimension = (horz ? me.width : me.height) / offsetAmt;\n\n\t\t\tpixel -= horz ? me.left : me.top;\n\n\t\t\tif (offset) {\n\t\t\t\tpixel -= (valueDimension / 2);\n\t\t\t}\n\n\t\t\tif (pixel <= 0) {\n\t\t\t\tvalue = 0;\n\t\t\t} else {\n\t\t\t\tvalue = Math.round(pixel / valueDimension);\n\t\t\t}\n\n\t\t\treturn value + me.minIndex;\n\t\t},\n\t\tgetBasePixel: function() {\n\t\t\treturn this.bottom;\n\t\t}\n\t});\n\n\tscaleService.registerScaleType('category', DatasetScale, defaultConfig);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTdiMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvc2NhbGVzL3NjYWxlLmNhdGVnb3J5LmpzP2YxM2IiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgU2NhbGUgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuc2NhbGUnKTtcbnZhciBzY2FsZVNlcnZpY2UgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuc2NhbGVTZXJ2aWNlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG5cblx0Ly8gRGVmYXVsdCBjb25maWcgZm9yIGEgY2F0ZWdvcnkgc2NhbGVcblx0dmFyIGRlZmF1bHRDb25maWcgPSB7XG5cdFx0cG9zaXRpb246ICdib3R0b20nXG5cdH07XG5cblx0dmFyIERhdGFzZXRTY2FsZSA9IFNjYWxlLmV4dGVuZCh7XG5cdFx0LyoqXG5cdFx0KiBJbnRlcm5hbCBmdW5jdGlvbiB0byBnZXQgdGhlIGNvcnJlY3QgbGFiZWxzLiBJZiBkYXRhLnhMYWJlbHMgb3IgZGF0YS55TGFiZWxzIGFyZSBkZWZpbmVkLCB1c2UgdGhvc2Vcblx0XHQqIGVsc2UgZmFsbCBiYWNrIHRvIGRhdGEubGFiZWxzXG5cdFx0KiBAcHJpdmF0ZVxuXHRcdCovXG5cdFx0Z2V0TGFiZWxzOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBkYXRhID0gdGhpcy5jaGFydC5kYXRhO1xuXHRcdFx0cmV0dXJuIHRoaXMub3B0aW9ucy5sYWJlbHMgfHwgKHRoaXMuaXNIb3Jpem9udGFsKCkgPyBkYXRhLnhMYWJlbHMgOiBkYXRhLnlMYWJlbHMpIHx8IGRhdGEubGFiZWxzO1xuXHRcdH0sXG5cblx0XHRkZXRlcm1pbmVEYXRhTGltaXRzOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgbGFiZWxzID0gbWUuZ2V0TGFiZWxzKCk7XG5cdFx0XHRtZS5taW5JbmRleCA9IDA7XG5cdFx0XHRtZS5tYXhJbmRleCA9IGxhYmVscy5sZW5ndGggLSAxO1xuXHRcdFx0dmFyIGZpbmRJbmRleDtcblxuXHRcdFx0aWYgKG1lLm9wdGlvbnMudGlja3MubWluICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0Ly8gdXNlciBzcGVjaWZpZWQgbWluIHZhbHVlXG5cdFx0XHRcdGZpbmRJbmRleCA9IGxhYmVscy5pbmRleE9mKG1lLm9wdGlvbnMudGlja3MubWluKTtcblx0XHRcdFx0bWUubWluSW5kZXggPSBmaW5kSW5kZXggIT09IC0xID8gZmluZEluZGV4IDogbWUubWluSW5kZXg7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChtZS5vcHRpb25zLnRpY2tzLm1heCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdC8vIHVzZXIgc3BlY2lmaWVkIG1heCB2YWx1ZVxuXHRcdFx0XHRmaW5kSW5kZXggPSBsYWJlbHMuaW5kZXhPZihtZS5vcHRpb25zLnRpY2tzLm1heCk7XG5cdFx0XHRcdG1lLm1heEluZGV4ID0gZmluZEluZGV4ICE9PSAtMSA/IGZpbmRJbmRleCA6IG1lLm1heEluZGV4O1xuXHRcdFx0fVxuXG5cdFx0XHRtZS5taW4gPSBsYWJlbHNbbWUubWluSW5kZXhdO1xuXHRcdFx0bWUubWF4ID0gbGFiZWxzW21lLm1heEluZGV4XTtcblx0XHR9LFxuXG5cdFx0YnVpbGRUaWNrczogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIGxhYmVscyA9IG1lLmdldExhYmVscygpO1xuXHRcdFx0Ly8gSWYgd2UgYXJlIHZpZXdpbmcgc29tZSBzdWJzZXQgb2YgbGFiZWxzLCBzbGljZSB0aGUgb3JpZ2luYWwgYXJyYXlcblx0XHRcdG1lLnRpY2tzID0gKG1lLm1pbkluZGV4ID09PSAwICYmIG1lLm1heEluZGV4ID09PSBsYWJlbHMubGVuZ3RoIC0gMSkgPyBsYWJlbHMgOiBsYWJlbHMuc2xpY2UobWUubWluSW5kZXgsIG1lLm1heEluZGV4ICsgMSk7XG5cdFx0fSxcblxuXHRcdGdldExhYmVsRm9ySW5kZXg6IGZ1bmN0aW9uKGluZGV4LCBkYXRhc2V0SW5kZXgpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgZGF0YSA9IG1lLmNoYXJ0LmRhdGE7XG5cdFx0XHR2YXIgaXNIb3Jpem9udGFsID0gbWUuaXNIb3Jpem9udGFsKCk7XG5cblx0XHRcdGlmIChkYXRhLnlMYWJlbHMgJiYgIWlzSG9yaXpvbnRhbCkge1xuXHRcdFx0XHRyZXR1cm4gbWUuZ2V0UmlnaHRWYWx1ZShkYXRhLmRhdGFzZXRzW2RhdGFzZXRJbmRleF0uZGF0YVtpbmRleF0pO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1lLnRpY2tzW2luZGV4IC0gbWUubWluSW5kZXhdO1xuXHRcdH0sXG5cblx0XHQvLyBVc2VkIHRvIGdldCBkYXRhIHZhbHVlIGxvY2F0aW9ucy4gIFZhbHVlIGNhbiBlaXRoZXIgYmUgYW4gaW5kZXggb3IgYSBudW1lcmljYWwgdmFsdWVcblx0XHRnZXRQaXhlbEZvclZhbHVlOiBmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgb2Zmc2V0ID0gbWUub3B0aW9ucy5vZmZzZXQ7XG5cdFx0XHQvLyAxIGlzIGFkZGVkIGJlY2F1c2Ugd2UgbmVlZCB0aGUgbGVuZ3RoIGJ1dCB3ZSBoYXZlIHRoZSBpbmRleGVzXG5cdFx0XHR2YXIgb2Zmc2V0QW10ID0gTWF0aC5tYXgoKG1lLm1heEluZGV4ICsgMSAtIG1lLm1pbkluZGV4IC0gKG9mZnNldCA/IDAgOiAxKSksIDEpO1xuXG5cdFx0XHQvLyBJZiB2YWx1ZSBpcyBhIGRhdGEgb2JqZWN0LCB0aGVuIGluZGV4IGlzIHRoZSBpbmRleCBpbiB0aGUgZGF0YSBhcnJheSxcblx0XHRcdC8vIG5vdCB0aGUgaW5kZXggb2YgdGhlIHNjYWxlLiBXZSBuZWVkIHRvIGNoYW5nZSB0aGF0LlxuXHRcdFx0dmFyIHZhbHVlQ2F0ZWdvcnk7XG5cdFx0XHRpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCkge1xuXHRcdFx0XHR2YWx1ZUNhdGVnb3J5ID0gbWUuaXNIb3Jpem9udGFsKCkgPyB2YWx1ZS54IDogdmFsdWUueTtcblx0XHRcdH1cblx0XHRcdGlmICh2YWx1ZUNhdGVnb3J5ICE9PSB1bmRlZmluZWQgfHwgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgaXNOYU4oaW5kZXgpKSkge1xuXHRcdFx0XHR2YXIgbGFiZWxzID0gbWUuZ2V0TGFiZWxzKCk7XG5cdFx0XHRcdHZhbHVlID0gdmFsdWVDYXRlZ29yeSB8fCB2YWx1ZTtcblx0XHRcdFx0dmFyIGlkeCA9IGxhYmVscy5pbmRleE9mKHZhbHVlKTtcblx0XHRcdFx0aW5kZXggPSBpZHggIT09IC0xID8gaWR4IDogaW5kZXg7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChtZS5pc0hvcml6b250YWwoKSkge1xuXHRcdFx0XHR2YXIgdmFsdWVXaWR0aCA9IG1lLndpZHRoIC8gb2Zmc2V0QW10O1xuXHRcdFx0XHR2YXIgd2lkdGhPZmZzZXQgPSAodmFsdWVXaWR0aCAqIChpbmRleCAtIG1lLm1pbkluZGV4KSk7XG5cblx0XHRcdFx0aWYgKG9mZnNldCkge1xuXHRcdFx0XHRcdHdpZHRoT2Zmc2V0ICs9ICh2YWx1ZVdpZHRoIC8gMik7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gbWUubGVmdCArIE1hdGgucm91bmQod2lkdGhPZmZzZXQpO1xuXHRcdFx0fVxuXHRcdFx0dmFyIHZhbHVlSGVpZ2h0ID0gbWUuaGVpZ2h0IC8gb2Zmc2V0QW10O1xuXHRcdFx0dmFyIGhlaWdodE9mZnNldCA9ICh2YWx1ZUhlaWdodCAqIChpbmRleCAtIG1lLm1pbkluZGV4KSk7XG5cblx0XHRcdGlmIChvZmZzZXQpIHtcblx0XHRcdFx0aGVpZ2h0T2Zmc2V0ICs9ICh2YWx1ZUhlaWdodCAvIDIpO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbWUudG9wICsgTWF0aC5yb3VuZChoZWlnaHRPZmZzZXQpO1xuXHRcdH0sXG5cdFx0Z2V0UGl4ZWxGb3JUaWNrOiBmdW5jdGlvbihpbmRleCkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZ2V0UGl4ZWxGb3JWYWx1ZSh0aGlzLnRpY2tzW2luZGV4XSwgaW5kZXggKyB0aGlzLm1pbkluZGV4LCBudWxsKTtcblx0XHR9LFxuXHRcdGdldFZhbHVlRm9yUGl4ZWw6IGZ1bmN0aW9uKHBpeGVsKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG9mZnNldCA9IG1lLm9wdGlvbnMub2Zmc2V0O1xuXHRcdFx0dmFyIHZhbHVlO1xuXHRcdFx0dmFyIG9mZnNldEFtdCA9IE1hdGgubWF4KChtZS5fdGlja3MubGVuZ3RoIC0gKG9mZnNldCA/IDAgOiAxKSksIDEpO1xuXHRcdFx0dmFyIGhvcnogPSBtZS5pc0hvcml6b250YWwoKTtcblx0XHRcdHZhciB2YWx1ZURpbWVuc2lvbiA9IChob3J6ID8gbWUud2lkdGggOiBtZS5oZWlnaHQpIC8gb2Zmc2V0QW10O1xuXG5cdFx0XHRwaXhlbCAtPSBob3J6ID8gbWUubGVmdCA6IG1lLnRvcDtcblxuXHRcdFx0aWYgKG9mZnNldCkge1xuXHRcdFx0XHRwaXhlbCAtPSAodmFsdWVEaW1lbnNpb24gLyAyKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHBpeGVsIDw9IDApIHtcblx0XHRcdFx0dmFsdWUgPSAwO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dmFsdWUgPSBNYXRoLnJvdW5kKHBpeGVsIC8gdmFsdWVEaW1lbnNpb24pO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdmFsdWUgKyBtZS5taW5JbmRleDtcblx0XHR9LFxuXHRcdGdldEJhc2VQaXhlbDogZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5ib3R0b207XG5cdFx0fVxuXHR9KTtcblxuXHRzY2FsZVNlcnZpY2UucmVnaXN0ZXJTY2FsZVR5cGUoJ2NhdGVnb3J5JywgRGF0YXNldFNjYWxlLCBkZWZhdWx0Q29uZmlnKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///57b3\n")},"5f7c":function(module,exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = function(Chart) {\n\n\tChart.PolarArea = function(context, config) {\n\t\tconfig.type = 'polarArea';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNWY3Yy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY2hhcnRzL0NoYXJ0LlBvbGFyQXJlYS5qcz9hYjM2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDaGFydCkge1xuXG5cdENoYXJ0LlBvbGFyQXJlYSA9IGZ1bmN0aW9uKGNvbnRleHQsIGNvbmZpZykge1xuXHRcdGNvbmZpZy50eXBlID0gJ3BvbGFyQXJlYSc7XG5cblx0XHRyZXR1cm4gbmV3IENoYXJ0KGNvbnRleHQsIGNvbmZpZyk7XG5cdH07XG5cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5f7c\n")},"612d":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\nmodule.exports = function(Chart) {\n\n\tvar arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];\n\n\t/**\n\t * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',\n\t * 'unshift') and notify the listener AFTER the array has been altered. Listeners are\n\t * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.\n\t */\n\tfunction listenArrayEvents(array, listener) {\n\t\tif (array._chartjs) {\n\t\t\tarray._chartjs.listeners.push(listener);\n\t\t\treturn;\n\t\t}\n\n\t\tObject.defineProperty(array, '_chartjs', {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: {\n\t\t\t\tlisteners: [listener]\n\t\t\t}\n\t\t});\n\n\t\tarrayEvents.forEach(function(key) {\n\t\t\tvar method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);\n\t\t\tvar base = array[key];\n\n\t\t\tObject.defineProperty(array, key, {\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: function() {\n\t\t\t\t\tvar args = Array.prototype.slice.call(arguments);\n\t\t\t\t\tvar res = base.apply(this, args);\n\n\t\t\t\t\thelpers.each(array._chartjs.listeners, function(object) {\n\t\t\t\t\t\tif (typeof object[method] === 'function') {\n\t\t\t\t\t\t\tobject[method].apply(object, args);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Removes the given array event listener and cleanup extra attached properties (such as\n\t * the _chartjs stub and overridden methods) if array doesn't have any more listeners.\n\t */\n\tfunction unlistenArrayEvents(array, listener) {\n\t\tvar stub = array._chartjs;\n\t\tif (!stub) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar listeners = stub.listeners;\n\t\tvar index = listeners.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length > 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tarrayEvents.forEach(function(key) {\n\t\t\tdelete array[key];\n\t\t});\n\n\t\tdelete array._chartjs;\n\t}\n\n\t// Base class for all dataset controllers (line, bar, etc)\n\tChart.DatasetController = function(chart, datasetIndex) {\n\t\tthis.initialize(chart, datasetIndex);\n\t};\n\n\thelpers.extend(Chart.DatasetController.prototype, {\n\n\t\t/**\n\t\t * Element type used to generate a meta dataset (e.g. Chart.element.Line).\n\t\t * @type {Chart.core.element}\n\t\t */\n\t\tdatasetElementType: null,\n\n\t\t/**\n\t\t * Element type used to generate a meta data (e.g. Chart.element.Point).\n\t\t * @type {Chart.core.element}\n\t\t */\n\t\tdataElementType: null,\n\n\t\tinitialize: function(chart, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tme.chart = chart;\n\t\t\tme.index = datasetIndex;\n\t\t\tme.linkScales();\n\t\t\tme.addElements();\n\t\t},\n\n\t\tupdateIndex: function(datasetIndex) {\n\t\t\tthis.index = datasetIndex;\n\t\t},\n\n\t\tlinkScales: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar dataset = me.getDataset();\n\n\t\t\tif (meta.xAxisID === null || !(meta.xAxisID in me.chart.scales)) {\n\t\t\t\tmeta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;\n\t\t\t}\n\t\t\tif (meta.yAxisID === null || !(meta.yAxisID in me.chart.scales)) {\n\t\t\t\tmeta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;\n\t\t\t}\n\t\t},\n\n\t\tgetDataset: function() {\n\t\t\treturn this.chart.data.datasets[this.index];\n\t\t},\n\n\t\tgetMeta: function() {\n\t\t\treturn this.chart.getDatasetMeta(this.index);\n\t\t},\n\n\t\tgetScaleForId: function(scaleID) {\n\t\t\treturn this.chart.scales[scaleID];\n\t\t},\n\n\t\treset: function() {\n\t\t\tthis.update(true);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tdestroy: function() {\n\t\t\tif (this._data) {\n\t\t\t\tunlistenArrayEvents(this._data, this);\n\t\t\t}\n\t\t},\n\n\t\tcreateMetaDataset: function() {\n\t\t\tvar me = this;\n\t\t\tvar type = me.datasetElementType;\n\t\t\treturn type && new type({\n\t\t\t\t_chart: me.chart,\n\t\t\t\t_datasetIndex: me.index\n\t\t\t});\n\t\t},\n\n\t\tcreateMetaData: function(index) {\n\t\t\tvar me = this;\n\t\t\tvar type = me.dataElementType;\n\t\t\treturn type && new type({\n\t\t\t\t_chart: me.chart,\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index\n\t\t\t});\n\t\t},\n\n\t\taddElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar data = me.getDataset().data || [];\n\t\t\tvar metaData = meta.data;\n\t\t\tvar i, ilen;\n\n\t\t\tfor (i = 0, ilen = data.length; i < ilen; ++i) {\n\t\t\t\tmetaData[i] = metaData[i] || me.createMetaData(i);\n\t\t\t}\n\n\t\t\tmeta.dataset = meta.dataset || me.createMetaDataset();\n\t\t},\n\n\t\taddElementAndReset: function(index) {\n\t\t\tvar element = this.createMetaData(index);\n\t\t\tthis.getMeta().data.splice(index, 0, element);\n\t\t\tthis.updateElement(element, index, true);\n\t\t},\n\n\t\tbuildOrUpdateElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar data = dataset.data || (dataset.data = []);\n\n\t\t\t// In order to correctly handle data addition/deletion animation (an thus simulate\n\t\t\t// real-time charts), we need to monitor these data modifications and synchronize\n\t\t\t// the internal meta data accordingly.\n\t\t\tif (me._data !== data) {\n\t\t\t\tif (me._data) {\n\t\t\t\t\t// This case happens when the user replaced the data array instance.\n\t\t\t\t\tunlistenArrayEvents(me._data, me);\n\t\t\t\t}\n\n\t\t\t\tlistenArrayEvents(data, me);\n\t\t\t\tme._data = data;\n\t\t\t}\n\n\t\t\t// Re-sync meta data in case the user replaced the data array or if we missed\n\t\t\t// any updates and so make sure that we handle number of datapoints changing.\n\t\t\tme.resyncElements();\n\t\t},\n\n\t\tupdate: helpers.noop,\n\n\t\ttransition: function(easingValue) {\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar elements = meta.data || [];\n\t\t\tvar ilen = elements.length;\n\t\t\tvar i = 0;\n\n\t\t\tfor (; i < ilen; ++i) {\n\t\t\t\telements[i].transition(easingValue);\n\t\t\t}\n\n\t\t\tif (meta.dataset) {\n\t\t\t\tmeta.dataset.transition(easingValue);\n\t\t\t}\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar elements = meta.data || [];\n\t\t\tvar ilen = elements.length;\n\t\t\tvar i = 0;\n\n\t\t\tif (meta.dataset) {\n\t\t\t\tmeta.dataset.draw();\n\t\t\t}\n\n\t\t\tfor (; i < ilen; ++i) {\n\t\t\t\telements[i].draw();\n\t\t\t}\n\t\t},\n\n\t\tremoveHoverStyle: function(element) {\n\t\t\thelpers.merge(element._model, element.$previousStyle || {});\n\t\t\tdelete element.$previousStyle;\n\t\t},\n\n\t\tsetHoverStyle: function(element) {\n\t\t\tvar dataset = this.chart.data.datasets[element._datasetIndex];\n\t\t\tvar index = element._index;\n\t\t\tvar custom = element.custom || {};\n\t\t\tvar valueOrDefault = helpers.valueAtIndexOrDefault;\n\t\t\tvar getHoverColor = helpers.getHoverColor;\n\t\t\tvar model = element._model;\n\n\t\t\telement.$previousStyle = {\n\t\t\t\tbackgroundColor: model.backgroundColor,\n\t\t\t\tborderColor: model.borderColor,\n\t\t\t\tborderWidth: model.borderWidth\n\t\t\t};\n\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tresyncElements: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar data = me.getDataset().data;\n\t\t\tvar numMeta = meta.data.length;\n\t\t\tvar numData = data.length;\n\n\t\t\tif (numData < numMeta) {\n\t\t\t\tmeta.data.splice(numData, numMeta - numData);\n\t\t\t} else if (numData > numMeta) {\n\t\t\t\tme.insertElements(numMeta, numData - numMeta);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tinsertElements: function(start, count) {\n\t\t\tfor (var i = 0; i < count; ++i) {\n\t\t\t\tthis.addElementAndReset(start + i);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataPush: function() {\n\t\t\tthis.insertElements(this.getDataset().data.length - 1, arguments.length);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataPop: function() {\n\t\t\tthis.getMeta().data.pop();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataShift: function() {\n\t\t\tthis.getMeta().data.shift();\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataSplice: function(start, count) {\n\t\t\tthis.getMeta().data.splice(start, count);\n\t\t\tthis.insertElements(start, arguments.length - 2);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tonDataUnshift: function() {\n\t\t\tthis.insertElements(0, arguments.length);\n\t\t}\n\t});\n\n\tChart.DatasetController.extend = helpers.inherits;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjEyZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmRhdGFzZXRDb250cm9sbGVyLmpzPzI4MDQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDaGFydCkge1xuXG5cdHZhciBhcnJheUV2ZW50cyA9IFsncHVzaCcsICdwb3AnLCAnc2hpZnQnLCAnc3BsaWNlJywgJ3Vuc2hpZnQnXTtcblxuXHQvKipcblx0ICogSG9va3MgdGhlIGFycmF5IG1ldGhvZHMgdGhhdCBhZGQgb3IgcmVtb3ZlIHZhbHVlcyAoJ3B1c2gnLCBwb3AnLCAnc2hpZnQnLCAnc3BsaWNlJyxcblx0ICogJ3Vuc2hpZnQnKSBhbmQgbm90aWZ5IHRoZSBsaXN0ZW5lciBBRlRFUiB0aGUgYXJyYXkgaGFzIGJlZW4gYWx0ZXJlZC4gTGlzdGVuZXJzIGFyZVxuXHQgKiBjYWxsZWQgb24gdGhlICdvbkRhdGEqJyBjYWxsYmFja3MgKGUuZy4gb25EYXRhUHVzaCwgZXRjLikgd2l0aCBzYW1lIGFyZ3VtZW50cy5cblx0ICovXG5cdGZ1bmN0aW9uIGxpc3RlbkFycmF5RXZlbnRzKGFycmF5LCBsaXN0ZW5lcikge1xuXHRcdGlmIChhcnJheS5fY2hhcnRqcykge1xuXHRcdFx0YXJyYXkuX2NoYXJ0anMubGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcnJheSwgJ19jaGFydGpzJywge1xuXHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlLFxuXHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHR2YWx1ZToge1xuXHRcdFx0XHRsaXN0ZW5lcnM6IFtsaXN0ZW5lcl1cblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdGFycmF5RXZlbnRzLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG5cdFx0XHR2YXIgbWV0aG9kID0gJ29uRGF0YScgKyBrZXkuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBrZXkuc2xpY2UoMSk7XG5cdFx0XHR2YXIgYmFzZSA9IGFycmF5W2tleV07XG5cblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcnJheSwga2V5LCB7XG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXG5cdFx0XHRcdHZhbHVlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHR2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cdFx0XHRcdFx0dmFyIHJlcyA9IGJhc2UuYXBwbHkodGhpcywgYXJncyk7XG5cblx0XHRcdFx0XHRoZWxwZXJzLmVhY2goYXJyYXkuX2NoYXJ0anMubGlzdGVuZXJzLCBmdW5jdGlvbihvYmplY3QpIHtcblx0XHRcdFx0XHRcdGlmICh0eXBlb2Ygb2JqZWN0W21ldGhvZF0gPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0XHRcdFx0b2JqZWN0W21ldGhvZF0uYXBwbHkob2JqZWN0LCBhcmdzKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblxuXHRcdFx0XHRcdHJldHVybiByZXM7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIGdpdmVuIGFycmF5IGV2ZW50IGxpc3RlbmVyIGFuZCBjbGVhbnVwIGV4dHJhIGF0dGFjaGVkIHByb3BlcnRpZXMgKHN1Y2ggYXNcblx0ICogdGhlIF9jaGFydGpzIHN0dWIgYW5kIG92ZXJyaWRkZW4gbWV0aG9kcykgaWYgYXJyYXkgZG9lc24ndCBoYXZlIGFueSBtb3JlIGxpc3RlbmVycy5cblx0ICovXG5cdGZ1bmN0aW9uIHVubGlzdGVuQXJyYXlFdmVudHMoYXJyYXksIGxpc3RlbmVyKSB7XG5cdFx0dmFyIHN0dWIgPSBhcnJheS5fY2hhcnRqcztcblx0XHRpZiAoIXN0dWIpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgbGlzdGVuZXJzID0gc3R1Yi5saXN0ZW5lcnM7XG5cdFx0dmFyIGluZGV4ID0gbGlzdGVuZXJzLmluZGV4T2YobGlzdGVuZXIpO1xuXHRcdGlmIChpbmRleCAhPT0gLTEpIHtcblx0XHRcdGxpc3RlbmVycy5zcGxpY2UoaW5kZXgsIDEpO1xuXHRcdH1cblxuXHRcdGlmIChsaXN0ZW5lcnMubGVuZ3RoID4gMCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGFycmF5RXZlbnRzLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG5cdFx0XHRkZWxldGUgYXJyYXlba2V5XTtcblx0XHR9KTtcblxuXHRcdGRlbGV0ZSBhcnJheS5fY2hhcnRqcztcblx0fVxuXG5cdC8vIEJhc2UgY2xhc3MgZm9yIGFsbCBkYXRhc2V0IGNvbnRyb2xsZXJzIChsaW5lLCBiYXIsIGV0Yylcblx0Q2hhcnQuRGF0YXNldENvbnRyb2xsZXIgPSBmdW5jdGlvbihjaGFydCwgZGF0YXNldEluZGV4KSB7XG5cdFx0dGhpcy5pbml0aWFsaXplKGNoYXJ0LCBkYXRhc2V0SW5kZXgpO1xuXHR9O1xuXG5cdGhlbHBlcnMuZXh0ZW5kKENoYXJ0LkRhdGFzZXRDb250cm9sbGVyLnByb3RvdHlwZSwge1xuXG5cdFx0LyoqXG5cdFx0ICogRWxlbWVudCB0eXBlIHVzZWQgdG8gZ2VuZXJhdGUgYSBtZXRhIGRhdGFzZXQgKGUuZy4gQ2hhcnQuZWxlbWVudC5MaW5lKS5cblx0XHQgKiBAdHlwZSB7Q2hhcnQuY29yZS5lbGVtZW50fVxuXHRcdCAqL1xuXHRcdGRhdGFzZXRFbGVtZW50VHlwZTogbnVsbCxcblxuXHRcdC8qKlxuXHRcdCAqIEVsZW1lbnQgdHlwZSB1c2VkIHRvIGdlbmVyYXRlIGEgbWV0YSBkYXRhIChlLmcuIENoYXJ0LmVsZW1lbnQuUG9pbnQpLlxuXHRcdCAqIEB0eXBlIHtDaGFydC5jb3JlLmVsZW1lbnR9XG5cdFx0ICovXG5cdFx0ZGF0YUVsZW1lbnRUeXBlOiBudWxsLFxuXG5cdFx0aW5pdGlhbGl6ZTogZnVuY3Rpb24oY2hhcnQsIGRhdGFzZXRJbmRleCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdG1lLmNoYXJ0ID0gY2hhcnQ7XG5cdFx0XHRtZS5pbmRleCA9IGRhdGFzZXRJbmRleDtcblx0XHRcdG1lLmxpbmtTY2FsZXMoKTtcblx0XHRcdG1lLmFkZEVsZW1lbnRzKCk7XG5cdFx0fSxcblxuXHRcdHVwZGF0ZUluZGV4OiBmdW5jdGlvbihkYXRhc2V0SW5kZXgpIHtcblx0XHRcdHRoaXMuaW5kZXggPSBkYXRhc2V0SW5kZXg7XG5cdFx0fSxcblxuXHRcdGxpbmtTY2FsZXM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xuXHRcdFx0dmFyIGRhdGFzZXQgPSBtZS5nZXREYXRhc2V0KCk7XG5cblx0XHRcdGlmIChtZXRhLnhBeGlzSUQgPT09IG51bGwgfHwgIShtZXRhLnhBeGlzSUQgaW4gbWUuY2hhcnQuc2NhbGVzKSkge1xuXHRcdFx0XHRtZXRhLnhBeGlzSUQgPSBkYXRhc2V0LnhBeGlzSUQgfHwgbWUuY2hhcnQub3B0aW9ucy5zY2FsZXMueEF4ZXNbMF0uaWQ7XG5cdFx0XHR9XG5cdFx0XHRpZiAobWV0YS55QXhpc0lEID09PSBudWxsIHx8ICEobWV0YS55QXhpc0lEIGluIG1lLmNoYXJ0LnNjYWxlcykpIHtcblx0XHRcdFx0bWV0YS55QXhpc0lEID0gZGF0YXNldC55QXhpc0lEIHx8IG1lLmNoYXJ0Lm9wdGlvbnMuc2NhbGVzLnlBeGVzWzBdLmlkO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRnZXREYXRhc2V0OiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbdGhpcy5pbmRleF07XG5cdFx0fSxcblxuXHRcdGdldE1ldGE6IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHRoaXMuY2hhcnQuZ2V0RGF0YXNldE1ldGEodGhpcy5pbmRleCk7XG5cdFx0fSxcblxuXHRcdGdldFNjYWxlRm9ySWQ6IGZ1bmN0aW9uKHNjYWxlSUQpIHtcblx0XHRcdHJldHVybiB0aGlzLmNoYXJ0LnNjYWxlc1tzY2FsZUlEXTtcblx0XHR9LFxuXG5cdFx0cmVzZXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dGhpcy51cGRhdGUodHJ1ZSk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0ZGVzdHJveTogZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAodGhpcy5fZGF0YSkge1xuXHRcdFx0XHR1bmxpc3RlbkFycmF5RXZlbnRzKHRoaXMuX2RhdGEsIHRoaXMpO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRjcmVhdGVNZXRhRGF0YXNldDogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIHR5cGUgPSBtZS5kYXRhc2V0RWxlbWVudFR5cGU7XG5cdFx0XHRyZXR1cm4gdHlwZSAmJiBuZXcgdHlwZSh7XG5cdFx0XHRcdF9jaGFydDogbWUuY2hhcnQsXG5cdFx0XHRcdF9kYXRhc2V0SW5kZXg6IG1lLmluZGV4XG5cdFx0XHR9KTtcblx0XHR9LFxuXG5cdFx0Y3JlYXRlTWV0YURhdGE6IGZ1bmN0aW9uKGluZGV4KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIHR5cGUgPSBtZS5kYXRhRWxlbWVudFR5cGU7XG5cdFx0XHRyZXR1cm4gdHlwZSAmJiBuZXcgdHlwZSh7XG5cdFx0XHRcdF9jaGFydDogbWUuY2hhcnQsXG5cdFx0XHRcdF9kYXRhc2V0SW5kZXg6IG1lLmluZGV4LFxuXHRcdFx0XHRfaW5kZXg6IGluZGV4XG5cdFx0XHR9KTtcblx0XHR9LFxuXG5cdFx0YWRkRWxlbWVudHM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xuXHRcdFx0dmFyIGRhdGEgPSBtZS5nZXREYXRhc2V0KCkuZGF0YSB8fCBbXTtcblx0XHRcdHZhciBtZXRhRGF0YSA9IG1ldGEuZGF0YTtcblx0XHRcdHZhciBpLCBpbGVuO1xuXG5cdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0gZGF0YS5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdFx0bWV0YURhdGFbaV0gPSBtZXRhRGF0YVtpXSB8fCBtZS5jcmVhdGVNZXRhRGF0YShpKTtcblx0XHRcdH1cblxuXHRcdFx0bWV0YS5kYXRhc2V0ID0gbWV0YS5kYXRhc2V0IHx8IG1lLmNyZWF0ZU1ldGFEYXRhc2V0KCk7XG5cdFx0fSxcblxuXHRcdGFkZEVsZW1lbnRBbmRSZXNldDogZnVuY3Rpb24oaW5kZXgpIHtcblx0XHRcdHZhciBlbGVtZW50ID0gdGhpcy5jcmVhdGVNZXRhRGF0YShpbmRleCk7XG5cdFx0XHR0aGlzLmdldE1ldGEoKS5kYXRhLnNwbGljZShpbmRleCwgMCwgZWxlbWVudCk7XG5cdFx0XHR0aGlzLnVwZGF0ZUVsZW1lbnQoZWxlbWVudCwgaW5kZXgsIHRydWUpO1xuXHRcdH0sXG5cblx0XHRidWlsZE9yVXBkYXRlRWxlbWVudHM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xuXHRcdFx0dmFyIGRhdGEgPSBkYXRhc2V0LmRhdGEgfHwgKGRhdGFzZXQuZGF0YSA9IFtdKTtcblxuXHRcdFx0Ly8gSW4gb3JkZXIgdG8gY29ycmVjdGx5IGhhbmRsZSBkYXRhIGFkZGl0aW9uL2RlbGV0aW9uIGFuaW1hdGlvbiAoYW4gdGh1cyBzaW11bGF0ZVxuXHRcdFx0Ly8gcmVhbC10aW1lIGNoYXJ0cyksIHdlIG5lZWQgdG8gbW9uaXRvciB0aGVzZSBkYXRhIG1vZGlmaWNhdGlvbnMgYW5kIHN5bmNocm9uaXplXG5cdFx0XHQvLyB0aGUgaW50ZXJuYWwgbWV0YSBkYXRhIGFjY29yZGluZ2x5LlxuXHRcdFx0aWYgKG1lLl9kYXRhICE9PSBkYXRhKSB7XG5cdFx0XHRcdGlmIChtZS5fZGF0YSkge1xuXHRcdFx0XHRcdC8vIFRoaXMgY2FzZSBoYXBwZW5zIHdoZW4gdGhlIHVzZXIgcmVwbGFjZWQgdGhlIGRhdGEgYXJyYXkgaW5zdGFuY2UuXG5cdFx0XHRcdFx0dW5saXN0ZW5BcnJheUV2ZW50cyhtZS5fZGF0YSwgbWUpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0bGlzdGVuQXJyYXlFdmVudHMoZGF0YSwgbWUpO1xuXHRcdFx0XHRtZS5fZGF0YSA9IGRhdGE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlLXN5bmMgbWV0YSBkYXRhIGluIGNhc2UgdGhlIHVzZXIgcmVwbGFjZWQgdGhlIGRhdGEgYXJyYXkgb3IgaWYgd2UgbWlzc2VkXG5cdFx0XHQvLyBhbnkgdXBkYXRlcyBhbmQgc28gbWFrZSBzdXJlIHRoYXQgd2UgaGFuZGxlIG51bWJlciBvZiBkYXRhcG9pbnRzIGNoYW5naW5nLlxuXHRcdFx0bWUucmVzeW5jRWxlbWVudHMoKTtcblx0XHR9LFxuXG5cdFx0dXBkYXRlOiBoZWxwZXJzLm5vb3AsXG5cblx0XHR0cmFuc2l0aW9uOiBmdW5jdGlvbihlYXNpbmdWYWx1ZSkge1xuXHRcdFx0dmFyIG1ldGEgPSB0aGlzLmdldE1ldGEoKTtcblx0XHRcdHZhciBlbGVtZW50cyA9IG1ldGEuZGF0YSB8fCBbXTtcblx0XHRcdHZhciBpbGVuID0gZWxlbWVudHMubGVuZ3RoO1xuXHRcdFx0dmFyIGkgPSAwO1xuXG5cdFx0XHRmb3IgKDsgaSA8IGlsZW47ICsraSkge1xuXHRcdFx0XHRlbGVtZW50c1tpXS50cmFuc2l0aW9uKGVhc2luZ1ZhbHVlKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKG1ldGEuZGF0YXNldCkge1xuXHRcdFx0XHRtZXRhLmRhdGFzZXQudHJhbnNpdGlvbihlYXNpbmdWYWx1ZSk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdGRyYXc6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1ldGEgPSB0aGlzLmdldE1ldGEoKTtcblx0XHRcdHZhciBlbGVtZW50cyA9IG1ldGEuZGF0YSB8fCBbXTtcblx0XHRcdHZhciBpbGVuID0gZWxlbWVudHMubGVuZ3RoO1xuXHRcdFx0dmFyIGkgPSAwO1xuXG5cdFx0XHRpZiAobWV0YS5kYXRhc2V0KSB7XG5cdFx0XHRcdG1ldGEuZGF0YXNldC5kcmF3KCk7XG5cdFx0XHR9XG5cblx0XHRcdGZvciAoOyBpIDwgaWxlbjsgKytpKSB7XG5cdFx0XHRcdGVsZW1lbnRzW2ldLmRyYXcoKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0cmVtb3ZlSG92ZXJTdHlsZTogZnVuY3Rpb24oZWxlbWVudCkge1xuXHRcdFx0aGVscGVycy5tZXJnZShlbGVtZW50Ll9tb2RlbCwgZWxlbWVudC4kcHJldmlvdXNTdHlsZSB8fCB7fSk7XG5cdFx0XHRkZWxldGUgZWxlbWVudC4kcHJldmlvdXNTdHlsZTtcblx0XHR9LFxuXG5cdFx0c2V0SG92ZXJTdHlsZTogZnVuY3Rpb24oZWxlbWVudCkge1xuXHRcdFx0dmFyIGRhdGFzZXQgPSB0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbZWxlbWVudC5fZGF0YXNldEluZGV4XTtcblx0XHRcdHZhciBpbmRleCA9IGVsZW1lbnQuX2luZGV4O1xuXHRcdFx0dmFyIGN1c3RvbSA9IGVsZW1lbnQuY3VzdG9tIHx8IHt9O1xuXHRcdFx0dmFyIHZhbHVlT3JEZWZhdWx0ID0gaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQ7XG5cdFx0XHR2YXIgZ2V0SG92ZXJDb2xvciA9IGhlbHBlcnMuZ2V0SG92ZXJDb2xvcjtcblx0XHRcdHZhciBtb2RlbCA9IGVsZW1lbnQuX21vZGVsO1xuXG5cdFx0XHRlbGVtZW50LiRwcmV2aW91c1N0eWxlID0ge1xuXHRcdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IG1vZGVsLmJhY2tncm91bmRDb2xvcixcblx0XHRcdFx0Ym9yZGVyQ29sb3I6IG1vZGVsLmJvcmRlckNvbG9yLFxuXHRcdFx0XHRib3JkZXJXaWR0aDogbW9kZWwuYm9yZGVyV2lkdGhcblx0XHRcdH07XG5cblx0XHRcdG1vZGVsLmJhY2tncm91bmRDb2xvciA9IGN1c3RvbS5ob3ZlckJhY2tncm91bmRDb2xvciA/IGN1c3RvbS5ob3ZlckJhY2tncm91bmRDb2xvciA6IHZhbHVlT3JEZWZhdWx0KGRhdGFzZXQuaG92ZXJCYWNrZ3JvdW5kQ29sb3IsIGluZGV4LCBnZXRIb3ZlckNvbG9yKG1vZGVsLmJhY2tncm91bmRDb2xvcikpO1xuXHRcdFx0bW9kZWwuYm9yZGVyQ29sb3IgPSBjdXN0b20uaG92ZXJCb3JkZXJDb2xvciA/IGN1c3RvbS5ob3ZlckJvcmRlckNvbG9yIDogdmFsdWVPckRlZmF1bHQoZGF0YXNldC5ob3ZlckJvcmRlckNvbG9yLCBpbmRleCwgZ2V0SG92ZXJDb2xvcihtb2RlbC5ib3JkZXJDb2xvcikpO1xuXHRcdFx0bW9kZWwuYm9yZGVyV2lkdGggPSBjdXN0b20uaG92ZXJCb3JkZXJXaWR0aCA/IGN1c3RvbS5ob3ZlckJvcmRlcldpZHRoIDogdmFsdWVPckRlZmF1bHQoZGF0YXNldC5ob3ZlckJvcmRlcldpZHRoLCBpbmRleCwgbW9kZWwuYm9yZGVyV2lkdGgpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdHJlc3luY0VsZW1lbnRzOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgbWV0YSA9IG1lLmdldE1ldGEoKTtcblx0XHRcdHZhciBkYXRhID0gbWUuZ2V0RGF0YXNldCgpLmRhdGE7XG5cdFx0XHR2YXIgbnVtTWV0YSA9IG1ldGEuZGF0YS5sZW5ndGg7XG5cdFx0XHR2YXIgbnVtRGF0YSA9IGRhdGEubGVuZ3RoO1xuXG5cdFx0XHRpZiAobnVtRGF0YSA8IG51bU1ldGEpIHtcblx0XHRcdFx0bWV0YS5kYXRhLnNwbGljZShudW1EYXRhLCBudW1NZXRhIC0gbnVtRGF0YSk7XG5cdFx0XHR9IGVsc2UgaWYgKG51bURhdGEgPiBudW1NZXRhKSB7XG5cdFx0XHRcdG1lLmluc2VydEVsZW1lbnRzKG51bU1ldGEsIG51bURhdGEgLSBudW1NZXRhKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRpbnNlcnRFbGVtZW50czogZnVuY3Rpb24oc3RhcnQsIGNvdW50KSB7XG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcblx0XHRcdFx0dGhpcy5hZGRFbGVtZW50QW5kUmVzZXQoc3RhcnQgKyBpKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRvbkRhdGFQdXNoOiBmdW5jdGlvbigpIHtcblx0XHRcdHRoaXMuaW5zZXJ0RWxlbWVudHModGhpcy5nZXREYXRhc2V0KCkuZGF0YS5sZW5ndGggLSAxLCBhcmd1bWVudHMubGVuZ3RoKTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRvbkRhdGFQb3A6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dGhpcy5nZXRNZXRhKCkuZGF0YS5wb3AoKTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRvbkRhdGFTaGlmdDogZnVuY3Rpb24oKSB7XG5cdFx0XHR0aGlzLmdldE1ldGEoKS5kYXRhLnNoaWZ0KCk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0b25EYXRhU3BsaWNlOiBmdW5jdGlvbihzdGFydCwgY291bnQpIHtcblx0XHRcdHRoaXMuZ2V0TWV0YSgpLmRhdGEuc3BsaWNlKHN0YXJ0LCBjb3VudCk7XG5cdFx0XHR0aGlzLmluc2VydEVsZW1lbnRzKHN0YXJ0LCBhcmd1bWVudHMubGVuZ3RoIC0gMik7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0b25EYXRhVW5zaGlmdDogZnVuY3Rpb24oKSB7XG5cdFx0XHR0aGlzLmluc2VydEVsZW1lbnRzKDAsIGFyZ3VtZW50cy5sZW5ndGgpO1xuXHRcdH1cblx0fSk7XG5cblx0Q2hhcnQuRGF0YXNldENvbnRyb2xsZXIuZXh0ZW5kID0gaGVscGVycy5pbmhlcml0cztcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///612d\n")},"65bb":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar Element = __webpack_require__(/*! ./core.element */ \"4a45\");\n\nvar exports = module.exports = Element.extend({\n\tchart: null, // the animation associated chart instance\n\tcurrentStep: 0, // the current animation step\n\tnumSteps: 60, // default number of steps\n\teasing: '', // the easing to use for this animation\n\trender: null, // render function used by the animation service\n\n\tonAnimationProgress: null, // user specified callback to fire on each step of the animation\n\tonAnimationComplete: null, // user specified callback to fire when the animation finishes\n});\n\n// DEPRECATIONS\n\n/**\n * Provided for backward compatibility, use Chart.Animation instead\n * @prop Chart.Animation#animationObject\n * @deprecated since version 2.6.0\n * @todo remove at version 3\n */\nObject.defineProperty(exports.prototype, 'animationObject', {\n\tget: function() {\n\t\treturn this;\n\t}\n});\n\n/**\n * Provided for backward compatibility, use Chart.Animation#chart instead\n * @prop Chart.Animation#chartInstance\n * @deprecated since version 2.6.0\n * @todo remove at version 3\n */\nObject.defineProperty(exports.prototype, 'chartInstance', {\n\tget: function() {\n\t\treturn this.chart;\n\t},\n\tset: function(value) {\n\t\tthis.chart = value;\n\t}\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjViYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmFuaW1hdGlvbi5qcz8wMzliIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIEVsZW1lbnQgPSByZXF1aXJlKCcuL2NvcmUuZWxlbWVudCcpO1xuXG52YXIgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gRWxlbWVudC5leHRlbmQoe1xuXHRjaGFydDogbnVsbCwgLy8gdGhlIGFuaW1hdGlvbiBhc3NvY2lhdGVkIGNoYXJ0IGluc3RhbmNlXG5cdGN1cnJlbnRTdGVwOiAwLCAvLyB0aGUgY3VycmVudCBhbmltYXRpb24gc3RlcFxuXHRudW1TdGVwczogNjAsIC8vIGRlZmF1bHQgbnVtYmVyIG9mIHN0ZXBzXG5cdGVhc2luZzogJycsIC8vIHRoZSBlYXNpbmcgdG8gdXNlIGZvciB0aGlzIGFuaW1hdGlvblxuXHRyZW5kZXI6IG51bGwsIC8vIHJlbmRlciBmdW5jdGlvbiB1c2VkIGJ5IHRoZSBhbmltYXRpb24gc2VydmljZVxuXG5cdG9uQW5pbWF0aW9uUHJvZ3Jlc3M6IG51bGwsIC8vIHVzZXIgc3BlY2lmaWVkIGNhbGxiYWNrIHRvIGZpcmUgb24gZWFjaCBzdGVwIG9mIHRoZSBhbmltYXRpb25cblx0b25BbmltYXRpb25Db21wbGV0ZTogbnVsbCwgLy8gdXNlciBzcGVjaWZpZWQgY2FsbGJhY2sgdG8gZmlyZSB3aGVuIHRoZSBhbmltYXRpb24gZmluaXNoZXNcbn0pO1xuXG4vLyBERVBSRUNBVElPTlNcblxuLyoqXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LkFuaW1hdGlvbiBpbnN0ZWFkXG4gKiBAcHJvcCBDaGFydC5BbmltYXRpb24jYW5pbWF0aW9uT2JqZWN0XG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNi4wXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLnByb3RvdHlwZSwgJ2FuaW1hdGlvbk9iamVjdCcsIHtcblx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxufSk7XG5cbi8qKlxuICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHVzZSBDaGFydC5BbmltYXRpb24jY2hhcnQgaW5zdGVhZFxuICogQHByb3AgQ2hhcnQuQW5pbWF0aW9uI2NoYXJ0SW5zdGFuY2VcbiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi42LjBcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMucHJvdG90eXBlLCAnY2hhcnRJbnN0YW5jZScsIHtcblx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5jaGFydDtcblx0fSxcblx0c2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdHRoaXMuY2hhcnQgPSB2YWx1ZTtcblx0fVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///65bb\n")},"66c8":function(module,exports,__webpack_require__){"use strict";eval('\n\nmodule.exports = __webpack_require__(/*! ./helpers.core */ "7d23");\nmodule.exports.easing = __webpack_require__(/*! ./helpers.easing */ "f974");\nmodule.exports.canvas = __webpack_require__(/*! ./helpers.canvas */ "7e33");\nmodule.exports.options = __webpack_require__(/*! ./helpers.options */ "7542");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjZjOC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9pbmRleC5qcz80NDM4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2hlbHBlcnMuY29yZScpO1xubW9kdWxlLmV4cG9ydHMuZWFzaW5nID0gcmVxdWlyZSgnLi9oZWxwZXJzLmVhc2luZycpO1xubW9kdWxlLmV4cG9ydHMuY2FudmFzID0gcmVxdWlyZSgnLi9oZWxwZXJzLmNhbnZhcycpO1xubW9kdWxlLmV4cG9ydHMub3B0aW9ucyA9IHJlcXVpcmUoJy4vaGVscGVycy5vcHRpb25zJyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///66c8\n')},6701:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\n/**\n * Helper function to get relative position for an event\n * @param {Event|IEvent} event - The event to get the position for\n * @param {Chart} chart - The chart\n * @returns {Point} the event position\n */\nfunction getRelativePosition(e, chart) {\n\tif (e.native) {\n\t\treturn {\n\t\t\tx: e.x,\n\t\t\ty: e.y\n\t\t};\n\t}\n\n\treturn helpers.getRelativePosition(e, chart);\n}\n\n/**\n * Helper function to traverse all of the visible elements in the chart\n * @param chart {chart} the chart\n * @param handler {Function} the callback to execute for each visible item\n */\nfunction parseVisibleItems(chart, handler) {\n\tvar datasets = chart.data.datasets;\n\tvar meta, i, j, ilen, jlen;\n\n\tfor (i = 0, ilen = datasets.length; i < ilen; ++i) {\n\t\tif (!chart.isDatasetVisible(i)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tmeta = chart.getDatasetMeta(i);\n\t\tfor (j = 0, jlen = meta.data.length; j < jlen; ++j) {\n\t\t\tvar element = meta.data[j];\n\t\t\tif (!element._view.skip) {\n\t\t\t\thandler(element);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Helper function to get the items that intersect the event position\n * @param items {ChartElement[]} elements to filter\n * @param position {Point} the point to be nearest to\n * @return {ChartElement[]} the nearest items\n */\nfunction getIntersectItems(chart, position) {\n\tvar elements = [];\n\n\tparseVisibleItems(chart, function(element) {\n\t\tif (element.inRange(position.x, position.y)) {\n\t\t\telements.push(element);\n\t\t}\n\t});\n\n\treturn elements;\n}\n\n/**\n * Helper function to get the items nearest to the event position considering all visible items in teh chart\n * @param chart {Chart} the chart to look at elements from\n * @param position {Point} the point to be nearest to\n * @param intersect {Boolean} if true, only consider items that intersect the position\n * @param distanceMetric {Function} function to provide the distance between points\n * @return {ChartElement[]} the nearest items\n */\nfunction getNearestItems(chart, position, intersect, distanceMetric) {\n\tvar minDistance = Number.POSITIVE_INFINITY;\n\tvar nearestItems = [];\n\n\tparseVisibleItems(chart, function(element) {\n\t\tif (intersect && !element.inRange(position.x, position.y)) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar center = element.getCenterPoint();\n\t\tvar distance = distanceMetric(position, center);\n\n\t\tif (distance < minDistance) {\n\t\t\tnearestItems = [element];\n\t\t\tminDistance = distance;\n\t\t} else if (distance === minDistance) {\n\t\t\t// Can have multiple items at the same distance in which case we sort by size\n\t\t\tnearestItems.push(element);\n\t\t}\n\t});\n\n\treturn nearestItems;\n}\n\n/**\n * Get a distance metric function for two points based on the\n * axis mode setting\n * @param {String} axis the axis mode. x|y|xy\n */\nfunction getDistanceMetricForAxis(axis) {\n\tvar useX = axis.indexOf('x') !== -1;\n\tvar useY = axis.indexOf('y') !== -1;\n\n\treturn function(pt1, pt2) {\n\t\tvar deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0;\n\t\tvar deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0;\n\t\treturn Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));\n\t};\n}\n\nfunction indexMode(chart, e, options) {\n\tvar position = getRelativePosition(e, chart);\n\t// Default axis for index mode is 'x' to match old behaviour\n\toptions.axis = options.axis || 'x';\n\tvar distanceMetric = getDistanceMetricForAxis(options.axis);\n\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);\n\tvar elements = [];\n\n\tif (!items.length) {\n\t\treturn [];\n\t}\n\n\tchart.data.datasets.forEach(function(dataset, datasetIndex) {\n\t\tif (chart.isDatasetVisible(datasetIndex)) {\n\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\tvar element = meta.data[items[0]._index];\n\n\t\t\t// don't count items that are skipped (null data)\n\t\t\tif (element && !element._view.skip) {\n\t\t\t\telements.push(element);\n\t\t\t}\n\t\t}\n\t});\n\n\treturn elements;\n}\n\n/**\n * @interface IInteractionOptions\n */\n/**\n * If true, only consider items that intersect the point\n * @name IInterfaceOptions#boolean\n * @type Boolean\n */\n\n/**\n * Contains interaction related functions\n * @namespace Chart.Interaction\n */\nmodule.exports = {\n\t// Helper function for different modes\n\tmodes: {\n\t\tsingle: function(chart, e) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\tvar elements = [];\n\n\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\telements.push(element);\n\t\t\t\t\treturn elements;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn elements.slice(0, 1);\n\t\t},\n\n\t\t/**\n\t\t * @function Chart.Interaction.modes.label\n\t\t * @deprecated since version 2.4.0\n\t\t * @todo remove at version 3\n\t\t * @private\n\t\t */\n\t\tlabel: indexMode,\n\n\t\t/**\n\t\t * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something\n\t\t * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item\n\t\t * @function Chart.Interaction.modes.index\n\t\t * @since v2.4.0\n\t\t * @param chart {chart} the chart we are returning items from\n\t\t * @param e {Event} the event we are find things at\n\t\t * @param options {IInteractionOptions} options to use during interaction\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\tindex: indexMode,\n\n\t\t/**\n\t\t * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something\n\t\t * If the options.intersect is false, we find the nearest item and return the items in that dataset\n\t\t * @function Chart.Interaction.modes.dataset\n\t\t * @param chart {chart} the chart we are returning items from\n\t\t * @param e {Event} the event we are find things at\n\t\t * @param options {IInteractionOptions} options to use during interaction\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\tdataset: function(chart, e, options) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\toptions.axis = options.axis || 'xy';\n\t\t\tvar distanceMetric = getDistanceMetricForAxis(options.axis);\n\t\t\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);\n\n\t\t\tif (items.length > 0) {\n\t\t\t\titems = chart.getDatasetMeta(items[0]._datasetIndex).data;\n\t\t\t}\n\n\t\t\treturn items;\n\t\t},\n\n\t\t/**\n\t\t * @function Chart.Interaction.modes.x-axis\n\t\t * @deprecated since version 2.4.0. Use index mode and intersect == true\n\t\t * @todo remove at version 3\n\t\t * @private\n\t\t */\n\t\t'x-axis': function(chart, e) {\n\t\t\treturn indexMode(chart, e, {intersect: false});\n\t\t},\n\n\t\t/**\n\t\t * Point mode returns all elements that hit test based on the event position\n\t\t * of the event\n\t\t * @function Chart.Interaction.modes.intersect\n\t\t * @param chart {chart} the chart we are returning items from\n\t\t * @param e {Event} the event we are find things at\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\tpoint: function(chart, e) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\treturn getIntersectItems(chart, position);\n\t\t},\n\n\t\t/**\n\t\t * nearest mode returns the element closest to the point\n\t\t * @function Chart.Interaction.modes.intersect\n\t\t * @param chart {chart} the chart we are returning items from\n\t\t * @param e {Event} the event we are find things at\n\t\t * @param options {IInteractionOptions} options to use\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\tnearest: function(chart, e, options) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\toptions.axis = options.axis || 'xy';\n\t\t\tvar distanceMetric = getDistanceMetricForAxis(options.axis);\n\t\t\tvar nearestItems = getNearestItems(chart, position, options.intersect, distanceMetric);\n\n\t\t\t// We have multiple items at the same distance from the event. Now sort by smallest\n\t\t\tif (nearestItems.length > 1) {\n\t\t\t\tnearestItems.sort(function(a, b) {\n\t\t\t\t\tvar sizeA = a.getArea();\n\t\t\t\t\tvar sizeB = b.getArea();\n\t\t\t\t\tvar ret = sizeA - sizeB;\n\n\t\t\t\t\tif (ret === 0) {\n\t\t\t\t\t\t// if equal sort by dataset index\n\t\t\t\t\t\tret = a._datasetIndex - b._datasetIndex;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ret;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Return only 1 item\n\t\t\treturn nearestItems.slice(0, 1);\n\t\t},\n\n\t\t/**\n\t\t * x mode returns the elements that hit-test at the current x coordinate\n\t\t * @function Chart.Interaction.modes.x\n\t\t * @param chart {chart} the chart we are returning items from\n\t\t * @param e {Event} the event we are find things at\n\t\t * @param options {IInteractionOptions} options to use\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\tx: function(chart, e, options) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\tvar items = [];\n\t\t\tvar intersectsItem = false;\n\n\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\tif (element.inXRange(position.x)) {\n\t\t\t\t\titems.push(element);\n\t\t\t\t}\n\n\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\tintersectsItem = true;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// If we want to trigger on an intersect and we don't have any items\n\t\t\t// that intersect the position, return nothing\n\t\t\tif (options.intersect && !intersectsItem) {\n\t\t\t\titems = [];\n\t\t\t}\n\t\t\treturn items;\n\t\t},\n\n\t\t/**\n\t\t * y mode returns the elements that hit-test at the current y coordinate\n\t\t * @function Chart.Interaction.modes.y\n\t\t * @param chart {chart} the chart we are returning items from\n\t\t * @param e {Event} the event we are find things at\n\t\t * @param options {IInteractionOptions} options to use\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\ty: function(chart, e, options) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\tvar items = [];\n\t\t\tvar intersectsItem = false;\n\n\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\tif (element.inYRange(position.y)) {\n\t\t\t\t\titems.push(element);\n\t\t\t\t}\n\n\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\tintersectsItem = true;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// If we want to trigger on an intersect and we don't have any items\n\t\t\t// that intersect the position, return nothing\n\t\t\tif (options.intersect && !intersectsItem) {\n\t\t\t\titems = [];\n\t\t\t}\n\t\t\treturn items;\n\t\t}\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjcwMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmludGVyYWN0aW9uLmpzPzlhNWEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IHJlbGF0aXZlIHBvc2l0aW9uIGZvciBhbiBldmVudFxuICogQHBhcmFtIHtFdmVudHxJRXZlbnR9IGV2ZW50IC0gVGhlIGV2ZW50IHRvIGdldCB0aGUgcG9zaXRpb24gZm9yXG4gKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIFRoZSBjaGFydFxuICogQHJldHVybnMge1BvaW50fSB0aGUgZXZlbnQgcG9zaXRpb25cbiAqL1xuZnVuY3Rpb24gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCkge1xuXHRpZiAoZS5uYXRpdmUpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0eDogZS54LFxuXHRcdFx0eTogZS55XG5cdFx0fTtcblx0fVxuXG5cdHJldHVybiBoZWxwZXJzLmdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byB0cmF2ZXJzZSBhbGwgb2YgdGhlIHZpc2libGUgZWxlbWVudHMgaW4gdGhlIGNoYXJ0XG4gKiBAcGFyYW0gY2hhcnQge2NoYXJ0fSB0aGUgY2hhcnRcbiAqIEBwYXJhbSBoYW5kbGVyIHtGdW5jdGlvbn0gdGhlIGNhbGxiYWNrIHRvIGV4ZWN1dGUgZm9yIGVhY2ggdmlzaWJsZSBpdGVtXG4gKi9cbmZ1bmN0aW9uIHBhcnNlVmlzaWJsZUl0ZW1zKGNoYXJ0LCBoYW5kbGVyKSB7XG5cdHZhciBkYXRhc2V0cyA9IGNoYXJ0LmRhdGEuZGF0YXNldHM7XG5cdHZhciBtZXRhLCBpLCBqLCBpbGVuLCBqbGVuO1xuXG5cdGZvciAoaSA9IDAsIGlsZW4gPSBkYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRpZiAoIWNoYXJ0LmlzRGF0YXNldFZpc2libGUoaSkpIHtcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblxuXHRcdG1ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YShpKTtcblx0XHRmb3IgKGogPSAwLCBqbGVuID0gbWV0YS5kYXRhLmxlbmd0aDsgaiA8IGpsZW47ICsraikge1xuXHRcdFx0dmFyIGVsZW1lbnQgPSBtZXRhLmRhdGFbal07XG5cdFx0XHRpZiAoIWVsZW1lbnQuX3ZpZXcuc2tpcCkge1xuXHRcdFx0XHRoYW5kbGVyKGVsZW1lbnQpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBnZXQgdGhlIGl0ZW1zIHRoYXQgaW50ZXJzZWN0IHRoZSBldmVudCBwb3NpdGlvblxuICogQHBhcmFtIGl0ZW1zIHtDaGFydEVsZW1lbnRbXX0gZWxlbWVudHMgdG8gZmlsdGVyXG4gKiBAcGFyYW0gcG9zaXRpb24ge1BvaW50fSB0aGUgcG9pbnQgdG8gYmUgbmVhcmVzdCB0b1xuICogQHJldHVybiB7Q2hhcnRFbGVtZW50W119IHRoZSBuZWFyZXN0IGl0ZW1zXG4gKi9cbmZ1bmN0aW9uIGdldEludGVyc2VjdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbikge1xuXHR2YXIgZWxlbWVudHMgPSBbXTtcblxuXHRwYXJzZVZpc2libGVJdGVtcyhjaGFydCwgZnVuY3Rpb24oZWxlbWVudCkge1xuXHRcdGlmIChlbGVtZW50LmluUmFuZ2UocG9zaXRpb24ueCwgcG9zaXRpb24ueSkpIHtcblx0XHRcdGVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG5cdFx0fVxuXHR9KTtcblxuXHRyZXR1cm4gZWxlbWVudHM7XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGdldCB0aGUgaXRlbXMgbmVhcmVzdCB0byB0aGUgZXZlbnQgcG9zaXRpb24gY29uc2lkZXJpbmcgYWxsIHZpc2libGUgaXRlbXMgaW4gdGVoIGNoYXJ0XG4gKiBAcGFyYW0gY2hhcnQge0NoYXJ0fSB0aGUgY2hhcnQgdG8gbG9vayBhdCBlbGVtZW50cyBmcm9tXG4gKiBAcGFyYW0gcG9zaXRpb24ge1BvaW50fSB0aGUgcG9pbnQgdG8gYmUgbmVhcmVzdCB0b1xuICogQHBhcmFtIGludGVyc2VjdCB7Qm9vbGVhbn0gaWYgdHJ1ZSwgb25seSBjb25zaWRlciBpdGVtcyB0aGF0IGludGVyc2VjdCB0aGUgcG9zaXRpb25cbiAqIEBwYXJhbSBkaXN0YW5jZU1ldHJpYyB7RnVuY3Rpb259IGZ1bmN0aW9uIHRvIHByb3ZpZGUgdGhlIGRpc3RhbmNlIGJldHdlZW4gcG9pbnRzXG4gKiBAcmV0dXJuIHtDaGFydEVsZW1lbnRbXX0gdGhlIG5lYXJlc3QgaXRlbXNcbiAqL1xuZnVuY3Rpb24gZ2V0TmVhcmVzdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgaW50ZXJzZWN0LCBkaXN0YW5jZU1ldHJpYykge1xuXHR2YXIgbWluRGlzdGFuY2UgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG5cdHZhciBuZWFyZXN0SXRlbXMgPSBbXTtcblxuXHRwYXJzZVZpc2libGVJdGVtcyhjaGFydCwgZnVuY3Rpb24oZWxlbWVudCkge1xuXHRcdGlmIChpbnRlcnNlY3QgJiYgIWVsZW1lbnQuaW5SYW5nZShwb3NpdGlvbi54LCBwb3NpdGlvbi55KSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBjZW50ZXIgPSBlbGVtZW50LmdldENlbnRlclBvaW50KCk7XG5cdFx0dmFyIGRpc3RhbmNlID0gZGlzdGFuY2VNZXRyaWMocG9zaXRpb24sIGNlbnRlcik7XG5cblx0XHRpZiAoZGlzdGFuY2UgPCBtaW5EaXN0YW5jZSkge1xuXHRcdFx0bmVhcmVzdEl0ZW1zID0gW2VsZW1lbnRdO1xuXHRcdFx0bWluRGlzdGFuY2UgPSBkaXN0YW5jZTtcblx0XHR9IGVsc2UgaWYgKGRpc3RhbmNlID09PSBtaW5EaXN0YW5jZSkge1xuXHRcdFx0Ly8gQ2FuIGhhdmUgbXVsdGlwbGUgaXRlbXMgYXQgdGhlIHNhbWUgZGlzdGFuY2UgaW4gd2hpY2ggY2FzZSB3ZSBzb3J0IGJ5IHNpemVcblx0XHRcdG5lYXJlc3RJdGVtcy5wdXNoKGVsZW1lbnQpO1xuXHRcdH1cblx0fSk7XG5cblx0cmV0dXJuIG5lYXJlc3RJdGVtcztcbn1cblxuLyoqXG4gKiBHZXQgYSBkaXN0YW5jZSBtZXRyaWMgZnVuY3Rpb24gZm9yIHR3byBwb2ludHMgYmFzZWQgb24gdGhlXG4gKiBheGlzIG1vZGUgc2V0dGluZ1xuICogQHBhcmFtIHtTdHJpbmd9IGF4aXMgdGhlIGF4aXMgbW9kZS4geHx5fHh5XG4gKi9cbmZ1bmN0aW9uIGdldERpc3RhbmNlTWV0cmljRm9yQXhpcyhheGlzKSB7XG5cdHZhciB1c2VYID0gYXhpcy5pbmRleE9mKCd4JykgIT09IC0xO1xuXHR2YXIgdXNlWSA9IGF4aXMuaW5kZXhPZigneScpICE9PSAtMTtcblxuXHRyZXR1cm4gZnVuY3Rpb24ocHQxLCBwdDIpIHtcblx0XHR2YXIgZGVsdGFYID0gdXNlWCA/IE1hdGguYWJzKHB0MS54IC0gcHQyLngpIDogMDtcblx0XHR2YXIgZGVsdGFZID0gdXNlWSA/IE1hdGguYWJzKHB0MS55IC0gcHQyLnkpIDogMDtcblx0XHRyZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KGRlbHRhWCwgMikgKyBNYXRoLnBvdyhkZWx0YVksIDIpKTtcblx0fTtcbn1cblxuZnVuY3Rpb24gaW5kZXhNb2RlKGNoYXJ0LCBlLCBvcHRpb25zKSB7XG5cdHZhciBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xuXHQvLyBEZWZhdWx0IGF4aXMgZm9yIGluZGV4IG1vZGUgaXMgJ3gnIHRvIG1hdGNoIG9sZCBiZWhhdmlvdXJcblx0b3B0aW9ucy5heGlzID0gb3B0aW9ucy5heGlzIHx8ICd4Jztcblx0dmFyIGRpc3RhbmNlTWV0cmljID0gZ2V0RGlzdGFuY2VNZXRyaWNGb3JBeGlzKG9wdGlvbnMuYXhpcyk7XG5cdHZhciBpdGVtcyA9IG9wdGlvbnMuaW50ZXJzZWN0ID8gZ2V0SW50ZXJzZWN0SXRlbXMoY2hhcnQsIHBvc2l0aW9uKSA6IGdldE5lYXJlc3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIGZhbHNlLCBkaXN0YW5jZU1ldHJpYyk7XG5cdHZhciBlbGVtZW50cyA9IFtdO1xuXG5cdGlmICghaXRlbXMubGVuZ3RoKSB7XG5cdFx0cmV0dXJuIFtdO1xuXHR9XG5cblx0Y2hhcnQuZGF0YS5kYXRhc2V0cy5mb3JFYWNoKGZ1bmN0aW9uKGRhdGFzZXQsIGRhdGFzZXRJbmRleCkge1xuXHRcdGlmIChjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGRhdGFzZXRJbmRleCkpIHtcblx0XHRcdHZhciBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcblx0XHRcdHZhciBlbGVtZW50ID0gbWV0YS5kYXRhW2l0ZW1zWzBdLl9pbmRleF07XG5cblx0XHRcdC8vIGRvbid0IGNvdW50IGl0ZW1zIHRoYXQgYXJlIHNraXBwZWQgKG51bGwgZGF0YSlcblx0XHRcdGlmIChlbGVtZW50ICYmICFlbGVtZW50Ll92aWV3LnNraXApIHtcblx0XHRcdFx0ZWxlbWVudHMucHVzaChlbGVtZW50KTtcblx0XHRcdH1cblx0XHR9XG5cdH0pO1xuXG5cdHJldHVybiBlbGVtZW50cztcbn1cblxuLyoqXG4gKiBAaW50ZXJmYWNlIElJbnRlcmFjdGlvbk9wdGlvbnNcbiAqL1xuLyoqXG4gKiBJZiB0cnVlLCBvbmx5IGNvbnNpZGVyIGl0ZW1zIHRoYXQgaW50ZXJzZWN0IHRoZSBwb2ludFxuICogQG5hbWUgSUludGVyZmFjZU9wdGlvbnMjYm9vbGVhblxuICogQHR5cGUgQm9vbGVhblxuICovXG5cbi8qKlxuICogQ29udGFpbnMgaW50ZXJhY3Rpb24gcmVsYXRlZCBmdW5jdGlvbnNcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuSW50ZXJhY3Rpb25cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSB7XG5cdC8vIEhlbHBlciBmdW5jdGlvbiBmb3IgZGlmZmVyZW50IG1vZGVzXG5cdG1vZGVzOiB7XG5cdFx0c2luZ2xlOiBmdW5jdGlvbihjaGFydCwgZSkge1xuXHRcdFx0dmFyIHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XG5cdFx0XHR2YXIgZWxlbWVudHMgPSBbXTtcblxuXHRcdFx0cGFyc2VWaXNpYmxlSXRlbXMoY2hhcnQsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcblx0XHRcdFx0aWYgKGVsZW1lbnQuaW5SYW5nZShwb3NpdGlvbi54LCBwb3NpdGlvbi55KSkge1xuXHRcdFx0XHRcdGVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG5cdFx0XHRcdFx0cmV0dXJuIGVsZW1lbnRzO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0cmV0dXJuIGVsZW1lbnRzLnNsaWNlKDAsIDEpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAZnVuY3Rpb24gQ2hhcnQuSW50ZXJhY3Rpb24ubW9kZXMubGFiZWxcblx0XHQgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNC4wXG5cdFx0ICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0bGFiZWw6IGluZGV4TW9kZSxcblxuXHRcdC8qKlxuXHRcdCAqIFJldHVybnMgaXRlbXMgYXQgdGhlIHNhbWUgaW5kZXguIElmIHRoZSBvcHRpb25zLmludGVyc2VjdCBwYXJhbWV0ZXIgaXMgdHJ1ZSwgd2Ugb25seSByZXR1cm4gaXRlbXMgaWYgd2UgaW50ZXJzZWN0IHNvbWV0aGluZ1xuXHRcdCAqIElmIHRoZSBvcHRpb25zLmludGVyc2VjdCBtb2RlIGlzIGZhbHNlLCB3ZSBmaW5kIHRoZSBuZWFyZXN0IGl0ZW0gYW5kIHJldHVybiB0aGUgaXRlbXMgYXQgdGhlIHNhbWUgaW5kZXggYXMgdGhhdCBpdGVtXG5cdFx0ICogQGZ1bmN0aW9uIENoYXJ0LkludGVyYWN0aW9uLm1vZGVzLmluZGV4XG5cdFx0ICogQHNpbmNlIHYyLjQuMFxuXHRcdCAqIEBwYXJhbSBjaGFydCB7Y2hhcnR9IHRoZSBjaGFydCB3ZSBhcmUgcmV0dXJuaW5nIGl0ZW1zIGZyb21cblx0XHQgKiBAcGFyYW0gZSB7RXZlbnR9IHRoZSBldmVudCB3ZSBhcmUgZmluZCB0aGluZ3MgYXRcblx0XHQgKiBAcGFyYW0gb3B0aW9ucyB7SUludGVyYWN0aW9uT3B0aW9uc30gb3B0aW9ucyB0byB1c2UgZHVyaW5nIGludGVyYWN0aW9uXG5cdFx0ICogQHJldHVybiB7Q2hhcnQuRWxlbWVudFtdfSBBcnJheSBvZiBlbGVtZW50cyB0aGF0IGFyZSB1bmRlciB0aGUgcG9pbnQuIElmIG5vbmUgYXJlIGZvdW5kLCBhbiBlbXB0eSBhcnJheSBpcyByZXR1cm5lZFxuXHRcdCAqL1xuXHRcdGluZGV4OiBpbmRleE1vZGUsXG5cblx0XHQvKipcblx0XHQgKiBSZXR1cm5zIGl0ZW1zIGluIHRoZSBzYW1lIGRhdGFzZXQuIElmIHRoZSBvcHRpb25zLmludGVyc2VjdCBwYXJhbWV0ZXIgaXMgdHJ1ZSwgd2Ugb25seSByZXR1cm4gaXRlbXMgaWYgd2UgaW50ZXJzZWN0IHNvbWV0aGluZ1xuXHRcdCAqIElmIHRoZSBvcHRpb25zLmludGVyc2VjdCBpcyBmYWxzZSwgd2UgZmluZCB0aGUgbmVhcmVzdCBpdGVtIGFuZCByZXR1cm4gdGhlIGl0ZW1zIGluIHRoYXQgZGF0YXNldFxuXHRcdCAqIEBmdW5jdGlvbiBDaGFydC5JbnRlcmFjdGlvbi5tb2Rlcy5kYXRhc2V0XG5cdFx0ICogQHBhcmFtIGNoYXJ0IHtjaGFydH0gdGhlIGNoYXJ0IHdlIGFyZSByZXR1cm5pbmcgaXRlbXMgZnJvbVxuXHRcdCAqIEBwYXJhbSBlIHtFdmVudH0gdGhlIGV2ZW50IHdlIGFyZSBmaW5kIHRoaW5ncyBhdFxuXHRcdCAqIEBwYXJhbSBvcHRpb25zIHtJSW50ZXJhY3Rpb25PcHRpb25zfSBvcHRpb25zIHRvIHVzZSBkdXJpbmcgaW50ZXJhY3Rpb25cblx0XHQgKiBAcmV0dXJuIHtDaGFydC5FbGVtZW50W119IEFycmF5IG9mIGVsZW1lbnRzIHRoYXQgYXJlIHVuZGVyIHRoZSBwb2ludC4gSWYgbm9uZSBhcmUgZm91bmQsIGFuIGVtcHR5IGFycmF5IGlzIHJldHVybmVkXG5cdFx0ICovXG5cdFx0ZGF0YXNldDogZnVuY3Rpb24oY2hhcnQsIGUsIG9wdGlvbnMpIHtcblx0XHRcdHZhciBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xuXHRcdFx0b3B0aW9ucy5heGlzID0gb3B0aW9ucy5heGlzIHx8ICd4eSc7XG5cdFx0XHR2YXIgZGlzdGFuY2VNZXRyaWMgPSBnZXREaXN0YW5jZU1ldHJpY0ZvckF4aXMob3B0aW9ucy5heGlzKTtcblx0XHRcdHZhciBpdGVtcyA9IG9wdGlvbnMuaW50ZXJzZWN0ID8gZ2V0SW50ZXJzZWN0SXRlbXMoY2hhcnQsIHBvc2l0aW9uKSA6IGdldE5lYXJlc3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIGZhbHNlLCBkaXN0YW5jZU1ldHJpYyk7XG5cblx0XHRcdGlmIChpdGVtcy5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdGl0ZW1zID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoaXRlbXNbMF0uX2RhdGFzZXRJbmRleCkuZGF0YTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGl0ZW1zO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAZnVuY3Rpb24gQ2hhcnQuSW50ZXJhY3Rpb24ubW9kZXMueC1heGlzXG5cdFx0ICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjQuMC4gVXNlIGluZGV4IG1vZGUgYW5kIGludGVyc2VjdCA9PSB0cnVlXG5cdFx0ICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0J3gtYXhpcyc6IGZ1bmN0aW9uKGNoYXJ0LCBlKSB7XG5cdFx0XHRyZXR1cm4gaW5kZXhNb2RlKGNoYXJ0LCBlLCB7aW50ZXJzZWN0OiBmYWxzZX0pO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBQb2ludCBtb2RlIHJldHVybnMgYWxsIGVsZW1lbnRzIHRoYXQgaGl0IHRlc3QgYmFzZWQgb24gdGhlIGV2ZW50IHBvc2l0aW9uXG5cdFx0ICogb2YgdGhlIGV2ZW50XG5cdFx0ICogQGZ1bmN0aW9uIENoYXJ0LkludGVyYWN0aW9uLm1vZGVzLmludGVyc2VjdFxuXHRcdCAqIEBwYXJhbSBjaGFydCB7Y2hhcnR9IHRoZSBjaGFydCB3ZSBhcmUgcmV0dXJuaW5nIGl0ZW1zIGZyb21cblx0XHQgKiBAcGFyYW0gZSB7RXZlbnR9IHRoZSBldmVudCB3ZSBhcmUgZmluZCB0aGluZ3MgYXRcblx0XHQgKiBAcmV0dXJuIHtDaGFydC5FbGVtZW50W119IEFycmF5IG9mIGVsZW1lbnRzIHRoYXQgYXJlIHVuZGVyIHRoZSBwb2ludC4gSWYgbm9uZSBhcmUgZm91bmQsIGFuIGVtcHR5IGFycmF5IGlzIHJldHVybmVkXG5cdFx0ICovXG5cdFx0cG9pbnQ6IGZ1bmN0aW9uKGNoYXJ0LCBlKSB7XG5cdFx0XHR2YXIgcG9zaXRpb24gPSBnZXRSZWxhdGl2ZVBvc2l0aW9uKGUsIGNoYXJ0KTtcblx0XHRcdHJldHVybiBnZXRJbnRlcnNlY3RJdGVtcyhjaGFydCwgcG9zaXRpb24pO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBuZWFyZXN0IG1vZGUgcmV0dXJucyB0aGUgZWxlbWVudCBjbG9zZXN0IHRvIHRoZSBwb2ludFxuXHRcdCAqIEBmdW5jdGlvbiBDaGFydC5JbnRlcmFjdGlvbi5tb2Rlcy5pbnRlcnNlY3Rcblx0XHQgKiBAcGFyYW0gY2hhcnQge2NoYXJ0fSB0aGUgY2hhcnQgd2UgYXJlIHJldHVybmluZyBpdGVtcyBmcm9tXG5cdFx0ICogQHBhcmFtIGUge0V2ZW50fSB0aGUgZXZlbnQgd2UgYXJlIGZpbmQgdGhpbmdzIGF0XG5cdFx0ICogQHBhcmFtIG9wdGlvbnMge0lJbnRlcmFjdGlvbk9wdGlvbnN9IG9wdGlvbnMgdG8gdXNlXG5cdFx0ICogQHJldHVybiB7Q2hhcnQuRWxlbWVudFtdfSBBcnJheSBvZiBlbGVtZW50cyB0aGF0IGFyZSB1bmRlciB0aGUgcG9pbnQuIElmIG5vbmUgYXJlIGZvdW5kLCBhbiBlbXB0eSBhcnJheSBpcyByZXR1cm5lZFxuXHRcdCAqL1xuXHRcdG5lYXJlc3Q6IGZ1bmN0aW9uKGNoYXJ0LCBlLCBvcHRpb25zKSB7XG5cdFx0XHR2YXIgcG9zaXRpb24gPSBnZXRSZWxhdGl2ZVBvc2l0aW9uKGUsIGNoYXJ0KTtcblx0XHRcdG9wdGlvbnMuYXhpcyA9IG9wdGlvbnMuYXhpcyB8fCAneHknO1xuXHRcdFx0dmFyIGRpc3RhbmNlTWV0cmljID0gZ2V0RGlzdGFuY2VNZXRyaWNGb3JBeGlzKG9wdGlvbnMuYXhpcyk7XG5cdFx0XHR2YXIgbmVhcmVzdEl0ZW1zID0gZ2V0TmVhcmVzdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgb3B0aW9ucy5pbnRlcnNlY3QsIGRpc3RhbmNlTWV0cmljKTtcblxuXHRcdFx0Ly8gV2UgaGF2ZSBtdWx0aXBsZSBpdGVtcyBhdCB0aGUgc2FtZSBkaXN0YW5jZSBmcm9tIHRoZSBldmVudC4gTm93IHNvcnQgYnkgc21hbGxlc3Rcblx0XHRcdGlmIChuZWFyZXN0SXRlbXMubGVuZ3RoID4gMSkge1xuXHRcdFx0XHRuZWFyZXN0SXRlbXMuc29ydChmdW5jdGlvbihhLCBiKSB7XG5cdFx0XHRcdFx0dmFyIHNpemVBID0gYS5nZXRBcmVhKCk7XG5cdFx0XHRcdFx0dmFyIHNpemVCID0gYi5nZXRBcmVhKCk7XG5cdFx0XHRcdFx0dmFyIHJldCA9IHNpemVBIC0gc2l6ZUI7XG5cblx0XHRcdFx0XHRpZiAocmV0ID09PSAwKSB7XG5cdFx0XHRcdFx0XHQvLyBpZiBlcXVhbCBzb3J0IGJ5IGRhdGFzZXQgaW5kZXhcblx0XHRcdFx0XHRcdHJldCA9IGEuX2RhdGFzZXRJbmRleCAtIGIuX2RhdGFzZXRJbmRleDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUmV0dXJuIG9ubHkgMSBpdGVtXG5cdFx0XHRyZXR1cm4gbmVhcmVzdEl0ZW1zLnNsaWNlKDAsIDEpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiB4IG1vZGUgcmV0dXJucyB0aGUgZWxlbWVudHMgdGhhdCBoaXQtdGVzdCBhdCB0aGUgY3VycmVudCB4IGNvb3JkaW5hdGVcblx0XHQgKiBAZnVuY3Rpb24gQ2hhcnQuSW50ZXJhY3Rpb24ubW9kZXMueFxuXHRcdCAqIEBwYXJhbSBjaGFydCB7Y2hhcnR9IHRoZSBjaGFydCB3ZSBhcmUgcmV0dXJuaW5nIGl0ZW1zIGZyb21cblx0XHQgKiBAcGFyYW0gZSB7RXZlbnR9IHRoZSBldmVudCB3ZSBhcmUgZmluZCB0aGluZ3MgYXRcblx0XHQgKiBAcGFyYW0gb3B0aW9ucyB7SUludGVyYWN0aW9uT3B0aW9uc30gb3B0aW9ucyB0byB1c2Vcblx0XHQgKiBAcmV0dXJuIHtDaGFydC5FbGVtZW50W119IEFycmF5IG9mIGVsZW1lbnRzIHRoYXQgYXJlIHVuZGVyIHRoZSBwb2ludC4gSWYgbm9uZSBhcmUgZm91bmQsIGFuIGVtcHR5IGFycmF5IGlzIHJldHVybmVkXG5cdFx0ICovXG5cdFx0eDogZnVuY3Rpb24oY2hhcnQsIGUsIG9wdGlvbnMpIHtcblx0XHRcdHZhciBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xuXHRcdFx0dmFyIGl0ZW1zID0gW107XG5cdFx0XHR2YXIgaW50ZXJzZWN0c0l0ZW0gPSBmYWxzZTtcblxuXHRcdFx0cGFyc2VWaXNpYmxlSXRlbXMoY2hhcnQsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcblx0XHRcdFx0aWYgKGVsZW1lbnQuaW5YUmFuZ2UocG9zaXRpb24ueCkpIHtcblx0XHRcdFx0XHRpdGVtcy5wdXNoKGVsZW1lbnQpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGVsZW1lbnQuaW5SYW5nZShwb3NpdGlvbi54LCBwb3NpdGlvbi55KSkge1xuXHRcdFx0XHRcdGludGVyc2VjdHNJdGVtID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdC8vIElmIHdlIHdhbnQgdG8gdHJpZ2dlciBvbiBhbiBpbnRlcnNlY3QgYW5kIHdlIGRvbid0IGhhdmUgYW55IGl0ZW1zXG5cdFx0XHQvLyB0aGF0IGludGVyc2VjdCB0aGUgcG9zaXRpb24sIHJldHVybiBub3RoaW5nXG5cdFx0XHRpZiAob3B0aW9ucy5pbnRlcnNlY3QgJiYgIWludGVyc2VjdHNJdGVtKSB7XG5cdFx0XHRcdGl0ZW1zID0gW107XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gaXRlbXM7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIHkgbW9kZSByZXR1cm5zIHRoZSBlbGVtZW50cyB0aGF0IGhpdC10ZXN0IGF0IHRoZSBjdXJyZW50IHkgY29vcmRpbmF0ZVxuXHRcdCAqIEBmdW5jdGlvbiBDaGFydC5JbnRlcmFjdGlvbi5tb2Rlcy55XG5cdFx0ICogQHBhcmFtIGNoYXJ0IHtjaGFydH0gdGhlIGNoYXJ0IHdlIGFyZSByZXR1cm5pbmcgaXRlbXMgZnJvbVxuXHRcdCAqIEBwYXJhbSBlIHtFdmVudH0gdGhlIGV2ZW50IHdlIGFyZSBmaW5kIHRoaW5ncyBhdFxuXHRcdCAqIEBwYXJhbSBvcHRpb25zIHtJSW50ZXJhY3Rpb25PcHRpb25zfSBvcHRpb25zIHRvIHVzZVxuXHRcdCAqIEByZXR1cm4ge0NoYXJ0LkVsZW1lbnRbXX0gQXJyYXkgb2YgZWxlbWVudHMgdGhhdCBhcmUgdW5kZXIgdGhlIHBvaW50LiBJZiBub25lIGFyZSBmb3VuZCwgYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWRcblx0XHQgKi9cblx0XHR5OiBmdW5jdGlvbihjaGFydCwgZSwgb3B0aW9ucykge1xuXHRcdFx0dmFyIHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XG5cdFx0XHR2YXIgaXRlbXMgPSBbXTtcblx0XHRcdHZhciBpbnRlcnNlY3RzSXRlbSA9IGZhbHNlO1xuXG5cdFx0XHRwYXJzZVZpc2libGVJdGVtcyhjaGFydCwgZnVuY3Rpb24oZWxlbWVudCkge1xuXHRcdFx0XHRpZiAoZWxlbWVudC5pbllSYW5nZShwb3NpdGlvbi55KSkge1xuXHRcdFx0XHRcdGl0ZW1zLnB1c2goZWxlbWVudCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoZWxlbWVudC5pblJhbmdlKHBvc2l0aW9uLngsIHBvc2l0aW9uLnkpKSB7XG5cdFx0XHRcdFx0aW50ZXJzZWN0c0l0ZW0gPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gSWYgd2Ugd2FudCB0byB0cmlnZ2VyIG9uIGFuIGludGVyc2VjdCBhbmQgd2UgZG9uJ3QgaGF2ZSBhbnkgaXRlbXNcblx0XHRcdC8vIHRoYXQgaW50ZXJzZWN0IHRoZSBwb3NpdGlvbiwgcmV0dXJuIG5vdGhpbmdcblx0XHRcdGlmIChvcHRpb25zLmludGVyc2VjdCAmJiAhaW50ZXJzZWN0c0l0ZW0pIHtcblx0XHRcdFx0aXRlbXMgPSBbXTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBpdGVtcztcblx0XHR9XG5cdH1cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///6701\n")},6705:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\nfunction filterByPosition(array, position) {\n\treturn helpers.where(array, function(v) {\n\t\treturn v.position === position;\n\t});\n}\n\nfunction sortByWeight(array, reverse) {\n\tarray.forEach(function(v, i) {\n\t\tv._tmpIndex_ = i;\n\t\treturn v;\n\t});\n\tarray.sort(function(a, b) {\n\t\tvar v0 = reverse ? b : a;\n\t\tvar v1 = reverse ? a : b;\n\t\treturn v0.weight === v1.weight ?\n\t\t\tv0._tmpIndex_ - v1._tmpIndex_ :\n\t\t\tv0.weight - v1.weight;\n\t});\n\tarray.forEach(function(v) {\n\t\tdelete v._tmpIndex_;\n\t});\n}\n\n/**\n * @interface ILayoutItem\n * @prop {String} position - The position of the item in the chart layout. Possible values are\n * 'left', 'top', 'right', 'bottom', and 'chartArea'\n * @prop {Number} weight - The weight used to sort the item. Higher weights are further away from the chart area\n * @prop {Boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down\n * @prop {Function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)\n * @prop {Function} update - Takes two parameters: width and height. Returns size of item\n * @prop {Function} getPadding -  Returns an object with padding on the edges\n * @prop {Number} width - Width of item. Must be valid after update()\n * @prop {Number} height - Height of item. Must be valid after update()\n * @prop {Number} left - Left edge of the item. Set by layout system and cannot be used in update\n * @prop {Number} top - Top edge of the item. Set by layout system and cannot be used in update\n * @prop {Number} right - Right edge of the item. Set by layout system and cannot be used in update\n * @prop {Number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update\n */\n\n// The layout service is very self explanatory.  It's responsible for the layout within a chart.\n// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need\n// It is this service's responsibility of carrying out that layout.\nmodule.exports = {\n\tdefaults: {},\n\n\t/**\n\t * Register a box to a chart.\n\t * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.\n\t * @param {Chart} chart - the chart to use\n\t * @param {ILayoutItem} item - the item to add to be layed out\n\t */\n\taddBox: function(chart, item) {\n\t\tif (!chart.boxes) {\n\t\t\tchart.boxes = [];\n\t\t}\n\n\t\t// initialize item with default values\n\t\titem.fullWidth = item.fullWidth || false;\n\t\titem.position = item.position || 'top';\n\t\titem.weight = item.weight || 0;\n\n\t\tchart.boxes.push(item);\n\t},\n\n\t/**\n\t * Remove a layoutItem from a chart\n\t * @param {Chart} chart - the chart to remove the box from\n\t * @param {Object} layoutItem - the item to remove from the layout\n\t */\n\tremoveBox: function(chart, layoutItem) {\n\t\tvar index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;\n\t\tif (index !== -1) {\n\t\t\tchart.boxes.splice(index, 1);\n\t\t}\n\t},\n\n\t/**\n\t * Sets (or updates) options on the given `item`.\n\t * @param {Chart} chart - the chart in which the item lives (or will be added to)\n\t * @param {Object} item - the item to configure with the given options\n\t * @param {Object} options - the new item options.\n\t */\n\tconfigure: function(chart, item, options) {\n\t\tvar props = ['fullWidth', 'position', 'weight'];\n\t\tvar ilen = props.length;\n\t\tvar i = 0;\n\t\tvar prop;\n\n\t\tfor (; i < ilen; ++i) {\n\t\t\tprop = props[i];\n\t\t\tif (options.hasOwnProperty(prop)) {\n\t\t\t\titem[prop] = options[prop];\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Fits boxes of the given chart into the given size by having each box measure itself\n\t * then running a fitting algorithm\n\t * @param {Chart} chart - the chart\n\t * @param {Number} width - the width to fit into\n\t * @param {Number} height - the height to fit into\n\t */\n\tupdate: function(chart, width, height) {\n\t\tif (!chart) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar layoutOptions = chart.options.layout || {};\n\t\tvar padding = helpers.options.toPadding(layoutOptions.padding);\n\t\tvar leftPadding = padding.left;\n\t\tvar rightPadding = padding.right;\n\t\tvar topPadding = padding.top;\n\t\tvar bottomPadding = padding.bottom;\n\n\t\tvar leftBoxes = filterByPosition(chart.boxes, 'left');\n\t\tvar rightBoxes = filterByPosition(chart.boxes, 'right');\n\t\tvar topBoxes = filterByPosition(chart.boxes, 'top');\n\t\tvar bottomBoxes = filterByPosition(chart.boxes, 'bottom');\n\t\tvar chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea');\n\n\t\t// Sort boxes by weight. A higher weight is further away from the chart area\n\t\tsortByWeight(leftBoxes, true);\n\t\tsortByWeight(rightBoxes, false);\n\t\tsortByWeight(topBoxes, true);\n\t\tsortByWeight(bottomBoxes, false);\n\n\t\t// Essentially we now have any number of boxes on each of the 4 sides.\n\t\t// Our canvas looks like the following.\n\t\t// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and\n\t\t// B1 is the bottom axis\n\t\t// There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays\n\t\t// These locations are single-box locations only, when trying to register a chartArea location that is already taken,\n\t\t// an error will be thrown.\n\t\t//\n\t\t// |----------------------------------------------------|\n\t\t// |                  T1 (Full Width)                   |\n\t\t// |----------------------------------------------------|\n\t\t// |    |    |                 T2                  |    |\n\t\t// |    |----|-------------------------------------|----|\n\t\t// |    |    | C1 |                           | C2 |    |\n\t\t// |    |    |----|                           |----|    |\n\t\t// |    |    |                                     |    |\n\t\t// | L1 | L2 |           ChartArea (C0)            | R1 |\n\t\t// |    |    |                                     |    |\n\t\t// |    |    |----|                           |----|    |\n\t\t// |    |    | C3 |                           | C4 |    |\n\t\t// |    |----|-------------------------------------|----|\n\t\t// |    |    |                 B1                  |    |\n\t\t// |----------------------------------------------------|\n\t\t// |                  B2 (Full Width)                   |\n\t\t// |----------------------------------------------------|\n\t\t//\n\t\t// What we do to find the best sizing, we do the following\n\t\t// 1. Determine the minimum size of the chart area.\n\t\t// 2. Split the remaining width equally between each vertical axis\n\t\t// 3. Split the remaining height equally between each horizontal axis\n\t\t// 4. Give each layout the maximum size it can be. The layout will return it's minimum size\n\t\t// 5. Adjust the sizes of each axis based on it's minimum reported size.\n\t\t// 6. Refit each axis\n\t\t// 7. Position each axis in the final location\n\t\t// 8. Tell the chart the final location of the chart area\n\t\t// 9. Tell any axes that overlay the chart area the positions of the chart area\n\n\t\t// Step 1\n\t\tvar chartWidth = width - leftPadding - rightPadding;\n\t\tvar chartHeight = height - topPadding - bottomPadding;\n\t\tvar chartAreaWidth = chartWidth / 2; // min 50%\n\t\tvar chartAreaHeight = chartHeight / 2; // min 50%\n\n\t\t// Step 2\n\t\tvar verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);\n\n\t\t// Step 3\n\t\tvar horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);\n\n\t\t// Step 4\n\t\tvar maxChartAreaWidth = chartWidth;\n\t\tvar maxChartAreaHeight = chartHeight;\n\t\tvar minBoxSizes = [];\n\n\t\tfunction getMinimumBoxSize(box) {\n\t\t\tvar minSize;\n\t\t\tvar isHorizontal = box.isHorizontal();\n\n\t\t\tif (isHorizontal) {\n\t\t\t\tminSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);\n\t\t\t\tmaxChartAreaHeight -= minSize.height;\n\t\t\t} else {\n\t\t\t\tminSize = box.update(verticalBoxWidth, maxChartAreaHeight);\n\t\t\t\tmaxChartAreaWidth -= minSize.width;\n\t\t\t}\n\n\t\t\tminBoxSizes.push({\n\t\t\t\thorizontal: isHorizontal,\n\t\t\t\tminSize: minSize,\n\t\t\t\tbox: box,\n\t\t\t});\n\t\t}\n\n\t\thelpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);\n\n\t\t// If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478)\n\t\tvar maxHorizontalLeftPadding = 0;\n\t\tvar maxHorizontalRightPadding = 0;\n\t\tvar maxVerticalTopPadding = 0;\n\t\tvar maxVerticalBottomPadding = 0;\n\n\t\thelpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) {\n\t\t\tif (horizontalBox.getPadding) {\n\t\t\t\tvar boxPadding = horizontalBox.getPadding();\n\t\t\t\tmaxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left);\n\t\t\t\tmaxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right);\n\t\t\t}\n\t\t});\n\n\t\thelpers.each(leftBoxes.concat(rightBoxes), function(verticalBox) {\n\t\t\tif (verticalBox.getPadding) {\n\t\t\t\tvar boxPadding = verticalBox.getPadding();\n\t\t\t\tmaxVerticalTopPadding = Math.max(maxVerticalTopPadding, boxPadding.top);\n\t\t\t\tmaxVerticalBottomPadding = Math.max(maxVerticalBottomPadding, boxPadding.bottom);\n\t\t\t}\n\t\t});\n\n\t\t// At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could\n\t\t// be if the axes are drawn at their minimum sizes.\n\t\t// Steps 5 & 6\n\t\tvar totalLeftBoxesWidth = leftPadding;\n\t\tvar totalRightBoxesWidth = rightPadding;\n\t\tvar totalTopBoxesHeight = topPadding;\n\t\tvar totalBottomBoxesHeight = bottomPadding;\n\n\t\t// Function to fit a box\n\t\tfunction fitBox(box) {\n\t\t\tvar minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {\n\t\t\t\treturn minBox.box === box;\n\t\t\t});\n\n\t\t\tif (minBoxSize) {\n\t\t\t\tif (box.isHorizontal()) {\n\t\t\t\t\tvar scaleMargin = {\n\t\t\t\t\t\tleft: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),\n\t\t\t\t\t\tright: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),\n\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\tbottom: 0\n\t\t\t\t\t};\n\n\t\t\t\t\t// Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends\n\t\t\t\t\t// on the margin. Sometimes they need to increase in size slightly\n\t\t\t\t\tbox.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);\n\t\t\t\t} else {\n\t\t\t\t\tbox.update(minBoxSize.minSize.width, maxChartAreaHeight);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Update, and calculate the left and right margins for the horizontal boxes\n\t\thelpers.each(leftBoxes.concat(rightBoxes), fitBox);\n\n\t\thelpers.each(leftBoxes, function(box) {\n\t\t\ttotalLeftBoxesWidth += box.width;\n\t\t});\n\n\t\thelpers.each(rightBoxes, function(box) {\n\t\t\ttotalRightBoxesWidth += box.width;\n\t\t});\n\n\t\t// Set the Left and Right margins for the horizontal boxes\n\t\thelpers.each(topBoxes.concat(bottomBoxes), fitBox);\n\n\t\t// Figure out how much margin is on the top and bottom of the vertical boxes\n\t\thelpers.each(topBoxes, function(box) {\n\t\t\ttotalTopBoxesHeight += box.height;\n\t\t});\n\n\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\ttotalBottomBoxesHeight += box.height;\n\t\t});\n\n\t\tfunction finalFitVerticalBox(box) {\n\t\t\tvar minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {\n\t\t\t\treturn minSize.box === box;\n\t\t\t});\n\n\t\t\tvar scaleMargin = {\n\t\t\t\tleft: 0,\n\t\t\t\tright: 0,\n\t\t\t\ttop: totalTopBoxesHeight,\n\t\t\t\tbottom: totalBottomBoxesHeight\n\t\t\t};\n\n\t\t\tif (minBoxSize) {\n\t\t\t\tbox.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);\n\t\t\t}\n\t\t}\n\n\t\t// Let the left layout know the final margin\n\t\thelpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);\n\n\t\t// Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)\n\t\ttotalLeftBoxesWidth = leftPadding;\n\t\ttotalRightBoxesWidth = rightPadding;\n\t\ttotalTopBoxesHeight = topPadding;\n\t\ttotalBottomBoxesHeight = bottomPadding;\n\n\t\thelpers.each(leftBoxes, function(box) {\n\t\t\ttotalLeftBoxesWidth += box.width;\n\t\t});\n\n\t\thelpers.each(rightBoxes, function(box) {\n\t\t\ttotalRightBoxesWidth += box.width;\n\t\t});\n\n\t\thelpers.each(topBoxes, function(box) {\n\t\t\ttotalTopBoxesHeight += box.height;\n\t\t});\n\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\ttotalBottomBoxesHeight += box.height;\n\t\t});\n\n\t\t// We may be adding some padding to account for rotated x axis labels\n\t\tvar leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0);\n\t\ttotalLeftBoxesWidth += leftPaddingAddition;\n\t\ttotalRightBoxesWidth += Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0);\n\n\t\tvar topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0);\n\t\ttotalTopBoxesHeight += topPaddingAddition;\n\t\ttotalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0);\n\n\t\t// Figure out if our chart area changed. This would occur if the dataset layout label rotation\n\t\t// changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do\n\t\t// without calling `fit` again\n\t\tvar newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;\n\t\tvar newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;\n\n\t\tif (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {\n\t\t\thelpers.each(leftBoxes, function(box) {\n\t\t\t\tbox.height = newMaxChartAreaHeight;\n\t\t\t});\n\n\t\t\thelpers.each(rightBoxes, function(box) {\n\t\t\t\tbox.height = newMaxChartAreaHeight;\n\t\t\t});\n\n\t\t\thelpers.each(topBoxes, function(box) {\n\t\t\t\tif (!box.fullWidth) {\n\t\t\t\t\tbox.width = newMaxChartAreaWidth;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\thelpers.each(bottomBoxes, function(box) {\n\t\t\t\tif (!box.fullWidth) {\n\t\t\t\t\tbox.width = newMaxChartAreaWidth;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmaxChartAreaHeight = newMaxChartAreaHeight;\n\t\t\tmaxChartAreaWidth = newMaxChartAreaWidth;\n\t\t}\n\n\t\t// Step 7 - Position the boxes\n\t\tvar left = leftPadding + leftPaddingAddition;\n\t\tvar top = topPadding + topPaddingAddition;\n\n\t\tfunction placeBox(box) {\n\t\t\tif (box.isHorizontal()) {\n\t\t\t\tbox.left = box.fullWidth ? leftPadding : totalLeftBoxesWidth;\n\t\t\t\tbox.right = box.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth;\n\t\t\t\tbox.top = top;\n\t\t\t\tbox.bottom = top + box.height;\n\n\t\t\t\t// Move to next point\n\t\t\t\ttop = box.bottom;\n\n\t\t\t} else {\n\n\t\t\t\tbox.left = left;\n\t\t\t\tbox.right = left + box.width;\n\t\t\t\tbox.top = totalTopBoxesHeight;\n\t\t\t\tbox.bottom = totalTopBoxesHeight + maxChartAreaHeight;\n\n\t\t\t\t// Move to next point\n\t\t\t\tleft = box.right;\n\t\t\t}\n\t\t}\n\n\t\thelpers.each(leftBoxes.concat(topBoxes), placeBox);\n\n\t\t// Account for chart width and height\n\t\tleft += maxChartAreaWidth;\n\t\ttop += maxChartAreaHeight;\n\n\t\thelpers.each(rightBoxes, placeBox);\n\t\thelpers.each(bottomBoxes, placeBox);\n\n\t\t// Step 8\n\t\tchart.chartArea = {\n\t\t\tleft: totalLeftBoxesWidth,\n\t\t\ttop: totalTopBoxesHeight,\n\t\t\tright: totalLeftBoxesWidth + maxChartAreaWidth,\n\t\t\tbottom: totalTopBoxesHeight + maxChartAreaHeight\n\t\t};\n\n\t\t// Step 9\n\t\thelpers.each(chartAreaBoxes, function(box) {\n\t\t\tbox.left = chart.chartArea.left;\n\t\t\tbox.top = chart.chartArea.top;\n\t\t\tbox.right = chart.chartArea.right;\n\t\t\tbox.bottom = chart.chartArea.bottom;\n\n\t\t\tbox.update(maxChartAreaWidth, maxChartAreaHeight);\n\t\t});\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjcwNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmxheW91dHMuanM/N2M0MiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xuXG5mdW5jdGlvbiBmaWx0ZXJCeVBvc2l0aW9uKGFycmF5LCBwb3NpdGlvbikge1xuXHRyZXR1cm4gaGVscGVycy53aGVyZShhcnJheSwgZnVuY3Rpb24odikge1xuXHRcdHJldHVybiB2LnBvc2l0aW9uID09PSBwb3NpdGlvbjtcblx0fSk7XG59XG5cbmZ1bmN0aW9uIHNvcnRCeVdlaWdodChhcnJheSwgcmV2ZXJzZSkge1xuXHRhcnJheS5mb3JFYWNoKGZ1bmN0aW9uKHYsIGkpIHtcblx0XHR2Ll90bXBJbmRleF8gPSBpO1xuXHRcdHJldHVybiB2O1xuXHR9KTtcblx0YXJyYXkuc29ydChmdW5jdGlvbihhLCBiKSB7XG5cdFx0dmFyIHYwID0gcmV2ZXJzZSA/IGIgOiBhO1xuXHRcdHZhciB2MSA9IHJldmVyc2UgPyBhIDogYjtcblx0XHRyZXR1cm4gdjAud2VpZ2h0ID09PSB2MS53ZWlnaHQgP1xuXHRcdFx0djAuX3RtcEluZGV4XyAtIHYxLl90bXBJbmRleF8gOlxuXHRcdFx0djAud2VpZ2h0IC0gdjEud2VpZ2h0O1xuXHR9KTtcblx0YXJyYXkuZm9yRWFjaChmdW5jdGlvbih2KSB7XG5cdFx0ZGVsZXRlIHYuX3RtcEluZGV4Xztcblx0fSk7XG59XG5cbi8qKlxuICogQGludGVyZmFjZSBJTGF5b3V0SXRlbVxuICogQHByb3Age1N0cmluZ30gcG9zaXRpb24gLSBUaGUgcG9zaXRpb24gb2YgdGhlIGl0ZW0gaW4gdGhlIGNoYXJ0IGxheW91dC4gUG9zc2libGUgdmFsdWVzIGFyZVxuICogJ2xlZnQnLCAndG9wJywgJ3JpZ2h0JywgJ2JvdHRvbScsIGFuZCAnY2hhcnRBcmVhJ1xuICogQHByb3Age051bWJlcn0gd2VpZ2h0IC0gVGhlIHdlaWdodCB1c2VkIHRvIHNvcnQgdGhlIGl0ZW0uIEhpZ2hlciB3ZWlnaHRzIGFyZSBmdXJ0aGVyIGF3YXkgZnJvbSB0aGUgY2hhcnQgYXJlYVxuICogQHByb3Age0Jvb2xlYW59IGZ1bGxXaWR0aCAtIGlmIHRydWUsIGFuZCB0aGUgaXRlbSBpcyBob3Jpem9udGFsLCB0aGVuIHB1c2ggdmVydGljYWwgYm94ZXMgZG93blxuICogQHByb3Age0Z1bmN0aW9ufSBpc0hvcml6b250YWwgLSByZXR1cm5zIHRydWUgaWYgdGhlIGxheW91dCBpdGVtIGlzIGhvcml6b250YWwgKGllLiB0b3Agb3IgYm90dG9tKVxuICogQHByb3Age0Z1bmN0aW9ufSB1cGRhdGUgLSBUYWtlcyB0d28gcGFyYW1ldGVyczogd2lkdGggYW5kIGhlaWdodC4gUmV0dXJucyBzaXplIG9mIGl0ZW1cbiAqIEBwcm9wIHtGdW5jdGlvbn0gZ2V0UGFkZGluZyAtICBSZXR1cm5zIGFuIG9iamVjdCB3aXRoIHBhZGRpbmcgb24gdGhlIGVkZ2VzXG4gKiBAcHJvcCB7TnVtYmVyfSB3aWR0aCAtIFdpZHRoIG9mIGl0ZW0uIE11c3QgYmUgdmFsaWQgYWZ0ZXIgdXBkYXRlKClcbiAqIEBwcm9wIHtOdW1iZXJ9IGhlaWdodCAtIEhlaWdodCBvZiBpdGVtLiBNdXN0IGJlIHZhbGlkIGFmdGVyIHVwZGF0ZSgpXG4gKiBAcHJvcCB7TnVtYmVyfSBsZWZ0IC0gTGVmdCBlZGdlIG9mIHRoZSBpdGVtLiBTZXQgYnkgbGF5b3V0IHN5c3RlbSBhbmQgY2Fubm90IGJlIHVzZWQgaW4gdXBkYXRlXG4gKiBAcHJvcCB7TnVtYmVyfSB0b3AgLSBUb3AgZWRnZSBvZiB0aGUgaXRlbS4gU2V0IGJ5IGxheW91dCBzeXN0ZW0gYW5kIGNhbm5vdCBiZSB1c2VkIGluIHVwZGF0ZVxuICogQHByb3Age051bWJlcn0gcmlnaHQgLSBSaWdodCBlZGdlIG9mIHRoZSBpdGVtLiBTZXQgYnkgbGF5b3V0IHN5c3RlbSBhbmQgY2Fubm90IGJlIHVzZWQgaW4gdXBkYXRlXG4gKiBAcHJvcCB7TnVtYmVyfSBib3R0b20gLSBCb3R0b20gZWRnZSBvZiB0aGUgaXRlbS4gU2V0IGJ5IGxheW91dCBzeXN0ZW0gYW5kIGNhbm5vdCBiZSB1c2VkIGluIHVwZGF0ZVxuICovXG5cbi8vIFRoZSBsYXlvdXQgc2VydmljZSBpcyB2ZXJ5IHNlbGYgZXhwbGFuYXRvcnkuICBJdCdzIHJlc3BvbnNpYmxlIGZvciB0aGUgbGF5b3V0IHdpdGhpbiBhIGNoYXJ0LlxuLy8gU2NhbGVzLCBMZWdlbmRzIGFuZCBQbHVnaW5zIGFsbCByZWx5IG9uIHRoZSBsYXlvdXQgc2VydmljZSBhbmQgY2FuIGVhc2lseSByZWdpc3RlciB0byBiZSBwbGFjZWQgYW55d2hlcmUgdGhleSBuZWVkXG4vLyBJdCBpcyB0aGlzIHNlcnZpY2UncyByZXNwb25zaWJpbGl0eSBvZiBjYXJyeWluZyBvdXQgdGhhdCBsYXlvdXQuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0ZGVmYXVsdHM6IHt9LFxuXG5cdC8qKlxuXHQgKiBSZWdpc3RlciBhIGJveCB0byBhIGNoYXJ0LlxuXHQgKiBBIGJveCBpcyBzaW1wbHkgYSByZWZlcmVuY2UgdG8gYW4gb2JqZWN0IHRoYXQgcmVxdWlyZXMgbGF5b3V0LiBlZy4gU2NhbGVzLCBMZWdlbmQsIFRpdGxlLlxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCB0byB1c2Vcblx0ICogQHBhcmFtIHtJTGF5b3V0SXRlbX0gaXRlbSAtIHRoZSBpdGVtIHRvIGFkZCB0byBiZSBsYXllZCBvdXRcblx0ICovXG5cdGFkZEJveDogZnVuY3Rpb24oY2hhcnQsIGl0ZW0pIHtcblx0XHRpZiAoIWNoYXJ0LmJveGVzKSB7XG5cdFx0XHRjaGFydC5ib3hlcyA9IFtdO1xuXHRcdH1cblxuXHRcdC8vIGluaXRpYWxpemUgaXRlbSB3aXRoIGRlZmF1bHQgdmFsdWVzXG5cdFx0aXRlbS5mdWxsV2lkdGggPSBpdGVtLmZ1bGxXaWR0aCB8fCBmYWxzZTtcblx0XHRpdGVtLnBvc2l0aW9uID0gaXRlbS5wb3NpdGlvbiB8fCAndG9wJztcblx0XHRpdGVtLndlaWdodCA9IGl0ZW0ud2VpZ2h0IHx8IDA7XG5cblx0XHRjaGFydC5ib3hlcy5wdXNoKGl0ZW0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZW1vdmUgYSBsYXlvdXRJdGVtIGZyb20gYSBjaGFydFxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCB0byByZW1vdmUgdGhlIGJveCBmcm9tXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBsYXlvdXRJdGVtIC0gdGhlIGl0ZW0gdG8gcmVtb3ZlIGZyb20gdGhlIGxheW91dFxuXHQgKi9cblx0cmVtb3ZlQm94OiBmdW5jdGlvbihjaGFydCwgbGF5b3V0SXRlbSkge1xuXHRcdHZhciBpbmRleCA9IGNoYXJ0LmJveGVzID8gY2hhcnQuYm94ZXMuaW5kZXhPZihsYXlvdXRJdGVtKSA6IC0xO1xuXHRcdGlmIChpbmRleCAhPT0gLTEpIHtcblx0XHRcdGNoYXJ0LmJveGVzLnNwbGljZShpbmRleCwgMSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXRzIChvciB1cGRhdGVzKSBvcHRpb25zIG9uIHRoZSBnaXZlbiBgaXRlbWAuXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IGluIHdoaWNoIHRoZSBpdGVtIGxpdmVzIChvciB3aWxsIGJlIGFkZGVkIHRvKVxuXHQgKiBAcGFyYW0ge09iamVjdH0gaXRlbSAtIHRoZSBpdGVtIHRvIGNvbmZpZ3VyZSB3aXRoIHRoZSBnaXZlbiBvcHRpb25zXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gdGhlIG5ldyBpdGVtIG9wdGlvbnMuXG5cdCAqL1xuXHRjb25maWd1cmU6IGZ1bmN0aW9uKGNoYXJ0LCBpdGVtLCBvcHRpb25zKSB7XG5cdFx0dmFyIHByb3BzID0gWydmdWxsV2lkdGgnLCAncG9zaXRpb24nLCAnd2VpZ2h0J107XG5cdFx0dmFyIGlsZW4gPSBwcm9wcy5sZW5ndGg7XG5cdFx0dmFyIGkgPSAwO1xuXHRcdHZhciBwcm9wO1xuXG5cdFx0Zm9yICg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdHByb3AgPSBwcm9wc1tpXTtcblx0XHRcdGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KHByb3ApKSB7XG5cdFx0XHRcdGl0ZW1bcHJvcF0gPSBvcHRpb25zW3Byb3BdO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogRml0cyBib3hlcyBvZiB0aGUgZ2l2ZW4gY2hhcnQgaW50byB0aGUgZ2l2ZW4gc2l6ZSBieSBoYXZpbmcgZWFjaCBib3ggbWVhc3VyZSBpdHNlbGZcblx0ICogdGhlbiBydW5uaW5nIGEgZml0dGluZyBhbGdvcml0aG1cblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnRcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHdpZHRoIC0gdGhlIHdpZHRoIHRvIGZpdCBpbnRvXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBoZWlnaHQgLSB0aGUgaGVpZ2h0IHRvIGZpdCBpbnRvXG5cdCAqL1xuXHR1cGRhdGU6IGZ1bmN0aW9uKGNoYXJ0LCB3aWR0aCwgaGVpZ2h0KSB7XG5cdFx0aWYgKCFjaGFydCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBsYXlvdXRPcHRpb25zID0gY2hhcnQub3B0aW9ucy5sYXlvdXQgfHwge307XG5cdFx0dmFyIHBhZGRpbmcgPSBoZWxwZXJzLm9wdGlvbnMudG9QYWRkaW5nKGxheW91dE9wdGlvbnMucGFkZGluZyk7XG5cdFx0dmFyIGxlZnRQYWRkaW5nID0gcGFkZGluZy5sZWZ0O1xuXHRcdHZhciByaWdodFBhZGRpbmcgPSBwYWRkaW5nLnJpZ2h0O1xuXHRcdHZhciB0b3BQYWRkaW5nID0gcGFkZGluZy50b3A7XG5cdFx0dmFyIGJvdHRvbVBhZGRpbmcgPSBwYWRkaW5nLmJvdHRvbTtcblxuXHRcdHZhciBsZWZ0Qm94ZXMgPSBmaWx0ZXJCeVBvc2l0aW9uKGNoYXJ0LmJveGVzLCAnbGVmdCcpO1xuXHRcdHZhciByaWdodEJveGVzID0gZmlsdGVyQnlQb3NpdGlvbihjaGFydC5ib3hlcywgJ3JpZ2h0Jyk7XG5cdFx0dmFyIHRvcEJveGVzID0gZmlsdGVyQnlQb3NpdGlvbihjaGFydC5ib3hlcywgJ3RvcCcpO1xuXHRcdHZhciBib3R0b21Cb3hlcyA9IGZpbHRlckJ5UG9zaXRpb24oY2hhcnQuYm94ZXMsICdib3R0b20nKTtcblx0XHR2YXIgY2hhcnRBcmVhQm94ZXMgPSBmaWx0ZXJCeVBvc2l0aW9uKGNoYXJ0LmJveGVzLCAnY2hhcnRBcmVhJyk7XG5cblx0XHQvLyBTb3J0IGJveGVzIGJ5IHdlaWdodC4gQSBoaWdoZXIgd2VpZ2h0IGlzIGZ1cnRoZXIgYXdheSBmcm9tIHRoZSBjaGFydCBhcmVhXG5cdFx0c29ydEJ5V2VpZ2h0KGxlZnRCb3hlcywgdHJ1ZSk7XG5cdFx0c29ydEJ5V2VpZ2h0KHJpZ2h0Qm94ZXMsIGZhbHNlKTtcblx0XHRzb3J0QnlXZWlnaHQodG9wQm94ZXMsIHRydWUpO1xuXHRcdHNvcnRCeVdlaWdodChib3R0b21Cb3hlcywgZmFsc2UpO1xuXG5cdFx0Ly8gRXNzZW50aWFsbHkgd2Ugbm93IGhhdmUgYW55IG51bWJlciBvZiBib3hlcyBvbiBlYWNoIG9mIHRoZSA0IHNpZGVzLlxuXHRcdC8vIE91ciBjYW52YXMgbG9va3MgbGlrZSB0aGUgZm9sbG93aW5nLlxuXHRcdC8vIFRoZSBhcmVhcyBMMSBhbmQgTDIgYXJlIHRoZSBsZWZ0IGF4ZXMuIFIxIGlzIHRoZSByaWdodCBheGlzLCBUMSBpcyB0aGUgdG9wIGF4aXMgYW5kXG5cdFx0Ly8gQjEgaXMgdGhlIGJvdHRvbSBheGlzXG5cdFx0Ly8gVGhlcmUgYXJlIGFsc28gNCBxdWFkcmFudC1saWtlIGxvY2F0aW9ucyAobGVmdCB0byByaWdodCBpbnN0ZWFkIG9mIGNsb2Nrd2lzZSkgcmVzZXJ2ZWQgZm9yIGNoYXJ0IG92ZXJsYXlzXG5cdFx0Ly8gVGhlc2UgbG9jYXRpb25zIGFyZSBzaW5nbGUtYm94IGxvY2F0aW9ucyBvbmx5LCB3aGVuIHRyeWluZyB0byByZWdpc3RlciBhIGNoYXJ0QXJlYSBsb2NhdGlvbiB0aGF0IGlzIGFscmVhZHkgdGFrZW4sXG5cdFx0Ly8gYW4gZXJyb3Igd2lsbCBiZSB0aHJvd24uXG5cdFx0Ly9cblx0XHQvLyB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcblx0XHQvLyB8ICAgICAgICAgICAgICAgICAgVDEgKEZ1bGwgV2lkdGgpICAgICAgICAgICAgICAgICAgIHxcblx0XHQvLyB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcblx0XHQvLyB8ICAgIHwgICAgfCAgICAgICAgICAgICAgICAgVDIgICAgICAgICAgICAgICAgICB8ICAgIHxcblx0XHQvLyB8ICAgIHwtLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLXxcblx0XHQvLyB8ICAgIHwgICAgfCBDMSB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDMiB8ICAgIHxcblx0XHQvLyB8ICAgIHwgICAgfC0tLS18ICAgICAgICAgICAgICAgICAgICAgICAgICAgfC0tLS18ICAgIHxcblx0XHQvLyB8ICAgIHwgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIHxcblx0XHQvLyB8IEwxIHwgTDIgfCAgICAgICAgICAgQ2hhcnRBcmVhIChDMCkgICAgICAgICAgICB8IFIxIHxcblx0XHQvLyB8ICAgIHwgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIHxcblx0XHQvLyB8ICAgIHwgICAgfC0tLS18ICAgICAgICAgICAgICAgICAgICAgICAgICAgfC0tLS18ICAgIHxcblx0XHQvLyB8ICAgIHwgICAgfCBDMyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDNCB8ICAgIHxcblx0XHQvLyB8ICAgIHwtLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLXxcblx0XHQvLyB8ICAgIHwgICAgfCAgICAgICAgICAgICAgICAgQjEgICAgICAgICAgICAgICAgICB8ICAgIHxcblx0XHQvLyB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcblx0XHQvLyB8ICAgICAgICAgICAgICAgICAgQjIgKEZ1bGwgV2lkdGgpICAgICAgICAgICAgICAgICAgIHxcblx0XHQvLyB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcblx0XHQvL1xuXHRcdC8vIFdoYXQgd2UgZG8gdG8gZmluZCB0aGUgYmVzdCBzaXppbmcsIHdlIGRvIHRoZSBmb2xsb3dpbmdcblx0XHQvLyAxLiBEZXRlcm1pbmUgdGhlIG1pbmltdW0gc2l6ZSBvZiB0aGUgY2hhcnQgYXJlYS5cblx0XHQvLyAyLiBTcGxpdCB0aGUgcmVtYWluaW5nIHdpZHRoIGVxdWFsbHkgYmV0d2VlbiBlYWNoIHZlcnRpY2FsIGF4aXNcblx0XHQvLyAzLiBTcGxpdCB0aGUgcmVtYWluaW5nIGhlaWdodCBlcXVhbGx5IGJldHdlZW4gZWFjaCBob3Jpem9udGFsIGF4aXNcblx0XHQvLyA0LiBHaXZlIGVhY2ggbGF5b3V0IHRoZSBtYXhpbXVtIHNpemUgaXQgY2FuIGJlLiBUaGUgbGF5b3V0IHdpbGwgcmV0dXJuIGl0J3MgbWluaW11bSBzaXplXG5cdFx0Ly8gNS4gQWRqdXN0IHRoZSBzaXplcyBvZiBlYWNoIGF4aXMgYmFzZWQgb24gaXQncyBtaW5pbXVtIHJlcG9ydGVkIHNpemUuXG5cdFx0Ly8gNi4gUmVmaXQgZWFjaCBheGlzXG5cdFx0Ly8gNy4gUG9zaXRpb24gZWFjaCBheGlzIGluIHRoZSBmaW5hbCBsb2NhdGlvblxuXHRcdC8vIDguIFRlbGwgdGhlIGNoYXJ0IHRoZSBmaW5hbCBsb2NhdGlvbiBvZiB0aGUgY2hhcnQgYXJlYVxuXHRcdC8vIDkuIFRlbGwgYW55IGF4ZXMgdGhhdCBvdmVybGF5IHRoZSBjaGFydCBhcmVhIHRoZSBwb3NpdGlvbnMgb2YgdGhlIGNoYXJ0IGFyZWFcblxuXHRcdC8vIFN0ZXAgMVxuXHRcdHZhciBjaGFydFdpZHRoID0gd2lkdGggLSBsZWZ0UGFkZGluZyAtIHJpZ2h0UGFkZGluZztcblx0XHR2YXIgY2hhcnRIZWlnaHQgPSBoZWlnaHQgLSB0b3BQYWRkaW5nIC0gYm90dG9tUGFkZGluZztcblx0XHR2YXIgY2hhcnRBcmVhV2lkdGggPSBjaGFydFdpZHRoIC8gMjsgLy8gbWluIDUwJVxuXHRcdHZhciBjaGFydEFyZWFIZWlnaHQgPSBjaGFydEhlaWdodCAvIDI7IC8vIG1pbiA1MCVcblxuXHRcdC8vIFN0ZXAgMlxuXHRcdHZhciB2ZXJ0aWNhbEJveFdpZHRoID0gKHdpZHRoIC0gY2hhcnRBcmVhV2lkdGgpIC8gKGxlZnRCb3hlcy5sZW5ndGggKyByaWdodEJveGVzLmxlbmd0aCk7XG5cblx0XHQvLyBTdGVwIDNcblx0XHR2YXIgaG9yaXpvbnRhbEJveEhlaWdodCA9IChoZWlnaHQgLSBjaGFydEFyZWFIZWlnaHQpIC8gKHRvcEJveGVzLmxlbmd0aCArIGJvdHRvbUJveGVzLmxlbmd0aCk7XG5cblx0XHQvLyBTdGVwIDRcblx0XHR2YXIgbWF4Q2hhcnRBcmVhV2lkdGggPSBjaGFydFdpZHRoO1xuXHRcdHZhciBtYXhDaGFydEFyZWFIZWlnaHQgPSBjaGFydEhlaWdodDtcblx0XHR2YXIgbWluQm94U2l6ZXMgPSBbXTtcblxuXHRcdGZ1bmN0aW9uIGdldE1pbmltdW1Cb3hTaXplKGJveCkge1xuXHRcdFx0dmFyIG1pblNpemU7XG5cdFx0XHR2YXIgaXNIb3Jpem9udGFsID0gYm94LmlzSG9yaXpvbnRhbCgpO1xuXG5cdFx0XHRpZiAoaXNIb3Jpem9udGFsKSB7XG5cdFx0XHRcdG1pblNpemUgPSBib3gudXBkYXRlKGJveC5mdWxsV2lkdGggPyBjaGFydFdpZHRoIDogbWF4Q2hhcnRBcmVhV2lkdGgsIGhvcml6b250YWxCb3hIZWlnaHQpO1xuXHRcdFx0XHRtYXhDaGFydEFyZWFIZWlnaHQgLT0gbWluU2l6ZS5oZWlnaHQ7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtaW5TaXplID0gYm94LnVwZGF0ZSh2ZXJ0aWNhbEJveFdpZHRoLCBtYXhDaGFydEFyZWFIZWlnaHQpO1xuXHRcdFx0XHRtYXhDaGFydEFyZWFXaWR0aCAtPSBtaW5TaXplLndpZHRoO1xuXHRcdFx0fVxuXG5cdFx0XHRtaW5Cb3hTaXplcy5wdXNoKHtcblx0XHRcdFx0aG9yaXpvbnRhbDogaXNIb3Jpem9udGFsLFxuXHRcdFx0XHRtaW5TaXplOiBtaW5TaXplLFxuXHRcdFx0XHRib3g6IGJveCxcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGhlbHBlcnMuZWFjaChsZWZ0Qm94ZXMuY29uY2F0KHJpZ2h0Qm94ZXMsIHRvcEJveGVzLCBib3R0b21Cb3hlcyksIGdldE1pbmltdW1Cb3hTaXplKTtcblxuXHRcdC8vIElmIGEgaG9yaXpvbnRhbCBib3ggaGFzIHBhZGRpbmcsIHdlIG1vdmUgdGhlIGxlZnQgYm94ZXMgb3ZlciB0byBhdm9pZCB1Z2x5IGNoYXJ0cyAoc2VlIGlzc3VlICMyNDc4KVxuXHRcdHZhciBtYXhIb3Jpem9udGFsTGVmdFBhZGRpbmcgPSAwO1xuXHRcdHZhciBtYXhIb3Jpem9udGFsUmlnaHRQYWRkaW5nID0gMDtcblx0XHR2YXIgbWF4VmVydGljYWxUb3BQYWRkaW5nID0gMDtcblx0XHR2YXIgbWF4VmVydGljYWxCb3R0b21QYWRkaW5nID0gMDtcblxuXHRcdGhlbHBlcnMuZWFjaCh0b3BCb3hlcy5jb25jYXQoYm90dG9tQm94ZXMpLCBmdW5jdGlvbihob3Jpem9udGFsQm94KSB7XG5cdFx0XHRpZiAoaG9yaXpvbnRhbEJveC5nZXRQYWRkaW5nKSB7XG5cdFx0XHRcdHZhciBib3hQYWRkaW5nID0gaG9yaXpvbnRhbEJveC5nZXRQYWRkaW5nKCk7XG5cdFx0XHRcdG1heEhvcml6b250YWxMZWZ0UGFkZGluZyA9IE1hdGgubWF4KG1heEhvcml6b250YWxMZWZ0UGFkZGluZywgYm94UGFkZGluZy5sZWZ0KTtcblx0XHRcdFx0bWF4SG9yaXpvbnRhbFJpZ2h0UGFkZGluZyA9IE1hdGgubWF4KG1heEhvcml6b250YWxSaWdodFBhZGRpbmcsIGJveFBhZGRpbmcucmlnaHQpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0aGVscGVycy5lYWNoKGxlZnRCb3hlcy5jb25jYXQocmlnaHRCb3hlcyksIGZ1bmN0aW9uKHZlcnRpY2FsQm94KSB7XG5cdFx0XHRpZiAodmVydGljYWxCb3guZ2V0UGFkZGluZykge1xuXHRcdFx0XHR2YXIgYm94UGFkZGluZyA9IHZlcnRpY2FsQm94LmdldFBhZGRpbmcoKTtcblx0XHRcdFx0bWF4VmVydGljYWxUb3BQYWRkaW5nID0gTWF0aC5tYXgobWF4VmVydGljYWxUb3BQYWRkaW5nLCBib3hQYWRkaW5nLnRvcCk7XG5cdFx0XHRcdG1heFZlcnRpY2FsQm90dG9tUGFkZGluZyA9IE1hdGgubWF4KG1heFZlcnRpY2FsQm90dG9tUGFkZGluZywgYm94UGFkZGluZy5ib3R0b20pO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0Ly8gQXQgdGhpcyBwb2ludCwgbWF4Q2hhcnRBcmVhSGVpZ2h0IGFuZCBtYXhDaGFydEFyZWFXaWR0aCBhcmUgdGhlIHNpemUgdGhlIGNoYXJ0IGFyZWEgY291bGRcblx0XHQvLyBiZSBpZiB0aGUgYXhlcyBhcmUgZHJhd24gYXQgdGhlaXIgbWluaW11bSBzaXplcy5cblx0XHQvLyBTdGVwcyA1ICYgNlxuXHRcdHZhciB0b3RhbExlZnRCb3hlc1dpZHRoID0gbGVmdFBhZGRpbmc7XG5cdFx0dmFyIHRvdGFsUmlnaHRCb3hlc1dpZHRoID0gcmlnaHRQYWRkaW5nO1xuXHRcdHZhciB0b3RhbFRvcEJveGVzSGVpZ2h0ID0gdG9wUGFkZGluZztcblx0XHR2YXIgdG90YWxCb3R0b21Cb3hlc0hlaWdodCA9IGJvdHRvbVBhZGRpbmc7XG5cblx0XHQvLyBGdW5jdGlvbiB0byBmaXQgYSBib3hcblx0XHRmdW5jdGlvbiBmaXRCb3goYm94KSB7XG5cdFx0XHR2YXIgbWluQm94U2l6ZSA9IGhlbHBlcnMuZmluZE5leHRXaGVyZShtaW5Cb3hTaXplcywgZnVuY3Rpb24obWluQm94KSB7XG5cdFx0XHRcdHJldHVybiBtaW5Cb3guYm94ID09PSBib3g7XG5cdFx0XHR9KTtcblxuXHRcdFx0aWYgKG1pbkJveFNpemUpIHtcblx0XHRcdFx0aWYgKGJveC5pc0hvcml6b250YWwoKSkge1xuXHRcdFx0XHRcdHZhciBzY2FsZU1hcmdpbiA9IHtcblx0XHRcdFx0XHRcdGxlZnQ6IE1hdGgubWF4KHRvdGFsTGVmdEJveGVzV2lkdGgsIG1heEhvcml6b250YWxMZWZ0UGFkZGluZyksXG5cdFx0XHRcdFx0XHRyaWdodDogTWF0aC5tYXgodG90YWxSaWdodEJveGVzV2lkdGgsIG1heEhvcml6b250YWxSaWdodFBhZGRpbmcpLFxuXHRcdFx0XHRcdFx0dG9wOiAwLFxuXHRcdFx0XHRcdFx0Ym90dG9tOiAwXG5cdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdC8vIERvbid0IHVzZSBtaW4gc2l6ZSBoZXJlIGJlY2F1c2Ugb2YgbGFiZWwgcm90YXRpb24uIFdoZW4gdGhlIGxhYmVscyBhcmUgcm90YXRlZCwgdGhlaXIgcm90YXRpb24gaGlnaGx5IGRlcGVuZHNcblx0XHRcdFx0XHQvLyBvbiB0aGUgbWFyZ2luLiBTb21ldGltZXMgdGhleSBuZWVkIHRvIGluY3JlYXNlIGluIHNpemUgc2xpZ2h0bHlcblx0XHRcdFx0XHRib3gudXBkYXRlKGJveC5mdWxsV2lkdGggPyBjaGFydFdpZHRoIDogbWF4Q2hhcnRBcmVhV2lkdGgsIGNoYXJ0SGVpZ2h0IC8gMiwgc2NhbGVNYXJnaW4pO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGJveC51cGRhdGUobWluQm94U2l6ZS5taW5TaXplLndpZHRoLCBtYXhDaGFydEFyZWFIZWlnaHQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gVXBkYXRlLCBhbmQgY2FsY3VsYXRlIHRoZSBsZWZ0IGFuZCByaWdodCBtYXJnaW5zIGZvciB0aGUgaG9yaXpvbnRhbCBib3hlc1xuXHRcdGhlbHBlcnMuZWFjaChsZWZ0Qm94ZXMuY29uY2F0KHJpZ2h0Qm94ZXMpLCBmaXRCb3gpO1xuXG5cdFx0aGVscGVycy5lYWNoKGxlZnRCb3hlcywgZnVuY3Rpb24oYm94KSB7XG5cdFx0XHR0b3RhbExlZnRCb3hlc1dpZHRoICs9IGJveC53aWR0aDtcblx0XHR9KTtcblxuXHRcdGhlbHBlcnMuZWFjaChyaWdodEJveGVzLCBmdW5jdGlvbihib3gpIHtcblx0XHRcdHRvdGFsUmlnaHRCb3hlc1dpZHRoICs9IGJveC53aWR0aDtcblx0XHR9KTtcblxuXHRcdC8vIFNldCB0aGUgTGVmdCBhbmQgUmlnaHQgbWFyZ2lucyBmb3IgdGhlIGhvcml6b250YWwgYm94ZXNcblx0XHRoZWxwZXJzLmVhY2godG9wQm94ZXMuY29uY2F0KGJvdHRvbUJveGVzKSwgZml0Qm94KTtcblxuXHRcdC8vIEZpZ3VyZSBvdXQgaG93IG11Y2ggbWFyZ2luIGlzIG9uIHRoZSB0b3AgYW5kIGJvdHRvbSBvZiB0aGUgdmVydGljYWwgYm94ZXNcblx0XHRoZWxwZXJzLmVhY2godG9wQm94ZXMsIGZ1bmN0aW9uKGJveCkge1xuXHRcdFx0dG90YWxUb3BCb3hlc0hlaWdodCArPSBib3guaGVpZ2h0O1xuXHRcdH0pO1xuXG5cdFx0aGVscGVycy5lYWNoKGJvdHRvbUJveGVzLCBmdW5jdGlvbihib3gpIHtcblx0XHRcdHRvdGFsQm90dG9tQm94ZXNIZWlnaHQgKz0gYm94LmhlaWdodDtcblx0XHR9KTtcblxuXHRcdGZ1bmN0aW9uIGZpbmFsRml0VmVydGljYWxCb3goYm94KSB7XG5cdFx0XHR2YXIgbWluQm94U2l6ZSA9IGhlbHBlcnMuZmluZE5leHRXaGVyZShtaW5Cb3hTaXplcywgZnVuY3Rpb24obWluU2l6ZSkge1xuXHRcdFx0XHRyZXR1cm4gbWluU2l6ZS5ib3ggPT09IGJveDtcblx0XHRcdH0pO1xuXG5cdFx0XHR2YXIgc2NhbGVNYXJnaW4gPSB7XG5cdFx0XHRcdGxlZnQ6IDAsXG5cdFx0XHRcdHJpZ2h0OiAwLFxuXHRcdFx0XHR0b3A6IHRvdGFsVG9wQm94ZXNIZWlnaHQsXG5cdFx0XHRcdGJvdHRvbTogdG90YWxCb3R0b21Cb3hlc0hlaWdodFxuXHRcdFx0fTtcblxuXHRcdFx0aWYgKG1pbkJveFNpemUpIHtcblx0XHRcdFx0Ym94LnVwZGF0ZShtaW5Cb3hTaXplLm1pblNpemUud2lkdGgsIG1heENoYXJ0QXJlYUhlaWdodCwgc2NhbGVNYXJnaW4pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIExldCB0aGUgbGVmdCBsYXlvdXQga25vdyB0aGUgZmluYWwgbWFyZ2luXG5cdFx0aGVscGVycy5lYWNoKGxlZnRCb3hlcy5jb25jYXQocmlnaHRCb3hlcyksIGZpbmFsRml0VmVydGljYWxCb3gpO1xuXG5cdFx0Ly8gUmVjYWxjdWxhdGUgYmVjYXVzZSB0aGUgc2l6ZSBvZiBlYWNoIGxheW91dCBtaWdodCBoYXZlIGNoYW5nZWQgc2xpZ2h0bHkgZHVlIHRvIHRoZSBtYXJnaW5zIChsYWJlbCByb3RhdGlvbiBmb3IgaW5zdGFuY2UpXG5cdFx0dG90YWxMZWZ0Qm94ZXNXaWR0aCA9IGxlZnRQYWRkaW5nO1xuXHRcdHRvdGFsUmlnaHRCb3hlc1dpZHRoID0gcmlnaHRQYWRkaW5nO1xuXHRcdHRvdGFsVG9wQm94ZXNIZWlnaHQgPSB0b3BQYWRkaW5nO1xuXHRcdHRvdGFsQm90dG9tQm94ZXNIZWlnaHQgPSBib3R0b21QYWRkaW5nO1xuXG5cdFx0aGVscGVycy5lYWNoKGxlZnRCb3hlcywgZnVuY3Rpb24oYm94KSB7XG5cdFx0XHR0b3RhbExlZnRCb3hlc1dpZHRoICs9IGJveC53aWR0aDtcblx0XHR9KTtcblxuXHRcdGhlbHBlcnMuZWFjaChyaWdodEJveGVzLCBmdW5jdGlvbihib3gpIHtcblx0XHRcdHRvdGFsUmlnaHRCb3hlc1dpZHRoICs9IGJveC53aWR0aDtcblx0XHR9KTtcblxuXHRcdGhlbHBlcnMuZWFjaCh0b3BCb3hlcywgZnVuY3Rpb24oYm94KSB7XG5cdFx0XHR0b3RhbFRvcEJveGVzSGVpZ2h0ICs9IGJveC5oZWlnaHQ7XG5cdFx0fSk7XG5cdFx0aGVscGVycy5lYWNoKGJvdHRvbUJveGVzLCBmdW5jdGlvbihib3gpIHtcblx0XHRcdHRvdGFsQm90dG9tQm94ZXNIZWlnaHQgKz0gYm94LmhlaWdodDtcblx0XHR9KTtcblxuXHRcdC8vIFdlIG1heSBiZSBhZGRpbmcgc29tZSBwYWRkaW5nIHRvIGFjY291bnQgZm9yIHJvdGF0ZWQgeCBheGlzIGxhYmVsc1xuXHRcdHZhciBsZWZ0UGFkZGluZ0FkZGl0aW9uID0gTWF0aC5tYXgobWF4SG9yaXpvbnRhbExlZnRQYWRkaW5nIC0gdG90YWxMZWZ0Qm94ZXNXaWR0aCwgMCk7XG5cdFx0dG90YWxMZWZ0Qm94ZXNXaWR0aCArPSBsZWZ0UGFkZGluZ0FkZGl0aW9uO1xuXHRcdHRvdGFsUmlnaHRCb3hlc1dpZHRoICs9IE1hdGgubWF4KG1heEhvcml6b250YWxSaWdodFBhZGRpbmcgLSB0b3RhbFJpZ2h0Qm94ZXNXaWR0aCwgMCk7XG5cblx0XHR2YXIgdG9wUGFkZGluZ0FkZGl0aW9uID0gTWF0aC5tYXgobWF4VmVydGljYWxUb3BQYWRkaW5nIC0gdG90YWxUb3BCb3hlc0hlaWdodCwgMCk7XG5cdFx0dG90YWxUb3BCb3hlc0hlaWdodCArPSB0b3BQYWRkaW5nQWRkaXRpb247XG5cdFx0dG90YWxCb3R0b21Cb3hlc0hlaWdodCArPSBNYXRoLm1heChtYXhWZXJ0aWNhbEJvdHRvbVBhZGRpbmcgLSB0b3RhbEJvdHRvbUJveGVzSGVpZ2h0LCAwKTtcblxuXHRcdC8vIEZpZ3VyZSBvdXQgaWYgb3VyIGNoYXJ0IGFyZWEgY2hhbmdlZC4gVGhpcyB3b3VsZCBvY2N1ciBpZiB0aGUgZGF0YXNldCBsYXlvdXQgbGFiZWwgcm90YXRpb25cblx0XHQvLyBjaGFuZ2VkIGR1ZSB0byB0aGUgYXBwbGljYXRpb24gb2YgdGhlIG1hcmdpbnMgaW4gc3RlcCA2LiBTaW5jZSB3ZSBjYW4gb25seSBnZXQgYmlnZ2VyLCB0aGlzIGlzIHNhZmUgdG8gZG9cblx0XHQvLyB3aXRob3V0IGNhbGxpbmcgYGZpdGAgYWdhaW5cblx0XHR2YXIgbmV3TWF4Q2hhcnRBcmVhSGVpZ2h0ID0gaGVpZ2h0IC0gdG90YWxUb3BCb3hlc0hlaWdodCAtIHRvdGFsQm90dG9tQm94ZXNIZWlnaHQ7XG5cdFx0dmFyIG5ld01heENoYXJ0QXJlYVdpZHRoID0gd2lkdGggLSB0b3RhbExlZnRCb3hlc1dpZHRoIC0gdG90YWxSaWdodEJveGVzV2lkdGg7XG5cblx0XHRpZiAobmV3TWF4Q2hhcnRBcmVhV2lkdGggIT09IG1heENoYXJ0QXJlYVdpZHRoIHx8IG5ld01heENoYXJ0QXJlYUhlaWdodCAhPT0gbWF4Q2hhcnRBcmVhSGVpZ2h0KSB7XG5cdFx0XHRoZWxwZXJzLmVhY2gobGVmdEJveGVzLCBmdW5jdGlvbihib3gpIHtcblx0XHRcdFx0Ym94LmhlaWdodCA9IG5ld01heENoYXJ0QXJlYUhlaWdodDtcblx0XHRcdH0pO1xuXG5cdFx0XHRoZWxwZXJzLmVhY2gocmlnaHRCb3hlcywgZnVuY3Rpb24oYm94KSB7XG5cdFx0XHRcdGJveC5oZWlnaHQgPSBuZXdNYXhDaGFydEFyZWFIZWlnaHQ7XG5cdFx0XHR9KTtcblxuXHRcdFx0aGVscGVycy5lYWNoKHRvcEJveGVzLCBmdW5jdGlvbihib3gpIHtcblx0XHRcdFx0aWYgKCFib3guZnVsbFdpZHRoKSB7XG5cdFx0XHRcdFx0Ym94LndpZHRoID0gbmV3TWF4Q2hhcnRBcmVhV2lkdGg7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHRoZWxwZXJzLmVhY2goYm90dG9tQm94ZXMsIGZ1bmN0aW9uKGJveCkge1xuXHRcdFx0XHRpZiAoIWJveC5mdWxsV2lkdGgpIHtcblx0XHRcdFx0XHRib3gud2lkdGggPSBuZXdNYXhDaGFydEFyZWFXaWR0aDtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdG1heENoYXJ0QXJlYUhlaWdodCA9IG5ld01heENoYXJ0QXJlYUhlaWdodDtcblx0XHRcdG1heENoYXJ0QXJlYVdpZHRoID0gbmV3TWF4Q2hhcnRBcmVhV2lkdGg7XG5cdFx0fVxuXG5cdFx0Ly8gU3RlcCA3IC0gUG9zaXRpb24gdGhlIGJveGVzXG5cdFx0dmFyIGxlZnQgPSBsZWZ0UGFkZGluZyArIGxlZnRQYWRkaW5nQWRkaXRpb247XG5cdFx0dmFyIHRvcCA9IHRvcFBhZGRpbmcgKyB0b3BQYWRkaW5nQWRkaXRpb247XG5cblx0XHRmdW5jdGlvbiBwbGFjZUJveChib3gpIHtcblx0XHRcdGlmIChib3guaXNIb3Jpem9udGFsKCkpIHtcblx0XHRcdFx0Ym94LmxlZnQgPSBib3guZnVsbFdpZHRoID8gbGVmdFBhZGRpbmcgOiB0b3RhbExlZnRCb3hlc1dpZHRoO1xuXHRcdFx0XHRib3gucmlnaHQgPSBib3guZnVsbFdpZHRoID8gd2lkdGggLSByaWdodFBhZGRpbmcgOiB0b3RhbExlZnRCb3hlc1dpZHRoICsgbWF4Q2hhcnRBcmVhV2lkdGg7XG5cdFx0XHRcdGJveC50b3AgPSB0b3A7XG5cdFx0XHRcdGJveC5ib3R0b20gPSB0b3AgKyBib3guaGVpZ2h0O1xuXG5cdFx0XHRcdC8vIE1vdmUgdG8gbmV4dCBwb2ludFxuXHRcdFx0XHR0b3AgPSBib3guYm90dG9tO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdGJveC5sZWZ0ID0gbGVmdDtcblx0XHRcdFx0Ym94LnJpZ2h0ID0gbGVmdCArIGJveC53aWR0aDtcblx0XHRcdFx0Ym94LnRvcCA9IHRvdGFsVG9wQm94ZXNIZWlnaHQ7XG5cdFx0XHRcdGJveC5ib3R0b20gPSB0b3RhbFRvcEJveGVzSGVpZ2h0ICsgbWF4Q2hhcnRBcmVhSGVpZ2h0O1xuXG5cdFx0XHRcdC8vIE1vdmUgdG8gbmV4dCBwb2ludFxuXHRcdFx0XHRsZWZ0ID0gYm94LnJpZ2h0O1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGhlbHBlcnMuZWFjaChsZWZ0Qm94ZXMuY29uY2F0KHRvcEJveGVzKSwgcGxhY2VCb3gpO1xuXG5cdFx0Ly8gQWNjb3VudCBmb3IgY2hhcnQgd2lkdGggYW5kIGhlaWdodFxuXHRcdGxlZnQgKz0gbWF4Q2hhcnRBcmVhV2lkdGg7XG5cdFx0dG9wICs9IG1heENoYXJ0QXJlYUhlaWdodDtcblxuXHRcdGhlbHBlcnMuZWFjaChyaWdodEJveGVzLCBwbGFjZUJveCk7XG5cdFx0aGVscGVycy5lYWNoKGJvdHRvbUJveGVzLCBwbGFjZUJveCk7XG5cblx0XHQvLyBTdGVwIDhcblx0XHRjaGFydC5jaGFydEFyZWEgPSB7XG5cdFx0XHRsZWZ0OiB0b3RhbExlZnRCb3hlc1dpZHRoLFxuXHRcdFx0dG9wOiB0b3RhbFRvcEJveGVzSGVpZ2h0LFxuXHRcdFx0cmlnaHQ6IHRvdGFsTGVmdEJveGVzV2lkdGggKyBtYXhDaGFydEFyZWFXaWR0aCxcblx0XHRcdGJvdHRvbTogdG90YWxUb3BCb3hlc0hlaWdodCArIG1heENoYXJ0QXJlYUhlaWdodFxuXHRcdH07XG5cblx0XHQvLyBTdGVwIDlcblx0XHRoZWxwZXJzLmVhY2goY2hhcnRBcmVhQm94ZXMsIGZ1bmN0aW9uKGJveCkge1xuXHRcdFx0Ym94LmxlZnQgPSBjaGFydC5jaGFydEFyZWEubGVmdDtcblx0XHRcdGJveC50b3AgPSBjaGFydC5jaGFydEFyZWEudG9wO1xuXHRcdFx0Ym94LnJpZ2h0ID0gY2hhcnQuY2hhcnRBcmVhLnJpZ2h0O1xuXHRcdFx0Ym94LmJvdHRvbSA9IGNoYXJ0LmNoYXJ0QXJlYS5ib3R0b207XG5cblx0XHRcdGJveC51cGRhdGUobWF4Q2hhcnRBcmVhV2lkdGgsIG1heENoYXJ0QXJlYUhlaWdodCk7XG5cdFx0fSk7XG5cdH1cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6705\n")},"675a":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar Element = __webpack_require__(/*! ../core/core.element */ \"4a45\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\nvar layouts = __webpack_require__(/*! ../core/core.layouts */ \"6705\");\n\nvar noop = helpers.noop;\n\ndefaults._set('global', {\n\tlegend: {\n\t\tdisplay: true,\n\t\tposition: 'top',\n\t\tfullWidth: true,\n\t\treverse: false,\n\t\tweight: 1000,\n\n\t\t// a callback that will handle\n\t\tonClick: function(e, legendItem) {\n\t\t\tvar index = legendItem.datasetIndex;\n\t\t\tvar ci = this.chart;\n\t\t\tvar meta = ci.getDatasetMeta(index);\n\n\t\t\t// See controller.isDatasetVisible comment\n\t\t\tmeta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;\n\n\t\t\t// We hid a dataset ... rerender the chart\n\t\t\tci.update();\n\t\t},\n\n\t\tonHover: null,\n\n\t\tlabels: {\n\t\t\tboxWidth: 40,\n\t\t\tpadding: 10,\n\t\t\t// Generates labels shown in the legend\n\t\t\t// Valid properties to return:\n\t\t\t// text : text to display\n\t\t\t// fillStyle : fill of coloured box\n\t\t\t// strokeStyle: stroke of coloured box\n\t\t\t// hidden : if this legend item refers to a hidden item\n\t\t\t// lineCap : cap style for line\n\t\t\t// lineDash\n\t\t\t// lineDashOffset :\n\t\t\t// lineJoin :\n\t\t\t// lineWidth :\n\t\t\tgenerateLabels: function(chart) {\n\t\t\t\tvar data = chart.data;\n\t\t\t\treturn helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttext: dataset.label,\n\t\t\t\t\t\tfillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),\n\t\t\t\t\t\thidden: !chart.isDatasetVisible(i),\n\t\t\t\t\t\tlineCap: dataset.borderCapStyle,\n\t\t\t\t\t\tlineDash: dataset.borderDash,\n\t\t\t\t\t\tlineDashOffset: dataset.borderDashOffset,\n\t\t\t\t\t\tlineJoin: dataset.borderJoinStyle,\n\t\t\t\t\t\tlineWidth: dataset.borderWidth,\n\t\t\t\t\t\tstrokeStyle: dataset.borderColor,\n\t\t\t\t\t\tpointStyle: dataset.pointStyle,\n\n\t\t\t\t\t\t// Below is extra data used for toggling the datasets\n\t\t\t\t\t\tdatasetIndex: i\n\t\t\t\t\t};\n\t\t\t\t}, this) : [];\n\t\t\t}\n\t\t}\n\t},\n\n\tlegendCallback: function(chart) {\n\t\tvar text = [];\n\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\t\tfor (var i = 0; i < chart.data.datasets.length; i++) {\n\t\t\ttext.push('<li><span style=\"background-color:' + chart.data.datasets[i].backgroundColor + '\"></span>');\n\t\t\tif (chart.data.datasets[i].label) {\n\t\t\t\ttext.push(chart.data.datasets[i].label);\n\t\t\t}\n\t\t\ttext.push('</li>');\n\t\t}\n\t\ttext.push('</ul>');\n\t\treturn text.join('');\n\t}\n});\n\n/**\n * Helper function to get the box width based on the usePointStyle option\n * @param labelopts {Object} the label options on the legend\n * @param fontSize {Number} the label font size\n * @return {Number} width of the color box area\n */\nfunction getBoxWidth(labelOpts, fontSize) {\n\treturn labelOpts.usePointStyle ?\n\t\tfontSize * Math.SQRT2 :\n\t\tlabelOpts.boxWidth;\n}\n\n/**\n * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required!\n */\nvar Legend = Element.extend({\n\n\tinitialize: function(config) {\n\t\thelpers.extend(this, config);\n\n\t\t// Contains hit boxes for each dataset (in dataset order)\n\t\tthis.legendHitBoxes = [];\n\n\t\t// Are we in doughnut mode which has a different data type\n\t\tthis.doughnutMode = false;\n\t},\n\n\t// These methods are ordered by lifecycle. Utilities then follow.\n\t// Any function defined here is inherited by all legend types.\n\t// Any function can be extended by the legend type\n\n\tbeforeUpdate: noop,\n\tupdate: function(maxWidth, maxHeight, margins) {\n\t\tvar me = this;\n\n\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\tme.beforeUpdate();\n\n\t\t// Absorb the master measurements\n\t\tme.maxWidth = maxWidth;\n\t\tme.maxHeight = maxHeight;\n\t\tme.margins = margins;\n\n\t\t// Dimensions\n\t\tme.beforeSetDimensions();\n\t\tme.setDimensions();\n\t\tme.afterSetDimensions();\n\t\t// Labels\n\t\tme.beforeBuildLabels();\n\t\tme.buildLabels();\n\t\tme.afterBuildLabels();\n\n\t\t// Fit\n\t\tme.beforeFit();\n\t\tme.fit();\n\t\tme.afterFit();\n\t\t//\n\t\tme.afterUpdate();\n\n\t\treturn me.minSize;\n\t},\n\tafterUpdate: noop,\n\n\t//\n\n\tbeforeSetDimensions: noop,\n\tsetDimensions: function() {\n\t\tvar me = this;\n\t\t// Set the unconstrained dimension before label rotation\n\t\tif (me.isHorizontal()) {\n\t\t\t// Reset position before calculating rotation\n\t\t\tme.width = me.maxWidth;\n\t\t\tme.left = 0;\n\t\t\tme.right = me.width;\n\t\t} else {\n\t\t\tme.height = me.maxHeight;\n\n\t\t\t// Reset position before calculating rotation\n\t\t\tme.top = 0;\n\t\t\tme.bottom = me.height;\n\t\t}\n\n\t\t// Reset padding\n\t\tme.paddingLeft = 0;\n\t\tme.paddingTop = 0;\n\t\tme.paddingRight = 0;\n\t\tme.paddingBottom = 0;\n\n\t\t// Reset minSize\n\t\tme.minSize = {\n\t\t\twidth: 0,\n\t\t\theight: 0\n\t\t};\n\t},\n\tafterSetDimensions: noop,\n\n\t//\n\n\tbeforeBuildLabels: noop,\n\tbuildLabels: function() {\n\t\tvar me = this;\n\t\tvar labelOpts = me.options.labels || {};\n\t\tvar legendItems = helpers.callback(labelOpts.generateLabels, [me.chart], me) || [];\n\n\t\tif (labelOpts.filter) {\n\t\t\tlegendItems = legendItems.filter(function(item) {\n\t\t\t\treturn labelOpts.filter(item, me.chart.data);\n\t\t\t});\n\t\t}\n\n\t\tif (me.options.reverse) {\n\t\t\tlegendItems.reverse();\n\t\t}\n\n\t\tme.legendItems = legendItems;\n\t},\n\tafterBuildLabels: noop,\n\n\t//\n\n\tbeforeFit: noop,\n\tfit: function() {\n\t\tvar me = this;\n\t\tvar opts = me.options;\n\t\tvar labelOpts = opts.labels;\n\t\tvar display = opts.display;\n\n\t\tvar ctx = me.ctx;\n\n\t\tvar globalDefault = defaults.global;\n\t\tvar valueOrDefault = helpers.valueOrDefault;\n\t\tvar fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize);\n\t\tvar fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle);\n\t\tvar fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily);\n\t\tvar labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\n\n\t\t// Reset hit boxes\n\t\tvar hitboxes = me.legendHitBoxes = [];\n\n\t\tvar minSize = me.minSize;\n\t\tvar isHorizontal = me.isHorizontal();\n\n\t\tif (isHorizontal) {\n\t\t\tminSize.width = me.maxWidth; // fill all the width\n\t\t\tminSize.height = display ? 10 : 0;\n\t\t} else {\n\t\t\tminSize.width = display ? 10 : 0;\n\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t}\n\n\t\t// Increase sizes here\n\t\tif (display) {\n\t\t\tctx.font = labelFont;\n\n\t\t\tif (isHorizontal) {\n\t\t\t\t// Labels\n\n\t\t\t\t// Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one\n\t\t\t\tvar lineWidths = me.lineWidths = [0];\n\t\t\t\tvar totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;\n\n\t\t\t\tctx.textAlign = 'left';\n\t\t\t\tctx.textBaseline = 'top';\n\n\t\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\n\t\t\t\t\tvar width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\n\n\t\t\t\t\tif (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {\n\t\t\t\t\t\ttotalHeight += fontSize + (labelOpts.padding);\n\t\t\t\t\t\tlineWidths[lineWidths.length] = me.left;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Store the hitbox width and height here. Final position will be updated in `draw`\n\t\t\t\t\thitboxes[i] = {\n\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\twidth: width,\n\t\t\t\t\t\theight: fontSize\n\t\t\t\t\t};\n\n\t\t\t\t\tlineWidths[lineWidths.length - 1] += width + labelOpts.padding;\n\t\t\t\t});\n\n\t\t\t\tminSize.height += totalHeight;\n\n\t\t\t} else {\n\t\t\t\tvar vPadding = labelOpts.padding;\n\t\t\t\tvar columnWidths = me.columnWidths = [];\n\t\t\t\tvar totalWidth = labelOpts.padding;\n\t\t\t\tvar currentColWidth = 0;\n\t\t\t\tvar currentColHeight = 0;\n\t\t\t\tvar itemHeight = fontSize + vPadding;\n\n\t\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\n\t\t\t\t\tvar itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\n\n\t\t\t\t\t// If too tall, go to new column\n\t\t\t\t\tif (currentColHeight + itemHeight > minSize.height) {\n\t\t\t\t\t\ttotalWidth += currentColWidth + labelOpts.padding;\n\t\t\t\t\t\tcolumnWidths.push(currentColWidth); // previous column width\n\n\t\t\t\t\t\tcurrentColWidth = 0;\n\t\t\t\t\t\tcurrentColHeight = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Get max width\n\t\t\t\t\tcurrentColWidth = Math.max(currentColWidth, itemWidth);\n\t\t\t\t\tcurrentColHeight += itemHeight;\n\n\t\t\t\t\t// Store the hitbox width and height here. Final position will be updated in `draw`\n\t\t\t\t\thitboxes[i] = {\n\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\twidth: itemWidth,\n\t\t\t\t\t\theight: fontSize\n\t\t\t\t\t};\n\t\t\t\t});\n\n\t\t\t\ttotalWidth += currentColWidth;\n\t\t\t\tcolumnWidths.push(currentColWidth);\n\t\t\t\tminSize.width += totalWidth;\n\t\t\t}\n\t\t}\n\n\t\tme.width = minSize.width;\n\t\tme.height = minSize.height;\n\t},\n\tafterFit: noop,\n\n\t// Shared Methods\n\tisHorizontal: function() {\n\t\treturn this.options.position === 'top' || this.options.position === 'bottom';\n\t},\n\n\t// Actually draw the legend on the canvas\n\tdraw: function() {\n\t\tvar me = this;\n\t\tvar opts = me.options;\n\t\tvar labelOpts = opts.labels;\n\t\tvar globalDefault = defaults.global;\n\t\tvar lineDefault = globalDefault.elements.line;\n\t\tvar legendWidth = me.width;\n\t\tvar lineWidths = me.lineWidths;\n\n\t\tif (opts.display) {\n\t\t\tvar ctx = me.ctx;\n\t\t\tvar valueOrDefault = helpers.valueOrDefault;\n\t\t\tvar fontColor = valueOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor);\n\t\t\tvar fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize);\n\t\t\tvar fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle);\n\t\t\tvar fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily);\n\t\t\tvar labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);\n\t\t\tvar cursor;\n\n\t\t\t// Canvas setup\n\t\t\tctx.textAlign = 'left';\n\t\t\tctx.textBaseline = 'middle';\n\t\t\tctx.lineWidth = 0.5;\n\t\t\tctx.strokeStyle = fontColor; // for strikethrough effect\n\t\t\tctx.fillStyle = fontColor; // render in correct colour\n\t\t\tctx.font = labelFont;\n\n\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\n\t\t\tvar hitboxes = me.legendHitBoxes;\n\n\t\t\t// current position\n\t\t\tvar drawLegendBox = function(x, y, legendItem) {\n\t\t\t\tif (isNaN(boxWidth) || boxWidth <= 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Set the ctx for the box\n\t\t\t\tctx.save();\n\n\t\t\t\tctx.fillStyle = valueOrDefault(legendItem.fillStyle, globalDefault.defaultColor);\n\t\t\t\tctx.lineCap = valueOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);\n\t\t\t\tctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);\n\t\t\t\tctx.lineJoin = valueOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);\n\t\t\t\tctx.lineWidth = valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth);\n\t\t\t\tctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);\n\t\t\t\tvar isLineWidthZero = (valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0);\n\n\t\t\t\tif (ctx.setLineDash) {\n\t\t\t\t\t// IE 9 and 10 do not support line dash\n\t\t\t\t\tctx.setLineDash(valueOrDefault(legendItem.lineDash, lineDefault.borderDash));\n\t\t\t\t}\n\n\t\t\t\tif (opts.labels && opts.labels.usePointStyle) {\n\t\t\t\t\t// Recalculate x and y for drawPoint() because its expecting\n\t\t\t\t\t// x and y to be center of figure (instead of top left)\n\t\t\t\t\tvar radius = fontSize * Math.SQRT2 / 2;\n\t\t\t\t\tvar offSet = radius / Math.SQRT2;\n\t\t\t\t\tvar centerX = x + offSet;\n\t\t\t\t\tvar centerY = y + offSet;\n\n\t\t\t\t\t// Draw pointStyle as legend symbol\n\t\t\t\t\thelpers.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);\n\t\t\t\t} else {\n\t\t\t\t\t// Draw box as legend symbol\n\t\t\t\t\tif (!isLineWidthZero) {\n\t\t\t\t\t\tctx.strokeRect(x, y, boxWidth, fontSize);\n\t\t\t\t\t}\n\t\t\t\t\tctx.fillRect(x, y, boxWidth, fontSize);\n\t\t\t\t}\n\n\t\t\t\tctx.restore();\n\t\t\t};\n\t\t\tvar fillText = function(x, y, legendItem, textWidth) {\n\t\t\t\tvar halfFontSize = fontSize / 2;\n\t\t\t\tvar xLeft = boxWidth + halfFontSize + x;\n\t\t\t\tvar yMiddle = y + halfFontSize;\n\n\t\t\t\tctx.fillText(legendItem.text, xLeft, yMiddle);\n\n\t\t\t\tif (legendItem.hidden) {\n\t\t\t\t\t// Strikethrough the text if hidden\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.lineWidth = 2;\n\t\t\t\t\tctx.moveTo(xLeft, yMiddle);\n\t\t\t\t\tctx.lineTo(xLeft + textWidth, yMiddle);\n\t\t\t\t\tctx.stroke();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Horizontal\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tif (isHorizontal) {\n\t\t\t\tcursor = {\n\t\t\t\t\tx: me.left + ((legendWidth - lineWidths[0]) / 2),\n\t\t\t\t\ty: me.top + labelOpts.padding,\n\t\t\t\t\tline: 0\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tcursor = {\n\t\t\t\t\tx: me.left + labelOpts.padding,\n\t\t\t\t\ty: me.top + labelOpts.padding,\n\t\t\t\t\tline: 0\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tvar itemHeight = fontSize + labelOpts.padding;\n\t\t\thelpers.each(me.legendItems, function(legendItem, i) {\n\t\t\t\tvar textWidth = ctx.measureText(legendItem.text).width;\n\t\t\t\tvar width = boxWidth + (fontSize / 2) + textWidth;\n\t\t\t\tvar x = cursor.x;\n\t\t\t\tvar y = cursor.y;\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tif (x + width >= legendWidth) {\n\t\t\t\t\t\ty = cursor.y += itemHeight;\n\t\t\t\t\t\tcursor.line++;\n\t\t\t\t\t\tx = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);\n\t\t\t\t\t}\n\t\t\t\t} else if (y + itemHeight > me.bottom) {\n\t\t\t\t\tx = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;\n\t\t\t\t\ty = cursor.y = me.top + labelOpts.padding;\n\t\t\t\t\tcursor.line++;\n\t\t\t\t}\n\n\t\t\t\tdrawLegendBox(x, y, legendItem);\n\n\t\t\t\thitboxes[i].left = x;\n\t\t\t\thitboxes[i].top = y;\n\n\t\t\t\t// Fill the actual label\n\t\t\t\tfillText(x, y, legendItem, textWidth);\n\n\t\t\t\tif (isHorizontal) {\n\t\t\t\t\tcursor.x += width + (labelOpts.padding);\n\t\t\t\t} else {\n\t\t\t\t\tcursor.y += itemHeight;\n\t\t\t\t}\n\n\t\t\t});\n\t\t}\n\t},\n\n\t/**\n\t * Handle an event\n\t * @private\n\t * @param {IEvent} event - The event to handle\n\t * @return {Boolean} true if a change occured\n\t */\n\thandleEvent: function(e) {\n\t\tvar me = this;\n\t\tvar opts = me.options;\n\t\tvar type = e.type === 'mouseup' ? 'click' : e.type;\n\t\tvar changed = false;\n\n\t\tif (type === 'mousemove') {\n\t\t\tif (!opts.onHover) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else if (type === 'click') {\n\t\t\tif (!opts.onClick) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\t// Chart event already has relative position in it\n\t\tvar x = e.x;\n\t\tvar y = e.y;\n\n\t\tif (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {\n\t\t\t// See if we are touching one of the dataset boxes\n\t\t\tvar lh = me.legendHitBoxes;\n\t\t\tfor (var i = 0; i < lh.length; ++i) {\n\t\t\t\tvar hitBox = lh[i];\n\n\t\t\t\tif (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {\n\t\t\t\t\t// Touching an element\n\t\t\t\t\tif (type === 'click') {\n\t\t\t\t\t\t// use e.native for backwards compatibility\n\t\t\t\t\t\topts.onClick.call(me, e.native, me.legendItems[i]);\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (type === 'mousemove') {\n\t\t\t\t\t\t// use e.native for backwards compatibility\n\t\t\t\t\t\topts.onHover.call(me, e.native, me.legendItems[i]);\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn changed;\n\t}\n});\n\nfunction createNewLegendAndAttach(chart, legendOpts) {\n\tvar legend = new Legend({\n\t\tctx: chart.ctx,\n\t\toptions: legendOpts,\n\t\tchart: chart\n\t});\n\n\tlayouts.configure(chart, legend, legendOpts);\n\tlayouts.addBox(chart, legend);\n\tchart.legend = legend;\n}\n\nmodule.exports = {\n\tid: 'legend',\n\n\t/**\n\t * Backward compatibility: since 2.1.5, the legend is registered as a plugin, making\n\t * Chart.Legend obsolete. To avoid a breaking change, we export the Legend as part of\n\t * the plugin, which one will be re-exposed in the chart.js file.\n\t * https://github.com/chartjs/Chart.js/pull/2640\n\t * @private\n\t */\n\t_element: Legend,\n\n\tbeforeInit: function(chart) {\n\t\tvar legendOpts = chart.options.legend;\n\n\t\tif (legendOpts) {\n\t\t\tcreateNewLegendAndAttach(chart, legendOpts);\n\t\t}\n\t},\n\n\tbeforeUpdate: function(chart) {\n\t\tvar legendOpts = chart.options.legend;\n\t\tvar legend = chart.legend;\n\n\t\tif (legendOpts) {\n\t\t\thelpers.mergeIf(legendOpts, defaults.global.legend);\n\n\t\t\tif (legend) {\n\t\t\t\tlayouts.configure(chart, legend, legendOpts);\n\t\t\t\tlegend.options = legendOpts;\n\t\t\t} else {\n\t\t\t\tcreateNewLegendAndAttach(chart, legendOpts);\n\t\t\t}\n\t\t} else if (legend) {\n\t\t\tlayouts.removeBox(chart, legend);\n\t\t\tdelete chart.legend;\n\t\t}\n\t},\n\n\tafterEvent: function(chart, e) {\n\t\tvar legend = chart.legend;\n\t\tif (legend) {\n\t\t\tlegend.handleEvent(e);\n\t\t}\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjc1YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4ubGVnZW5kLmpzPzAxN2UiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuZGVmYXVsdHMnKTtcbnZhciBFbGVtZW50ID0gcmVxdWlyZSgnLi4vY29yZS9jb3JlLmVsZW1lbnQnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xudmFyIGxheW91dHMgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUubGF5b3V0cycpO1xuXG52YXIgbm9vcCA9IGhlbHBlcnMubm9vcDtcblxuZGVmYXVsdHMuX3NldCgnZ2xvYmFsJywge1xuXHRsZWdlbmQ6IHtcblx0XHRkaXNwbGF5OiB0cnVlLFxuXHRcdHBvc2l0aW9uOiAndG9wJyxcblx0XHRmdWxsV2lkdGg6IHRydWUsXG5cdFx0cmV2ZXJzZTogZmFsc2UsXG5cdFx0d2VpZ2h0OiAxMDAwLFxuXG5cdFx0Ly8gYSBjYWxsYmFjayB0aGF0IHdpbGwgaGFuZGxlXG5cdFx0b25DbGljazogZnVuY3Rpb24oZSwgbGVnZW5kSXRlbSkge1xuXHRcdFx0dmFyIGluZGV4ID0gbGVnZW5kSXRlbS5kYXRhc2V0SW5kZXg7XG5cdFx0XHR2YXIgY2kgPSB0aGlzLmNoYXJ0O1xuXHRcdFx0dmFyIG1ldGEgPSBjaS5nZXREYXRhc2V0TWV0YShpbmRleCk7XG5cblx0XHRcdC8vIFNlZSBjb250cm9sbGVyLmlzRGF0YXNldFZpc2libGUgY29tbWVudFxuXHRcdFx0bWV0YS5oaWRkZW4gPSBtZXRhLmhpZGRlbiA9PT0gbnVsbCA/ICFjaS5kYXRhLmRhdGFzZXRzW2luZGV4XS5oaWRkZW4gOiBudWxsO1xuXG5cdFx0XHQvLyBXZSBoaWQgYSBkYXRhc2V0IC4uLiByZXJlbmRlciB0aGUgY2hhcnRcblx0XHRcdGNpLnVwZGF0ZSgpO1xuXHRcdH0sXG5cblx0XHRvbkhvdmVyOiBudWxsLFxuXG5cdFx0bGFiZWxzOiB7XG5cdFx0XHRib3hXaWR0aDogNDAsXG5cdFx0XHRwYWRkaW5nOiAxMCxcblx0XHRcdC8vIEdlbmVyYXRlcyBsYWJlbHMgc2hvd24gaW4gdGhlIGxlZ2VuZFxuXHRcdFx0Ly8gVmFsaWQgcHJvcGVydGllcyB0byByZXR1cm46XG5cdFx0XHQvLyB0ZXh0IDogdGV4dCB0byBkaXNwbGF5XG5cdFx0XHQvLyBmaWxsU3R5bGUgOiBmaWxsIG9mIGNvbG91cmVkIGJveFxuXHRcdFx0Ly8gc3Ryb2tlU3R5bGU6IHN0cm9rZSBvZiBjb2xvdXJlZCBib3hcblx0XHRcdC8vIGhpZGRlbiA6IGlmIHRoaXMgbGVnZW5kIGl0ZW0gcmVmZXJzIHRvIGEgaGlkZGVuIGl0ZW1cblx0XHRcdC8vIGxpbmVDYXAgOiBjYXAgc3R5bGUgZm9yIGxpbmVcblx0XHRcdC8vIGxpbmVEYXNoXG5cdFx0XHQvLyBsaW5lRGFzaE9mZnNldCA6XG5cdFx0XHQvLyBsaW5lSm9pbiA6XG5cdFx0XHQvLyBsaW5lV2lkdGggOlxuXHRcdFx0Z2VuZXJhdGVMYWJlbHM6IGZ1bmN0aW9uKGNoYXJ0KSB7XG5cdFx0XHRcdHZhciBkYXRhID0gY2hhcnQuZGF0YTtcblx0XHRcdFx0cmV0dXJuIGhlbHBlcnMuaXNBcnJheShkYXRhLmRhdGFzZXRzKSA/IGRhdGEuZGF0YXNldHMubWFwKGZ1bmN0aW9uKGRhdGFzZXQsIGkpIHtcblx0XHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdFx0dGV4dDogZGF0YXNldC5sYWJlbCxcblx0XHRcdFx0XHRcdGZpbGxTdHlsZTogKCFoZWxwZXJzLmlzQXJyYXkoZGF0YXNldC5iYWNrZ3JvdW5kQ29sb3IpID8gZGF0YXNldC5iYWNrZ3JvdW5kQ29sb3IgOiBkYXRhc2V0LmJhY2tncm91bmRDb2xvclswXSksXG5cdFx0XHRcdFx0XHRoaWRkZW46ICFjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGkpLFxuXHRcdFx0XHRcdFx0bGluZUNhcDogZGF0YXNldC5ib3JkZXJDYXBTdHlsZSxcblx0XHRcdFx0XHRcdGxpbmVEYXNoOiBkYXRhc2V0LmJvcmRlckRhc2gsXG5cdFx0XHRcdFx0XHRsaW5lRGFzaE9mZnNldDogZGF0YXNldC5ib3JkZXJEYXNoT2Zmc2V0LFxuXHRcdFx0XHRcdFx0bGluZUpvaW46IGRhdGFzZXQuYm9yZGVySm9pblN0eWxlLFxuXHRcdFx0XHRcdFx0bGluZVdpZHRoOiBkYXRhc2V0LmJvcmRlcldpZHRoLFxuXHRcdFx0XHRcdFx0c3Ryb2tlU3R5bGU6IGRhdGFzZXQuYm9yZGVyQ29sb3IsXG5cdFx0XHRcdFx0XHRwb2ludFN0eWxlOiBkYXRhc2V0LnBvaW50U3R5bGUsXG5cblx0XHRcdFx0XHRcdC8vIEJlbG93IGlzIGV4dHJhIGRhdGEgdXNlZCBmb3IgdG9nZ2xpbmcgdGhlIGRhdGFzZXRzXG5cdFx0XHRcdFx0XHRkYXRhc2V0SW5kZXg6IGlcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9LCB0aGlzKSA6IFtdO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHRsZWdlbmRDYWxsYmFjazogZnVuY3Rpb24oY2hhcnQpIHtcblx0XHR2YXIgdGV4dCA9IFtdO1xuXHRcdHRleHQucHVzaCgnPHVsIGNsYXNzPVwiJyArIGNoYXJ0LmlkICsgJy1sZWdlbmRcIj4nKTtcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGNoYXJ0LmRhdGEuZGF0YXNldHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRleHQucHVzaCgnPGxpPjxzcGFuIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjonICsgY2hhcnQuZGF0YS5kYXRhc2V0c1tpXS5iYWNrZ3JvdW5kQ29sb3IgKyAnXCI+PC9zcGFuPicpO1xuXHRcdFx0aWYgKGNoYXJ0LmRhdGEuZGF0YXNldHNbaV0ubGFiZWwpIHtcblx0XHRcdFx0dGV4dC5wdXNoKGNoYXJ0LmRhdGEuZGF0YXNldHNbaV0ubGFiZWwpO1xuXHRcdFx0fVxuXHRcdFx0dGV4dC5wdXNoKCc8L2xpPicpO1xuXHRcdH1cblx0XHR0ZXh0LnB1c2goJzwvdWw+Jyk7XG5cdFx0cmV0dXJuIHRleHQuam9pbignJyk7XG5cdH1cbn0pO1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBnZXQgdGhlIGJveCB3aWR0aCBiYXNlZCBvbiB0aGUgdXNlUG9pbnRTdHlsZSBvcHRpb25cbiAqIEBwYXJhbSBsYWJlbG9wdHMge09iamVjdH0gdGhlIGxhYmVsIG9wdGlvbnMgb24gdGhlIGxlZ2VuZFxuICogQHBhcmFtIGZvbnRTaXplIHtOdW1iZXJ9IHRoZSBsYWJlbCBmb250IHNpemVcbiAqIEByZXR1cm4ge051bWJlcn0gd2lkdGggb2YgdGhlIGNvbG9yIGJveCBhcmVhXG4gKi9cbmZ1bmN0aW9uIGdldEJveFdpZHRoKGxhYmVsT3B0cywgZm9udFNpemUpIHtcblx0cmV0dXJuIGxhYmVsT3B0cy51c2VQb2ludFN0eWxlID9cblx0XHRmb250U2l6ZSAqIE1hdGguU1FSVDIgOlxuXHRcdGxhYmVsT3B0cy5ib3hXaWR0aDtcbn1cblxuLyoqXG4gKiBJTVBPUlRBTlQ6IHRoaXMgY2xhc3MgaXMgZXhwb3NlZCBwdWJsaWNseSBhcyBDaGFydC5MZWdlbmQsIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgcmVxdWlyZWQhXG4gKi9cbnZhciBMZWdlbmQgPSBFbGVtZW50LmV4dGVuZCh7XG5cblx0aW5pdGlhbGl6ZTogZnVuY3Rpb24oY29uZmlnKSB7XG5cdFx0aGVscGVycy5leHRlbmQodGhpcywgY29uZmlnKTtcblxuXHRcdC8vIENvbnRhaW5zIGhpdCBib3hlcyBmb3IgZWFjaCBkYXRhc2V0IChpbiBkYXRhc2V0IG9yZGVyKVxuXHRcdHRoaXMubGVnZW5kSGl0Qm94ZXMgPSBbXTtcblxuXHRcdC8vIEFyZSB3ZSBpbiBkb3VnaG51dCBtb2RlIHdoaWNoIGhhcyBhIGRpZmZlcmVudCBkYXRhIHR5cGVcblx0XHR0aGlzLmRvdWdobnV0TW9kZSA9IGZhbHNlO1xuXHR9LFxuXG5cdC8vIFRoZXNlIG1ldGhvZHMgYXJlIG9yZGVyZWQgYnkgbGlmZWN5Y2xlLiBVdGlsaXRpZXMgdGhlbiBmb2xsb3cuXG5cdC8vIEFueSBmdW5jdGlvbiBkZWZpbmVkIGhlcmUgaXMgaW5oZXJpdGVkIGJ5IGFsbCBsZWdlbmQgdHlwZXMuXG5cdC8vIEFueSBmdW5jdGlvbiBjYW4gYmUgZXh0ZW5kZWQgYnkgdGhlIGxlZ2VuZCB0eXBlXG5cblx0YmVmb3JlVXBkYXRlOiBub29wLFxuXHR1cGRhdGU6IGZ1bmN0aW9uKG1heFdpZHRoLCBtYXhIZWlnaHQsIG1hcmdpbnMpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXG5cdFx0Ly8gVXBkYXRlIExpZmVjeWNsZSAtIFByb2JhYmx5IGRvbid0IHdhbnQgdG8gZXZlciBleHRlbmQgb3Igb3ZlcndyaXRlIHRoaXMgZnVuY3Rpb24gOylcblx0XHRtZS5iZWZvcmVVcGRhdGUoKTtcblxuXHRcdC8vIEFic29yYiB0aGUgbWFzdGVyIG1lYXN1cmVtZW50c1xuXHRcdG1lLm1heFdpZHRoID0gbWF4V2lkdGg7XG5cdFx0bWUubWF4SGVpZ2h0ID0gbWF4SGVpZ2h0O1xuXHRcdG1lLm1hcmdpbnMgPSBtYXJnaW5zO1xuXG5cdFx0Ly8gRGltZW5zaW9uc1xuXHRcdG1lLmJlZm9yZVNldERpbWVuc2lvbnMoKTtcblx0XHRtZS5zZXREaW1lbnNpb25zKCk7XG5cdFx0bWUuYWZ0ZXJTZXREaW1lbnNpb25zKCk7XG5cdFx0Ly8gTGFiZWxzXG5cdFx0bWUuYmVmb3JlQnVpbGRMYWJlbHMoKTtcblx0XHRtZS5idWlsZExhYmVscygpO1xuXHRcdG1lLmFmdGVyQnVpbGRMYWJlbHMoKTtcblxuXHRcdC8vIEZpdFxuXHRcdG1lLmJlZm9yZUZpdCgpO1xuXHRcdG1lLmZpdCgpO1xuXHRcdG1lLmFmdGVyRml0KCk7XG5cdFx0Ly9cblx0XHRtZS5hZnRlclVwZGF0ZSgpO1xuXG5cdFx0cmV0dXJuIG1lLm1pblNpemU7XG5cdH0sXG5cdGFmdGVyVXBkYXRlOiBub29wLFxuXG5cdC8vXG5cblx0YmVmb3JlU2V0RGltZW5zaW9uczogbm9vcCxcblx0c2V0RGltZW5zaW9uczogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIG1lID0gdGhpcztcblx0XHQvLyBTZXQgdGhlIHVuY29uc3RyYWluZWQgZGltZW5zaW9uIGJlZm9yZSBsYWJlbCByb3RhdGlvblxuXHRcdGlmIChtZS5pc0hvcml6b250YWwoKSkge1xuXHRcdFx0Ly8gUmVzZXQgcG9zaXRpb24gYmVmb3JlIGNhbGN1bGF0aW5nIHJvdGF0aW9uXG5cdFx0XHRtZS53aWR0aCA9IG1lLm1heFdpZHRoO1xuXHRcdFx0bWUubGVmdCA9IDA7XG5cdFx0XHRtZS5yaWdodCA9IG1lLndpZHRoO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRtZS5oZWlnaHQgPSBtZS5tYXhIZWlnaHQ7XG5cblx0XHRcdC8vIFJlc2V0IHBvc2l0aW9uIGJlZm9yZSBjYWxjdWxhdGluZyByb3RhdGlvblxuXHRcdFx0bWUudG9wID0gMDtcblx0XHRcdG1lLmJvdHRvbSA9IG1lLmhlaWdodDtcblx0XHR9XG5cblx0XHQvLyBSZXNldCBwYWRkaW5nXG5cdFx0bWUucGFkZGluZ0xlZnQgPSAwO1xuXHRcdG1lLnBhZGRpbmdUb3AgPSAwO1xuXHRcdG1lLnBhZGRpbmdSaWdodCA9IDA7XG5cdFx0bWUucGFkZGluZ0JvdHRvbSA9IDA7XG5cblx0XHQvLyBSZXNldCBtaW5TaXplXG5cdFx0bWUubWluU2l6ZSA9IHtcblx0XHRcdHdpZHRoOiAwLFxuXHRcdFx0aGVpZ2h0OiAwXG5cdFx0fTtcblx0fSxcblx0YWZ0ZXJTZXREaW1lbnNpb25zOiBub29wLFxuXG5cdC8vXG5cblx0YmVmb3JlQnVpbGRMYWJlbHM6IG5vb3AsXG5cdGJ1aWxkTGFiZWxzOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciBsYWJlbE9wdHMgPSBtZS5vcHRpb25zLmxhYmVscyB8fCB7fTtcblx0XHR2YXIgbGVnZW5kSXRlbXMgPSBoZWxwZXJzLmNhbGxiYWNrKGxhYmVsT3B0cy5nZW5lcmF0ZUxhYmVscywgW21lLmNoYXJ0XSwgbWUpIHx8IFtdO1xuXG5cdFx0aWYgKGxhYmVsT3B0cy5maWx0ZXIpIHtcblx0XHRcdGxlZ2VuZEl0ZW1zID0gbGVnZW5kSXRlbXMuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcblx0XHRcdFx0cmV0dXJuIGxhYmVsT3B0cy5maWx0ZXIoaXRlbSwgbWUuY2hhcnQuZGF0YSk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRpZiAobWUub3B0aW9ucy5yZXZlcnNlKSB7XG5cdFx0XHRsZWdlbmRJdGVtcy5yZXZlcnNlKCk7XG5cdFx0fVxuXG5cdFx0bWUubGVnZW5kSXRlbXMgPSBsZWdlbmRJdGVtcztcblx0fSxcblx0YWZ0ZXJCdWlsZExhYmVsczogbm9vcCxcblxuXHQvL1xuXG5cdGJlZm9yZUZpdDogbm9vcCxcblx0Zml0OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcblx0XHR2YXIgbGFiZWxPcHRzID0gb3B0cy5sYWJlbHM7XG5cdFx0dmFyIGRpc3BsYXkgPSBvcHRzLmRpc3BsYXk7XG5cblx0XHR2YXIgY3R4ID0gbWUuY3R4O1xuXG5cdFx0dmFyIGdsb2JhbERlZmF1bHQgPSBkZWZhdWx0cy5nbG9iYWw7XG5cdFx0dmFyIHZhbHVlT3JEZWZhdWx0ID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdDtcblx0XHR2YXIgZm9udFNpemUgPSB2YWx1ZU9yRGVmYXVsdChsYWJlbE9wdHMuZm9udFNpemUsIGdsb2JhbERlZmF1bHQuZGVmYXVsdEZvbnRTaXplKTtcblx0XHR2YXIgZm9udFN0eWxlID0gdmFsdWVPckRlZmF1bHQobGFiZWxPcHRzLmZvbnRTdHlsZSwgZ2xvYmFsRGVmYXVsdC5kZWZhdWx0Rm9udFN0eWxlKTtcblx0XHR2YXIgZm9udEZhbWlseSA9IHZhbHVlT3JEZWZhdWx0KGxhYmVsT3B0cy5mb250RmFtaWx5LCBnbG9iYWxEZWZhdWx0LmRlZmF1bHRGb250RmFtaWx5KTtcblx0XHR2YXIgbGFiZWxGb250ID0gaGVscGVycy5mb250U3RyaW5nKGZvbnRTaXplLCBmb250U3R5bGUsIGZvbnRGYW1pbHkpO1xuXG5cdFx0Ly8gUmVzZXQgaGl0IGJveGVzXG5cdFx0dmFyIGhpdGJveGVzID0gbWUubGVnZW5kSGl0Qm94ZXMgPSBbXTtcblxuXHRcdHZhciBtaW5TaXplID0gbWUubWluU2l6ZTtcblx0XHR2YXIgaXNIb3Jpem9udGFsID0gbWUuaXNIb3Jpem9udGFsKCk7XG5cblx0XHRpZiAoaXNIb3Jpem9udGFsKSB7XG5cdFx0XHRtaW5TaXplLndpZHRoID0gbWUubWF4V2lkdGg7IC8vIGZpbGwgYWxsIHRoZSB3aWR0aFxuXHRcdFx0bWluU2l6ZS5oZWlnaHQgPSBkaXNwbGF5ID8gMTAgOiAwO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRtaW5TaXplLndpZHRoID0gZGlzcGxheSA/IDEwIDogMDtcblx0XHRcdG1pblNpemUuaGVpZ2h0ID0gbWUubWF4SGVpZ2h0OyAvLyBmaWxsIGFsbCB0aGUgaGVpZ2h0XG5cdFx0fVxuXG5cdFx0Ly8gSW5jcmVhc2Ugc2l6ZXMgaGVyZVxuXHRcdGlmIChkaXNwbGF5KSB7XG5cdFx0XHRjdHguZm9udCA9IGxhYmVsRm9udDtcblxuXHRcdFx0aWYgKGlzSG9yaXpvbnRhbCkge1xuXHRcdFx0XHQvLyBMYWJlbHNcblxuXHRcdFx0XHQvLyBXaWR0aCBvZiBlYWNoIGxpbmUgb2YgbGVnZW5kIGJveGVzLiBMYWJlbHMgd3JhcCBvbnRvIG11bHRpcGxlIGxpbmVzIHdoZW4gdGhlcmUgYXJlIHRvbyBtYW55IHRvIGZpdCBvbiBvbmVcblx0XHRcdFx0dmFyIGxpbmVXaWR0aHMgPSBtZS5saW5lV2lkdGhzID0gWzBdO1xuXHRcdFx0XHR2YXIgdG90YWxIZWlnaHQgPSBtZS5sZWdlbmRJdGVtcy5sZW5ndGggPyBmb250U2l6ZSArIChsYWJlbE9wdHMucGFkZGluZykgOiAwO1xuXG5cdFx0XHRcdGN0eC50ZXh0QWxpZ24gPSAnbGVmdCc7XG5cdFx0XHRcdGN0eC50ZXh0QmFzZWxpbmUgPSAndG9wJztcblxuXHRcdFx0XHRoZWxwZXJzLmVhY2gobWUubGVnZW5kSXRlbXMsIGZ1bmN0aW9uKGxlZ2VuZEl0ZW0sIGkpIHtcblx0XHRcdFx0XHR2YXIgYm94V2lkdGggPSBnZXRCb3hXaWR0aChsYWJlbE9wdHMsIGZvbnRTaXplKTtcblx0XHRcdFx0XHR2YXIgd2lkdGggPSBib3hXaWR0aCArIChmb250U2l6ZSAvIDIpICsgY3R4Lm1lYXN1cmVUZXh0KGxlZ2VuZEl0ZW0udGV4dCkud2lkdGg7XG5cblx0XHRcdFx0XHRpZiAobGluZVdpZHRoc1tsaW5lV2lkdGhzLmxlbmd0aCAtIDFdICsgd2lkdGggKyBsYWJlbE9wdHMucGFkZGluZyA+PSBtZS53aWR0aCkge1xuXHRcdFx0XHRcdFx0dG90YWxIZWlnaHQgKz0gZm9udFNpemUgKyAobGFiZWxPcHRzLnBhZGRpbmcpO1xuXHRcdFx0XHRcdFx0bGluZVdpZHRoc1tsaW5lV2lkdGhzLmxlbmd0aF0gPSBtZS5sZWZ0O1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFN0b3JlIHRoZSBoaXRib3ggd2lkdGggYW5kIGhlaWdodCBoZXJlLiBGaW5hbCBwb3NpdGlvbiB3aWxsIGJlIHVwZGF0ZWQgaW4gYGRyYXdgXG5cdFx0XHRcdFx0aGl0Ym94ZXNbaV0gPSB7XG5cdFx0XHRcdFx0XHRsZWZ0OiAwLFxuXHRcdFx0XHRcdFx0dG9wOiAwLFxuXHRcdFx0XHRcdFx0d2lkdGg6IHdpZHRoLFxuXHRcdFx0XHRcdFx0aGVpZ2h0OiBmb250U2l6ZVxuXHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRsaW5lV2lkdGhzW2xpbmVXaWR0aHMubGVuZ3RoIC0gMV0gKz0gd2lkdGggKyBsYWJlbE9wdHMucGFkZGluZztcblx0XHRcdFx0fSk7XG5cblx0XHRcdFx0bWluU2l6ZS5oZWlnaHQgKz0gdG90YWxIZWlnaHQ7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHZhciB2UGFkZGluZyA9IGxhYmVsT3B0cy5wYWRkaW5nO1xuXHRcdFx0XHR2YXIgY29sdW1uV2lkdGhzID0gbWUuY29sdW1uV2lkdGhzID0gW107XG5cdFx0XHRcdHZhciB0b3RhbFdpZHRoID0gbGFiZWxPcHRzLnBhZGRpbmc7XG5cdFx0XHRcdHZhciBjdXJyZW50Q29sV2lkdGggPSAwO1xuXHRcdFx0XHR2YXIgY3VycmVudENvbEhlaWdodCA9IDA7XG5cdFx0XHRcdHZhciBpdGVtSGVpZ2h0ID0gZm9udFNpemUgKyB2UGFkZGluZztcblxuXHRcdFx0XHRoZWxwZXJzLmVhY2gobWUubGVnZW5kSXRlbXMsIGZ1bmN0aW9uKGxlZ2VuZEl0ZW0sIGkpIHtcblx0XHRcdFx0XHR2YXIgYm94V2lkdGggPSBnZXRCb3hXaWR0aChsYWJlbE9wdHMsIGZvbnRTaXplKTtcblx0XHRcdFx0XHR2YXIgaXRlbVdpZHRoID0gYm94V2lkdGggKyAoZm9udFNpemUgLyAyKSArIGN0eC5tZWFzdXJlVGV4dChsZWdlbmRJdGVtLnRleHQpLndpZHRoO1xuXG5cdFx0XHRcdFx0Ly8gSWYgdG9vIHRhbGwsIGdvIHRvIG5ldyBjb2x1bW5cblx0XHRcdFx0XHRpZiAoY3VycmVudENvbEhlaWdodCArIGl0ZW1IZWlnaHQgPiBtaW5TaXplLmhlaWdodCkge1xuXHRcdFx0XHRcdFx0dG90YWxXaWR0aCArPSBjdXJyZW50Q29sV2lkdGggKyBsYWJlbE9wdHMucGFkZGluZztcblx0XHRcdFx0XHRcdGNvbHVtbldpZHRocy5wdXNoKGN1cnJlbnRDb2xXaWR0aCk7IC8vIHByZXZpb3VzIGNvbHVtbiB3aWR0aFxuXG5cdFx0XHRcdFx0XHRjdXJyZW50Q29sV2lkdGggPSAwO1xuXHRcdFx0XHRcdFx0Y3VycmVudENvbEhlaWdodCA9IDA7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gR2V0IG1heCB3aWR0aFxuXHRcdFx0XHRcdGN1cnJlbnRDb2xXaWR0aCA9IE1hdGgubWF4KGN1cnJlbnRDb2xXaWR0aCwgaXRlbVdpZHRoKTtcblx0XHRcdFx0XHRjdXJyZW50Q29sSGVpZ2h0ICs9IGl0ZW1IZWlnaHQ7XG5cblx0XHRcdFx0XHQvLyBTdG9yZSB0aGUgaGl0Ym94IHdpZHRoIGFuZCBoZWlnaHQgaGVyZS4gRmluYWwgcG9zaXRpb24gd2lsbCBiZSB1cGRhdGVkIGluIGBkcmF3YFxuXHRcdFx0XHRcdGhpdGJveGVzW2ldID0ge1xuXHRcdFx0XHRcdFx0bGVmdDogMCxcblx0XHRcdFx0XHRcdHRvcDogMCxcblx0XHRcdFx0XHRcdHdpZHRoOiBpdGVtV2lkdGgsXG5cdFx0XHRcdFx0XHRoZWlnaHQ6IGZvbnRTaXplXG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fSk7XG5cblx0XHRcdFx0dG90YWxXaWR0aCArPSBjdXJyZW50Q29sV2lkdGg7XG5cdFx0XHRcdGNvbHVtbldpZHRocy5wdXNoKGN1cnJlbnRDb2xXaWR0aCk7XG5cdFx0XHRcdG1pblNpemUud2lkdGggKz0gdG90YWxXaWR0aDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRtZS53aWR0aCA9IG1pblNpemUud2lkdGg7XG5cdFx0bWUuaGVpZ2h0ID0gbWluU2l6ZS5oZWlnaHQ7XG5cdH0sXG5cdGFmdGVyRml0OiBub29wLFxuXG5cdC8vIFNoYXJlZCBNZXRob2RzXG5cdGlzSG9yaXpvbnRhbDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMub3B0aW9ucy5wb3NpdGlvbiA9PT0gJ3RvcCcgfHwgdGhpcy5vcHRpb25zLnBvc2l0aW9uID09PSAnYm90dG9tJztcblx0fSxcblxuXHQvLyBBY3R1YWxseSBkcmF3IHRoZSBsZWdlbmQgb24gdGhlIGNhbnZhc1xuXHRkcmF3OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcblx0XHR2YXIgbGFiZWxPcHRzID0gb3B0cy5sYWJlbHM7XG5cdFx0dmFyIGdsb2JhbERlZmF1bHQgPSBkZWZhdWx0cy5nbG9iYWw7XG5cdFx0dmFyIGxpbmVEZWZhdWx0ID0gZ2xvYmFsRGVmYXVsdC5lbGVtZW50cy5saW5lO1xuXHRcdHZhciBsZWdlbmRXaWR0aCA9IG1lLndpZHRoO1xuXHRcdHZhciBsaW5lV2lkdGhzID0gbWUubGluZVdpZHRocztcblxuXHRcdGlmIChvcHRzLmRpc3BsYXkpIHtcblx0XHRcdHZhciBjdHggPSBtZS5jdHg7XG5cdFx0XHR2YXIgdmFsdWVPckRlZmF1bHQgPSBoZWxwZXJzLnZhbHVlT3JEZWZhdWx0O1xuXHRcdFx0dmFyIGZvbnRDb2xvciA9IHZhbHVlT3JEZWZhdWx0KGxhYmVsT3B0cy5mb250Q29sb3IsIGdsb2JhbERlZmF1bHQuZGVmYXVsdEZvbnRDb2xvcik7XG5cdFx0XHR2YXIgZm9udFNpemUgPSB2YWx1ZU9yRGVmYXVsdChsYWJlbE9wdHMuZm9udFNpemUsIGdsb2JhbERlZmF1bHQuZGVmYXVsdEZvbnRTaXplKTtcblx0XHRcdHZhciBmb250U3R5bGUgPSB2YWx1ZU9yRGVmYXVsdChsYWJlbE9wdHMuZm9udFN0eWxlLCBnbG9iYWxEZWZhdWx0LmRlZmF1bHRGb250U3R5bGUpO1xuXHRcdFx0dmFyIGZvbnRGYW1pbHkgPSB2YWx1ZU9yRGVmYXVsdChsYWJlbE9wdHMuZm9udEZhbWlseSwgZ2xvYmFsRGVmYXVsdC5kZWZhdWx0Rm9udEZhbWlseSk7XG5cdFx0XHR2YXIgbGFiZWxGb250ID0gaGVscGVycy5mb250U3RyaW5nKGZvbnRTaXplLCBmb250U3R5bGUsIGZvbnRGYW1pbHkpO1xuXHRcdFx0dmFyIGN1cnNvcjtcblxuXHRcdFx0Ly8gQ2FudmFzIHNldHVwXG5cdFx0XHRjdHgudGV4dEFsaWduID0gJ2xlZnQnO1xuXHRcdFx0Y3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuXHRcdFx0Y3R4LmxpbmVXaWR0aCA9IDAuNTtcblx0XHRcdGN0eC5zdHJva2VTdHlsZSA9IGZvbnRDb2xvcjsgLy8gZm9yIHN0cmlrZXRocm91Z2ggZWZmZWN0XG5cdFx0XHRjdHguZmlsbFN0eWxlID0gZm9udENvbG9yOyAvLyByZW5kZXIgaW4gY29ycmVjdCBjb2xvdXJcblx0XHRcdGN0eC5mb250ID0gbGFiZWxGb250O1xuXG5cdFx0XHR2YXIgYm94V2lkdGggPSBnZXRCb3hXaWR0aChsYWJlbE9wdHMsIGZvbnRTaXplKTtcblx0XHRcdHZhciBoaXRib3hlcyA9IG1lLmxlZ2VuZEhpdEJveGVzO1xuXG5cdFx0XHQvLyBjdXJyZW50IHBvc2l0aW9uXG5cdFx0XHR2YXIgZHJhd0xlZ2VuZEJveCA9IGZ1bmN0aW9uKHgsIHksIGxlZ2VuZEl0ZW0pIHtcblx0XHRcdFx0aWYgKGlzTmFOKGJveFdpZHRoKSB8fCBib3hXaWR0aCA8PSAwKSB7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gU2V0IHRoZSBjdHggZm9yIHRoZSBib3hcblx0XHRcdFx0Y3R4LnNhdmUoKTtcblxuXHRcdFx0XHRjdHguZmlsbFN0eWxlID0gdmFsdWVPckRlZmF1bHQobGVnZW5kSXRlbS5maWxsU3R5bGUsIGdsb2JhbERlZmF1bHQuZGVmYXVsdENvbG9yKTtcblx0XHRcdFx0Y3R4LmxpbmVDYXAgPSB2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLmxpbmVDYXAsIGxpbmVEZWZhdWx0LmJvcmRlckNhcFN0eWxlKTtcblx0XHRcdFx0Y3R4LmxpbmVEYXNoT2Zmc2V0ID0gdmFsdWVPckRlZmF1bHQobGVnZW5kSXRlbS5saW5lRGFzaE9mZnNldCwgbGluZURlZmF1bHQuYm9yZGVyRGFzaE9mZnNldCk7XG5cdFx0XHRcdGN0eC5saW5lSm9pbiA9IHZhbHVlT3JEZWZhdWx0KGxlZ2VuZEl0ZW0ubGluZUpvaW4sIGxpbmVEZWZhdWx0LmJvcmRlckpvaW5TdHlsZSk7XG5cdFx0XHRcdGN0eC5saW5lV2lkdGggPSB2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLmxpbmVXaWR0aCwgbGluZURlZmF1bHQuYm9yZGVyV2lkdGgpO1xuXHRcdFx0XHRjdHguc3Ryb2tlU3R5bGUgPSB2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLnN0cm9rZVN0eWxlLCBnbG9iYWxEZWZhdWx0LmRlZmF1bHRDb2xvcik7XG5cdFx0XHRcdHZhciBpc0xpbmVXaWR0aFplcm8gPSAodmFsdWVPckRlZmF1bHQobGVnZW5kSXRlbS5saW5lV2lkdGgsIGxpbmVEZWZhdWx0LmJvcmRlcldpZHRoKSA9PT0gMCk7XG5cblx0XHRcdFx0aWYgKGN0eC5zZXRMaW5lRGFzaCkge1xuXHRcdFx0XHRcdC8vIElFIDkgYW5kIDEwIGRvIG5vdCBzdXBwb3J0IGxpbmUgZGFzaFxuXHRcdFx0XHRcdGN0eC5zZXRMaW5lRGFzaCh2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLmxpbmVEYXNoLCBsaW5lRGVmYXVsdC5ib3JkZXJEYXNoKSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAob3B0cy5sYWJlbHMgJiYgb3B0cy5sYWJlbHMudXNlUG9pbnRTdHlsZSkge1xuXHRcdFx0XHRcdC8vIFJlY2FsY3VsYXRlIHggYW5kIHkgZm9yIGRyYXdQb2ludCgpIGJlY2F1c2UgaXRzIGV4cGVjdGluZ1xuXHRcdFx0XHRcdC8vIHggYW5kIHkgdG8gYmUgY2VudGVyIG9mIGZpZ3VyZSAoaW5zdGVhZCBvZiB0b3AgbGVmdClcblx0XHRcdFx0XHR2YXIgcmFkaXVzID0gZm9udFNpemUgKiBNYXRoLlNRUlQyIC8gMjtcblx0XHRcdFx0XHR2YXIgb2ZmU2V0ID0gcmFkaXVzIC8gTWF0aC5TUVJUMjtcblx0XHRcdFx0XHR2YXIgY2VudGVyWCA9IHggKyBvZmZTZXQ7XG5cdFx0XHRcdFx0dmFyIGNlbnRlclkgPSB5ICsgb2ZmU2V0O1xuXG5cdFx0XHRcdFx0Ly8gRHJhdyBwb2ludFN0eWxlIGFzIGxlZ2VuZCBzeW1ib2xcblx0XHRcdFx0XHRoZWxwZXJzLmNhbnZhcy5kcmF3UG9pbnQoY3R4LCBsZWdlbmRJdGVtLnBvaW50U3R5bGUsIHJhZGl1cywgY2VudGVyWCwgY2VudGVyWSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gRHJhdyBib3ggYXMgbGVnZW5kIHN5bWJvbFxuXHRcdFx0XHRcdGlmICghaXNMaW5lV2lkdGhaZXJvKSB7XG5cdFx0XHRcdFx0XHRjdHguc3Ryb2tlUmVjdCh4LCB5LCBib3hXaWR0aCwgZm9udFNpemUpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjdHguZmlsbFJlY3QoeCwgeSwgYm94V2lkdGgsIGZvbnRTaXplKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGN0eC5yZXN0b3JlKCk7XG5cdFx0XHR9O1xuXHRcdFx0dmFyIGZpbGxUZXh0ID0gZnVuY3Rpb24oeCwgeSwgbGVnZW5kSXRlbSwgdGV4dFdpZHRoKSB7XG5cdFx0XHRcdHZhciBoYWxmRm9udFNpemUgPSBmb250U2l6ZSAvIDI7XG5cdFx0XHRcdHZhciB4TGVmdCA9IGJveFdpZHRoICsgaGFsZkZvbnRTaXplICsgeDtcblx0XHRcdFx0dmFyIHlNaWRkbGUgPSB5ICsgaGFsZkZvbnRTaXplO1xuXG5cdFx0XHRcdGN0eC5maWxsVGV4dChsZWdlbmRJdGVtLnRleHQsIHhMZWZ0LCB5TWlkZGxlKTtcblxuXHRcdFx0XHRpZiAobGVnZW5kSXRlbS5oaWRkZW4pIHtcblx0XHRcdFx0XHQvLyBTdHJpa2V0aHJvdWdoIHRoZSB0ZXh0IGlmIGhpZGRlblxuXHRcdFx0XHRcdGN0eC5iZWdpblBhdGgoKTtcblx0XHRcdFx0XHRjdHgubGluZVdpZHRoID0gMjtcblx0XHRcdFx0XHRjdHgubW92ZVRvKHhMZWZ0LCB5TWlkZGxlKTtcblx0XHRcdFx0XHRjdHgubGluZVRvKHhMZWZ0ICsgdGV4dFdpZHRoLCB5TWlkZGxlKTtcblx0XHRcdFx0XHRjdHguc3Ryb2tlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHRcdC8vIEhvcml6b250YWxcblx0XHRcdHZhciBpc0hvcml6b250YWwgPSBtZS5pc0hvcml6b250YWwoKTtcblx0XHRcdGlmIChpc0hvcml6b250YWwpIHtcblx0XHRcdFx0Y3Vyc29yID0ge1xuXHRcdFx0XHRcdHg6IG1lLmxlZnQgKyAoKGxlZ2VuZFdpZHRoIC0gbGluZVdpZHRoc1swXSkgLyAyKSxcblx0XHRcdFx0XHR5OiBtZS50b3AgKyBsYWJlbE9wdHMucGFkZGluZyxcblx0XHRcdFx0XHRsaW5lOiAwXG5cdFx0XHRcdH07XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjdXJzb3IgPSB7XG5cdFx0XHRcdFx0eDogbWUubGVmdCArIGxhYmVsT3B0cy5wYWRkaW5nLFxuXHRcdFx0XHRcdHk6IG1lLnRvcCArIGxhYmVsT3B0cy5wYWRkaW5nLFxuXHRcdFx0XHRcdGxpbmU6IDBcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0dmFyIGl0ZW1IZWlnaHQgPSBmb250U2l6ZSArIGxhYmVsT3B0cy5wYWRkaW5nO1xuXHRcdFx0aGVscGVycy5lYWNoKG1lLmxlZ2VuZEl0ZW1zLCBmdW5jdGlvbihsZWdlbmRJdGVtLCBpKSB7XG5cdFx0XHRcdHZhciB0ZXh0V2lkdGggPSBjdHgubWVhc3VyZVRleHQobGVnZW5kSXRlbS50ZXh0KS53aWR0aDtcblx0XHRcdFx0dmFyIHdpZHRoID0gYm94V2lkdGggKyAoZm9udFNpemUgLyAyKSArIHRleHRXaWR0aDtcblx0XHRcdFx0dmFyIHggPSBjdXJzb3IueDtcblx0XHRcdFx0dmFyIHkgPSBjdXJzb3IueTtcblxuXHRcdFx0XHRpZiAoaXNIb3Jpem9udGFsKSB7XG5cdFx0XHRcdFx0aWYgKHggKyB3aWR0aCA+PSBsZWdlbmRXaWR0aCkge1xuXHRcdFx0XHRcdFx0eSA9IGN1cnNvci55ICs9IGl0ZW1IZWlnaHQ7XG5cdFx0XHRcdFx0XHRjdXJzb3IubGluZSsrO1xuXHRcdFx0XHRcdFx0eCA9IGN1cnNvci54ID0gbWUubGVmdCArICgobGVnZW5kV2lkdGggLSBsaW5lV2lkdGhzW2N1cnNvci5saW5lXSkgLyAyKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSBpZiAoeSArIGl0ZW1IZWlnaHQgPiBtZS5ib3R0b20pIHtcblx0XHRcdFx0XHR4ID0gY3Vyc29yLnggPSB4ICsgbWUuY29sdW1uV2lkdGhzW2N1cnNvci5saW5lXSArIGxhYmVsT3B0cy5wYWRkaW5nO1xuXHRcdFx0XHRcdHkgPSBjdXJzb3IueSA9IG1lLnRvcCArIGxhYmVsT3B0cy5wYWRkaW5nO1xuXHRcdFx0XHRcdGN1cnNvci5saW5lKys7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRkcmF3TGVnZW5kQm94KHgsIHksIGxlZ2VuZEl0ZW0pO1xuXG5cdFx0XHRcdGhpdGJveGVzW2ldLmxlZnQgPSB4O1xuXHRcdFx0XHRoaXRib3hlc1tpXS50b3AgPSB5O1xuXG5cdFx0XHRcdC8vIEZpbGwgdGhlIGFjdHVhbCBsYWJlbFxuXHRcdFx0XHRmaWxsVGV4dCh4LCB5LCBsZWdlbmRJdGVtLCB0ZXh0V2lkdGgpO1xuXG5cdFx0XHRcdGlmIChpc0hvcml6b250YWwpIHtcblx0XHRcdFx0XHRjdXJzb3IueCArPSB3aWR0aCArIChsYWJlbE9wdHMucGFkZGluZyk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y3Vyc29yLnkgKz0gaXRlbUhlaWdodDtcblx0XHRcdFx0fVxuXG5cdFx0XHR9KTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIEhhbmRsZSBhbiBldmVudFxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge0lFdmVudH0gZXZlbnQgLSBUaGUgZXZlbnQgdG8gaGFuZGxlXG5cdCAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgYSBjaGFuZ2Ugb2NjdXJlZFxuXHQgKi9cblx0aGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGUpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcblx0XHR2YXIgdHlwZSA9IGUudHlwZSA9PT0gJ21vdXNldXAnID8gJ2NsaWNrJyA6IGUudHlwZTtcblx0XHR2YXIgY2hhbmdlZCA9IGZhbHNlO1xuXG5cdFx0aWYgKHR5cGUgPT09ICdtb3VzZW1vdmUnKSB7XG5cdFx0XHRpZiAoIW9wdHMub25Ib3Zlcikge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmICh0eXBlID09PSAnY2xpY2snKSB7XG5cdFx0XHRpZiAoIW9wdHMub25DbGljaykge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBDaGFydCBldmVudCBhbHJlYWR5IGhhcyByZWxhdGl2ZSBwb3NpdGlvbiBpbiBpdFxuXHRcdHZhciB4ID0gZS54O1xuXHRcdHZhciB5ID0gZS55O1xuXG5cdFx0aWYgKHggPj0gbWUubGVmdCAmJiB4IDw9IG1lLnJpZ2h0ICYmIHkgPj0gbWUudG9wICYmIHkgPD0gbWUuYm90dG9tKSB7XG5cdFx0XHQvLyBTZWUgaWYgd2UgYXJlIHRvdWNoaW5nIG9uZSBvZiB0aGUgZGF0YXNldCBib3hlc1xuXHRcdFx0dmFyIGxoID0gbWUubGVnZW5kSGl0Qm94ZXM7XG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGxoLmxlbmd0aDsgKytpKSB7XG5cdFx0XHRcdHZhciBoaXRCb3ggPSBsaFtpXTtcblxuXHRcdFx0XHRpZiAoeCA+PSBoaXRCb3gubGVmdCAmJiB4IDw9IGhpdEJveC5sZWZ0ICsgaGl0Qm94LndpZHRoICYmIHkgPj0gaGl0Qm94LnRvcCAmJiB5IDw9IGhpdEJveC50b3AgKyBoaXRCb3guaGVpZ2h0KSB7XG5cdFx0XHRcdFx0Ly8gVG91Y2hpbmcgYW4gZWxlbWVudFxuXHRcdFx0XHRcdGlmICh0eXBlID09PSAnY2xpY2snKSB7XG5cdFx0XHRcdFx0XHQvLyB1c2UgZS5uYXRpdmUgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5cdFx0XHRcdFx0XHRvcHRzLm9uQ2xpY2suY2FsbChtZSwgZS5uYXRpdmUsIG1lLmxlZ2VuZEl0ZW1zW2ldKTtcblx0XHRcdFx0XHRcdGNoYW5nZWQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fSBlbHNlIGlmICh0eXBlID09PSAnbW91c2Vtb3ZlJykge1xuXHRcdFx0XHRcdFx0Ly8gdXNlIGUubmF0aXZlIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuXHRcdFx0XHRcdFx0b3B0cy5vbkhvdmVyLmNhbGwobWUsIGUubmF0aXZlLCBtZS5sZWdlbmRJdGVtc1tpXSk7XG5cdFx0XHRcdFx0XHRjaGFuZ2VkID0gdHJ1ZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBjaGFuZ2VkO1xuXHR9XG59KTtcblxuZnVuY3Rpb24gY3JlYXRlTmV3TGVnZW5kQW5kQXR0YWNoKGNoYXJ0LCBsZWdlbmRPcHRzKSB7XG5cdHZhciBsZWdlbmQgPSBuZXcgTGVnZW5kKHtcblx0XHRjdHg6IGNoYXJ0LmN0eCxcblx0XHRvcHRpb25zOiBsZWdlbmRPcHRzLFxuXHRcdGNoYXJ0OiBjaGFydFxuXHR9KTtcblxuXHRsYXlvdXRzLmNvbmZpZ3VyZShjaGFydCwgbGVnZW5kLCBsZWdlbmRPcHRzKTtcblx0bGF5b3V0cy5hZGRCb3goY2hhcnQsIGxlZ2VuZCk7XG5cdGNoYXJ0LmxlZ2VuZCA9IGxlZ2VuZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdGlkOiAnbGVnZW5kJyxcblxuXHQvKipcblx0ICogQmFja3dhcmQgY29tcGF0aWJpbGl0eTogc2luY2UgMi4xLjUsIHRoZSBsZWdlbmQgaXMgcmVnaXN0ZXJlZCBhcyBhIHBsdWdpbiwgbWFraW5nXG5cdCAqIENoYXJ0LkxlZ2VuZCBvYnNvbGV0ZS4gVG8gYXZvaWQgYSBicmVha2luZyBjaGFuZ2UsIHdlIGV4cG9ydCB0aGUgTGVnZW5kIGFzIHBhcnQgb2Zcblx0ICogdGhlIHBsdWdpbiwgd2hpY2ggb25lIHdpbGwgYmUgcmUtZXhwb3NlZCBpbiB0aGUgY2hhcnQuanMgZmlsZS5cblx0ICogaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvcHVsbC8yNjQwXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRfZWxlbWVudDogTGVnZW5kLFxuXG5cdGJlZm9yZUluaXQ6IGZ1bmN0aW9uKGNoYXJ0KSB7XG5cdFx0dmFyIGxlZ2VuZE9wdHMgPSBjaGFydC5vcHRpb25zLmxlZ2VuZDtcblxuXHRcdGlmIChsZWdlbmRPcHRzKSB7XG5cdFx0XHRjcmVhdGVOZXdMZWdlbmRBbmRBdHRhY2goY2hhcnQsIGxlZ2VuZE9wdHMpO1xuXHRcdH1cblx0fSxcblxuXHRiZWZvcmVVcGRhdGU6IGZ1bmN0aW9uKGNoYXJ0KSB7XG5cdFx0dmFyIGxlZ2VuZE9wdHMgPSBjaGFydC5vcHRpb25zLmxlZ2VuZDtcblx0XHR2YXIgbGVnZW5kID0gY2hhcnQubGVnZW5kO1xuXG5cdFx0aWYgKGxlZ2VuZE9wdHMpIHtcblx0XHRcdGhlbHBlcnMubWVyZ2VJZihsZWdlbmRPcHRzLCBkZWZhdWx0cy5nbG9iYWwubGVnZW5kKTtcblxuXHRcdFx0aWYgKGxlZ2VuZCkge1xuXHRcdFx0XHRsYXlvdXRzLmNvbmZpZ3VyZShjaGFydCwgbGVnZW5kLCBsZWdlbmRPcHRzKTtcblx0XHRcdFx0bGVnZW5kLm9wdGlvbnMgPSBsZWdlbmRPcHRzO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y3JlYXRlTmV3TGVnZW5kQW5kQXR0YWNoKGNoYXJ0LCBsZWdlbmRPcHRzKTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKGxlZ2VuZCkge1xuXHRcdFx0bGF5b3V0cy5yZW1vdmVCb3goY2hhcnQsIGxlZ2VuZCk7XG5cdFx0XHRkZWxldGUgY2hhcnQubGVnZW5kO1xuXHRcdH1cblx0fSxcblxuXHRhZnRlckV2ZW50OiBmdW5jdGlvbihjaGFydCwgZSkge1xuXHRcdHZhciBsZWdlbmQgPSBjaGFydC5sZWdlbmQ7XG5cdFx0aWYgKGxlZ2VuZCkge1xuXHRcdFx0bGVnZW5kLmhhbmRsZUV2ZW50KGUpO1xuXHRcdH1cblx0fVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///675a\n")},"6a4a":function(module,exports,__webpack_require__){"use strict";eval("/* global window: false */\n\n\nvar defaults = __webpack_require__(/*! ./core.defaults */ \"beaa\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\ndefaults._set('global', {\n\tanimation: {\n\t\tduration: 1000,\n\t\teasing: 'easeOutQuart',\n\t\tonProgress: helpers.noop,\n\t\tonComplete: helpers.noop\n\t}\n});\n\nmodule.exports = {\n\tframeDuration: 17,\n\tanimations: [],\n\tdropFrames: 0,\n\trequest: null,\n\n\t/**\n\t * @param {Chart} chart - The chart to animate.\n\t * @param {Chart.Animation} animation - The animation that we will animate.\n\t * @param {Number} duration - The animation duration in ms.\n\t * @param {Boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions\n\t */\n\taddAnimation: function(chart, animation, duration, lazy) {\n\t\tvar animations = this.animations;\n\t\tvar i, ilen;\n\n\t\tanimation.chart = chart;\n\n\t\tif (!lazy) {\n\t\t\tchart.animating = true;\n\t\t}\n\n\t\tfor (i = 0, ilen = animations.length; i < ilen; ++i) {\n\t\t\tif (animations[i].chart === chart) {\n\t\t\t\tanimations[i] = animation;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tanimations.push(animation);\n\n\t\t// If there are no animations queued, manually kickstart a digest, for lack of a better word\n\t\tif (animations.length === 1) {\n\t\t\tthis.requestAnimationFrame();\n\t\t}\n\t},\n\n\tcancelAnimation: function(chart) {\n\t\tvar index = helpers.findIndex(this.animations, function(animation) {\n\t\t\treturn animation.chart === chart;\n\t\t});\n\n\t\tif (index !== -1) {\n\t\t\tthis.animations.splice(index, 1);\n\t\t\tchart.animating = false;\n\t\t}\n\t},\n\n\trequestAnimationFrame: function() {\n\t\tvar me = this;\n\t\tif (me.request === null) {\n\t\t\t// Skip animation frame requests until the active one is executed.\n\t\t\t// This can happen when processing mouse events, e.g. 'mousemove'\n\t\t\t// and 'mouseout' events will trigger multiple renders.\n\t\t\tme.request = helpers.requestAnimFrame.call(window, function() {\n\t\t\t\tme.request = null;\n\t\t\t\tme.startDigest();\n\t\t\t});\n\t\t}\n\t},\n\n\t/**\n\t * @private\n\t */\n\tstartDigest: function() {\n\t\tvar me = this;\n\t\tvar startTime = Date.now();\n\t\tvar framesToDrop = 0;\n\n\t\tif (me.dropFrames > 1) {\n\t\t\tframesToDrop = Math.floor(me.dropFrames);\n\t\t\tme.dropFrames = me.dropFrames % 1;\n\t\t}\n\n\t\tme.advance(1 + framesToDrop);\n\n\t\tvar endTime = Date.now();\n\n\t\tme.dropFrames += (endTime - startTime) / me.frameDuration;\n\n\t\t// Do we have more stuff to animate?\n\t\tif (me.animations.length > 0) {\n\t\t\tme.requestAnimationFrame();\n\t\t}\n\t},\n\n\t/**\n\t * @private\n\t */\n\tadvance: function(count) {\n\t\tvar animations = this.animations;\n\t\tvar animation, chart;\n\t\tvar i = 0;\n\n\t\twhile (i < animations.length) {\n\t\t\tanimation = animations[i];\n\t\t\tchart = animation.chart;\n\n\t\t\tanimation.currentStep = (animation.currentStep || 0) + count;\n\t\t\tanimation.currentStep = Math.min(animation.currentStep, animation.numSteps);\n\n\t\t\thelpers.callback(animation.render, [chart, animation], chart);\n\t\t\thelpers.callback(animation.onAnimationProgress, [animation], chart);\n\n\t\t\tif (animation.currentStep >= animation.numSteps) {\n\t\t\t\thelpers.callback(animation.onAnimationComplete, [animation], chart);\n\t\t\t\tchart.animating = false;\n\t\t\t\tanimations.splice(i, 1);\n\t\t\t} else {\n\t\t\t\t++i;\n\t\t\t}\n\t\t}\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNmE0YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmFuaW1hdGlvbnMuanM/NzY5OSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBnbG9iYWwgd2luZG93OiBmYWxzZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2NvcmUuZGVmYXVsdHMnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xuXG5kZWZhdWx0cy5fc2V0KCdnbG9iYWwnLCB7XG5cdGFuaW1hdGlvbjoge1xuXHRcdGR1cmF0aW9uOiAxMDAwLFxuXHRcdGVhc2luZzogJ2Vhc2VPdXRRdWFydCcsXG5cdFx0b25Qcm9ncmVzczogaGVscGVycy5ub29wLFxuXHRcdG9uQ29tcGxldGU6IGhlbHBlcnMubm9vcFxuXHR9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdGZyYW1lRHVyYXRpb246IDE3LFxuXHRhbmltYXRpb25zOiBbXSxcblx0ZHJvcEZyYW1lczogMCxcblx0cmVxdWVzdDogbnVsbCxcblxuXHQvKipcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSBUaGUgY2hhcnQgdG8gYW5pbWF0ZS5cblx0ICogQHBhcmFtIHtDaGFydC5BbmltYXRpb259IGFuaW1hdGlvbiAtIFRoZSBhbmltYXRpb24gdGhhdCB3ZSB3aWxsIGFuaW1hdGUuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBkdXJhdGlvbiAtIFRoZSBhbmltYXRpb24gZHVyYXRpb24gaW4gbXMuXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gbGF6eSAtIGlmIHRydWUsIHRoZSBjaGFydCBpcyBub3QgbWFya2VkIGFzIGFuaW1hdGluZyB0byBlbmFibGUgbW9yZSByZXNwb25zaXZlIGludGVyYWN0aW9uc1xuXHQgKi9cblx0YWRkQW5pbWF0aW9uOiBmdW5jdGlvbihjaGFydCwgYW5pbWF0aW9uLCBkdXJhdGlvbiwgbGF6eSkge1xuXHRcdHZhciBhbmltYXRpb25zID0gdGhpcy5hbmltYXRpb25zO1xuXHRcdHZhciBpLCBpbGVuO1xuXG5cdFx0YW5pbWF0aW9uLmNoYXJ0ID0gY2hhcnQ7XG5cblx0XHRpZiAoIWxhenkpIHtcblx0XHRcdGNoYXJ0LmFuaW1hdGluZyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IGFuaW1hdGlvbnMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG5cdFx0XHRpZiAoYW5pbWF0aW9uc1tpXS5jaGFydCA9PT0gY2hhcnQpIHtcblx0XHRcdFx0YW5pbWF0aW9uc1tpXSA9IGFuaW1hdGlvbjtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGFuaW1hdGlvbnMucHVzaChhbmltYXRpb24pO1xuXG5cdFx0Ly8gSWYgdGhlcmUgYXJlIG5vIGFuaW1hdGlvbnMgcXVldWVkLCBtYW51YWxseSBraWNrc3RhcnQgYSBkaWdlc3QsIGZvciBsYWNrIG9mIGEgYmV0dGVyIHdvcmRcblx0XHRpZiAoYW5pbWF0aW9ucy5sZW5ndGggPT09IDEpIHtcblx0XHRcdHRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCk7XG5cdFx0fVxuXHR9LFxuXG5cdGNhbmNlbEFuaW1hdGlvbjogZnVuY3Rpb24oY2hhcnQpIHtcblx0XHR2YXIgaW5kZXggPSBoZWxwZXJzLmZpbmRJbmRleCh0aGlzLmFuaW1hdGlvbnMsIGZ1bmN0aW9uKGFuaW1hdGlvbikge1xuXHRcdFx0cmV0dXJuIGFuaW1hdGlvbi5jaGFydCA9PT0gY2hhcnQ7XG5cdFx0fSk7XG5cblx0XHRpZiAoaW5kZXggIT09IC0xKSB7XG5cdFx0XHR0aGlzLmFuaW1hdGlvbnMuc3BsaWNlKGluZGV4LCAxKTtcblx0XHRcdGNoYXJ0LmFuaW1hdGluZyA9IGZhbHNlO1xuXHRcdH1cblx0fSxcblxuXHRyZXF1ZXN0QW5pbWF0aW9uRnJhbWU6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0aWYgKG1lLnJlcXVlc3QgPT09IG51bGwpIHtcblx0XHRcdC8vIFNraXAgYW5pbWF0aW9uIGZyYW1lIHJlcXVlc3RzIHVudGlsIHRoZSBhY3RpdmUgb25lIGlzIGV4ZWN1dGVkLlxuXHRcdFx0Ly8gVGhpcyBjYW4gaGFwcGVuIHdoZW4gcHJvY2Vzc2luZyBtb3VzZSBldmVudHMsIGUuZy4gJ21vdXNlbW92ZSdcblx0XHRcdC8vIGFuZCAnbW91c2VvdXQnIGV2ZW50cyB3aWxsIHRyaWdnZXIgbXVsdGlwbGUgcmVuZGVycy5cblx0XHRcdG1lLnJlcXVlc3QgPSBoZWxwZXJzLnJlcXVlc3RBbmltRnJhbWUuY2FsbCh3aW5kb3csIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRtZS5yZXF1ZXN0ID0gbnVsbDtcblx0XHRcdFx0bWUuc3RhcnREaWdlc3QoKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogQHByaXZhdGVcblx0ICovXG5cdHN0YXJ0RGlnZXN0OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXHRcdHZhciBmcmFtZXNUb0Ryb3AgPSAwO1xuXG5cdFx0aWYgKG1lLmRyb3BGcmFtZXMgPiAxKSB7XG5cdFx0XHRmcmFtZXNUb0Ryb3AgPSBNYXRoLmZsb29yKG1lLmRyb3BGcmFtZXMpO1xuXHRcdFx0bWUuZHJvcEZyYW1lcyA9IG1lLmRyb3BGcmFtZXMgJSAxO1xuXHRcdH1cblxuXHRcdG1lLmFkdmFuY2UoMSArIGZyYW1lc1RvRHJvcCk7XG5cblx0XHR2YXIgZW5kVGltZSA9IERhdGUubm93KCk7XG5cblx0XHRtZS5kcm9wRnJhbWVzICs9IChlbmRUaW1lIC0gc3RhcnRUaW1lKSAvIG1lLmZyYW1lRHVyYXRpb247XG5cblx0XHQvLyBEbyB3ZSBoYXZlIG1vcmUgc3R1ZmYgdG8gYW5pbWF0ZT9cblx0XHRpZiAobWUuYW5pbWF0aW9ucy5sZW5ndGggPiAwKSB7XG5cdFx0XHRtZS5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRhZHZhbmNlOiBmdW5jdGlvbihjb3VudCkge1xuXHRcdHZhciBhbmltYXRpb25zID0gdGhpcy5hbmltYXRpb25zO1xuXHRcdHZhciBhbmltYXRpb24sIGNoYXJ0O1xuXHRcdHZhciBpID0gMDtcblxuXHRcdHdoaWxlIChpIDwgYW5pbWF0aW9ucy5sZW5ndGgpIHtcblx0XHRcdGFuaW1hdGlvbiA9IGFuaW1hdGlvbnNbaV07XG5cdFx0XHRjaGFydCA9IGFuaW1hdGlvbi5jaGFydDtcblxuXHRcdFx0YW5pbWF0aW9uLmN1cnJlbnRTdGVwID0gKGFuaW1hdGlvbi5jdXJyZW50U3RlcCB8fCAwKSArIGNvdW50O1xuXHRcdFx0YW5pbWF0aW9uLmN1cnJlbnRTdGVwID0gTWF0aC5taW4oYW5pbWF0aW9uLmN1cnJlbnRTdGVwLCBhbmltYXRpb24ubnVtU3RlcHMpO1xuXG5cdFx0XHRoZWxwZXJzLmNhbGxiYWNrKGFuaW1hdGlvbi5yZW5kZXIsIFtjaGFydCwgYW5pbWF0aW9uXSwgY2hhcnQpO1xuXHRcdFx0aGVscGVycy5jYWxsYmFjayhhbmltYXRpb24ub25BbmltYXRpb25Qcm9ncmVzcywgW2FuaW1hdGlvbl0sIGNoYXJ0KTtcblxuXHRcdFx0aWYgKGFuaW1hdGlvbi5jdXJyZW50U3RlcCA+PSBhbmltYXRpb24ubnVtU3RlcHMpIHtcblx0XHRcdFx0aGVscGVycy5jYWxsYmFjayhhbmltYXRpb24ub25BbmltYXRpb25Db21wbGV0ZSwgW2FuaW1hdGlvbl0sIGNoYXJ0KTtcblx0XHRcdFx0Y2hhcnQuYW5pbWF0aW5nID0gZmFsc2U7XG5cdFx0XHRcdGFuaW1hdGlvbnMuc3BsaWNlKGksIDEpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0KytpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6a4a\n")},"707c":function(module,exports,__webpack_require__){"use strict";eval("/**\n * Plugin based on discussion from the following Chart.js issues:\n * @see https://github.com/chartjs/Chart.js/issues/2380#issuecomment-279961569\n * @see https://github.com/chartjs/Chart.js/issues/2440#issuecomment-256461897\n */\n\n\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar elements = __webpack_require__(/*! ../elements/index */ \"0687\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\ndefaults._set('global', {\n\tplugins: {\n\t\tfiller: {\n\t\t\tpropagate: true\n\t\t}\n\t}\n});\n\nvar mappers = {\n\tdataset: function(source) {\n\t\tvar index = source.fill;\n\t\tvar chart = source.chart;\n\t\tvar meta = chart.getDatasetMeta(index);\n\t\tvar visible = meta && chart.isDatasetVisible(index);\n\t\tvar points = (visible && meta.dataset._children) || [];\n\t\tvar length = points.length || 0;\n\n\t\treturn !length ? null : function(point, i) {\n\t\t\treturn (i < length && points[i]._view) || null;\n\t\t};\n\t},\n\n\tboundary: function(source) {\n\t\tvar boundary = source.boundary;\n\t\tvar x = boundary ? boundary.x : null;\n\t\tvar y = boundary ? boundary.y : null;\n\n\t\treturn function(point) {\n\t\t\treturn {\n\t\t\t\tx: x === null ? point.x : x,\n\t\t\t\ty: y === null ? point.y : y,\n\t\t\t};\n\t\t};\n\t}\n};\n\n// @todo if (fill[0] === '#')\nfunction decodeFill(el, index, count) {\n\tvar model = el._model || {};\n\tvar fill = model.fill;\n\tvar target;\n\n\tif (fill === undefined) {\n\t\tfill = !!model.backgroundColor;\n\t}\n\n\tif (fill === false || fill === null) {\n\t\treturn false;\n\t}\n\n\tif (fill === true) {\n\t\treturn 'origin';\n\t}\n\n\ttarget = parseFloat(fill, 10);\n\tif (isFinite(target) && Math.floor(target) === target) {\n\t\tif (fill[0] === '-' || fill[0] === '+') {\n\t\t\ttarget = index + target;\n\t\t}\n\n\t\tif (target === index || target < 0 || target >= count) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn target;\n\t}\n\n\tswitch (fill) {\n\t// compatibility\n\tcase 'bottom':\n\t\treturn 'start';\n\tcase 'top':\n\t\treturn 'end';\n\tcase 'zero':\n\t\treturn 'origin';\n\t// supported boundaries\n\tcase 'origin':\n\tcase 'start':\n\tcase 'end':\n\t\treturn fill;\n\t// invalid fill values\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nfunction computeBoundary(source) {\n\tvar model = source.el._model || {};\n\tvar scale = source.el._scale || {};\n\tvar fill = source.fill;\n\tvar target = null;\n\tvar horizontal;\n\n\tif (isFinite(fill)) {\n\t\treturn null;\n\t}\n\n\t// Backward compatibility: until v3, we still need to support boundary values set on\n\t// the model (scaleTop, scaleBottom and scaleZero) because some external plugins and\n\t// controllers might still use it (e.g. the Smith chart).\n\n\tif (fill === 'start') {\n\t\ttarget = model.scaleBottom === undefined ? scale.bottom : model.scaleBottom;\n\t} else if (fill === 'end') {\n\t\ttarget = model.scaleTop === undefined ? scale.top : model.scaleTop;\n\t} else if (model.scaleZero !== undefined) {\n\t\ttarget = model.scaleZero;\n\t} else if (scale.getBasePosition) {\n\t\ttarget = scale.getBasePosition();\n\t} else if (scale.getBasePixel) {\n\t\ttarget = scale.getBasePixel();\n\t}\n\n\tif (target !== undefined && target !== null) {\n\t\tif (target.x !== undefined && target.y !== undefined) {\n\t\t\treturn target;\n\t\t}\n\n\t\tif (typeof target === 'number' && isFinite(target)) {\n\t\t\thorizontal = scale.isHorizontal();\n\t\t\treturn {\n\t\t\t\tx: horizontal ? target : null,\n\t\t\t\ty: horizontal ? null : target\n\t\t\t};\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction resolveTarget(sources, index, propagate) {\n\tvar source = sources[index];\n\tvar fill = source.fill;\n\tvar visited = [index];\n\tvar target;\n\n\tif (!propagate) {\n\t\treturn fill;\n\t}\n\n\twhile (fill !== false && visited.indexOf(fill) === -1) {\n\t\tif (!isFinite(fill)) {\n\t\t\treturn fill;\n\t\t}\n\n\t\ttarget = sources[fill];\n\t\tif (!target) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (target.visible) {\n\t\t\treturn fill;\n\t\t}\n\n\t\tvisited.push(fill);\n\t\tfill = target.fill;\n\t}\n\n\treturn false;\n}\n\nfunction createMapper(source) {\n\tvar fill = source.fill;\n\tvar type = 'dataset';\n\n\tif (fill === false) {\n\t\treturn null;\n\t}\n\n\tif (!isFinite(fill)) {\n\t\ttype = 'boundary';\n\t}\n\n\treturn mappers[type](source);\n}\n\nfunction isDrawable(point) {\n\treturn point && !point.skip;\n}\n\nfunction drawArea(ctx, curve0, curve1, len0, len1) {\n\tvar i;\n\n\tif (!len0 || !len1) {\n\t\treturn;\n\t}\n\n\t// building first area curve (normal)\n\tctx.moveTo(curve0[0].x, curve0[0].y);\n\tfor (i = 1; i < len0; ++i) {\n\t\thelpers.canvas.lineTo(ctx, curve0[i - 1], curve0[i]);\n\t}\n\n\t// joining the two area curves\n\tctx.lineTo(curve1[len1 - 1].x, curve1[len1 - 1].y);\n\n\t// building opposite area curve (reverse)\n\tfor (i = len1 - 1; i > 0; --i) {\n\t\thelpers.canvas.lineTo(ctx, curve1[i], curve1[i - 1], true);\n\t}\n}\n\nfunction doFill(ctx, points, mapper, view, color, loop) {\n\tvar count = points.length;\n\tvar span = view.spanGaps;\n\tvar curve0 = [];\n\tvar curve1 = [];\n\tvar len0 = 0;\n\tvar len1 = 0;\n\tvar i, ilen, index, p0, p1, d0, d1;\n\n\tctx.beginPath();\n\n\tfor (i = 0, ilen = (count + !!loop); i < ilen; ++i) {\n\t\tindex = i % count;\n\t\tp0 = points[index]._view;\n\t\tp1 = mapper(p0, index, view);\n\t\td0 = isDrawable(p0);\n\t\td1 = isDrawable(p1);\n\n\t\tif (d0 && d1) {\n\t\t\tlen0 = curve0.push(p0);\n\t\t\tlen1 = curve1.push(p1);\n\t\t} else if (len0 && len1) {\n\t\t\tif (!span) {\n\t\t\t\tdrawArea(ctx, curve0, curve1, len0, len1);\n\t\t\t\tlen0 = len1 = 0;\n\t\t\t\tcurve0 = [];\n\t\t\t\tcurve1 = [];\n\t\t\t} else {\n\t\t\t\tif (d0) {\n\t\t\t\t\tcurve0.push(p0);\n\t\t\t\t}\n\t\t\t\tif (d1) {\n\t\t\t\t\tcurve1.push(p1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdrawArea(ctx, curve0, curve1, len0, len1);\n\n\tctx.closePath();\n\tctx.fillStyle = color;\n\tctx.fill();\n}\n\nmodule.exports = {\n\tid: 'filler',\n\n\tafterDatasetsUpdate: function(chart, options) {\n\t\tvar count = (chart.data.datasets || []).length;\n\t\tvar propagate = options.propagate;\n\t\tvar sources = [];\n\t\tvar meta, i, el, source;\n\n\t\tfor (i = 0; i < count; ++i) {\n\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\tel = meta.dataset;\n\t\t\tsource = null;\n\n\t\t\tif (el && el._model && el instanceof elements.Line) {\n\t\t\t\tsource = {\n\t\t\t\t\tvisible: chart.isDatasetVisible(i),\n\t\t\t\t\tfill: decodeFill(el, i, count),\n\t\t\t\t\tchart: chart,\n\t\t\t\t\tel: el\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tmeta.$filler = source;\n\t\t\tsources.push(source);\n\t\t}\n\n\t\tfor (i = 0; i < count; ++i) {\n\t\t\tsource = sources[i];\n\t\t\tif (!source) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tsource.fill = resolveTarget(sources, i, propagate);\n\t\t\tsource.boundary = computeBoundary(source);\n\t\t\tsource.mapper = createMapper(source);\n\t\t}\n\t},\n\n\tbeforeDatasetDraw: function(chart, args) {\n\t\tvar meta = args.meta.$filler;\n\t\tif (!meta) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar ctx = chart.ctx;\n\t\tvar el = meta.el;\n\t\tvar view = el._view;\n\t\tvar points = el._children || [];\n\t\tvar mapper = meta.mapper;\n\t\tvar color = view.backgroundColor || defaults.global.defaultColor;\n\n\t\tif (mapper && color && points.length) {\n\t\t\thelpers.canvas.clipArea(ctx, chart.chartArea);\n\t\t\tdoFill(ctx, points, mapper, view, color, el._loop);\n\t\t\thelpers.canvas.unclipArea(ctx);\n\t\t}\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzA3Yy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4uZmlsbGVyLmpzP2JlOTMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQbHVnaW4gYmFzZWQgb24gZGlzY3Vzc2lvbiBmcm9tIHRoZSBmb2xsb3dpbmcgQ2hhcnQuanMgaXNzdWVzOlxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvMjM4MCNpc3N1ZWNvbW1lbnQtMjc5OTYxNTY5XG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8yNDQwI2lzc3VlY29tbWVudC0yNTY0NjE4OTdcbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5kZWZhdWx0cycpO1xudmFyIGVsZW1lbnRzID0gcmVxdWlyZSgnLi4vZWxlbWVudHMvaW5kZXgnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xuXG5kZWZhdWx0cy5fc2V0KCdnbG9iYWwnLCB7XG5cdHBsdWdpbnM6IHtcblx0XHRmaWxsZXI6IHtcblx0XHRcdHByb3BhZ2F0ZTogdHJ1ZVxuXHRcdH1cblx0fVxufSk7XG5cbnZhciBtYXBwZXJzID0ge1xuXHRkYXRhc2V0OiBmdW5jdGlvbihzb3VyY2UpIHtcblx0XHR2YXIgaW5kZXggPSBzb3VyY2UuZmlsbDtcblx0XHR2YXIgY2hhcnQgPSBzb3VyY2UuY2hhcnQ7XG5cdFx0dmFyIG1ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YShpbmRleCk7XG5cdFx0dmFyIHZpc2libGUgPSBtZXRhICYmIGNoYXJ0LmlzRGF0YXNldFZpc2libGUoaW5kZXgpO1xuXHRcdHZhciBwb2ludHMgPSAodmlzaWJsZSAmJiBtZXRhLmRhdGFzZXQuX2NoaWxkcmVuKSB8fCBbXTtcblx0XHR2YXIgbGVuZ3RoID0gcG9pbnRzLmxlbmd0aCB8fCAwO1xuXG5cdFx0cmV0dXJuICFsZW5ndGggPyBudWxsIDogZnVuY3Rpb24ocG9pbnQsIGkpIHtcblx0XHRcdHJldHVybiAoaSA8IGxlbmd0aCAmJiBwb2ludHNbaV0uX3ZpZXcpIHx8IG51bGw7XG5cdFx0fTtcblx0fSxcblxuXHRib3VuZGFyeTogZnVuY3Rpb24oc291cmNlKSB7XG5cdFx0dmFyIGJvdW5kYXJ5ID0gc291cmNlLmJvdW5kYXJ5O1xuXHRcdHZhciB4ID0gYm91bmRhcnkgPyBib3VuZGFyeS54IDogbnVsbDtcblx0XHR2YXIgeSA9IGJvdW5kYXJ5ID8gYm91bmRhcnkueSA6IG51bGw7XG5cblx0XHRyZXR1cm4gZnVuY3Rpb24ocG9pbnQpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdHg6IHggPT09IG51bGwgPyBwb2ludC54IDogeCxcblx0XHRcdFx0eTogeSA9PT0gbnVsbCA/IHBvaW50LnkgOiB5LFxuXHRcdFx0fTtcblx0XHR9O1xuXHR9XG59O1xuXG4vLyBAdG9kbyBpZiAoZmlsbFswXSA9PT0gJyMnKVxuZnVuY3Rpb24gZGVjb2RlRmlsbChlbCwgaW5kZXgsIGNvdW50KSB7XG5cdHZhciBtb2RlbCA9IGVsLl9tb2RlbCB8fCB7fTtcblx0dmFyIGZpbGwgPSBtb2RlbC5maWxsO1xuXHR2YXIgdGFyZ2V0O1xuXG5cdGlmIChmaWxsID09PSB1bmRlZmluZWQpIHtcblx0XHRmaWxsID0gISFtb2RlbC5iYWNrZ3JvdW5kQ29sb3I7XG5cdH1cblxuXHRpZiAoZmlsbCA9PT0gZmFsc2UgfHwgZmlsbCA9PT0gbnVsbCkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGlmIChmaWxsID09PSB0cnVlKSB7XG5cdFx0cmV0dXJuICdvcmlnaW4nO1xuXHR9XG5cblx0dGFyZ2V0ID0gcGFyc2VGbG9hdChmaWxsLCAxMCk7XG5cdGlmIChpc0Zpbml0ZSh0YXJnZXQpICYmIE1hdGguZmxvb3IodGFyZ2V0KSA9PT0gdGFyZ2V0KSB7XG5cdFx0aWYgKGZpbGxbMF0gPT09ICctJyB8fCBmaWxsWzBdID09PSAnKycpIHtcblx0XHRcdHRhcmdldCA9IGluZGV4ICsgdGFyZ2V0O1xuXHRcdH1cblxuXHRcdGlmICh0YXJnZXQgPT09IGluZGV4IHx8IHRhcmdldCA8IDAgfHwgdGFyZ2V0ID49IGNvdW50KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRhcmdldDtcblx0fVxuXG5cdHN3aXRjaCAoZmlsbCkge1xuXHQvLyBjb21wYXRpYmlsaXR5XG5cdGNhc2UgJ2JvdHRvbSc6XG5cdFx0cmV0dXJuICdzdGFydCc7XG5cdGNhc2UgJ3RvcCc6XG5cdFx0cmV0dXJuICdlbmQnO1xuXHRjYXNlICd6ZXJvJzpcblx0XHRyZXR1cm4gJ29yaWdpbic7XG5cdC8vIHN1cHBvcnRlZCBib3VuZGFyaWVzXG5cdGNhc2UgJ29yaWdpbic6XG5cdGNhc2UgJ3N0YXJ0Jzpcblx0Y2FzZSAnZW5kJzpcblx0XHRyZXR1cm4gZmlsbDtcblx0Ly8gaW52YWxpZCBmaWxsIHZhbHVlc1xuXHRkZWZhdWx0OlxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuXG5mdW5jdGlvbiBjb21wdXRlQm91bmRhcnkoc291cmNlKSB7XG5cdHZhciBtb2RlbCA9IHNvdXJjZS5lbC5fbW9kZWwgfHwge307XG5cdHZhciBzY2FsZSA9IHNvdXJjZS5lbC5fc2NhbGUgfHwge307XG5cdHZhciBmaWxsID0gc291cmNlLmZpbGw7XG5cdHZhciB0YXJnZXQgPSBudWxsO1xuXHR2YXIgaG9yaXpvbnRhbDtcblxuXHRpZiAoaXNGaW5pdGUoZmlsbCkpIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIEJhY2t3YXJkIGNvbXBhdGliaWxpdHk6IHVudGlsIHYzLCB3ZSBzdGlsbCBuZWVkIHRvIHN1cHBvcnQgYm91bmRhcnkgdmFsdWVzIHNldCBvblxuXHQvLyB0aGUgbW9kZWwgKHNjYWxlVG9wLCBzY2FsZUJvdHRvbSBhbmQgc2NhbGVaZXJvKSBiZWNhdXNlIHNvbWUgZXh0ZXJuYWwgcGx1Z2lucyBhbmRcblx0Ly8gY29udHJvbGxlcnMgbWlnaHQgc3RpbGwgdXNlIGl0IChlLmcuIHRoZSBTbWl0aCBjaGFydCkuXG5cblx0aWYgKGZpbGwgPT09ICdzdGFydCcpIHtcblx0XHR0YXJnZXQgPSBtb2RlbC5zY2FsZUJvdHRvbSA9PT0gdW5kZWZpbmVkID8gc2NhbGUuYm90dG9tIDogbW9kZWwuc2NhbGVCb3R0b207XG5cdH0gZWxzZSBpZiAoZmlsbCA9PT0gJ2VuZCcpIHtcblx0XHR0YXJnZXQgPSBtb2RlbC5zY2FsZVRvcCA9PT0gdW5kZWZpbmVkID8gc2NhbGUudG9wIDogbW9kZWwuc2NhbGVUb3A7XG5cdH0gZWxzZSBpZiAobW9kZWwuc2NhbGVaZXJvICE9PSB1bmRlZmluZWQpIHtcblx0XHR0YXJnZXQgPSBtb2RlbC5zY2FsZVplcm87XG5cdH0gZWxzZSBpZiAoc2NhbGUuZ2V0QmFzZVBvc2l0aW9uKSB7XG5cdFx0dGFyZ2V0ID0gc2NhbGUuZ2V0QmFzZVBvc2l0aW9uKCk7XG5cdH0gZWxzZSBpZiAoc2NhbGUuZ2V0QmFzZVBpeGVsKSB7XG5cdFx0dGFyZ2V0ID0gc2NhbGUuZ2V0QmFzZVBpeGVsKCk7XG5cdH1cblxuXHRpZiAodGFyZ2V0ICE9PSB1bmRlZmluZWQgJiYgdGFyZ2V0ICE9PSBudWxsKSB7XG5cdFx0aWYgKHRhcmdldC54ICE9PSB1bmRlZmluZWQgJiYgdGFyZ2V0LnkgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0cmV0dXJuIHRhcmdldDtcblx0XHR9XG5cblx0XHRpZiAodHlwZW9mIHRhcmdldCA9PT0gJ251bWJlcicgJiYgaXNGaW5pdGUodGFyZ2V0KSkge1xuXHRcdFx0aG9yaXpvbnRhbCA9IHNjYWxlLmlzSG9yaXpvbnRhbCgpO1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0eDogaG9yaXpvbnRhbCA/IHRhcmdldCA6IG51bGwsXG5cdFx0XHRcdHk6IGhvcml6b250YWwgPyBudWxsIDogdGFyZ2V0XG5cdFx0XHR9O1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlVGFyZ2V0KHNvdXJjZXMsIGluZGV4LCBwcm9wYWdhdGUpIHtcblx0dmFyIHNvdXJjZSA9IHNvdXJjZXNbaW5kZXhdO1xuXHR2YXIgZmlsbCA9IHNvdXJjZS5maWxsO1xuXHR2YXIgdmlzaXRlZCA9IFtpbmRleF07XG5cdHZhciB0YXJnZXQ7XG5cblx0aWYgKCFwcm9wYWdhdGUpIHtcblx0XHRyZXR1cm4gZmlsbDtcblx0fVxuXG5cdHdoaWxlIChmaWxsICE9PSBmYWxzZSAmJiB2aXNpdGVkLmluZGV4T2YoZmlsbCkgPT09IC0xKSB7XG5cdFx0aWYgKCFpc0Zpbml0ZShmaWxsKSkge1xuXHRcdFx0cmV0dXJuIGZpbGw7XG5cdFx0fVxuXG5cdFx0dGFyZ2V0ID0gc291cmNlc1tmaWxsXTtcblx0XHRpZiAoIXRhcmdldCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdGlmICh0YXJnZXQudmlzaWJsZSkge1xuXHRcdFx0cmV0dXJuIGZpbGw7XG5cdFx0fVxuXG5cdFx0dmlzaXRlZC5wdXNoKGZpbGwpO1xuXHRcdGZpbGwgPSB0YXJnZXQuZmlsbDtcblx0fVxuXG5cdHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlTWFwcGVyKHNvdXJjZSkge1xuXHR2YXIgZmlsbCA9IHNvdXJjZS5maWxsO1xuXHR2YXIgdHlwZSA9ICdkYXRhc2V0JztcblxuXHRpZiAoZmlsbCA9PT0gZmFsc2UpIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdGlmICghaXNGaW5pdGUoZmlsbCkpIHtcblx0XHR0eXBlID0gJ2JvdW5kYXJ5Jztcblx0fVxuXG5cdHJldHVybiBtYXBwZXJzW3R5cGVdKHNvdXJjZSk7XG59XG5cbmZ1bmN0aW9uIGlzRHJhd2FibGUocG9pbnQpIHtcblx0cmV0dXJuIHBvaW50ICYmICFwb2ludC5za2lwO1xufVxuXG5mdW5jdGlvbiBkcmF3QXJlYShjdHgsIGN1cnZlMCwgY3VydmUxLCBsZW4wLCBsZW4xKSB7XG5cdHZhciBpO1xuXG5cdGlmICghbGVuMCB8fCAhbGVuMSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIGJ1aWxkaW5nIGZpcnN0IGFyZWEgY3VydmUgKG5vcm1hbClcblx0Y3R4Lm1vdmVUbyhjdXJ2ZTBbMF0ueCwgY3VydmUwWzBdLnkpO1xuXHRmb3IgKGkgPSAxOyBpIDwgbGVuMDsgKytpKSB7XG5cdFx0aGVscGVycy5jYW52YXMubGluZVRvKGN0eCwgY3VydmUwW2kgLSAxXSwgY3VydmUwW2ldKTtcblx0fVxuXG5cdC8vIGpvaW5pbmcgdGhlIHR3byBhcmVhIGN1cnZlc1xuXHRjdHgubGluZVRvKGN1cnZlMVtsZW4xIC0gMV0ueCwgY3VydmUxW2xlbjEgLSAxXS55KTtcblxuXHQvLyBidWlsZGluZyBvcHBvc2l0ZSBhcmVhIGN1cnZlIChyZXZlcnNlKVxuXHRmb3IgKGkgPSBsZW4xIC0gMTsgaSA+IDA7IC0taSkge1xuXHRcdGhlbHBlcnMuY2FudmFzLmxpbmVUbyhjdHgsIGN1cnZlMVtpXSwgY3VydmUxW2kgLSAxXSwgdHJ1ZSk7XG5cdH1cbn1cblxuZnVuY3Rpb24gZG9GaWxsKGN0eCwgcG9pbnRzLCBtYXBwZXIsIHZpZXcsIGNvbG9yLCBsb29wKSB7XG5cdHZhciBjb3VudCA9IHBvaW50cy5sZW5ndGg7XG5cdHZhciBzcGFuID0gdmlldy5zcGFuR2Fwcztcblx0dmFyIGN1cnZlMCA9IFtdO1xuXHR2YXIgY3VydmUxID0gW107XG5cdHZhciBsZW4wID0gMDtcblx0dmFyIGxlbjEgPSAwO1xuXHR2YXIgaSwgaWxlbiwgaW5kZXgsIHAwLCBwMSwgZDAsIGQxO1xuXG5cdGN0eC5iZWdpblBhdGgoKTtcblxuXHRmb3IgKGkgPSAwLCBpbGVuID0gKGNvdW50ICsgISFsb29wKTsgaSA8IGlsZW47ICsraSkge1xuXHRcdGluZGV4ID0gaSAlIGNvdW50O1xuXHRcdHAwID0gcG9pbnRzW2luZGV4XS5fdmlldztcblx0XHRwMSA9IG1hcHBlcihwMCwgaW5kZXgsIHZpZXcpO1xuXHRcdGQwID0gaXNEcmF3YWJsZShwMCk7XG5cdFx0ZDEgPSBpc0RyYXdhYmxlKHAxKTtcblxuXHRcdGlmIChkMCAmJiBkMSkge1xuXHRcdFx0bGVuMCA9IGN1cnZlMC5wdXNoKHAwKTtcblx0XHRcdGxlbjEgPSBjdXJ2ZTEucHVzaChwMSk7XG5cdFx0fSBlbHNlIGlmIChsZW4wICYmIGxlbjEpIHtcblx0XHRcdGlmICghc3Bhbikge1xuXHRcdFx0XHRkcmF3QXJlYShjdHgsIGN1cnZlMCwgY3VydmUxLCBsZW4wLCBsZW4xKTtcblx0XHRcdFx0bGVuMCA9IGxlbjEgPSAwO1xuXHRcdFx0XHRjdXJ2ZTAgPSBbXTtcblx0XHRcdFx0Y3VydmUxID0gW107XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAoZDApIHtcblx0XHRcdFx0XHRjdXJ2ZTAucHVzaChwMCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGQxKSB7XG5cdFx0XHRcdFx0Y3VydmUxLnB1c2gocDEpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0ZHJhd0FyZWEoY3R4LCBjdXJ2ZTAsIGN1cnZlMSwgbGVuMCwgbGVuMSk7XG5cblx0Y3R4LmNsb3NlUGF0aCgpO1xuXHRjdHguZmlsbFN0eWxlID0gY29sb3I7XG5cdGN0eC5maWxsKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRpZDogJ2ZpbGxlcicsXG5cblx0YWZ0ZXJEYXRhc2V0c1VwZGF0ZTogZnVuY3Rpb24oY2hhcnQsIG9wdGlvbnMpIHtcblx0XHR2YXIgY291bnQgPSAoY2hhcnQuZGF0YS5kYXRhc2V0cyB8fCBbXSkubGVuZ3RoO1xuXHRcdHZhciBwcm9wYWdhdGUgPSBvcHRpb25zLnByb3BhZ2F0ZTtcblx0XHR2YXIgc291cmNlcyA9IFtdO1xuXHRcdHZhciBtZXRhLCBpLCBlbCwgc291cmNlO1xuXG5cdFx0Zm9yIChpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcblx0XHRcdG1ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YShpKTtcblx0XHRcdGVsID0gbWV0YS5kYXRhc2V0O1xuXHRcdFx0c291cmNlID0gbnVsbDtcblxuXHRcdFx0aWYgKGVsICYmIGVsLl9tb2RlbCAmJiBlbCBpbnN0YW5jZW9mIGVsZW1lbnRzLkxpbmUpIHtcblx0XHRcdFx0c291cmNlID0ge1xuXHRcdFx0XHRcdHZpc2libGU6IGNoYXJ0LmlzRGF0YXNldFZpc2libGUoaSksXG5cdFx0XHRcdFx0ZmlsbDogZGVjb2RlRmlsbChlbCwgaSwgY291bnQpLFxuXHRcdFx0XHRcdGNoYXJ0OiBjaGFydCxcblx0XHRcdFx0XHRlbDogZWxcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0bWV0YS4kZmlsbGVyID0gc291cmNlO1xuXHRcdFx0c291cmNlcy5wdXNoKHNvdXJjZSk7XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcblx0XHRcdHNvdXJjZSA9IHNvdXJjZXNbaV07XG5cdFx0XHRpZiAoIXNvdXJjZSkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0c291cmNlLmZpbGwgPSByZXNvbHZlVGFyZ2V0KHNvdXJjZXMsIGksIHByb3BhZ2F0ZSk7XG5cdFx0XHRzb3VyY2UuYm91bmRhcnkgPSBjb21wdXRlQm91bmRhcnkoc291cmNlKTtcblx0XHRcdHNvdXJjZS5tYXBwZXIgPSBjcmVhdGVNYXBwZXIoc291cmNlKTtcblx0XHR9XG5cdH0sXG5cblx0YmVmb3JlRGF0YXNldERyYXc6IGZ1bmN0aW9uKGNoYXJ0LCBhcmdzKSB7XG5cdFx0dmFyIG1ldGEgPSBhcmdzLm1ldGEuJGZpbGxlcjtcblx0XHRpZiAoIW1ldGEpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgY3R4ID0gY2hhcnQuY3R4O1xuXHRcdHZhciBlbCA9IG1ldGEuZWw7XG5cdFx0dmFyIHZpZXcgPSBlbC5fdmlldztcblx0XHR2YXIgcG9pbnRzID0gZWwuX2NoaWxkcmVuIHx8IFtdO1xuXHRcdHZhciBtYXBwZXIgPSBtZXRhLm1hcHBlcjtcblx0XHR2YXIgY29sb3IgPSB2aWV3LmJhY2tncm91bmRDb2xvciB8fCBkZWZhdWx0cy5nbG9iYWwuZGVmYXVsdENvbG9yO1xuXG5cdFx0aWYgKG1hcHBlciAmJiBjb2xvciAmJiBwb2ludHMubGVuZ3RoKSB7XG5cdFx0XHRoZWxwZXJzLmNhbnZhcy5jbGlwQXJlYShjdHgsIGNoYXJ0LmNoYXJ0QXJlYSk7XG5cdFx0XHRkb0ZpbGwoY3R4LCBwb2ludHMsIG1hcHBlciwgdmlldywgY29sb3IsIGVsLl9sb29wKTtcblx0XHRcdGhlbHBlcnMuY2FudmFzLnVuY2xpcEFyZWEoY3R4KTtcblx0XHR9XG5cdH1cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///707c\n")},"70b5":function(module,exports,__webpack_require__){eval('/**\n * @namespace Chart\n */\nvar Chart = __webpack_require__(/*! ./core/core */ "790a")();\n\nChart.helpers = __webpack_require__(/*! ./helpers/index */ "66c8");\n\n// @todo dispatch these helpers into appropriated helpers/helpers.* file and write unit tests!\n__webpack_require__(/*! ./core/core.helpers */ "fbd8")(Chart);\n\nChart.Animation = __webpack_require__(/*! ./core/core.animation */ "65bb");\nChart.animationService = __webpack_require__(/*! ./core/core.animations */ "6a4a");\nChart.defaults = __webpack_require__(/*! ./core/core.defaults */ "beaa");\nChart.Element = __webpack_require__(/*! ./core/core.element */ "4a45");\nChart.elements = __webpack_require__(/*! ./elements/index */ "0687");\nChart.Interaction = __webpack_require__(/*! ./core/core.interaction */ "6701");\nChart.layouts = __webpack_require__(/*! ./core/core.layouts */ "6705");\nChart.platform = __webpack_require__(/*! ./platforms/platform */ "8507");\nChart.plugins = __webpack_require__(/*! ./core/core.plugins */ "cb9d");\nChart.Scale = __webpack_require__(/*! ./core/core.scale */ "d1b4");\nChart.scaleService = __webpack_require__(/*! ./core/core.scaleService */ "7c56");\nChart.Ticks = __webpack_require__(/*! ./core/core.ticks */ "1220");\nChart.Tooltip = __webpack_require__(/*! ./core/core.tooltip */ "9af9");\n\n__webpack_require__(/*! ./core/core.controller */ "23a9")(Chart);\n__webpack_require__(/*! ./core/core.datasetController */ "612d")(Chart);\n\n__webpack_require__(/*! ./scales/scale.linearbase */ "2e15")(Chart);\n__webpack_require__(/*! ./scales/scale.category */ "57b3")(Chart);\n__webpack_require__(/*! ./scales/scale.linear */ "e866")(Chart);\n__webpack_require__(/*! ./scales/scale.logarithmic */ "f1c0")(Chart);\n__webpack_require__(/*! ./scales/scale.radialLinear */ "90fd")(Chart);\n__webpack_require__(/*! ./scales/scale.time */ "a87cc")(Chart);\n\n// Controllers must be loaded after elements\n// See Chart.core.datasetController.dataElementType\n__webpack_require__(/*! ./controllers/controller.bar */ "2bea")(Chart);\n__webpack_require__(/*! ./controllers/controller.bubble */ "7560")(Chart);\n__webpack_require__(/*! ./controllers/controller.doughnut */ "7dc6")(Chart);\n__webpack_require__(/*! ./controllers/controller.line */ "f3c1")(Chart);\n__webpack_require__(/*! ./controllers/controller.polarArea */ "1fc5")(Chart);\n__webpack_require__(/*! ./controllers/controller.radar */ "241a")(Chart);\n__webpack_require__(/*! ./controllers/controller.scatter */ "314a")(Chart);\n\n__webpack_require__(/*! ./charts/Chart.Bar */ "f0d9")(Chart);\n__webpack_require__(/*! ./charts/Chart.Bubble */ "9a10")(Chart);\n__webpack_require__(/*! ./charts/Chart.Doughnut */ "9778")(Chart);\n__webpack_require__(/*! ./charts/Chart.Line */ "803b")(Chart);\n__webpack_require__(/*! ./charts/Chart.PolarArea */ "5f7c")(Chart);\n__webpack_require__(/*! ./charts/Chart.Radar */ "bd22")(Chart);\n__webpack_require__(/*! ./charts/Chart.Scatter */ "8d36")(Chart);\n\n// Loading built-in plugins\nvar plugins = __webpack_require__(/*! ./plugins */ "0953");\nfor (var k in plugins) {\n\tif (plugins.hasOwnProperty(k)) {\n\t\tChart.plugins.register(plugins[k]);\n\t}\n}\n\nChart.platform.initialize();\n\nmodule.exports = Chart;\nif (typeof window !== \'undefined\') {\n\twindow.Chart = Chart;\n}\n\n// DEPRECATIONS\n\n/**\n * Provided for backward compatibility, not available anymore\n * @namespace Chart.Legend\n * @deprecated since version 2.1.5\n * @todo remove at version 3\n * @private\n */\nChart.Legend = plugins.legend._element;\n\n/**\n * Provided for backward compatibility, not available anymore\n * @namespace Chart.Title\n * @deprecated since version 2.1.5\n * @todo remove at version 3\n * @private\n */\nChart.Title = plugins.title._element;\n\n/**\n * Provided for backward compatibility, use Chart.plugins instead\n * @namespace Chart.pluginService\n * @deprecated since version 2.1.5\n * @todo remove at version 3\n * @private\n */\nChart.pluginService = Chart.plugins;\n\n/**\n * Provided for backward compatibility, inheriting from Chart.PlugingBase has no\n * effect, instead simply create/register plugins via plain JavaScript objects.\n * @interface Chart.PluginBase\n * @deprecated since version 2.5.0\n * @todo remove at version 3\n * @private\n */\nChart.PluginBase = Chart.Element.extend({});\n\n/**\n * Provided for backward compatibility, use Chart.helpers.canvas instead.\n * @namespace Chart.canvasHelpers\n * @deprecated since version 2.6.0\n * @todo remove at version 3\n * @private\n */\nChart.canvasHelpers = Chart.helpers.canvas;\n\n/**\n * Provided for backward compatibility, use Chart.layouts instead.\n * @namespace Chart.layoutService\n * @deprecated since version 2.8.0\n * @todo remove at version 3\n * @private\n */\nChart.layoutService = Chart.layouts;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzBiNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY2hhcnQuanM/NWIyMCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBuYW1lc3BhY2UgQ2hhcnRcbiAqL1xudmFyIENoYXJ0ID0gcmVxdWlyZSgnLi9jb3JlL2NvcmUnKSgpO1xuXG5DaGFydC5oZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzL2luZGV4Jyk7XG5cbi8vIEB0b2RvIGRpc3BhdGNoIHRoZXNlIGhlbHBlcnMgaW50byBhcHByb3ByaWF0ZWQgaGVscGVycy9oZWxwZXJzLiogZmlsZSBhbmQgd3JpdGUgdW5pdCB0ZXN0cyFcbnJlcXVpcmUoJy4vY29yZS9jb3JlLmhlbHBlcnMnKShDaGFydCk7XG5cbkNoYXJ0LkFuaW1hdGlvbiA9IHJlcXVpcmUoJy4vY29yZS9jb3JlLmFuaW1hdGlvbicpO1xuQ2hhcnQuYW5pbWF0aW9uU2VydmljZSA9IHJlcXVpcmUoJy4vY29yZS9jb3JlLmFuaW1hdGlvbnMnKTtcbkNoYXJ0LmRlZmF1bHRzID0gcmVxdWlyZSgnLi9jb3JlL2NvcmUuZGVmYXVsdHMnKTtcbkNoYXJ0LkVsZW1lbnQgPSByZXF1aXJlKCcuL2NvcmUvY29yZS5lbGVtZW50Jyk7XG5DaGFydC5lbGVtZW50cyA9IHJlcXVpcmUoJy4vZWxlbWVudHMvaW5kZXgnKTtcbkNoYXJ0LkludGVyYWN0aW9uID0gcmVxdWlyZSgnLi9jb3JlL2NvcmUuaW50ZXJhY3Rpb24nKTtcbkNoYXJ0LmxheW91dHMgPSByZXF1aXJlKCcuL2NvcmUvY29yZS5sYXlvdXRzJyk7XG5DaGFydC5wbGF0Zm9ybSA9IHJlcXVpcmUoJy4vcGxhdGZvcm1zL3BsYXRmb3JtJyk7XG5DaGFydC5wbHVnaW5zID0gcmVxdWlyZSgnLi9jb3JlL2NvcmUucGx1Z2lucycpO1xuQ2hhcnQuU2NhbGUgPSByZXF1aXJlKCcuL2NvcmUvY29yZS5zY2FsZScpO1xuQ2hhcnQuc2NhbGVTZXJ2aWNlID0gcmVxdWlyZSgnLi9jb3JlL2NvcmUuc2NhbGVTZXJ2aWNlJyk7XG5DaGFydC5UaWNrcyA9IHJlcXVpcmUoJy4vY29yZS9jb3JlLnRpY2tzJyk7XG5DaGFydC5Ub29sdGlwID0gcmVxdWlyZSgnLi9jb3JlL2NvcmUudG9vbHRpcCcpO1xuXG5yZXF1aXJlKCcuL2NvcmUvY29yZS5jb250cm9sbGVyJykoQ2hhcnQpO1xucmVxdWlyZSgnLi9jb3JlL2NvcmUuZGF0YXNldENvbnRyb2xsZXInKShDaGFydCk7XG5cbnJlcXVpcmUoJy4vc2NhbGVzL3NjYWxlLmxpbmVhcmJhc2UnKShDaGFydCk7XG5yZXF1aXJlKCcuL3NjYWxlcy9zY2FsZS5jYXRlZ29yeScpKENoYXJ0KTtcbnJlcXVpcmUoJy4vc2NhbGVzL3NjYWxlLmxpbmVhcicpKENoYXJ0KTtcbnJlcXVpcmUoJy4vc2NhbGVzL3NjYWxlLmxvZ2FyaXRobWljJykoQ2hhcnQpO1xucmVxdWlyZSgnLi9zY2FsZXMvc2NhbGUucmFkaWFsTGluZWFyJykoQ2hhcnQpO1xucmVxdWlyZSgnLi9zY2FsZXMvc2NhbGUudGltZScpKENoYXJ0KTtcblxuLy8gQ29udHJvbGxlcnMgbXVzdCBiZSBsb2FkZWQgYWZ0ZXIgZWxlbWVudHNcbi8vIFNlZSBDaGFydC5jb3JlLmRhdGFzZXRDb250cm9sbGVyLmRhdGFFbGVtZW50VHlwZVxucmVxdWlyZSgnLi9jb250cm9sbGVycy9jb250cm9sbGVyLmJhcicpKENoYXJ0KTtcbnJlcXVpcmUoJy4vY29udHJvbGxlcnMvY29udHJvbGxlci5idWJibGUnKShDaGFydCk7XG5yZXF1aXJlKCcuL2NvbnRyb2xsZXJzL2NvbnRyb2xsZXIuZG91Z2hudXQnKShDaGFydCk7XG5yZXF1aXJlKCcuL2NvbnRyb2xsZXJzL2NvbnRyb2xsZXIubGluZScpKENoYXJ0KTtcbnJlcXVpcmUoJy4vY29udHJvbGxlcnMvY29udHJvbGxlci5wb2xhckFyZWEnKShDaGFydCk7XG5yZXF1aXJlKCcuL2NvbnRyb2xsZXJzL2NvbnRyb2xsZXIucmFkYXInKShDaGFydCk7XG5yZXF1aXJlKCcuL2NvbnRyb2xsZXJzL2NvbnRyb2xsZXIuc2NhdHRlcicpKENoYXJ0KTtcblxucmVxdWlyZSgnLi9jaGFydHMvQ2hhcnQuQmFyJykoQ2hhcnQpO1xucmVxdWlyZSgnLi9jaGFydHMvQ2hhcnQuQnViYmxlJykoQ2hhcnQpO1xucmVxdWlyZSgnLi9jaGFydHMvQ2hhcnQuRG91Z2hudXQnKShDaGFydCk7XG5yZXF1aXJlKCcuL2NoYXJ0cy9DaGFydC5MaW5lJykoQ2hhcnQpO1xucmVxdWlyZSgnLi9jaGFydHMvQ2hhcnQuUG9sYXJBcmVhJykoQ2hhcnQpO1xucmVxdWlyZSgnLi9jaGFydHMvQ2hhcnQuUmFkYXInKShDaGFydCk7XG5yZXF1aXJlKCcuL2NoYXJ0cy9DaGFydC5TY2F0dGVyJykoQ2hhcnQpO1xuXG4vLyBMb2FkaW5nIGJ1aWx0LWluIHBsdWdpbnNcbnZhciBwbHVnaW5zID0gcmVxdWlyZSgnLi9wbHVnaW5zJyk7XG5mb3IgKHZhciBrIGluIHBsdWdpbnMpIHtcblx0aWYgKHBsdWdpbnMuaGFzT3duUHJvcGVydHkoaykpIHtcblx0XHRDaGFydC5wbHVnaW5zLnJlZ2lzdGVyKHBsdWdpbnNba10pO1xuXHR9XG59XG5cbkNoYXJ0LnBsYXRmb3JtLmluaXRpYWxpemUoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBDaGFydDtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuXHR3aW5kb3cuQ2hhcnQgPSBDaGFydDtcbn1cblxuLy8gREVQUkVDQVRJT05TXG5cbi8qKlxuICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIG5vdCBhdmFpbGFibGUgYW55bW9yZVxuICogQG5hbWVzcGFjZSBDaGFydC5MZWdlbmRcbiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi4xLjVcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcbiAqIEBwcml2YXRlXG4gKi9cbkNoYXJ0LkxlZ2VuZCA9IHBsdWdpbnMubGVnZW5kLl9lbGVtZW50O1xuXG4vKipcbiAqIFByb3ZpZGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCBub3QgYXZhaWxhYmxlIGFueW1vcmVcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuVGl0bGVcbiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi4xLjVcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcbiAqIEBwcml2YXRlXG4gKi9cbkNoYXJ0LlRpdGxlID0gcGx1Z2lucy50aXRsZS5fZWxlbWVudDtcblxuLyoqXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LnBsdWdpbnMgaW5zdGVhZFxuICogQG5hbWVzcGFjZSBDaGFydC5wbHVnaW5TZXJ2aWNlXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuMS41XG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXG4gKiBAcHJpdmF0ZVxuICovXG5DaGFydC5wbHVnaW5TZXJ2aWNlID0gQ2hhcnQucGx1Z2lucztcblxuLyoqXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgaW5oZXJpdGluZyBmcm9tIENoYXJ0LlBsdWdpbmdCYXNlIGhhcyBub1xuICogZWZmZWN0LCBpbnN0ZWFkIHNpbXBseSBjcmVhdGUvcmVnaXN0ZXIgcGx1Z2lucyB2aWEgcGxhaW4gSmF2YVNjcmlwdCBvYmplY3RzLlxuICogQGludGVyZmFjZSBDaGFydC5QbHVnaW5CYXNlXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNS4wXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXG4gKiBAcHJpdmF0ZVxuICovXG5DaGFydC5QbHVnaW5CYXNlID0gQ2hhcnQuRWxlbWVudC5leHRlbmQoe30pO1xuXG4vKipcbiAqIFByb3ZpZGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB1c2UgQ2hhcnQuaGVscGVycy5jYW52YXMgaW5zdGVhZC5cbiAqIEBuYW1lc3BhY2UgQ2hhcnQuY2FudmFzSGVscGVyc1xuICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjYuMFxuICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xuICogQHByaXZhdGVcbiAqL1xuQ2hhcnQuY2FudmFzSGVscGVycyA9IENoYXJ0LmhlbHBlcnMuY2FudmFzO1xuXG4vKipcbiAqIFByb3ZpZGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB1c2UgQ2hhcnQubGF5b3V0cyBpbnN0ZWFkLlxuICogQG5hbWVzcGFjZSBDaGFydC5sYXlvdXRTZXJ2aWNlXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuOC4wXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXG4gKiBAcHJpdmF0ZVxuICovXG5DaGFydC5sYXlvdXRTZXJ2aWNlID0gQ2hhcnQubGF5b3V0cztcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///70b5\n')},7542:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar helpers = __webpack_require__(/*! ./helpers.core */ \"7d23\");\n\n/**\n * @alias Chart.helpers.options\n * @namespace\n */\nmodule.exports = {\n\t/**\n\t * Converts the given line height `value` in pixels for a specific font `size`.\n\t * @param {Number|String} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em').\n\t * @param {Number} size - The font size (in pixels) used to resolve relative `value`.\n\t * @returns {Number} The effective line height in pixels (size * 1.2 if value is invalid).\n\t * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height\n\t * @since 2.7.0\n\t */\n\ttoLineHeight: function(value, size) {\n\t\tvar matches = ('' + value).match(/^(normal|(\\d+(?:\\.\\d+)?)(px|em|%)?)$/);\n\t\tif (!matches || matches[1] === 'normal') {\n\t\t\treturn size * 1.2;\n\t\t}\n\n\t\tvalue = +matches[2];\n\n\t\tswitch (matches[3]) {\n\t\tcase 'px':\n\t\t\treturn value;\n\t\tcase '%':\n\t\t\tvalue /= 100;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\treturn size * value;\n\t},\n\n\t/**\n\t * Converts the given value into a padding object with pre-computed width/height.\n\t * @param {Number|Object} value - If a number, set the value to all TRBL component,\n\t *  else, if and object, use defined properties and sets undefined ones to 0.\n\t * @returns {Object} The padding values (top, right, bottom, left, width, height)\n\t * @since 2.7.0\n\t */\n\ttoPadding: function(value) {\n\t\tvar t, r, b, l;\n\n\t\tif (helpers.isObject(value)) {\n\t\t\tt = +value.top || 0;\n\t\t\tr = +value.right || 0;\n\t\t\tb = +value.bottom || 0;\n\t\t\tl = +value.left || 0;\n\t\t} else {\n\t\t\tt = r = b = l = +value || 0;\n\t\t}\n\n\t\treturn {\n\t\t\ttop: t,\n\t\t\tright: r,\n\t\t\tbottom: b,\n\t\t\tleft: l,\n\t\t\theight: t + b,\n\t\t\twidth: l + r\n\t\t};\n\t},\n\n\t/**\n\t * Evaluates the given `inputs` sequentially and returns the first defined value.\n\t * @param {Array[]} inputs - An array of values, falling back to the last value.\n\t * @param {Object} [context] - If defined and the current value is a function, the value\n\t * is called with `context` as first argument and the result becomes the new input.\n\t * @param {Number} [index] - If defined and the current value is an array, the value\n\t * at `index` become the new input.\n\t * @since 2.7.0\n\t */\n\tresolve: function(inputs, context, index) {\n\t\tvar i, ilen, value;\n\n\t\tfor (i = 0, ilen = inputs.length; i < ilen; ++i) {\n\t\t\tvalue = inputs[i];\n\t\t\tif (value === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (context !== undefined && typeof value === 'function') {\n\t\t\t\tvalue = value(context);\n\t\t\t}\n\t\t\tif (index !== undefined && helpers.isArray(value)) {\n\t\t\t\tvalue = value[index];\n\t\t\t}\n\t\t\tif (value !== undefined) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzU0Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLm9wdGlvbnMuanM/MDJjZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzLmNvcmUnKTtcblxuLyoqXG4gKiBAYWxpYXMgQ2hhcnQuaGVscGVycy5vcHRpb25zXG4gKiBAbmFtZXNwYWNlXG4gKi9cbm1vZHVsZS5leHBvcnRzID0ge1xuXHQvKipcblx0ICogQ29udmVydHMgdGhlIGdpdmVuIGxpbmUgaGVpZ2h0IGB2YWx1ZWAgaW4gcGl4ZWxzIGZvciBhIHNwZWNpZmljIGZvbnQgYHNpemVgLlxuXHQgKiBAcGFyYW0ge051bWJlcnxTdHJpbmd9IHZhbHVlIC0gVGhlIGxpbmVIZWlnaHQgdG8gcGFyc2UgKGVnLiAxLjYsICcxNHB4JywgJzc1JScsICcxLjZlbScpLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gc2l6ZSAtIFRoZSBmb250IHNpemUgKGluIHBpeGVscykgdXNlZCB0byByZXNvbHZlIHJlbGF0aXZlIGB2YWx1ZWAuXG5cdCAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBlZmZlY3RpdmUgbGluZSBoZWlnaHQgaW4gcGl4ZWxzIChzaXplICogMS4yIGlmIHZhbHVlIGlzIGludmFsaWQpLlxuXHQgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9saW5lLWhlaWdodFxuXHQgKiBAc2luY2UgMi43LjBcblx0ICovXG5cdHRvTGluZUhlaWdodDogZnVuY3Rpb24odmFsdWUsIHNpemUpIHtcblx0XHR2YXIgbWF0Y2hlcyA9ICgnJyArIHZhbHVlKS5tYXRjaCgvXihub3JtYWx8KFxcZCsoPzpcXC5cXGQrKT8pKHB4fGVtfCUpPykkLyk7XG5cdFx0aWYgKCFtYXRjaGVzIHx8IG1hdGNoZXNbMV0gPT09ICdub3JtYWwnKSB7XG5cdFx0XHRyZXR1cm4gc2l6ZSAqIDEuMjtcblx0XHR9XG5cblx0XHR2YWx1ZSA9ICttYXRjaGVzWzJdO1xuXG5cdFx0c3dpdGNoIChtYXRjaGVzWzNdKSB7XG5cdFx0Y2FzZSAncHgnOlxuXHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdGNhc2UgJyUnOlxuXHRcdFx0dmFsdWUgLz0gMTAwO1xuXHRcdFx0YnJlYWs7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdGJyZWFrO1xuXHRcdH1cblxuXHRcdHJldHVybiBzaXplICogdmFsdWU7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIHRoZSBnaXZlbiB2YWx1ZSBpbnRvIGEgcGFkZGluZyBvYmplY3Qgd2l0aCBwcmUtY29tcHV0ZWQgd2lkdGgvaGVpZ2h0LlxuXHQgKiBAcGFyYW0ge051bWJlcnxPYmplY3R9IHZhbHVlIC0gSWYgYSBudW1iZXIsIHNldCB0aGUgdmFsdWUgdG8gYWxsIFRSQkwgY29tcG9uZW50LFxuXHQgKiAgZWxzZSwgaWYgYW5kIG9iamVjdCwgdXNlIGRlZmluZWQgcHJvcGVydGllcyBhbmQgc2V0cyB1bmRlZmluZWQgb25lcyB0byAwLlxuXHQgKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgcGFkZGluZyB2YWx1ZXMgKHRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdCwgd2lkdGgsIGhlaWdodClcblx0ICogQHNpbmNlIDIuNy4wXG5cdCAqL1xuXHR0b1BhZGRpbmc6IGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0dmFyIHQsIHIsIGIsIGw7XG5cblx0XHRpZiAoaGVscGVycy5pc09iamVjdCh2YWx1ZSkpIHtcblx0XHRcdHQgPSArdmFsdWUudG9wIHx8IDA7XG5cdFx0XHRyID0gK3ZhbHVlLnJpZ2h0IHx8IDA7XG5cdFx0XHRiID0gK3ZhbHVlLmJvdHRvbSB8fCAwO1xuXHRcdFx0bCA9ICt2YWx1ZS5sZWZ0IHx8IDA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHQgPSByID0gYiA9IGwgPSArdmFsdWUgfHwgMDtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0dG9wOiB0LFxuXHRcdFx0cmlnaHQ6IHIsXG5cdFx0XHRib3R0b206IGIsXG5cdFx0XHRsZWZ0OiBsLFxuXHRcdFx0aGVpZ2h0OiB0ICsgYixcblx0XHRcdHdpZHRoOiBsICsgclxuXHRcdH07XG5cdH0sXG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4gYGlucHV0c2Agc2VxdWVudGlhbGx5IGFuZCByZXR1cm5zIHRoZSBmaXJzdCBkZWZpbmVkIHZhbHVlLlxuXHQgKiBAcGFyYW0ge0FycmF5W119IGlucHV0cyAtIEFuIGFycmF5IG9mIHZhbHVlcywgZmFsbGluZyBiYWNrIHRvIHRoZSBsYXN0IHZhbHVlLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW2NvbnRleHRdIC0gSWYgZGVmaW5lZCBhbmQgdGhlIGN1cnJlbnQgdmFsdWUgaXMgYSBmdW5jdGlvbiwgdGhlIHZhbHVlXG5cdCAqIGlzIGNhbGxlZCB3aXRoIGBjb250ZXh0YCBhcyBmaXJzdCBhcmd1bWVudCBhbmQgdGhlIHJlc3VsdCBiZWNvbWVzIHRoZSBuZXcgaW5wdXQuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbaW5kZXhdIC0gSWYgZGVmaW5lZCBhbmQgdGhlIGN1cnJlbnQgdmFsdWUgaXMgYW4gYXJyYXksIHRoZSB2YWx1ZVxuXHQgKiBhdCBgaW5kZXhgIGJlY29tZSB0aGUgbmV3IGlucHV0LlxuXHQgKiBAc2luY2UgMi43LjBcblx0ICovXG5cdHJlc29sdmU6IGZ1bmN0aW9uKGlucHV0cywgY29udGV4dCwgaW5kZXgpIHtcblx0XHR2YXIgaSwgaWxlbiwgdmFsdWU7XG5cblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gaW5wdXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdFx0dmFsdWUgPSBpbnB1dHNbaV07XG5cdFx0XHRpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblx0XHRcdGlmIChjb250ZXh0ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRcdHZhbHVlID0gdmFsdWUoY29udGV4dCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoaW5kZXggIT09IHVuZGVmaW5lZCAmJiBoZWxwZXJzLmlzQXJyYXkodmFsdWUpKSB7XG5cdFx0XHRcdHZhbHVlID0gdmFsdWVbaW5kZXhdO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7542\n")},7560:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar elements = __webpack_require__(/*! ../elements/index */ \"0687\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\ndefaults._set('bubble', {\n\thover: {\n\t\tmode: 'single'\n\t},\n\n\tscales: {\n\t\txAxes: [{\n\t\t\ttype: 'linear', // bubble should probably use a linear scale by default\n\t\t\tposition: 'bottom',\n\t\t\tid: 'x-axis-0' // need an ID so datasets can reference the scale\n\t\t}],\n\t\tyAxes: [{\n\t\t\ttype: 'linear',\n\t\t\tposition: 'left',\n\t\t\tid: 'y-axis-0'\n\t\t}]\n\t},\n\n\ttooltips: {\n\t\tcallbacks: {\n\t\t\ttitle: function() {\n\t\t\t\t// Title doesn't make sense for scatter since we format the data as a point\n\t\t\t\treturn '';\n\t\t\t},\n\t\t\tlabel: function(item, data) {\n\t\t\t\tvar datasetLabel = data.datasets[item.datasetIndex].label || '';\n\t\t\t\tvar dataPoint = data.datasets[item.datasetIndex].data[item.index];\n\t\t\t\treturn datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')';\n\t\t\t}\n\t\t}\n\t}\n});\n\n\nmodule.exports = function(Chart) {\n\n\tChart.controllers.bubble = Chart.DatasetController.extend({\n\t\t/**\n\t\t * @protected\n\t\t */\n\t\tdataElementType: elements.Point,\n\n\t\t/**\n\t\t * @protected\n\t\t */\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar points = meta.data;\n\n\t\t\t// Update Points\n\t\t\thelpers.each(points, function(point, index) {\n\t\t\t\tme.updateElement(point, index, reset);\n\t\t\t});\n\t\t},\n\n\t\t/**\n\t\t * @protected\n\t\t */\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar xScale = me.getScaleForId(meta.xAxisID);\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar options = me._resolveElementOptions(point, index);\n\t\t\tvar data = me.getDataset().data[index];\n\t\t\tvar dsIndex = me.index;\n\n\t\t\tvar x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex);\n\t\t\tvar y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex);\n\n\t\t\tpoint._xScale = xScale;\n\t\t\tpoint._yScale = yScale;\n\t\t\tpoint._options = options;\n\t\t\tpoint._datasetIndex = dsIndex;\n\t\t\tpoint._index = index;\n\t\t\tpoint._model = {\n\t\t\t\tbackgroundColor: options.backgroundColor,\n\t\t\t\tborderColor: options.borderColor,\n\t\t\t\tborderWidth: options.borderWidth,\n\t\t\t\thitRadius: options.hitRadius,\n\t\t\t\tpointStyle: options.pointStyle,\n\t\t\t\trotation: options.rotation,\n\t\t\t\tradius: reset ? 0 : options.radius,\n\t\t\t\tskip: custom.skip || isNaN(x) || isNaN(y),\n\t\t\t\tx: x,\n\t\t\t\ty: y,\n\t\t\t};\n\n\t\t\tpoint.pivot();\n\t\t},\n\n\t\t/**\n\t\t * @protected\n\t\t */\n\t\tsetHoverStyle: function(point) {\n\t\t\tvar model = point._model;\n\t\t\tvar options = point._options;\n\t\t\tpoint.$previousStyle = {\n\t\t\t\tbackgroundColor: model.backgroundColor,\n\t\t\t\tborderColor: model.borderColor,\n\t\t\t\tborderWidth: model.borderWidth,\n\t\t\t\tradius: model.radius\n\t\t\t};\n\t\t\tmodel.backgroundColor = helpers.valueOrDefault(options.hoverBackgroundColor, helpers.getHoverColor(options.backgroundColor));\n\t\t\tmodel.borderColor = helpers.valueOrDefault(options.hoverBorderColor, helpers.getHoverColor(options.borderColor));\n\t\t\tmodel.borderWidth = helpers.valueOrDefault(options.hoverBorderWidth, options.borderWidth);\n\t\t\tmodel.radius = options.radius + options.hoverRadius;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\t_resolveElementOptions: function(point, index) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar datasets = chart.data.datasets;\n\t\t\tvar dataset = datasets[me.index];\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar options = chart.options.elements.point;\n\t\t\tvar resolve = helpers.options.resolve;\n\t\t\tvar data = dataset.data[index];\n\t\t\tvar values = {};\n\t\t\tvar i, ilen, key;\n\n\t\t\t// Scriptable options\n\t\t\tvar context = {\n\t\t\t\tchart: chart,\n\t\t\t\tdataIndex: index,\n\t\t\t\tdataset: dataset,\n\t\t\t\tdatasetIndex: me.index\n\t\t\t};\n\n\t\t\tvar keys = [\n\t\t\t\t'backgroundColor',\n\t\t\t\t'borderColor',\n\t\t\t\t'borderWidth',\n\t\t\t\t'hoverBackgroundColor',\n\t\t\t\t'hoverBorderColor',\n\t\t\t\t'hoverBorderWidth',\n\t\t\t\t'hoverRadius',\n\t\t\t\t'hitRadius',\n\t\t\t\t'pointStyle',\n\t\t\t\t'rotation'\n\t\t\t];\n\n\t\t\tfor (i = 0, ilen = keys.length; i < ilen; ++i) {\n\t\t\t\tkey = keys[i];\n\t\t\t\tvalues[key] = resolve([\n\t\t\t\t\tcustom[key],\n\t\t\t\t\tdataset[key],\n\t\t\t\t\toptions[key]\n\t\t\t\t], context, index);\n\t\t\t}\n\n\t\t\t// Custom radius resolution\n\t\t\tvalues.radius = resolve([\n\t\t\t\tcustom.radius,\n\t\t\t\tdata ? data.r : undefined,\n\t\t\t\tdataset.radius,\n\t\t\t\toptions.radius\n\t\t\t], context, index);\n\t\t\treturn values;\n\t\t}\n\t});\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzU2MC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5idWJibGUuanM/NmUyNyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5kZWZhdWx0cycpO1xudmFyIGVsZW1lbnRzID0gcmVxdWlyZSgnLi4vZWxlbWVudHMvaW5kZXgnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xuXG5kZWZhdWx0cy5fc2V0KCdidWJibGUnLCB7XG5cdGhvdmVyOiB7XG5cdFx0bW9kZTogJ3NpbmdsZSdcblx0fSxcblxuXHRzY2FsZXM6IHtcblx0XHR4QXhlczogW3tcblx0XHRcdHR5cGU6ICdsaW5lYXInLCAvLyBidWJibGUgc2hvdWxkIHByb2JhYmx5IHVzZSBhIGxpbmVhciBzY2FsZSBieSBkZWZhdWx0XG5cdFx0XHRwb3NpdGlvbjogJ2JvdHRvbScsXG5cdFx0XHRpZDogJ3gtYXhpcy0wJyAvLyBuZWVkIGFuIElEIHNvIGRhdGFzZXRzIGNhbiByZWZlcmVuY2UgdGhlIHNjYWxlXG5cdFx0fV0sXG5cdFx0eUF4ZXM6IFt7XG5cdFx0XHR0eXBlOiAnbGluZWFyJyxcblx0XHRcdHBvc2l0aW9uOiAnbGVmdCcsXG5cdFx0XHRpZDogJ3ktYXhpcy0wJ1xuXHRcdH1dXG5cdH0sXG5cblx0dG9vbHRpcHM6IHtcblx0XHRjYWxsYmFja3M6IHtcblx0XHRcdHRpdGxlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0Ly8gVGl0bGUgZG9lc24ndCBtYWtlIHNlbnNlIGZvciBzY2F0dGVyIHNpbmNlIHdlIGZvcm1hdCB0aGUgZGF0YSBhcyBhIHBvaW50XG5cdFx0XHRcdHJldHVybiAnJztcblx0XHRcdH0sXG5cdFx0XHRsYWJlbDogZnVuY3Rpb24oaXRlbSwgZGF0YSkge1xuXHRcdFx0XHR2YXIgZGF0YXNldExhYmVsID0gZGF0YS5kYXRhc2V0c1tpdGVtLmRhdGFzZXRJbmRleF0ubGFiZWwgfHwgJyc7XG5cdFx0XHRcdHZhciBkYXRhUG9pbnQgPSBkYXRhLmRhdGFzZXRzW2l0ZW0uZGF0YXNldEluZGV4XS5kYXRhW2l0ZW0uaW5kZXhdO1xuXHRcdFx0XHRyZXR1cm4gZGF0YXNldExhYmVsICsgJzogKCcgKyBpdGVtLnhMYWJlbCArICcsICcgKyBpdGVtLnlMYWJlbCArICcsICcgKyBkYXRhUG9pbnQuciArICcpJztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn0pO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oQ2hhcnQpIHtcblxuXHRDaGFydC5jb250cm9sbGVycy5idWJibGUgPSBDaGFydC5EYXRhc2V0Q29udHJvbGxlci5leHRlbmQoe1xuXHRcdC8qKlxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHRkYXRhRWxlbWVudFR5cGU6IGVsZW1lbnRzLlBvaW50LFxuXG5cdFx0LyoqXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHVwZGF0ZTogZnVuY3Rpb24ocmVzZXQpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgbWV0YSA9IG1lLmdldE1ldGEoKTtcblx0XHRcdHZhciBwb2ludHMgPSBtZXRhLmRhdGE7XG5cblx0XHRcdC8vIFVwZGF0ZSBQb2ludHNcblx0XHRcdGhlbHBlcnMuZWFjaChwb2ludHMsIGZ1bmN0aW9uKHBvaW50LCBpbmRleCkge1xuXHRcdFx0XHRtZS51cGRhdGVFbGVtZW50KHBvaW50LCBpbmRleCwgcmVzZXQpO1xuXHRcdFx0fSk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR1cGRhdGVFbGVtZW50OiBmdW5jdGlvbihwb2ludCwgaW5kZXgsIHJlc2V0KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG1ldGEgPSBtZS5nZXRNZXRhKCk7XG5cdFx0XHR2YXIgY3VzdG9tID0gcG9pbnQuY3VzdG9tIHx8IHt9O1xuXHRcdFx0dmFyIHhTY2FsZSA9IG1lLmdldFNjYWxlRm9ySWQobWV0YS54QXhpc0lEKTtcblx0XHRcdHZhciB5U2NhbGUgPSBtZS5nZXRTY2FsZUZvcklkKG1ldGEueUF4aXNJRCk7XG5cdFx0XHR2YXIgb3B0aW9ucyA9IG1lLl9yZXNvbHZlRWxlbWVudE9wdGlvbnMocG9pbnQsIGluZGV4KTtcblx0XHRcdHZhciBkYXRhID0gbWUuZ2V0RGF0YXNldCgpLmRhdGFbaW5kZXhdO1xuXHRcdFx0dmFyIGRzSW5kZXggPSBtZS5pbmRleDtcblxuXHRcdFx0dmFyIHggPSByZXNldCA/IHhTY2FsZS5nZXRQaXhlbEZvckRlY2ltYWwoMC41KSA6IHhTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHR5cGVvZiBkYXRhID09PSAnb2JqZWN0JyA/IGRhdGEgOiBOYU4sIGluZGV4LCBkc0luZGV4KTtcblx0XHRcdHZhciB5ID0gcmVzZXQgPyB5U2NhbGUuZ2V0QmFzZVBpeGVsKCkgOiB5U2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShkYXRhLCBpbmRleCwgZHNJbmRleCk7XG5cblx0XHRcdHBvaW50Ll94U2NhbGUgPSB4U2NhbGU7XG5cdFx0XHRwb2ludC5feVNjYWxlID0geVNjYWxlO1xuXHRcdFx0cG9pbnQuX29wdGlvbnMgPSBvcHRpb25zO1xuXHRcdFx0cG9pbnQuX2RhdGFzZXRJbmRleCA9IGRzSW5kZXg7XG5cdFx0XHRwb2ludC5faW5kZXggPSBpbmRleDtcblx0XHRcdHBvaW50Ll9tb2RlbCA9IHtcblx0XHRcdFx0YmFja2dyb3VuZENvbG9yOiBvcHRpb25zLmJhY2tncm91bmRDb2xvcixcblx0XHRcdFx0Ym9yZGVyQ29sb3I6IG9wdGlvbnMuYm9yZGVyQ29sb3IsXG5cdFx0XHRcdGJvcmRlcldpZHRoOiBvcHRpb25zLmJvcmRlcldpZHRoLFxuXHRcdFx0XHRoaXRSYWRpdXM6IG9wdGlvbnMuaGl0UmFkaXVzLFxuXHRcdFx0XHRwb2ludFN0eWxlOiBvcHRpb25zLnBvaW50U3R5bGUsXG5cdFx0XHRcdHJvdGF0aW9uOiBvcHRpb25zLnJvdGF0aW9uLFxuXHRcdFx0XHRyYWRpdXM6IHJlc2V0ID8gMCA6IG9wdGlvbnMucmFkaXVzLFxuXHRcdFx0XHRza2lwOiBjdXN0b20uc2tpcCB8fCBpc05hTih4KSB8fCBpc05hTih5KSxcblx0XHRcdFx0eDogeCxcblx0XHRcdFx0eTogeSxcblx0XHRcdH07XG5cblx0XHRcdHBvaW50LnBpdm90KCk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHRzZXRIb3ZlclN0eWxlOiBmdW5jdGlvbihwb2ludCkge1xuXHRcdFx0dmFyIG1vZGVsID0gcG9pbnQuX21vZGVsO1xuXHRcdFx0dmFyIG9wdGlvbnMgPSBwb2ludC5fb3B0aW9ucztcblx0XHRcdHBvaW50LiRwcmV2aW91c1N0eWxlID0ge1xuXHRcdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IG1vZGVsLmJhY2tncm91bmRDb2xvcixcblx0XHRcdFx0Ym9yZGVyQ29sb3I6IG1vZGVsLmJvcmRlckNvbG9yLFxuXHRcdFx0XHRib3JkZXJXaWR0aDogbW9kZWwuYm9yZGVyV2lkdGgsXG5cdFx0XHRcdHJhZGl1czogbW9kZWwucmFkaXVzXG5cdFx0XHR9O1xuXHRcdFx0bW9kZWwuYmFja2dyb3VuZENvbG9yID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdChvcHRpb25zLmhvdmVyQmFja2dyb3VuZENvbG9yLCBoZWxwZXJzLmdldEhvdmVyQ29sb3Iob3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IpKTtcblx0XHRcdG1vZGVsLmJvcmRlckNvbG9yID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdChvcHRpb25zLmhvdmVyQm9yZGVyQ29sb3IsIGhlbHBlcnMuZ2V0SG92ZXJDb2xvcihvcHRpb25zLmJvcmRlckNvbG9yKSk7XG5cdFx0XHRtb2RlbC5ib3JkZXJXaWR0aCA9IGhlbHBlcnMudmFsdWVPckRlZmF1bHQob3B0aW9ucy5ob3ZlckJvcmRlcldpZHRoLCBvcHRpb25zLmJvcmRlcldpZHRoKTtcblx0XHRcdG1vZGVsLnJhZGl1cyA9IG9wdGlvbnMucmFkaXVzICsgb3B0aW9ucy5ob3ZlclJhZGl1cztcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRfcmVzb2x2ZUVsZW1lbnRPcHRpb25zOiBmdW5jdGlvbihwb2ludCwgaW5kZXgpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcblx0XHRcdHZhciBkYXRhc2V0cyA9IGNoYXJ0LmRhdGEuZGF0YXNldHM7XG5cdFx0XHR2YXIgZGF0YXNldCA9IGRhdGFzZXRzW21lLmluZGV4XTtcblx0XHRcdHZhciBjdXN0b20gPSBwb2ludC5jdXN0b20gfHwge307XG5cdFx0XHR2YXIgb3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnMuZWxlbWVudHMucG9pbnQ7XG5cdFx0XHR2YXIgcmVzb2x2ZSA9IGhlbHBlcnMub3B0aW9ucy5yZXNvbHZlO1xuXHRcdFx0dmFyIGRhdGEgPSBkYXRhc2V0LmRhdGFbaW5kZXhdO1xuXHRcdFx0dmFyIHZhbHVlcyA9IHt9O1xuXHRcdFx0dmFyIGksIGlsZW4sIGtleTtcblxuXHRcdFx0Ly8gU2NyaXB0YWJsZSBvcHRpb25zXG5cdFx0XHR2YXIgY29udGV4dCA9IHtcblx0XHRcdFx0Y2hhcnQ6IGNoYXJ0LFxuXHRcdFx0XHRkYXRhSW5kZXg6IGluZGV4LFxuXHRcdFx0XHRkYXRhc2V0OiBkYXRhc2V0LFxuXHRcdFx0XHRkYXRhc2V0SW5kZXg6IG1lLmluZGV4XG5cdFx0XHR9O1xuXG5cdFx0XHR2YXIga2V5cyA9IFtcblx0XHRcdFx0J2JhY2tncm91bmRDb2xvcicsXG5cdFx0XHRcdCdib3JkZXJDb2xvcicsXG5cdFx0XHRcdCdib3JkZXJXaWR0aCcsXG5cdFx0XHRcdCdob3ZlckJhY2tncm91bmRDb2xvcicsXG5cdFx0XHRcdCdob3ZlckJvcmRlckNvbG9yJyxcblx0XHRcdFx0J2hvdmVyQm9yZGVyV2lkdGgnLFxuXHRcdFx0XHQnaG92ZXJSYWRpdXMnLFxuXHRcdFx0XHQnaGl0UmFkaXVzJyxcblx0XHRcdFx0J3BvaW50U3R5bGUnLFxuXHRcdFx0XHQncm90YXRpb24nXG5cdFx0XHRdO1xuXG5cdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0ga2V5cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdFx0a2V5ID0ga2V5c1tpXTtcblx0XHRcdFx0dmFsdWVzW2tleV0gPSByZXNvbHZlKFtcblx0XHRcdFx0XHRjdXN0b21ba2V5XSxcblx0XHRcdFx0XHRkYXRhc2V0W2tleV0sXG5cdFx0XHRcdFx0b3B0aW9uc1trZXldXG5cdFx0XHRcdF0sIGNvbnRleHQsIGluZGV4KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ3VzdG9tIHJhZGl1cyByZXNvbHV0aW9uXG5cdFx0XHR2YWx1ZXMucmFkaXVzID0gcmVzb2x2ZShbXG5cdFx0XHRcdGN1c3RvbS5yYWRpdXMsXG5cdFx0XHRcdGRhdGEgPyBkYXRhLnIgOiB1bmRlZmluZWQsXG5cdFx0XHRcdGRhdGFzZXQucmFkaXVzLFxuXHRcdFx0XHRvcHRpb25zLnJhZGl1c1xuXHRcdFx0XSwgY29udGV4dCwgaW5kZXgpO1xuXHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHR9XG5cdH0pO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7560\n")},"790a":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ./core.defaults */ \"beaa\");\n\ndefaults._set('global', {\n\tresponsive: true,\n\tresponsiveAnimationDuration: 0,\n\tmaintainAspectRatio: true,\n\tevents: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],\n\thover: {\n\t\tonHover: null,\n\t\tmode: 'nearest',\n\t\tintersect: true,\n\t\tanimationDuration: 400\n\t},\n\tonClick: null,\n\tdefaultColor: 'rgba(0,0,0,0.1)',\n\tdefaultFontColor: '#666',\n\tdefaultFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\tdefaultFontSize: 12,\n\tdefaultFontStyle: 'normal',\n\tshowLines: true,\n\n\t// Element defaults defined in element extensions\n\telements: {},\n\n\t// Layout options such as padding\n\tlayout: {\n\t\tpadding: {\n\t\t\ttop: 0,\n\t\t\tright: 0,\n\t\t\tbottom: 0,\n\t\t\tleft: 0\n\t\t}\n\t}\n});\n\nmodule.exports = function() {\n\n\t// Occupy the global variable of Chart, and create a simple base class\n\tvar Chart = function(item, config) {\n\t\tthis.construct(item, config);\n\t\treturn this;\n\t};\n\n\tChart.Chart = Chart;\n\n\treturn Chart;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzkwYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmpzP2M4ZjMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2NvcmUuZGVmYXVsdHMnKTtcblxuZGVmYXVsdHMuX3NldCgnZ2xvYmFsJywge1xuXHRyZXNwb25zaXZlOiB0cnVlLFxuXHRyZXNwb25zaXZlQW5pbWF0aW9uRHVyYXRpb246IDAsXG5cdG1haW50YWluQXNwZWN0UmF0aW86IHRydWUsXG5cdGV2ZW50czogWydtb3VzZW1vdmUnLCAnbW91c2VvdXQnLCAnY2xpY2snLCAndG91Y2hzdGFydCcsICd0b3VjaG1vdmUnXSxcblx0aG92ZXI6IHtcblx0XHRvbkhvdmVyOiBudWxsLFxuXHRcdG1vZGU6ICduZWFyZXN0Jyxcblx0XHRpbnRlcnNlY3Q6IHRydWUsXG5cdFx0YW5pbWF0aW9uRHVyYXRpb246IDQwMFxuXHR9LFxuXHRvbkNsaWNrOiBudWxsLFxuXHRkZWZhdWx0Q29sb3I6ICdyZ2JhKDAsMCwwLDAuMSknLFxuXHRkZWZhdWx0Rm9udENvbG9yOiAnIzY2NicsXG5cdGRlZmF1bHRGb250RmFtaWx5OiBcIidIZWx2ZXRpY2EgTmV1ZScsICdIZWx2ZXRpY2EnLCAnQXJpYWwnLCBzYW5zLXNlcmlmXCIsXG5cdGRlZmF1bHRGb250U2l6ZTogMTIsXG5cdGRlZmF1bHRGb250U3R5bGU6ICdub3JtYWwnLFxuXHRzaG93TGluZXM6IHRydWUsXG5cblx0Ly8gRWxlbWVudCBkZWZhdWx0cyBkZWZpbmVkIGluIGVsZW1lbnQgZXh0ZW5zaW9uc1xuXHRlbGVtZW50czoge30sXG5cblx0Ly8gTGF5b3V0IG9wdGlvbnMgc3VjaCBhcyBwYWRkaW5nXG5cdGxheW91dDoge1xuXHRcdHBhZGRpbmc6IHtcblx0XHRcdHRvcDogMCxcblx0XHRcdHJpZ2h0OiAwLFxuXHRcdFx0Ym90dG9tOiAwLFxuXHRcdFx0bGVmdDogMFxuXHRcdH1cblx0fVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG5cblx0Ly8gT2NjdXB5IHRoZSBnbG9iYWwgdmFyaWFibGUgb2YgQ2hhcnQsIGFuZCBjcmVhdGUgYSBzaW1wbGUgYmFzZSBjbGFzc1xuXHR2YXIgQ2hhcnQgPSBmdW5jdGlvbihpdGVtLCBjb25maWcpIHtcblx0XHR0aGlzLmNvbnN0cnVjdChpdGVtLCBjb25maWcpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9O1xuXG5cdENoYXJ0LkNoYXJ0ID0gQ2hhcnQ7XG5cblx0cmV0dXJuIENoYXJ0O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///790a\n")},"7c56":function(module,exports,__webpack_require__){"use strict";eval('\n\nvar defaults = __webpack_require__(/*! ./core.defaults */ "beaa");\nvar helpers = __webpack_require__(/*! ../helpers/index */ "66c8");\nvar layouts = __webpack_require__(/*! ./core.layouts */ "6705");\n\nmodule.exports = {\n\t// Scale registration object. Extensions can register new scale types (such as log or DB scales) and then\n\t// use the new chart options to grab the correct scale\n\tconstructors: {},\n\t// Use a registration function so that we can move to an ES6 map when we no longer need to support\n\t// old browsers\n\n\t// Scale config defaults\n\tdefaults: {},\n\tregisterScaleType: function(type, scaleConstructor, scaleDefaults) {\n\t\tthis.constructors[type] = scaleConstructor;\n\t\tthis.defaults[type] = helpers.clone(scaleDefaults);\n\t},\n\tgetScaleConstructor: function(type) {\n\t\treturn this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;\n\t},\n\tgetScaleDefaults: function(type) {\n\t\t// Return the scale defaults merged with the global settings so that we always use the latest ones\n\t\treturn this.defaults.hasOwnProperty(type) ? helpers.merge({}, [defaults.scale, this.defaults[type]]) : {};\n\t},\n\tupdateScaleDefaults: function(type, additions) {\n\t\tvar me = this;\n\t\tif (me.defaults.hasOwnProperty(type)) {\n\t\t\tme.defaults[type] = helpers.extend(me.defaults[type], additions);\n\t\t}\n\t},\n\taddScalesToLayout: function(chart) {\n\t\t// Adds each scale to the chart.boxes array to be sized accordingly\n\t\thelpers.each(chart.scales, function(scale) {\n\t\t\t// Set ILayoutItem parameters for backwards compatibility\n\t\t\tscale.fullWidth = scale.options.fullWidth;\n\t\t\tscale.position = scale.options.position;\n\t\t\tscale.weight = scale.options.weight;\n\t\t\tlayouts.addBox(chart, scale);\n\t\t});\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2M1Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLnNjYWxlU2VydmljZS5qcz9iNjMxIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmF1bHRzID0gcmVxdWlyZSgnLi9jb3JlLmRlZmF1bHRzJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcbnZhciBsYXlvdXRzID0gcmVxdWlyZSgnLi9jb3JlLmxheW91dHMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdC8vIFNjYWxlIHJlZ2lzdHJhdGlvbiBvYmplY3QuIEV4dGVuc2lvbnMgY2FuIHJlZ2lzdGVyIG5ldyBzY2FsZSB0eXBlcyAoc3VjaCBhcyBsb2cgb3IgREIgc2NhbGVzKSBhbmQgdGhlblxuXHQvLyB1c2UgdGhlIG5ldyBjaGFydCBvcHRpb25zIHRvIGdyYWIgdGhlIGNvcnJlY3Qgc2NhbGVcblx0Y29uc3RydWN0b3JzOiB7fSxcblx0Ly8gVXNlIGEgcmVnaXN0cmF0aW9uIGZ1bmN0aW9uIHNvIHRoYXQgd2UgY2FuIG1vdmUgdG8gYW4gRVM2IG1hcCB3aGVuIHdlIG5vIGxvbmdlciBuZWVkIHRvIHN1cHBvcnRcblx0Ly8gb2xkIGJyb3dzZXJzXG5cblx0Ly8gU2NhbGUgY29uZmlnIGRlZmF1bHRzXG5cdGRlZmF1bHRzOiB7fSxcblx0cmVnaXN0ZXJTY2FsZVR5cGU6IGZ1bmN0aW9uKHR5cGUsIHNjYWxlQ29uc3RydWN0b3IsIHNjYWxlRGVmYXVsdHMpIHtcblx0XHR0aGlzLmNvbnN0cnVjdG9yc1t0eXBlXSA9IHNjYWxlQ29uc3RydWN0b3I7XG5cdFx0dGhpcy5kZWZhdWx0c1t0eXBlXSA9IGhlbHBlcnMuY2xvbmUoc2NhbGVEZWZhdWx0cyk7XG5cdH0sXG5cdGdldFNjYWxlQ29uc3RydWN0b3I6IGZ1bmN0aW9uKHR5cGUpIHtcblx0XHRyZXR1cm4gdGhpcy5jb25zdHJ1Y3RvcnMuaGFzT3duUHJvcGVydHkodHlwZSkgPyB0aGlzLmNvbnN0cnVjdG9yc1t0eXBlXSA6IHVuZGVmaW5lZDtcblx0fSxcblx0Z2V0U2NhbGVEZWZhdWx0czogZnVuY3Rpb24odHlwZSkge1xuXHRcdC8vIFJldHVybiB0aGUgc2NhbGUgZGVmYXVsdHMgbWVyZ2VkIHdpdGggdGhlIGdsb2JhbCBzZXR0aW5ncyBzbyB0aGF0IHdlIGFsd2F5cyB1c2UgdGhlIGxhdGVzdCBvbmVzXG5cdFx0cmV0dXJuIHRoaXMuZGVmYXVsdHMuaGFzT3duUHJvcGVydHkodHlwZSkgPyBoZWxwZXJzLm1lcmdlKHt9LCBbZGVmYXVsdHMuc2NhbGUsIHRoaXMuZGVmYXVsdHNbdHlwZV1dKSA6IHt9O1xuXHR9LFxuXHR1cGRhdGVTY2FsZURlZmF1bHRzOiBmdW5jdGlvbih0eXBlLCBhZGRpdGlvbnMpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdGlmIChtZS5kZWZhdWx0cy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkge1xuXHRcdFx0bWUuZGVmYXVsdHNbdHlwZV0gPSBoZWxwZXJzLmV4dGVuZChtZS5kZWZhdWx0c1t0eXBlXSwgYWRkaXRpb25zKTtcblx0XHR9XG5cdH0sXG5cdGFkZFNjYWxlc1RvTGF5b3V0OiBmdW5jdGlvbihjaGFydCkge1xuXHRcdC8vIEFkZHMgZWFjaCBzY2FsZSB0byB0aGUgY2hhcnQuYm94ZXMgYXJyYXkgdG8gYmUgc2l6ZWQgYWNjb3JkaW5nbHlcblx0XHRoZWxwZXJzLmVhY2goY2hhcnQuc2NhbGVzLCBmdW5jdGlvbihzY2FsZSkge1xuXHRcdFx0Ly8gU2V0IElMYXlvdXRJdGVtIHBhcmFtZXRlcnMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5cdFx0XHRzY2FsZS5mdWxsV2lkdGggPSBzY2FsZS5vcHRpb25zLmZ1bGxXaWR0aDtcblx0XHRcdHNjYWxlLnBvc2l0aW9uID0gc2NhbGUub3B0aW9ucy5wb3NpdGlvbjtcblx0XHRcdHNjYWxlLndlaWdodCA9IHNjYWxlLm9wdGlvbnMud2VpZ2h0O1xuXHRcdFx0bGF5b3V0cy5hZGRCb3goY2hhcnQsIHNjYWxlKTtcblx0XHR9KTtcblx0fVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7c56\n')},"7d23":function(module,exports,__webpack_require__){"use strict";eval("\n\n/**\n * @namespace Chart.helpers\n */\nvar helpers = {\n\t/**\n\t * An empty function that can be used, for example, for optional callback.\n\t */\n\tnoop: function() {},\n\n\t/**\n\t * Returns a unique id, sequentially generated from a global variable.\n\t * @returns {Number}\n\t * @function\n\t */\n\tuid: (function() {\n\t\tvar id = 0;\n\t\treturn function() {\n\t\t\treturn id++;\n\t\t};\n\t}()),\n\n\t/**\n\t * Returns true if `value` is neither null nor undefined, else returns false.\n\t * @param {*} value - The value to test.\n\t * @returns {Boolean}\n\t * @since 2.7.0\n\t */\n\tisNullOrUndef: function(value) {\n\t\treturn value === null || typeof value === 'undefined';\n\t},\n\n\t/**\n\t * Returns true if `value` is an array, else returns false.\n\t * @param {*} value - The value to test.\n\t * @returns {Boolean}\n\t * @function\n\t */\n\tisArray: Array.isArray ? Array.isArray : function(value) {\n\t\treturn Object.prototype.toString.call(value) === '[object Array]';\n\t},\n\n\t/**\n\t * Returns true if `value` is an object (excluding null), else returns false.\n\t * @param {*} value - The value to test.\n\t * @returns {Boolean}\n\t * @since 2.7.0\n\t */\n\tisObject: function(value) {\n\t\treturn value !== null && Object.prototype.toString.call(value) === '[object Object]';\n\t},\n\n\t/**\n\t * Returns `value` if defined, else returns `defaultValue`.\n\t * @param {*} value - The value to return if defined.\n\t * @param {*} defaultValue - The value to return if `value` is undefined.\n\t * @returns {*}\n\t */\n\tvalueOrDefault: function(value, defaultValue) {\n\t\treturn typeof value === 'undefined' ? defaultValue : value;\n\t},\n\n\t/**\n\t * Returns value at the given `index` in array if defined, else returns `defaultValue`.\n\t * @param {Array} value - The array to lookup for value at `index`.\n\t * @param {Number} index - The index in `value` to lookup for value.\n\t * @param {*} defaultValue - The value to return if `value[index]` is undefined.\n\t * @returns {*}\n\t */\n\tvalueAtIndexOrDefault: function(value, index, defaultValue) {\n\t\treturn helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue);\n\t},\n\n\t/**\n\t * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the\n\t * value returned by `fn`. If `fn` is not a function, this method returns undefined.\n\t * @param {Function} fn - The function to call.\n\t * @param {Array|undefined|null} args - The arguments with which `fn` should be called.\n\t * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.\n\t * @returns {*}\n\t */\n\tcallback: function(fn, args, thisArg) {\n\t\tif (fn && typeof fn.call === 'function') {\n\t\t\treturn fn.apply(thisArg, args);\n\t\t}\n\t},\n\n\t/**\n\t * Note(SB) for performance sake, this method should only be used when loopable type\n\t * is unknown or in none intensive code (not called often and small loopable). Else\n\t * it's preferable to use a regular for() loop and save extra function calls.\n\t * @param {Object|Array} loopable - The object or array to be iterated.\n\t * @param {Function} fn - The function to call for each item.\n\t * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.\n\t * @param {Boolean} [reverse] - If true, iterates backward on the loopable.\n\t */\n\teach: function(loopable, fn, thisArg, reverse) {\n\t\tvar i, len, keys;\n\t\tif (helpers.isArray(loopable)) {\n\t\t\tlen = loopable.length;\n\t\t\tif (reverse) {\n\t\t\t\tfor (i = len - 1; i >= 0; i--) {\n\t\t\t\t\tfn.call(thisArg, loopable[i], i);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\t\tfn.call(thisArg, loopable[i], i);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (helpers.isObject(loopable)) {\n\t\t\tkeys = Object.keys(loopable);\n\t\t\tlen = keys.length;\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tfn.call(thisArg, loopable[keys[i]], keys[i]);\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Returns true if the `a0` and `a1` arrays have the same content, else returns false.\n\t * @see http://stackoverflow.com/a/14853974\n\t * @param {Array} a0 - The array to compare\n\t * @param {Array} a1 - The array to compare\n\t * @returns {Boolean}\n\t */\n\tarrayEquals: function(a0, a1) {\n\t\tvar i, ilen, v0, v1;\n\n\t\tif (!a0 || !a1 || a0.length !== a1.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (i = 0, ilen = a0.length; i < ilen; ++i) {\n\t\t\tv0 = a0[i];\n\t\t\tv1 = a1[i];\n\n\t\t\tif (v0 instanceof Array && v1 instanceof Array) {\n\t\t\t\tif (!helpers.arrayEquals(v0, v1)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else if (v0 !== v1) {\n\t\t\t\t// NOTE: two different object instances will never be equal: {x:20} != {x:20}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t},\n\n\t/**\n\t * Returns a deep copy of `source` without keeping references on objects and arrays.\n\t * @param {*} source - The value to clone.\n\t * @returns {*}\n\t */\n\tclone: function(source) {\n\t\tif (helpers.isArray(source)) {\n\t\t\treturn source.map(helpers.clone);\n\t\t}\n\n\t\tif (helpers.isObject(source)) {\n\t\t\tvar target = {};\n\t\t\tvar keys = Object.keys(source);\n\t\t\tvar klen = keys.length;\n\t\t\tvar k = 0;\n\n\t\t\tfor (; k < klen; ++k) {\n\t\t\t\ttarget[keys[k]] = helpers.clone(source[keys[k]]);\n\t\t\t}\n\n\t\t\treturn target;\n\t\t}\n\n\t\treturn source;\n\t},\n\n\t/**\n\t * The default merger when Chart.helpers.merge is called without merger option.\n\t * Note(SB): this method is also used by configMerge and scaleMerge as fallback.\n\t * @private\n\t */\n\t_merger: function(key, target, source, options) {\n\t\tvar tval = target[key];\n\t\tvar sval = source[key];\n\n\t\tif (helpers.isObject(tval) && helpers.isObject(sval)) {\n\t\t\thelpers.merge(tval, sval, options);\n\t\t} else {\n\t\t\ttarget[key] = helpers.clone(sval);\n\t\t}\n\t},\n\n\t/**\n\t * Merges source[key] in target[key] only if target[key] is undefined.\n\t * @private\n\t */\n\t_mergerIf: function(key, target, source) {\n\t\tvar tval = target[key];\n\t\tvar sval = source[key];\n\n\t\tif (helpers.isObject(tval) && helpers.isObject(sval)) {\n\t\t\thelpers.mergeIf(tval, sval);\n\t\t} else if (!target.hasOwnProperty(key)) {\n\t\t\ttarget[key] = helpers.clone(sval);\n\t\t}\n\t},\n\n\t/**\n\t * Recursively deep copies `source` properties into `target` with the given `options`.\n\t * IMPORTANT: `target` is not cloned and will be updated with `source` properties.\n\t * @param {Object} target - The target object in which all sources are merged into.\n\t * @param {Object|Array(Object)} source - Object(s) to merge into `target`.\n\t * @param {Object} [options] - Merging options:\n\t * @param {Function} [options.merger] - The merge method (key, target, source, options)\n\t * @returns {Object} The `target` object.\n\t */\n\tmerge: function(target, source, options) {\n\t\tvar sources = helpers.isArray(source) ? source : [source];\n\t\tvar ilen = sources.length;\n\t\tvar merge, i, keys, klen, k;\n\n\t\tif (!helpers.isObject(target)) {\n\t\t\treturn target;\n\t\t}\n\n\t\toptions = options || {};\n\t\tmerge = options.merger || helpers._merger;\n\n\t\tfor (i = 0; i < ilen; ++i) {\n\t\t\tsource = sources[i];\n\t\t\tif (!helpers.isObject(source)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tkeys = Object.keys(source);\n\t\t\tfor (k = 0, klen = keys.length; k < klen; ++k) {\n\t\t\t\tmerge(keys[k], target, source, options);\n\t\t\t}\n\t\t}\n\n\t\treturn target;\n\t},\n\n\t/**\n\t * Recursively deep copies `source` properties into `target` *only* if not defined in target.\n\t * IMPORTANT: `target` is not cloned and will be updated with `source` properties.\n\t * @param {Object} target - The target object in which all sources are merged into.\n\t * @param {Object|Array(Object)} source - Object(s) to merge into `target`.\n\t * @returns {Object} The `target` object.\n\t */\n\tmergeIf: function(target, source) {\n\t\treturn helpers.merge(target, source, {merger: helpers._mergerIf});\n\t},\n\n\t/**\n\t * Applies the contents of two or more objects together into the first object.\n\t * @param {Object} target - The target object in which all objects are merged into.\n\t * @param {Object} arg1 - Object containing additional properties to merge in target.\n\t * @param {Object} argN - Additional objects containing properties to merge in target.\n\t * @returns {Object} The `target` object.\n\t */\n\textend: function(target) {\n\t\tvar setFn = function(value, key) {\n\t\t\ttarget[key] = value;\n\t\t};\n\t\tfor (var i = 1, ilen = arguments.length; i < ilen; ++i) {\n\t\t\thelpers.each(arguments[i], setFn);\n\t\t}\n\t\treturn target;\n\t},\n\n\t/**\n\t * Basic javascript inheritance based on the model created in Backbone.js\n\t */\n\tinherits: function(extensions) {\n\t\tvar me = this;\n\t\tvar ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {\n\t\t\treturn me.apply(this, arguments);\n\t\t};\n\n\t\tvar Surrogate = function() {\n\t\t\tthis.constructor = ChartElement;\n\t\t};\n\n\t\tSurrogate.prototype = me.prototype;\n\t\tChartElement.prototype = new Surrogate();\n\t\tChartElement.extend = helpers.inherits;\n\n\t\tif (extensions) {\n\t\t\thelpers.extend(ChartElement.prototype, extensions);\n\t\t}\n\n\t\tChartElement.__super__ = me.prototype;\n\t\treturn ChartElement;\n\t}\n};\n\nmodule.exports = helpers;\n\n// DEPRECATIONS\n\n/**\n * Provided for backward compatibility, use Chart.helpers.callback instead.\n * @function Chart.helpers.callCallback\n * @deprecated since version 2.6.0\n * @todo remove at version 3\n * @private\n */\nhelpers.callCallback = helpers.callback;\n\n/**\n * Provided for backward compatibility, use Array.prototype.indexOf instead.\n * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+\n * @function Chart.helpers.indexOf\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers.indexOf = function(array, item, fromIndex) {\n\treturn Array.prototype.indexOf.call(array, item, fromIndex);\n};\n\n/**\n * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead.\n * @function Chart.helpers.getValueOrDefault\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers.getValueOrDefault = helpers.valueOrDefault;\n\n/**\n * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead.\n * @function Chart.helpers.getValueAtIndexOrDefault\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2QyMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLmNvcmUuanM/NGMyZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogQG5hbWVzcGFjZSBDaGFydC5oZWxwZXJzXG4gKi9cbnZhciBoZWxwZXJzID0ge1xuXHQvKipcblx0ICogQW4gZW1wdHkgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCwgZm9yIGV4YW1wbGUsIGZvciBvcHRpb25hbCBjYWxsYmFjay5cblx0ICovXG5cdG5vb3A6IGZ1bmN0aW9uKCkge30sXG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSB1bmlxdWUgaWQsIHNlcXVlbnRpYWxseSBnZW5lcmF0ZWQgZnJvbSBhIGdsb2JhbCB2YXJpYWJsZS5cblx0ICogQHJldHVybnMge051bWJlcn1cblx0ICogQGZ1bmN0aW9uXG5cdCAqL1xuXHR1aWQ6IChmdW5jdGlvbigpIHtcblx0XHR2YXIgaWQgPSAwO1xuXHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBpZCsrO1xuXHRcdH07XG5cdH0oKSksXG5cblx0LyoqXG5cdCAqIFJldHVybnMgdHJ1ZSBpZiBgdmFsdWVgIGlzIG5laXRoZXIgbnVsbCBub3IgdW5kZWZpbmVkLCBlbHNlIHJldHVybnMgZmFsc2UuXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gdGVzdC5cblx0ICogQHJldHVybnMge0Jvb2xlYW59XG5cdCAqIEBzaW5jZSAyLjcuMFxuXHQgKi9cblx0aXNOdWxsT3JVbmRlZjogZnVuY3Rpb24odmFsdWUpIHtcblx0XHRyZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJztcblx0fSxcblxuXHQvKipcblx0ICogUmV0dXJucyB0cnVlIGlmIGB2YWx1ZWAgaXMgYW4gYXJyYXksIGVsc2UgcmV0dXJucyBmYWxzZS5cblx0ICogQHBhcmFtIHsqfSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byB0ZXN0LlxuXHQgKiBAcmV0dXJucyB7Qm9vbGVhbn1cblx0ICogQGZ1bmN0aW9uXG5cdCAqL1xuXHRpc0FycmF5OiBBcnJheS5pc0FycmF5ID8gQXJyYXkuaXNBcnJheSA6IGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0cmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJldHVybnMgdHJ1ZSBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCAoZXhjbHVkaW5nIG51bGwpLCBlbHNlIHJldHVybnMgZmFsc2UuXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gdGVzdC5cblx0ICogQHJldHVybnMge0Jvb2xlYW59XG5cdCAqIEBzaW5jZSAyLjcuMFxuXHQgKi9cblx0aXNPYmplY3Q6IGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0cmV0dXJuIHZhbHVlICE9PSBudWxsICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT09ICdbb2JqZWN0IE9iamVjdF0nO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGB2YWx1ZWAgaWYgZGVmaW5lZCwgZWxzZSByZXR1cm5zIGBkZWZhdWx0VmFsdWVgLlxuXHQgKiBAcGFyYW0geyp9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIHJldHVybiBpZiBkZWZpbmVkLlxuXHQgKiBAcGFyYW0geyp9IGRlZmF1bHRWYWx1ZSAtIFRoZSB2YWx1ZSB0byByZXR1cm4gaWYgYHZhbHVlYCBpcyB1bmRlZmluZWQuXG5cdCAqIEByZXR1cm5zIHsqfVxuXHQgKi9cblx0dmFsdWVPckRlZmF1bHQ6IGZ1bmN0aW9uKHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcblx0XHRyZXR1cm4gdHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJyA/IGRlZmF1bHRWYWx1ZSA6IHZhbHVlO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHZhbHVlIGF0IHRoZSBnaXZlbiBgaW5kZXhgIGluIGFycmF5IGlmIGRlZmluZWQsIGVsc2UgcmV0dXJucyBgZGVmYXVsdFZhbHVlYC5cblx0ICogQHBhcmFtIHtBcnJheX0gdmFsdWUgLSBUaGUgYXJyYXkgdG8gbG9va3VwIGZvciB2YWx1ZSBhdCBgaW5kZXhgLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gaW5kZXggLSBUaGUgaW5kZXggaW4gYHZhbHVlYCB0byBsb29rdXAgZm9yIHZhbHVlLlxuXHQgKiBAcGFyYW0geyp9IGRlZmF1bHRWYWx1ZSAtIFRoZSB2YWx1ZSB0byByZXR1cm4gaWYgYHZhbHVlW2luZGV4XWAgaXMgdW5kZWZpbmVkLlxuXHQgKiBAcmV0dXJucyB7Kn1cblx0ICovXG5cdHZhbHVlQXRJbmRleE9yRGVmYXVsdDogZnVuY3Rpb24odmFsdWUsIGluZGV4LCBkZWZhdWx0VmFsdWUpIHtcblx0XHRyZXR1cm4gaGVscGVycy52YWx1ZU9yRGVmYXVsdChoZWxwZXJzLmlzQXJyYXkodmFsdWUpID8gdmFsdWVbaW5kZXhdIDogdmFsdWUsIGRlZmF1bHRWYWx1ZSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENhbGxzIGBmbmAgd2l0aCB0aGUgZ2l2ZW4gYGFyZ3NgIGluIHRoZSBzY29wZSBkZWZpbmVkIGJ5IGB0aGlzQXJnYCBhbmQgcmV0dXJucyB0aGVcblx0ICogdmFsdWUgcmV0dXJuZWQgYnkgYGZuYC4gSWYgYGZuYCBpcyBub3QgYSBmdW5jdGlvbiwgdGhpcyBtZXRob2QgcmV0dXJucyB1bmRlZmluZWQuXG5cdCAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gVGhlIGZ1bmN0aW9uIHRvIGNhbGwuXG5cdCAqIEBwYXJhbSB7QXJyYXl8dW5kZWZpbmVkfG51bGx9IGFyZ3MgLSBUaGUgYXJndW1lbnRzIHdpdGggd2hpY2ggYGZuYCBzaG91bGQgYmUgY2FsbGVkLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW3RoaXNBcmddIC0gVGhlIHZhbHVlIG9mIGB0aGlzYCBwcm92aWRlZCBmb3IgdGhlIGNhbGwgdG8gYGZuYC5cblx0ICogQHJldHVybnMgeyp9XG5cdCAqL1xuXHRjYWxsYmFjazogZnVuY3Rpb24oZm4sIGFyZ3MsIHRoaXNBcmcpIHtcblx0XHRpZiAoZm4gJiYgdHlwZW9mIGZuLmNhbGwgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdHJldHVybiBmbi5hcHBseSh0aGlzQXJnLCBhcmdzKTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIE5vdGUoU0IpIGZvciBwZXJmb3JtYW5jZSBzYWtlLCB0aGlzIG1ldGhvZCBzaG91bGQgb25seSBiZSB1c2VkIHdoZW4gbG9vcGFibGUgdHlwZVxuXHQgKiBpcyB1bmtub3duIG9yIGluIG5vbmUgaW50ZW5zaXZlIGNvZGUgKG5vdCBjYWxsZWQgb2Z0ZW4gYW5kIHNtYWxsIGxvb3BhYmxlKS4gRWxzZVxuXHQgKiBpdCdzIHByZWZlcmFibGUgdG8gdXNlIGEgcmVndWxhciBmb3IoKSBsb29wIGFuZCBzYXZlIGV4dHJhIGZ1bmN0aW9uIGNhbGxzLlxuXHQgKiBAcGFyYW0ge09iamVjdHxBcnJheX0gbG9vcGFibGUgLSBUaGUgb2JqZWN0IG9yIGFycmF5IHRvIGJlIGl0ZXJhdGVkLlxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIFRoZSBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGl0ZW0uXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbdGhpc0FyZ10gLSBUaGUgdmFsdWUgb2YgYHRoaXNgIHByb3ZpZGVkIGZvciB0aGUgY2FsbCB0byBgZm5gLlxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtyZXZlcnNlXSAtIElmIHRydWUsIGl0ZXJhdGVzIGJhY2t3YXJkIG9uIHRoZSBsb29wYWJsZS5cblx0ICovXG5cdGVhY2g6IGZ1bmN0aW9uKGxvb3BhYmxlLCBmbiwgdGhpc0FyZywgcmV2ZXJzZSkge1xuXHRcdHZhciBpLCBsZW4sIGtleXM7XG5cdFx0aWYgKGhlbHBlcnMuaXNBcnJheShsb29wYWJsZSkpIHtcblx0XHRcdGxlbiA9IGxvb3BhYmxlLmxlbmd0aDtcblx0XHRcdGlmIChyZXZlcnNlKSB7XG5cdFx0XHRcdGZvciAoaSA9IGxlbiAtIDE7IGkgPj0gMDsgaS0tKSB7XG5cdFx0XHRcdFx0Zm4uY2FsbCh0aGlzQXJnLCBsb29wYWJsZVtpXSwgaSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0XHRcdGZuLmNhbGwodGhpc0FyZywgbG9vcGFibGVbaV0sIGkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChoZWxwZXJzLmlzT2JqZWN0KGxvb3BhYmxlKSkge1xuXHRcdFx0a2V5cyA9IE9iamVjdC5rZXlzKGxvb3BhYmxlKTtcblx0XHRcdGxlbiA9IGtleXMubGVuZ3RoO1xuXHRcdFx0Zm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRcdGZuLmNhbGwodGhpc0FyZywgbG9vcGFibGVba2V5c1tpXV0sIGtleXNbaV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUmV0dXJucyB0cnVlIGlmIHRoZSBgYTBgIGFuZCBgYTFgIGFycmF5cyBoYXZlIHRoZSBzYW1lIGNvbnRlbnQsIGVsc2UgcmV0dXJucyBmYWxzZS5cblx0ICogQHNlZSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNDg1Mzk3NFxuXHQgKiBAcGFyYW0ge0FycmF5fSBhMCAtIFRoZSBhcnJheSB0byBjb21wYXJlXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGExIC0gVGhlIGFycmF5IHRvIGNvbXBhcmVcblx0ICogQHJldHVybnMge0Jvb2xlYW59XG5cdCAqL1xuXHRhcnJheUVxdWFsczogZnVuY3Rpb24oYTAsIGExKSB7XG5cdFx0dmFyIGksIGlsZW4sIHYwLCB2MTtcblxuXHRcdGlmICghYTAgfHwgIWExIHx8IGEwLmxlbmd0aCAhPT0gYTEubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IGEwLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdFx0djAgPSBhMFtpXTtcblx0XHRcdHYxID0gYTFbaV07XG5cblx0XHRcdGlmICh2MCBpbnN0YW5jZW9mIEFycmF5ICYmIHYxIGluc3RhbmNlb2YgQXJyYXkpIHtcblx0XHRcdFx0aWYgKCFoZWxwZXJzLmFycmF5RXF1YWxzKHYwLCB2MSkpIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAodjAgIT09IHYxKSB7XG5cdFx0XHRcdC8vIE5PVEU6IHR3byBkaWZmZXJlbnQgb2JqZWN0IGluc3RhbmNlcyB3aWxsIG5ldmVyIGJlIGVxdWFsOiB7eDoyMH0gIT0ge3g6MjB9XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSxcblxuXHQvKipcblx0ICogUmV0dXJucyBhIGRlZXAgY29weSBvZiBgc291cmNlYCB3aXRob3V0IGtlZXBpbmcgcmVmZXJlbmNlcyBvbiBvYmplY3RzIGFuZCBhcnJheXMuXG5cdCAqIEBwYXJhbSB7Kn0gc291cmNlIC0gVGhlIHZhbHVlIHRvIGNsb25lLlxuXHQgKiBAcmV0dXJucyB7Kn1cblx0ICovXG5cdGNsb25lOiBmdW5jdGlvbihzb3VyY2UpIHtcblx0XHRpZiAoaGVscGVycy5pc0FycmF5KHNvdXJjZSkpIHtcblx0XHRcdHJldHVybiBzb3VyY2UubWFwKGhlbHBlcnMuY2xvbmUpO1xuXHRcdH1cblxuXHRcdGlmIChoZWxwZXJzLmlzT2JqZWN0KHNvdXJjZSkpIHtcblx0XHRcdHZhciB0YXJnZXQgPSB7fTtcblx0XHRcdHZhciBrZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblx0XHRcdHZhciBrbGVuID0ga2V5cy5sZW5ndGg7XG5cdFx0XHR2YXIgayA9IDA7XG5cblx0XHRcdGZvciAoOyBrIDwga2xlbjsgKytrKSB7XG5cdFx0XHRcdHRhcmdldFtrZXlzW2tdXSA9IGhlbHBlcnMuY2xvbmUoc291cmNlW2tleXNba11dKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRhcmdldDtcblx0XHR9XG5cblx0XHRyZXR1cm4gc291cmNlO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBUaGUgZGVmYXVsdCBtZXJnZXIgd2hlbiBDaGFydC5oZWxwZXJzLm1lcmdlIGlzIGNhbGxlZCB3aXRob3V0IG1lcmdlciBvcHRpb24uXG5cdCAqIE5vdGUoU0IpOiB0aGlzIG1ldGhvZCBpcyBhbHNvIHVzZWQgYnkgY29uZmlnTWVyZ2UgYW5kIHNjYWxlTWVyZ2UgYXMgZmFsbGJhY2suXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRfbWVyZ2VyOiBmdW5jdGlvbihrZXksIHRhcmdldCwgc291cmNlLCBvcHRpb25zKSB7XG5cdFx0dmFyIHR2YWwgPSB0YXJnZXRba2V5XTtcblx0XHR2YXIgc3ZhbCA9IHNvdXJjZVtrZXldO1xuXG5cdFx0aWYgKGhlbHBlcnMuaXNPYmplY3QodHZhbCkgJiYgaGVscGVycy5pc09iamVjdChzdmFsKSkge1xuXHRcdFx0aGVscGVycy5tZXJnZSh0dmFsLCBzdmFsLCBvcHRpb25zKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGFyZ2V0W2tleV0gPSBoZWxwZXJzLmNsb25lKHN2YWwpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogTWVyZ2VzIHNvdXJjZVtrZXldIGluIHRhcmdldFtrZXldIG9ubHkgaWYgdGFyZ2V0W2tleV0gaXMgdW5kZWZpbmVkLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0X21lcmdlcklmOiBmdW5jdGlvbihrZXksIHRhcmdldCwgc291cmNlKSB7XG5cdFx0dmFyIHR2YWwgPSB0YXJnZXRba2V5XTtcblx0XHR2YXIgc3ZhbCA9IHNvdXJjZVtrZXldO1xuXG5cdFx0aWYgKGhlbHBlcnMuaXNPYmplY3QodHZhbCkgJiYgaGVscGVycy5pc09iamVjdChzdmFsKSkge1xuXHRcdFx0aGVscGVycy5tZXJnZUlmKHR2YWwsIHN2YWwpO1xuXHRcdH0gZWxzZSBpZiAoIXRhcmdldC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0XHR0YXJnZXRba2V5XSA9IGhlbHBlcnMuY2xvbmUoc3ZhbCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZWN1cnNpdmVseSBkZWVwIGNvcGllcyBgc291cmNlYCBwcm9wZXJ0aWVzIGludG8gYHRhcmdldGAgd2l0aCB0aGUgZ2l2ZW4gYG9wdGlvbnNgLlxuXHQgKiBJTVBPUlRBTlQ6IGB0YXJnZXRgIGlzIG5vdCBjbG9uZWQgYW5kIHdpbGwgYmUgdXBkYXRlZCB3aXRoIGBzb3VyY2VgIHByb3BlcnRpZXMuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXQgLSBUaGUgdGFyZ2V0IG9iamVjdCBpbiB3aGljaCBhbGwgc291cmNlcyBhcmUgbWVyZ2VkIGludG8uXG5cdCAqIEBwYXJhbSB7T2JqZWN0fEFycmF5KE9iamVjdCl9IHNvdXJjZSAtIE9iamVjdChzKSB0byBtZXJnZSBpbnRvIGB0YXJnZXRgLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0gTWVyZ2luZyBvcHRpb25zOlxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5tZXJnZXJdIC0gVGhlIG1lcmdlIG1ldGhvZCAoa2V5LCB0YXJnZXQsIHNvdXJjZSwgb3B0aW9ucylcblx0ICogQHJldHVybnMge09iamVjdH0gVGhlIGB0YXJnZXRgIG9iamVjdC5cblx0ICovXG5cdG1lcmdlOiBmdW5jdGlvbih0YXJnZXQsIHNvdXJjZSwgb3B0aW9ucykge1xuXHRcdHZhciBzb3VyY2VzID0gaGVscGVycy5pc0FycmF5KHNvdXJjZSkgPyBzb3VyY2UgOiBbc291cmNlXTtcblx0XHR2YXIgaWxlbiA9IHNvdXJjZXMubGVuZ3RoO1xuXHRcdHZhciBtZXJnZSwgaSwga2V5cywga2xlbiwgaztcblxuXHRcdGlmICghaGVscGVycy5pc09iamVjdCh0YXJnZXQpKSB7XG5cdFx0XHRyZXR1cm4gdGFyZ2V0O1xuXHRcdH1cblxuXHRcdG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXHRcdG1lcmdlID0gb3B0aW9ucy5tZXJnZXIgfHwgaGVscGVycy5fbWVyZ2VyO1xuXG5cdFx0Zm9yIChpID0gMDsgaSA8IGlsZW47ICsraSkge1xuXHRcdFx0c291cmNlID0gc291cmNlc1tpXTtcblx0XHRcdGlmICghaGVscGVycy5pc09iamVjdChzb3VyY2UpKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRrZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblx0XHRcdGZvciAoayA9IDAsIGtsZW4gPSBrZXlzLmxlbmd0aDsgayA8IGtsZW47ICsraykge1xuXHRcdFx0XHRtZXJnZShrZXlzW2tdLCB0YXJnZXQsIHNvdXJjZSwgb3B0aW9ucyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRhcmdldDtcblx0fSxcblxuXHQvKipcblx0ICogUmVjdXJzaXZlbHkgZGVlcCBjb3BpZXMgYHNvdXJjZWAgcHJvcGVydGllcyBpbnRvIGB0YXJnZXRgICpvbmx5KiBpZiBub3QgZGVmaW5lZCBpbiB0YXJnZXQuXG5cdCAqIElNUE9SVEFOVDogYHRhcmdldGAgaXMgbm90IGNsb25lZCBhbmQgd2lsbCBiZSB1cGRhdGVkIHdpdGggYHNvdXJjZWAgcHJvcGVydGllcy5cblx0ICogQHBhcmFtIHtPYmplY3R9IHRhcmdldCAtIFRoZSB0YXJnZXQgb2JqZWN0IGluIHdoaWNoIGFsbCBzb3VyY2VzIGFyZSBtZXJnZWQgaW50by5cblx0ICogQHBhcmFtIHtPYmplY3R8QXJyYXkoT2JqZWN0KX0gc291cmNlIC0gT2JqZWN0KHMpIHRvIG1lcmdlIGludG8gYHRhcmdldGAuXG5cdCAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBgdGFyZ2V0YCBvYmplY3QuXG5cdCAqL1xuXHRtZXJnZUlmOiBmdW5jdGlvbih0YXJnZXQsIHNvdXJjZSkge1xuXHRcdHJldHVybiBoZWxwZXJzLm1lcmdlKHRhcmdldCwgc291cmNlLCB7bWVyZ2VyOiBoZWxwZXJzLl9tZXJnZXJJZn0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBcHBsaWVzIHRoZSBjb250ZW50cyBvZiB0d28gb3IgbW9yZSBvYmplY3RzIHRvZ2V0aGVyIGludG8gdGhlIGZpcnN0IG9iamVjdC5cblx0ICogQHBhcmFtIHtPYmplY3R9IHRhcmdldCAtIFRoZSB0YXJnZXQgb2JqZWN0IGluIHdoaWNoIGFsbCBvYmplY3RzIGFyZSBtZXJnZWQgaW50by5cblx0ICogQHBhcmFtIHtPYmplY3R9IGFyZzEgLSBPYmplY3QgY29udGFpbmluZyBhZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gbWVyZ2UgaW4gdGFyZ2V0LlxuXHQgKiBAcGFyYW0ge09iamVjdH0gYXJnTiAtIEFkZGl0aW9uYWwgb2JqZWN0cyBjb250YWluaW5nIHByb3BlcnRpZXMgdG8gbWVyZ2UgaW4gdGFyZ2V0LlxuXHQgKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgYHRhcmdldGAgb2JqZWN0LlxuXHQgKi9cblx0ZXh0ZW5kOiBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHR2YXIgc2V0Rm4gPSBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG5cdFx0XHR0YXJnZXRba2V5XSA9IHZhbHVlO1xuXHRcdH07XG5cdFx0Zm9yICh2YXIgaSA9IDEsIGlsZW4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG5cdFx0XHRoZWxwZXJzLmVhY2goYXJndW1lbnRzW2ldLCBzZXRGbik7XG5cdFx0fVxuXHRcdHJldHVybiB0YXJnZXQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEJhc2ljIGphdmFzY3JpcHQgaW5oZXJpdGFuY2UgYmFzZWQgb24gdGhlIG1vZGVsIGNyZWF0ZWQgaW4gQmFja2JvbmUuanNcblx0ICovXG5cdGluaGVyaXRzOiBmdW5jdGlvbihleHRlbnNpb25zKSB7XG5cdFx0dmFyIG1lID0gdGhpcztcblx0XHR2YXIgQ2hhcnRFbGVtZW50ID0gKGV4dGVuc2lvbnMgJiYgZXh0ZW5zaW9ucy5oYXNPd25Qcm9wZXJ0eSgnY29uc3RydWN0b3InKSkgPyBleHRlbnNpb25zLmNvbnN0cnVjdG9yIDogZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gbWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0XHR9O1xuXG5cdFx0dmFyIFN1cnJvZ2F0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0dGhpcy5jb25zdHJ1Y3RvciA9IENoYXJ0RWxlbWVudDtcblx0XHR9O1xuXG5cdFx0U3Vycm9nYXRlLnByb3RvdHlwZSA9IG1lLnByb3RvdHlwZTtcblx0XHRDaGFydEVsZW1lbnQucHJvdG90eXBlID0gbmV3IFN1cnJvZ2F0ZSgpO1xuXHRcdENoYXJ0RWxlbWVudC5leHRlbmQgPSBoZWxwZXJzLmluaGVyaXRzO1xuXG5cdFx0aWYgKGV4dGVuc2lvbnMpIHtcblx0XHRcdGhlbHBlcnMuZXh0ZW5kKENoYXJ0RWxlbWVudC5wcm90b3R5cGUsIGV4dGVuc2lvbnMpO1xuXHRcdH1cblxuXHRcdENoYXJ0RWxlbWVudC5fX3N1cGVyX18gPSBtZS5wcm90b3R5cGU7XG5cdFx0cmV0dXJuIENoYXJ0RWxlbWVudDtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBoZWxwZXJzO1xuXG4vLyBERVBSRUNBVElPTlNcblxuLyoqXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LmhlbHBlcnMuY2FsbGJhY2sgaW5zdGVhZC5cbiAqIEBmdW5jdGlvbiBDaGFydC5oZWxwZXJzLmNhbGxDYWxsYmFja1xuICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjYuMFxuICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xuICogQHByaXZhdGVcbiAqL1xuaGVscGVycy5jYWxsQ2FsbGJhY2sgPSBoZWxwZXJzLmNhbGxiYWNrO1xuXG4vKipcbiAqIFByb3ZpZGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB1c2UgQXJyYXkucHJvdG90eXBlLmluZGV4T2YgaW5zdGVhZC5cbiAqIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIGNvbXBhdGliaWxpdHk6IENocm9tZSwgT3BlcmEsIFNhZmFyaSwgRkYxLjUrLCBJRTkrXG4gKiBAZnVuY3Rpb24gQ2hhcnQuaGVscGVycy5pbmRleE9mXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNy4wXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXG4gKiBAcHJpdmF0ZVxuICovXG5oZWxwZXJzLmluZGV4T2YgPSBmdW5jdGlvbihhcnJheSwgaXRlbSwgZnJvbUluZGV4KSB7XG5cdHJldHVybiBBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGFycmF5LCBpdGVtLCBmcm9tSW5kZXgpO1xufTtcblxuLyoqXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LmhlbHBlcnMudmFsdWVPckRlZmF1bHQgaW5zdGVhZC5cbiAqIEBmdW5jdGlvbiBDaGFydC5oZWxwZXJzLmdldFZhbHVlT3JEZWZhdWx0XG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNy4wXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXG4gKiBAcHJpdmF0ZVxuICovXG5oZWxwZXJzLmdldFZhbHVlT3JEZWZhdWx0ID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdDtcblxuLyoqXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LmhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0IGluc3RlYWQuXG4gKiBAZnVuY3Rpb24gQ2hhcnQuaGVscGVycy5nZXRWYWx1ZUF0SW5kZXhPckRlZmF1bHRcbiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi43LjBcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcbiAqIEBwcml2YXRlXG4gKi9cbmhlbHBlcnMuZ2V0VmFsdWVBdEluZGV4T3JEZWZhdWx0ID0gaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQ7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7d23\n")},"7dc6":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar elements = __webpack_require__(/*! ../elements/index */ \"0687\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\ndefaults._set('doughnut', {\n\tanimation: {\n\t\t// Boolean - Whether we animate the rotation of the Doughnut\n\t\tanimateRotate: true,\n\t\t// Boolean - Whether we animate scaling the Doughnut from the centre\n\t\tanimateScale: false\n\t},\n\thover: {\n\t\tmode: 'single'\n\t},\n\tlegendCallback: function(chart) {\n\t\tvar text = [];\n\t\ttext.push('<ul class=\"' + chart.id + '-legend\">');\n\n\t\tvar data = chart.data;\n\t\tvar datasets = data.datasets;\n\t\tvar labels = data.labels;\n\n\t\tif (datasets.length) {\n\t\t\tfor (var i = 0; i < datasets[0].data.length; ++i) {\n\t\t\t\ttext.push('<li><span style=\"background-color:' + datasets[0].backgroundColor[i] + '\"></span>');\n\t\t\t\tif (labels[i]) {\n\t\t\t\t\ttext.push(labels[i]);\n\t\t\t\t}\n\t\t\t\ttext.push('</li>');\n\t\t\t}\n\t\t}\n\n\t\ttext.push('</ul>');\n\t\treturn text.join('');\n\t},\n\tlegend: {\n\t\tlabels: {\n\t\t\tgenerateLabels: function(chart) {\n\t\t\t\tvar data = chart.data;\n\t\t\t\tif (data.labels.length && data.datasets.length) {\n\t\t\t\t\treturn data.labels.map(function(label, i) {\n\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\t\t\t\tvar ds = data.datasets[0];\n\t\t\t\t\t\tvar arc = meta.data[i];\n\t\t\t\t\t\tvar custom = arc && arc.custom || {};\n\t\t\t\t\t\tvar valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;\n\t\t\t\t\t\tvar arcOpts = chart.options.elements.arc;\n\t\t\t\t\t\tvar fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);\n\t\t\t\t\t\tvar stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);\n\t\t\t\t\t\tvar bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttext: label,\n\t\t\t\t\t\t\tfillStyle: fill,\n\t\t\t\t\t\t\tstrokeStyle: stroke,\n\t\t\t\t\t\t\tlineWidth: bw,\n\t\t\t\t\t\t\thidden: isNaN(ds.data[i]) || meta.data[i].hidden,\n\n\t\t\t\t\t\t\t// Extra data used for toggling the correct item\n\t\t\t\t\t\t\tindex: i\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\n\t\tonClick: function(e, legendItem) {\n\t\t\tvar index = legendItem.index;\n\t\t\tvar chart = this.chart;\n\t\t\tvar i, ilen, meta;\n\n\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\t// toggle visibility of index if exists\n\t\t\t\tif (meta.data[index]) {\n\t\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchart.update();\n\t\t}\n\t},\n\n\t// The percentage of the chart that we cut out of the middle.\n\tcutoutPercentage: 50,\n\n\t// The rotation of the chart, where the first data arc begins.\n\trotation: Math.PI * -0.5,\n\n\t// The total circumference of the chart.\n\tcircumference: Math.PI * 2.0,\n\n\t// Need to override these to give a nice default\n\ttooltips: {\n\t\tcallbacks: {\n\t\t\ttitle: function() {\n\t\t\t\treturn '';\n\t\t\t},\n\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\tvar dataLabel = data.labels[tooltipItem.index];\n\t\t\t\tvar value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\n\n\t\t\t\tif (helpers.isArray(dataLabel)) {\n\t\t\t\t\t// show value on first line of multiline label\n\t\t\t\t\t// need to clone because we are changing the value\n\t\t\t\t\tdataLabel = dataLabel.slice();\n\t\t\t\t\tdataLabel[0] += value;\n\t\t\t\t} else {\n\t\t\t\t\tdataLabel += value;\n\t\t\t\t}\n\n\t\t\t\treturn dataLabel;\n\t\t\t}\n\t\t}\n\t}\n});\n\ndefaults._set('pie', helpers.clone(defaults.doughnut));\ndefaults._set('pie', {\n\tcutoutPercentage: 0\n});\n\nmodule.exports = function(Chart) {\n\n\tChart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({\n\n\t\tdataElementType: elements.Arc,\n\n\t\tlinkScales: helpers.noop,\n\n\t\t// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly\n\t\tgetRingIndex: function(datasetIndex) {\n\t\t\tvar ringIndex = 0;\n\n\t\t\tfor (var j = 0; j < datasetIndex; ++j) {\n\t\t\t\tif (this.chart.isDatasetVisible(j)) {\n\t\t\t\t\t++ringIndex;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ringIndex;\n\t\t},\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar chartArea = chart.chartArea;\n\t\t\tvar opts = chart.options;\n\t\t\tvar arcOpts = opts.elements.arc;\n\t\t\tvar availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth;\n\t\t\tvar availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth;\n\t\t\tvar minSize = Math.min(availableWidth, availableHeight);\n\t\t\tvar offset = {x: 0, y: 0};\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar cutoutPercentage = opts.cutoutPercentage;\n\t\t\tvar circumference = opts.circumference;\n\n\t\t\t// If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc\n\t\t\tif (circumference < Math.PI * 2.0) {\n\t\t\t\tvar startAngle = opts.rotation % (Math.PI * 2.0);\n\t\t\t\tstartAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);\n\t\t\t\tvar endAngle = startAngle + circumference;\n\t\t\t\tvar start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};\n\t\t\t\tvar end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};\n\t\t\t\tvar contains0 = (startAngle <= 0 && endAngle >= 0) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);\n\t\t\t\tvar contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);\n\t\t\t\tvar contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);\n\t\t\t\tvar contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);\n\t\t\t\tvar cutout = cutoutPercentage / 100.0;\n\t\t\t\tvar min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};\n\t\t\t\tvar max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};\n\t\t\t\tvar size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};\n\t\t\t\tminSize = Math.min(availableWidth / size.width, availableHeight / size.height);\n\t\t\t\toffset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};\n\t\t\t}\n\n\t\t\tchart.borderWidth = me.getMaxBorderWidth(meta.data);\n\t\t\tchart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);\n\t\t\tchart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);\n\t\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\n\t\t\tchart.offsetX = offset.x * chart.outerRadius;\n\t\t\tchart.offsetY = offset.y * chart.outerRadius;\n\n\t\t\tmeta.total = me.calculateTotal();\n\n\t\t\tme.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));\n\t\t\tme.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);\n\n\t\t\thelpers.each(meta.data, function(arc, index) {\n\t\t\t\tme.updateElement(arc, index, reset);\n\t\t\t});\n\t\t},\n\n\t\tupdateElement: function(arc, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar chartArea = chart.chartArea;\n\t\t\tvar opts = chart.options;\n\t\t\tvar animationOpts = opts.animation;\n\t\t\tvar centerX = (chartArea.left + chartArea.right) / 2;\n\t\t\tvar centerY = (chartArea.top + chartArea.bottom) / 2;\n\t\t\tvar startAngle = opts.rotation; // non reset case handled later\n\t\t\tvar endAngle = opts.rotation; // non reset case handled later\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI));\n\t\t\tvar innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius;\n\t\t\tvar outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius;\n\t\t\tvar valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;\n\n\t\t\thelpers.extend(arc, {\n\t\t\t\t// Utility\n\t\t\t\t_datasetIndex: me.index,\n\t\t\t\t_index: index,\n\n\t\t\t\t// Desired view properties\n\t\t\t\t_model: {\n\t\t\t\t\tx: centerX + chart.offsetX,\n\t\t\t\t\ty: centerY + chart.offsetY,\n\t\t\t\t\tstartAngle: startAngle,\n\t\t\t\t\tendAngle: endAngle,\n\t\t\t\t\tcircumference: circumference,\n\t\t\t\t\touterRadius: outerRadius,\n\t\t\t\t\tinnerRadius: innerRadius,\n\t\t\t\t\tlabel: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar model = arc._model;\n\n\t\t\t// Resets the visual styles\n\t\t\tvar custom = arc.custom || {};\n\t\t\tvar valueOrDefault = helpers.valueAtIndexOrDefault;\n\t\t\tvar elementOpts = this.chart.options.elements.arc;\n\t\t\tmodel.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);\n\t\t\tmodel.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);\n\t\t\tmodel.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);\n\n\t\t\t// Set correct angles if not resetting\n\t\t\tif (!reset || !animationOpts.animateRotate) {\n\t\t\t\tif (index === 0) {\n\t\t\t\t\tmodel.startAngle = opts.rotation;\n\t\t\t\t} else {\n\t\t\t\t\tmodel.startAngle = me.getMeta().data[index - 1]._model.endAngle;\n\t\t\t\t}\n\n\t\t\t\tmodel.endAngle = model.startAngle + model.circumference;\n\t\t\t}\n\n\t\t\tarc.pivot();\n\t\t},\n\n\t\tcalculateTotal: function() {\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar meta = this.getMeta();\n\t\t\tvar total = 0;\n\t\t\tvar value;\n\n\t\t\thelpers.each(meta.data, function(element, index) {\n\t\t\t\tvalue = dataset.data[index];\n\t\t\t\tif (!isNaN(value) && !element.hidden) {\n\t\t\t\t\ttotal += Math.abs(value);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t/* if (total === 0) {\n\t\t\t\ttotal = NaN;\n\t\t\t}*/\n\n\t\t\treturn total;\n\t\t},\n\n\t\tcalculateCircumference: function(value) {\n\t\t\tvar total = this.getMeta().total;\n\t\t\tif (total > 0 && !isNaN(value)) {\n\t\t\t\treturn (Math.PI * 2.0) * (Math.abs(value) / total);\n\t\t\t}\n\t\t\treturn 0;\n\t\t},\n\n\t\t// gets the max border or hover width to properly scale pie charts\n\t\tgetMaxBorderWidth: function(arcs) {\n\t\t\tvar max = 0;\n\t\t\tvar index = this.index;\n\t\t\tvar length = arcs.length;\n\t\t\tvar borderWidth;\n\t\t\tvar hoverWidth;\n\n\t\t\tfor (var i = 0; i < length; i++) {\n\t\t\t\tborderWidth = arcs[i]._model ? arcs[i]._model.borderWidth : 0;\n\t\t\t\thoverWidth = arcs[i]._chart ? arcs[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;\n\n\t\t\t\tmax = borderWidth > max ? borderWidth : max;\n\t\t\t\tmax = hoverWidth > max ? hoverWidth : max;\n\t\t\t}\n\t\t\treturn max;\n\t\t}\n\t});\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2RjNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5kb3VnaG51dC5qcz81ZDA4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmF1bHRzID0gcmVxdWlyZSgnLi4vY29yZS9jb3JlLmRlZmF1bHRzJyk7XG52YXIgZWxlbWVudHMgPSByZXF1aXJlKCcuLi9lbGVtZW50cy9pbmRleCcpO1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2luZGV4Jyk7XG5cbmRlZmF1bHRzLl9zZXQoJ2RvdWdobnV0Jywge1xuXHRhbmltYXRpb246IHtcblx0XHQvLyBCb29sZWFuIC0gV2hldGhlciB3ZSBhbmltYXRlIHRoZSByb3RhdGlvbiBvZiB0aGUgRG91Z2hudXRcblx0XHRhbmltYXRlUm90YXRlOiB0cnVlLFxuXHRcdC8vIEJvb2xlYW4gLSBXaGV0aGVyIHdlIGFuaW1hdGUgc2NhbGluZyB0aGUgRG91Z2hudXQgZnJvbSB0aGUgY2VudHJlXG5cdFx0YW5pbWF0ZVNjYWxlOiBmYWxzZVxuXHR9LFxuXHRob3Zlcjoge1xuXHRcdG1vZGU6ICdzaW5nbGUnXG5cdH0sXG5cdGxlZ2VuZENhbGxiYWNrOiBmdW5jdGlvbihjaGFydCkge1xuXHRcdHZhciB0ZXh0ID0gW107XG5cdFx0dGV4dC5wdXNoKCc8dWwgY2xhc3M9XCInICsgY2hhcnQuaWQgKyAnLWxlZ2VuZFwiPicpO1xuXG5cdFx0dmFyIGRhdGEgPSBjaGFydC5kYXRhO1xuXHRcdHZhciBkYXRhc2V0cyA9IGRhdGEuZGF0YXNldHM7XG5cdFx0dmFyIGxhYmVscyA9IGRhdGEubGFiZWxzO1xuXG5cdFx0aWYgKGRhdGFzZXRzLmxlbmd0aCkge1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhc2V0c1swXS5kYXRhLmxlbmd0aDsgKytpKSB7XG5cdFx0XHRcdHRleHQucHVzaCgnPGxpPjxzcGFuIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjonICsgZGF0YXNldHNbMF0uYmFja2dyb3VuZENvbG9yW2ldICsgJ1wiPjwvc3Bhbj4nKTtcblx0XHRcdFx0aWYgKGxhYmVsc1tpXSkge1xuXHRcdFx0XHRcdHRleHQucHVzaChsYWJlbHNbaV0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRleHQucHVzaCgnPC9saT4nKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0ZXh0LnB1c2goJzwvdWw+Jyk7XG5cdFx0cmV0dXJuIHRleHQuam9pbignJyk7XG5cdH0sXG5cdGxlZ2VuZDoge1xuXHRcdGxhYmVsczoge1xuXHRcdFx0Z2VuZXJhdGVMYWJlbHM6IGZ1bmN0aW9uKGNoYXJ0KSB7XG5cdFx0XHRcdHZhciBkYXRhID0gY2hhcnQuZGF0YTtcblx0XHRcdFx0aWYgKGRhdGEubGFiZWxzLmxlbmd0aCAmJiBkYXRhLmRhdGFzZXRzLmxlbmd0aCkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhLmxhYmVscy5tYXAoZnVuY3Rpb24obGFiZWwsIGkpIHtcblx0XHRcdFx0XHRcdHZhciBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoMCk7XG5cdFx0XHRcdFx0XHR2YXIgZHMgPSBkYXRhLmRhdGFzZXRzWzBdO1xuXHRcdFx0XHRcdFx0dmFyIGFyYyA9IG1ldGEuZGF0YVtpXTtcblx0XHRcdFx0XHRcdHZhciBjdXN0b20gPSBhcmMgJiYgYXJjLmN1c3RvbSB8fCB7fTtcblx0XHRcdFx0XHRcdHZhciB2YWx1ZUF0SW5kZXhPckRlZmF1bHQgPSBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdDtcblx0XHRcdFx0XHRcdHZhciBhcmNPcHRzID0gY2hhcnQub3B0aW9ucy5lbGVtZW50cy5hcmM7XG5cdFx0XHRcdFx0XHR2YXIgZmlsbCA9IGN1c3RvbS5iYWNrZ3JvdW5kQ29sb3IgPyBjdXN0b20uYmFja2dyb3VuZENvbG9yIDogdmFsdWVBdEluZGV4T3JEZWZhdWx0KGRzLmJhY2tncm91bmRDb2xvciwgaSwgYXJjT3B0cy5iYWNrZ3JvdW5kQ29sb3IpO1xuXHRcdFx0XHRcdFx0dmFyIHN0cm9rZSA9IGN1c3RvbS5ib3JkZXJDb2xvciA/IGN1c3RvbS5ib3JkZXJDb2xvciA6IHZhbHVlQXRJbmRleE9yRGVmYXVsdChkcy5ib3JkZXJDb2xvciwgaSwgYXJjT3B0cy5ib3JkZXJDb2xvcik7XG5cdFx0XHRcdFx0XHR2YXIgYncgPSBjdXN0b20uYm9yZGVyV2lkdGggPyBjdXN0b20uYm9yZGVyV2lkdGggOiB2YWx1ZUF0SW5kZXhPckRlZmF1bHQoZHMuYm9yZGVyV2lkdGgsIGksIGFyY09wdHMuYm9yZGVyV2lkdGgpO1xuXG5cdFx0XHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdFx0XHR0ZXh0OiBsYWJlbCxcblx0XHRcdFx0XHRcdFx0ZmlsbFN0eWxlOiBmaWxsLFxuXHRcdFx0XHRcdFx0XHRzdHJva2VTdHlsZTogc3Ryb2tlLFxuXHRcdFx0XHRcdFx0XHRsaW5lV2lkdGg6IGJ3LFxuXHRcdFx0XHRcdFx0XHRoaWRkZW46IGlzTmFOKGRzLmRhdGFbaV0pIHx8IG1ldGEuZGF0YVtpXS5oaWRkZW4sXG5cblx0XHRcdFx0XHRcdFx0Ly8gRXh0cmEgZGF0YSB1c2VkIGZvciB0b2dnbGluZyB0aGUgY29ycmVjdCBpdGVtXG5cdFx0XHRcdFx0XHRcdGluZGV4OiBpXG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBbXTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0b25DbGljazogZnVuY3Rpb24oZSwgbGVnZW5kSXRlbSkge1xuXHRcdFx0dmFyIGluZGV4ID0gbGVnZW5kSXRlbS5pbmRleDtcblx0XHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQ7XG5cdFx0XHR2YXIgaSwgaWxlbiwgbWV0YTtcblxuXHRcdFx0Zm9yIChpID0gMCwgaWxlbiA9IChjaGFydC5kYXRhLmRhdGFzZXRzIHx8IFtdKS5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdFx0bWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGkpO1xuXHRcdFx0XHQvLyB0b2dnbGUgdmlzaWJpbGl0eSBvZiBpbmRleCBpZiBleGlzdHNcblx0XHRcdFx0aWYgKG1ldGEuZGF0YVtpbmRleF0pIHtcblx0XHRcdFx0XHRtZXRhLmRhdGFbaW5kZXhdLmhpZGRlbiA9ICFtZXRhLmRhdGFbaW5kZXhdLmhpZGRlbjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRjaGFydC51cGRhdGUoKTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gVGhlIHBlcmNlbnRhZ2Ugb2YgdGhlIGNoYXJ0IHRoYXQgd2UgY3V0IG91dCBvZiB0aGUgbWlkZGxlLlxuXHRjdXRvdXRQZXJjZW50YWdlOiA1MCxcblxuXHQvLyBUaGUgcm90YXRpb24gb2YgdGhlIGNoYXJ0LCB3aGVyZSB0aGUgZmlyc3QgZGF0YSBhcmMgYmVnaW5zLlxuXHRyb3RhdGlvbjogTWF0aC5QSSAqIC0wLjUsXG5cblx0Ly8gVGhlIHRvdGFsIGNpcmN1bWZlcmVuY2Ugb2YgdGhlIGNoYXJ0LlxuXHRjaXJjdW1mZXJlbmNlOiBNYXRoLlBJICogMi4wLFxuXG5cdC8vIE5lZWQgdG8gb3ZlcnJpZGUgdGhlc2UgdG8gZ2l2ZSBhIG5pY2UgZGVmYXVsdFxuXHR0b29sdGlwczoge1xuXHRcdGNhbGxiYWNrczoge1xuXHRcdFx0dGl0bGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gJyc7XG5cdFx0XHR9LFxuXHRcdFx0bGFiZWw6IGZ1bmN0aW9uKHRvb2x0aXBJdGVtLCBkYXRhKSB7XG5cdFx0XHRcdHZhciBkYXRhTGFiZWwgPSBkYXRhLmxhYmVsc1t0b29sdGlwSXRlbS5pbmRleF07XG5cdFx0XHRcdHZhciB2YWx1ZSA9ICc6ICcgKyBkYXRhLmRhdGFzZXRzW3Rvb2x0aXBJdGVtLmRhdGFzZXRJbmRleF0uZGF0YVt0b29sdGlwSXRlbS5pbmRleF07XG5cblx0XHRcdFx0aWYgKGhlbHBlcnMuaXNBcnJheShkYXRhTGFiZWwpKSB7XG5cdFx0XHRcdFx0Ly8gc2hvdyB2YWx1ZSBvbiBmaXJzdCBsaW5lIG9mIG11bHRpbGluZSBsYWJlbFxuXHRcdFx0XHRcdC8vIG5lZWQgdG8gY2xvbmUgYmVjYXVzZSB3ZSBhcmUgY2hhbmdpbmcgdGhlIHZhbHVlXG5cdFx0XHRcdFx0ZGF0YUxhYmVsID0gZGF0YUxhYmVsLnNsaWNlKCk7XG5cdFx0XHRcdFx0ZGF0YUxhYmVsWzBdICs9IHZhbHVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGRhdGFMYWJlbCArPSB2YWx1ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBkYXRhTGFiZWw7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59KTtcblxuZGVmYXVsdHMuX3NldCgncGllJywgaGVscGVycy5jbG9uZShkZWZhdWx0cy5kb3VnaG51dCkpO1xuZGVmYXVsdHMuX3NldCgncGllJywge1xuXHRjdXRvdXRQZXJjZW50YWdlOiAwXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDaGFydCkge1xuXG5cdENoYXJ0LmNvbnRyb2xsZXJzLmRvdWdobnV0ID0gQ2hhcnQuY29udHJvbGxlcnMucGllID0gQ2hhcnQuRGF0YXNldENvbnRyb2xsZXIuZXh0ZW5kKHtcblxuXHRcdGRhdGFFbGVtZW50VHlwZTogZWxlbWVudHMuQXJjLFxuXG5cdFx0bGlua1NjYWxlczogaGVscGVycy5ub29wLFxuXG5cdFx0Ly8gR2V0IGluZGV4IG9mIHRoZSBkYXRhc2V0IGluIHJlbGF0aW9uIHRvIHRoZSB2aXNpYmxlIGRhdGFzZXRzLiBUaGlzIGFsbG93cyBkZXRlcm1pbmluZyB0aGUgaW5uZXIgYW5kIG91dGVyIHJhZGl1cyBjb3JyZWN0bHlcblx0XHRnZXRSaW5nSW5kZXg6IGZ1bmN0aW9uKGRhdGFzZXRJbmRleCkge1xuXHRcdFx0dmFyIHJpbmdJbmRleCA9IDA7XG5cblx0XHRcdGZvciAodmFyIGogPSAwOyBqIDwgZGF0YXNldEluZGV4OyArK2opIHtcblx0XHRcdFx0aWYgKHRoaXMuY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShqKSkge1xuXHRcdFx0XHRcdCsrcmluZ0luZGV4O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiByaW5nSW5kZXg7XG5cdFx0fSxcblxuXHRcdHVwZGF0ZTogZnVuY3Rpb24ocmVzZXQpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcblx0XHRcdHZhciBjaGFydEFyZWEgPSBjaGFydC5jaGFydEFyZWE7XG5cdFx0XHR2YXIgb3B0cyA9IGNoYXJ0Lm9wdGlvbnM7XG5cdFx0XHR2YXIgYXJjT3B0cyA9IG9wdHMuZWxlbWVudHMuYXJjO1xuXHRcdFx0dmFyIGF2YWlsYWJsZVdpZHRoID0gY2hhcnRBcmVhLnJpZ2h0IC0gY2hhcnRBcmVhLmxlZnQgLSBhcmNPcHRzLmJvcmRlcldpZHRoO1xuXHRcdFx0dmFyIGF2YWlsYWJsZUhlaWdodCA9IGNoYXJ0QXJlYS5ib3R0b20gLSBjaGFydEFyZWEudG9wIC0gYXJjT3B0cy5ib3JkZXJXaWR0aDtcblx0XHRcdHZhciBtaW5TaXplID0gTWF0aC5taW4oYXZhaWxhYmxlV2lkdGgsIGF2YWlsYWJsZUhlaWdodCk7XG5cdFx0XHR2YXIgb2Zmc2V0ID0ge3g6IDAsIHk6IDB9O1xuXHRcdFx0dmFyIG1ldGEgPSBtZS5nZXRNZXRhKCk7XG5cdFx0XHR2YXIgY3V0b3V0UGVyY2VudGFnZSA9IG9wdHMuY3V0b3V0UGVyY2VudGFnZTtcblx0XHRcdHZhciBjaXJjdW1mZXJlbmNlID0gb3B0cy5jaXJjdW1mZXJlbmNlO1xuXG5cdFx0XHQvLyBJZiB0aGUgY2hhcnQncyBjaXJjdW1mZXJlbmNlIGlzbid0IGEgZnVsbCBjaXJjbGUsIGNhbGN1bGF0ZSBtaW5TaXplIGFzIGEgcmF0aW8gb2YgdGhlIHdpZHRoL2hlaWdodCBvZiB0aGUgYXJjXG5cdFx0XHRpZiAoY2lyY3VtZmVyZW5jZSA8IE1hdGguUEkgKiAyLjApIHtcblx0XHRcdFx0dmFyIHN0YXJ0QW5nbGUgPSBvcHRzLnJvdGF0aW9uICUgKE1hdGguUEkgKiAyLjApO1xuXHRcdFx0XHRzdGFydEFuZ2xlICs9IE1hdGguUEkgKiAyLjAgKiAoc3RhcnRBbmdsZSA+PSBNYXRoLlBJID8gLTEgOiBzdGFydEFuZ2xlIDwgLU1hdGguUEkgPyAxIDogMCk7XG5cdFx0XHRcdHZhciBlbmRBbmdsZSA9IHN0YXJ0QW5nbGUgKyBjaXJjdW1mZXJlbmNlO1xuXHRcdFx0XHR2YXIgc3RhcnQgPSB7eDogTWF0aC5jb3Moc3RhcnRBbmdsZSksIHk6IE1hdGguc2luKHN0YXJ0QW5nbGUpfTtcblx0XHRcdFx0dmFyIGVuZCA9IHt4OiBNYXRoLmNvcyhlbmRBbmdsZSksIHk6IE1hdGguc2luKGVuZEFuZ2xlKX07XG5cdFx0XHRcdHZhciBjb250YWluczAgPSAoc3RhcnRBbmdsZSA8PSAwICYmIGVuZEFuZ2xlID49IDApIHx8IChzdGFydEFuZ2xlIDw9IE1hdGguUEkgKiAyLjAgJiYgTWF0aC5QSSAqIDIuMCA8PSBlbmRBbmdsZSk7XG5cdFx0XHRcdHZhciBjb250YWluczkwID0gKHN0YXJ0QW5nbGUgPD0gTWF0aC5QSSAqIDAuNSAmJiBNYXRoLlBJICogMC41IDw9IGVuZEFuZ2xlKSB8fCAoc3RhcnRBbmdsZSA8PSBNYXRoLlBJICogMi41ICYmIE1hdGguUEkgKiAyLjUgPD0gZW5kQW5nbGUpO1xuXHRcdFx0XHR2YXIgY29udGFpbnMxODAgPSAoc3RhcnRBbmdsZSA8PSAtTWF0aC5QSSAmJiAtTWF0aC5QSSA8PSBlbmRBbmdsZSkgfHwgKHN0YXJ0QW5nbGUgPD0gTWF0aC5QSSAmJiBNYXRoLlBJIDw9IGVuZEFuZ2xlKTtcblx0XHRcdFx0dmFyIGNvbnRhaW5zMjcwID0gKHN0YXJ0QW5nbGUgPD0gLU1hdGguUEkgKiAwLjUgJiYgLU1hdGguUEkgKiAwLjUgPD0gZW5kQW5nbGUpIHx8IChzdGFydEFuZ2xlIDw9IE1hdGguUEkgKiAxLjUgJiYgTWF0aC5QSSAqIDEuNSA8PSBlbmRBbmdsZSk7XG5cdFx0XHRcdHZhciBjdXRvdXQgPSBjdXRvdXRQZXJjZW50YWdlIC8gMTAwLjA7XG5cdFx0XHRcdHZhciBtaW4gPSB7eDogY29udGFpbnMxODAgPyAtMSA6IE1hdGgubWluKHN0YXJ0LnggKiAoc3RhcnQueCA8IDAgPyAxIDogY3V0b3V0KSwgZW5kLnggKiAoZW5kLnggPCAwID8gMSA6IGN1dG91dCkpLCB5OiBjb250YWluczI3MCA/IC0xIDogTWF0aC5taW4oc3RhcnQueSAqIChzdGFydC55IDwgMCA/IDEgOiBjdXRvdXQpLCBlbmQueSAqIChlbmQueSA8IDAgPyAxIDogY3V0b3V0KSl9O1xuXHRcdFx0XHR2YXIgbWF4ID0ge3g6IGNvbnRhaW5zMCA/IDEgOiBNYXRoLm1heChzdGFydC54ICogKHN0YXJ0LnggPiAwID8gMSA6IGN1dG91dCksIGVuZC54ICogKGVuZC54ID4gMCA/IDEgOiBjdXRvdXQpKSwgeTogY29udGFpbnM5MCA/IDEgOiBNYXRoLm1heChzdGFydC55ICogKHN0YXJ0LnkgPiAwID8gMSA6IGN1dG91dCksIGVuZC55ICogKGVuZC55ID4gMCA/IDEgOiBjdXRvdXQpKX07XG5cdFx0XHRcdHZhciBzaXplID0ge3dpZHRoOiAobWF4LnggLSBtaW4ueCkgKiAwLjUsIGhlaWdodDogKG1heC55IC0gbWluLnkpICogMC41fTtcblx0XHRcdFx0bWluU2l6ZSA9IE1hdGgubWluKGF2YWlsYWJsZVdpZHRoIC8gc2l6ZS53aWR0aCwgYXZhaWxhYmxlSGVpZ2h0IC8gc2l6ZS5oZWlnaHQpO1xuXHRcdFx0XHRvZmZzZXQgPSB7eDogKG1heC54ICsgbWluLngpICogLTAuNSwgeTogKG1heC55ICsgbWluLnkpICogLTAuNX07XG5cdFx0XHR9XG5cblx0XHRcdGNoYXJ0LmJvcmRlcldpZHRoID0gbWUuZ2V0TWF4Qm9yZGVyV2lkdGgobWV0YS5kYXRhKTtcblx0XHRcdGNoYXJ0Lm91dGVyUmFkaXVzID0gTWF0aC5tYXgoKG1pblNpemUgLSBjaGFydC5ib3JkZXJXaWR0aCkgLyAyLCAwKTtcblx0XHRcdGNoYXJ0LmlubmVyUmFkaXVzID0gTWF0aC5tYXgoY3V0b3V0UGVyY2VudGFnZSA/IChjaGFydC5vdXRlclJhZGl1cyAvIDEwMCkgKiAoY3V0b3V0UGVyY2VudGFnZSkgOiAwLCAwKTtcblx0XHRcdGNoYXJ0LnJhZGl1c0xlbmd0aCA9IChjaGFydC5vdXRlclJhZGl1cyAtIGNoYXJ0LmlubmVyUmFkaXVzKSAvIGNoYXJ0LmdldFZpc2libGVEYXRhc2V0Q291bnQoKTtcblx0XHRcdGNoYXJ0Lm9mZnNldFggPSBvZmZzZXQueCAqIGNoYXJ0Lm91dGVyUmFkaXVzO1xuXHRcdFx0Y2hhcnQub2Zmc2V0WSA9IG9mZnNldC55ICogY2hhcnQub3V0ZXJSYWRpdXM7XG5cblx0XHRcdG1ldGEudG90YWwgPSBtZS5jYWxjdWxhdGVUb3RhbCgpO1xuXG5cdFx0XHRtZS5vdXRlclJhZGl1cyA9IGNoYXJ0Lm91dGVyUmFkaXVzIC0gKGNoYXJ0LnJhZGl1c0xlbmd0aCAqIG1lLmdldFJpbmdJbmRleChtZS5pbmRleCkpO1xuXHRcdFx0bWUuaW5uZXJSYWRpdXMgPSBNYXRoLm1heChtZS5vdXRlclJhZGl1cyAtIGNoYXJ0LnJhZGl1c0xlbmd0aCwgMCk7XG5cblx0XHRcdGhlbHBlcnMuZWFjaChtZXRhLmRhdGEsIGZ1bmN0aW9uKGFyYywgaW5kZXgpIHtcblx0XHRcdFx0bWUudXBkYXRlRWxlbWVudChhcmMsIGluZGV4LCByZXNldCk7XG5cdFx0XHR9KTtcblx0XHR9LFxuXG5cdFx0dXBkYXRlRWxlbWVudDogZnVuY3Rpb24oYXJjLCBpbmRleCwgcmVzZXQpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcblx0XHRcdHZhciBjaGFydEFyZWEgPSBjaGFydC5jaGFydEFyZWE7XG5cdFx0XHR2YXIgb3B0cyA9IGNoYXJ0Lm9wdGlvbnM7XG5cdFx0XHR2YXIgYW5pbWF0aW9uT3B0cyA9IG9wdHMuYW5pbWF0aW9uO1xuXHRcdFx0dmFyIGNlbnRlclggPSAoY2hhcnRBcmVhLmxlZnQgKyBjaGFydEFyZWEucmlnaHQpIC8gMjtcblx0XHRcdHZhciBjZW50ZXJZID0gKGNoYXJ0QXJlYS50b3AgKyBjaGFydEFyZWEuYm90dG9tKSAvIDI7XG5cdFx0XHR2YXIgc3RhcnRBbmdsZSA9IG9wdHMucm90YXRpb247IC8vIG5vbiByZXNldCBjYXNlIGhhbmRsZWQgbGF0ZXJcblx0XHRcdHZhciBlbmRBbmdsZSA9IG9wdHMucm90YXRpb247IC8vIG5vbiByZXNldCBjYXNlIGhhbmRsZWQgbGF0ZXJcblx0XHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xuXHRcdFx0dmFyIGNpcmN1bWZlcmVuY2UgPSByZXNldCAmJiBhbmltYXRpb25PcHRzLmFuaW1hdGVSb3RhdGUgPyAwIDogYXJjLmhpZGRlbiA/IDAgOiBtZS5jYWxjdWxhdGVDaXJjdW1mZXJlbmNlKGRhdGFzZXQuZGF0YVtpbmRleF0pICogKG9wdHMuY2lyY3VtZmVyZW5jZSAvICgyLjAgKiBNYXRoLlBJKSk7XG5cdFx0XHR2YXIgaW5uZXJSYWRpdXMgPSByZXNldCAmJiBhbmltYXRpb25PcHRzLmFuaW1hdGVTY2FsZSA/IDAgOiBtZS5pbm5lclJhZGl1cztcblx0XHRcdHZhciBvdXRlclJhZGl1cyA9IHJlc2V0ICYmIGFuaW1hdGlvbk9wdHMuYW5pbWF0ZVNjYWxlID8gMCA6IG1lLm91dGVyUmFkaXVzO1xuXHRcdFx0dmFyIHZhbHVlQXRJbmRleE9yRGVmYXVsdCA9IGhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0O1xuXG5cdFx0XHRoZWxwZXJzLmV4dGVuZChhcmMsIHtcblx0XHRcdFx0Ly8gVXRpbGl0eVxuXHRcdFx0XHRfZGF0YXNldEluZGV4OiBtZS5pbmRleCxcblx0XHRcdFx0X2luZGV4OiBpbmRleCxcblxuXHRcdFx0XHQvLyBEZXNpcmVkIHZpZXcgcHJvcGVydGllc1xuXHRcdFx0XHRfbW9kZWw6IHtcblx0XHRcdFx0XHR4OiBjZW50ZXJYICsgY2hhcnQub2Zmc2V0WCxcblx0XHRcdFx0XHR5OiBjZW50ZXJZICsgY2hhcnQub2Zmc2V0WSxcblx0XHRcdFx0XHRzdGFydEFuZ2xlOiBzdGFydEFuZ2xlLFxuXHRcdFx0XHRcdGVuZEFuZ2xlOiBlbmRBbmdsZSxcblx0XHRcdFx0XHRjaXJjdW1mZXJlbmNlOiBjaXJjdW1mZXJlbmNlLFxuXHRcdFx0XHRcdG91dGVyUmFkaXVzOiBvdXRlclJhZGl1cyxcblx0XHRcdFx0XHRpbm5lclJhZGl1czogaW5uZXJSYWRpdXMsXG5cdFx0XHRcdFx0bGFiZWw6IHZhbHVlQXRJbmRleE9yRGVmYXVsdChkYXRhc2V0LmxhYmVsLCBpbmRleCwgY2hhcnQuZGF0YS5sYWJlbHNbaW5kZXhdKVxuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0dmFyIG1vZGVsID0gYXJjLl9tb2RlbDtcblxuXHRcdFx0Ly8gUmVzZXRzIHRoZSB2aXN1YWwgc3R5bGVzXG5cdFx0XHR2YXIgY3VzdG9tID0gYXJjLmN1c3RvbSB8fCB7fTtcblx0XHRcdHZhciB2YWx1ZU9yRGVmYXVsdCA9IGhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0O1xuXHRcdFx0dmFyIGVsZW1lbnRPcHRzID0gdGhpcy5jaGFydC5vcHRpb25zLmVsZW1lbnRzLmFyYztcblx0XHRcdG1vZGVsLmJhY2tncm91bmRDb2xvciA9IGN1c3RvbS5iYWNrZ3JvdW5kQ29sb3IgPyBjdXN0b20uYmFja2dyb3VuZENvbG9yIDogdmFsdWVPckRlZmF1bHQoZGF0YXNldC5iYWNrZ3JvdW5kQ29sb3IsIGluZGV4LCBlbGVtZW50T3B0cy5iYWNrZ3JvdW5kQ29sb3IpO1xuXHRcdFx0bW9kZWwuYm9yZGVyQ29sb3IgPSBjdXN0b20uYm9yZGVyQ29sb3IgPyBjdXN0b20uYm9yZGVyQ29sb3IgOiB2YWx1ZU9yRGVmYXVsdChkYXRhc2V0LmJvcmRlckNvbG9yLCBpbmRleCwgZWxlbWVudE9wdHMuYm9yZGVyQ29sb3IpO1xuXHRcdFx0bW9kZWwuYm9yZGVyV2lkdGggPSBjdXN0b20uYm9yZGVyV2lkdGggPyBjdXN0b20uYm9yZGVyV2lkdGggOiB2YWx1ZU9yRGVmYXVsdChkYXRhc2V0LmJvcmRlcldpZHRoLCBpbmRleCwgZWxlbWVudE9wdHMuYm9yZGVyV2lkdGgpO1xuXG5cdFx0XHQvLyBTZXQgY29ycmVjdCBhbmdsZXMgaWYgbm90IHJlc2V0dGluZ1xuXHRcdFx0aWYgKCFyZXNldCB8fCAhYW5pbWF0aW9uT3B0cy5hbmltYXRlUm90YXRlKSB7XG5cdFx0XHRcdGlmIChpbmRleCA9PT0gMCkge1xuXHRcdFx0XHRcdG1vZGVsLnN0YXJ0QW5nbGUgPSBvcHRzLnJvdGF0aW9uO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdG1vZGVsLnN0YXJ0QW5nbGUgPSBtZS5nZXRNZXRhKCkuZGF0YVtpbmRleCAtIDFdLl9tb2RlbC5lbmRBbmdsZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdG1vZGVsLmVuZEFuZ2xlID0gbW9kZWwuc3RhcnRBbmdsZSArIG1vZGVsLmNpcmN1bWZlcmVuY2U7XG5cdFx0XHR9XG5cblx0XHRcdGFyYy5waXZvdCgpO1xuXHRcdH0sXG5cblx0XHRjYWxjdWxhdGVUb3RhbDogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgZGF0YXNldCA9IHRoaXMuZ2V0RGF0YXNldCgpO1xuXHRcdFx0dmFyIG1ldGEgPSB0aGlzLmdldE1ldGEoKTtcblx0XHRcdHZhciB0b3RhbCA9IDA7XG5cdFx0XHR2YXIgdmFsdWU7XG5cblx0XHRcdGhlbHBlcnMuZWFjaChtZXRhLmRhdGEsIGZ1bmN0aW9uKGVsZW1lbnQsIGluZGV4KSB7XG5cdFx0XHRcdHZhbHVlID0gZGF0YXNldC5kYXRhW2luZGV4XTtcblx0XHRcdFx0aWYgKCFpc05hTih2YWx1ZSkgJiYgIWVsZW1lbnQuaGlkZGVuKSB7XG5cdFx0XHRcdFx0dG90YWwgKz0gTWF0aC5hYnModmFsdWUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0LyogaWYgKHRvdGFsID09PSAwKSB7XG5cdFx0XHRcdHRvdGFsID0gTmFOO1xuXHRcdFx0fSovXG5cblx0XHRcdHJldHVybiB0b3RhbDtcblx0XHR9LFxuXG5cdFx0Y2FsY3VsYXRlQ2lyY3VtZmVyZW5jZTogZnVuY3Rpb24odmFsdWUpIHtcblx0XHRcdHZhciB0b3RhbCA9IHRoaXMuZ2V0TWV0YSgpLnRvdGFsO1xuXHRcdFx0aWYgKHRvdGFsID4gMCAmJiAhaXNOYU4odmFsdWUpKSB7XG5cdFx0XHRcdHJldHVybiAoTWF0aC5QSSAqIDIuMCkgKiAoTWF0aC5hYnModmFsdWUpIC8gdG90YWwpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fSxcblxuXHRcdC8vIGdldHMgdGhlIG1heCBib3JkZXIgb3IgaG92ZXIgd2lkdGggdG8gcHJvcGVybHkgc2NhbGUgcGllIGNoYXJ0c1xuXHRcdGdldE1heEJvcmRlcldpZHRoOiBmdW5jdGlvbihhcmNzKSB7XG5cdFx0XHR2YXIgbWF4ID0gMDtcblx0XHRcdHZhciBpbmRleCA9IHRoaXMuaW5kZXg7XG5cdFx0XHR2YXIgbGVuZ3RoID0gYXJjcy5sZW5ndGg7XG5cdFx0XHR2YXIgYm9yZGVyV2lkdGg7XG5cdFx0XHR2YXIgaG92ZXJXaWR0aDtcblxuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuXHRcdFx0XHRib3JkZXJXaWR0aCA9IGFyY3NbaV0uX21vZGVsID8gYXJjc1tpXS5fbW9kZWwuYm9yZGVyV2lkdGggOiAwO1xuXHRcdFx0XHRob3ZlcldpZHRoID0gYXJjc1tpXS5fY2hhcnQgPyBhcmNzW2ldLl9jaGFydC5jb25maWcuZGF0YS5kYXRhc2V0c1tpbmRleF0uaG92ZXJCb3JkZXJXaWR0aCA6IDA7XG5cblx0XHRcdFx0bWF4ID0gYm9yZGVyV2lkdGggPiBtYXggPyBib3JkZXJXaWR0aCA6IG1heDtcblx0XHRcdFx0bWF4ID0gaG92ZXJXaWR0aCA+IG1heCA/IGhvdmVyV2lkdGggOiBtYXg7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF4O1xuXHRcdH1cblx0fSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7dc6\n")},"7e33":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar helpers = __webpack_require__(/*! ./helpers.core */ \"7d23\");\n\n/**\n * @namespace Chart.helpers.canvas\n */\nvar exports = module.exports = {\n\t/**\n\t * Clears the entire canvas associated to the given `chart`.\n\t * @param {Chart} chart - The chart for which to clear the canvas.\n\t */\n\tclear: function(chart) {\n\t\tchart.ctx.clearRect(0, 0, chart.width, chart.height);\n\t},\n\n\t/**\n\t * Creates a \"path\" for a rectangle with rounded corners at position (x, y) with a\n\t * given size (width, height) and the same `radius` for all corners.\n\t * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context.\n\t * @param {Number} x - The x axis of the coordinate for the rectangle starting point.\n\t * @param {Number} y - The y axis of the coordinate for the rectangle starting point.\n\t * @param {Number} width - The rectangle's width.\n\t * @param {Number} height - The rectangle's height.\n\t * @param {Number} radius - The rounded amount (in pixels) for the four corners.\n\t * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object?\n\t */\n\troundedRect: function(ctx, x, y, width, height, radius) {\n\t\tif (radius) {\n\t\t\t// NOTE(SB) `epsilon` helps to prevent minor artifacts appearing\n\t\t\t// on Chrome when `r` is exactly half the height or the width.\n\t\t\tvar epsilon = 0.0000001;\n\t\t\tvar r = Math.min(radius, (height / 2) - epsilon, (width / 2) - epsilon);\n\n\t\t\tctx.moveTo(x + r, y);\n\t\t\tctx.lineTo(x + width - r, y);\n\t\t\tctx.arcTo(x + width, y, x + width, y + r, r);\n\t\t\tctx.lineTo(x + width, y + height - r);\n\t\t\tctx.arcTo(x + width, y + height, x + width - r, y + height, r);\n\t\t\tctx.lineTo(x + r, y + height);\n\t\t\tctx.arcTo(x, y + height, x, y + height - r, r);\n\t\t\tctx.lineTo(x, y + r);\n\t\t\tctx.arcTo(x, y, x + r, y, r);\n\t\t\tctx.closePath();\n\t\t\tctx.moveTo(x, y);\n\t\t} else {\n\t\t\tctx.rect(x, y, width, height);\n\t\t}\n\t},\n\n\tdrawPoint: function(ctx, style, radius, x, y, rotation) {\n\t\tvar type, edgeLength, xOffset, yOffset, height, size;\n\t\trotation = rotation || 0;\n\n\t\tif (style && typeof style === 'object') {\n\t\t\ttype = style.toString();\n\t\t\tif (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {\n\t\t\t\tctx.drawImage(style, x - style.width / 2, y - style.height / 2, style.width, style.height);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (isNaN(radius) || radius <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tctx.save();\n\t\tctx.translate(x, y);\n\t\tctx.rotate(rotation * Math.PI / 180);\n\t\tctx.beginPath();\n\n\t\tswitch (style) {\n\t\t// Default includes circle\n\t\tdefault:\n\t\t\tctx.arc(0, 0, radius, 0, Math.PI * 2);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'triangle':\n\t\t\tedgeLength = 3 * radius / Math.sqrt(3);\n\t\t\theight = edgeLength * Math.sqrt(3) / 2;\n\t\t\tctx.moveTo(-edgeLength / 2, height / 3);\n\t\t\tctx.lineTo(edgeLength / 2, height / 3);\n\t\t\tctx.lineTo(0, -2 * height / 3);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'rect':\n\t\t\tsize = 1 / Math.SQRT2 * radius;\n\t\t\tctx.rect(-size, -size, 2 * size, 2 * size);\n\t\t\tbreak;\n\t\tcase 'rectRounded':\n\t\t\tvar offset = radius / Math.SQRT2;\n\t\t\tvar leftX = -offset;\n\t\t\tvar topY = -offset;\n\t\t\tvar sideSize = Math.SQRT2 * radius;\n\n\t\t\t// NOTE(SB) the rounded rect implementation changed to use `arcTo`\n\t\t\t// instead of `quadraticCurveTo` since it generates better results\n\t\t\t// when rect is almost a circle. 0.425 (instead of 0.5) produces\n\t\t\t// results visually closer to the previous impl.\n\t\t\tthis.roundedRect(ctx, leftX, topY, sideSize, sideSize, radius * 0.425);\n\t\t\tbreak;\n\t\tcase 'rectRot':\n\t\t\tsize = 1 / Math.SQRT2 * radius;\n\t\t\tctx.moveTo(-size, 0);\n\t\t\tctx.lineTo(0, size);\n\t\t\tctx.lineTo(size, 0);\n\t\t\tctx.lineTo(0, -size);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'cross':\n\t\t\tctx.moveTo(0, radius);\n\t\t\tctx.lineTo(0, -radius);\n\t\t\tctx.moveTo(-radius, 0);\n\t\t\tctx.lineTo(radius, 0);\n\t\t\tbreak;\n\t\tcase 'crossRot':\n\t\t\txOffset = Math.cos(Math.PI / 4) * radius;\n\t\t\tyOffset = Math.sin(Math.PI / 4) * radius;\n\t\t\tctx.moveTo(-xOffset, -yOffset);\n\t\t\tctx.lineTo(xOffset, yOffset);\n\t\t\tctx.moveTo(-xOffset, yOffset);\n\t\t\tctx.lineTo(xOffset, -yOffset);\n\t\t\tbreak;\n\t\tcase 'star':\n\t\t\tctx.moveTo(0, radius);\n\t\t\tctx.lineTo(0, -radius);\n\t\t\tctx.moveTo(-radius, 0);\n\t\t\tctx.lineTo(radius, 0);\n\t\t\txOffset = Math.cos(Math.PI / 4) * radius;\n\t\t\tyOffset = Math.sin(Math.PI / 4) * radius;\n\t\t\tctx.moveTo(-xOffset, -yOffset);\n\t\t\tctx.lineTo(xOffset, yOffset);\n\t\t\tctx.moveTo(-xOffset, yOffset);\n\t\t\tctx.lineTo(xOffset, -yOffset);\n\t\t\tbreak;\n\t\tcase 'line':\n\t\t\tctx.moveTo(-radius, 0);\n\t\t\tctx.lineTo(radius, 0);\n\t\t\tbreak;\n\t\tcase 'dash':\n\t\t\tctx.moveTo(0, 0);\n\t\t\tctx.lineTo(radius, 0);\n\t\t\tbreak;\n\t\t}\n\n\t\tctx.fill();\n\t\tctx.stroke();\n\t\tctx.restore();\n\t},\n\n\tclipArea: function(ctx, area) {\n\t\tctx.save();\n\t\tctx.beginPath();\n\t\tctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);\n\t\tctx.clip();\n\t},\n\n\tunclipArea: function(ctx) {\n\t\tctx.restore();\n\t},\n\n\tlineTo: function(ctx, previous, target, flip) {\n\t\tif (target.steppedLine) {\n\t\t\tif ((target.steppedLine === 'after' && !flip) || (target.steppedLine !== 'after' && flip)) {\n\t\t\t\tctx.lineTo(previous.x, target.y);\n\t\t\t} else {\n\t\t\t\tctx.lineTo(target.x, previous.y);\n\t\t\t}\n\t\t\tctx.lineTo(target.x, target.y);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!target.tension) {\n\t\t\tctx.lineTo(target.x, target.y);\n\t\t\treturn;\n\t\t}\n\n\t\tctx.bezierCurveTo(\n\t\t\tflip ? previous.controlPointPreviousX : previous.controlPointNextX,\n\t\t\tflip ? previous.controlPointPreviousY : previous.controlPointNextY,\n\t\t\tflip ? target.controlPointNextX : target.controlPointPreviousX,\n\t\t\tflip ? target.controlPointNextY : target.controlPointPreviousY,\n\t\t\ttarget.x,\n\t\t\ttarget.y);\n\t}\n};\n\n// DEPRECATIONS\n\n/**\n * Provided for backward compatibility, use Chart.helpers.canvas.clear instead.\n * @namespace Chart.helpers.clear\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers.clear = exports.clear;\n\n/**\n * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead.\n * @namespace Chart.helpers.drawRoundedRectangle\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers.drawRoundedRectangle = function(ctx) {\n\tctx.beginPath();\n\texports.roundedRect.apply(exports, arguments);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2UzMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLmNhbnZhcy5qcz80OWZhIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMuY29yZScpO1xuXG4vKipcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuaGVscGVycy5jYW52YXNcbiAqL1xudmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHtcblx0LyoqXG5cdCAqIENsZWFycyB0aGUgZW50aXJlIGNhbnZhcyBhc3NvY2lhdGVkIHRvIHRoZSBnaXZlbiBgY2hhcnRgLlxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIFRoZSBjaGFydCBmb3Igd2hpY2ggdG8gY2xlYXIgdGhlIGNhbnZhcy5cblx0ICovXG5cdGNsZWFyOiBmdW5jdGlvbihjaGFydCkge1xuXHRcdGNoYXJ0LmN0eC5jbGVhclJlY3QoMCwgMCwgY2hhcnQud2lkdGgsIGNoYXJ0LmhlaWdodCk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBcInBhdGhcIiBmb3IgYSByZWN0YW5nbGUgd2l0aCByb3VuZGVkIGNvcm5lcnMgYXQgcG9zaXRpb24gKHgsIHkpIHdpdGggYVxuXHQgKiBnaXZlbiBzaXplICh3aWR0aCwgaGVpZ2h0KSBhbmQgdGhlIHNhbWUgYHJhZGl1c2AgZm9yIGFsbCBjb3JuZXJzLlxuXHQgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY3R4IC0gVGhlIGNhbnZhcyAyRCBDb250ZXh0LlxuXHQgKiBAcGFyYW0ge051bWJlcn0geCAtIFRoZSB4IGF4aXMgb2YgdGhlIGNvb3JkaW5hdGUgZm9yIHRoZSByZWN0YW5nbGUgc3RhcnRpbmcgcG9pbnQuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5IC0gVGhlIHkgYXhpcyBvZiB0aGUgY29vcmRpbmF0ZSBmb3IgdGhlIHJlY3RhbmdsZSBzdGFydGluZyBwb2ludC5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IHdpZHRoIC0gVGhlIHJlY3RhbmdsZSdzIHdpZHRoLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gaGVpZ2h0IC0gVGhlIHJlY3RhbmdsZSdzIGhlaWdodC5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IHJhZGl1cyAtIFRoZSByb3VuZGVkIGFtb3VudCAoaW4gcGl4ZWxzKSBmb3IgdGhlIGZvdXIgY29ybmVycy5cblx0ICogQHRvZG8gaGFuZGxlIGByYWRpdXNgIGFzIHRvcC1sZWZ0LCB0b3AtcmlnaHQsIGJvdHRvbS1yaWdodCwgYm90dG9tLWxlZnQgYXJyYXkvb2JqZWN0P1xuXHQgKi9cblx0cm91bmRlZFJlY3Q6IGZ1bmN0aW9uKGN0eCwgeCwgeSwgd2lkdGgsIGhlaWdodCwgcmFkaXVzKSB7XG5cdFx0aWYgKHJhZGl1cykge1xuXHRcdFx0Ly8gTk9URShTQikgYGVwc2lsb25gIGhlbHBzIHRvIHByZXZlbnQgbWlub3IgYXJ0aWZhY3RzIGFwcGVhcmluZ1xuXHRcdFx0Ly8gb24gQ2hyb21lIHdoZW4gYHJgIGlzIGV4YWN0bHkgaGFsZiB0aGUgaGVpZ2h0IG9yIHRoZSB3aWR0aC5cblx0XHRcdHZhciBlcHNpbG9uID0gMC4wMDAwMDAxO1xuXHRcdFx0dmFyIHIgPSBNYXRoLm1pbihyYWRpdXMsIChoZWlnaHQgLyAyKSAtIGVwc2lsb24sICh3aWR0aCAvIDIpIC0gZXBzaWxvbik7XG5cblx0XHRcdGN0eC5tb3ZlVG8oeCArIHIsIHkpO1xuXHRcdFx0Y3R4LmxpbmVUbyh4ICsgd2lkdGggLSByLCB5KTtcblx0XHRcdGN0eC5hcmNUbyh4ICsgd2lkdGgsIHksIHggKyB3aWR0aCwgeSArIHIsIHIpO1xuXHRcdFx0Y3R4LmxpbmVUbyh4ICsgd2lkdGgsIHkgKyBoZWlnaHQgLSByKTtcblx0XHRcdGN0eC5hcmNUbyh4ICsgd2lkdGgsIHkgKyBoZWlnaHQsIHggKyB3aWR0aCAtIHIsIHkgKyBoZWlnaHQsIHIpO1xuXHRcdFx0Y3R4LmxpbmVUbyh4ICsgciwgeSArIGhlaWdodCk7XG5cdFx0XHRjdHguYXJjVG8oeCwgeSArIGhlaWdodCwgeCwgeSArIGhlaWdodCAtIHIsIHIpO1xuXHRcdFx0Y3R4LmxpbmVUbyh4LCB5ICsgcik7XG5cdFx0XHRjdHguYXJjVG8oeCwgeSwgeCArIHIsIHksIHIpO1xuXHRcdFx0Y3R4LmNsb3NlUGF0aCgpO1xuXHRcdFx0Y3R4Lm1vdmVUbyh4LCB5KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y3R4LnJlY3QoeCwgeSwgd2lkdGgsIGhlaWdodCk7XG5cdFx0fVxuXHR9LFxuXG5cdGRyYXdQb2ludDogZnVuY3Rpb24oY3R4LCBzdHlsZSwgcmFkaXVzLCB4LCB5LCByb3RhdGlvbikge1xuXHRcdHZhciB0eXBlLCBlZGdlTGVuZ3RoLCB4T2Zmc2V0LCB5T2Zmc2V0LCBoZWlnaHQsIHNpemU7XG5cdFx0cm90YXRpb24gPSByb3RhdGlvbiB8fCAwO1xuXG5cdFx0aWYgKHN0eWxlICYmIHR5cGVvZiBzdHlsZSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdHR5cGUgPSBzdHlsZS50b1N0cmluZygpO1xuXHRcdFx0aWYgKHR5cGUgPT09ICdbb2JqZWN0IEhUTUxJbWFnZUVsZW1lbnRdJyB8fCB0eXBlID09PSAnW29iamVjdCBIVE1MQ2FudmFzRWxlbWVudF0nKSB7XG5cdFx0XHRcdGN0eC5kcmF3SW1hZ2Uoc3R5bGUsIHggLSBzdHlsZS53aWR0aCAvIDIsIHkgLSBzdHlsZS5oZWlnaHQgLyAyLCBzdHlsZS53aWR0aCwgc3R5bGUuaGVpZ2h0KTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChpc05hTihyYWRpdXMpIHx8IHJhZGl1cyA8PSAwKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y3R4LnNhdmUoKTtcblx0XHRjdHgudHJhbnNsYXRlKHgsIHkpO1xuXHRcdGN0eC5yb3RhdGUocm90YXRpb24gKiBNYXRoLlBJIC8gMTgwKTtcblx0XHRjdHguYmVnaW5QYXRoKCk7XG5cblx0XHRzd2l0Y2ggKHN0eWxlKSB7XG5cdFx0Ly8gRGVmYXVsdCBpbmNsdWRlcyBjaXJjbGVcblx0XHRkZWZhdWx0OlxuXHRcdFx0Y3R4LmFyYygwLCAwLCByYWRpdXMsIDAsIE1hdGguUEkgKiAyKTtcblx0XHRcdGN0eC5jbG9zZVBhdGgoKTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ3RyaWFuZ2xlJzpcblx0XHRcdGVkZ2VMZW5ndGggPSAzICogcmFkaXVzIC8gTWF0aC5zcXJ0KDMpO1xuXHRcdFx0aGVpZ2h0ID0gZWRnZUxlbmd0aCAqIE1hdGguc3FydCgzKSAvIDI7XG5cdFx0XHRjdHgubW92ZVRvKC1lZGdlTGVuZ3RoIC8gMiwgaGVpZ2h0IC8gMyk7XG5cdFx0XHRjdHgubGluZVRvKGVkZ2VMZW5ndGggLyAyLCBoZWlnaHQgLyAzKTtcblx0XHRcdGN0eC5saW5lVG8oMCwgLTIgKiBoZWlnaHQgLyAzKTtcblx0XHRcdGN0eC5jbG9zZVBhdGgoKTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ3JlY3QnOlxuXHRcdFx0c2l6ZSA9IDEgLyBNYXRoLlNRUlQyICogcmFkaXVzO1xuXHRcdFx0Y3R4LnJlY3QoLXNpemUsIC1zaXplLCAyICogc2l6ZSwgMiAqIHNpemUpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAncmVjdFJvdW5kZWQnOlxuXHRcdFx0dmFyIG9mZnNldCA9IHJhZGl1cyAvIE1hdGguU1FSVDI7XG5cdFx0XHR2YXIgbGVmdFggPSAtb2Zmc2V0O1xuXHRcdFx0dmFyIHRvcFkgPSAtb2Zmc2V0O1xuXHRcdFx0dmFyIHNpZGVTaXplID0gTWF0aC5TUVJUMiAqIHJhZGl1cztcblxuXHRcdFx0Ly8gTk9URShTQikgdGhlIHJvdW5kZWQgcmVjdCBpbXBsZW1lbnRhdGlvbiBjaGFuZ2VkIHRvIHVzZSBgYXJjVG9gXG5cdFx0XHQvLyBpbnN0ZWFkIG9mIGBxdWFkcmF0aWNDdXJ2ZVRvYCBzaW5jZSBpdCBnZW5lcmF0ZXMgYmV0dGVyIHJlc3VsdHNcblx0XHRcdC8vIHdoZW4gcmVjdCBpcyBhbG1vc3QgYSBjaXJjbGUuIDAuNDI1IChpbnN0ZWFkIG9mIDAuNSkgcHJvZHVjZXNcblx0XHRcdC8vIHJlc3VsdHMgdmlzdWFsbHkgY2xvc2VyIHRvIHRoZSBwcmV2aW91cyBpbXBsLlxuXHRcdFx0dGhpcy5yb3VuZGVkUmVjdChjdHgsIGxlZnRYLCB0b3BZLCBzaWRlU2l6ZSwgc2lkZVNpemUsIHJhZGl1cyAqIDAuNDI1KTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ3JlY3RSb3QnOlxuXHRcdFx0c2l6ZSA9IDEgLyBNYXRoLlNRUlQyICogcmFkaXVzO1xuXHRcdFx0Y3R4Lm1vdmVUbygtc2l6ZSwgMCk7XG5cdFx0XHRjdHgubGluZVRvKDAsIHNpemUpO1xuXHRcdFx0Y3R4LmxpbmVUbyhzaXplLCAwKTtcblx0XHRcdGN0eC5saW5lVG8oMCwgLXNpemUpO1xuXHRcdFx0Y3R4LmNsb3NlUGF0aCgpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnY3Jvc3MnOlxuXHRcdFx0Y3R4Lm1vdmVUbygwLCByYWRpdXMpO1xuXHRcdFx0Y3R4LmxpbmVUbygwLCAtcmFkaXVzKTtcblx0XHRcdGN0eC5tb3ZlVG8oLXJhZGl1cywgMCk7XG5cdFx0XHRjdHgubGluZVRvKHJhZGl1cywgMCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdjcm9zc1JvdCc6XG5cdFx0XHR4T2Zmc2V0ID0gTWF0aC5jb3MoTWF0aC5QSSAvIDQpICogcmFkaXVzO1xuXHRcdFx0eU9mZnNldCA9IE1hdGguc2luKE1hdGguUEkgLyA0KSAqIHJhZGl1cztcblx0XHRcdGN0eC5tb3ZlVG8oLXhPZmZzZXQsIC15T2Zmc2V0KTtcblx0XHRcdGN0eC5saW5lVG8oeE9mZnNldCwgeU9mZnNldCk7XG5cdFx0XHRjdHgubW92ZVRvKC14T2Zmc2V0LCB5T2Zmc2V0KTtcblx0XHRcdGN0eC5saW5lVG8oeE9mZnNldCwgLXlPZmZzZXQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnc3Rhcic6XG5cdFx0XHRjdHgubW92ZVRvKDAsIHJhZGl1cyk7XG5cdFx0XHRjdHgubGluZVRvKDAsIC1yYWRpdXMpO1xuXHRcdFx0Y3R4Lm1vdmVUbygtcmFkaXVzLCAwKTtcblx0XHRcdGN0eC5saW5lVG8ocmFkaXVzLCAwKTtcblx0XHRcdHhPZmZzZXQgPSBNYXRoLmNvcyhNYXRoLlBJIC8gNCkgKiByYWRpdXM7XG5cdFx0XHR5T2Zmc2V0ID0gTWF0aC5zaW4oTWF0aC5QSSAvIDQpICogcmFkaXVzO1xuXHRcdFx0Y3R4Lm1vdmVUbygteE9mZnNldCwgLXlPZmZzZXQpO1xuXHRcdFx0Y3R4LmxpbmVUbyh4T2Zmc2V0LCB5T2Zmc2V0KTtcblx0XHRcdGN0eC5tb3ZlVG8oLXhPZmZzZXQsIHlPZmZzZXQpO1xuXHRcdFx0Y3R4LmxpbmVUbyh4T2Zmc2V0LCAteU9mZnNldCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdsaW5lJzpcblx0XHRcdGN0eC5tb3ZlVG8oLXJhZGl1cywgMCk7XG5cdFx0XHRjdHgubGluZVRvKHJhZGl1cywgMCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdkYXNoJzpcblx0XHRcdGN0eC5tb3ZlVG8oMCwgMCk7XG5cdFx0XHRjdHgubGluZVRvKHJhZGl1cywgMCk7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHRjdHguZmlsbCgpO1xuXHRcdGN0eC5zdHJva2UoKTtcblx0XHRjdHgucmVzdG9yZSgpO1xuXHR9LFxuXG5cdGNsaXBBcmVhOiBmdW5jdGlvbihjdHgsIGFyZWEpIHtcblx0XHRjdHguc2F2ZSgpO1xuXHRcdGN0eC5iZWdpblBhdGgoKTtcblx0XHRjdHgucmVjdChhcmVhLmxlZnQsIGFyZWEudG9wLCBhcmVhLnJpZ2h0IC0gYXJlYS5sZWZ0LCBhcmVhLmJvdHRvbSAtIGFyZWEudG9wKTtcblx0XHRjdHguY2xpcCgpO1xuXHR9LFxuXG5cdHVuY2xpcEFyZWE6IGZ1bmN0aW9uKGN0eCkge1xuXHRcdGN0eC5yZXN0b3JlKCk7XG5cdH0sXG5cblx0bGluZVRvOiBmdW5jdGlvbihjdHgsIHByZXZpb3VzLCB0YXJnZXQsIGZsaXApIHtcblx0XHRpZiAodGFyZ2V0LnN0ZXBwZWRMaW5lKSB7XG5cdFx0XHRpZiAoKHRhcmdldC5zdGVwcGVkTGluZSA9PT0gJ2FmdGVyJyAmJiAhZmxpcCkgfHwgKHRhcmdldC5zdGVwcGVkTGluZSAhPT0gJ2FmdGVyJyAmJiBmbGlwKSkge1xuXHRcdFx0XHRjdHgubGluZVRvKHByZXZpb3VzLngsIHRhcmdldC55KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGN0eC5saW5lVG8odGFyZ2V0LngsIHByZXZpb3VzLnkpO1xuXHRcdFx0fVxuXHRcdFx0Y3R4LmxpbmVUbyh0YXJnZXQueCwgdGFyZ2V0LnkpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICghdGFyZ2V0LnRlbnNpb24pIHtcblx0XHRcdGN0eC5saW5lVG8odGFyZ2V0LngsIHRhcmdldC55KTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjdHguYmV6aWVyQ3VydmVUbyhcblx0XHRcdGZsaXAgPyBwcmV2aW91cy5jb250cm9sUG9pbnRQcmV2aW91c1ggOiBwcmV2aW91cy5jb250cm9sUG9pbnROZXh0WCxcblx0XHRcdGZsaXAgPyBwcmV2aW91cy5jb250cm9sUG9pbnRQcmV2aW91c1kgOiBwcmV2aW91cy5jb250cm9sUG9pbnROZXh0WSxcblx0XHRcdGZsaXAgPyB0YXJnZXQuY29udHJvbFBvaW50TmV4dFggOiB0YXJnZXQuY29udHJvbFBvaW50UHJldmlvdXNYLFxuXHRcdFx0ZmxpcCA/IHRhcmdldC5jb250cm9sUG9pbnROZXh0WSA6IHRhcmdldC5jb250cm9sUG9pbnRQcmV2aW91c1ksXG5cdFx0XHR0YXJnZXQueCxcblx0XHRcdHRhcmdldC55KTtcblx0fVxufTtcblxuLy8gREVQUkVDQVRJT05TXG5cbi8qKlxuICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHVzZSBDaGFydC5oZWxwZXJzLmNhbnZhcy5jbGVhciBpbnN0ZWFkLlxuICogQG5hbWVzcGFjZSBDaGFydC5oZWxwZXJzLmNsZWFyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNy4wXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXG4gKiBAcHJpdmF0ZVxuICovXG5oZWxwZXJzLmNsZWFyID0gZXhwb3J0cy5jbGVhcjtcblxuLyoqXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LmhlbHBlcnMuY2FudmFzLnJvdW5kZWRSZWN0IGluc3RlYWQuXG4gKiBAbmFtZXNwYWNlIENoYXJ0LmhlbHBlcnMuZHJhd1JvdW5kZWRSZWN0YW5nbGVcbiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi43LjBcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcbiAqIEBwcml2YXRlXG4gKi9cbmhlbHBlcnMuZHJhd1JvdW5kZWRSZWN0YW5nbGUgPSBmdW5jdGlvbihjdHgpIHtcblx0Y3R4LmJlZ2luUGF0aCgpO1xuXHRleHBvcnRzLnJvdW5kZWRSZWN0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cyk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7e33\n")},"803b":function(module,exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = function(Chart) {\n\n\tChart.Line = function(context, config) {\n\t\tconfig.type = 'line';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODAzYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY2hhcnRzL0NoYXJ0LkxpbmUuanM/ZWNlZSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oQ2hhcnQpIHtcblxuXHRDaGFydC5MaW5lID0gZnVuY3Rpb24oY29udGV4dCwgY29uZmlnKSB7XG5cdFx0Y29uZmlnLnR5cGUgPSAnbGluZSc7XG5cblx0XHRyZXR1cm4gbmV3IENoYXJ0KGNvbnRleHQsIGNvbmZpZyk7XG5cdH07XG5cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///803b\n")},8507:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\nvar basic = __webpack_require__(/*! ./platform.basic */ \"318e\");\nvar dom = __webpack_require__(/*! ./platform.dom */ \"db1a\");\n\n// @TODO Make possible to select another platform at build time.\nvar implementation = dom._enabled ? dom : basic;\n\n/**\n * @namespace Chart.platform\n * @see https://chartjs.gitbooks.io/proposals/content/Platform.html\n * @since 2.4.0\n */\nmodule.exports = helpers.extend({\n\t/**\n\t * @since 2.7.0\n\t */\n\tinitialize: function() {},\n\n\t/**\n\t * Called at chart construction time, returns a context2d instance implementing\n\t * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}.\n\t * @param {*} item - The native item from which to acquire context (platform specific)\n\t * @param {Object} options - The chart options\n\t * @returns {CanvasRenderingContext2D} context2d instance\n\t */\n\tacquireContext: function() {},\n\n\t/**\n\t * Called at chart destruction time, releases any resources associated to the context\n\t * previously returned by the acquireContext() method.\n\t * @param {CanvasRenderingContext2D} context - The context2d instance\n\t * @returns {Boolean} true if the method succeeded, else false\n\t */\n\treleaseContext: function() {},\n\n\t/**\n\t * Registers the specified listener on the given chart.\n\t * @param {Chart} chart - Chart from which to listen for event\n\t * @param {String} type - The ({@link IEvent}) type to listen for\n\t * @param {Function} listener - Receives a notification (an object that implements\n\t * the {@link IEvent} interface) when an event of the specified type occurs.\n\t */\n\taddEventListener: function() {},\n\n\t/**\n\t * Removes the specified listener previously registered with addEventListener.\n\t * @param {Chart} chart -Chart from which to remove the listener\n\t * @param {String} type - The ({@link IEvent}) type to remove\n\t * @param {Function} listener - The listener function to remove from the event target.\n\t */\n\tremoveEventListener: function() {}\n\n}, implementation);\n\n/**\n * @interface IPlatform\n * Allows abstracting platform dependencies away from the chart\n * @borrows Chart.platform.acquireContext as acquireContext\n * @borrows Chart.platform.releaseContext as releaseContext\n * @borrows Chart.platform.addEventListener as addEventListener\n * @borrows Chart.platform.removeEventListener as removeEventListener\n */\n\n/**\n * @interface IEvent\n * @prop {String} type - The event type name, possible values are:\n * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout',\n * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize'\n * @prop {*} native - The original native event (null for emulated events, e.g. 'resize')\n * @prop {Number} x - The mouse x position, relative to the canvas (null for incompatible events)\n * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events)\n */\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUwNy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGxhdGZvcm1zL3BsYXRmb3JtLmpzPzg4Y2UiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcbnZhciBiYXNpYyA9IHJlcXVpcmUoJy4vcGxhdGZvcm0uYmFzaWMnKTtcbnZhciBkb20gPSByZXF1aXJlKCcuL3BsYXRmb3JtLmRvbScpO1xuXG4vLyBAVE9ETyBNYWtlIHBvc3NpYmxlIHRvIHNlbGVjdCBhbm90aGVyIHBsYXRmb3JtIGF0IGJ1aWxkIHRpbWUuXG52YXIgaW1wbGVtZW50YXRpb24gPSBkb20uX2VuYWJsZWQgPyBkb20gOiBiYXNpYztcblxuLyoqXG4gKiBAbmFtZXNwYWNlIENoYXJ0LnBsYXRmb3JtXG4gKiBAc2VlIGh0dHBzOi8vY2hhcnRqcy5naXRib29rcy5pby9wcm9wb3NhbHMvY29udGVudC9QbGF0Zm9ybS5odG1sXG4gKiBAc2luY2UgMi40LjBcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBoZWxwZXJzLmV4dGVuZCh7XG5cdC8qKlxuXHQgKiBAc2luY2UgMi43LjBcblx0ICovXG5cdGluaXRpYWxpemU6IGZ1bmN0aW9uKCkge30sXG5cblx0LyoqXG5cdCAqIENhbGxlZCBhdCBjaGFydCBjb25zdHJ1Y3Rpb24gdGltZSwgcmV0dXJucyBhIGNvbnRleHQyZCBpbnN0YW5jZSBpbXBsZW1lbnRpbmdcblx0ICogdGhlIFtXM0MgQ2FudmFzIDJEIENvbnRleHQgQVBJIHN0YW5kYXJkXXtAbGluayBodHRwczovL3d3dy53My5vcmcvVFIvMmRjb250ZXh0L30uXG5cdCAqIEBwYXJhbSB7Kn0gaXRlbSAtIFRoZSBuYXRpdmUgaXRlbSBmcm9tIHdoaWNoIHRvIGFjcXVpcmUgY29udGV4dCAocGxhdGZvcm0gc3BlY2lmaWMpXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIGNoYXJ0IG9wdGlvbnNcblx0ICogQHJldHVybnMge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dDJkIGluc3RhbmNlXG5cdCAqL1xuXHRhY3F1aXJlQ29udGV4dDogZnVuY3Rpb24oKSB7fSxcblxuXHQvKipcblx0ICogQ2FsbGVkIGF0IGNoYXJ0IGRlc3RydWN0aW9uIHRpbWUsIHJlbGVhc2VzIGFueSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgY29udGV4dFxuXHQgKiBwcmV2aW91c2x5IHJldHVybmVkIGJ5IHRoZSBhY3F1aXJlQ29udGV4dCgpIG1ldGhvZC5cblx0ICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgLSBUaGUgY29udGV4dDJkIGluc3RhbmNlXG5cdCAqIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHRoZSBtZXRob2Qgc3VjY2VlZGVkLCBlbHNlIGZhbHNlXG5cdCAqL1xuXHRyZWxlYXNlQ29udGV4dDogZnVuY3Rpb24oKSB7fSxcblxuXHQvKipcblx0ICogUmVnaXN0ZXJzIHRoZSBzcGVjaWZpZWQgbGlzdGVuZXIgb24gdGhlIGdpdmVuIGNoYXJ0LlxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIENoYXJ0IGZyb20gd2hpY2ggdG8gbGlzdGVuIGZvciBldmVudFxuXHQgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAtIFRoZSAoe0BsaW5rIElFdmVudH0pIHR5cGUgdG8gbGlzdGVuIGZvclxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciAtIFJlY2VpdmVzIGEgbm90aWZpY2F0aW9uIChhbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzXG5cdCAqIHRoZSB7QGxpbmsgSUV2ZW50fSBpbnRlcmZhY2UpIHdoZW4gYW4gZXZlbnQgb2YgdGhlIHNwZWNpZmllZCB0eXBlIG9jY3Vycy5cblx0ICovXG5cdGFkZEV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uKCkge30sXG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBhZGRFdmVudExpc3RlbmVyLlxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtQ2hhcnQgZnJvbSB3aGljaCB0byByZW1vdmUgdGhlIGxpc3RlbmVyXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIC0gVGhlICh7QGxpbmsgSUV2ZW50fSkgdHlwZSB0byByZW1vdmVcblx0ICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgLSBUaGUgbGlzdGVuZXIgZnVuY3Rpb24gdG8gcmVtb3ZlIGZyb20gdGhlIGV2ZW50IHRhcmdldC5cblx0ICovXG5cdHJlbW92ZUV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uKCkge31cblxufSwgaW1wbGVtZW50YXRpb24pO1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgSVBsYXRmb3JtXG4gKiBBbGxvd3MgYWJzdHJhY3RpbmcgcGxhdGZvcm0gZGVwZW5kZW5jaWVzIGF3YXkgZnJvbSB0aGUgY2hhcnRcbiAqIEBib3Jyb3dzIENoYXJ0LnBsYXRmb3JtLmFjcXVpcmVDb250ZXh0IGFzIGFjcXVpcmVDb250ZXh0XG4gKiBAYm9ycm93cyBDaGFydC5wbGF0Zm9ybS5yZWxlYXNlQ29udGV4dCBhcyByZWxlYXNlQ29udGV4dFxuICogQGJvcnJvd3MgQ2hhcnQucGxhdGZvcm0uYWRkRXZlbnRMaXN0ZW5lciBhcyBhZGRFdmVudExpc3RlbmVyXG4gKiBAYm9ycm93cyBDaGFydC5wbGF0Zm9ybS5yZW1vdmVFdmVudExpc3RlbmVyIGFzIHJlbW92ZUV2ZW50TGlzdGVuZXJcbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgSUV2ZW50XG4gKiBAcHJvcCB7U3RyaW5nfSB0eXBlIC0gVGhlIGV2ZW50IHR5cGUgbmFtZSwgcG9zc2libGUgdmFsdWVzIGFyZTpcbiAqICdjb250ZXh0bWVudScsICdtb3VzZWVudGVyJywgJ21vdXNlZG93bicsICdtb3VzZW1vdmUnLCAnbW91c2V1cCcsICdtb3VzZW91dCcsXG4gKiAnY2xpY2snLCAnZGJsY2xpY2snLCAna2V5ZG93bicsICdrZXlwcmVzcycsICdrZXl1cCcgYW5kICdyZXNpemUnXG4gKiBAcHJvcCB7Kn0gbmF0aXZlIC0gVGhlIG9yaWdpbmFsIG5hdGl2ZSBldmVudCAobnVsbCBmb3IgZW11bGF0ZWQgZXZlbnRzLCBlLmcuICdyZXNpemUnKVxuICogQHByb3Age051bWJlcn0geCAtIFRoZSBtb3VzZSB4IHBvc2l0aW9uLCByZWxhdGl2ZSB0byB0aGUgY2FudmFzIChudWxsIGZvciBpbmNvbXBhdGlibGUgZXZlbnRzKVxuICogQHByb3Age051bWJlcn0geSAtIFRoZSBtb3VzZSB5IHBvc2l0aW9uLCByZWxhdGl2ZSB0byB0aGUgY2FudmFzIChudWxsIGZvciBpbmNvbXBhdGlibGUgZXZlbnRzKVxuICovXG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8507\n")},"8d36":function(module,exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = function(Chart) {\n\tChart.Scatter = function(context, config) {\n\t\tconfig.type = 'scatter';\n\t\treturn new Chart(context, config);\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOGQzNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY2hhcnRzL0NoYXJ0LlNjYXR0ZXIuanM/NGI3ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oQ2hhcnQpIHtcblx0Q2hhcnQuU2NhdHRlciA9IGZ1bmN0aW9uKGNvbnRleHQsIGNvbmZpZykge1xuXHRcdGNvbmZpZy50eXBlID0gJ3NjYXR0ZXInO1xuXHRcdHJldHVybiBuZXcgQ2hhcnQoY29udGV4dCwgY29uZmlnKTtcblx0fTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8d36\n")},"90fd":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\nvar scaleService = __webpack_require__(/*! ../core/core.scaleService */ \"7c56\");\nvar Ticks = __webpack_require__(/*! ../core/core.ticks */ \"1220\");\n\nmodule.exports = function(Chart) {\n\n\tvar globalDefaults = defaults.global;\n\n\tvar defaultConfig = {\n\t\tdisplay: true,\n\n\t\t// Boolean - Whether to animate scaling the chart from the centre\n\t\tanimate: true,\n\t\tposition: 'chartArea',\n\n\t\tangleLines: {\n\t\t\tdisplay: true,\n\t\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\t\tlineWidth: 1\n\t\t},\n\n\t\tgridLines: {\n\t\t\tcircular: false\n\t\t},\n\n\t\t// label settings\n\t\tticks: {\n\t\t\t// Boolean - Show a backdrop to the scale label\n\t\t\tshowLabelBackdrop: true,\n\n\t\t\t// String - The colour of the label backdrop\n\t\t\tbackdropColor: 'rgba(255,255,255,0.75)',\n\n\t\t\t// Number - The backdrop padding above & below the label in pixels\n\t\t\tbackdropPaddingY: 2,\n\n\t\t\t// Number - The backdrop padding to the side of the label in pixels\n\t\t\tbackdropPaddingX: 2,\n\n\t\t\tcallback: Ticks.formatters.linear\n\t\t},\n\n\t\tpointLabels: {\n\t\t\t// Boolean - if true, show point labels\n\t\t\tdisplay: true,\n\n\t\t\t// Number - Point label font size in pixels\n\t\t\tfontSize: 10,\n\n\t\t\t// Function - Used to convert point labels\n\t\t\tcallback: function(label) {\n\t\t\t\treturn label;\n\t\t\t}\n\t\t}\n\t};\n\n\tfunction getValueCount(scale) {\n\t\tvar opts = scale.options;\n\t\treturn opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0;\n\t}\n\n\tfunction getPointLabelFontOptions(scale) {\n\t\tvar pointLabelOptions = scale.options.pointLabels;\n\t\tvar fontSize = helpers.valueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize);\n\t\tvar fontStyle = helpers.valueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle);\n\t\tvar fontFamily = helpers.valueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily);\n\t\tvar font = helpers.fontString(fontSize, fontStyle, fontFamily);\n\n\t\treturn {\n\t\t\tsize: fontSize,\n\t\t\tstyle: fontStyle,\n\t\t\tfamily: fontFamily,\n\t\t\tfont: font\n\t\t};\n\t}\n\n\tfunction measureLabelSize(ctx, fontSize, label) {\n\t\tif (helpers.isArray(label)) {\n\t\t\treturn {\n\t\t\t\tw: helpers.longestText(ctx, ctx.font, label),\n\t\t\t\th: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize)\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tw: ctx.measureText(label).width,\n\t\t\th: fontSize\n\t\t};\n\t}\n\n\tfunction determineLimits(angle, pos, size, min, max) {\n\t\tif (angle === min || angle === max) {\n\t\t\treturn {\n\t\t\t\tstart: pos - (size / 2),\n\t\t\t\tend: pos + (size / 2)\n\t\t\t};\n\t\t} else if (angle < min || angle > max) {\n\t\t\treturn {\n\t\t\t\tstart: pos - size - 5,\n\t\t\t\tend: pos\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstart: pos,\n\t\t\tend: pos + size + 5\n\t\t};\n\t}\n\n\t/**\n\t * Helper function to fit a radial linear scale with point labels\n\t */\n\tfunction fitWithPointLabels(scale) {\n\t\t/*\n\t\t * Right, this is really confusing and there is a lot of maths going on here\n\t\t * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9\n\t\t *\n\t\t * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif\n\t\t *\n\t\t * Solution:\n\t\t *\n\t\t * We assume the radius of the polygon is half the size of the canvas at first\n\t\t * at each index we check if the text overlaps.\n\t\t *\n\t\t * Where it does, we store that angle and that index.\n\t\t *\n\t\t * After finding the largest index and angle we calculate how much we need to remove\n\t\t * from the shape radius to move the point inwards by that x.\n\t\t *\n\t\t * We average the left and right distances to get the maximum shape radius that can fit in the box\n\t\t * along with labels.\n\t\t *\n\t\t * Once we have that, we can find the centre point for the chart, by taking the x text protrusion\n\t\t * on each side, removing that from the size, halving it and adding the left x protrusion width.\n\t\t *\n\t\t * This will mean we have a shape fitted to the canvas, as large as it can be with the labels\n\t\t * and position it in the most space efficient manner\n\t\t *\n\t\t * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif\n\t\t */\n\n\t\tvar plFont = getPointLabelFontOptions(scale);\n\n\t\t// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.\n\t\t// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points\n\t\tvar largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);\n\t\tvar furthestLimits = {\n\t\t\tr: scale.width,\n\t\t\tl: 0,\n\t\t\tt: scale.height,\n\t\t\tb: 0\n\t\t};\n\t\tvar furthestAngles = {};\n\t\tvar i, textSize, pointPosition;\n\n\t\tscale.ctx.font = plFont.font;\n\t\tscale._pointLabelSizes = [];\n\n\t\tvar valueCount = getValueCount(scale);\n\t\tfor (i = 0; i < valueCount; i++) {\n\t\t\tpointPosition = scale.getPointPosition(i, largestPossibleRadius);\n\t\t\ttextSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || '');\n\t\t\tscale._pointLabelSizes[i] = textSize;\n\n\t\t\t// Add quarter circle to make degree 0 mean top of circle\n\t\t\tvar angleRadians = scale.getIndexAngle(i);\n\t\t\tvar angle = helpers.toDegrees(angleRadians) % 360;\n\t\t\tvar hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);\n\t\t\tvar vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);\n\n\t\t\tif (hLimits.start < furthestLimits.l) {\n\t\t\t\tfurthestLimits.l = hLimits.start;\n\t\t\t\tfurthestAngles.l = angleRadians;\n\t\t\t}\n\n\t\t\tif (hLimits.end > furthestLimits.r) {\n\t\t\t\tfurthestLimits.r = hLimits.end;\n\t\t\t\tfurthestAngles.r = angleRadians;\n\t\t\t}\n\n\t\t\tif (vLimits.start < furthestLimits.t) {\n\t\t\t\tfurthestLimits.t = vLimits.start;\n\t\t\t\tfurthestAngles.t = angleRadians;\n\t\t\t}\n\n\t\t\tif (vLimits.end > furthestLimits.b) {\n\t\t\t\tfurthestLimits.b = vLimits.end;\n\t\t\t\tfurthestAngles.b = angleRadians;\n\t\t\t}\n\t\t}\n\n\t\tscale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles);\n\t}\n\n\t/**\n\t * Helper function to fit a radial linear scale with no point labels\n\t */\n\tfunction fit(scale) {\n\t\tvar largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);\n\t\tscale.drawingArea = Math.round(largestPossibleRadius);\n\t\tscale.setCenterPoint(0, 0, 0, 0);\n\t}\n\n\tfunction getTextAlignForAngle(angle) {\n\t\tif (angle === 0 || angle === 180) {\n\t\t\treturn 'center';\n\t\t} else if (angle < 180) {\n\t\t\treturn 'left';\n\t\t}\n\n\t\treturn 'right';\n\t}\n\n\tfunction fillText(ctx, text, position, fontSize) {\n\t\tif (helpers.isArray(text)) {\n\t\t\tvar y = position.y;\n\t\t\tvar spacing = 1.5 * fontSize;\n\n\t\t\tfor (var i = 0; i < text.length; ++i) {\n\t\t\t\tctx.fillText(text[i], position.x, y);\n\t\t\t\ty += spacing;\n\t\t\t}\n\t\t} else {\n\t\t\tctx.fillText(text, position.x, position.y);\n\t\t}\n\t}\n\n\tfunction adjustPointPositionForLabelHeight(angle, textSize, position) {\n\t\tif (angle === 90 || angle === 270) {\n\t\t\tposition.y -= (textSize.h / 2);\n\t\t} else if (angle > 270 || angle < 90) {\n\t\t\tposition.y -= textSize.h;\n\t\t}\n\t}\n\n\tfunction drawPointLabels(scale) {\n\t\tvar ctx = scale.ctx;\n\t\tvar opts = scale.options;\n\t\tvar angleLineOpts = opts.angleLines;\n\t\tvar pointLabelOpts = opts.pointLabels;\n\n\t\tctx.lineWidth = angleLineOpts.lineWidth;\n\t\tctx.strokeStyle = angleLineOpts.color;\n\n\t\tvar outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);\n\n\t\t// Point Label Font\n\t\tvar plFont = getPointLabelFontOptions(scale);\n\n\t\tctx.textBaseline = 'top';\n\n\t\tfor (var i = getValueCount(scale) - 1; i >= 0; i--) {\n\t\t\tif (angleLineOpts.display) {\n\t\t\t\tvar outerPosition = scale.getPointPosition(i, outerDistance);\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.moveTo(scale.xCenter, scale.yCenter);\n\t\t\t\tctx.lineTo(outerPosition.x, outerPosition.y);\n\t\t\t\tctx.stroke();\n\t\t\t\tctx.closePath();\n\t\t\t}\n\n\t\t\tif (pointLabelOpts.display) {\n\t\t\t\t// Extra 3px out for some label spacing\n\t\t\t\tvar pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);\n\n\t\t\t\t// Keep this in loop since we may support array properties here\n\t\t\t\tvar pointLabelFontColor = helpers.valueAtIndexOrDefault(pointLabelOpts.fontColor, i, globalDefaults.defaultFontColor);\n\t\t\t\tctx.font = plFont.font;\n\t\t\t\tctx.fillStyle = pointLabelFontColor;\n\n\t\t\t\tvar angleRadians = scale.getIndexAngle(i);\n\t\t\t\tvar angle = helpers.toDegrees(angleRadians);\n\t\t\t\tctx.textAlign = getTextAlignForAngle(angle);\n\t\t\t\tadjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);\n\t\t\t\tfillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size);\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction drawRadiusLine(scale, gridLineOpts, radius, index) {\n\t\tvar ctx = scale.ctx;\n\t\tctx.strokeStyle = helpers.valueAtIndexOrDefault(gridLineOpts.color, index - 1);\n\t\tctx.lineWidth = helpers.valueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);\n\n\t\tif (scale.options.gridLines.circular) {\n\t\t\t// Draw circular arcs between the points\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2);\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t} else {\n\t\t\t// Draw straight lines connecting each index\n\t\t\tvar valueCount = getValueCount(scale);\n\n\t\t\tif (valueCount === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tctx.beginPath();\n\t\t\tvar pointPosition = scale.getPointPosition(0, radius);\n\t\t\tctx.moveTo(pointPosition.x, pointPosition.y);\n\n\t\t\tfor (var i = 1; i < valueCount; i++) {\n\t\t\t\tpointPosition = scale.getPointPosition(i, radius);\n\t\t\t\tctx.lineTo(pointPosition.x, pointPosition.y);\n\t\t\t}\n\n\t\t\tctx.closePath();\n\t\t\tctx.stroke();\n\t\t}\n\t}\n\n\tfunction numberOrZero(param) {\n\t\treturn helpers.isNumber(param) ? param : 0;\n\t}\n\n\tvar LinearRadialScale = Chart.LinearScaleBase.extend({\n\t\tsetDimensions: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\t// Set the unconstrained dimension before label rotation\n\t\t\tme.width = me.maxWidth;\n\t\t\tme.height = me.maxHeight;\n\t\t\tme.xCenter = Math.round(me.width / 2);\n\t\t\tme.yCenter = Math.round(me.height / 2);\n\n\t\t\tvar minSize = helpers.min([me.height, me.width]);\n\t\t\tvar tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\tme.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);\n\t\t},\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar min = Number.POSITIVE_INFINITY;\n\t\t\tvar max = Number.NEGATIVE_INFINITY;\n\n\t\t\thelpers.each(chart.data.datasets, function(dataset, datasetIndex) {\n\t\t\t\tif (chart.isDatasetVisible(datasetIndex)) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\n\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmin = Math.min(value, min);\n\t\t\t\t\t\tmax = Math.max(value, max);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tme.min = (min === Number.POSITIVE_INFINITY ? 0 : min);\n\t\t\tme.max = (max === Number.NEGATIVE_INFINITY ? 0 : max);\n\n\t\t\t// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\n\t\t\tme.handleTickRangeOptions();\n\t\t},\n\t\tgetTickLimit: function() {\n\t\t\tvar tickOpts = this.options.ticks;\n\t\t\tvar tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\treturn Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tvar me = this;\n\n\t\t\tChart.LinearScaleBase.prototype.convertTicksToLabels.call(me);\n\n\t\t\t// Point labels\n\t\t\tme.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);\n\t\t},\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\tfit: function() {\n\t\t\tif (this.options.pointLabels.display) {\n\t\t\t\tfitWithPointLabels(this);\n\t\t\t} else {\n\t\t\t\tfit(this);\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * Set radius reductions and determine new radius and center point\n\t\t * @private\n\t\t */\n\t\tsetReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) {\n\t\t\tvar me = this;\n\t\t\tvar radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);\n\t\t\tvar radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r);\n\t\t\tvar radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);\n\t\t\tvar radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b);\n\n\t\t\tradiusReductionLeft = numberOrZero(radiusReductionLeft);\n\t\t\tradiusReductionRight = numberOrZero(radiusReductionRight);\n\t\t\tradiusReductionTop = numberOrZero(radiusReductionTop);\n\t\t\tradiusReductionBottom = numberOrZero(radiusReductionBottom);\n\n\t\t\tme.drawingArea = Math.min(\n\t\t\t\tMath.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2),\n\t\t\t\tMath.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2));\n\t\t\tme.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);\n\t\t},\n\t\tsetCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) {\n\t\t\tvar me = this;\n\t\t\tvar maxRight = me.width - rightMovement - me.drawingArea;\n\t\t\tvar maxLeft = leftMovement + me.drawingArea;\n\t\t\tvar maxTop = topMovement + me.drawingArea;\n\t\t\tvar maxBottom = me.height - bottomMovement - me.drawingArea;\n\n\t\t\tme.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);\n\t\t\tme.yCenter = Math.round(((maxTop + maxBottom) / 2) + me.top);\n\t\t},\n\n\t\tgetIndexAngle: function(index) {\n\t\t\tvar angleMultiplier = (Math.PI * 2) / getValueCount(this);\n\t\t\tvar startAngle = this.chart.options && this.chart.options.startAngle ?\n\t\t\t\tthis.chart.options.startAngle :\n\t\t\t\t0;\n\n\t\t\tvar startAngleRadians = startAngle * Math.PI * 2 / 360;\n\n\t\t\t// Start from the top instead of right, so remove a quarter of the circle\n\t\t\treturn index * angleMultiplier + startAngleRadians;\n\t\t},\n\t\tgetDistanceFromCenterForValue: function(value) {\n\t\t\tvar me = this;\n\n\t\t\tif (value === null) {\n\t\t\t\treturn 0; // null always in center\n\t\t\t}\n\n\t\t\t// Take into account half font size + the yPadding of the top value\n\t\t\tvar scalingFactor = me.drawingArea / (me.max - me.min);\n\t\t\tif (me.options.ticks.reverse) {\n\t\t\t\treturn (me.max - value) * scalingFactor;\n\t\t\t}\n\t\t\treturn (value - me.min) * scalingFactor;\n\t\t},\n\t\tgetPointPosition: function(index, distanceFromCenter) {\n\t\t\tvar me = this;\n\t\t\tvar thisAngle = me.getIndexAngle(index) - (Math.PI / 2);\n\t\t\treturn {\n\t\t\t\tx: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,\n\t\t\t\ty: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter\n\t\t\t};\n\t\t},\n\t\tgetPointPositionForValue: function(index, value) {\n\t\t\treturn this.getPointPosition(index, this.getDistanceFromCenterForValue(value));\n\t\t},\n\n\t\tgetBasePosition: function() {\n\t\t\tvar me = this;\n\t\t\tvar min = me.min;\n\t\t\tvar max = me.max;\n\n\t\t\treturn me.getPointPositionForValue(0,\n\t\t\t\tme.beginAtZero ? 0 :\n\t\t\t\tmin < 0 && max < 0 ? max :\n\t\t\t\tmin > 0 && max > 0 ? min :\n\t\t\t\t0);\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar gridLineOpts = opts.gridLines;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar valueOrDefault = helpers.valueOrDefault;\n\n\t\t\tif (opts.display) {\n\t\t\t\tvar ctx = me.ctx;\n\t\t\t\tvar startAngle = this.getIndexAngle(0);\n\n\t\t\t\t// Tick Font\n\t\t\t\tvar tickFontSize = valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);\n\t\t\t\tvar tickFontStyle = valueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);\n\t\t\t\tvar tickFontFamily = valueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);\n\t\t\t\tvar tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);\n\n\t\t\t\thelpers.each(me.ticks, function(label, index) {\n\t\t\t\t\t// Don't draw a centre value (if it is minimum)\n\t\t\t\t\tif (index > 0 || tickOpts.reverse) {\n\t\t\t\t\t\tvar yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);\n\n\t\t\t\t\t\t// Draw circular lines around the scale\n\t\t\t\t\t\tif (gridLineOpts.display && index !== 0) {\n\t\t\t\t\t\t\tdrawRadiusLine(me, gridLineOpts, yCenterOffset, index);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (tickOpts.display) {\n\t\t\t\t\t\t\tvar tickFontColor = valueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);\n\t\t\t\t\t\t\tctx.font = tickLabelFont;\n\n\t\t\t\t\t\t\tctx.save();\n\t\t\t\t\t\t\tctx.translate(me.xCenter, me.yCenter);\n\t\t\t\t\t\t\tctx.rotate(startAngle);\n\n\t\t\t\t\t\t\tif (tickOpts.showLabelBackdrop) {\n\t\t\t\t\t\t\t\tvar labelWidth = ctx.measureText(label).width;\n\t\t\t\t\t\t\t\tctx.fillStyle = tickOpts.backdropColor;\n\t\t\t\t\t\t\t\tctx.fillRect(\n\t\t\t\t\t\t\t\t\t-labelWidth / 2 - tickOpts.backdropPaddingX,\n\t\t\t\t\t\t\t\t\t-yCenterOffset - tickFontSize / 2 - tickOpts.backdropPaddingY,\n\t\t\t\t\t\t\t\t\tlabelWidth + tickOpts.backdropPaddingX * 2,\n\t\t\t\t\t\t\t\t\ttickFontSize + tickOpts.backdropPaddingY * 2\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\t\t\t\tctx.fillStyle = tickFontColor;\n\t\t\t\t\t\t\tctx.fillText(label, 0, -yCenterOffset);\n\t\t\t\t\t\t\tctx.restore();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (opts.angleLines.display || opts.pointLabels.display) {\n\t\t\t\t\tdrawPointLabels(me);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\tscaleService.registerScaleType('radialLinear', LinearRadialScale, defaultConfig);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTBmZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvc2NhbGVzL3NjYWxlLnJhZGlhbExpbmVhci5qcz9mM2ZmIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmF1bHRzID0gcmVxdWlyZSgnLi4vY29yZS9jb3JlLmRlZmF1bHRzJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcbnZhciBzY2FsZVNlcnZpY2UgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuc2NhbGVTZXJ2aWNlJyk7XG52YXIgVGlja3MgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUudGlja3MnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDaGFydCkge1xuXG5cdHZhciBnbG9iYWxEZWZhdWx0cyA9IGRlZmF1bHRzLmdsb2JhbDtcblxuXHR2YXIgZGVmYXVsdENvbmZpZyA9IHtcblx0XHRkaXNwbGF5OiB0cnVlLFxuXG5cdFx0Ly8gQm9vbGVhbiAtIFdoZXRoZXIgdG8gYW5pbWF0ZSBzY2FsaW5nIHRoZSBjaGFydCBmcm9tIHRoZSBjZW50cmVcblx0XHRhbmltYXRlOiB0cnVlLFxuXHRcdHBvc2l0aW9uOiAnY2hhcnRBcmVhJyxcblxuXHRcdGFuZ2xlTGluZXM6IHtcblx0XHRcdGRpc3BsYXk6IHRydWUsXG5cdFx0XHRjb2xvcjogJ3JnYmEoMCwgMCwgMCwgMC4xKScsXG5cdFx0XHRsaW5lV2lkdGg6IDFcblx0XHR9LFxuXG5cdFx0Z3JpZExpbmVzOiB7XG5cdFx0XHRjaXJjdWxhcjogZmFsc2Vcblx0XHR9LFxuXG5cdFx0Ly8gbGFiZWwgc2V0dGluZ3Ncblx0XHR0aWNrczoge1xuXHRcdFx0Ly8gQm9vbGVhbiAtIFNob3cgYSBiYWNrZHJvcCB0byB0aGUgc2NhbGUgbGFiZWxcblx0XHRcdHNob3dMYWJlbEJhY2tkcm9wOiB0cnVlLFxuXG5cdFx0XHQvLyBTdHJpbmcgLSBUaGUgY29sb3VyIG9mIHRoZSBsYWJlbCBiYWNrZHJvcFxuXHRcdFx0YmFja2Ryb3BDb2xvcjogJ3JnYmEoMjU1LDI1NSwyNTUsMC43NSknLFxuXG5cdFx0XHQvLyBOdW1iZXIgLSBUaGUgYmFja2Ryb3AgcGFkZGluZyBhYm92ZSAmIGJlbG93IHRoZSBsYWJlbCBpbiBwaXhlbHNcblx0XHRcdGJhY2tkcm9wUGFkZGluZ1k6IDIsXG5cblx0XHRcdC8vIE51bWJlciAtIFRoZSBiYWNrZHJvcCBwYWRkaW5nIHRvIHRoZSBzaWRlIG9mIHRoZSBsYWJlbCBpbiBwaXhlbHNcblx0XHRcdGJhY2tkcm9wUGFkZGluZ1g6IDIsXG5cblx0XHRcdGNhbGxiYWNrOiBUaWNrcy5mb3JtYXR0ZXJzLmxpbmVhclxuXHRcdH0sXG5cblx0XHRwb2ludExhYmVsczoge1xuXHRcdFx0Ly8gQm9vbGVhbiAtIGlmIHRydWUsIHNob3cgcG9pbnQgbGFiZWxzXG5cdFx0XHRkaXNwbGF5OiB0cnVlLFxuXG5cdFx0XHQvLyBOdW1iZXIgLSBQb2ludCBsYWJlbCBmb250IHNpemUgaW4gcGl4ZWxzXG5cdFx0XHRmb250U2l6ZTogMTAsXG5cblx0XHRcdC8vIEZ1bmN0aW9uIC0gVXNlZCB0byBjb252ZXJ0IHBvaW50IGxhYmVsc1xuXHRcdFx0Y2FsbGJhY2s6IGZ1bmN0aW9uKGxhYmVsKSB7XG5cdFx0XHRcdHJldHVybiBsYWJlbDtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cblx0ZnVuY3Rpb24gZ2V0VmFsdWVDb3VudChzY2FsZSkge1xuXHRcdHZhciBvcHRzID0gc2NhbGUub3B0aW9ucztcblx0XHRyZXR1cm4gb3B0cy5hbmdsZUxpbmVzLmRpc3BsYXkgfHwgb3B0cy5wb2ludExhYmVscy5kaXNwbGF5ID8gc2NhbGUuY2hhcnQuZGF0YS5sYWJlbHMubGVuZ3RoIDogMDtcblx0fVxuXG5cdGZ1bmN0aW9uIGdldFBvaW50TGFiZWxGb250T3B0aW9ucyhzY2FsZSkge1xuXHRcdHZhciBwb2ludExhYmVsT3B0aW9ucyA9IHNjYWxlLm9wdGlvbnMucG9pbnRMYWJlbHM7XG5cdFx0dmFyIGZvbnRTaXplID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdChwb2ludExhYmVsT3B0aW9ucy5mb250U2l6ZSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRTaXplKTtcblx0XHR2YXIgZm9udFN0eWxlID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdChwb2ludExhYmVsT3B0aW9ucy5mb250U3R5bGUsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250U3R5bGUpO1xuXHRcdHZhciBmb250RmFtaWx5ID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdChwb2ludExhYmVsT3B0aW9ucy5mb250RmFtaWx5LCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udEZhbWlseSk7XG5cdFx0dmFyIGZvbnQgPSBoZWxwZXJzLmZvbnRTdHJpbmcoZm9udFNpemUsIGZvbnRTdHlsZSwgZm9udEZhbWlseSk7XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0c2l6ZTogZm9udFNpemUsXG5cdFx0XHRzdHlsZTogZm9udFN0eWxlLFxuXHRcdFx0ZmFtaWx5OiBmb250RmFtaWx5LFxuXHRcdFx0Zm9udDogZm9udFxuXHRcdH07XG5cdH1cblxuXHRmdW5jdGlvbiBtZWFzdXJlTGFiZWxTaXplKGN0eCwgZm9udFNpemUsIGxhYmVsKSB7XG5cdFx0aWYgKGhlbHBlcnMuaXNBcnJheShsYWJlbCkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdHc6IGhlbHBlcnMubG9uZ2VzdFRleHQoY3R4LCBjdHguZm9udCwgbGFiZWwpLFxuXHRcdFx0XHRoOiAobGFiZWwubGVuZ3RoICogZm9udFNpemUpICsgKChsYWJlbC5sZW5ndGggLSAxKSAqIDEuNSAqIGZvbnRTaXplKVxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0dzogY3R4Lm1lYXN1cmVUZXh0KGxhYmVsKS53aWR0aCxcblx0XHRcdGg6IGZvbnRTaXplXG5cdFx0fTtcblx0fVxuXG5cdGZ1bmN0aW9uIGRldGVybWluZUxpbWl0cyhhbmdsZSwgcG9zLCBzaXplLCBtaW4sIG1heCkge1xuXHRcdGlmIChhbmdsZSA9PT0gbWluIHx8IGFuZ2xlID09PSBtYXgpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdHN0YXJ0OiBwb3MgLSAoc2l6ZSAvIDIpLFxuXHRcdFx0XHRlbmQ6IHBvcyArIChzaXplIC8gMilcblx0XHRcdH07XG5cdFx0fSBlbHNlIGlmIChhbmdsZSA8IG1pbiB8fCBhbmdsZSA+IG1heCkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0c3RhcnQ6IHBvcyAtIHNpemUgLSA1LFxuXHRcdFx0XHRlbmQ6IHBvc1xuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0c3RhcnQ6IHBvcyxcblx0XHRcdGVuZDogcG9zICsgc2l6ZSArIDVcblx0XHR9O1xuXHR9XG5cblx0LyoqXG5cdCAqIEhlbHBlciBmdW5jdGlvbiB0byBmaXQgYSByYWRpYWwgbGluZWFyIHNjYWxlIHdpdGggcG9pbnQgbGFiZWxzXG5cdCAqL1xuXHRmdW5jdGlvbiBmaXRXaXRoUG9pbnRMYWJlbHMoc2NhbGUpIHtcblx0XHQvKlxuXHRcdCAqIFJpZ2h0LCB0aGlzIGlzIHJlYWxseSBjb25mdXNpbmcgYW5kIHRoZXJlIGlzIGEgbG90IG9mIG1hdGhzIGdvaW5nIG9uIGhlcmVcblx0XHQgKiBUaGUgZ2lzdCBvZiB0aGUgcHJvYmxlbSBpcyBoZXJlOiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9ubm5pY2svNjk2Y2M5YzU1ZjRiMGJlYjhmZTlcblx0XHQgKlxuXHRcdCAqIFJlYWN0aW9uOiBodHRwczovL2RsLmRyb3Bib3h1c2VyY29udGVudC5jb20vdS8zNDYwMTM2My90b29tdWNoc2NpZW5jZS5naWZcblx0XHQgKlxuXHRcdCAqIFNvbHV0aW9uOlxuXHRcdCAqXG5cdFx0ICogV2UgYXNzdW1lIHRoZSByYWRpdXMgb2YgdGhlIHBvbHlnb24gaXMgaGFsZiB0aGUgc2l6ZSBvZiB0aGUgY2FudmFzIGF0IGZpcnN0XG5cdFx0ICogYXQgZWFjaCBpbmRleCB3ZSBjaGVjayBpZiB0aGUgdGV4dCBvdmVybGFwcy5cblx0XHQgKlxuXHRcdCAqIFdoZXJlIGl0IGRvZXMsIHdlIHN0b3JlIHRoYXQgYW5nbGUgYW5kIHRoYXQgaW5kZXguXG5cdFx0ICpcblx0XHQgKiBBZnRlciBmaW5kaW5nIHRoZSBsYXJnZXN0IGluZGV4IGFuZCBhbmdsZSB3ZSBjYWxjdWxhdGUgaG93IG11Y2ggd2UgbmVlZCB0byByZW1vdmVcblx0XHQgKiBmcm9tIHRoZSBzaGFwZSByYWRpdXMgdG8gbW92ZSB0aGUgcG9pbnQgaW53YXJkcyBieSB0aGF0IHguXG5cdFx0ICpcblx0XHQgKiBXZSBhdmVyYWdlIHRoZSBsZWZ0IGFuZCByaWdodCBkaXN0YW5jZXMgdG8gZ2V0IHRoZSBtYXhpbXVtIHNoYXBlIHJhZGl1cyB0aGF0IGNhbiBmaXQgaW4gdGhlIGJveFxuXHRcdCAqIGFsb25nIHdpdGggbGFiZWxzLlxuXHRcdCAqXG5cdFx0ICogT25jZSB3ZSBoYXZlIHRoYXQsIHdlIGNhbiBmaW5kIHRoZSBjZW50cmUgcG9pbnQgZm9yIHRoZSBjaGFydCwgYnkgdGFraW5nIHRoZSB4IHRleHQgcHJvdHJ1c2lvblxuXHRcdCAqIG9uIGVhY2ggc2lkZSwgcmVtb3ZpbmcgdGhhdCBmcm9tIHRoZSBzaXplLCBoYWx2aW5nIGl0IGFuZCBhZGRpbmcgdGhlIGxlZnQgeCBwcm90cnVzaW9uIHdpZHRoLlxuXHRcdCAqXG5cdFx0ICogVGhpcyB3aWxsIG1lYW4gd2UgaGF2ZSBhIHNoYXBlIGZpdHRlZCB0byB0aGUgY2FudmFzLCBhcyBsYXJnZSBhcyBpdCBjYW4gYmUgd2l0aCB0aGUgbGFiZWxzXG5cdFx0ICogYW5kIHBvc2l0aW9uIGl0IGluIHRoZSBtb3N0IHNwYWNlIGVmZmljaWVudCBtYW5uZXJcblx0XHQgKlxuXHRcdCAqIGh0dHBzOi8vZGwuZHJvcGJveHVzZXJjb250ZW50LmNvbS91LzM0NjAxMzYzL3llYWhzY2llbmNlLmdpZlxuXHRcdCAqL1xuXG5cdFx0dmFyIHBsRm9udCA9IGdldFBvaW50TGFiZWxGb250T3B0aW9ucyhzY2FsZSk7XG5cblx0XHQvLyBHZXQgbWF4aW11bSByYWRpdXMgb2YgdGhlIHBvbHlnb24uIEVpdGhlciBoYWxmIHRoZSBoZWlnaHQgKG1pbnVzIHRoZSB0ZXh0IHdpZHRoKSBvciBoYWxmIHRoZSB3aWR0aC5cblx0XHQvLyBVc2UgdGhpcyB0byBjYWxjdWxhdGUgdGhlIG9mZnNldCArIGNoYW5nZS4gLSBNYWtlIHN1cmUgTC9SIHByb3RydXNpb24gaXMgYXQgbGVhc3QgMCB0byBzdG9wIGlzc3VlcyB3aXRoIGNlbnRyZSBwb2ludHNcblx0XHR2YXIgbGFyZ2VzdFBvc3NpYmxlUmFkaXVzID0gTWF0aC5taW4oc2NhbGUuaGVpZ2h0IC8gMiwgc2NhbGUud2lkdGggLyAyKTtcblx0XHR2YXIgZnVydGhlc3RMaW1pdHMgPSB7XG5cdFx0XHRyOiBzY2FsZS53aWR0aCxcblx0XHRcdGw6IDAsXG5cdFx0XHR0OiBzY2FsZS5oZWlnaHQsXG5cdFx0XHRiOiAwXG5cdFx0fTtcblx0XHR2YXIgZnVydGhlc3RBbmdsZXMgPSB7fTtcblx0XHR2YXIgaSwgdGV4dFNpemUsIHBvaW50UG9zaXRpb247XG5cblx0XHRzY2FsZS5jdHguZm9udCA9IHBsRm9udC5mb250O1xuXHRcdHNjYWxlLl9wb2ludExhYmVsU2l6ZXMgPSBbXTtcblxuXHRcdHZhciB2YWx1ZUNvdW50ID0gZ2V0VmFsdWVDb3VudChzY2FsZSk7XG5cdFx0Zm9yIChpID0gMDsgaSA8IHZhbHVlQ291bnQ7IGkrKykge1xuXHRcdFx0cG9pbnRQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb24oaSwgbGFyZ2VzdFBvc3NpYmxlUmFkaXVzKTtcblx0XHRcdHRleHRTaXplID0gbWVhc3VyZUxhYmVsU2l6ZShzY2FsZS5jdHgsIHBsRm9udC5zaXplLCBzY2FsZS5wb2ludExhYmVsc1tpXSB8fCAnJyk7XG5cdFx0XHRzY2FsZS5fcG9pbnRMYWJlbFNpemVzW2ldID0gdGV4dFNpemU7XG5cblx0XHRcdC8vIEFkZCBxdWFydGVyIGNpcmNsZSB0byBtYWtlIGRlZ3JlZSAwIG1lYW4gdG9wIG9mIGNpcmNsZVxuXHRcdFx0dmFyIGFuZ2xlUmFkaWFucyA9IHNjYWxlLmdldEluZGV4QW5nbGUoaSk7XG5cdFx0XHR2YXIgYW5nbGUgPSBoZWxwZXJzLnRvRGVncmVlcyhhbmdsZVJhZGlhbnMpICUgMzYwO1xuXHRcdFx0dmFyIGhMaW1pdHMgPSBkZXRlcm1pbmVMaW1pdHMoYW5nbGUsIHBvaW50UG9zaXRpb24ueCwgdGV4dFNpemUudywgMCwgMTgwKTtcblx0XHRcdHZhciB2TGltaXRzID0gZGV0ZXJtaW5lTGltaXRzKGFuZ2xlLCBwb2ludFBvc2l0aW9uLnksIHRleHRTaXplLmgsIDkwLCAyNzApO1xuXG5cdFx0XHRpZiAoaExpbWl0cy5zdGFydCA8IGZ1cnRoZXN0TGltaXRzLmwpIHtcblx0XHRcdFx0ZnVydGhlc3RMaW1pdHMubCA9IGhMaW1pdHMuc3RhcnQ7XG5cdFx0XHRcdGZ1cnRoZXN0QW5nbGVzLmwgPSBhbmdsZVJhZGlhbnM7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChoTGltaXRzLmVuZCA+IGZ1cnRoZXN0TGltaXRzLnIpIHtcblx0XHRcdFx0ZnVydGhlc3RMaW1pdHMuciA9IGhMaW1pdHMuZW5kO1xuXHRcdFx0XHRmdXJ0aGVzdEFuZ2xlcy5yID0gYW5nbGVSYWRpYW5zO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodkxpbWl0cy5zdGFydCA8IGZ1cnRoZXN0TGltaXRzLnQpIHtcblx0XHRcdFx0ZnVydGhlc3RMaW1pdHMudCA9IHZMaW1pdHMuc3RhcnQ7XG5cdFx0XHRcdGZ1cnRoZXN0QW5nbGVzLnQgPSBhbmdsZVJhZGlhbnM7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh2TGltaXRzLmVuZCA+IGZ1cnRoZXN0TGltaXRzLmIpIHtcblx0XHRcdFx0ZnVydGhlc3RMaW1pdHMuYiA9IHZMaW1pdHMuZW5kO1xuXHRcdFx0XHRmdXJ0aGVzdEFuZ2xlcy5iID0gYW5nbGVSYWRpYW5zO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHNjYWxlLnNldFJlZHVjdGlvbnMobGFyZ2VzdFBvc3NpYmxlUmFkaXVzLCBmdXJ0aGVzdExpbWl0cywgZnVydGhlc3RBbmdsZXMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEhlbHBlciBmdW5jdGlvbiB0byBmaXQgYSByYWRpYWwgbGluZWFyIHNjYWxlIHdpdGggbm8gcG9pbnQgbGFiZWxzXG5cdCAqL1xuXHRmdW5jdGlvbiBmaXQoc2NhbGUpIHtcblx0XHR2YXIgbGFyZ2VzdFBvc3NpYmxlUmFkaXVzID0gTWF0aC5taW4oc2NhbGUuaGVpZ2h0IC8gMiwgc2NhbGUud2lkdGggLyAyKTtcblx0XHRzY2FsZS5kcmF3aW5nQXJlYSA9IE1hdGgucm91bmQobGFyZ2VzdFBvc3NpYmxlUmFkaXVzKTtcblx0XHRzY2FsZS5zZXRDZW50ZXJQb2ludCgwLCAwLCAwLCAwKTtcblx0fVxuXG5cdGZ1bmN0aW9uIGdldFRleHRBbGlnbkZvckFuZ2xlKGFuZ2xlKSB7XG5cdFx0aWYgKGFuZ2xlID09PSAwIHx8IGFuZ2xlID09PSAxODApIHtcblx0XHRcdHJldHVybiAnY2VudGVyJztcblx0XHR9IGVsc2UgaWYgKGFuZ2xlIDwgMTgwKSB7XG5cdFx0XHRyZXR1cm4gJ2xlZnQnO1xuXHRcdH1cblxuXHRcdHJldHVybiAncmlnaHQnO1xuXHR9XG5cblx0ZnVuY3Rpb24gZmlsbFRleHQoY3R4LCB0ZXh0LCBwb3NpdGlvbiwgZm9udFNpemUpIHtcblx0XHRpZiAoaGVscGVycy5pc0FycmF5KHRleHQpKSB7XG5cdFx0XHR2YXIgeSA9IHBvc2l0aW9uLnk7XG5cdFx0XHR2YXIgc3BhY2luZyA9IDEuNSAqIGZvbnRTaXplO1xuXG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHRleHQubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0Y3R4LmZpbGxUZXh0KHRleHRbaV0sIHBvc2l0aW9uLngsIHkpO1xuXHRcdFx0XHR5ICs9IHNwYWNpbmc7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGN0eC5maWxsVGV4dCh0ZXh0LCBwb3NpdGlvbi54LCBwb3NpdGlvbi55KTtcblx0XHR9XG5cdH1cblxuXHRmdW5jdGlvbiBhZGp1c3RQb2ludFBvc2l0aW9uRm9yTGFiZWxIZWlnaHQoYW5nbGUsIHRleHRTaXplLCBwb3NpdGlvbikge1xuXHRcdGlmIChhbmdsZSA9PT0gOTAgfHwgYW5nbGUgPT09IDI3MCkge1xuXHRcdFx0cG9zaXRpb24ueSAtPSAodGV4dFNpemUuaCAvIDIpO1xuXHRcdH0gZWxzZSBpZiAoYW5nbGUgPiAyNzAgfHwgYW5nbGUgPCA5MCkge1xuXHRcdFx0cG9zaXRpb24ueSAtPSB0ZXh0U2l6ZS5oO1xuXHRcdH1cblx0fVxuXG5cdGZ1bmN0aW9uIGRyYXdQb2ludExhYmVscyhzY2FsZSkge1xuXHRcdHZhciBjdHggPSBzY2FsZS5jdHg7XG5cdFx0dmFyIG9wdHMgPSBzY2FsZS5vcHRpb25zO1xuXHRcdHZhciBhbmdsZUxpbmVPcHRzID0gb3B0cy5hbmdsZUxpbmVzO1xuXHRcdHZhciBwb2ludExhYmVsT3B0cyA9IG9wdHMucG9pbnRMYWJlbHM7XG5cblx0XHRjdHgubGluZVdpZHRoID0gYW5nbGVMaW5lT3B0cy5saW5lV2lkdGg7XG5cdFx0Y3R4LnN0cm9rZVN0eWxlID0gYW5nbGVMaW5lT3B0cy5jb2xvcjtcblxuXHRcdHZhciBvdXRlckRpc3RhbmNlID0gc2NhbGUuZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUob3B0cy50aWNrcy5yZXZlcnNlID8gc2NhbGUubWluIDogc2NhbGUubWF4KTtcblxuXHRcdC8vIFBvaW50IExhYmVsIEZvbnRcblx0XHR2YXIgcGxGb250ID0gZ2V0UG9pbnRMYWJlbEZvbnRPcHRpb25zKHNjYWxlKTtcblxuXHRcdGN0eC50ZXh0QmFzZWxpbmUgPSAndG9wJztcblxuXHRcdGZvciAodmFyIGkgPSBnZXRWYWx1ZUNvdW50KHNjYWxlKSAtIDE7IGkgPj0gMDsgaS0tKSB7XG5cdFx0XHRpZiAoYW5nbGVMaW5lT3B0cy5kaXNwbGF5KSB7XG5cdFx0XHRcdHZhciBvdXRlclBvc2l0aW9uID0gc2NhbGUuZ2V0UG9pbnRQb3NpdGlvbihpLCBvdXRlckRpc3RhbmNlKTtcblx0XHRcdFx0Y3R4LmJlZ2luUGF0aCgpO1xuXHRcdFx0XHRjdHgubW92ZVRvKHNjYWxlLnhDZW50ZXIsIHNjYWxlLnlDZW50ZXIpO1xuXHRcdFx0XHRjdHgubGluZVRvKG91dGVyUG9zaXRpb24ueCwgb3V0ZXJQb3NpdGlvbi55KTtcblx0XHRcdFx0Y3R4LnN0cm9rZSgpO1xuXHRcdFx0XHRjdHguY2xvc2VQYXRoKCk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChwb2ludExhYmVsT3B0cy5kaXNwbGF5KSB7XG5cdFx0XHRcdC8vIEV4dHJhIDNweCBvdXQgZm9yIHNvbWUgbGFiZWwgc3BhY2luZ1xuXHRcdFx0XHR2YXIgcG9pbnRMYWJlbFBvc2l0aW9uID0gc2NhbGUuZ2V0UG9pbnRQb3NpdGlvbihpLCBvdXRlckRpc3RhbmNlICsgNSk7XG5cblx0XHRcdFx0Ly8gS2VlcCB0aGlzIGluIGxvb3Agc2luY2Ugd2UgbWF5IHN1cHBvcnQgYXJyYXkgcHJvcGVydGllcyBoZXJlXG5cdFx0XHRcdHZhciBwb2ludExhYmVsRm9udENvbG9yID0gaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQocG9pbnRMYWJlbE9wdHMuZm9udENvbG9yLCBpLCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udENvbG9yKTtcblx0XHRcdFx0Y3R4LmZvbnQgPSBwbEZvbnQuZm9udDtcblx0XHRcdFx0Y3R4LmZpbGxTdHlsZSA9IHBvaW50TGFiZWxGb250Q29sb3I7XG5cblx0XHRcdFx0dmFyIGFuZ2xlUmFkaWFucyA9IHNjYWxlLmdldEluZGV4QW5nbGUoaSk7XG5cdFx0XHRcdHZhciBhbmdsZSA9IGhlbHBlcnMudG9EZWdyZWVzKGFuZ2xlUmFkaWFucyk7XG5cdFx0XHRcdGN0eC50ZXh0QWxpZ24gPSBnZXRUZXh0QWxpZ25Gb3JBbmdsZShhbmdsZSk7XG5cdFx0XHRcdGFkanVzdFBvaW50UG9zaXRpb25Gb3JMYWJlbEhlaWdodChhbmdsZSwgc2NhbGUuX3BvaW50TGFiZWxTaXplc1tpXSwgcG9pbnRMYWJlbFBvc2l0aW9uKTtcblx0XHRcdFx0ZmlsbFRleHQoY3R4LCBzY2FsZS5wb2ludExhYmVsc1tpXSB8fCAnJywgcG9pbnRMYWJlbFBvc2l0aW9uLCBwbEZvbnQuc2l6ZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0ZnVuY3Rpb24gZHJhd1JhZGl1c0xpbmUoc2NhbGUsIGdyaWRMaW5lT3B0cywgcmFkaXVzLCBpbmRleCkge1xuXHRcdHZhciBjdHggPSBzY2FsZS5jdHg7XG5cdFx0Y3R4LnN0cm9rZVN0eWxlID0gaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZ3JpZExpbmVPcHRzLmNvbG9yLCBpbmRleCAtIDEpO1xuXHRcdGN0eC5saW5lV2lkdGggPSBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdChncmlkTGluZU9wdHMubGluZVdpZHRoLCBpbmRleCAtIDEpO1xuXG5cdFx0aWYgKHNjYWxlLm9wdGlvbnMuZ3JpZExpbmVzLmNpcmN1bGFyKSB7XG5cdFx0XHQvLyBEcmF3IGNpcmN1bGFyIGFyY3MgYmV0d2VlbiB0aGUgcG9pbnRzXG5cdFx0XHRjdHguYmVnaW5QYXRoKCk7XG5cdFx0XHRjdHguYXJjKHNjYWxlLnhDZW50ZXIsIHNjYWxlLnlDZW50ZXIsIHJhZGl1cywgMCwgTWF0aC5QSSAqIDIpO1xuXHRcdFx0Y3R4LmNsb3NlUGF0aCgpO1xuXHRcdFx0Y3R4LnN0cm9rZSgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBEcmF3IHN0cmFpZ2h0IGxpbmVzIGNvbm5lY3RpbmcgZWFjaCBpbmRleFxuXHRcdFx0dmFyIHZhbHVlQ291bnQgPSBnZXRWYWx1ZUNvdW50KHNjYWxlKTtcblxuXHRcdFx0aWYgKHZhbHVlQ291bnQgPT09IDApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRjdHguYmVnaW5QYXRoKCk7XG5cdFx0XHR2YXIgcG9pbnRQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb24oMCwgcmFkaXVzKTtcblx0XHRcdGN0eC5tb3ZlVG8ocG9pbnRQb3NpdGlvbi54LCBwb2ludFBvc2l0aW9uLnkpO1xuXG5cdFx0XHRmb3IgKHZhciBpID0gMTsgaSA8IHZhbHVlQ291bnQ7IGkrKykge1xuXHRcdFx0XHRwb2ludFBvc2l0aW9uID0gc2NhbGUuZ2V0UG9pbnRQb3NpdGlvbihpLCByYWRpdXMpO1xuXHRcdFx0XHRjdHgubGluZVRvKHBvaW50UG9zaXRpb24ueCwgcG9pbnRQb3NpdGlvbi55KTtcblx0XHRcdH1cblxuXHRcdFx0Y3R4LmNsb3NlUGF0aCgpO1xuXHRcdFx0Y3R4LnN0cm9rZSgpO1xuXHRcdH1cblx0fVxuXG5cdGZ1bmN0aW9uIG51bWJlck9yWmVybyhwYXJhbSkge1xuXHRcdHJldHVybiBoZWxwZXJzLmlzTnVtYmVyKHBhcmFtKSA/IHBhcmFtIDogMDtcblx0fVxuXG5cdHZhciBMaW5lYXJSYWRpYWxTY2FsZSA9IENoYXJ0LkxpbmVhclNjYWxlQmFzZS5leHRlbmQoe1xuXHRcdHNldERpbWVuc2lvbnM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcblx0XHRcdHZhciB0aWNrT3B0cyA9IG9wdHMudGlja3M7XG5cdFx0XHQvLyBTZXQgdGhlIHVuY29uc3RyYWluZWQgZGltZW5zaW9uIGJlZm9yZSBsYWJlbCByb3RhdGlvblxuXHRcdFx0bWUud2lkdGggPSBtZS5tYXhXaWR0aDtcblx0XHRcdG1lLmhlaWdodCA9IG1lLm1heEhlaWdodDtcblx0XHRcdG1lLnhDZW50ZXIgPSBNYXRoLnJvdW5kKG1lLndpZHRoIC8gMik7XG5cdFx0XHRtZS55Q2VudGVyID0gTWF0aC5yb3VuZChtZS5oZWlnaHQgLyAyKTtcblxuXHRcdFx0dmFyIG1pblNpemUgPSBoZWxwZXJzLm1pbihbbWUuaGVpZ2h0LCBtZS53aWR0aF0pO1xuXHRcdFx0dmFyIHRpY2tGb250U2l6ZSA9IGhlbHBlcnMudmFsdWVPckRlZmF1bHQodGlja09wdHMuZm9udFNpemUsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250U2l6ZSk7XG5cdFx0XHRtZS5kcmF3aW5nQXJlYSA9IG9wdHMuZGlzcGxheSA/IChtaW5TaXplIC8gMikgLSAodGlja0ZvbnRTaXplIC8gMiArIHRpY2tPcHRzLmJhY2tkcm9wUGFkZGluZ1kpIDogKG1pblNpemUgLyAyKTtcblx0XHR9LFxuXHRcdGRldGVybWluZURhdGFMaW1pdHM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBjaGFydCA9IG1lLmNoYXJ0O1xuXHRcdFx0dmFyIG1pbiA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcblx0XHRcdHZhciBtYXggPSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XG5cblx0XHRcdGhlbHBlcnMuZWFjaChjaGFydC5kYXRhLmRhdGFzZXRzLCBmdW5jdGlvbihkYXRhc2V0LCBkYXRhc2V0SW5kZXgpIHtcblx0XHRcdFx0aWYgKGNoYXJ0LmlzRGF0YXNldFZpc2libGUoZGF0YXNldEluZGV4KSkge1xuXHRcdFx0XHRcdHZhciBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcblxuXHRcdFx0XHRcdGhlbHBlcnMuZWFjaChkYXRhc2V0LmRhdGEsIGZ1bmN0aW9uKHJhd1ZhbHVlLCBpbmRleCkge1xuXHRcdFx0XHRcdFx0dmFyIHZhbHVlID0gK21lLmdldFJpZ2h0VmFsdWUocmF3VmFsdWUpO1xuXHRcdFx0XHRcdFx0aWYgKGlzTmFOKHZhbHVlKSB8fCBtZXRhLmRhdGFbaW5kZXhdLmhpZGRlbikge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdG1pbiA9IE1hdGgubWluKHZhbHVlLCBtaW4pO1xuXHRcdFx0XHRcdFx0bWF4ID0gTWF0aC5tYXgodmFsdWUsIG1heCk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHRtZS5taW4gPSAobWluID09PSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgPyAwIDogbWluKTtcblx0XHRcdG1lLm1heCA9IChtYXggPT09IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSA/IDAgOiBtYXgpO1xuXG5cdFx0XHQvLyBDb21tb24gYmFzZSBpbXBsZW1lbnRhdGlvbiB0byBoYW5kbGUgdGlja3MubWluLCB0aWNrcy5tYXgsIHRpY2tzLmJlZ2luQXRaZXJvXG5cdFx0XHRtZS5oYW5kbGVUaWNrUmFuZ2VPcHRpb25zKCk7XG5cdFx0fSxcblx0XHRnZXRUaWNrTGltaXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHRpY2tPcHRzID0gdGhpcy5vcHRpb25zLnRpY2tzO1xuXHRcdFx0dmFyIHRpY2tGb250U2l6ZSA9IGhlbHBlcnMudmFsdWVPckRlZmF1bHQodGlja09wdHMuZm9udFNpemUsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250U2l6ZSk7XG5cdFx0XHRyZXR1cm4gTWF0aC5taW4odGlja09wdHMubWF4VGlja3NMaW1pdCA/IHRpY2tPcHRzLm1heFRpY2tzTGltaXQgOiAxMSwgTWF0aC5jZWlsKHRoaXMuZHJhd2luZ0FyZWEgLyAoMS41ICogdGlja0ZvbnRTaXplKSkpO1xuXHRcdH0sXG5cdFx0Y29udmVydFRpY2tzVG9MYWJlbHM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblxuXHRcdFx0Q2hhcnQuTGluZWFyU2NhbGVCYXNlLnByb3RvdHlwZS5jb252ZXJ0VGlja3NUb0xhYmVscy5jYWxsKG1lKTtcblxuXHRcdFx0Ly8gUG9pbnQgbGFiZWxzXG5cdFx0XHRtZS5wb2ludExhYmVscyA9IG1lLmNoYXJ0LmRhdGEubGFiZWxzLm1hcChtZS5vcHRpb25zLnBvaW50TGFiZWxzLmNhbGxiYWNrLCBtZSk7XG5cdFx0fSxcblx0XHRnZXRMYWJlbEZvckluZGV4OiBmdW5jdGlvbihpbmRleCwgZGF0YXNldEluZGV4KSB7XG5cdFx0XHRyZXR1cm4gK3RoaXMuZ2V0UmlnaHRWYWx1ZSh0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XS5kYXRhW2luZGV4XSk7XG5cdFx0fSxcblx0XHRmaXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKHRoaXMub3B0aW9ucy5wb2ludExhYmVscy5kaXNwbGF5KSB7XG5cdFx0XHRcdGZpdFdpdGhQb2ludExhYmVscyh0aGlzKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZpdCh0aGlzKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIFNldCByYWRpdXMgcmVkdWN0aW9ucyBhbmQgZGV0ZXJtaW5lIG5ldyByYWRpdXMgYW5kIGNlbnRlciBwb2ludFxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0c2V0UmVkdWN0aW9uczogZnVuY3Rpb24obGFyZ2VzdFBvc3NpYmxlUmFkaXVzLCBmdXJ0aGVzdExpbWl0cywgZnVydGhlc3RBbmdsZXMpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgcmFkaXVzUmVkdWN0aW9uTGVmdCA9IGZ1cnRoZXN0TGltaXRzLmwgLyBNYXRoLnNpbihmdXJ0aGVzdEFuZ2xlcy5sKTtcblx0XHRcdHZhciByYWRpdXNSZWR1Y3Rpb25SaWdodCA9IE1hdGgubWF4KGZ1cnRoZXN0TGltaXRzLnIgLSBtZS53aWR0aCwgMCkgLyBNYXRoLnNpbihmdXJ0aGVzdEFuZ2xlcy5yKTtcblx0XHRcdHZhciByYWRpdXNSZWR1Y3Rpb25Ub3AgPSAtZnVydGhlc3RMaW1pdHMudCAvIE1hdGguY29zKGZ1cnRoZXN0QW5nbGVzLnQpO1xuXHRcdFx0dmFyIHJhZGl1c1JlZHVjdGlvbkJvdHRvbSA9IC1NYXRoLm1heChmdXJ0aGVzdExpbWl0cy5iIC0gbWUuaGVpZ2h0LCAwKSAvIE1hdGguY29zKGZ1cnRoZXN0QW5nbGVzLmIpO1xuXG5cdFx0XHRyYWRpdXNSZWR1Y3Rpb25MZWZ0ID0gbnVtYmVyT3JaZXJvKHJhZGl1c1JlZHVjdGlvbkxlZnQpO1xuXHRcdFx0cmFkaXVzUmVkdWN0aW9uUmlnaHQgPSBudW1iZXJPclplcm8ocmFkaXVzUmVkdWN0aW9uUmlnaHQpO1xuXHRcdFx0cmFkaXVzUmVkdWN0aW9uVG9wID0gbnVtYmVyT3JaZXJvKHJhZGl1c1JlZHVjdGlvblRvcCk7XG5cdFx0XHRyYWRpdXNSZWR1Y3Rpb25Cb3R0b20gPSBudW1iZXJPclplcm8ocmFkaXVzUmVkdWN0aW9uQm90dG9tKTtcblxuXHRcdFx0bWUuZHJhd2luZ0FyZWEgPSBNYXRoLm1pbihcblx0XHRcdFx0TWF0aC5yb3VuZChsYXJnZXN0UG9zc2libGVSYWRpdXMgLSAocmFkaXVzUmVkdWN0aW9uTGVmdCArIHJhZGl1c1JlZHVjdGlvblJpZ2h0KSAvIDIpLFxuXHRcdFx0XHRNYXRoLnJvdW5kKGxhcmdlc3RQb3NzaWJsZVJhZGl1cyAtIChyYWRpdXNSZWR1Y3Rpb25Ub3AgKyByYWRpdXNSZWR1Y3Rpb25Cb3R0b20pIC8gMikpO1xuXHRcdFx0bWUuc2V0Q2VudGVyUG9pbnQocmFkaXVzUmVkdWN0aW9uTGVmdCwgcmFkaXVzUmVkdWN0aW9uUmlnaHQsIHJhZGl1c1JlZHVjdGlvblRvcCwgcmFkaXVzUmVkdWN0aW9uQm90dG9tKTtcblx0XHR9LFxuXHRcdHNldENlbnRlclBvaW50OiBmdW5jdGlvbihsZWZ0TW92ZW1lbnQsIHJpZ2h0TW92ZW1lbnQsIHRvcE1vdmVtZW50LCBib3R0b21Nb3ZlbWVudCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBtYXhSaWdodCA9IG1lLndpZHRoIC0gcmlnaHRNb3ZlbWVudCAtIG1lLmRyYXdpbmdBcmVhO1xuXHRcdFx0dmFyIG1heExlZnQgPSBsZWZ0TW92ZW1lbnQgKyBtZS5kcmF3aW5nQXJlYTtcblx0XHRcdHZhciBtYXhUb3AgPSB0b3BNb3ZlbWVudCArIG1lLmRyYXdpbmdBcmVhO1xuXHRcdFx0dmFyIG1heEJvdHRvbSA9IG1lLmhlaWdodCAtIGJvdHRvbU1vdmVtZW50IC0gbWUuZHJhd2luZ0FyZWE7XG5cblx0XHRcdG1lLnhDZW50ZXIgPSBNYXRoLnJvdW5kKCgobWF4TGVmdCArIG1heFJpZ2h0KSAvIDIpICsgbWUubGVmdCk7XG5cdFx0XHRtZS55Q2VudGVyID0gTWF0aC5yb3VuZCgoKG1heFRvcCArIG1heEJvdHRvbSkgLyAyKSArIG1lLnRvcCk7XG5cdFx0fSxcblxuXHRcdGdldEluZGV4QW5nbGU6IGZ1bmN0aW9uKGluZGV4KSB7XG5cdFx0XHR2YXIgYW5nbGVNdWx0aXBsaWVyID0gKE1hdGguUEkgKiAyKSAvIGdldFZhbHVlQ291bnQodGhpcyk7XG5cdFx0XHR2YXIgc3RhcnRBbmdsZSA9IHRoaXMuY2hhcnQub3B0aW9ucyAmJiB0aGlzLmNoYXJ0Lm9wdGlvbnMuc3RhcnRBbmdsZSA/XG5cdFx0XHRcdHRoaXMuY2hhcnQub3B0aW9ucy5zdGFydEFuZ2xlIDpcblx0XHRcdFx0MDtcblxuXHRcdFx0dmFyIHN0YXJ0QW5nbGVSYWRpYW5zID0gc3RhcnRBbmdsZSAqIE1hdGguUEkgKiAyIC8gMzYwO1xuXG5cdFx0XHQvLyBTdGFydCBmcm9tIHRoZSB0b3AgaW5zdGVhZCBvZiByaWdodCwgc28gcmVtb3ZlIGEgcXVhcnRlciBvZiB0aGUgY2lyY2xlXG5cdFx0XHRyZXR1cm4gaW5kZXggKiBhbmdsZU11bHRpcGxpZXIgKyBzdGFydEFuZ2xlUmFkaWFucztcblx0XHR9LFxuXHRcdGdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlOiBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblxuXHRcdFx0aWYgKHZhbHVlID09PSBudWxsKSB7XG5cdFx0XHRcdHJldHVybiAwOyAvLyBudWxsIGFsd2F5cyBpbiBjZW50ZXJcblx0XHRcdH1cblxuXHRcdFx0Ly8gVGFrZSBpbnRvIGFjY291bnQgaGFsZiBmb250IHNpemUgKyB0aGUgeVBhZGRpbmcgb2YgdGhlIHRvcCB2YWx1ZVxuXHRcdFx0dmFyIHNjYWxpbmdGYWN0b3IgPSBtZS5kcmF3aW5nQXJlYSAvIChtZS5tYXggLSBtZS5taW4pO1xuXHRcdFx0aWYgKG1lLm9wdGlvbnMudGlja3MucmV2ZXJzZSkge1xuXHRcdFx0XHRyZXR1cm4gKG1lLm1heCAtIHZhbHVlKSAqIHNjYWxpbmdGYWN0b3I7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gKHZhbHVlIC0gbWUubWluKSAqIHNjYWxpbmdGYWN0b3I7XG5cdFx0fSxcblx0XHRnZXRQb2ludFBvc2l0aW9uOiBmdW5jdGlvbihpbmRleCwgZGlzdGFuY2VGcm9tQ2VudGVyKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIHRoaXNBbmdsZSA9IG1lLmdldEluZGV4QW5nbGUoaW5kZXgpIC0gKE1hdGguUEkgLyAyKTtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdHg6IE1hdGgucm91bmQoTWF0aC5jb3ModGhpc0FuZ2xlKSAqIGRpc3RhbmNlRnJvbUNlbnRlcikgKyBtZS54Q2VudGVyLFxuXHRcdFx0XHR5OiBNYXRoLnJvdW5kKE1hdGguc2luKHRoaXNBbmdsZSkgKiBkaXN0YW5jZUZyb21DZW50ZXIpICsgbWUueUNlbnRlclxuXHRcdFx0fTtcblx0XHR9LFxuXHRcdGdldFBvaW50UG9zaXRpb25Gb3JWYWx1ZTogZnVuY3Rpb24oaW5kZXgsIHZhbHVlKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5nZXRQb2ludFBvc2l0aW9uKGluZGV4LCB0aGlzLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKHZhbHVlKSk7XG5cdFx0fSxcblxuXHRcdGdldEJhc2VQb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG1pbiA9IG1lLm1pbjtcblx0XHRcdHZhciBtYXggPSBtZS5tYXg7XG5cblx0XHRcdHJldHVybiBtZS5nZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUoMCxcblx0XHRcdFx0bWUuYmVnaW5BdFplcm8gPyAwIDpcblx0XHRcdFx0bWluIDwgMCAmJiBtYXggPCAwID8gbWF4IDpcblx0XHRcdFx0bWluID4gMCAmJiBtYXggPiAwID8gbWluIDpcblx0XHRcdFx0MCk7XG5cdFx0fSxcblxuXHRcdGRyYXc6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcblx0XHRcdHZhciBncmlkTGluZU9wdHMgPSBvcHRzLmdyaWRMaW5lcztcblx0XHRcdHZhciB0aWNrT3B0cyA9IG9wdHMudGlja3M7XG5cdFx0XHR2YXIgdmFsdWVPckRlZmF1bHQgPSBoZWxwZXJzLnZhbHVlT3JEZWZhdWx0O1xuXG5cdFx0XHRpZiAob3B0cy5kaXNwbGF5KSB7XG5cdFx0XHRcdHZhciBjdHggPSBtZS5jdHg7XG5cdFx0XHRcdHZhciBzdGFydEFuZ2xlID0gdGhpcy5nZXRJbmRleEFuZ2xlKDApO1xuXG5cdFx0XHRcdC8vIFRpY2sgRm9udFxuXHRcdFx0XHR2YXIgdGlja0ZvbnRTaXplID0gdmFsdWVPckRlZmF1bHQodGlja09wdHMuZm9udFNpemUsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250U2l6ZSk7XG5cdFx0XHRcdHZhciB0aWNrRm9udFN0eWxlID0gdmFsdWVPckRlZmF1bHQodGlja09wdHMuZm9udFN0eWxlLCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udFN0eWxlKTtcblx0XHRcdFx0dmFyIHRpY2tGb250RmFtaWx5ID0gdmFsdWVPckRlZmF1bHQodGlja09wdHMuZm9udEZhbWlseSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRGYW1pbHkpO1xuXHRcdFx0XHR2YXIgdGlja0xhYmVsRm9udCA9IGhlbHBlcnMuZm9udFN0cmluZyh0aWNrRm9udFNpemUsIHRpY2tGb250U3R5bGUsIHRpY2tGb250RmFtaWx5KTtcblxuXHRcdFx0XHRoZWxwZXJzLmVhY2gobWUudGlja3MsIGZ1bmN0aW9uKGxhYmVsLCBpbmRleCkge1xuXHRcdFx0XHRcdC8vIERvbid0IGRyYXcgYSBjZW50cmUgdmFsdWUgKGlmIGl0IGlzIG1pbmltdW0pXG5cdFx0XHRcdFx0aWYgKGluZGV4ID4gMCB8fCB0aWNrT3B0cy5yZXZlcnNlKSB7XG5cdFx0XHRcdFx0XHR2YXIgeUNlbnRlck9mZnNldCA9IG1lLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKG1lLnRpY2tzQXNOdW1iZXJzW2luZGV4XSk7XG5cblx0XHRcdFx0XHRcdC8vIERyYXcgY2lyY3VsYXIgbGluZXMgYXJvdW5kIHRoZSBzY2FsZVxuXHRcdFx0XHRcdFx0aWYgKGdyaWRMaW5lT3B0cy5kaXNwbGF5ICYmIGluZGV4ICE9PSAwKSB7XG5cdFx0XHRcdFx0XHRcdGRyYXdSYWRpdXNMaW5lKG1lLCBncmlkTGluZU9wdHMsIHlDZW50ZXJPZmZzZXQsIGluZGV4KTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKHRpY2tPcHRzLmRpc3BsYXkpIHtcblx0XHRcdFx0XHRcdFx0dmFyIHRpY2tGb250Q29sb3IgPSB2YWx1ZU9yRGVmYXVsdCh0aWNrT3B0cy5mb250Q29sb3IsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250Q29sb3IpO1xuXHRcdFx0XHRcdFx0XHRjdHguZm9udCA9IHRpY2tMYWJlbEZvbnQ7XG5cblx0XHRcdFx0XHRcdFx0Y3R4LnNhdmUoKTtcblx0XHRcdFx0XHRcdFx0Y3R4LnRyYW5zbGF0ZShtZS54Q2VudGVyLCBtZS55Q2VudGVyKTtcblx0XHRcdFx0XHRcdFx0Y3R4LnJvdGF0ZShzdGFydEFuZ2xlKTtcblxuXHRcdFx0XHRcdFx0XHRpZiAodGlja09wdHMuc2hvd0xhYmVsQmFja2Ryb3ApIHtcblx0XHRcdFx0XHRcdFx0XHR2YXIgbGFiZWxXaWR0aCA9IGN0eC5tZWFzdXJlVGV4dChsYWJlbCkud2lkdGg7XG5cdFx0XHRcdFx0XHRcdFx0Y3R4LmZpbGxTdHlsZSA9IHRpY2tPcHRzLmJhY2tkcm9wQ29sb3I7XG5cdFx0XHRcdFx0XHRcdFx0Y3R4LmZpbGxSZWN0KFxuXHRcdFx0XHRcdFx0XHRcdFx0LWxhYmVsV2lkdGggLyAyIC0gdGlja09wdHMuYmFja2Ryb3BQYWRkaW5nWCxcblx0XHRcdFx0XHRcdFx0XHRcdC15Q2VudGVyT2Zmc2V0IC0gdGlja0ZvbnRTaXplIC8gMiAtIHRpY2tPcHRzLmJhY2tkcm9wUGFkZGluZ1ksXG5cdFx0XHRcdFx0XHRcdFx0XHRsYWJlbFdpZHRoICsgdGlja09wdHMuYmFja2Ryb3BQYWRkaW5nWCAqIDIsXG5cdFx0XHRcdFx0XHRcdFx0XHR0aWNrRm9udFNpemUgKyB0aWNrT3B0cy5iYWNrZHJvcFBhZGRpbmdZICogMlxuXHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRjdHgudGV4dEFsaWduID0gJ2NlbnRlcic7XG5cdFx0XHRcdFx0XHRcdGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcblx0XHRcdFx0XHRcdFx0Y3R4LmZpbGxTdHlsZSA9IHRpY2tGb250Q29sb3I7XG5cdFx0XHRcdFx0XHRcdGN0eC5maWxsVGV4dChsYWJlbCwgMCwgLXlDZW50ZXJPZmZzZXQpO1xuXHRcdFx0XHRcdFx0XHRjdHgucmVzdG9yZSgpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cblx0XHRcdFx0aWYgKG9wdHMuYW5nbGVMaW5lcy5kaXNwbGF5IHx8IG9wdHMucG9pbnRMYWJlbHMuZGlzcGxheSkge1xuXHRcdFx0XHRcdGRyYXdQb2ludExhYmVscyhtZSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0pO1xuXG5cdHNjYWxlU2VydmljZS5yZWdpc3RlclNjYWxlVHlwZSgncmFkaWFsTGluZWFyJywgTGluZWFyUmFkaWFsU2NhbGUsIGRlZmF1bHRDb25maWcpO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///90fd\n")},9778:function(module,exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = function(Chart) {\n\n\tChart.Doughnut = function(context, config) {\n\t\tconfig.type = 'doughnut';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTc3OC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY2hhcnRzL0NoYXJ0LkRvdWdobnV0LmpzPzRiYjMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKENoYXJ0KSB7XG5cblx0Q2hhcnQuRG91Z2hudXQgPSBmdW5jdGlvbihjb250ZXh0LCBjb25maWcpIHtcblx0XHRjb25maWcudHlwZSA9ICdkb3VnaG51dCc7XG5cblx0XHRyZXR1cm4gbmV3IENoYXJ0KGNvbnRleHQsIGNvbmZpZyk7XG5cdH07XG5cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9778\n")},9905:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar Element = __webpack_require__(/*! ../core/core.element */ \"4a45\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\nvar globalDefaults = defaults.global;\n\ndefaults._set('global', {\n\telements: {\n\t\tline: {\n\t\t\ttension: 0.4,\n\t\t\tbackgroundColor: globalDefaults.defaultColor,\n\t\t\tborderWidth: 3,\n\t\t\tborderColor: globalDefaults.defaultColor,\n\t\t\tborderCapStyle: 'butt',\n\t\t\tborderDash: [],\n\t\t\tborderDashOffset: 0.0,\n\t\t\tborderJoinStyle: 'miter',\n\t\t\tcapBezierPoints: true,\n\t\t\tfill: true, // do we fill in the area between the line and its base axis\n\t\t}\n\t}\n});\n\nmodule.exports = Element.extend({\n\tdraw: function() {\n\t\tvar me = this;\n\t\tvar vm = me._view;\n\t\tvar ctx = me._chart.ctx;\n\t\tvar spanGaps = vm.spanGaps;\n\t\tvar points = me._children.slice(); // clone array\n\t\tvar globalOptionLineElements = globalDefaults.elements.line;\n\t\tvar lastDrawnIndex = -1;\n\t\tvar index, current, previous, currentVM;\n\n\t\t// If we are looping, adding the first point again\n\t\tif (me._loop && points.length) {\n\t\t\tpoints.push(points[0]);\n\t\t}\n\n\t\tctx.save();\n\n\t\t// Stroke Line Options\n\t\tctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;\n\n\t\t// IE 9 and 10 do not support line dash\n\t\tif (ctx.setLineDash) {\n\t\t\tctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);\n\t\t}\n\n\t\tctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;\n\t\tctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;\n\t\tctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;\n\t\tctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;\n\n\t\t// Stroke Line\n\t\tctx.beginPath();\n\t\tlastDrawnIndex = -1;\n\n\t\tfor (index = 0; index < points.length; ++index) {\n\t\t\tcurrent = points[index];\n\t\t\tprevious = helpers.previousItem(points, index);\n\t\t\tcurrentVM = current._view;\n\n\t\t\t// First point moves to it's starting position no matter what\n\t\t\tif (index === 0) {\n\t\t\t\tif (!currentVM.skip) {\n\t\t\t\t\tctx.moveTo(currentVM.x, currentVM.y);\n\t\t\t\t\tlastDrawnIndex = index;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tprevious = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];\n\n\t\t\t\tif (!currentVM.skip) {\n\t\t\t\t\tif ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {\n\t\t\t\t\t\t// There was a gap and this is the first point after the gap\n\t\t\t\t\t\tctx.moveTo(currentVM.x, currentVM.y);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Line to next point\n\t\t\t\t\t\thelpers.canvas.lineTo(ctx, previous._view, current._view);\n\t\t\t\t\t}\n\t\t\t\t\tlastDrawnIndex = index;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tctx.stroke();\n\t\tctx.restore();\n\t}\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTkwNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvZWxlbWVudHMvZWxlbWVudC5saW5lLmpzPzUyYTkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuZGVmYXVsdHMnKTtcbnZhciBFbGVtZW50ID0gcmVxdWlyZSgnLi4vY29yZS9jb3JlLmVsZW1lbnQnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xuXG52YXIgZ2xvYmFsRGVmYXVsdHMgPSBkZWZhdWx0cy5nbG9iYWw7XG5cbmRlZmF1bHRzLl9zZXQoJ2dsb2JhbCcsIHtcblx0ZWxlbWVudHM6IHtcblx0XHRsaW5lOiB7XG5cdFx0XHR0ZW5zaW9uOiAwLjQsXG5cdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IGdsb2JhbERlZmF1bHRzLmRlZmF1bHRDb2xvcixcblx0XHRcdGJvcmRlcldpZHRoOiAzLFxuXHRcdFx0Ym9yZGVyQ29sb3I6IGdsb2JhbERlZmF1bHRzLmRlZmF1bHRDb2xvcixcblx0XHRcdGJvcmRlckNhcFN0eWxlOiAnYnV0dCcsXG5cdFx0XHRib3JkZXJEYXNoOiBbXSxcblx0XHRcdGJvcmRlckRhc2hPZmZzZXQ6IDAuMCxcblx0XHRcdGJvcmRlckpvaW5TdHlsZTogJ21pdGVyJyxcblx0XHRcdGNhcEJlemllclBvaW50czogdHJ1ZSxcblx0XHRcdGZpbGw6IHRydWUsIC8vIGRvIHdlIGZpbGwgaW4gdGhlIGFyZWEgYmV0d2VlbiB0aGUgbGluZSBhbmQgaXRzIGJhc2UgYXhpc1xuXHRcdH1cblx0fVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gRWxlbWVudC5leHRlbmQoe1xuXHRkcmF3OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciB2bSA9IG1lLl92aWV3O1xuXHRcdHZhciBjdHggPSBtZS5fY2hhcnQuY3R4O1xuXHRcdHZhciBzcGFuR2FwcyA9IHZtLnNwYW5HYXBzO1xuXHRcdHZhciBwb2ludHMgPSBtZS5fY2hpbGRyZW4uc2xpY2UoKTsgLy8gY2xvbmUgYXJyYXlcblx0XHR2YXIgZ2xvYmFsT3B0aW9uTGluZUVsZW1lbnRzID0gZ2xvYmFsRGVmYXVsdHMuZWxlbWVudHMubGluZTtcblx0XHR2YXIgbGFzdERyYXduSW5kZXggPSAtMTtcblx0XHR2YXIgaW5kZXgsIGN1cnJlbnQsIHByZXZpb3VzLCBjdXJyZW50Vk07XG5cblx0XHQvLyBJZiB3ZSBhcmUgbG9vcGluZywgYWRkaW5nIHRoZSBmaXJzdCBwb2ludCBhZ2FpblxuXHRcdGlmIChtZS5fbG9vcCAmJiBwb2ludHMubGVuZ3RoKSB7XG5cdFx0XHRwb2ludHMucHVzaChwb2ludHNbMF0pO1xuXHRcdH1cblxuXHRcdGN0eC5zYXZlKCk7XG5cblx0XHQvLyBTdHJva2UgTGluZSBPcHRpb25zXG5cdFx0Y3R4LmxpbmVDYXAgPSB2bS5ib3JkZXJDYXBTdHlsZSB8fCBnbG9iYWxPcHRpb25MaW5lRWxlbWVudHMuYm9yZGVyQ2FwU3R5bGU7XG5cblx0XHQvLyBJRSA5IGFuZCAxMCBkbyBub3Qgc3VwcG9ydCBsaW5lIGRhc2hcblx0XHRpZiAoY3R4LnNldExpbmVEYXNoKSB7XG5cdFx0XHRjdHguc2V0TGluZURhc2godm0uYm9yZGVyRGFzaCB8fCBnbG9iYWxPcHRpb25MaW5lRWxlbWVudHMuYm9yZGVyRGFzaCk7XG5cdFx0fVxuXG5cdFx0Y3R4LmxpbmVEYXNoT2Zmc2V0ID0gdm0uYm9yZGVyRGFzaE9mZnNldCB8fCBnbG9iYWxPcHRpb25MaW5lRWxlbWVudHMuYm9yZGVyRGFzaE9mZnNldDtcblx0XHRjdHgubGluZUpvaW4gPSB2bS5ib3JkZXJKb2luU3R5bGUgfHwgZ2xvYmFsT3B0aW9uTGluZUVsZW1lbnRzLmJvcmRlckpvaW5TdHlsZTtcblx0XHRjdHgubGluZVdpZHRoID0gdm0uYm9yZGVyV2lkdGggfHwgZ2xvYmFsT3B0aW9uTGluZUVsZW1lbnRzLmJvcmRlcldpZHRoO1xuXHRcdGN0eC5zdHJva2VTdHlsZSA9IHZtLmJvcmRlckNvbG9yIHx8IGdsb2JhbERlZmF1bHRzLmRlZmF1bHRDb2xvcjtcblxuXHRcdC8vIFN0cm9rZSBMaW5lXG5cdFx0Y3R4LmJlZ2luUGF0aCgpO1xuXHRcdGxhc3REcmF3bkluZGV4ID0gLTE7XG5cblx0XHRmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBwb2ludHMubGVuZ3RoOyArK2luZGV4KSB7XG5cdFx0XHRjdXJyZW50ID0gcG9pbnRzW2luZGV4XTtcblx0XHRcdHByZXZpb3VzID0gaGVscGVycy5wcmV2aW91c0l0ZW0ocG9pbnRzLCBpbmRleCk7XG5cdFx0XHRjdXJyZW50Vk0gPSBjdXJyZW50Ll92aWV3O1xuXG5cdFx0XHQvLyBGaXJzdCBwb2ludCBtb3ZlcyB0byBpdCdzIHN0YXJ0aW5nIHBvc2l0aW9uIG5vIG1hdHRlciB3aGF0XG5cdFx0XHRpZiAoaW5kZXggPT09IDApIHtcblx0XHRcdFx0aWYgKCFjdXJyZW50Vk0uc2tpcCkge1xuXHRcdFx0XHRcdGN0eC5tb3ZlVG8oY3VycmVudFZNLngsIGN1cnJlbnRWTS55KTtcblx0XHRcdFx0XHRsYXN0RHJhd25JbmRleCA9IGluZGV4O1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwcmV2aW91cyA9IGxhc3REcmF3bkluZGV4ID09PSAtMSA/IHByZXZpb3VzIDogcG9pbnRzW2xhc3REcmF3bkluZGV4XTtcblxuXHRcdFx0XHRpZiAoIWN1cnJlbnRWTS5za2lwKSB7XG5cdFx0XHRcdFx0aWYgKChsYXN0RHJhd25JbmRleCAhPT0gKGluZGV4IC0gMSkgJiYgIXNwYW5HYXBzKSB8fCBsYXN0RHJhd25JbmRleCA9PT0gLTEpIHtcblx0XHRcdFx0XHRcdC8vIFRoZXJlIHdhcyBhIGdhcCBhbmQgdGhpcyBpcyB0aGUgZmlyc3QgcG9pbnQgYWZ0ZXIgdGhlIGdhcFxuXHRcdFx0XHRcdFx0Y3R4Lm1vdmVUbyhjdXJyZW50Vk0ueCwgY3VycmVudFZNLnkpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHQvLyBMaW5lIHRvIG5leHQgcG9pbnRcblx0XHRcdFx0XHRcdGhlbHBlcnMuY2FudmFzLmxpbmVUbyhjdHgsIHByZXZpb3VzLl92aWV3LCBjdXJyZW50Ll92aWV3KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0bGFzdERyYXduSW5kZXggPSBpbmRleDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGN0eC5zdHJva2UoKTtcblx0XHRjdHgucmVzdG9yZSgpO1xuXHR9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9905\n")},"9a10":function(module,exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = function(Chart) {\n\n\tChart.Bubble = function(context, config) {\n\t\tconfig.type = 'bubble';\n\t\treturn new Chart(context, config);\n\t};\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWExMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY2hhcnRzL0NoYXJ0LkJ1YmJsZS5qcz80MWVjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDaGFydCkge1xuXG5cdENoYXJ0LkJ1YmJsZSA9IGZ1bmN0aW9uKGNvbnRleHQsIGNvbmZpZykge1xuXHRcdGNvbmZpZy50eXBlID0gJ2J1YmJsZSc7XG5cdFx0cmV0dXJuIG5ldyBDaGFydChjb250ZXh0LCBjb25maWcpO1xuXHR9O1xuXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9a10\n")},"9af9":function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ./core.defaults */ \"beaa\");\nvar Element = __webpack_require__(/*! ./core.element */ \"4a45\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\ndefaults._set('global', {\n\ttooltips: {\n\t\tenabled: true,\n\t\tcustom: null,\n\t\tmode: 'nearest',\n\t\tposition: 'average',\n\t\tintersect: true,\n\t\tbackgroundColor: 'rgba(0,0,0,0.8)',\n\t\ttitleFontStyle: 'bold',\n\t\ttitleSpacing: 2,\n\t\ttitleMarginBottom: 6,\n\t\ttitleFontColor: '#fff',\n\t\ttitleAlign: 'left',\n\t\tbodySpacing: 2,\n\t\tbodyFontColor: '#fff',\n\t\tbodyAlign: 'left',\n\t\tfooterFontStyle: 'bold',\n\t\tfooterSpacing: 2,\n\t\tfooterMarginTop: 6,\n\t\tfooterFontColor: '#fff',\n\t\tfooterAlign: 'left',\n\t\tyPadding: 6,\n\t\txPadding: 6,\n\t\tcaretPadding: 2,\n\t\tcaretSize: 5,\n\t\tcornerRadius: 6,\n\t\tmultiKeyBackground: '#fff',\n\t\tdisplayColors: true,\n\t\tborderColor: 'rgba(0,0,0,0)',\n\t\tborderWidth: 0,\n\t\tcallbacks: {\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeTitle: helpers.noop,\n\t\t\ttitle: function(tooltipItems, data) {\n\t\t\t\t// Pick first xLabel for now\n\t\t\t\tvar title = '';\n\t\t\t\tvar labels = data.labels;\n\t\t\t\tvar labelCount = labels ? labels.length : 0;\n\n\t\t\t\tif (tooltipItems.length > 0) {\n\t\t\t\t\tvar item = tooltipItems[0];\n\n\t\t\t\t\tif (item.xLabel) {\n\t\t\t\t\t\ttitle = item.xLabel;\n\t\t\t\t\t} else if (labelCount > 0 && item.index < labelCount) {\n\t\t\t\t\t\ttitle = labels[item.index];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn title;\n\t\t\t},\n\t\t\tafterTitle: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeBody: helpers.noop,\n\n\t\t\t// Args are: (tooltipItem, data)\n\t\t\tbeforeLabel: helpers.noop,\n\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\tvar label = data.datasets[tooltipItem.datasetIndex].label || '';\n\n\t\t\t\tif (label) {\n\t\t\t\t\tlabel += ': ';\n\t\t\t\t}\n\t\t\t\tlabel += tooltipItem.yLabel;\n\t\t\t\treturn label;\n\t\t\t},\n\t\t\tlabelColor: function(tooltipItem, chart) {\n\t\t\t\tvar meta = chart.getDatasetMeta(tooltipItem.datasetIndex);\n\t\t\t\tvar activeElement = meta.data[tooltipItem.index];\n\t\t\t\tvar view = activeElement._view;\n\t\t\t\treturn {\n\t\t\t\t\tborderColor: view.borderColor,\n\t\t\t\t\tbackgroundColor: view.backgroundColor\n\t\t\t\t};\n\t\t\t},\n\t\t\tlabelTextColor: function() {\n\t\t\t\treturn this._options.bodyFontColor;\n\t\t\t},\n\t\t\tafterLabel: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tafterBody: helpers.noop,\n\n\t\t\t// Args are: (tooltipItems, data)\n\t\t\tbeforeFooter: helpers.noop,\n\t\t\tfooter: helpers.noop,\n\t\t\tafterFooter: helpers.noop\n\t\t}\n\t}\n});\n\nvar positioners = {\n\t/**\n\t * Average mode places the tooltip at the average position of the elements shown\n\t * @function Chart.Tooltip.positioners.average\n\t * @param elements {ChartElement[]} the elements being displayed in the tooltip\n\t * @returns {Point} tooltip position\n\t */\n\taverage: function(elements) {\n\t\tif (!elements.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar i, len;\n\t\tvar x = 0;\n\t\tvar y = 0;\n\t\tvar count = 0;\n\n\t\tfor (i = 0, len = elements.length; i < len; ++i) {\n\t\t\tvar el = elements[i];\n\t\t\tif (el && el.hasValue()) {\n\t\t\t\tvar pos = el.tooltipPosition();\n\t\t\t\tx += pos.x;\n\t\t\t\ty += pos.y;\n\t\t\t\t++count;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tx: Math.round(x / count),\n\t\t\ty: Math.round(y / count)\n\t\t};\n\t},\n\n\t/**\n\t * Gets the tooltip position nearest of the item nearest to the event position\n\t * @function Chart.Tooltip.positioners.nearest\n\t * @param elements {Chart.Element[]} the tooltip elements\n\t * @param eventPosition {Point} the position of the event in canvas coordinates\n\t * @returns {Point} the tooltip position\n\t */\n\tnearest: function(elements, eventPosition) {\n\t\tvar x = eventPosition.x;\n\t\tvar y = eventPosition.y;\n\t\tvar minDistance = Number.POSITIVE_INFINITY;\n\t\tvar i, len, nearestElement;\n\n\t\tfor (i = 0, len = elements.length; i < len; ++i) {\n\t\t\tvar el = elements[i];\n\t\t\tif (el && el.hasValue()) {\n\t\t\t\tvar center = el.getCenterPoint();\n\t\t\t\tvar d = helpers.distanceBetweenPoints(eventPosition, center);\n\n\t\t\t\tif (d < minDistance) {\n\t\t\t\t\tminDistance = d;\n\t\t\t\t\tnearestElement = el;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (nearestElement) {\n\t\t\tvar tp = nearestElement.tooltipPosition();\n\t\t\tx = tp.x;\n\t\t\ty = tp.y;\n\t\t}\n\n\t\treturn {\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\t}\n};\n\n/**\n * Helper method to merge the opacity into a color\n */\nfunction mergeOpacity(colorString, opacity) {\n\tvar color = helpers.color(colorString);\n\treturn color.alpha(opacity * color.alpha()).rgbaString();\n}\n\n// Helper to push or concat based on if the 2nd parameter is an array or not\nfunction pushOrConcat(base, toPush) {\n\tif (toPush) {\n\t\tif (helpers.isArray(toPush)) {\n\t\t\t// base = base.concat(toPush);\n\t\t\tArray.prototype.push.apply(base, toPush);\n\t\t} else {\n\t\t\tbase.push(toPush);\n\t\t}\n\t}\n\n\treturn base;\n}\n\n/**\n * Returns array of strings split by newline\n * @param {String} value - The value to split by newline.\n * @returns {Array} value if newline present - Returned from String split() method\n * @function\n */\nfunction splitNewlines(str) {\n\tif ((typeof str === 'string' || str instanceof String) && str.indexOf('\\n') > -1) {\n\t\treturn str.split('\\n');\n\t}\n\treturn str;\n}\n\n\n// Private helper to create a tooltip item model\n// @param element : the chart element (point, arc, bar) to create the tooltip item for\n// @return : new tooltip item\nfunction createTooltipItem(element) {\n\tvar xScale = element._xScale;\n\tvar yScale = element._yScale || element._scale; // handle radar || polarArea charts\n\tvar index = element._index;\n\tvar datasetIndex = element._datasetIndex;\n\n\treturn {\n\t\txLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',\n\t\tyLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',\n\t\tindex: index,\n\t\tdatasetIndex: datasetIndex,\n\t\tx: element._model.x,\n\t\ty: element._model.y\n\t};\n}\n\n/**\n * Helper to get the reset model for the tooltip\n * @param tooltipOpts {Object} the tooltip options\n */\nfunction getBaseModel(tooltipOpts) {\n\tvar globalDefaults = defaults.global;\n\tvar valueOrDefault = helpers.valueOrDefault;\n\n\treturn {\n\t\t// Positioning\n\t\txPadding: tooltipOpts.xPadding,\n\t\tyPadding: tooltipOpts.yPadding,\n\t\txAlign: tooltipOpts.xAlign,\n\t\tyAlign: tooltipOpts.yAlign,\n\n\t\t// Body\n\t\tbodyFontColor: tooltipOpts.bodyFontColor,\n\t\t_bodyFontFamily: valueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),\n\t\t_bodyFontStyle: valueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),\n\t\t_bodyAlign: tooltipOpts.bodyAlign,\n\t\tbodyFontSize: valueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),\n\t\tbodySpacing: tooltipOpts.bodySpacing,\n\n\t\t// Title\n\t\ttitleFontColor: tooltipOpts.titleFontColor,\n\t\t_titleFontFamily: valueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),\n\t\t_titleFontStyle: valueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),\n\t\ttitleFontSize: valueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),\n\t\t_titleAlign: tooltipOpts.titleAlign,\n\t\ttitleSpacing: tooltipOpts.titleSpacing,\n\t\ttitleMarginBottom: tooltipOpts.titleMarginBottom,\n\n\t\t// Footer\n\t\tfooterFontColor: tooltipOpts.footerFontColor,\n\t\t_footerFontFamily: valueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),\n\t\t_footerFontStyle: valueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),\n\t\tfooterFontSize: valueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),\n\t\t_footerAlign: tooltipOpts.footerAlign,\n\t\tfooterSpacing: tooltipOpts.footerSpacing,\n\t\tfooterMarginTop: tooltipOpts.footerMarginTop,\n\n\t\t// Appearance\n\t\tcaretSize: tooltipOpts.caretSize,\n\t\tcornerRadius: tooltipOpts.cornerRadius,\n\t\tbackgroundColor: tooltipOpts.backgroundColor,\n\t\topacity: 0,\n\t\tlegendColorBackground: tooltipOpts.multiKeyBackground,\n\t\tdisplayColors: tooltipOpts.displayColors,\n\t\tborderColor: tooltipOpts.borderColor,\n\t\tborderWidth: tooltipOpts.borderWidth\n\t};\n}\n\n/**\n * Get the size of the tooltip\n */\nfunction getTooltipSize(tooltip, model) {\n\tvar ctx = tooltip._chart.ctx;\n\n\tvar height = model.yPadding * 2; // Tooltip Padding\n\tvar width = 0;\n\n\t// Count of all lines in the body\n\tvar body = model.body;\n\tvar combinedBodyLength = body.reduce(function(count, bodyItem) {\n\t\treturn count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;\n\t}, 0);\n\tcombinedBodyLength += model.beforeBody.length + model.afterBody.length;\n\n\tvar titleLineCount = model.title.length;\n\tvar footerLineCount = model.footer.length;\n\tvar titleFontSize = model.titleFontSize;\n\tvar bodyFontSize = model.bodyFontSize;\n\tvar footerFontSize = model.footerFontSize;\n\n\theight += titleLineCount * titleFontSize; // Title Lines\n\theight += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing\n\theight += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin\n\theight += combinedBodyLength * bodyFontSize; // Body Lines\n\theight += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing\n\theight += footerLineCount ? model.footerMarginTop : 0; // Footer Margin\n\theight += footerLineCount * (footerFontSize); // Footer Lines\n\theight += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing\n\n\t// Title width\n\tvar widthPadding = 0;\n\tvar maxLineWidth = function(line) {\n\t\twidth = Math.max(width, ctx.measureText(line).width + widthPadding);\n\t};\n\n\tctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);\n\thelpers.each(model.title, maxLineWidth);\n\n\t// Body width\n\tctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);\n\thelpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);\n\n\t// Body lines may include some extra width due to the color box\n\twidthPadding = model.displayColors ? (bodyFontSize + 2) : 0;\n\thelpers.each(body, function(bodyItem) {\n\t\thelpers.each(bodyItem.before, maxLineWidth);\n\t\thelpers.each(bodyItem.lines, maxLineWidth);\n\t\thelpers.each(bodyItem.after, maxLineWidth);\n\t});\n\n\t// Reset back to 0\n\twidthPadding = 0;\n\n\t// Footer width\n\tctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);\n\thelpers.each(model.footer, maxLineWidth);\n\n\t// Add padding\n\twidth += 2 * model.xPadding;\n\n\treturn {\n\t\twidth: width,\n\t\theight: height\n\t};\n}\n\n/**\n * Helper to get the alignment of a tooltip given the size\n */\nfunction determineAlignment(tooltip, size) {\n\tvar model = tooltip._model;\n\tvar chart = tooltip._chart;\n\tvar chartArea = tooltip._chart.chartArea;\n\tvar xAlign = 'center';\n\tvar yAlign = 'center';\n\n\tif (model.y < size.height) {\n\t\tyAlign = 'top';\n\t} else if (model.y > (chart.height - size.height)) {\n\t\tyAlign = 'bottom';\n\t}\n\n\tvar lf, rf; // functions to determine left, right alignment\n\tvar olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart\n\tvar yf; // function to get the y alignment if the tooltip goes outside of the left or right edges\n\tvar midX = (chartArea.left + chartArea.right) / 2;\n\tvar midY = (chartArea.top + chartArea.bottom) / 2;\n\n\tif (yAlign === 'center') {\n\t\tlf = function(x) {\n\t\t\treturn x <= midX;\n\t\t};\n\t\trf = function(x) {\n\t\t\treturn x > midX;\n\t\t};\n\t} else {\n\t\tlf = function(x) {\n\t\t\treturn x <= (size.width / 2);\n\t\t};\n\t\trf = function(x) {\n\t\t\treturn x >= (chart.width - (size.width / 2));\n\t\t};\n\t}\n\n\tolf = function(x) {\n\t\treturn x + size.width + model.caretSize + model.caretPadding > chart.width;\n\t};\n\torf = function(x) {\n\t\treturn x - size.width - model.caretSize - model.caretPadding < 0;\n\t};\n\tyf = function(y) {\n\t\treturn y <= midY ? 'top' : 'bottom';\n\t};\n\n\tif (lf(model.x)) {\n\t\txAlign = 'left';\n\n\t\t// Is tooltip too wide and goes over the right side of the chart.?\n\t\tif (olf(model.x)) {\n\t\t\txAlign = 'center';\n\t\t\tyAlign = yf(model.y);\n\t\t}\n\t} else if (rf(model.x)) {\n\t\txAlign = 'right';\n\n\t\t// Is tooltip too wide and goes outside left edge of canvas?\n\t\tif (orf(model.x)) {\n\t\t\txAlign = 'center';\n\t\t\tyAlign = yf(model.y);\n\t\t}\n\t}\n\n\tvar opts = tooltip._options;\n\treturn {\n\t\txAlign: opts.xAlign ? opts.xAlign : xAlign,\n\t\tyAlign: opts.yAlign ? opts.yAlign : yAlign\n\t};\n}\n\n/**\n * Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment\n */\nfunction getBackgroundPoint(vm, size, alignment, chart) {\n\t// Background Position\n\tvar x = vm.x;\n\tvar y = vm.y;\n\n\tvar caretSize = vm.caretSize;\n\tvar caretPadding = vm.caretPadding;\n\tvar cornerRadius = vm.cornerRadius;\n\tvar xAlign = alignment.xAlign;\n\tvar yAlign = alignment.yAlign;\n\tvar paddingAndSize = caretSize + caretPadding;\n\tvar radiusAndPadding = cornerRadius + caretPadding;\n\n\tif (xAlign === 'right') {\n\t\tx -= size.width;\n\t} else if (xAlign === 'center') {\n\t\tx -= (size.width / 2);\n\t\tif (x + size.width > chart.width) {\n\t\t\tx = chart.width - size.width;\n\t\t}\n\t\tif (x < 0) {\n\t\t\tx = 0;\n\t\t}\n\t}\n\n\tif (yAlign === 'top') {\n\t\ty += paddingAndSize;\n\t} else if (yAlign === 'bottom') {\n\t\ty -= size.height + paddingAndSize;\n\t} else {\n\t\ty -= (size.height / 2);\n\t}\n\n\tif (yAlign === 'center') {\n\t\tif (xAlign === 'left') {\n\t\t\tx += paddingAndSize;\n\t\t} else if (xAlign === 'right') {\n\t\t\tx -= paddingAndSize;\n\t\t}\n\t} else if (xAlign === 'left') {\n\t\tx -= radiusAndPadding;\n\t} else if (xAlign === 'right') {\n\t\tx += radiusAndPadding;\n\t}\n\n\treturn {\n\t\tx: x,\n\t\ty: y\n\t};\n}\n\n/**\n * Helper to build before and after body lines\n */\nfunction getBeforeAfterBodyLines(callback) {\n\treturn pushOrConcat([], splitNewlines(callback));\n}\n\nvar exports = module.exports = Element.extend({\n\tinitialize: function() {\n\t\tthis._model = getBaseModel(this._options);\n\t\tthis._lastActive = [];\n\t},\n\n\t// Get the title\n\t// Args are: (tooltipItem, data)\n\tgetTitle: function() {\n\t\tvar me = this;\n\t\tvar opts = me._options;\n\t\tvar callbacks = opts.callbacks;\n\n\t\tvar beforeTitle = callbacks.beforeTitle.apply(me, arguments);\n\t\tvar title = callbacks.title.apply(me, arguments);\n\t\tvar afterTitle = callbacks.afterTitle.apply(me, arguments);\n\n\t\tvar lines = [];\n\t\tlines = pushOrConcat(lines, splitNewlines(beforeTitle));\n\t\tlines = pushOrConcat(lines, splitNewlines(title));\n\t\tlines = pushOrConcat(lines, splitNewlines(afterTitle));\n\n\t\treturn lines;\n\t},\n\n\t// Args are: (tooltipItem, data)\n\tgetBeforeBody: function() {\n\t\treturn getBeforeAfterBodyLines(this._options.callbacks.beforeBody.apply(this, arguments));\n\t},\n\n\t// Args are: (tooltipItem, data)\n\tgetBody: function(tooltipItems, data) {\n\t\tvar me = this;\n\t\tvar callbacks = me._options.callbacks;\n\t\tvar bodyItems = [];\n\n\t\thelpers.each(tooltipItems, function(tooltipItem) {\n\t\t\tvar bodyItem = {\n\t\t\t\tbefore: [],\n\t\t\t\tlines: [],\n\t\t\t\tafter: []\n\t\t\t};\n\t\t\tpushOrConcat(bodyItem.before, splitNewlines(callbacks.beforeLabel.call(me, tooltipItem, data)));\n\t\t\tpushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));\n\t\t\tpushOrConcat(bodyItem.after, splitNewlines(callbacks.afterLabel.call(me, tooltipItem, data)));\n\n\t\t\tbodyItems.push(bodyItem);\n\t\t});\n\n\t\treturn bodyItems;\n\t},\n\n\t// Args are: (tooltipItem, data)\n\tgetAfterBody: function() {\n\t\treturn getBeforeAfterBodyLines(this._options.callbacks.afterBody.apply(this, arguments));\n\t},\n\n\t// Get the footer and beforeFooter and afterFooter lines\n\t// Args are: (tooltipItem, data)\n\tgetFooter: function() {\n\t\tvar me = this;\n\t\tvar callbacks = me._options.callbacks;\n\n\t\tvar beforeFooter = callbacks.beforeFooter.apply(me, arguments);\n\t\tvar footer = callbacks.footer.apply(me, arguments);\n\t\tvar afterFooter = callbacks.afterFooter.apply(me, arguments);\n\n\t\tvar lines = [];\n\t\tlines = pushOrConcat(lines, splitNewlines(beforeFooter));\n\t\tlines = pushOrConcat(lines, splitNewlines(footer));\n\t\tlines = pushOrConcat(lines, splitNewlines(afterFooter));\n\n\t\treturn lines;\n\t},\n\n\tupdate: function(changed) {\n\t\tvar me = this;\n\t\tvar opts = me._options;\n\n\t\t// Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition\n\t\t// that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time\n\t\t// which breaks any animations.\n\t\tvar existingModel = me._model;\n\t\tvar model = me._model = getBaseModel(opts);\n\t\tvar active = me._active;\n\n\t\tvar data = me._data;\n\n\t\t// In the case where active.length === 0 we need to keep these at existing values for good animations\n\t\tvar alignment = {\n\t\t\txAlign: existingModel.xAlign,\n\t\t\tyAlign: existingModel.yAlign\n\t\t};\n\t\tvar backgroundPoint = {\n\t\t\tx: existingModel.x,\n\t\t\ty: existingModel.y\n\t\t};\n\t\tvar tooltipSize = {\n\t\t\twidth: existingModel.width,\n\t\t\theight: existingModel.height\n\t\t};\n\t\tvar tooltipPosition = {\n\t\t\tx: existingModel.caretX,\n\t\t\ty: existingModel.caretY\n\t\t};\n\n\t\tvar i, len;\n\n\t\tif (active.length) {\n\t\t\tmodel.opacity = 1;\n\n\t\t\tvar labelColors = [];\n\t\t\tvar labelTextColors = [];\n\t\t\ttooltipPosition = positioners[opts.position].call(me, active, me._eventPosition);\n\n\t\t\tvar tooltipItems = [];\n\t\t\tfor (i = 0, len = active.length; i < len; ++i) {\n\t\t\t\ttooltipItems.push(createTooltipItem(active[i]));\n\t\t\t}\n\n\t\t\t// If the user provided a filter function, use it to modify the tooltip items\n\t\t\tif (opts.filter) {\n\t\t\t\ttooltipItems = tooltipItems.filter(function(a) {\n\t\t\t\t\treturn opts.filter(a, data);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// If the user provided a sorting function, use it to modify the tooltip items\n\t\t\tif (opts.itemSort) {\n\t\t\t\ttooltipItems = tooltipItems.sort(function(a, b) {\n\t\t\t\t\treturn opts.itemSort(a, b, data);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Determine colors for boxes\n\t\t\thelpers.each(tooltipItems, function(tooltipItem) {\n\t\t\t\tlabelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart));\n\t\t\t\tlabelTextColors.push(opts.callbacks.labelTextColor.call(me, tooltipItem, me._chart));\n\t\t\t});\n\n\n\t\t\t// Build the Text Lines\n\t\t\tmodel.title = me.getTitle(tooltipItems, data);\n\t\t\tmodel.beforeBody = me.getBeforeBody(tooltipItems, data);\n\t\t\tmodel.body = me.getBody(tooltipItems, data);\n\t\t\tmodel.afterBody = me.getAfterBody(tooltipItems, data);\n\t\t\tmodel.footer = me.getFooter(tooltipItems, data);\n\n\t\t\t// Initial positioning and colors\n\t\t\tmodel.x = Math.round(tooltipPosition.x);\n\t\t\tmodel.y = Math.round(tooltipPosition.y);\n\t\t\tmodel.caretPadding = opts.caretPadding;\n\t\t\tmodel.labelColors = labelColors;\n\t\t\tmodel.labelTextColors = labelTextColors;\n\n\t\t\t// data points\n\t\t\tmodel.dataPoints = tooltipItems;\n\n\t\t\t// We need to determine alignment of the tooltip\n\t\t\ttooltipSize = getTooltipSize(this, model);\n\t\t\talignment = determineAlignment(this, tooltipSize);\n\t\t\t// Final Size and Position\n\t\t\tbackgroundPoint = getBackgroundPoint(model, tooltipSize, alignment, me._chart);\n\t\t} else {\n\t\t\tmodel.opacity = 0;\n\t\t}\n\n\t\tmodel.xAlign = alignment.xAlign;\n\t\tmodel.yAlign = alignment.yAlign;\n\t\tmodel.x = backgroundPoint.x;\n\t\tmodel.y = backgroundPoint.y;\n\t\tmodel.width = tooltipSize.width;\n\t\tmodel.height = tooltipSize.height;\n\n\t\t// Point where the caret on the tooltip points to\n\t\tmodel.caretX = tooltipPosition.x;\n\t\tmodel.caretY = tooltipPosition.y;\n\n\t\tme._model = model;\n\n\t\tif (changed && opts.custom) {\n\t\t\topts.custom.call(me, model);\n\t\t}\n\n\t\treturn me;\n\t},\n\n\tdrawCaret: function(tooltipPoint, size) {\n\t\tvar ctx = this._chart.ctx;\n\t\tvar vm = this._view;\n\t\tvar caretPosition = this.getCaretPosition(tooltipPoint, size, vm);\n\n\t\tctx.lineTo(caretPosition.x1, caretPosition.y1);\n\t\tctx.lineTo(caretPosition.x2, caretPosition.y2);\n\t\tctx.lineTo(caretPosition.x3, caretPosition.y3);\n\t},\n\tgetCaretPosition: function(tooltipPoint, size, vm) {\n\t\tvar x1, x2, x3, y1, y2, y3;\n\t\tvar caretSize = vm.caretSize;\n\t\tvar cornerRadius = vm.cornerRadius;\n\t\tvar xAlign = vm.xAlign;\n\t\tvar yAlign = vm.yAlign;\n\t\tvar ptX = tooltipPoint.x;\n\t\tvar ptY = tooltipPoint.y;\n\t\tvar width = size.width;\n\t\tvar height = size.height;\n\n\t\tif (yAlign === 'center') {\n\t\t\ty2 = ptY + (height / 2);\n\n\t\t\tif (xAlign === 'left') {\n\t\t\t\tx1 = ptX;\n\t\t\t\tx2 = x1 - caretSize;\n\t\t\t\tx3 = x1;\n\n\t\t\t\ty1 = y2 + caretSize;\n\t\t\t\ty3 = y2 - caretSize;\n\t\t\t} else {\n\t\t\t\tx1 = ptX + width;\n\t\t\t\tx2 = x1 + caretSize;\n\t\t\t\tx3 = x1;\n\n\t\t\t\ty1 = y2 - caretSize;\n\t\t\t\ty3 = y2 + caretSize;\n\t\t\t}\n\t\t} else {\n\t\t\tif (xAlign === 'left') {\n\t\t\t\tx2 = ptX + cornerRadius + (caretSize);\n\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\tx3 = x2 + caretSize;\n\t\t\t} else if (xAlign === 'right') {\n\t\t\t\tx2 = ptX + width - cornerRadius - caretSize;\n\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\tx3 = x2 + caretSize;\n\t\t\t} else {\n\t\t\t\tx2 = vm.caretX;\n\t\t\t\tx1 = x2 - caretSize;\n\t\t\t\tx3 = x2 + caretSize;\n\t\t\t}\n\t\t\tif (yAlign === 'top') {\n\t\t\t\ty1 = ptY;\n\t\t\t\ty2 = y1 - caretSize;\n\t\t\t\ty3 = y1;\n\t\t\t} else {\n\t\t\t\ty1 = ptY + height;\n\t\t\t\ty2 = y1 + caretSize;\n\t\t\t\ty3 = y1;\n\t\t\t\t// invert drawing order\n\t\t\t\tvar tmp = x3;\n\t\t\t\tx3 = x1;\n\t\t\t\tx1 = tmp;\n\t\t\t}\n\t\t}\n\t\treturn {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};\n\t},\n\n\tdrawTitle: function(pt, vm, ctx, opacity) {\n\t\tvar title = vm.title;\n\n\t\tif (title.length) {\n\t\t\tctx.textAlign = vm._titleAlign;\n\t\t\tctx.textBaseline = 'top';\n\n\t\t\tvar titleFontSize = vm.titleFontSize;\n\t\t\tvar titleSpacing = vm.titleSpacing;\n\n\t\t\tctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);\n\t\t\tctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);\n\n\t\t\tvar i, len;\n\t\t\tfor (i = 0, len = title.length; i < len; ++i) {\n\t\t\t\tctx.fillText(title[i], pt.x, pt.y);\n\t\t\t\tpt.y += titleFontSize + titleSpacing; // Line Height and spacing\n\n\t\t\t\tif (i + 1 === title.length) {\n\t\t\t\t\tpt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tdrawBody: function(pt, vm, ctx, opacity) {\n\t\tvar bodyFontSize = vm.bodyFontSize;\n\t\tvar bodySpacing = vm.bodySpacing;\n\t\tvar body = vm.body;\n\n\t\tctx.textAlign = vm._bodyAlign;\n\t\tctx.textBaseline = 'top';\n\t\tctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);\n\n\t\t// Before Body\n\t\tvar xLinePadding = 0;\n\t\tvar fillLineOfText = function(line) {\n\t\t\tctx.fillText(line, pt.x + xLinePadding, pt.y);\n\t\t\tpt.y += bodyFontSize + bodySpacing;\n\t\t};\n\n\t\t// Before body lines\n\t\tctx.fillStyle = mergeOpacity(vm.bodyFontColor, opacity);\n\t\thelpers.each(vm.beforeBody, fillLineOfText);\n\n\t\tvar drawColorBoxes = vm.displayColors;\n\t\txLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;\n\n\t\t// Draw body lines now\n\t\thelpers.each(body, function(bodyItem, i) {\n\t\t\tvar textColor = mergeOpacity(vm.labelTextColors[i], opacity);\n\t\t\tctx.fillStyle = textColor;\n\t\t\thelpers.each(bodyItem.before, fillLineOfText);\n\n\t\t\thelpers.each(bodyItem.lines, function(line) {\n\t\t\t\t// Draw Legend-like boxes if needed\n\t\t\t\tif (drawColorBoxes) {\n\t\t\t\t\t// Fill a white rect so that colours merge nicely if the opacity is < 1\n\t\t\t\t\tctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);\n\t\t\t\t\tctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\n\n\t\t\t\t\t// Border\n\t\t\t\t\tctx.lineWidth = 1;\n\t\t\t\t\tctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);\n\t\t\t\t\tctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);\n\n\t\t\t\t\t// Inner square\n\t\t\t\t\tctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);\n\t\t\t\t\tctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);\n\t\t\t\t\tctx.fillStyle = textColor;\n\t\t\t\t}\n\n\t\t\t\tfillLineOfText(line);\n\t\t\t});\n\n\t\t\thelpers.each(bodyItem.after, fillLineOfText);\n\t\t});\n\n\t\t// Reset back to 0 for after body\n\t\txLinePadding = 0;\n\n\t\t// After body lines\n\t\thelpers.each(vm.afterBody, fillLineOfText);\n\t\tpt.y -= bodySpacing; // Remove last body spacing\n\t},\n\n\tdrawFooter: function(pt, vm, ctx, opacity) {\n\t\tvar footer = vm.footer;\n\n\t\tif (footer.length) {\n\t\t\tpt.y += vm.footerMarginTop;\n\n\t\t\tctx.textAlign = vm._footerAlign;\n\t\t\tctx.textBaseline = 'top';\n\n\t\t\tctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);\n\t\t\tctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);\n\n\t\t\thelpers.each(footer, function(line) {\n\t\t\t\tctx.fillText(line, pt.x, pt.y);\n\t\t\t\tpt.y += vm.footerFontSize + vm.footerSpacing;\n\t\t\t});\n\t\t}\n\t},\n\n\tdrawBackground: function(pt, vm, ctx, tooltipSize, opacity) {\n\t\tctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);\n\t\tctx.strokeStyle = mergeOpacity(vm.borderColor, opacity);\n\t\tctx.lineWidth = vm.borderWidth;\n\t\tvar xAlign = vm.xAlign;\n\t\tvar yAlign = vm.yAlign;\n\t\tvar x = pt.x;\n\t\tvar y = pt.y;\n\t\tvar width = tooltipSize.width;\n\t\tvar height = tooltipSize.height;\n\t\tvar radius = vm.cornerRadius;\n\n\t\tctx.beginPath();\n\t\tctx.moveTo(x + radius, y);\n\t\tif (yAlign === 'top') {\n\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t}\n\t\tctx.lineTo(x + width - radius, y);\n\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n\t\tif (yAlign === 'center' && xAlign === 'right') {\n\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t}\n\t\tctx.lineTo(x + width, y + height - radius);\n\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n\t\tif (yAlign === 'bottom') {\n\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t}\n\t\tctx.lineTo(x + radius, y + height);\n\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n\t\tif (yAlign === 'center' && xAlign === 'left') {\n\t\t\tthis.drawCaret(pt, tooltipSize);\n\t\t}\n\t\tctx.lineTo(x, y + radius);\n\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t\tctx.closePath();\n\n\t\tctx.fill();\n\n\t\tif (vm.borderWidth > 0) {\n\t\t\tctx.stroke();\n\t\t}\n\t},\n\n\tdraw: function() {\n\t\tvar ctx = this._chart.ctx;\n\t\tvar vm = this._view;\n\n\t\tif (vm.opacity === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar tooltipSize = {\n\t\t\twidth: vm.width,\n\t\t\theight: vm.height\n\t\t};\n\t\tvar pt = {\n\t\t\tx: vm.x,\n\t\t\ty: vm.y\n\t\t};\n\n\t\t// IE11/Edge does not like very small opacities, so snap to 0\n\t\tvar opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;\n\n\t\t// Truthy/falsey value for empty tooltip\n\t\tvar hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;\n\n\t\tif (this._options.enabled && hasTooltipContent) {\n\t\t\t// Draw Background\n\t\t\tthis.drawBackground(pt, vm, ctx, tooltipSize, opacity);\n\n\t\t\t// Draw Title, Body, and Footer\n\t\t\tpt.x += vm.xPadding;\n\t\t\tpt.y += vm.yPadding;\n\n\t\t\t// Titles\n\t\t\tthis.drawTitle(pt, vm, ctx, opacity);\n\n\t\t\t// Body\n\t\t\tthis.drawBody(pt, vm, ctx, opacity);\n\n\t\t\t// Footer\n\t\t\tthis.drawFooter(pt, vm, ctx, opacity);\n\t\t}\n\t},\n\n\t/**\n\t * Handle an event\n\t * @private\n\t * @param {IEvent} event - The event to handle\n\t * @returns {Boolean} true if the tooltip changed\n\t */\n\thandleEvent: function(e) {\n\t\tvar me = this;\n\t\tvar options = me._options;\n\t\tvar changed = false;\n\n\t\tme._lastActive = me._lastActive || [];\n\n\t\t// Find Active Elements for tooltips\n\t\tif (e.type === 'mouseout') {\n\t\t\tme._active = [];\n\t\t} else {\n\t\t\tme._active = me._chart.getElementsAtEventForMode(e, options.mode, options);\n\t\t}\n\n\t\t// Remember Last Actives\n\t\tchanged = !helpers.arrayEquals(me._active, me._lastActive);\n\n\t\t// Only handle target event on tooltip change\n\t\tif (changed) {\n\t\t\tme._lastActive = me._active;\n\n\t\t\tif (options.enabled || options.custom) {\n\t\t\t\tme._eventPosition = {\n\t\t\t\t\tx: e.x,\n\t\t\t\t\ty: e.y\n\t\t\t\t};\n\n\t\t\t\tme.update(true);\n\t\t\t\tme.pivot();\n\t\t\t}\n\t\t}\n\n\t\treturn changed;\n\t}\n});\n\n/**\n * @namespace Chart.Tooltip.positioners\n */\nexports.positioners = positioners;\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWFmOS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLnRvb2x0aXAuanM/YzdjYiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4vY29yZS5kZWZhdWx0cycpO1xudmFyIEVsZW1lbnQgPSByZXF1aXJlKCcuL2NvcmUuZWxlbWVudCcpO1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2luZGV4Jyk7XG5cbmRlZmF1bHRzLl9zZXQoJ2dsb2JhbCcsIHtcblx0dG9vbHRpcHM6IHtcblx0XHRlbmFibGVkOiB0cnVlLFxuXHRcdGN1c3RvbTogbnVsbCxcblx0XHRtb2RlOiAnbmVhcmVzdCcsXG5cdFx0cG9zaXRpb246ICdhdmVyYWdlJyxcblx0XHRpbnRlcnNlY3Q6IHRydWUsXG5cdFx0YmFja2dyb3VuZENvbG9yOiAncmdiYSgwLDAsMCwwLjgpJyxcblx0XHR0aXRsZUZvbnRTdHlsZTogJ2JvbGQnLFxuXHRcdHRpdGxlU3BhY2luZzogMixcblx0XHR0aXRsZU1hcmdpbkJvdHRvbTogNixcblx0XHR0aXRsZUZvbnRDb2xvcjogJyNmZmYnLFxuXHRcdHRpdGxlQWxpZ246ICdsZWZ0Jyxcblx0XHRib2R5U3BhY2luZzogMixcblx0XHRib2R5Rm9udENvbG9yOiAnI2ZmZicsXG5cdFx0Ym9keUFsaWduOiAnbGVmdCcsXG5cdFx0Zm9vdGVyRm9udFN0eWxlOiAnYm9sZCcsXG5cdFx0Zm9vdGVyU3BhY2luZzogMixcblx0XHRmb290ZXJNYXJnaW5Ub3A6IDYsXG5cdFx0Zm9vdGVyRm9udENvbG9yOiAnI2ZmZicsXG5cdFx0Zm9vdGVyQWxpZ246ICdsZWZ0Jyxcblx0XHR5UGFkZGluZzogNixcblx0XHR4UGFkZGluZzogNixcblx0XHRjYXJldFBhZGRpbmc6IDIsXG5cdFx0Y2FyZXRTaXplOiA1LFxuXHRcdGNvcm5lclJhZGl1czogNixcblx0XHRtdWx0aUtleUJhY2tncm91bmQ6ICcjZmZmJyxcblx0XHRkaXNwbGF5Q29sb3JzOiB0cnVlLFxuXHRcdGJvcmRlckNvbG9yOiAncmdiYSgwLDAsMCwwKScsXG5cdFx0Ym9yZGVyV2lkdGg6IDAsXG5cdFx0Y2FsbGJhY2tzOiB7XG5cdFx0XHQvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtcywgZGF0YSlcblx0XHRcdGJlZm9yZVRpdGxlOiBoZWxwZXJzLm5vb3AsXG5cdFx0XHR0aXRsZTogZnVuY3Rpb24odG9vbHRpcEl0ZW1zLCBkYXRhKSB7XG5cdFx0XHRcdC8vIFBpY2sgZmlyc3QgeExhYmVsIGZvciBub3dcblx0XHRcdFx0dmFyIHRpdGxlID0gJyc7XG5cdFx0XHRcdHZhciBsYWJlbHMgPSBkYXRhLmxhYmVscztcblx0XHRcdFx0dmFyIGxhYmVsQ291bnQgPSBsYWJlbHMgPyBsYWJlbHMubGVuZ3RoIDogMDtcblxuXHRcdFx0XHRpZiAodG9vbHRpcEl0ZW1zLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHR2YXIgaXRlbSA9IHRvb2x0aXBJdGVtc1swXTtcblxuXHRcdFx0XHRcdGlmIChpdGVtLnhMYWJlbCkge1xuXHRcdFx0XHRcdFx0dGl0bGUgPSBpdGVtLnhMYWJlbDtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKGxhYmVsQ291bnQgPiAwICYmIGl0ZW0uaW5kZXggPCBsYWJlbENvdW50KSB7XG5cdFx0XHRcdFx0XHR0aXRsZSA9IGxhYmVsc1tpdGVtLmluZGV4XTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gdGl0bGU7XG5cdFx0XHR9LFxuXHRcdFx0YWZ0ZXJUaXRsZTogaGVscGVycy5ub29wLFxuXG5cdFx0XHQvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtcywgZGF0YSlcblx0XHRcdGJlZm9yZUJvZHk6IGhlbHBlcnMubm9vcCxcblxuXHRcdFx0Ly8gQXJncyBhcmU6ICh0b29sdGlwSXRlbSwgZGF0YSlcblx0XHRcdGJlZm9yZUxhYmVsOiBoZWxwZXJzLm5vb3AsXG5cdFx0XHRsYWJlbDogZnVuY3Rpb24odG9vbHRpcEl0ZW0sIGRhdGEpIHtcblx0XHRcdFx0dmFyIGxhYmVsID0gZGF0YS5kYXRhc2V0c1t0b29sdGlwSXRlbS5kYXRhc2V0SW5kZXhdLmxhYmVsIHx8ICcnO1xuXG5cdFx0XHRcdGlmIChsYWJlbCkge1xuXHRcdFx0XHRcdGxhYmVsICs9ICc6ICc7XG5cdFx0XHRcdH1cblx0XHRcdFx0bGFiZWwgKz0gdG9vbHRpcEl0ZW0ueUxhYmVsO1xuXHRcdFx0XHRyZXR1cm4gbGFiZWw7XG5cdFx0XHR9LFxuXHRcdFx0bGFiZWxDb2xvcjogZnVuY3Rpb24odG9vbHRpcEl0ZW0sIGNoYXJ0KSB7XG5cdFx0XHRcdHZhciBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEodG9vbHRpcEl0ZW0uZGF0YXNldEluZGV4KTtcblx0XHRcdFx0dmFyIGFjdGl2ZUVsZW1lbnQgPSBtZXRhLmRhdGFbdG9vbHRpcEl0ZW0uaW5kZXhdO1xuXHRcdFx0XHR2YXIgdmlldyA9IGFjdGl2ZUVsZW1lbnQuX3ZpZXc7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0Ym9yZGVyQ29sb3I6IHZpZXcuYm9yZGVyQ29sb3IsXG5cdFx0XHRcdFx0YmFja2dyb3VuZENvbG9yOiB2aWV3LmJhY2tncm91bmRDb2xvclxuXHRcdFx0XHR9O1xuXHRcdFx0fSxcblx0XHRcdGxhYmVsVGV4dENvbG9yOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuIHRoaXMuX29wdGlvbnMuYm9keUZvbnRDb2xvcjtcblx0XHRcdH0sXG5cdFx0XHRhZnRlckxhYmVsOiBoZWxwZXJzLm5vb3AsXG5cblx0XHRcdC8vIEFyZ3MgYXJlOiAodG9vbHRpcEl0ZW1zLCBkYXRhKVxuXHRcdFx0YWZ0ZXJCb2R5OiBoZWxwZXJzLm5vb3AsXG5cblx0XHRcdC8vIEFyZ3MgYXJlOiAodG9vbHRpcEl0ZW1zLCBkYXRhKVxuXHRcdFx0YmVmb3JlRm9vdGVyOiBoZWxwZXJzLm5vb3AsXG5cdFx0XHRmb290ZXI6IGhlbHBlcnMubm9vcCxcblx0XHRcdGFmdGVyRm9vdGVyOiBoZWxwZXJzLm5vb3Bcblx0XHR9XG5cdH1cbn0pO1xuXG52YXIgcG9zaXRpb25lcnMgPSB7XG5cdC8qKlxuXHQgKiBBdmVyYWdlIG1vZGUgcGxhY2VzIHRoZSB0b29sdGlwIGF0IHRoZSBhdmVyYWdlIHBvc2l0aW9uIG9mIHRoZSBlbGVtZW50cyBzaG93blxuXHQgKiBAZnVuY3Rpb24gQ2hhcnQuVG9vbHRpcC5wb3NpdGlvbmVycy5hdmVyYWdlXG5cdCAqIEBwYXJhbSBlbGVtZW50cyB7Q2hhcnRFbGVtZW50W119IHRoZSBlbGVtZW50cyBiZWluZyBkaXNwbGF5ZWQgaW4gdGhlIHRvb2x0aXBcblx0ICogQHJldHVybnMge1BvaW50fSB0b29sdGlwIHBvc2l0aW9uXG5cdCAqL1xuXHRhdmVyYWdlOiBmdW5jdGlvbihlbGVtZW50cykge1xuXHRcdGlmICghZWxlbWVudHMubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dmFyIGksIGxlbjtcblx0XHR2YXIgeCA9IDA7XG5cdFx0dmFyIHkgPSAwO1xuXHRcdHZhciBjb3VudCA9IDA7XG5cblx0XHRmb3IgKGkgPSAwLCBsZW4gPSBlbGVtZW50cy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuXHRcdFx0dmFyIGVsID0gZWxlbWVudHNbaV07XG5cdFx0XHRpZiAoZWwgJiYgZWwuaGFzVmFsdWUoKSkge1xuXHRcdFx0XHR2YXIgcG9zID0gZWwudG9vbHRpcFBvc2l0aW9uKCk7XG5cdFx0XHRcdHggKz0gcG9zLng7XG5cdFx0XHRcdHkgKz0gcG9zLnk7XG5cdFx0XHRcdCsrY291bnQ7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHtcblx0XHRcdHg6IE1hdGgucm91bmQoeCAvIGNvdW50KSxcblx0XHRcdHk6IE1hdGgucm91bmQoeSAvIGNvdW50KVxuXHRcdH07XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHRvb2x0aXAgcG9zaXRpb24gbmVhcmVzdCBvZiB0aGUgaXRlbSBuZWFyZXN0IHRvIHRoZSBldmVudCBwb3NpdGlvblxuXHQgKiBAZnVuY3Rpb24gQ2hhcnQuVG9vbHRpcC5wb3NpdGlvbmVycy5uZWFyZXN0XG5cdCAqIEBwYXJhbSBlbGVtZW50cyB7Q2hhcnQuRWxlbWVudFtdfSB0aGUgdG9vbHRpcCBlbGVtZW50c1xuXHQgKiBAcGFyYW0gZXZlbnRQb3NpdGlvbiB7UG9pbnR9IHRoZSBwb3NpdGlvbiBvZiB0aGUgZXZlbnQgaW4gY2FudmFzIGNvb3JkaW5hdGVzXG5cdCAqIEByZXR1cm5zIHtQb2ludH0gdGhlIHRvb2x0aXAgcG9zaXRpb25cblx0ICovXG5cdG5lYXJlc3Q6IGZ1bmN0aW9uKGVsZW1lbnRzLCBldmVudFBvc2l0aW9uKSB7XG5cdFx0dmFyIHggPSBldmVudFBvc2l0aW9uLng7XG5cdFx0dmFyIHkgPSBldmVudFBvc2l0aW9uLnk7XG5cdFx0dmFyIG1pbkRpc3RhbmNlID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuXHRcdHZhciBpLCBsZW4sIG5lYXJlc3RFbGVtZW50O1xuXG5cdFx0Zm9yIChpID0gMCwgbGVuID0gZWxlbWVudHMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcblx0XHRcdHZhciBlbCA9IGVsZW1lbnRzW2ldO1xuXHRcdFx0aWYgKGVsICYmIGVsLmhhc1ZhbHVlKCkpIHtcblx0XHRcdFx0dmFyIGNlbnRlciA9IGVsLmdldENlbnRlclBvaW50KCk7XG5cdFx0XHRcdHZhciBkID0gaGVscGVycy5kaXN0YW5jZUJldHdlZW5Qb2ludHMoZXZlbnRQb3NpdGlvbiwgY2VudGVyKTtcblxuXHRcdFx0XHRpZiAoZCA8IG1pbkRpc3RhbmNlKSB7XG5cdFx0XHRcdFx0bWluRGlzdGFuY2UgPSBkO1xuXHRcdFx0XHRcdG5lYXJlc3RFbGVtZW50ID0gZWw7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAobmVhcmVzdEVsZW1lbnQpIHtcblx0XHRcdHZhciB0cCA9IG5lYXJlc3RFbGVtZW50LnRvb2x0aXBQb3NpdGlvbigpO1xuXHRcdFx0eCA9IHRwLng7XG5cdFx0XHR5ID0gdHAueTtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0eDogeCxcblx0XHRcdHk6IHlcblx0XHR9O1xuXHR9XG59O1xuXG4vKipcbiAqIEhlbHBlciBtZXRob2QgdG8gbWVyZ2UgdGhlIG9wYWNpdHkgaW50byBhIGNvbG9yXG4gKi9cbmZ1bmN0aW9uIG1lcmdlT3BhY2l0eShjb2xvclN0cmluZywgb3BhY2l0eSkge1xuXHR2YXIgY29sb3IgPSBoZWxwZXJzLmNvbG9yKGNvbG9yU3RyaW5nKTtcblx0cmV0dXJuIGNvbG9yLmFscGhhKG9wYWNpdHkgKiBjb2xvci5hbHBoYSgpKS5yZ2JhU3RyaW5nKCk7XG59XG5cbi8vIEhlbHBlciB0byBwdXNoIG9yIGNvbmNhdCBiYXNlZCBvbiBpZiB0aGUgMm5kIHBhcmFtZXRlciBpcyBhbiBhcnJheSBvciBub3RcbmZ1bmN0aW9uIHB1c2hPckNvbmNhdChiYXNlLCB0b1B1c2gpIHtcblx0aWYgKHRvUHVzaCkge1xuXHRcdGlmIChoZWxwZXJzLmlzQXJyYXkodG9QdXNoKSkge1xuXHRcdFx0Ly8gYmFzZSA9IGJhc2UuY29uY2F0KHRvUHVzaCk7XG5cdFx0XHRBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShiYXNlLCB0b1B1c2gpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRiYXNlLnB1c2godG9QdXNoKTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gYmFzZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFycmF5IG9mIHN0cmluZ3Mgc3BsaXQgYnkgbmV3bGluZVxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIHNwbGl0IGJ5IG5ld2xpbmUuXG4gKiBAcmV0dXJucyB7QXJyYXl9IHZhbHVlIGlmIG5ld2xpbmUgcHJlc2VudCAtIFJldHVybmVkIGZyb20gU3RyaW5nIHNwbGl0KCkgbWV0aG9kXG4gKiBAZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gc3BsaXROZXdsaW5lcyhzdHIpIHtcblx0aWYgKCh0eXBlb2Ygc3RyID09PSAnc3RyaW5nJyB8fCBzdHIgaW5zdGFuY2VvZiBTdHJpbmcpICYmIHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG5cdFx0cmV0dXJuIHN0ci5zcGxpdCgnXFxuJyk7XG5cdH1cblx0cmV0dXJuIHN0cjtcbn1cblxuXG4vLyBQcml2YXRlIGhlbHBlciB0byBjcmVhdGUgYSB0b29sdGlwIGl0ZW0gbW9kZWxcbi8vIEBwYXJhbSBlbGVtZW50IDogdGhlIGNoYXJ0IGVsZW1lbnQgKHBvaW50LCBhcmMsIGJhcikgdG8gY3JlYXRlIHRoZSB0b29sdGlwIGl0ZW0gZm9yXG4vLyBAcmV0dXJuIDogbmV3IHRvb2x0aXAgaXRlbVxuZnVuY3Rpb24gY3JlYXRlVG9vbHRpcEl0ZW0oZWxlbWVudCkge1xuXHR2YXIgeFNjYWxlID0gZWxlbWVudC5feFNjYWxlO1xuXHR2YXIgeVNjYWxlID0gZWxlbWVudC5feVNjYWxlIHx8IGVsZW1lbnQuX3NjYWxlOyAvLyBoYW5kbGUgcmFkYXIgfHwgcG9sYXJBcmVhIGNoYXJ0c1xuXHR2YXIgaW5kZXggPSBlbGVtZW50Ll9pbmRleDtcblx0dmFyIGRhdGFzZXRJbmRleCA9IGVsZW1lbnQuX2RhdGFzZXRJbmRleDtcblxuXHRyZXR1cm4ge1xuXHRcdHhMYWJlbDogeFNjYWxlID8geFNjYWxlLmdldExhYmVsRm9ySW5kZXgoaW5kZXgsIGRhdGFzZXRJbmRleCkgOiAnJyxcblx0XHR5TGFiZWw6IHlTY2FsZSA/IHlTY2FsZS5nZXRMYWJlbEZvckluZGV4KGluZGV4LCBkYXRhc2V0SW5kZXgpIDogJycsXG5cdFx0aW5kZXg6IGluZGV4LFxuXHRcdGRhdGFzZXRJbmRleDogZGF0YXNldEluZGV4LFxuXHRcdHg6IGVsZW1lbnQuX21vZGVsLngsXG5cdFx0eTogZWxlbWVudC5fbW9kZWwueVxuXHR9O1xufVxuXG4vKipcbiAqIEhlbHBlciB0byBnZXQgdGhlIHJlc2V0IG1vZGVsIGZvciB0aGUgdG9vbHRpcFxuICogQHBhcmFtIHRvb2x0aXBPcHRzIHtPYmplY3R9IHRoZSB0b29sdGlwIG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gZ2V0QmFzZU1vZGVsKHRvb2x0aXBPcHRzKSB7XG5cdHZhciBnbG9iYWxEZWZhdWx0cyA9IGRlZmF1bHRzLmdsb2JhbDtcblx0dmFyIHZhbHVlT3JEZWZhdWx0ID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdDtcblxuXHRyZXR1cm4ge1xuXHRcdC8vIFBvc2l0aW9uaW5nXG5cdFx0eFBhZGRpbmc6IHRvb2x0aXBPcHRzLnhQYWRkaW5nLFxuXHRcdHlQYWRkaW5nOiB0b29sdGlwT3B0cy55UGFkZGluZyxcblx0XHR4QWxpZ246IHRvb2x0aXBPcHRzLnhBbGlnbixcblx0XHR5QWxpZ246IHRvb2x0aXBPcHRzLnlBbGlnbixcblxuXHRcdC8vIEJvZHlcblx0XHRib2R5Rm9udENvbG9yOiB0b29sdGlwT3B0cy5ib2R5Rm9udENvbG9yLFxuXHRcdF9ib2R5Rm9udEZhbWlseTogdmFsdWVPckRlZmF1bHQodG9vbHRpcE9wdHMuYm9keUZvbnRGYW1pbHksIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250RmFtaWx5KSxcblx0XHRfYm9keUZvbnRTdHlsZTogdmFsdWVPckRlZmF1bHQodG9vbHRpcE9wdHMuYm9keUZvbnRTdHlsZSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRTdHlsZSksXG5cdFx0X2JvZHlBbGlnbjogdG9vbHRpcE9wdHMuYm9keUFsaWduLFxuXHRcdGJvZHlGb250U2l6ZTogdmFsdWVPckRlZmF1bHQodG9vbHRpcE9wdHMuYm9keUZvbnRTaXplLCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udFNpemUpLFxuXHRcdGJvZHlTcGFjaW5nOiB0b29sdGlwT3B0cy5ib2R5U3BhY2luZyxcblxuXHRcdC8vIFRpdGxlXG5cdFx0dGl0bGVGb250Q29sb3I6IHRvb2x0aXBPcHRzLnRpdGxlRm9udENvbG9yLFxuXHRcdF90aXRsZUZvbnRGYW1pbHk6IHZhbHVlT3JEZWZhdWx0KHRvb2x0aXBPcHRzLnRpdGxlRm9udEZhbWlseSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRGYW1pbHkpLFxuXHRcdF90aXRsZUZvbnRTdHlsZTogdmFsdWVPckRlZmF1bHQodG9vbHRpcE9wdHMudGl0bGVGb250U3R5bGUsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250U3R5bGUpLFxuXHRcdHRpdGxlRm9udFNpemU6IHZhbHVlT3JEZWZhdWx0KHRvb2x0aXBPcHRzLnRpdGxlRm9udFNpemUsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250U2l6ZSksXG5cdFx0X3RpdGxlQWxpZ246IHRvb2x0aXBPcHRzLnRpdGxlQWxpZ24sXG5cdFx0dGl0bGVTcGFjaW5nOiB0b29sdGlwT3B0cy50aXRsZVNwYWNpbmcsXG5cdFx0dGl0bGVNYXJnaW5Cb3R0b206IHRvb2x0aXBPcHRzLnRpdGxlTWFyZ2luQm90dG9tLFxuXG5cdFx0Ly8gRm9vdGVyXG5cdFx0Zm9vdGVyRm9udENvbG9yOiB0b29sdGlwT3B0cy5mb290ZXJGb250Q29sb3IsXG5cdFx0X2Zvb3RlckZvbnRGYW1pbHk6IHZhbHVlT3JEZWZhdWx0KHRvb2x0aXBPcHRzLmZvb3RlckZvbnRGYW1pbHksIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250RmFtaWx5KSxcblx0XHRfZm9vdGVyRm9udFN0eWxlOiB2YWx1ZU9yRGVmYXVsdCh0b29sdGlwT3B0cy5mb290ZXJGb250U3R5bGUsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250U3R5bGUpLFxuXHRcdGZvb3RlckZvbnRTaXplOiB2YWx1ZU9yRGVmYXVsdCh0b29sdGlwT3B0cy5mb290ZXJGb250U2l6ZSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRTaXplKSxcblx0XHRfZm9vdGVyQWxpZ246IHRvb2x0aXBPcHRzLmZvb3RlckFsaWduLFxuXHRcdGZvb3RlclNwYWNpbmc6IHRvb2x0aXBPcHRzLmZvb3RlclNwYWNpbmcsXG5cdFx0Zm9vdGVyTWFyZ2luVG9wOiB0b29sdGlwT3B0cy5mb290ZXJNYXJnaW5Ub3AsXG5cblx0XHQvLyBBcHBlYXJhbmNlXG5cdFx0Y2FyZXRTaXplOiB0b29sdGlwT3B0cy5jYXJldFNpemUsXG5cdFx0Y29ybmVyUmFkaXVzOiB0b29sdGlwT3B0cy5jb3JuZXJSYWRpdXMsXG5cdFx0YmFja2dyb3VuZENvbG9yOiB0b29sdGlwT3B0cy5iYWNrZ3JvdW5kQ29sb3IsXG5cdFx0b3BhY2l0eTogMCxcblx0XHRsZWdlbmRDb2xvckJhY2tncm91bmQ6IHRvb2x0aXBPcHRzLm11bHRpS2V5QmFja2dyb3VuZCxcblx0XHRkaXNwbGF5Q29sb3JzOiB0b29sdGlwT3B0cy5kaXNwbGF5Q29sb3JzLFxuXHRcdGJvcmRlckNvbG9yOiB0b29sdGlwT3B0cy5ib3JkZXJDb2xvcixcblx0XHRib3JkZXJXaWR0aDogdG9vbHRpcE9wdHMuYm9yZGVyV2lkdGhcblx0fTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHNpemUgb2YgdGhlIHRvb2x0aXBcbiAqL1xuZnVuY3Rpb24gZ2V0VG9vbHRpcFNpemUodG9vbHRpcCwgbW9kZWwpIHtcblx0dmFyIGN0eCA9IHRvb2x0aXAuX2NoYXJ0LmN0eDtcblxuXHR2YXIgaGVpZ2h0ID0gbW9kZWwueVBhZGRpbmcgKiAyOyAvLyBUb29sdGlwIFBhZGRpbmdcblx0dmFyIHdpZHRoID0gMDtcblxuXHQvLyBDb3VudCBvZiBhbGwgbGluZXMgaW4gdGhlIGJvZHlcblx0dmFyIGJvZHkgPSBtb2RlbC5ib2R5O1xuXHR2YXIgY29tYmluZWRCb2R5TGVuZ3RoID0gYm9keS5yZWR1Y2UoZnVuY3Rpb24oY291bnQsIGJvZHlJdGVtKSB7XG5cdFx0cmV0dXJuIGNvdW50ICsgYm9keUl0ZW0uYmVmb3JlLmxlbmd0aCArIGJvZHlJdGVtLmxpbmVzLmxlbmd0aCArIGJvZHlJdGVtLmFmdGVyLmxlbmd0aDtcblx0fSwgMCk7XG5cdGNvbWJpbmVkQm9keUxlbmd0aCArPSBtb2RlbC5iZWZvcmVCb2R5Lmxlbmd0aCArIG1vZGVsLmFmdGVyQm9keS5sZW5ndGg7XG5cblx0dmFyIHRpdGxlTGluZUNvdW50ID0gbW9kZWwudGl0bGUubGVuZ3RoO1xuXHR2YXIgZm9vdGVyTGluZUNvdW50ID0gbW9kZWwuZm9vdGVyLmxlbmd0aDtcblx0dmFyIHRpdGxlRm9udFNpemUgPSBtb2RlbC50aXRsZUZvbnRTaXplO1xuXHR2YXIgYm9keUZvbnRTaXplID0gbW9kZWwuYm9keUZvbnRTaXplO1xuXHR2YXIgZm9vdGVyRm9udFNpemUgPSBtb2RlbC5mb290ZXJGb250U2l6ZTtcblxuXHRoZWlnaHQgKz0gdGl0bGVMaW5lQ291bnQgKiB0aXRsZUZvbnRTaXplOyAvLyBUaXRsZSBMaW5lc1xuXHRoZWlnaHQgKz0gdGl0bGVMaW5lQ291bnQgPyAodGl0bGVMaW5lQ291bnQgLSAxKSAqIG1vZGVsLnRpdGxlU3BhY2luZyA6IDA7IC8vIFRpdGxlIExpbmUgU3BhY2luZ1xuXHRoZWlnaHQgKz0gdGl0bGVMaW5lQ291bnQgPyBtb2RlbC50aXRsZU1hcmdpbkJvdHRvbSA6IDA7IC8vIFRpdGxlJ3MgYm90dG9tIE1hcmdpblxuXHRoZWlnaHQgKz0gY29tYmluZWRCb2R5TGVuZ3RoICogYm9keUZvbnRTaXplOyAvLyBCb2R5IExpbmVzXG5cdGhlaWdodCArPSBjb21iaW5lZEJvZHlMZW5ndGggPyAoY29tYmluZWRCb2R5TGVuZ3RoIC0gMSkgKiBtb2RlbC5ib2R5U3BhY2luZyA6IDA7IC8vIEJvZHkgTGluZSBTcGFjaW5nXG5cdGhlaWdodCArPSBmb290ZXJMaW5lQ291bnQgPyBtb2RlbC5mb290ZXJNYXJnaW5Ub3AgOiAwOyAvLyBGb290ZXIgTWFyZ2luXG5cdGhlaWdodCArPSBmb290ZXJMaW5lQ291bnQgKiAoZm9vdGVyRm9udFNpemUpOyAvLyBGb290ZXIgTGluZXNcblx0aGVpZ2h0ICs9IGZvb3RlckxpbmVDb3VudCA/IChmb290ZXJMaW5lQ291bnQgLSAxKSAqIG1vZGVsLmZvb3RlclNwYWNpbmcgOiAwOyAvLyBGb290ZXIgTGluZSBTcGFjaW5nXG5cblx0Ly8gVGl0bGUgd2lkdGhcblx0dmFyIHdpZHRoUGFkZGluZyA9IDA7XG5cdHZhciBtYXhMaW5lV2lkdGggPSBmdW5jdGlvbihsaW5lKSB7XG5cdFx0d2lkdGggPSBNYXRoLm1heCh3aWR0aCwgY3R4Lm1lYXN1cmVUZXh0KGxpbmUpLndpZHRoICsgd2lkdGhQYWRkaW5nKTtcblx0fTtcblxuXHRjdHguZm9udCA9IGhlbHBlcnMuZm9udFN0cmluZyh0aXRsZUZvbnRTaXplLCBtb2RlbC5fdGl0bGVGb250U3R5bGUsIG1vZGVsLl90aXRsZUZvbnRGYW1pbHkpO1xuXHRoZWxwZXJzLmVhY2gobW9kZWwudGl0bGUsIG1heExpbmVXaWR0aCk7XG5cblx0Ly8gQm9keSB3aWR0aFxuXHRjdHguZm9udCA9IGhlbHBlcnMuZm9udFN0cmluZyhib2R5Rm9udFNpemUsIG1vZGVsLl9ib2R5Rm9udFN0eWxlLCBtb2RlbC5fYm9keUZvbnRGYW1pbHkpO1xuXHRoZWxwZXJzLmVhY2gobW9kZWwuYmVmb3JlQm9keS5jb25jYXQobW9kZWwuYWZ0ZXJCb2R5KSwgbWF4TGluZVdpZHRoKTtcblxuXHQvLyBCb2R5IGxpbmVzIG1heSBpbmNsdWRlIHNvbWUgZXh0cmEgd2lkdGggZHVlIHRvIHRoZSBjb2xvciBib3hcblx0d2lkdGhQYWRkaW5nID0gbW9kZWwuZGlzcGxheUNvbG9ycyA/IChib2R5Rm9udFNpemUgKyAyKSA6IDA7XG5cdGhlbHBlcnMuZWFjaChib2R5LCBmdW5jdGlvbihib2R5SXRlbSkge1xuXHRcdGhlbHBlcnMuZWFjaChib2R5SXRlbS5iZWZvcmUsIG1heExpbmVXaWR0aCk7XG5cdFx0aGVscGVycy5lYWNoKGJvZHlJdGVtLmxpbmVzLCBtYXhMaW5lV2lkdGgpO1xuXHRcdGhlbHBlcnMuZWFjaChib2R5SXRlbS5hZnRlciwgbWF4TGluZVdpZHRoKTtcblx0fSk7XG5cblx0Ly8gUmVzZXQgYmFjayB0byAwXG5cdHdpZHRoUGFkZGluZyA9IDA7XG5cblx0Ly8gRm9vdGVyIHdpZHRoXG5cdGN0eC5mb250ID0gaGVscGVycy5mb250U3RyaW5nKGZvb3RlckZvbnRTaXplLCBtb2RlbC5fZm9vdGVyRm9udFN0eWxlLCBtb2RlbC5fZm9vdGVyRm9udEZhbWlseSk7XG5cdGhlbHBlcnMuZWFjaChtb2RlbC5mb290ZXIsIG1heExpbmVXaWR0aCk7XG5cblx0Ly8gQWRkIHBhZGRpbmdcblx0d2lkdGggKz0gMiAqIG1vZGVsLnhQYWRkaW5nO1xuXG5cdHJldHVybiB7XG5cdFx0d2lkdGg6IHdpZHRoLFxuXHRcdGhlaWdodDogaGVpZ2h0XG5cdH07XG59XG5cbi8qKlxuICogSGVscGVyIHRvIGdldCB0aGUgYWxpZ25tZW50IG9mIGEgdG9vbHRpcCBnaXZlbiB0aGUgc2l6ZVxuICovXG5mdW5jdGlvbiBkZXRlcm1pbmVBbGlnbm1lbnQodG9vbHRpcCwgc2l6ZSkge1xuXHR2YXIgbW9kZWwgPSB0b29sdGlwLl9tb2RlbDtcblx0dmFyIGNoYXJ0ID0gdG9vbHRpcC5fY2hhcnQ7XG5cdHZhciBjaGFydEFyZWEgPSB0b29sdGlwLl9jaGFydC5jaGFydEFyZWE7XG5cdHZhciB4QWxpZ24gPSAnY2VudGVyJztcblx0dmFyIHlBbGlnbiA9ICdjZW50ZXInO1xuXG5cdGlmIChtb2RlbC55IDwgc2l6ZS5oZWlnaHQpIHtcblx0XHR5QWxpZ24gPSAndG9wJztcblx0fSBlbHNlIGlmIChtb2RlbC55ID4gKGNoYXJ0LmhlaWdodCAtIHNpemUuaGVpZ2h0KSkge1xuXHRcdHlBbGlnbiA9ICdib3R0b20nO1xuXHR9XG5cblx0dmFyIGxmLCByZjsgLy8gZnVuY3Rpb25zIHRvIGRldGVybWluZSBsZWZ0LCByaWdodCBhbGlnbm1lbnRcblx0dmFyIG9sZiwgb3JmOyAvLyBmdW5jdGlvbnMgdG8gZGV0ZXJtaW5lIGlmIGxlZnQvcmlnaHQgYWxpZ25tZW50IGNhdXNlcyB0b29sdGlwIHRvIGdvIG91dHNpZGUgY2hhcnRcblx0dmFyIHlmOyAvLyBmdW5jdGlvbiB0byBnZXQgdGhlIHkgYWxpZ25tZW50IGlmIHRoZSB0b29sdGlwIGdvZXMgb3V0c2lkZSBvZiB0aGUgbGVmdCBvciByaWdodCBlZGdlc1xuXHR2YXIgbWlkWCA9IChjaGFydEFyZWEubGVmdCArIGNoYXJ0QXJlYS5yaWdodCkgLyAyO1xuXHR2YXIgbWlkWSA9IChjaGFydEFyZWEudG9wICsgY2hhcnRBcmVhLmJvdHRvbSkgLyAyO1xuXG5cdGlmICh5QWxpZ24gPT09ICdjZW50ZXInKSB7XG5cdFx0bGYgPSBmdW5jdGlvbih4KSB7XG5cdFx0XHRyZXR1cm4geCA8PSBtaWRYO1xuXHRcdH07XG5cdFx0cmYgPSBmdW5jdGlvbih4KSB7XG5cdFx0XHRyZXR1cm4geCA+IG1pZFg7XG5cdFx0fTtcblx0fSBlbHNlIHtcblx0XHRsZiA9IGZ1bmN0aW9uKHgpIHtcblx0XHRcdHJldHVybiB4IDw9IChzaXplLndpZHRoIC8gMik7XG5cdFx0fTtcblx0XHRyZiA9IGZ1bmN0aW9uKHgpIHtcblx0XHRcdHJldHVybiB4ID49IChjaGFydC53aWR0aCAtIChzaXplLndpZHRoIC8gMikpO1xuXHRcdH07XG5cdH1cblxuXHRvbGYgPSBmdW5jdGlvbih4KSB7XG5cdFx0cmV0dXJuIHggKyBzaXplLndpZHRoICsgbW9kZWwuY2FyZXRTaXplICsgbW9kZWwuY2FyZXRQYWRkaW5nID4gY2hhcnQud2lkdGg7XG5cdH07XG5cdG9yZiA9IGZ1bmN0aW9uKHgpIHtcblx0XHRyZXR1cm4geCAtIHNpemUud2lkdGggLSBtb2RlbC5jYXJldFNpemUgLSBtb2RlbC5jYXJldFBhZGRpbmcgPCAwO1xuXHR9O1xuXHR5ZiA9IGZ1bmN0aW9uKHkpIHtcblx0XHRyZXR1cm4geSA8PSBtaWRZID8gJ3RvcCcgOiAnYm90dG9tJztcblx0fTtcblxuXHRpZiAobGYobW9kZWwueCkpIHtcblx0XHR4QWxpZ24gPSAnbGVmdCc7XG5cblx0XHQvLyBJcyB0b29sdGlwIHRvbyB3aWRlIGFuZCBnb2VzIG92ZXIgdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNoYXJ0Lj9cblx0XHRpZiAob2xmKG1vZGVsLngpKSB7XG5cdFx0XHR4QWxpZ24gPSAnY2VudGVyJztcblx0XHRcdHlBbGlnbiA9IHlmKG1vZGVsLnkpO1xuXHRcdH1cblx0fSBlbHNlIGlmIChyZihtb2RlbC54KSkge1xuXHRcdHhBbGlnbiA9ICdyaWdodCc7XG5cblx0XHQvLyBJcyB0b29sdGlwIHRvbyB3aWRlIGFuZCBnb2VzIG91dHNpZGUgbGVmdCBlZGdlIG9mIGNhbnZhcz9cblx0XHRpZiAob3JmKG1vZGVsLngpKSB7XG5cdFx0XHR4QWxpZ24gPSAnY2VudGVyJztcblx0XHRcdHlBbGlnbiA9IHlmKG1vZGVsLnkpO1xuXHRcdH1cblx0fVxuXG5cdHZhciBvcHRzID0gdG9vbHRpcC5fb3B0aW9ucztcblx0cmV0dXJuIHtcblx0XHR4QWxpZ246IG9wdHMueEFsaWduID8gb3B0cy54QWxpZ24gOiB4QWxpZ24sXG5cdFx0eUFsaWduOiBvcHRzLnlBbGlnbiA/IG9wdHMueUFsaWduIDogeUFsaWduXG5cdH07XG59XG5cbi8qKlxuICogSGVscGVyIHRvIGdldCB0aGUgbG9jYXRpb24gYSB0b29sdGlwIG5lZWRzIHRvIGJlIHBsYWNlZCBhdCBnaXZlbiB0aGUgaW5pdGlhbCBwb3NpdGlvbiAodmlhIHRoZSB2bSkgYW5kIHRoZSBzaXplIGFuZCBhbGlnbm1lbnRcbiAqL1xuZnVuY3Rpb24gZ2V0QmFja2dyb3VuZFBvaW50KHZtLCBzaXplLCBhbGlnbm1lbnQsIGNoYXJ0KSB7XG5cdC8vIEJhY2tncm91bmQgUG9zaXRpb25cblx0dmFyIHggPSB2bS54O1xuXHR2YXIgeSA9IHZtLnk7XG5cblx0dmFyIGNhcmV0U2l6ZSA9IHZtLmNhcmV0U2l6ZTtcblx0dmFyIGNhcmV0UGFkZGluZyA9IHZtLmNhcmV0UGFkZGluZztcblx0dmFyIGNvcm5lclJhZGl1cyA9IHZtLmNvcm5lclJhZGl1cztcblx0dmFyIHhBbGlnbiA9IGFsaWdubWVudC54QWxpZ247XG5cdHZhciB5QWxpZ24gPSBhbGlnbm1lbnQueUFsaWduO1xuXHR2YXIgcGFkZGluZ0FuZFNpemUgPSBjYXJldFNpemUgKyBjYXJldFBhZGRpbmc7XG5cdHZhciByYWRpdXNBbmRQYWRkaW5nID0gY29ybmVyUmFkaXVzICsgY2FyZXRQYWRkaW5nO1xuXG5cdGlmICh4QWxpZ24gPT09ICdyaWdodCcpIHtcblx0XHR4IC09IHNpemUud2lkdGg7XG5cdH0gZWxzZSBpZiAoeEFsaWduID09PSAnY2VudGVyJykge1xuXHRcdHggLT0gKHNpemUud2lkdGggLyAyKTtcblx0XHRpZiAoeCArIHNpemUud2lkdGggPiBjaGFydC53aWR0aCkge1xuXHRcdFx0eCA9IGNoYXJ0LndpZHRoIC0gc2l6ZS53aWR0aDtcblx0XHR9XG5cdFx0aWYgKHggPCAwKSB7XG5cdFx0XHR4ID0gMDtcblx0XHR9XG5cdH1cblxuXHRpZiAoeUFsaWduID09PSAndG9wJykge1xuXHRcdHkgKz0gcGFkZGluZ0FuZFNpemU7XG5cdH0gZWxzZSBpZiAoeUFsaWduID09PSAnYm90dG9tJykge1xuXHRcdHkgLT0gc2l6ZS5oZWlnaHQgKyBwYWRkaW5nQW5kU2l6ZTtcblx0fSBlbHNlIHtcblx0XHR5IC09IChzaXplLmhlaWdodCAvIDIpO1xuXHR9XG5cblx0aWYgKHlBbGlnbiA9PT0gJ2NlbnRlcicpIHtcblx0XHRpZiAoeEFsaWduID09PSAnbGVmdCcpIHtcblx0XHRcdHggKz0gcGFkZGluZ0FuZFNpemU7XG5cdFx0fSBlbHNlIGlmICh4QWxpZ24gPT09ICdyaWdodCcpIHtcblx0XHRcdHggLT0gcGFkZGluZ0FuZFNpemU7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKHhBbGlnbiA9PT0gJ2xlZnQnKSB7XG5cdFx0eCAtPSByYWRpdXNBbmRQYWRkaW5nO1xuXHR9IGVsc2UgaWYgKHhBbGlnbiA9PT0gJ3JpZ2h0Jykge1xuXHRcdHggKz0gcmFkaXVzQW5kUGFkZGluZztcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0eDogeCxcblx0XHR5OiB5XG5cdH07XG59XG5cbi8qKlxuICogSGVscGVyIHRvIGJ1aWxkIGJlZm9yZSBhbmQgYWZ0ZXIgYm9keSBsaW5lc1xuICovXG5mdW5jdGlvbiBnZXRCZWZvcmVBZnRlckJvZHlMaW5lcyhjYWxsYmFjaykge1xuXHRyZXR1cm4gcHVzaE9yQ29uY2F0KFtdLCBzcGxpdE5ld2xpbmVzKGNhbGxiYWNrKSk7XG59XG5cbnZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBFbGVtZW50LmV4dGVuZCh7XG5cdGluaXRpYWxpemU6IGZ1bmN0aW9uKCkge1xuXHRcdHRoaXMuX21vZGVsID0gZ2V0QmFzZU1vZGVsKHRoaXMuX29wdGlvbnMpO1xuXHRcdHRoaXMuX2xhc3RBY3RpdmUgPSBbXTtcblx0fSxcblxuXHQvLyBHZXQgdGhlIHRpdGxlXG5cdC8vIEFyZ3MgYXJlOiAodG9vbHRpcEl0ZW0sIGRhdGEpXG5cdGdldFRpdGxlOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciBvcHRzID0gbWUuX29wdGlvbnM7XG5cdFx0dmFyIGNhbGxiYWNrcyA9IG9wdHMuY2FsbGJhY2tzO1xuXG5cdFx0dmFyIGJlZm9yZVRpdGxlID0gY2FsbGJhY2tzLmJlZm9yZVRpdGxlLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xuXHRcdHZhciB0aXRsZSA9IGNhbGxiYWNrcy50aXRsZS5hcHBseShtZSwgYXJndW1lbnRzKTtcblx0XHR2YXIgYWZ0ZXJUaXRsZSA9IGNhbGxiYWNrcy5hZnRlclRpdGxlLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xuXG5cdFx0dmFyIGxpbmVzID0gW107XG5cdFx0bGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoYmVmb3JlVGl0bGUpKTtcblx0XHRsaW5lcyA9IHB1c2hPckNvbmNhdChsaW5lcywgc3BsaXROZXdsaW5lcyh0aXRsZSkpO1xuXHRcdGxpbmVzID0gcHVzaE9yQ29uY2F0KGxpbmVzLCBzcGxpdE5ld2xpbmVzKGFmdGVyVGl0bGUpKTtcblxuXHRcdHJldHVybiBsaW5lcztcblx0fSxcblxuXHQvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtLCBkYXRhKVxuXHRnZXRCZWZvcmVCb2R5OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZ2V0QmVmb3JlQWZ0ZXJCb2R5TGluZXModGhpcy5fb3B0aW9ucy5jYWxsYmFja3MuYmVmb3JlQm9keS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTtcblx0fSxcblxuXHQvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtLCBkYXRhKVxuXHRnZXRCb2R5OiBmdW5jdGlvbih0b29sdGlwSXRlbXMsIGRhdGEpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciBjYWxsYmFja3MgPSBtZS5fb3B0aW9ucy5jYWxsYmFja3M7XG5cdFx0dmFyIGJvZHlJdGVtcyA9IFtdO1xuXG5cdFx0aGVscGVycy5lYWNoKHRvb2x0aXBJdGVtcywgZnVuY3Rpb24odG9vbHRpcEl0ZW0pIHtcblx0XHRcdHZhciBib2R5SXRlbSA9IHtcblx0XHRcdFx0YmVmb3JlOiBbXSxcblx0XHRcdFx0bGluZXM6IFtdLFxuXHRcdFx0XHRhZnRlcjogW11cblx0XHRcdH07XG5cdFx0XHRwdXNoT3JDb25jYXQoYm9keUl0ZW0uYmVmb3JlLCBzcGxpdE5ld2xpbmVzKGNhbGxiYWNrcy5iZWZvcmVMYWJlbC5jYWxsKG1lLCB0b29sdGlwSXRlbSwgZGF0YSkpKTtcblx0XHRcdHB1c2hPckNvbmNhdChib2R5SXRlbS5saW5lcywgY2FsbGJhY2tzLmxhYmVsLmNhbGwobWUsIHRvb2x0aXBJdGVtLCBkYXRhKSk7XG5cdFx0XHRwdXNoT3JDb25jYXQoYm9keUl0ZW0uYWZ0ZXIsIHNwbGl0TmV3bGluZXMoY2FsbGJhY2tzLmFmdGVyTGFiZWwuY2FsbChtZSwgdG9vbHRpcEl0ZW0sIGRhdGEpKSk7XG5cblx0XHRcdGJvZHlJdGVtcy5wdXNoKGJvZHlJdGVtKTtcblx0XHR9KTtcblxuXHRcdHJldHVybiBib2R5SXRlbXM7XG5cdH0sXG5cblx0Ly8gQXJncyBhcmU6ICh0b29sdGlwSXRlbSwgZGF0YSlcblx0Z2V0QWZ0ZXJCb2R5OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZ2V0QmVmb3JlQWZ0ZXJCb2R5TGluZXModGhpcy5fb3B0aW9ucy5jYWxsYmFja3MuYWZ0ZXJCb2R5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xuXHR9LFxuXG5cdC8vIEdldCB0aGUgZm9vdGVyIGFuZCBiZWZvcmVGb290ZXIgYW5kIGFmdGVyRm9vdGVyIGxpbmVzXG5cdC8vIEFyZ3MgYXJlOiAodG9vbHRpcEl0ZW0sIGRhdGEpXG5cdGdldEZvb3RlcjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIG1lID0gdGhpcztcblx0XHR2YXIgY2FsbGJhY2tzID0gbWUuX29wdGlvbnMuY2FsbGJhY2tzO1xuXG5cdFx0dmFyIGJlZm9yZUZvb3RlciA9IGNhbGxiYWNrcy5iZWZvcmVGb290ZXIuYXBwbHkobWUsIGFyZ3VtZW50cyk7XG5cdFx0dmFyIGZvb3RlciA9IGNhbGxiYWNrcy5mb290ZXIuYXBwbHkobWUsIGFyZ3VtZW50cyk7XG5cdFx0dmFyIGFmdGVyRm9vdGVyID0gY2FsbGJhY2tzLmFmdGVyRm9vdGVyLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xuXG5cdFx0dmFyIGxpbmVzID0gW107XG5cdFx0bGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoYmVmb3JlRm9vdGVyKSk7XG5cdFx0bGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoZm9vdGVyKSk7XG5cdFx0bGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoYWZ0ZXJGb290ZXIpKTtcblxuXHRcdHJldHVybiBsaW5lcztcblx0fSxcblxuXHR1cGRhdGU6IGZ1bmN0aW9uKGNoYW5nZWQpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciBvcHRzID0gbWUuX29wdGlvbnM7XG5cblx0XHQvLyBOZWVkIHRvIHJlZ2VuZXJhdGUgdGhlIG1vZGVsIGJlY2F1c2UgaXRzIGZhc3RlciB0aGFuIHVzaW5nIGV4dGVuZCBhbmQgaXQgaXMgbmVjZXNzYXJ5IGR1ZSB0byB0aGUgb3B0aW1pemF0aW9uIGluIENoYXJ0LkVsZW1lbnQudHJhbnNpdGlvblxuXHRcdC8vIHRoYXQgZG9lcyBfdmlldyA9IF9tb2RlbCBpZiBlYXNlID09PSAxLiBUaGlzIGNhdXNlcyB0aGUgMm5kIHRvb2x0aXAgdXBkYXRlIHRvIHNldCBwcm9wZXJ0aWVzIGluIGJvdGggdGhlIHZpZXcgYW5kIG1vZGVsIGF0IHRoZSBzYW1lIHRpbWVcblx0XHQvLyB3aGljaCBicmVha3MgYW55IGFuaW1hdGlvbnMuXG5cdFx0dmFyIGV4aXN0aW5nTW9kZWwgPSBtZS5fbW9kZWw7XG5cdFx0dmFyIG1vZGVsID0gbWUuX21vZGVsID0gZ2V0QmFzZU1vZGVsKG9wdHMpO1xuXHRcdHZhciBhY3RpdmUgPSBtZS5fYWN0aXZlO1xuXG5cdFx0dmFyIGRhdGEgPSBtZS5fZGF0YTtcblxuXHRcdC8vIEluIHRoZSBjYXNlIHdoZXJlIGFjdGl2ZS5sZW5ndGggPT09IDAgd2UgbmVlZCB0byBrZWVwIHRoZXNlIGF0IGV4aXN0aW5nIHZhbHVlcyBmb3IgZ29vZCBhbmltYXRpb25zXG5cdFx0dmFyIGFsaWdubWVudCA9IHtcblx0XHRcdHhBbGlnbjogZXhpc3RpbmdNb2RlbC54QWxpZ24sXG5cdFx0XHR5QWxpZ246IGV4aXN0aW5nTW9kZWwueUFsaWduXG5cdFx0fTtcblx0XHR2YXIgYmFja2dyb3VuZFBvaW50ID0ge1xuXHRcdFx0eDogZXhpc3RpbmdNb2RlbC54LFxuXHRcdFx0eTogZXhpc3RpbmdNb2RlbC55XG5cdFx0fTtcblx0XHR2YXIgdG9vbHRpcFNpemUgPSB7XG5cdFx0XHR3aWR0aDogZXhpc3RpbmdNb2RlbC53aWR0aCxcblx0XHRcdGhlaWdodDogZXhpc3RpbmdNb2RlbC5oZWlnaHRcblx0XHR9O1xuXHRcdHZhciB0b29sdGlwUG9zaXRpb24gPSB7XG5cdFx0XHR4OiBleGlzdGluZ01vZGVsLmNhcmV0WCxcblx0XHRcdHk6IGV4aXN0aW5nTW9kZWwuY2FyZXRZXG5cdFx0fTtcblxuXHRcdHZhciBpLCBsZW47XG5cblx0XHRpZiAoYWN0aXZlLmxlbmd0aCkge1xuXHRcdFx0bW9kZWwub3BhY2l0eSA9IDE7XG5cblx0XHRcdHZhciBsYWJlbENvbG9ycyA9IFtdO1xuXHRcdFx0dmFyIGxhYmVsVGV4dENvbG9ycyA9IFtdO1xuXHRcdFx0dG9vbHRpcFBvc2l0aW9uID0gcG9zaXRpb25lcnNbb3B0cy5wb3NpdGlvbl0uY2FsbChtZSwgYWN0aXZlLCBtZS5fZXZlbnRQb3NpdGlvbik7XG5cblx0XHRcdHZhciB0b29sdGlwSXRlbXMgPSBbXTtcblx0XHRcdGZvciAoaSA9IDAsIGxlbiA9IGFjdGl2ZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuXHRcdFx0XHR0b29sdGlwSXRlbXMucHVzaChjcmVhdGVUb29sdGlwSXRlbShhY3RpdmVbaV0pKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgdGhlIHVzZXIgcHJvdmlkZWQgYSBmaWx0ZXIgZnVuY3Rpb24sIHVzZSBpdCB0byBtb2RpZnkgdGhlIHRvb2x0aXAgaXRlbXNcblx0XHRcdGlmIChvcHRzLmZpbHRlcikge1xuXHRcdFx0XHR0b29sdGlwSXRlbXMgPSB0b29sdGlwSXRlbXMuZmlsdGVyKGZ1bmN0aW9uKGEpIHtcblx0XHRcdFx0XHRyZXR1cm4gb3B0cy5maWx0ZXIoYSwgZGF0YSk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiB0aGUgdXNlciBwcm92aWRlZCBhIHNvcnRpbmcgZnVuY3Rpb24sIHVzZSBpdCB0byBtb2RpZnkgdGhlIHRvb2x0aXAgaXRlbXNcblx0XHRcdGlmIChvcHRzLml0ZW1Tb3J0KSB7XG5cdFx0XHRcdHRvb2x0aXBJdGVtcyA9IHRvb2x0aXBJdGVtcy5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcblx0XHRcdFx0XHRyZXR1cm4gb3B0cy5pdGVtU29ydChhLCBiLCBkYXRhKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIERldGVybWluZSBjb2xvcnMgZm9yIGJveGVzXG5cdFx0XHRoZWxwZXJzLmVhY2godG9vbHRpcEl0ZW1zLCBmdW5jdGlvbih0b29sdGlwSXRlbSkge1xuXHRcdFx0XHRsYWJlbENvbG9ycy5wdXNoKG9wdHMuY2FsbGJhY2tzLmxhYmVsQ29sb3IuY2FsbChtZSwgdG9vbHRpcEl0ZW0sIG1lLl9jaGFydCkpO1xuXHRcdFx0XHRsYWJlbFRleHRDb2xvcnMucHVzaChvcHRzLmNhbGxiYWNrcy5sYWJlbFRleHRDb2xvci5jYWxsKG1lLCB0b29sdGlwSXRlbSwgbWUuX2NoYXJ0KSk7XG5cdFx0XHR9KTtcblxuXG5cdFx0XHQvLyBCdWlsZCB0aGUgVGV4dCBMaW5lc1xuXHRcdFx0bW9kZWwudGl0bGUgPSBtZS5nZXRUaXRsZSh0b29sdGlwSXRlbXMsIGRhdGEpO1xuXHRcdFx0bW9kZWwuYmVmb3JlQm9keSA9IG1lLmdldEJlZm9yZUJvZHkodG9vbHRpcEl0ZW1zLCBkYXRhKTtcblx0XHRcdG1vZGVsLmJvZHkgPSBtZS5nZXRCb2R5KHRvb2x0aXBJdGVtcywgZGF0YSk7XG5cdFx0XHRtb2RlbC5hZnRlckJvZHkgPSBtZS5nZXRBZnRlckJvZHkodG9vbHRpcEl0ZW1zLCBkYXRhKTtcblx0XHRcdG1vZGVsLmZvb3RlciA9IG1lLmdldEZvb3Rlcih0b29sdGlwSXRlbXMsIGRhdGEpO1xuXG5cdFx0XHQvLyBJbml0aWFsIHBvc2l0aW9uaW5nIGFuZCBjb2xvcnNcblx0XHRcdG1vZGVsLnggPSBNYXRoLnJvdW5kKHRvb2x0aXBQb3NpdGlvbi54KTtcblx0XHRcdG1vZGVsLnkgPSBNYXRoLnJvdW5kKHRvb2x0aXBQb3NpdGlvbi55KTtcblx0XHRcdG1vZGVsLmNhcmV0UGFkZGluZyA9IG9wdHMuY2FyZXRQYWRkaW5nO1xuXHRcdFx0bW9kZWwubGFiZWxDb2xvcnMgPSBsYWJlbENvbG9ycztcblx0XHRcdG1vZGVsLmxhYmVsVGV4dENvbG9ycyA9IGxhYmVsVGV4dENvbG9ycztcblxuXHRcdFx0Ly8gZGF0YSBwb2ludHNcblx0XHRcdG1vZGVsLmRhdGFQb2ludHMgPSB0b29sdGlwSXRlbXM7XG5cblx0XHRcdC8vIFdlIG5lZWQgdG8gZGV0ZXJtaW5lIGFsaWdubWVudCBvZiB0aGUgdG9vbHRpcFxuXHRcdFx0dG9vbHRpcFNpemUgPSBnZXRUb29sdGlwU2l6ZSh0aGlzLCBtb2RlbCk7XG5cdFx0XHRhbGlnbm1lbnQgPSBkZXRlcm1pbmVBbGlnbm1lbnQodGhpcywgdG9vbHRpcFNpemUpO1xuXHRcdFx0Ly8gRmluYWwgU2l6ZSBhbmQgUG9zaXRpb25cblx0XHRcdGJhY2tncm91bmRQb2ludCA9IGdldEJhY2tncm91bmRQb2ludChtb2RlbCwgdG9vbHRpcFNpemUsIGFsaWdubWVudCwgbWUuX2NoYXJ0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bW9kZWwub3BhY2l0eSA9IDA7XG5cdFx0fVxuXG5cdFx0bW9kZWwueEFsaWduID0gYWxpZ25tZW50LnhBbGlnbjtcblx0XHRtb2RlbC55QWxpZ24gPSBhbGlnbm1lbnQueUFsaWduO1xuXHRcdG1vZGVsLnggPSBiYWNrZ3JvdW5kUG9pbnQueDtcblx0XHRtb2RlbC55ID0gYmFja2dyb3VuZFBvaW50Lnk7XG5cdFx0bW9kZWwud2lkdGggPSB0b29sdGlwU2l6ZS53aWR0aDtcblx0XHRtb2RlbC5oZWlnaHQgPSB0b29sdGlwU2l6ZS5oZWlnaHQ7XG5cblx0XHQvLyBQb2ludCB3aGVyZSB0aGUgY2FyZXQgb24gdGhlIHRvb2x0aXAgcG9pbnRzIHRvXG5cdFx0bW9kZWwuY2FyZXRYID0gdG9vbHRpcFBvc2l0aW9uLng7XG5cdFx0bW9kZWwuY2FyZXRZID0gdG9vbHRpcFBvc2l0aW9uLnk7XG5cblx0XHRtZS5fbW9kZWwgPSBtb2RlbDtcblxuXHRcdGlmIChjaGFuZ2VkICYmIG9wdHMuY3VzdG9tKSB7XG5cdFx0XHRvcHRzLmN1c3RvbS5jYWxsKG1lLCBtb2RlbCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG1lO1xuXHR9LFxuXG5cdGRyYXdDYXJldDogZnVuY3Rpb24odG9vbHRpcFBvaW50LCBzaXplKSB7XG5cdFx0dmFyIGN0eCA9IHRoaXMuX2NoYXJ0LmN0eDtcblx0XHR2YXIgdm0gPSB0aGlzLl92aWV3O1xuXHRcdHZhciBjYXJldFBvc2l0aW9uID0gdGhpcy5nZXRDYXJldFBvc2l0aW9uKHRvb2x0aXBQb2ludCwgc2l6ZSwgdm0pO1xuXG5cdFx0Y3R4LmxpbmVUbyhjYXJldFBvc2l0aW9uLngxLCBjYXJldFBvc2l0aW9uLnkxKTtcblx0XHRjdHgubGluZVRvKGNhcmV0UG9zaXRpb24ueDIsIGNhcmV0UG9zaXRpb24ueTIpO1xuXHRcdGN0eC5saW5lVG8oY2FyZXRQb3NpdGlvbi54MywgY2FyZXRQb3NpdGlvbi55Myk7XG5cdH0sXG5cdGdldENhcmV0UG9zaXRpb246IGZ1bmN0aW9uKHRvb2x0aXBQb2ludCwgc2l6ZSwgdm0pIHtcblx0XHR2YXIgeDEsIHgyLCB4MywgeTEsIHkyLCB5Mztcblx0XHR2YXIgY2FyZXRTaXplID0gdm0uY2FyZXRTaXplO1xuXHRcdHZhciBjb3JuZXJSYWRpdXMgPSB2bS5jb3JuZXJSYWRpdXM7XG5cdFx0dmFyIHhBbGlnbiA9IHZtLnhBbGlnbjtcblx0XHR2YXIgeUFsaWduID0gdm0ueUFsaWduO1xuXHRcdHZhciBwdFggPSB0b29sdGlwUG9pbnQueDtcblx0XHR2YXIgcHRZID0gdG9vbHRpcFBvaW50Lnk7XG5cdFx0dmFyIHdpZHRoID0gc2l6ZS53aWR0aDtcblx0XHR2YXIgaGVpZ2h0ID0gc2l6ZS5oZWlnaHQ7XG5cblx0XHRpZiAoeUFsaWduID09PSAnY2VudGVyJykge1xuXHRcdFx0eTIgPSBwdFkgKyAoaGVpZ2h0IC8gMik7XG5cblx0XHRcdGlmICh4QWxpZ24gPT09ICdsZWZ0Jykge1xuXHRcdFx0XHR4MSA9IHB0WDtcblx0XHRcdFx0eDIgPSB4MSAtIGNhcmV0U2l6ZTtcblx0XHRcdFx0eDMgPSB4MTtcblxuXHRcdFx0XHR5MSA9IHkyICsgY2FyZXRTaXplO1xuXHRcdFx0XHR5MyA9IHkyIC0gY2FyZXRTaXplO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0eDEgPSBwdFggKyB3aWR0aDtcblx0XHRcdFx0eDIgPSB4MSArIGNhcmV0U2l6ZTtcblx0XHRcdFx0eDMgPSB4MTtcblxuXHRcdFx0XHR5MSA9IHkyIC0gY2FyZXRTaXplO1xuXHRcdFx0XHR5MyA9IHkyICsgY2FyZXRTaXplO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoeEFsaWduID09PSAnbGVmdCcpIHtcblx0XHRcdFx0eDIgPSBwdFggKyBjb3JuZXJSYWRpdXMgKyAoY2FyZXRTaXplKTtcblx0XHRcdFx0eDEgPSB4MiAtIGNhcmV0U2l6ZTtcblx0XHRcdFx0eDMgPSB4MiArIGNhcmV0U2l6ZTtcblx0XHRcdH0gZWxzZSBpZiAoeEFsaWduID09PSAncmlnaHQnKSB7XG5cdFx0XHRcdHgyID0gcHRYICsgd2lkdGggLSBjb3JuZXJSYWRpdXMgLSBjYXJldFNpemU7XG5cdFx0XHRcdHgxID0geDIgLSBjYXJldFNpemU7XG5cdFx0XHRcdHgzID0geDIgKyBjYXJldFNpemU7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR4MiA9IHZtLmNhcmV0WDtcblx0XHRcdFx0eDEgPSB4MiAtIGNhcmV0U2l6ZTtcblx0XHRcdFx0eDMgPSB4MiArIGNhcmV0U2l6ZTtcblx0XHRcdH1cblx0XHRcdGlmICh5QWxpZ24gPT09ICd0b3AnKSB7XG5cdFx0XHRcdHkxID0gcHRZO1xuXHRcdFx0XHR5MiA9IHkxIC0gY2FyZXRTaXplO1xuXHRcdFx0XHR5MyA9IHkxO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0eTEgPSBwdFkgKyBoZWlnaHQ7XG5cdFx0XHRcdHkyID0geTEgKyBjYXJldFNpemU7XG5cdFx0XHRcdHkzID0geTE7XG5cdFx0XHRcdC8vIGludmVydCBkcmF3aW5nIG9yZGVyXG5cdFx0XHRcdHZhciB0bXAgPSB4Mztcblx0XHRcdFx0eDMgPSB4MTtcblx0XHRcdFx0eDEgPSB0bXA7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB7eDE6IHgxLCB4MjogeDIsIHgzOiB4MywgeTE6IHkxLCB5MjogeTIsIHkzOiB5M307XG5cdH0sXG5cblx0ZHJhd1RpdGxlOiBmdW5jdGlvbihwdCwgdm0sIGN0eCwgb3BhY2l0eSkge1xuXHRcdHZhciB0aXRsZSA9IHZtLnRpdGxlO1xuXG5cdFx0aWYgKHRpdGxlLmxlbmd0aCkge1xuXHRcdFx0Y3R4LnRleHRBbGlnbiA9IHZtLl90aXRsZUFsaWduO1xuXHRcdFx0Y3R4LnRleHRCYXNlbGluZSA9ICd0b3AnO1xuXG5cdFx0XHR2YXIgdGl0bGVGb250U2l6ZSA9IHZtLnRpdGxlRm9udFNpemU7XG5cdFx0XHR2YXIgdGl0bGVTcGFjaW5nID0gdm0udGl0bGVTcGFjaW5nO1xuXG5cdFx0XHRjdHguZmlsbFN0eWxlID0gbWVyZ2VPcGFjaXR5KHZtLnRpdGxlRm9udENvbG9yLCBvcGFjaXR5KTtcblx0XHRcdGN0eC5mb250ID0gaGVscGVycy5mb250U3RyaW5nKHRpdGxlRm9udFNpemUsIHZtLl90aXRsZUZvbnRTdHlsZSwgdm0uX3RpdGxlRm9udEZhbWlseSk7XG5cblx0XHRcdHZhciBpLCBsZW47XG5cdFx0XHRmb3IgKGkgPSAwLCBsZW4gPSB0aXRsZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuXHRcdFx0XHRjdHguZmlsbFRleHQodGl0bGVbaV0sIHB0LngsIHB0LnkpO1xuXHRcdFx0XHRwdC55ICs9IHRpdGxlRm9udFNpemUgKyB0aXRsZVNwYWNpbmc7IC8vIExpbmUgSGVpZ2h0IGFuZCBzcGFjaW5nXG5cblx0XHRcdFx0aWYgKGkgKyAxID09PSB0aXRsZS5sZW5ndGgpIHtcblx0XHRcdFx0XHRwdC55ICs9IHZtLnRpdGxlTWFyZ2luQm90dG9tIC0gdGl0bGVTcGFjaW5nOyAvLyBJZiBMYXN0LCBhZGQgbWFyZ2luLCByZW1vdmUgc3BhY2luZ1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdGRyYXdCb2R5OiBmdW5jdGlvbihwdCwgdm0sIGN0eCwgb3BhY2l0eSkge1xuXHRcdHZhciBib2R5Rm9udFNpemUgPSB2bS5ib2R5Rm9udFNpemU7XG5cdFx0dmFyIGJvZHlTcGFjaW5nID0gdm0uYm9keVNwYWNpbmc7XG5cdFx0dmFyIGJvZHkgPSB2bS5ib2R5O1xuXG5cdFx0Y3R4LnRleHRBbGlnbiA9IHZtLl9ib2R5QWxpZ247XG5cdFx0Y3R4LnRleHRCYXNlbGluZSA9ICd0b3AnO1xuXHRcdGN0eC5mb250ID0gaGVscGVycy5mb250U3RyaW5nKGJvZHlGb250U2l6ZSwgdm0uX2JvZHlGb250U3R5bGUsIHZtLl9ib2R5Rm9udEZhbWlseSk7XG5cblx0XHQvLyBCZWZvcmUgQm9keVxuXHRcdHZhciB4TGluZVBhZGRpbmcgPSAwO1xuXHRcdHZhciBmaWxsTGluZU9mVGV4dCA9IGZ1bmN0aW9uKGxpbmUpIHtcblx0XHRcdGN0eC5maWxsVGV4dChsaW5lLCBwdC54ICsgeExpbmVQYWRkaW5nLCBwdC55KTtcblx0XHRcdHB0LnkgKz0gYm9keUZvbnRTaXplICsgYm9keVNwYWNpbmc7XG5cdFx0fTtcblxuXHRcdC8vIEJlZm9yZSBib2R5IGxpbmVzXG5cdFx0Y3R4LmZpbGxTdHlsZSA9IG1lcmdlT3BhY2l0eSh2bS5ib2R5Rm9udENvbG9yLCBvcGFjaXR5KTtcblx0XHRoZWxwZXJzLmVhY2godm0uYmVmb3JlQm9keSwgZmlsbExpbmVPZlRleHQpO1xuXG5cdFx0dmFyIGRyYXdDb2xvckJveGVzID0gdm0uZGlzcGxheUNvbG9ycztcblx0XHR4TGluZVBhZGRpbmcgPSBkcmF3Q29sb3JCb3hlcyA/IChib2R5Rm9udFNpemUgKyAyKSA6IDA7XG5cblx0XHQvLyBEcmF3IGJvZHkgbGluZXMgbm93XG5cdFx0aGVscGVycy5lYWNoKGJvZHksIGZ1bmN0aW9uKGJvZHlJdGVtLCBpKSB7XG5cdFx0XHR2YXIgdGV4dENvbG9yID0gbWVyZ2VPcGFjaXR5KHZtLmxhYmVsVGV4dENvbG9yc1tpXSwgb3BhY2l0eSk7XG5cdFx0XHRjdHguZmlsbFN0eWxlID0gdGV4dENvbG9yO1xuXHRcdFx0aGVscGVycy5lYWNoKGJvZHlJdGVtLmJlZm9yZSwgZmlsbExpbmVPZlRleHQpO1xuXG5cdFx0XHRoZWxwZXJzLmVhY2goYm9keUl0ZW0ubGluZXMsIGZ1bmN0aW9uKGxpbmUpIHtcblx0XHRcdFx0Ly8gRHJhdyBMZWdlbmQtbGlrZSBib3hlcyBpZiBuZWVkZWRcblx0XHRcdFx0aWYgKGRyYXdDb2xvckJveGVzKSB7XG5cdFx0XHRcdFx0Ly8gRmlsbCBhIHdoaXRlIHJlY3Qgc28gdGhhdCBjb2xvdXJzIG1lcmdlIG5pY2VseSBpZiB0aGUgb3BhY2l0eSBpcyA8IDFcblx0XHRcdFx0XHRjdHguZmlsbFN0eWxlID0gbWVyZ2VPcGFjaXR5KHZtLmxlZ2VuZENvbG9yQmFja2dyb3VuZCwgb3BhY2l0eSk7XG5cdFx0XHRcdFx0Y3R4LmZpbGxSZWN0KHB0LngsIHB0LnksIGJvZHlGb250U2l6ZSwgYm9keUZvbnRTaXplKTtcblxuXHRcdFx0XHRcdC8vIEJvcmRlclxuXHRcdFx0XHRcdGN0eC5saW5lV2lkdGggPSAxO1xuXHRcdFx0XHRcdGN0eC5zdHJva2VTdHlsZSA9IG1lcmdlT3BhY2l0eSh2bS5sYWJlbENvbG9yc1tpXS5ib3JkZXJDb2xvciwgb3BhY2l0eSk7XG5cdFx0XHRcdFx0Y3R4LnN0cm9rZVJlY3QocHQueCwgcHQueSwgYm9keUZvbnRTaXplLCBib2R5Rm9udFNpemUpO1xuXG5cdFx0XHRcdFx0Ly8gSW5uZXIgc3F1YXJlXG5cdFx0XHRcdFx0Y3R4LmZpbGxTdHlsZSA9IG1lcmdlT3BhY2l0eSh2bS5sYWJlbENvbG9yc1tpXS5iYWNrZ3JvdW5kQ29sb3IsIG9wYWNpdHkpO1xuXHRcdFx0XHRcdGN0eC5maWxsUmVjdChwdC54ICsgMSwgcHQueSArIDEsIGJvZHlGb250U2l6ZSAtIDIsIGJvZHlGb250U2l6ZSAtIDIpO1xuXHRcdFx0XHRcdGN0eC5maWxsU3R5bGUgPSB0ZXh0Q29sb3I7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRmaWxsTGluZU9mVGV4dChsaW5lKTtcblx0XHRcdH0pO1xuXG5cdFx0XHRoZWxwZXJzLmVhY2goYm9keUl0ZW0uYWZ0ZXIsIGZpbGxMaW5lT2ZUZXh0KTtcblx0XHR9KTtcblxuXHRcdC8vIFJlc2V0IGJhY2sgdG8gMCBmb3IgYWZ0ZXIgYm9keVxuXHRcdHhMaW5lUGFkZGluZyA9IDA7XG5cblx0XHQvLyBBZnRlciBib2R5IGxpbmVzXG5cdFx0aGVscGVycy5lYWNoKHZtLmFmdGVyQm9keSwgZmlsbExpbmVPZlRleHQpO1xuXHRcdHB0LnkgLT0gYm9keVNwYWNpbmc7IC8vIFJlbW92ZSBsYXN0IGJvZHkgc3BhY2luZ1xuXHR9LFxuXG5cdGRyYXdGb290ZXI6IGZ1bmN0aW9uKHB0LCB2bSwgY3R4LCBvcGFjaXR5KSB7XG5cdFx0dmFyIGZvb3RlciA9IHZtLmZvb3RlcjtcblxuXHRcdGlmIChmb290ZXIubGVuZ3RoKSB7XG5cdFx0XHRwdC55ICs9IHZtLmZvb3Rlck1hcmdpblRvcDtcblxuXHRcdFx0Y3R4LnRleHRBbGlnbiA9IHZtLl9mb290ZXJBbGlnbjtcblx0XHRcdGN0eC50ZXh0QmFzZWxpbmUgPSAndG9wJztcblxuXHRcdFx0Y3R4LmZpbGxTdHlsZSA9IG1lcmdlT3BhY2l0eSh2bS5mb290ZXJGb250Q29sb3IsIG9wYWNpdHkpO1xuXHRcdFx0Y3R4LmZvbnQgPSBoZWxwZXJzLmZvbnRTdHJpbmcodm0uZm9vdGVyRm9udFNpemUsIHZtLl9mb290ZXJGb250U3R5bGUsIHZtLl9mb290ZXJGb250RmFtaWx5KTtcblxuXHRcdFx0aGVscGVycy5lYWNoKGZvb3RlciwgZnVuY3Rpb24obGluZSkge1xuXHRcdFx0XHRjdHguZmlsbFRleHQobGluZSwgcHQueCwgcHQueSk7XG5cdFx0XHRcdHB0LnkgKz0gdm0uZm9vdGVyRm9udFNpemUgKyB2bS5mb290ZXJTcGFjaW5nO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9LFxuXG5cdGRyYXdCYWNrZ3JvdW5kOiBmdW5jdGlvbihwdCwgdm0sIGN0eCwgdG9vbHRpcFNpemUsIG9wYWNpdHkpIHtcblx0XHRjdHguZmlsbFN0eWxlID0gbWVyZ2VPcGFjaXR5KHZtLmJhY2tncm91bmRDb2xvciwgb3BhY2l0eSk7XG5cdFx0Y3R4LnN0cm9rZVN0eWxlID0gbWVyZ2VPcGFjaXR5KHZtLmJvcmRlckNvbG9yLCBvcGFjaXR5KTtcblx0XHRjdHgubGluZVdpZHRoID0gdm0uYm9yZGVyV2lkdGg7XG5cdFx0dmFyIHhBbGlnbiA9IHZtLnhBbGlnbjtcblx0XHR2YXIgeUFsaWduID0gdm0ueUFsaWduO1xuXHRcdHZhciB4ID0gcHQueDtcblx0XHR2YXIgeSA9IHB0Lnk7XG5cdFx0dmFyIHdpZHRoID0gdG9vbHRpcFNpemUud2lkdGg7XG5cdFx0dmFyIGhlaWdodCA9IHRvb2x0aXBTaXplLmhlaWdodDtcblx0XHR2YXIgcmFkaXVzID0gdm0uY29ybmVyUmFkaXVzO1xuXG5cdFx0Y3R4LmJlZ2luUGF0aCgpO1xuXHRcdGN0eC5tb3ZlVG8oeCArIHJhZGl1cywgeSk7XG5cdFx0aWYgKHlBbGlnbiA9PT0gJ3RvcCcpIHtcblx0XHRcdHRoaXMuZHJhd0NhcmV0KHB0LCB0b29sdGlwU2l6ZSk7XG5cdFx0fVxuXHRcdGN0eC5saW5lVG8oeCArIHdpZHRoIC0gcmFkaXVzLCB5KTtcblx0XHRjdHgucXVhZHJhdGljQ3VydmVUbyh4ICsgd2lkdGgsIHksIHggKyB3aWR0aCwgeSArIHJhZGl1cyk7XG5cdFx0aWYgKHlBbGlnbiA9PT0gJ2NlbnRlcicgJiYgeEFsaWduID09PSAncmlnaHQnKSB7XG5cdFx0XHR0aGlzLmRyYXdDYXJldChwdCwgdG9vbHRpcFNpemUpO1xuXHRcdH1cblx0XHRjdHgubGluZVRvKHggKyB3aWR0aCwgeSArIGhlaWdodCAtIHJhZGl1cyk7XG5cdFx0Y3R4LnF1YWRyYXRpY0N1cnZlVG8oeCArIHdpZHRoLCB5ICsgaGVpZ2h0LCB4ICsgd2lkdGggLSByYWRpdXMsIHkgKyBoZWlnaHQpO1xuXHRcdGlmICh5QWxpZ24gPT09ICdib3R0b20nKSB7XG5cdFx0XHR0aGlzLmRyYXdDYXJldChwdCwgdG9vbHRpcFNpemUpO1xuXHRcdH1cblx0XHRjdHgubGluZVRvKHggKyByYWRpdXMsIHkgKyBoZWlnaHQpO1xuXHRcdGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHgsIHkgKyBoZWlnaHQsIHgsIHkgKyBoZWlnaHQgLSByYWRpdXMpO1xuXHRcdGlmICh5QWxpZ24gPT09ICdjZW50ZXInICYmIHhBbGlnbiA9PT0gJ2xlZnQnKSB7XG5cdFx0XHR0aGlzLmRyYXdDYXJldChwdCwgdG9vbHRpcFNpemUpO1xuXHRcdH1cblx0XHRjdHgubGluZVRvKHgsIHkgKyByYWRpdXMpO1xuXHRcdGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHgsIHksIHggKyByYWRpdXMsIHkpO1xuXHRcdGN0eC5jbG9zZVBhdGgoKTtcblxuXHRcdGN0eC5maWxsKCk7XG5cblx0XHRpZiAodm0uYm9yZGVyV2lkdGggPiAwKSB7XG5cdFx0XHRjdHguc3Ryb2tlKCk7XG5cdFx0fVxuXHR9LFxuXG5cdGRyYXc6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBjdHggPSB0aGlzLl9jaGFydC5jdHg7XG5cdFx0dmFyIHZtID0gdGhpcy5fdmlldztcblxuXHRcdGlmICh2bS5vcGFjaXR5ID09PSAwKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIHRvb2x0aXBTaXplID0ge1xuXHRcdFx0d2lkdGg6IHZtLndpZHRoLFxuXHRcdFx0aGVpZ2h0OiB2bS5oZWlnaHRcblx0XHR9O1xuXHRcdHZhciBwdCA9IHtcblx0XHRcdHg6IHZtLngsXG5cdFx0XHR5OiB2bS55XG5cdFx0fTtcblxuXHRcdC8vIElFMTEvRWRnZSBkb2VzIG5vdCBsaWtlIHZlcnkgc21hbGwgb3BhY2l0aWVzLCBzbyBzbmFwIHRvIDBcblx0XHR2YXIgb3BhY2l0eSA9IE1hdGguYWJzKHZtLm9wYWNpdHkgPCAxZS0zKSA/IDAgOiB2bS5vcGFjaXR5O1xuXG5cdFx0Ly8gVHJ1dGh5L2ZhbHNleSB2YWx1ZSBmb3IgZW1wdHkgdG9vbHRpcFxuXHRcdHZhciBoYXNUb29sdGlwQ29udGVudCA9IHZtLnRpdGxlLmxlbmd0aCB8fCB2bS5iZWZvcmVCb2R5Lmxlbmd0aCB8fCB2bS5ib2R5Lmxlbmd0aCB8fCB2bS5hZnRlckJvZHkubGVuZ3RoIHx8IHZtLmZvb3Rlci5sZW5ndGg7XG5cblx0XHRpZiAodGhpcy5fb3B0aW9ucy5lbmFibGVkICYmIGhhc1Rvb2x0aXBDb250ZW50KSB7XG5cdFx0XHQvLyBEcmF3IEJhY2tncm91bmRcblx0XHRcdHRoaXMuZHJhd0JhY2tncm91bmQocHQsIHZtLCBjdHgsIHRvb2x0aXBTaXplLCBvcGFjaXR5KTtcblxuXHRcdFx0Ly8gRHJhdyBUaXRsZSwgQm9keSwgYW5kIEZvb3RlclxuXHRcdFx0cHQueCArPSB2bS54UGFkZGluZztcblx0XHRcdHB0LnkgKz0gdm0ueVBhZGRpbmc7XG5cblx0XHRcdC8vIFRpdGxlc1xuXHRcdFx0dGhpcy5kcmF3VGl0bGUocHQsIHZtLCBjdHgsIG9wYWNpdHkpO1xuXG5cdFx0XHQvLyBCb2R5XG5cdFx0XHR0aGlzLmRyYXdCb2R5KHB0LCB2bSwgY3R4LCBvcGFjaXR5KTtcblxuXHRcdFx0Ly8gRm9vdGVyXG5cdFx0XHR0aGlzLmRyYXdGb290ZXIocHQsIHZtLCBjdHgsIG9wYWNpdHkpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogSGFuZGxlIGFuIGV2ZW50XG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7SUV2ZW50fSBldmVudCAtIFRoZSBldmVudCB0byBoYW5kbGVcblx0ICogQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgdGhlIHRvb2x0aXAgY2hhbmdlZFxuXHQgKi9cblx0aGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGUpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciBvcHRpb25zID0gbWUuX29wdGlvbnM7XG5cdFx0dmFyIGNoYW5nZWQgPSBmYWxzZTtcblxuXHRcdG1lLl9sYXN0QWN0aXZlID0gbWUuX2xhc3RBY3RpdmUgfHwgW107XG5cblx0XHQvLyBGaW5kIEFjdGl2ZSBFbGVtZW50cyBmb3IgdG9vbHRpcHNcblx0XHRpZiAoZS50eXBlID09PSAnbW91c2VvdXQnKSB7XG5cdFx0XHRtZS5fYWN0aXZlID0gW107XG5cdFx0fSBlbHNlIHtcblx0XHRcdG1lLl9hY3RpdmUgPSBtZS5fY2hhcnQuZ2V0RWxlbWVudHNBdEV2ZW50Rm9yTW9kZShlLCBvcHRpb25zLm1vZGUsIG9wdGlvbnMpO1xuXHRcdH1cblxuXHRcdC8vIFJlbWVtYmVyIExhc3QgQWN0aXZlc1xuXHRcdGNoYW5nZWQgPSAhaGVscGVycy5hcnJheUVxdWFscyhtZS5fYWN0aXZlLCBtZS5fbGFzdEFjdGl2ZSk7XG5cblx0XHQvLyBPbmx5IGhhbmRsZSB0YXJnZXQgZXZlbnQgb24gdG9vbHRpcCBjaGFuZ2Vcblx0XHRpZiAoY2hhbmdlZCkge1xuXHRcdFx0bWUuX2xhc3RBY3RpdmUgPSBtZS5fYWN0aXZlO1xuXG5cdFx0XHRpZiAob3B0aW9ucy5lbmFibGVkIHx8IG9wdGlvbnMuY3VzdG9tKSB7XG5cdFx0XHRcdG1lLl9ldmVudFBvc2l0aW9uID0ge1xuXHRcdFx0XHRcdHg6IGUueCxcblx0XHRcdFx0XHR5OiBlLnlcblx0XHRcdFx0fTtcblxuXHRcdFx0XHRtZS51cGRhdGUodHJ1ZSk7XG5cdFx0XHRcdG1lLnBpdm90KCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNoYW5nZWQ7XG5cdH1cbn0pO1xuXG4vKipcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuVG9vbHRpcC5wb3NpdGlvbmVyc1xuICovXG5leHBvcnRzLnBvc2l0aW9uZXJzID0gcG9zaXRpb25lcnM7XG5cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9af9\n")},a87cc:function(module,exports,__webpack_require__){"use strict";eval("/* global window: false */\n\n\nvar moment = __webpack_require__(/*! moment */ \"da01\");\nmoment = typeof moment === 'function' ? moment : window.moment;\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\nvar Scale = __webpack_require__(/*! ../core/core.scale */ \"d1b4\");\nvar scaleService = __webpack_require__(/*! ../core/core.scaleService */ \"7c56\");\n\n// Integer constants are from the ES6 spec.\nvar MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991;\nvar MAX_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;\n\nvar INTERVALS = {\n\tmillisecond: {\n\t\tcommon: true,\n\t\tsize: 1,\n\t\tsteps: [1, 2, 5, 10, 20, 50, 100, 250, 500]\n\t},\n\tsecond: {\n\t\tcommon: true,\n\t\tsize: 1000,\n\t\tsteps: [1, 2, 5, 10, 15, 30]\n\t},\n\tminute: {\n\t\tcommon: true,\n\t\tsize: 60000,\n\t\tsteps: [1, 2, 5, 10, 15, 30]\n\t},\n\thour: {\n\t\tcommon: true,\n\t\tsize: 3600000,\n\t\tsteps: [1, 2, 3, 6, 12]\n\t},\n\tday: {\n\t\tcommon: true,\n\t\tsize: 86400000,\n\t\tsteps: [1, 2, 5]\n\t},\n\tweek: {\n\t\tcommon: false,\n\t\tsize: 604800000,\n\t\tsteps: [1, 2, 3, 4]\n\t},\n\tmonth: {\n\t\tcommon: true,\n\t\tsize: 2.628e9,\n\t\tsteps: [1, 2, 3]\n\t},\n\tquarter: {\n\t\tcommon: false,\n\t\tsize: 7.884e9,\n\t\tsteps: [1, 2, 3, 4]\n\t},\n\tyear: {\n\t\tcommon: true,\n\t\tsize: 3.154e10\n\t}\n};\n\nvar UNITS = Object.keys(INTERVALS);\n\nfunction sorter(a, b) {\n\treturn a - b;\n}\n\nfunction arrayUnique(items) {\n\tvar hash = {};\n\tvar out = [];\n\tvar i, ilen, item;\n\n\tfor (i = 0, ilen = items.length; i < ilen; ++i) {\n\t\titem = items[i];\n\t\tif (!hash[item]) {\n\t\t\thash[item] = true;\n\t\t\tout.push(item);\n\t\t}\n\t}\n\n\treturn out;\n}\n\n/**\n * Returns an array of {time, pos} objects used to interpolate a specific `time` or position\n * (`pos`) on the scale, by searching entries before and after the requested value. `pos` is\n * a decimal between 0 and 1: 0 being the start of the scale (left or top) and 1 the other\n * extremity (left + width or top + height). Note that it would be more optimized to directly\n * store pre-computed pixels, but the scale dimensions are not guaranteed at the time we need\n * to create the lookup table. The table ALWAYS contains at least two items: min and max.\n *\n * @param {Number[]} timestamps - timestamps sorted from lowest to highest.\n * @param {String} distribution - If 'linear', timestamps will be spread linearly along the min\n * and max range, so basically, the table will contains only two items: {min, 0} and {max, 1}.\n * If 'series', timestamps will be positioned at the same distance from each other. In this\n * case, only timestamps that break the time linearity are registered, meaning that in the\n * best case, all timestamps are linear, the table contains only min and max.\n */\nfunction buildLookupTable(timestamps, min, max, distribution) {\n\tif (distribution === 'linear' || !timestamps.length) {\n\t\treturn [\n\t\t\t{time: min, pos: 0},\n\t\t\t{time: max, pos: 1}\n\t\t];\n\t}\n\n\tvar table = [];\n\tvar items = [min];\n\tvar i, ilen, prev, curr, next;\n\n\tfor (i = 0, ilen = timestamps.length; i < ilen; ++i) {\n\t\tcurr = timestamps[i];\n\t\tif (curr > min && curr < max) {\n\t\t\titems.push(curr);\n\t\t}\n\t}\n\n\titems.push(max);\n\n\tfor (i = 0, ilen = items.length; i < ilen; ++i) {\n\t\tnext = items[i + 1];\n\t\tprev = items[i - 1];\n\t\tcurr = items[i];\n\n\t\t// only add points that breaks the scale linearity\n\t\tif (prev === undefined || next === undefined || Math.round((next + prev) / 2) !== curr) {\n\t\t\ttable.push({time: curr, pos: i / (ilen - 1)});\n\t\t}\n\t}\n\n\treturn table;\n}\n\n// @see adapted from http://www.anujgakhar.com/2014/03/01/binary-search-in-javascript/\nfunction lookup(table, key, value) {\n\tvar lo = 0;\n\tvar hi = table.length - 1;\n\tvar mid, i0, i1;\n\n\twhile (lo >= 0 && lo <= hi) {\n\t\tmid = (lo + hi) >> 1;\n\t\ti0 = table[mid - 1] || null;\n\t\ti1 = table[mid];\n\n\t\tif (!i0) {\n\t\t\t// given value is outside table (before first item)\n\t\t\treturn {lo: null, hi: i1};\n\t\t} else if (i1[key] < value) {\n\t\t\tlo = mid + 1;\n\t\t} else if (i0[key] > value) {\n\t\t\thi = mid - 1;\n\t\t} else {\n\t\t\treturn {lo: i0, hi: i1};\n\t\t}\n\t}\n\n\t// given value is outside table (after last item)\n\treturn {lo: i1, hi: null};\n}\n\n/**\n * Linearly interpolates the given source `value` using the table items `skey` values and\n * returns the associated `tkey` value. For example, interpolate(table, 'time', 42, 'pos')\n * returns the position for a timestamp equal to 42. If value is out of bounds, values at\n * index [0, 1] or [n - 1, n] are used for the interpolation.\n */\nfunction interpolate(table, skey, sval, tkey) {\n\tvar range = lookup(table, skey, sval);\n\n\t// Note: the lookup table ALWAYS contains at least 2 items (min and max)\n\tvar prev = !range.lo ? table[0] : !range.hi ? table[table.length - 2] : range.lo;\n\tvar next = !range.lo ? table[1] : !range.hi ? table[table.length - 1] : range.hi;\n\n\tvar span = next[skey] - prev[skey];\n\tvar ratio = span ? (sval - prev[skey]) / span : 0;\n\tvar offset = (next[tkey] - prev[tkey]) * ratio;\n\n\treturn prev[tkey] + offset;\n}\n\n/**\n * Convert the given value to a moment object using the given time options.\n * @see http://momentjs.com/docs/#/parsing/\n */\nfunction momentify(value, options) {\n\tvar parser = options.parser;\n\tvar format = options.parser || options.format;\n\n\tif (typeof parser === 'function') {\n\t\treturn parser(value);\n\t}\n\n\tif (typeof value === 'string' && typeof format === 'string') {\n\t\treturn moment(value, format);\n\t}\n\n\tif (!(value instanceof moment)) {\n\t\tvalue = moment(value);\n\t}\n\n\tif (value.isValid()) {\n\t\treturn value;\n\t}\n\n\t// Labels are in an incompatible moment format and no `parser` has been provided.\n\t// The user might still use the deprecated `format` option to convert his inputs.\n\tif (typeof format === 'function') {\n\t\treturn format(value);\n\t}\n\n\treturn value;\n}\n\nfunction parse(input, scale) {\n\tif (helpers.isNullOrUndef(input)) {\n\t\treturn null;\n\t}\n\n\tvar options = scale.options.time;\n\tvar value = momentify(scale.getRightValue(input), options);\n\tif (!value.isValid()) {\n\t\treturn null;\n\t}\n\n\tif (options.round) {\n\t\tvalue.startOf(options.round);\n\t}\n\n\treturn value.valueOf();\n}\n\n/**\n * Returns the number of unit to skip to be able to display up to `capacity` number of ticks\n * in `unit` for the given `min` / `max` range and respecting the interval steps constraints.\n */\nfunction determineStepSize(min, max, unit, capacity) {\n\tvar range = max - min;\n\tvar interval = INTERVALS[unit];\n\tvar milliseconds = interval.size;\n\tvar steps = interval.steps;\n\tvar i, ilen, factor;\n\n\tif (!steps) {\n\t\treturn Math.ceil(range / (capacity * milliseconds));\n\t}\n\n\tfor (i = 0, ilen = steps.length; i < ilen; ++i) {\n\t\tfactor = steps[i];\n\t\tif (Math.ceil(range / (milliseconds * factor)) <= capacity) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn factor;\n}\n\n/**\n * Figures out what unit results in an appropriate number of auto-generated ticks\n */\nfunction determineUnitForAutoTicks(minUnit, min, max, capacity) {\n\tvar ilen = UNITS.length;\n\tvar i, interval, factor;\n\n\tfor (i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) {\n\t\tinterval = INTERVALS[UNITS[i]];\n\t\tfactor = interval.steps ? interval.steps[interval.steps.length - 1] : MAX_INTEGER;\n\n\t\tif (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) {\n\t\t\treturn UNITS[i];\n\t\t}\n\t}\n\n\treturn UNITS[ilen - 1];\n}\n\n/**\n * Figures out what unit to format a set of ticks with\n */\nfunction determineUnitForFormatting(ticks, minUnit, min, max) {\n\tvar duration = moment.duration(moment(max).diff(moment(min)));\n\tvar ilen = UNITS.length;\n\tvar i, unit;\n\n\tfor (i = ilen - 1; i >= UNITS.indexOf(minUnit); i--) {\n\t\tunit = UNITS[i];\n\t\tif (INTERVALS[unit].common && duration.as(unit) >= ticks.length) {\n\t\t\treturn unit;\n\t\t}\n\t}\n\n\treturn UNITS[minUnit ? UNITS.indexOf(minUnit) : 0];\n}\n\nfunction determineMajorUnit(unit) {\n\tfor (var i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) {\n\t\tif (INTERVALS[UNITS[i]].common) {\n\t\t\treturn UNITS[i];\n\t\t}\n\t}\n}\n\n/**\n * Generates a maximum of `capacity` timestamps between min and max, rounded to the\n * `minor` unit, aligned on the `major` unit and using the given scale time `options`.\n * Important: this method can return ticks outside the min and max range, it's the\n * responsibility of the calling code to clamp values if needed.\n */\nfunction generate(min, max, capacity, options) {\n\tvar timeOpts = options.time;\n\tvar minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, capacity);\n\tvar major = determineMajorUnit(minor);\n\tvar stepSize = helpers.valueOrDefault(timeOpts.stepSize, timeOpts.unitStepSize);\n\tvar weekday = minor === 'week' ? timeOpts.isoWeekday : false;\n\tvar majorTicksEnabled = options.ticks.major.enabled;\n\tvar interval = INTERVALS[minor];\n\tvar first = moment(min);\n\tvar last = moment(max);\n\tvar ticks = [];\n\tvar time;\n\n\tif (!stepSize) {\n\t\tstepSize = determineStepSize(min, max, minor, capacity);\n\t}\n\n\t// For 'week' unit, handle the first day of week option\n\tif (weekday) {\n\t\tfirst = first.isoWeekday(weekday);\n\t\tlast = last.isoWeekday(weekday);\n\t}\n\n\t// Align first/last ticks on unit\n\tfirst = first.startOf(weekday ? 'day' : minor);\n\tlast = last.startOf(weekday ? 'day' : minor);\n\n\t// Make sure that the last tick include max\n\tif (last < max) {\n\t\tlast.add(1, minor);\n\t}\n\n\ttime = moment(first);\n\n\tif (majorTicksEnabled && major && !weekday && !timeOpts.round) {\n\t\t// Align the first tick on the previous `minor` unit aligned on the `major` unit:\n\t\t// we first aligned time on the previous `major` unit then add the number of full\n\t\t// stepSize there is between first and the previous major time.\n\t\ttime.startOf(major);\n\t\ttime.add(~~((first - time) / (interval.size * stepSize)) * stepSize, minor);\n\t}\n\n\tfor (; time < last; time.add(stepSize, minor)) {\n\t\tticks.push(+time);\n\t}\n\n\tticks.push(+time);\n\n\treturn ticks;\n}\n\n/**\n * Returns the right and left offsets from edges in the form of {left, right}.\n * Offsets are added when the `offset` option is true.\n */\nfunction computeOffsets(table, ticks, min, max, options) {\n\tvar left = 0;\n\tvar right = 0;\n\tvar upper, lower;\n\n\tif (options.offset && ticks.length) {\n\t\tif (!options.time.min) {\n\t\t\tupper = ticks.length > 1 ? ticks[1] : max;\n\t\t\tlower = ticks[0];\n\t\t\tleft = (\n\t\t\t\tinterpolate(table, 'time', upper, 'pos') -\n\t\t\t\tinterpolate(table, 'time', lower, 'pos')\n\t\t\t) / 2;\n\t\t}\n\t\tif (!options.time.max) {\n\t\t\tupper = ticks[ticks.length - 1];\n\t\t\tlower = ticks.length > 1 ? ticks[ticks.length - 2] : min;\n\t\t\tright = (\n\t\t\t\tinterpolate(table, 'time', upper, 'pos') -\n\t\t\t\tinterpolate(table, 'time', lower, 'pos')\n\t\t\t) / 2;\n\t\t}\n\t}\n\n\treturn {left: left, right: right};\n}\n\nfunction ticksFromTimestamps(values, majorUnit) {\n\tvar ticks = [];\n\tvar i, ilen, value, major;\n\n\tfor (i = 0, ilen = values.length; i < ilen; ++i) {\n\t\tvalue = values[i];\n\t\tmajor = majorUnit ? value === +moment(value).startOf(majorUnit) : false;\n\n\t\tticks.push({\n\t\t\tvalue: value,\n\t\t\tmajor: major\n\t\t});\n\t}\n\n\treturn ticks;\n}\n\nfunction determineLabelFormat(data, timeOpts) {\n\tvar i, momentDate, hasTime;\n\tvar ilen = data.length;\n\n\t// find the label with the most parts (milliseconds, minutes, etc.)\n\t// format all labels with the same level of detail as the most specific label\n\tfor (i = 0; i < ilen; i++) {\n\t\tmomentDate = momentify(data[i], timeOpts);\n\t\tif (momentDate.millisecond() !== 0) {\n\t\t\treturn 'MMM D, YYYY h:mm:ss.SSS a';\n\t\t}\n\t\tif (momentDate.second() !== 0 || momentDate.minute() !== 0 || momentDate.hour() !== 0) {\n\t\t\thasTime = true;\n\t\t}\n\t}\n\tif (hasTime) {\n\t\treturn 'MMM D, YYYY h:mm:ss a';\n\t}\n\treturn 'MMM D, YYYY';\n}\n\nmodule.exports = function() {\n\n\tvar defaultConfig = {\n\t\tposition: 'bottom',\n\n\t\t/**\n\t\t * Data distribution along the scale:\n\t\t * - 'linear': data are spread according to their time (distances can vary),\n\t\t * - 'series': data are spread at the same distance from each other.\n\t\t * @see https://github.com/chartjs/Chart.js/pull/4507\n\t\t * @since 2.7.0\n\t\t */\n\t\tdistribution: 'linear',\n\n\t\t/**\n\t\t * Scale boundary strategy (bypassed by min/max time options)\n\t\t * - `data`: make sure data are fully visible, ticks outside are removed\n\t\t * - `ticks`: make sure ticks are fully visible, data outside are truncated\n\t\t * @see https://github.com/chartjs/Chart.js/pull/4556\n\t\t * @since 2.7.0\n\t\t */\n\t\tbounds: 'data',\n\n\t\ttime: {\n\t\t\tparser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment\n\t\t\tformat: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/\n\t\t\tunit: false, // false == automatic or override with week, month, year, etc.\n\t\t\tround: false, // none, or override with week, month, year, etc.\n\t\t\tdisplayFormat: false, // DEPRECATED\n\t\t\tisoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/\n\t\t\tminUnit: 'millisecond',\n\n\t\t\t// defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/\n\t\t\tdisplayFormats: {\n\t\t\t\tmillisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM,\n\t\t\t\tsecond: 'h:mm:ss a', // 11:20:01 AM\n\t\t\t\tminute: 'h:mm a', // 11:20 AM\n\t\t\t\thour: 'hA', // 5PM\n\t\t\t\tday: 'MMM D', // Sep 4\n\t\t\t\tweek: 'll', // Week 46, or maybe \"[W]WW - YYYY\" ?\n\t\t\t\tmonth: 'MMM YYYY', // Sept 2015\n\t\t\t\tquarter: '[Q]Q - YYYY', // Q3\n\t\t\t\tyear: 'YYYY' // 2015\n\t\t\t},\n\t\t},\n\t\tticks: {\n\t\t\tautoSkip: false,\n\n\t\t\t/**\n\t\t\t * Ticks generation input values:\n\t\t\t * - 'auto': generates \"optimal\" ticks based on scale size and time options.\n\t\t\t * - 'data': generates ticks from data (including labels from data {t|x|y} objects).\n\t\t\t * - 'labels': generates ticks from user given `data.labels` values ONLY.\n\t\t\t * @see https://github.com/chartjs/Chart.js/pull/4507\n\t\t\t * @since 2.7.0\n\t\t\t */\n\t\t\tsource: 'auto',\n\n\t\t\tmajor: {\n\t\t\t\tenabled: false\n\t\t\t}\n\t\t}\n\t};\n\n\tvar TimeScale = Scale.extend({\n\t\tinitialize: function() {\n\t\t\tif (!moment) {\n\t\t\t\tthrow new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com');\n\t\t\t}\n\n\t\t\tthis.mergeTicksOptions();\n\n\t\t\tScale.prototype.initialize.call(this);\n\t\t},\n\n\t\tupdate: function() {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\n\t\t\t// DEPRECATIONS: output a message only one time per update\n\t\t\tif (options.time && options.time.format) {\n\t\t\t\tconsole.warn('options.time.format is deprecated and replaced by options.time.parser.');\n\t\t\t}\n\n\t\t\treturn Scale.prototype.update.apply(me, arguments);\n\t\t},\n\n\t\t/**\n\t\t * Allows data to be referenced via 't' attribute\n\t\t */\n\t\tgetRightValue: function(rawValue) {\n\t\t\tif (rawValue && rawValue.t !== undefined) {\n\t\t\t\trawValue = rawValue.t;\n\t\t\t}\n\t\t\treturn Scale.prototype.getRightValue.call(this, rawValue);\n\t\t},\n\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar timeOpts = me.options.time;\n\t\t\tvar unit = timeOpts.unit || 'day';\n\t\t\tvar min = MAX_INTEGER;\n\t\t\tvar max = MIN_INTEGER;\n\t\t\tvar timestamps = [];\n\t\t\tvar datasets = [];\n\t\t\tvar labels = [];\n\t\t\tvar i, j, ilen, jlen, data, timestamp;\n\n\t\t\t// Convert labels to timestamps\n\t\t\tfor (i = 0, ilen = chart.data.labels.length; i < ilen; ++i) {\n\t\t\t\tlabels.push(parse(chart.data.labels[i], me));\n\t\t\t}\n\n\t\t\t// Convert data to timestamps\n\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\tif (chart.isDatasetVisible(i)) {\n\t\t\t\t\tdata = chart.data.datasets[i].data;\n\n\t\t\t\t\t// Let's consider that all data have the same format.\n\t\t\t\t\tif (helpers.isObject(data[0])) {\n\t\t\t\t\t\tdatasets[i] = [];\n\n\t\t\t\t\t\tfor (j = 0, jlen = data.length; j < jlen; ++j) {\n\t\t\t\t\t\t\ttimestamp = parse(data[j], me);\n\t\t\t\t\t\t\ttimestamps.push(timestamp);\n\t\t\t\t\t\t\tdatasets[i][j] = timestamp;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttimestamps.push.apply(timestamps, labels);\n\t\t\t\t\t\tdatasets[i] = labels.slice(0);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tdatasets[i] = [];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (labels.length) {\n\t\t\t\t// Sort labels **after** data have been converted\n\t\t\t\tlabels = arrayUnique(labels).sort(sorter);\n\t\t\t\tmin = Math.min(min, labels[0]);\n\t\t\t\tmax = Math.max(max, labels[labels.length - 1]);\n\t\t\t}\n\n\t\t\tif (timestamps.length) {\n\t\t\t\ttimestamps = arrayUnique(timestamps).sort(sorter);\n\t\t\t\tmin = Math.min(min, timestamps[0]);\n\t\t\t\tmax = Math.max(max, timestamps[timestamps.length - 1]);\n\t\t\t}\n\n\t\t\tmin = parse(timeOpts.min, me) || min;\n\t\t\tmax = parse(timeOpts.max, me) || max;\n\n\t\t\t// In case there is no valid min/max, set limits based on unit time option\n\t\t\tmin = min === MAX_INTEGER ? +moment().startOf(unit) : min;\n\t\t\tmax = max === MIN_INTEGER ? +moment().endOf(unit) + 1 : max;\n\n\t\t\t// Make sure that max is strictly higher than min (required by the lookup table)\n\t\t\tme.min = Math.min(min, max);\n\t\t\tme.max = Math.max(min + 1, max);\n\n\t\t\t// PRIVATE\n\t\t\tme._horizontal = me.isHorizontal();\n\t\t\tme._table = [];\n\t\t\tme._timestamps = {\n\t\t\t\tdata: timestamps,\n\t\t\t\tdatasets: datasets,\n\t\t\t\tlabels: labels\n\t\t\t};\n\t\t},\n\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar min = me.min;\n\t\t\tvar max = me.max;\n\t\t\tvar options = me.options;\n\t\t\tvar timeOpts = options.time;\n\t\t\tvar timestamps = [];\n\t\t\tvar ticks = [];\n\t\t\tvar i, ilen, timestamp;\n\n\t\t\tswitch (options.ticks.source) {\n\t\t\tcase 'data':\n\t\t\t\ttimestamps = me._timestamps.data;\n\t\t\t\tbreak;\n\t\t\tcase 'labels':\n\t\t\t\ttimestamps = me._timestamps.labels;\n\t\t\t\tbreak;\n\t\t\tcase 'auto':\n\t\t\tdefault:\n\t\t\t\ttimestamps = generate(min, max, me.getLabelCapacity(min), options);\n\t\t\t}\n\n\t\t\tif (options.bounds === 'ticks' && timestamps.length) {\n\t\t\t\tmin = timestamps[0];\n\t\t\t\tmax = timestamps[timestamps.length - 1];\n\t\t\t}\n\n\t\t\t// Enforce limits with user min/max options\n\t\t\tmin = parse(timeOpts.min, me) || min;\n\t\t\tmax = parse(timeOpts.max, me) || max;\n\n\t\t\t// Remove ticks outside the min/max range\n\t\t\tfor (i = 0, ilen = timestamps.length; i < ilen; ++i) {\n\t\t\t\ttimestamp = timestamps[i];\n\t\t\t\tif (timestamp >= min && timestamp <= max) {\n\t\t\t\t\tticks.push(timestamp);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tme.min = min;\n\t\t\tme.max = max;\n\n\t\t\t// PRIVATE\n\t\t\tme._unit = timeOpts.unit || determineUnitForFormatting(ticks, timeOpts.minUnit, me.min, me.max);\n\t\t\tme._majorUnit = determineMajorUnit(me._unit);\n\t\t\tme._table = buildLookupTable(me._timestamps.data, min, max, options.distribution);\n\t\t\tme._offsets = computeOffsets(me._table, ticks, min, max, options);\n\t\t\tme._labelFormat = determineLabelFormat(me._timestamps.data, timeOpts);\n\n\t\t\treturn ticksFromTimestamps(ticks, me._majorUnit);\n\t\t},\n\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar data = me.chart.data;\n\t\t\tvar timeOpts = me.options.time;\n\t\t\tvar label = data.labels && index < data.labels.length ? data.labels[index] : '';\n\t\t\tvar value = data.datasets[datasetIndex].data[index];\n\n\t\t\tif (helpers.isObject(value)) {\n\t\t\t\tlabel = me.getRightValue(value);\n\t\t\t}\n\t\t\tif (timeOpts.tooltipFormat) {\n\t\t\t\treturn momentify(label, timeOpts).format(timeOpts.tooltipFormat);\n\t\t\t}\n\t\t\tif (typeof label === 'string') {\n\t\t\t\treturn label;\n\t\t\t}\n\n\t\t\treturn momentify(label, timeOpts).format(me._labelFormat);\n\t\t},\n\n\t\t/**\n\t\t * Function to format an individual tick mark\n\t\t * @private\n\t\t */\n\t\ttickFormatFunction: function(tick, index, ticks, formatOverride) {\n\t\t\tvar me = this;\n\t\t\tvar options = me.options;\n\t\t\tvar time = tick.valueOf();\n\t\t\tvar formats = options.time.displayFormats;\n\t\t\tvar minorFormat = formats[me._unit];\n\t\t\tvar majorUnit = me._majorUnit;\n\t\t\tvar majorFormat = formats[majorUnit];\n\t\t\tvar majorTime = tick.clone().startOf(majorUnit).valueOf();\n\t\t\tvar majorTickOpts = options.ticks.major;\n\t\t\tvar major = majorTickOpts.enabled && majorUnit && majorFormat && time === majorTime;\n\t\t\tvar label = tick.format(formatOverride ? formatOverride : major ? majorFormat : minorFormat);\n\t\t\tvar tickOpts = major ? majorTickOpts : options.ticks.minor;\n\t\t\tvar formatter = helpers.valueOrDefault(tickOpts.callback, tickOpts.userCallback);\n\n\t\t\treturn formatter ? formatter(label, index, ticks) : label;\n\t\t},\n\n\t\tconvertTicksToLabels: function(ticks) {\n\t\t\tvar labels = [];\n\t\t\tvar i, ilen;\n\n\t\t\tfor (i = 0, ilen = ticks.length; i < ilen; ++i) {\n\t\t\t\tlabels.push(this.tickFormatFunction(moment(ticks[i].value), i, ticks));\n\t\t\t}\n\n\t\t\treturn labels;\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetPixelForOffset: function(time) {\n\t\t\tvar me = this;\n\t\t\tvar size = me._horizontal ? me.width : me.height;\n\t\t\tvar start = me._horizontal ? me.left : me.top;\n\t\t\tvar pos = interpolate(me._table, 'time', time, 'pos');\n\n\t\t\treturn start + size * (me._offsets.left + pos) / (me._offsets.left + 1 + me._offsets.right);\n\t\t},\n\n\t\tgetPixelForValue: function(value, index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar time = null;\n\n\t\t\tif (index !== undefined && datasetIndex !== undefined) {\n\t\t\t\ttime = me._timestamps.datasets[datasetIndex][index];\n\t\t\t}\n\n\t\t\tif (time === null) {\n\t\t\t\ttime = parse(value, me);\n\t\t\t}\n\n\t\t\tif (time !== null) {\n\t\t\t\treturn me.getPixelForOffset(time);\n\t\t\t}\n\t\t},\n\n\t\tgetPixelForTick: function(index) {\n\t\t\tvar ticks = this.getTicks();\n\t\t\treturn index >= 0 && index < ticks.length ?\n\t\t\t\tthis.getPixelForOffset(ticks[index].value) :\n\t\t\t\tnull;\n\t\t},\n\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar size = me._horizontal ? me.width : me.height;\n\t\t\tvar start = me._horizontal ? me.left : me.top;\n\t\t\tvar pos = (size ? (pixel - start) / size : 0) * (me._offsets.left + 1 + me._offsets.left) - me._offsets.right;\n\t\t\tvar time = interpolate(me._table, 'pos', pos, 'time');\n\n\t\t\treturn moment(time);\n\t\t},\n\n\t\t/**\n\t\t * Crude approximation of what the label width might be\n\t\t * @private\n\t\t */\n\t\tgetLabelWidth: function(label) {\n\t\t\tvar me = this;\n\t\t\tvar ticksOpts = me.options.ticks;\n\t\t\tvar tickLabelWidth = me.ctx.measureText(label).width;\n\t\t\tvar angle = helpers.toRadians(ticksOpts.maxRotation);\n\t\t\tvar cosRotation = Math.cos(angle);\n\t\t\tvar sinRotation = Math.sin(angle);\n\t\t\tvar tickFontSize = helpers.valueOrDefault(ticksOpts.fontSize, defaults.global.defaultFontSize);\n\n\t\t\treturn (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);\n\t\t},\n\n\t\t/**\n\t\t * @private\n\t\t */\n\t\tgetLabelCapacity: function(exampleTime) {\n\t\t\tvar me = this;\n\n\t\t\tvar formatOverride = me.options.time.displayFormats.millisecond;\t// Pick the longest format for guestimation\n\n\t\t\tvar exampleLabel = me.tickFormatFunction(moment(exampleTime), 0, [], formatOverride);\n\t\t\tvar tickLabelWidth = me.getLabelWidth(exampleLabel);\n\t\t\tvar innerWidth = me.isHorizontal() ? me.width : me.height;\n\n\t\t\tvar capacity = Math.floor(innerWidth / tickLabelWidth);\n\t\t\treturn capacity > 0 ? capacity : 1;\n\t\t}\n\t});\n\n\tscaleService.registerScaleType('time', TimeScale, defaultConfig);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYTg3Y2MuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3NjYWxlcy9zY2FsZS50aW1lLmpzPzQ0MjEiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZ2xvYmFsIHdpbmRvdzogZmFsc2UgKi9cbid1c2Ugc3RyaWN0JztcblxudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudCcpO1xubW9tZW50ID0gdHlwZW9mIG1vbWVudCA9PT0gJ2Z1bmN0aW9uJyA/IG1vbWVudCA6IHdpbmRvdy5tb21lbnQ7XG5cbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5kZWZhdWx0cycpO1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2luZGV4Jyk7XG52YXIgU2NhbGUgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuc2NhbGUnKTtcbnZhciBzY2FsZVNlcnZpY2UgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuc2NhbGVTZXJ2aWNlJyk7XG5cbi8vIEludGVnZXIgY29uc3RhbnRzIGFyZSBmcm9tIHRoZSBFUzYgc3BlYy5cbnZhciBNSU5fSU5URUdFUiA9IE51bWJlci5NSU5fU0FGRV9JTlRFR0VSIHx8IC05MDA3MTk5MjU0NzQwOTkxO1xudmFyIE1BWF9JTlRFR0VSID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgfHwgOTAwNzE5OTI1NDc0MDk5MTtcblxudmFyIElOVEVSVkFMUyA9IHtcblx0bWlsbGlzZWNvbmQ6IHtcblx0XHRjb21tb246IHRydWUsXG5cdFx0c2l6ZTogMSxcblx0XHRzdGVwczogWzEsIDIsIDUsIDEwLCAyMCwgNTAsIDEwMCwgMjUwLCA1MDBdXG5cdH0sXG5cdHNlY29uZDoge1xuXHRcdGNvbW1vbjogdHJ1ZSxcblx0XHRzaXplOiAxMDAwLFxuXHRcdHN0ZXBzOiBbMSwgMiwgNSwgMTAsIDE1LCAzMF1cblx0fSxcblx0bWludXRlOiB7XG5cdFx0Y29tbW9uOiB0cnVlLFxuXHRcdHNpemU6IDYwMDAwLFxuXHRcdHN0ZXBzOiBbMSwgMiwgNSwgMTAsIDE1LCAzMF1cblx0fSxcblx0aG91cjoge1xuXHRcdGNvbW1vbjogdHJ1ZSxcblx0XHRzaXplOiAzNjAwMDAwLFxuXHRcdHN0ZXBzOiBbMSwgMiwgMywgNiwgMTJdXG5cdH0sXG5cdGRheToge1xuXHRcdGNvbW1vbjogdHJ1ZSxcblx0XHRzaXplOiA4NjQwMDAwMCxcblx0XHRzdGVwczogWzEsIDIsIDVdXG5cdH0sXG5cdHdlZWs6IHtcblx0XHRjb21tb246IGZhbHNlLFxuXHRcdHNpemU6IDYwNDgwMDAwMCxcblx0XHRzdGVwczogWzEsIDIsIDMsIDRdXG5cdH0sXG5cdG1vbnRoOiB7XG5cdFx0Y29tbW9uOiB0cnVlLFxuXHRcdHNpemU6IDIuNjI4ZTksXG5cdFx0c3RlcHM6IFsxLCAyLCAzXVxuXHR9LFxuXHRxdWFydGVyOiB7XG5cdFx0Y29tbW9uOiBmYWxzZSxcblx0XHRzaXplOiA3Ljg4NGU5LFxuXHRcdHN0ZXBzOiBbMSwgMiwgMywgNF1cblx0fSxcblx0eWVhcjoge1xuXHRcdGNvbW1vbjogdHJ1ZSxcblx0XHRzaXplOiAzLjE1NGUxMFxuXHR9XG59O1xuXG52YXIgVU5JVFMgPSBPYmplY3Qua2V5cyhJTlRFUlZBTFMpO1xuXG5mdW5jdGlvbiBzb3J0ZXIoYSwgYikge1xuXHRyZXR1cm4gYSAtIGI7XG59XG5cbmZ1bmN0aW9uIGFycmF5VW5pcXVlKGl0ZW1zKSB7XG5cdHZhciBoYXNoID0ge307XG5cdHZhciBvdXQgPSBbXTtcblx0dmFyIGksIGlsZW4sIGl0ZW07XG5cblx0Zm9yIChpID0gMCwgaWxlbiA9IGl0ZW1zLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdGl0ZW0gPSBpdGVtc1tpXTtcblx0XHRpZiAoIWhhc2hbaXRlbV0pIHtcblx0XHRcdGhhc2hbaXRlbV0gPSB0cnVlO1xuXHRcdFx0b3V0LnB1c2goaXRlbSk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIGFycmF5IG9mIHt0aW1lLCBwb3N9IG9iamVjdHMgdXNlZCB0byBpbnRlcnBvbGF0ZSBhIHNwZWNpZmljIGB0aW1lYCBvciBwb3NpdGlvblxuICogKGBwb3NgKSBvbiB0aGUgc2NhbGUsIGJ5IHNlYXJjaGluZyBlbnRyaWVzIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIHJlcXVlc3RlZCB2YWx1ZS4gYHBvc2AgaXNcbiAqIGEgZGVjaW1hbCBiZXR3ZWVuIDAgYW5kIDE6IDAgYmVpbmcgdGhlIHN0YXJ0IG9mIHRoZSBzY2FsZSAobGVmdCBvciB0b3ApIGFuZCAxIHRoZSBvdGhlclxuICogZXh0cmVtaXR5IChsZWZ0ICsgd2lkdGggb3IgdG9wICsgaGVpZ2h0KS4gTm90ZSB0aGF0IGl0IHdvdWxkIGJlIG1vcmUgb3B0aW1pemVkIHRvIGRpcmVjdGx5XG4gKiBzdG9yZSBwcmUtY29tcHV0ZWQgcGl4ZWxzLCBidXQgdGhlIHNjYWxlIGRpbWVuc2lvbnMgYXJlIG5vdCBndWFyYW50ZWVkIGF0IHRoZSB0aW1lIHdlIG5lZWRcbiAqIHRvIGNyZWF0ZSB0aGUgbG9va3VwIHRhYmxlLiBUaGUgdGFibGUgQUxXQVlTIGNvbnRhaW5zIGF0IGxlYXN0IHR3byBpdGVtczogbWluIGFuZCBtYXguXG4gKlxuICogQHBhcmFtIHtOdW1iZXJbXX0gdGltZXN0YW1wcyAtIHRpbWVzdGFtcHMgc29ydGVkIGZyb20gbG93ZXN0IHRvIGhpZ2hlc3QuXG4gKiBAcGFyYW0ge1N0cmluZ30gZGlzdHJpYnV0aW9uIC0gSWYgJ2xpbmVhcicsIHRpbWVzdGFtcHMgd2lsbCBiZSBzcHJlYWQgbGluZWFybHkgYWxvbmcgdGhlIG1pblxuICogYW5kIG1heCByYW5nZSwgc28gYmFzaWNhbGx5LCB0aGUgdGFibGUgd2lsbCBjb250YWlucyBvbmx5IHR3byBpdGVtczoge21pbiwgMH0gYW5kIHttYXgsIDF9LlxuICogSWYgJ3NlcmllcycsIHRpbWVzdGFtcHMgd2lsbCBiZSBwb3NpdGlvbmVkIGF0IHRoZSBzYW1lIGRpc3RhbmNlIGZyb20gZWFjaCBvdGhlci4gSW4gdGhpc1xuICogY2FzZSwgb25seSB0aW1lc3RhbXBzIHRoYXQgYnJlYWsgdGhlIHRpbWUgbGluZWFyaXR5IGFyZSByZWdpc3RlcmVkLCBtZWFuaW5nIHRoYXQgaW4gdGhlXG4gKiBiZXN0IGNhc2UsIGFsbCB0aW1lc3RhbXBzIGFyZSBsaW5lYXIsIHRoZSB0YWJsZSBjb250YWlucyBvbmx5IG1pbiBhbmQgbWF4LlxuICovXG5mdW5jdGlvbiBidWlsZExvb2t1cFRhYmxlKHRpbWVzdGFtcHMsIG1pbiwgbWF4LCBkaXN0cmlidXRpb24pIHtcblx0aWYgKGRpc3RyaWJ1dGlvbiA9PT0gJ2xpbmVhcicgfHwgIXRpbWVzdGFtcHMubGVuZ3RoKSB7XG5cdFx0cmV0dXJuIFtcblx0XHRcdHt0aW1lOiBtaW4sIHBvczogMH0sXG5cdFx0XHR7dGltZTogbWF4LCBwb3M6IDF9XG5cdFx0XTtcblx0fVxuXG5cdHZhciB0YWJsZSA9IFtdO1xuXHR2YXIgaXRlbXMgPSBbbWluXTtcblx0dmFyIGksIGlsZW4sIHByZXYsIGN1cnIsIG5leHQ7XG5cblx0Zm9yIChpID0gMCwgaWxlbiA9IHRpbWVzdGFtcHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG5cdFx0Y3VyciA9IHRpbWVzdGFtcHNbaV07XG5cdFx0aWYgKGN1cnIgPiBtaW4gJiYgY3VyciA8IG1heCkge1xuXHRcdFx0aXRlbXMucHVzaChjdXJyKTtcblx0XHR9XG5cdH1cblxuXHRpdGVtcy5wdXNoKG1heCk7XG5cblx0Zm9yIChpID0gMCwgaWxlbiA9IGl0ZW1zLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdG5leHQgPSBpdGVtc1tpICsgMV07XG5cdFx0cHJldiA9IGl0ZW1zW2kgLSAxXTtcblx0XHRjdXJyID0gaXRlbXNbaV07XG5cblx0XHQvLyBvbmx5IGFkZCBwb2ludHMgdGhhdCBicmVha3MgdGhlIHNjYWxlIGxpbmVhcml0eVxuXHRcdGlmIChwcmV2ID09PSB1bmRlZmluZWQgfHwgbmV4dCA9PT0gdW5kZWZpbmVkIHx8IE1hdGgucm91bmQoKG5leHQgKyBwcmV2KSAvIDIpICE9PSBjdXJyKSB7XG5cdFx0XHR0YWJsZS5wdXNoKHt0aW1lOiBjdXJyLCBwb3M6IGkgLyAoaWxlbiAtIDEpfSk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHRhYmxlO1xufVxuXG4vLyBAc2VlIGFkYXB0ZWQgZnJvbSBodHRwOi8vd3d3LmFudWpnYWtoYXIuY29tLzIwMTQvMDMvMDEvYmluYXJ5LXNlYXJjaC1pbi1qYXZhc2NyaXB0L1xuZnVuY3Rpb24gbG9va3VwKHRhYmxlLCBrZXksIHZhbHVlKSB7XG5cdHZhciBsbyA9IDA7XG5cdHZhciBoaSA9IHRhYmxlLmxlbmd0aCAtIDE7XG5cdHZhciBtaWQsIGkwLCBpMTtcblxuXHR3aGlsZSAobG8gPj0gMCAmJiBsbyA8PSBoaSkge1xuXHRcdG1pZCA9IChsbyArIGhpKSA+PiAxO1xuXHRcdGkwID0gdGFibGVbbWlkIC0gMV0gfHwgbnVsbDtcblx0XHRpMSA9IHRhYmxlW21pZF07XG5cblx0XHRpZiAoIWkwKSB7XG5cdFx0XHQvLyBnaXZlbiB2YWx1ZSBpcyBvdXRzaWRlIHRhYmxlIChiZWZvcmUgZmlyc3QgaXRlbSlcblx0XHRcdHJldHVybiB7bG86IG51bGwsIGhpOiBpMX07XG5cdFx0fSBlbHNlIGlmIChpMVtrZXldIDwgdmFsdWUpIHtcblx0XHRcdGxvID0gbWlkICsgMTtcblx0XHR9IGVsc2UgaWYgKGkwW2tleV0gPiB2YWx1ZSkge1xuXHRcdFx0aGkgPSBtaWQgLSAxO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4ge2xvOiBpMCwgaGk6IGkxfTtcblx0XHR9XG5cdH1cblxuXHQvLyBnaXZlbiB2YWx1ZSBpcyBvdXRzaWRlIHRhYmxlIChhZnRlciBsYXN0IGl0ZW0pXG5cdHJldHVybiB7bG86IGkxLCBoaTogbnVsbH07XG59XG5cbi8qKlxuICogTGluZWFybHkgaW50ZXJwb2xhdGVzIHRoZSBnaXZlbiBzb3VyY2UgYHZhbHVlYCB1c2luZyB0aGUgdGFibGUgaXRlbXMgYHNrZXlgIHZhbHVlcyBhbmRcbiAqIHJldHVybnMgdGhlIGFzc29jaWF0ZWQgYHRrZXlgIHZhbHVlLiBGb3IgZXhhbXBsZSwgaW50ZXJwb2xhdGUodGFibGUsICd0aW1lJywgNDIsICdwb3MnKVxuICogcmV0dXJucyB0aGUgcG9zaXRpb24gZm9yIGEgdGltZXN0YW1wIGVxdWFsIHRvIDQyLiBJZiB2YWx1ZSBpcyBvdXQgb2YgYm91bmRzLCB2YWx1ZXMgYXRcbiAqIGluZGV4IFswLCAxXSBvciBbbiAtIDEsIG5dIGFyZSB1c2VkIGZvciB0aGUgaW50ZXJwb2xhdGlvbi5cbiAqL1xuZnVuY3Rpb24gaW50ZXJwb2xhdGUodGFibGUsIHNrZXksIHN2YWwsIHRrZXkpIHtcblx0dmFyIHJhbmdlID0gbG9va3VwKHRhYmxlLCBza2V5LCBzdmFsKTtcblxuXHQvLyBOb3RlOiB0aGUgbG9va3VwIHRhYmxlIEFMV0FZUyBjb250YWlucyBhdCBsZWFzdCAyIGl0ZW1zIChtaW4gYW5kIG1heClcblx0dmFyIHByZXYgPSAhcmFuZ2UubG8gPyB0YWJsZVswXSA6ICFyYW5nZS5oaSA/IHRhYmxlW3RhYmxlLmxlbmd0aCAtIDJdIDogcmFuZ2UubG87XG5cdHZhciBuZXh0ID0gIXJhbmdlLmxvID8gdGFibGVbMV0gOiAhcmFuZ2UuaGkgPyB0YWJsZVt0YWJsZS5sZW5ndGggLSAxXSA6IHJhbmdlLmhpO1xuXG5cdHZhciBzcGFuID0gbmV4dFtza2V5XSAtIHByZXZbc2tleV07XG5cdHZhciByYXRpbyA9IHNwYW4gPyAoc3ZhbCAtIHByZXZbc2tleV0pIC8gc3BhbiA6IDA7XG5cdHZhciBvZmZzZXQgPSAobmV4dFt0a2V5XSAtIHByZXZbdGtleV0pICogcmF0aW87XG5cblx0cmV0dXJuIHByZXZbdGtleV0gKyBvZmZzZXQ7XG59XG5cbi8qKlxuICogQ29udmVydCB0aGUgZ2l2ZW4gdmFsdWUgdG8gYSBtb21lbnQgb2JqZWN0IHVzaW5nIHRoZSBnaXZlbiB0aW1lIG9wdGlvbnMuXG4gKiBAc2VlIGh0dHA6Ly9tb21lbnRqcy5jb20vZG9jcy8jL3BhcnNpbmcvXG4gKi9cbmZ1bmN0aW9uIG1vbWVudGlmeSh2YWx1ZSwgb3B0aW9ucykge1xuXHR2YXIgcGFyc2VyID0gb3B0aW9ucy5wYXJzZXI7XG5cdHZhciBmb3JtYXQgPSBvcHRpb25zLnBhcnNlciB8fCBvcHRpb25zLmZvcm1hdDtcblxuXHRpZiAodHlwZW9mIHBhcnNlciA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdHJldHVybiBwYXJzZXIodmFsdWUpO1xuXHR9XG5cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIGZvcm1hdCA9PT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gbW9tZW50KHZhbHVlLCBmb3JtYXQpO1xuXHR9XG5cblx0aWYgKCEodmFsdWUgaW5zdGFuY2VvZiBtb21lbnQpKSB7XG5cdFx0dmFsdWUgPSBtb21lbnQodmFsdWUpO1xuXHR9XG5cblx0aWYgKHZhbHVlLmlzVmFsaWQoKSkge1xuXHRcdHJldHVybiB2YWx1ZTtcblx0fVxuXG5cdC8vIExhYmVscyBhcmUgaW4gYW4gaW5jb21wYXRpYmxlIG1vbWVudCBmb3JtYXQgYW5kIG5vIGBwYXJzZXJgIGhhcyBiZWVuIHByb3ZpZGVkLlxuXHQvLyBUaGUgdXNlciBtaWdodCBzdGlsbCB1c2UgdGhlIGRlcHJlY2F0ZWQgYGZvcm1hdGAgb3B0aW9uIHRvIGNvbnZlcnQgaGlzIGlucHV0cy5cblx0aWYgKHR5cGVvZiBmb3JtYXQgPT09ICdmdW5jdGlvbicpIHtcblx0XHRyZXR1cm4gZm9ybWF0KHZhbHVlKTtcblx0fVxuXG5cdHJldHVybiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gcGFyc2UoaW5wdXQsIHNjYWxlKSB7XG5cdGlmIChoZWxwZXJzLmlzTnVsbE9yVW5kZWYoaW5wdXQpKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHR2YXIgb3B0aW9ucyA9IHNjYWxlLm9wdGlvbnMudGltZTtcblx0dmFyIHZhbHVlID0gbW9tZW50aWZ5KHNjYWxlLmdldFJpZ2h0VmFsdWUoaW5wdXQpLCBvcHRpb25zKTtcblx0aWYgKCF2YWx1ZS5pc1ZhbGlkKCkpIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdGlmIChvcHRpb25zLnJvdW5kKSB7XG5cdFx0dmFsdWUuc3RhcnRPZihvcHRpb25zLnJvdW5kKTtcblx0fVxuXG5cdHJldHVybiB2YWx1ZS52YWx1ZU9mKCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHVuaXQgdG8gc2tpcCB0byBiZSBhYmxlIHRvIGRpc3BsYXkgdXAgdG8gYGNhcGFjaXR5YCBudW1iZXIgb2YgdGlja3NcbiAqIGluIGB1bml0YCBmb3IgdGhlIGdpdmVuIGBtaW5gIC8gYG1heGAgcmFuZ2UgYW5kIHJlc3BlY3RpbmcgdGhlIGludGVydmFsIHN0ZXBzIGNvbnN0cmFpbnRzLlxuICovXG5mdW5jdGlvbiBkZXRlcm1pbmVTdGVwU2l6ZShtaW4sIG1heCwgdW5pdCwgY2FwYWNpdHkpIHtcblx0dmFyIHJhbmdlID0gbWF4IC0gbWluO1xuXHR2YXIgaW50ZXJ2YWwgPSBJTlRFUlZBTFNbdW5pdF07XG5cdHZhciBtaWxsaXNlY29uZHMgPSBpbnRlcnZhbC5zaXplO1xuXHR2YXIgc3RlcHMgPSBpbnRlcnZhbC5zdGVwcztcblx0dmFyIGksIGlsZW4sIGZhY3RvcjtcblxuXHRpZiAoIXN0ZXBzKSB7XG5cdFx0cmV0dXJuIE1hdGguY2VpbChyYW5nZSAvIChjYXBhY2l0eSAqIG1pbGxpc2Vjb25kcykpO1xuXHR9XG5cblx0Zm9yIChpID0gMCwgaWxlbiA9IHN0ZXBzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdGZhY3RvciA9IHN0ZXBzW2ldO1xuXHRcdGlmIChNYXRoLmNlaWwocmFuZ2UgLyAobWlsbGlzZWNvbmRzICogZmFjdG9yKSkgPD0gY2FwYWNpdHkpIHtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBmYWN0b3I7XG59XG5cbi8qKlxuICogRmlndXJlcyBvdXQgd2hhdCB1bml0IHJlc3VsdHMgaW4gYW4gYXBwcm9wcmlhdGUgbnVtYmVyIG9mIGF1dG8tZ2VuZXJhdGVkIHRpY2tzXG4gKi9cbmZ1bmN0aW9uIGRldGVybWluZVVuaXRGb3JBdXRvVGlja3MobWluVW5pdCwgbWluLCBtYXgsIGNhcGFjaXR5KSB7XG5cdHZhciBpbGVuID0gVU5JVFMubGVuZ3RoO1xuXHR2YXIgaSwgaW50ZXJ2YWwsIGZhY3RvcjtcblxuXHRmb3IgKGkgPSBVTklUUy5pbmRleE9mKG1pblVuaXQpOyBpIDwgaWxlbiAtIDE7ICsraSkge1xuXHRcdGludGVydmFsID0gSU5URVJWQUxTW1VOSVRTW2ldXTtcblx0XHRmYWN0b3IgPSBpbnRlcnZhbC5zdGVwcyA/IGludGVydmFsLnN0ZXBzW2ludGVydmFsLnN0ZXBzLmxlbmd0aCAtIDFdIDogTUFYX0lOVEVHRVI7XG5cblx0XHRpZiAoaW50ZXJ2YWwuY29tbW9uICYmIE1hdGguY2VpbCgobWF4IC0gbWluKSAvIChmYWN0b3IgKiBpbnRlcnZhbC5zaXplKSkgPD0gY2FwYWNpdHkpIHtcblx0XHRcdHJldHVybiBVTklUU1tpXTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gVU5JVFNbaWxlbiAtIDFdO1xufVxuXG4vKipcbiAqIEZpZ3VyZXMgb3V0IHdoYXQgdW5pdCB0byBmb3JtYXQgYSBzZXQgb2YgdGlja3Mgd2l0aFxuICovXG5mdW5jdGlvbiBkZXRlcm1pbmVVbml0Rm9yRm9ybWF0dGluZyh0aWNrcywgbWluVW5pdCwgbWluLCBtYXgpIHtcblx0dmFyIGR1cmF0aW9uID0gbW9tZW50LmR1cmF0aW9uKG1vbWVudChtYXgpLmRpZmYobW9tZW50KG1pbikpKTtcblx0dmFyIGlsZW4gPSBVTklUUy5sZW5ndGg7XG5cdHZhciBpLCB1bml0O1xuXG5cdGZvciAoaSA9IGlsZW4gLSAxOyBpID49IFVOSVRTLmluZGV4T2YobWluVW5pdCk7IGktLSkge1xuXHRcdHVuaXQgPSBVTklUU1tpXTtcblx0XHRpZiAoSU5URVJWQUxTW3VuaXRdLmNvbW1vbiAmJiBkdXJhdGlvbi5hcyh1bml0KSA+PSB0aWNrcy5sZW5ndGgpIHtcblx0XHRcdHJldHVybiB1bml0O1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBVTklUU1ttaW5Vbml0ID8gVU5JVFMuaW5kZXhPZihtaW5Vbml0KSA6IDBdO1xufVxuXG5mdW5jdGlvbiBkZXRlcm1pbmVNYWpvclVuaXQodW5pdCkge1xuXHRmb3IgKHZhciBpID0gVU5JVFMuaW5kZXhPZih1bml0KSArIDEsIGlsZW4gPSBVTklUUy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRpZiAoSU5URVJWQUxTW1VOSVRTW2ldXS5jb21tb24pIHtcblx0XHRcdHJldHVybiBVTklUU1tpXTtcblx0XHR9XG5cdH1cbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBtYXhpbXVtIG9mIGBjYXBhY2l0eWAgdGltZXN0YW1wcyBiZXR3ZWVuIG1pbiBhbmQgbWF4LCByb3VuZGVkIHRvIHRoZVxuICogYG1pbm9yYCB1bml0LCBhbGlnbmVkIG9uIHRoZSBgbWFqb3JgIHVuaXQgYW5kIHVzaW5nIHRoZSBnaXZlbiBzY2FsZSB0aW1lIGBvcHRpb25zYC5cbiAqIEltcG9ydGFudDogdGhpcyBtZXRob2QgY2FuIHJldHVybiB0aWNrcyBvdXRzaWRlIHRoZSBtaW4gYW5kIG1heCByYW5nZSwgaXQncyB0aGVcbiAqIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBjYWxsaW5nIGNvZGUgdG8gY2xhbXAgdmFsdWVzIGlmIG5lZWRlZC5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGUobWluLCBtYXgsIGNhcGFjaXR5LCBvcHRpb25zKSB7XG5cdHZhciB0aW1lT3B0cyA9IG9wdGlvbnMudGltZTtcblx0dmFyIG1pbm9yID0gdGltZU9wdHMudW5pdCB8fCBkZXRlcm1pbmVVbml0Rm9yQXV0b1RpY2tzKHRpbWVPcHRzLm1pblVuaXQsIG1pbiwgbWF4LCBjYXBhY2l0eSk7XG5cdHZhciBtYWpvciA9IGRldGVybWluZU1ham9yVW5pdChtaW5vcik7XG5cdHZhciBzdGVwU2l6ZSA9IGhlbHBlcnMudmFsdWVPckRlZmF1bHQodGltZU9wdHMuc3RlcFNpemUsIHRpbWVPcHRzLnVuaXRTdGVwU2l6ZSk7XG5cdHZhciB3ZWVrZGF5ID0gbWlub3IgPT09ICd3ZWVrJyA/IHRpbWVPcHRzLmlzb1dlZWtkYXkgOiBmYWxzZTtcblx0dmFyIG1ham9yVGlja3NFbmFibGVkID0gb3B0aW9ucy50aWNrcy5tYWpvci5lbmFibGVkO1xuXHR2YXIgaW50ZXJ2YWwgPSBJTlRFUlZBTFNbbWlub3JdO1xuXHR2YXIgZmlyc3QgPSBtb21lbnQobWluKTtcblx0dmFyIGxhc3QgPSBtb21lbnQobWF4KTtcblx0dmFyIHRpY2tzID0gW107XG5cdHZhciB0aW1lO1xuXG5cdGlmICghc3RlcFNpemUpIHtcblx0XHRzdGVwU2l6ZSA9IGRldGVybWluZVN0ZXBTaXplKG1pbiwgbWF4LCBtaW5vciwgY2FwYWNpdHkpO1xuXHR9XG5cblx0Ly8gRm9yICd3ZWVrJyB1bml0LCBoYW5kbGUgdGhlIGZpcnN0IGRheSBvZiB3ZWVrIG9wdGlvblxuXHRpZiAod2Vla2RheSkge1xuXHRcdGZpcnN0ID0gZmlyc3QuaXNvV2Vla2RheSh3ZWVrZGF5KTtcblx0XHRsYXN0ID0gbGFzdC5pc29XZWVrZGF5KHdlZWtkYXkpO1xuXHR9XG5cblx0Ly8gQWxpZ24gZmlyc3QvbGFzdCB0aWNrcyBvbiB1bml0XG5cdGZpcnN0ID0gZmlyc3Quc3RhcnRPZih3ZWVrZGF5ID8gJ2RheScgOiBtaW5vcik7XG5cdGxhc3QgPSBsYXN0LnN0YXJ0T2Yod2Vla2RheSA/ICdkYXknIDogbWlub3IpO1xuXG5cdC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBsYXN0IHRpY2sgaW5jbHVkZSBtYXhcblx0aWYgKGxhc3QgPCBtYXgpIHtcblx0XHRsYXN0LmFkZCgxLCBtaW5vcik7XG5cdH1cblxuXHR0aW1lID0gbW9tZW50KGZpcnN0KTtcblxuXHRpZiAobWFqb3JUaWNrc0VuYWJsZWQgJiYgbWFqb3IgJiYgIXdlZWtkYXkgJiYgIXRpbWVPcHRzLnJvdW5kKSB7XG5cdFx0Ly8gQWxpZ24gdGhlIGZpcnN0IHRpY2sgb24gdGhlIHByZXZpb3VzIGBtaW5vcmAgdW5pdCBhbGlnbmVkIG9uIHRoZSBgbWFqb3JgIHVuaXQ6XG5cdFx0Ly8gd2UgZmlyc3QgYWxpZ25lZCB0aW1lIG9uIHRoZSBwcmV2aW91cyBgbWFqb3JgIHVuaXQgdGhlbiBhZGQgdGhlIG51bWJlciBvZiBmdWxsXG5cdFx0Ly8gc3RlcFNpemUgdGhlcmUgaXMgYmV0d2VlbiBmaXJzdCBhbmQgdGhlIHByZXZpb3VzIG1ham9yIHRpbWUuXG5cdFx0dGltZS5zdGFydE9mKG1ham9yKTtcblx0XHR0aW1lLmFkZCh+figoZmlyc3QgLSB0aW1lKSAvIChpbnRlcnZhbC5zaXplICogc3RlcFNpemUpKSAqIHN0ZXBTaXplLCBtaW5vcik7XG5cdH1cblxuXHRmb3IgKDsgdGltZSA8IGxhc3Q7IHRpbWUuYWRkKHN0ZXBTaXplLCBtaW5vcikpIHtcblx0XHR0aWNrcy5wdXNoKCt0aW1lKTtcblx0fVxuXG5cdHRpY2tzLnB1c2goK3RpbWUpO1xuXG5cdHJldHVybiB0aWNrcztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSByaWdodCBhbmQgbGVmdCBvZmZzZXRzIGZyb20gZWRnZXMgaW4gdGhlIGZvcm0gb2Yge2xlZnQsIHJpZ2h0fS5cbiAqIE9mZnNldHMgYXJlIGFkZGVkIHdoZW4gdGhlIGBvZmZzZXRgIG9wdGlvbiBpcyB0cnVlLlxuICovXG5mdW5jdGlvbiBjb21wdXRlT2Zmc2V0cyh0YWJsZSwgdGlja3MsIG1pbiwgbWF4LCBvcHRpb25zKSB7XG5cdHZhciBsZWZ0ID0gMDtcblx0dmFyIHJpZ2h0ID0gMDtcblx0dmFyIHVwcGVyLCBsb3dlcjtcblxuXHRpZiAob3B0aW9ucy5vZmZzZXQgJiYgdGlja3MubGVuZ3RoKSB7XG5cdFx0aWYgKCFvcHRpb25zLnRpbWUubWluKSB7XG5cdFx0XHR1cHBlciA9IHRpY2tzLmxlbmd0aCA+IDEgPyB0aWNrc1sxXSA6IG1heDtcblx0XHRcdGxvd2VyID0gdGlja3NbMF07XG5cdFx0XHRsZWZ0ID0gKFxuXHRcdFx0XHRpbnRlcnBvbGF0ZSh0YWJsZSwgJ3RpbWUnLCB1cHBlciwgJ3BvcycpIC1cblx0XHRcdFx0aW50ZXJwb2xhdGUodGFibGUsICd0aW1lJywgbG93ZXIsICdwb3MnKVxuXHRcdFx0KSAvIDI7XG5cdFx0fVxuXHRcdGlmICghb3B0aW9ucy50aW1lLm1heCkge1xuXHRcdFx0dXBwZXIgPSB0aWNrc1t0aWNrcy5sZW5ndGggLSAxXTtcblx0XHRcdGxvd2VyID0gdGlja3MubGVuZ3RoID4gMSA/IHRpY2tzW3RpY2tzLmxlbmd0aCAtIDJdIDogbWluO1xuXHRcdFx0cmlnaHQgPSAoXG5cdFx0XHRcdGludGVycG9sYXRlKHRhYmxlLCAndGltZScsIHVwcGVyLCAncG9zJykgLVxuXHRcdFx0XHRpbnRlcnBvbGF0ZSh0YWJsZSwgJ3RpbWUnLCBsb3dlciwgJ3BvcycpXG5cdFx0XHQpIC8gMjtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4ge2xlZnQ6IGxlZnQsIHJpZ2h0OiByaWdodH07XG59XG5cbmZ1bmN0aW9uIHRpY2tzRnJvbVRpbWVzdGFtcHModmFsdWVzLCBtYWpvclVuaXQpIHtcblx0dmFyIHRpY2tzID0gW107XG5cdHZhciBpLCBpbGVuLCB2YWx1ZSwgbWFqb3I7XG5cblx0Zm9yIChpID0gMCwgaWxlbiA9IHZhbHVlcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHR2YWx1ZSA9IHZhbHVlc1tpXTtcblx0XHRtYWpvciA9IG1ham9yVW5pdCA/IHZhbHVlID09PSArbW9tZW50KHZhbHVlKS5zdGFydE9mKG1ham9yVW5pdCkgOiBmYWxzZTtcblxuXHRcdHRpY2tzLnB1c2goe1xuXHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0bWFqb3I6IG1ham9yXG5cdFx0fSk7XG5cdH1cblxuXHRyZXR1cm4gdGlja3M7XG59XG5cbmZ1bmN0aW9uIGRldGVybWluZUxhYmVsRm9ybWF0KGRhdGEsIHRpbWVPcHRzKSB7XG5cdHZhciBpLCBtb21lbnREYXRlLCBoYXNUaW1lO1xuXHR2YXIgaWxlbiA9IGRhdGEubGVuZ3RoO1xuXG5cdC8vIGZpbmQgdGhlIGxhYmVsIHdpdGggdGhlIG1vc3QgcGFydHMgKG1pbGxpc2Vjb25kcywgbWludXRlcywgZXRjLilcblx0Ly8gZm9ybWF0IGFsbCBsYWJlbHMgd2l0aCB0aGUgc2FtZSBsZXZlbCBvZiBkZXRhaWwgYXMgdGhlIG1vc3Qgc3BlY2lmaWMgbGFiZWxcblx0Zm9yIChpID0gMDsgaSA8IGlsZW47IGkrKykge1xuXHRcdG1vbWVudERhdGUgPSBtb21lbnRpZnkoZGF0YVtpXSwgdGltZU9wdHMpO1xuXHRcdGlmIChtb21lbnREYXRlLm1pbGxpc2Vjb25kKCkgIT09IDApIHtcblx0XHRcdHJldHVybiAnTU1NIEQsIFlZWVkgaDptbTpzcy5TU1MgYSc7XG5cdFx0fVxuXHRcdGlmIChtb21lbnREYXRlLnNlY29uZCgpICE9PSAwIHx8IG1vbWVudERhdGUubWludXRlKCkgIT09IDAgfHwgbW9tZW50RGF0ZS5ob3VyKCkgIT09IDApIHtcblx0XHRcdGhhc1RpbWUgPSB0cnVlO1xuXHRcdH1cblx0fVxuXHRpZiAoaGFzVGltZSkge1xuXHRcdHJldHVybiAnTU1NIEQsIFlZWVkgaDptbTpzcyBhJztcblx0fVxuXHRyZXR1cm4gJ01NTSBELCBZWVlZJztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcblxuXHR2YXIgZGVmYXVsdENvbmZpZyA9IHtcblx0XHRwb3NpdGlvbjogJ2JvdHRvbScsXG5cblx0XHQvKipcblx0XHQgKiBEYXRhIGRpc3RyaWJ1dGlvbiBhbG9uZyB0aGUgc2NhbGU6XG5cdFx0ICogLSAnbGluZWFyJzogZGF0YSBhcmUgc3ByZWFkIGFjY29yZGluZyB0byB0aGVpciB0aW1lIChkaXN0YW5jZXMgY2FuIHZhcnkpLFxuXHRcdCAqIC0gJ3Nlcmllcyc6IGRhdGEgYXJlIHNwcmVhZCBhdCB0aGUgc2FtZSBkaXN0YW5jZSBmcm9tIGVhY2ggb3RoZXIuXG5cdFx0ICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9wdWxsLzQ1MDdcblx0XHQgKiBAc2luY2UgMi43LjBcblx0XHQgKi9cblx0XHRkaXN0cmlidXRpb246ICdsaW5lYXInLFxuXG5cdFx0LyoqXG5cdFx0ICogU2NhbGUgYm91bmRhcnkgc3RyYXRlZ3kgKGJ5cGFzc2VkIGJ5IG1pbi9tYXggdGltZSBvcHRpb25zKVxuXHRcdCAqIC0gYGRhdGFgOiBtYWtlIHN1cmUgZGF0YSBhcmUgZnVsbHkgdmlzaWJsZSwgdGlja3Mgb3V0c2lkZSBhcmUgcmVtb3ZlZFxuXHRcdCAqIC0gYHRpY2tzYDogbWFrZSBzdXJlIHRpY2tzIGFyZSBmdWxseSB2aXNpYmxlLCBkYXRhIG91dHNpZGUgYXJlIHRydW5jYXRlZFxuXHRcdCAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvcHVsbC80NTU2XG5cdFx0ICogQHNpbmNlIDIuNy4wXG5cdFx0ICovXG5cdFx0Ym91bmRzOiAnZGF0YScsXG5cblx0XHR0aW1lOiB7XG5cdFx0XHRwYXJzZXI6IGZhbHNlLCAvLyBmYWxzZSA9PSBhIHBhdHRlcm4gc3RyaW5nIGZyb20gaHR0cDovL21vbWVudGpzLmNvbS9kb2NzLyMvcGFyc2luZy9zdHJpbmctZm9ybWF0LyBvciBhIGN1c3RvbSBjYWxsYmFjayB0aGF0IGNvbnZlcnRzIGl0cyBhcmd1bWVudCB0byBhIG1vbWVudFxuXHRcdFx0Zm9ybWF0OiBmYWxzZSwgLy8gREVQUkVDQVRFRCBmYWxzZSA9PSBkYXRlIG9iamVjdHMsIG1vbWVudCBvYmplY3QsIGNhbGxiYWNrIG9yIGEgcGF0dGVybiBzdHJpbmcgZnJvbSBodHRwOi8vbW9tZW50anMuY29tL2RvY3MvIy9wYXJzaW5nL3N0cmluZy1mb3JtYXQvXG5cdFx0XHR1bml0OiBmYWxzZSwgLy8gZmFsc2UgPT0gYXV0b21hdGljIG9yIG92ZXJyaWRlIHdpdGggd2VlaywgbW9udGgsIHllYXIsIGV0Yy5cblx0XHRcdHJvdW5kOiBmYWxzZSwgLy8gbm9uZSwgb3Igb3ZlcnJpZGUgd2l0aCB3ZWVrLCBtb250aCwgeWVhciwgZXRjLlxuXHRcdFx0ZGlzcGxheUZvcm1hdDogZmFsc2UsIC8vIERFUFJFQ0FURURcblx0XHRcdGlzb1dlZWtkYXk6IGZhbHNlLCAvLyBvdmVycmlkZSB3ZWVrIHN0YXJ0IGRheSAtIHNlZSBodHRwOi8vbW9tZW50anMuY29tL2RvY3MvIy9nZXQtc2V0L2lzby13ZWVrZGF5L1xuXHRcdFx0bWluVW5pdDogJ21pbGxpc2Vjb25kJyxcblxuXHRcdFx0Ly8gZGVmYXVsdHMgdG8gdW5pdCdzIGNvcnJlc3BvbmRpbmcgdW5pdEZvcm1hdCBiZWxvdyBvciBvdmVycmlkZSB1c2luZyBwYXR0ZXJuIHN0cmluZyBmcm9tIGh0dHA6Ly9tb21lbnRqcy5jb20vZG9jcy8jL2Rpc3BsYXlpbmcvZm9ybWF0L1xuXHRcdFx0ZGlzcGxheUZvcm1hdHM6IHtcblx0XHRcdFx0bWlsbGlzZWNvbmQ6ICdoOm1tOnNzLlNTUyBhJywgLy8gMTE6MjA6MDEuMTIzIEFNLFxuXHRcdFx0XHRzZWNvbmQ6ICdoOm1tOnNzIGEnLCAvLyAxMToyMDowMSBBTVxuXHRcdFx0XHRtaW51dGU6ICdoOm1tIGEnLCAvLyAxMToyMCBBTVxuXHRcdFx0XHRob3VyOiAnaEEnLCAvLyA1UE1cblx0XHRcdFx0ZGF5OiAnTU1NIEQnLCAvLyBTZXAgNFxuXHRcdFx0XHR3ZWVrOiAnbGwnLCAvLyBXZWVrIDQ2LCBvciBtYXliZSBcIltXXVdXIC0gWVlZWVwiID9cblx0XHRcdFx0bW9udGg6ICdNTU0gWVlZWScsIC8vIFNlcHQgMjAxNVxuXHRcdFx0XHRxdWFydGVyOiAnW1FdUSAtIFlZWVknLCAvLyBRM1xuXHRcdFx0XHR5ZWFyOiAnWVlZWScgLy8gMjAxNVxuXHRcdFx0fSxcblx0XHR9LFxuXHRcdHRpY2tzOiB7XG5cdFx0XHRhdXRvU2tpcDogZmFsc2UsXG5cblx0XHRcdC8qKlxuXHRcdFx0ICogVGlja3MgZ2VuZXJhdGlvbiBpbnB1dCB2YWx1ZXM6XG5cdFx0XHQgKiAtICdhdXRvJzogZ2VuZXJhdGVzIFwib3B0aW1hbFwiIHRpY2tzIGJhc2VkIG9uIHNjYWxlIHNpemUgYW5kIHRpbWUgb3B0aW9ucy5cblx0XHRcdCAqIC0gJ2RhdGEnOiBnZW5lcmF0ZXMgdGlja3MgZnJvbSBkYXRhIChpbmNsdWRpbmcgbGFiZWxzIGZyb20gZGF0YSB7dHx4fHl9IG9iamVjdHMpLlxuXHRcdFx0ICogLSAnbGFiZWxzJzogZ2VuZXJhdGVzIHRpY2tzIGZyb20gdXNlciBnaXZlbiBgZGF0YS5sYWJlbHNgIHZhbHVlcyBPTkxZLlxuXHRcdFx0ICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9wdWxsLzQ1MDdcblx0XHRcdCAqIEBzaW5jZSAyLjcuMFxuXHRcdFx0ICovXG5cdFx0XHRzb3VyY2U6ICdhdXRvJyxcblxuXHRcdFx0bWFqb3I6IHtcblx0XHRcdFx0ZW5hYmxlZDogZmFsc2Vcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cblx0dmFyIFRpbWVTY2FsZSA9IFNjYWxlLmV4dGVuZCh7XG5cdFx0aW5pdGlhbGl6ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIW1vbWVudCkge1xuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0NoYXJ0LmpzIC0gTW9tZW50LmpzIGNvdWxkIG5vdCBiZSBmb3VuZCEgWW91IG11c3QgaW5jbHVkZSBpdCBiZWZvcmUgQ2hhcnQuanMgdG8gdXNlIHRoZSB0aW1lIHNjYWxlLiBEb3dubG9hZCBhdCBodHRwczovL21vbWVudGpzLmNvbScpO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLm1lcmdlVGlja3NPcHRpb25zKCk7XG5cblx0XHRcdFNjYWxlLnByb3RvdHlwZS5pbml0aWFsaXplLmNhbGwodGhpcyk7XG5cdFx0fSxcblxuXHRcdHVwZGF0ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG9wdGlvbnMgPSBtZS5vcHRpb25zO1xuXG5cdFx0XHQvLyBERVBSRUNBVElPTlM6IG91dHB1dCBhIG1lc3NhZ2Ugb25seSBvbmUgdGltZSBwZXIgdXBkYXRlXG5cdFx0XHRpZiAob3B0aW9ucy50aW1lICYmIG9wdGlvbnMudGltZS5mb3JtYXQpIHtcblx0XHRcdFx0Y29uc29sZS53YXJuKCdvcHRpb25zLnRpbWUuZm9ybWF0IGlzIGRlcHJlY2F0ZWQgYW5kIHJlcGxhY2VkIGJ5IG9wdGlvbnMudGltZS5wYXJzZXIuJyk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBTY2FsZS5wcm90b3R5cGUudXBkYXRlLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBBbGxvd3MgZGF0YSB0byBiZSByZWZlcmVuY2VkIHZpYSAndCcgYXR0cmlidXRlXG5cdFx0ICovXG5cdFx0Z2V0UmlnaHRWYWx1ZTogZnVuY3Rpb24ocmF3VmFsdWUpIHtcblx0XHRcdGlmIChyYXdWYWx1ZSAmJiByYXdWYWx1ZS50ICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0cmF3VmFsdWUgPSByYXdWYWx1ZS50O1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIFNjYWxlLnByb3RvdHlwZS5nZXRSaWdodFZhbHVlLmNhbGwodGhpcywgcmF3VmFsdWUpO1xuXHRcdH0sXG5cblx0XHRkZXRlcm1pbmVEYXRhTGltaXRzOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcblx0XHRcdHZhciB0aW1lT3B0cyA9IG1lLm9wdGlvbnMudGltZTtcblx0XHRcdHZhciB1bml0ID0gdGltZU9wdHMudW5pdCB8fCAnZGF5Jztcblx0XHRcdHZhciBtaW4gPSBNQVhfSU5URUdFUjtcblx0XHRcdHZhciBtYXggPSBNSU5fSU5URUdFUjtcblx0XHRcdHZhciB0aW1lc3RhbXBzID0gW107XG5cdFx0XHR2YXIgZGF0YXNldHMgPSBbXTtcblx0XHRcdHZhciBsYWJlbHMgPSBbXTtcblx0XHRcdHZhciBpLCBqLCBpbGVuLCBqbGVuLCBkYXRhLCB0aW1lc3RhbXA7XG5cblx0XHRcdC8vIENvbnZlcnQgbGFiZWxzIHRvIHRpbWVzdGFtcHNcblx0XHRcdGZvciAoaSA9IDAsIGlsZW4gPSBjaGFydC5kYXRhLmxhYmVscy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdFx0bGFiZWxzLnB1c2gocGFyc2UoY2hhcnQuZGF0YS5sYWJlbHNbaV0sIG1lKSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbnZlcnQgZGF0YSB0byB0aW1lc3RhbXBzXG5cdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0gKGNoYXJ0LmRhdGEuZGF0YXNldHMgfHwgW10pLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdFx0XHRpZiAoY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShpKSkge1xuXHRcdFx0XHRcdGRhdGEgPSBjaGFydC5kYXRhLmRhdGFzZXRzW2ldLmRhdGE7XG5cblx0XHRcdFx0XHQvLyBMZXQncyBjb25zaWRlciB0aGF0IGFsbCBkYXRhIGhhdmUgdGhlIHNhbWUgZm9ybWF0LlxuXHRcdFx0XHRcdGlmIChoZWxwZXJzLmlzT2JqZWN0KGRhdGFbMF0pKSB7XG5cdFx0XHRcdFx0XHRkYXRhc2V0c1tpXSA9IFtdO1xuXG5cdFx0XHRcdFx0XHRmb3IgKGogPSAwLCBqbGVuID0gZGF0YS5sZW5ndGg7IGogPCBqbGVuOyArK2opIHtcblx0XHRcdFx0XHRcdFx0dGltZXN0YW1wID0gcGFyc2UoZGF0YVtqXSwgbWUpO1xuXHRcdFx0XHRcdFx0XHR0aW1lc3RhbXBzLnB1c2godGltZXN0YW1wKTtcblx0XHRcdFx0XHRcdFx0ZGF0YXNldHNbaV1bal0gPSB0aW1lc3RhbXA7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRpbWVzdGFtcHMucHVzaC5hcHBseSh0aW1lc3RhbXBzLCBsYWJlbHMpO1xuXHRcdFx0XHRcdFx0ZGF0YXNldHNbaV0gPSBsYWJlbHMuc2xpY2UoMCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGRhdGFzZXRzW2ldID0gW107XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aWYgKGxhYmVscy5sZW5ndGgpIHtcblx0XHRcdFx0Ly8gU29ydCBsYWJlbHMgKiphZnRlcioqIGRhdGEgaGF2ZSBiZWVuIGNvbnZlcnRlZFxuXHRcdFx0XHRsYWJlbHMgPSBhcnJheVVuaXF1ZShsYWJlbHMpLnNvcnQoc29ydGVyKTtcblx0XHRcdFx0bWluID0gTWF0aC5taW4obWluLCBsYWJlbHNbMF0pO1xuXHRcdFx0XHRtYXggPSBNYXRoLm1heChtYXgsIGxhYmVsc1tsYWJlbHMubGVuZ3RoIC0gMV0pO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGltZXN0YW1wcy5sZW5ndGgpIHtcblx0XHRcdFx0dGltZXN0YW1wcyA9IGFycmF5VW5pcXVlKHRpbWVzdGFtcHMpLnNvcnQoc29ydGVyKTtcblx0XHRcdFx0bWluID0gTWF0aC5taW4obWluLCB0aW1lc3RhbXBzWzBdKTtcblx0XHRcdFx0bWF4ID0gTWF0aC5tYXgobWF4LCB0aW1lc3RhbXBzW3RpbWVzdGFtcHMubGVuZ3RoIC0gMV0pO1xuXHRcdFx0fVxuXG5cdFx0XHRtaW4gPSBwYXJzZSh0aW1lT3B0cy5taW4sIG1lKSB8fCBtaW47XG5cdFx0XHRtYXggPSBwYXJzZSh0aW1lT3B0cy5tYXgsIG1lKSB8fCBtYXg7XG5cblx0XHRcdC8vIEluIGNhc2UgdGhlcmUgaXMgbm8gdmFsaWQgbWluL21heCwgc2V0IGxpbWl0cyBiYXNlZCBvbiB1bml0IHRpbWUgb3B0aW9uXG5cdFx0XHRtaW4gPSBtaW4gPT09IE1BWF9JTlRFR0VSID8gK21vbWVudCgpLnN0YXJ0T2YodW5pdCkgOiBtaW47XG5cdFx0XHRtYXggPSBtYXggPT09IE1JTl9JTlRFR0VSID8gK21vbWVudCgpLmVuZE9mKHVuaXQpICsgMSA6IG1heDtcblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgbWF4IGlzIHN0cmljdGx5IGhpZ2hlciB0aGFuIG1pbiAocmVxdWlyZWQgYnkgdGhlIGxvb2t1cCB0YWJsZSlcblx0XHRcdG1lLm1pbiA9IE1hdGgubWluKG1pbiwgbWF4KTtcblx0XHRcdG1lLm1heCA9IE1hdGgubWF4KG1pbiArIDEsIG1heCk7XG5cblx0XHRcdC8vIFBSSVZBVEVcblx0XHRcdG1lLl9ob3Jpem9udGFsID0gbWUuaXNIb3Jpem9udGFsKCk7XG5cdFx0XHRtZS5fdGFibGUgPSBbXTtcblx0XHRcdG1lLl90aW1lc3RhbXBzID0ge1xuXHRcdFx0XHRkYXRhOiB0aW1lc3RhbXBzLFxuXHRcdFx0XHRkYXRhc2V0czogZGF0YXNldHMsXG5cdFx0XHRcdGxhYmVsczogbGFiZWxzXG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRidWlsZFRpY2tzOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgbWluID0gbWUubWluO1xuXHRcdFx0dmFyIG1heCA9IG1lLm1heDtcblx0XHRcdHZhciBvcHRpb25zID0gbWUub3B0aW9ucztcblx0XHRcdHZhciB0aW1lT3B0cyA9IG9wdGlvbnMudGltZTtcblx0XHRcdHZhciB0aW1lc3RhbXBzID0gW107XG5cdFx0XHR2YXIgdGlja3MgPSBbXTtcblx0XHRcdHZhciBpLCBpbGVuLCB0aW1lc3RhbXA7XG5cblx0XHRcdHN3aXRjaCAob3B0aW9ucy50aWNrcy5zb3VyY2UpIHtcblx0XHRcdGNhc2UgJ2RhdGEnOlxuXHRcdFx0XHR0aW1lc3RhbXBzID0gbWUuX3RpbWVzdGFtcHMuZGF0YTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdsYWJlbHMnOlxuXHRcdFx0XHR0aW1lc3RhbXBzID0gbWUuX3RpbWVzdGFtcHMubGFiZWxzO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ2F1dG8nOlxuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0dGltZXN0YW1wcyA9IGdlbmVyYXRlKG1pbiwgbWF4LCBtZS5nZXRMYWJlbENhcGFjaXR5KG1pbiksIG9wdGlvbnMpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAob3B0aW9ucy5ib3VuZHMgPT09ICd0aWNrcycgJiYgdGltZXN0YW1wcy5sZW5ndGgpIHtcblx0XHRcdFx0bWluID0gdGltZXN0YW1wc1swXTtcblx0XHRcdFx0bWF4ID0gdGltZXN0YW1wc1t0aW1lc3RhbXBzLmxlbmd0aCAtIDFdO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBFbmZvcmNlIGxpbWl0cyB3aXRoIHVzZXIgbWluL21heCBvcHRpb25zXG5cdFx0XHRtaW4gPSBwYXJzZSh0aW1lT3B0cy5taW4sIG1lKSB8fCBtaW47XG5cdFx0XHRtYXggPSBwYXJzZSh0aW1lT3B0cy5tYXgsIG1lKSB8fCBtYXg7XG5cblx0XHRcdC8vIFJlbW92ZSB0aWNrcyBvdXRzaWRlIHRoZSBtaW4vbWF4IHJhbmdlXG5cdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0gdGltZXN0YW1wcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdFx0dGltZXN0YW1wID0gdGltZXN0YW1wc1tpXTtcblx0XHRcdFx0aWYgKHRpbWVzdGFtcCA+PSBtaW4gJiYgdGltZXN0YW1wIDw9IG1heCkge1xuXHRcdFx0XHRcdHRpY2tzLnB1c2godGltZXN0YW1wKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRtZS5taW4gPSBtaW47XG5cdFx0XHRtZS5tYXggPSBtYXg7XG5cblx0XHRcdC8vIFBSSVZBVEVcblx0XHRcdG1lLl91bml0ID0gdGltZU9wdHMudW5pdCB8fCBkZXRlcm1pbmVVbml0Rm9yRm9ybWF0dGluZyh0aWNrcywgdGltZU9wdHMubWluVW5pdCwgbWUubWluLCBtZS5tYXgpO1xuXHRcdFx0bWUuX21ham9yVW5pdCA9IGRldGVybWluZU1ham9yVW5pdChtZS5fdW5pdCk7XG5cdFx0XHRtZS5fdGFibGUgPSBidWlsZExvb2t1cFRhYmxlKG1lLl90aW1lc3RhbXBzLmRhdGEsIG1pbiwgbWF4LCBvcHRpb25zLmRpc3RyaWJ1dGlvbik7XG5cdFx0XHRtZS5fb2Zmc2V0cyA9IGNvbXB1dGVPZmZzZXRzKG1lLl90YWJsZSwgdGlja3MsIG1pbiwgbWF4LCBvcHRpb25zKTtcblx0XHRcdG1lLl9sYWJlbEZvcm1hdCA9IGRldGVybWluZUxhYmVsRm9ybWF0KG1lLl90aW1lc3RhbXBzLmRhdGEsIHRpbWVPcHRzKTtcblxuXHRcdFx0cmV0dXJuIHRpY2tzRnJvbVRpbWVzdGFtcHModGlja3MsIG1lLl9tYWpvclVuaXQpO1xuXHRcdH0sXG5cblx0XHRnZXRMYWJlbEZvckluZGV4OiBmdW5jdGlvbihpbmRleCwgZGF0YXNldEluZGV4KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIGRhdGEgPSBtZS5jaGFydC5kYXRhO1xuXHRcdFx0dmFyIHRpbWVPcHRzID0gbWUub3B0aW9ucy50aW1lO1xuXHRcdFx0dmFyIGxhYmVsID0gZGF0YS5sYWJlbHMgJiYgaW5kZXggPCBkYXRhLmxhYmVscy5sZW5ndGggPyBkYXRhLmxhYmVsc1tpbmRleF0gOiAnJztcblx0XHRcdHZhciB2YWx1ZSA9IGRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XS5kYXRhW2luZGV4XTtcblxuXHRcdFx0aWYgKGhlbHBlcnMuaXNPYmplY3QodmFsdWUpKSB7XG5cdFx0XHRcdGxhYmVsID0gbWUuZ2V0UmlnaHRWYWx1ZSh2YWx1ZSk7XG5cdFx0XHR9XG5cdFx0XHRpZiAodGltZU9wdHMudG9vbHRpcEZvcm1hdCkge1xuXHRcdFx0XHRyZXR1cm4gbW9tZW50aWZ5KGxhYmVsLCB0aW1lT3B0cykuZm9ybWF0KHRpbWVPcHRzLnRvb2x0aXBGb3JtYXQpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHR5cGVvZiBsYWJlbCA9PT0gJ3N0cmluZycpIHtcblx0XHRcdFx0cmV0dXJuIGxhYmVsO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbW9tZW50aWZ5KGxhYmVsLCB0aW1lT3B0cykuZm9ybWF0KG1lLl9sYWJlbEZvcm1hdCk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEZ1bmN0aW9uIHRvIGZvcm1hdCBhbiBpbmRpdmlkdWFsIHRpY2sgbWFya1xuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0dGlja0Zvcm1hdEZ1bmN0aW9uOiBmdW5jdGlvbih0aWNrLCBpbmRleCwgdGlja3MsIGZvcm1hdE92ZXJyaWRlKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG9wdGlvbnMgPSBtZS5vcHRpb25zO1xuXHRcdFx0dmFyIHRpbWUgPSB0aWNrLnZhbHVlT2YoKTtcblx0XHRcdHZhciBmb3JtYXRzID0gb3B0aW9ucy50aW1lLmRpc3BsYXlGb3JtYXRzO1xuXHRcdFx0dmFyIG1pbm9yRm9ybWF0ID0gZm9ybWF0c1ttZS5fdW5pdF07XG5cdFx0XHR2YXIgbWFqb3JVbml0ID0gbWUuX21ham9yVW5pdDtcblx0XHRcdHZhciBtYWpvckZvcm1hdCA9IGZvcm1hdHNbbWFqb3JVbml0XTtcblx0XHRcdHZhciBtYWpvclRpbWUgPSB0aWNrLmNsb25lKCkuc3RhcnRPZihtYWpvclVuaXQpLnZhbHVlT2YoKTtcblx0XHRcdHZhciBtYWpvclRpY2tPcHRzID0gb3B0aW9ucy50aWNrcy5tYWpvcjtcblx0XHRcdHZhciBtYWpvciA9IG1ham9yVGlja09wdHMuZW5hYmxlZCAmJiBtYWpvclVuaXQgJiYgbWFqb3JGb3JtYXQgJiYgdGltZSA9PT0gbWFqb3JUaW1lO1xuXHRcdFx0dmFyIGxhYmVsID0gdGljay5mb3JtYXQoZm9ybWF0T3ZlcnJpZGUgPyBmb3JtYXRPdmVycmlkZSA6IG1ham9yID8gbWFqb3JGb3JtYXQgOiBtaW5vckZvcm1hdCk7XG5cdFx0XHR2YXIgdGlja09wdHMgPSBtYWpvciA/IG1ham9yVGlja09wdHMgOiBvcHRpb25zLnRpY2tzLm1pbm9yO1xuXHRcdFx0dmFyIGZvcm1hdHRlciA9IGhlbHBlcnMudmFsdWVPckRlZmF1bHQodGlja09wdHMuY2FsbGJhY2ssIHRpY2tPcHRzLnVzZXJDYWxsYmFjayk7XG5cblx0XHRcdHJldHVybiBmb3JtYXR0ZXIgPyBmb3JtYXR0ZXIobGFiZWwsIGluZGV4LCB0aWNrcykgOiBsYWJlbDtcblx0XHR9LFxuXG5cdFx0Y29udmVydFRpY2tzVG9MYWJlbHM6IGZ1bmN0aW9uKHRpY2tzKSB7XG5cdFx0XHR2YXIgbGFiZWxzID0gW107XG5cdFx0XHR2YXIgaSwgaWxlbjtcblxuXHRcdFx0Zm9yIChpID0gMCwgaWxlbiA9IHRpY2tzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdFx0XHRsYWJlbHMucHVzaCh0aGlzLnRpY2tGb3JtYXRGdW5jdGlvbihtb21lbnQodGlja3NbaV0udmFsdWUpLCBpLCB0aWNrcykpO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbGFiZWxzO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdGdldFBpeGVsRm9yT2Zmc2V0OiBmdW5jdGlvbih0aW1lKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIHNpemUgPSBtZS5faG9yaXpvbnRhbCA/IG1lLndpZHRoIDogbWUuaGVpZ2h0O1xuXHRcdFx0dmFyIHN0YXJ0ID0gbWUuX2hvcml6b250YWwgPyBtZS5sZWZ0IDogbWUudG9wO1xuXHRcdFx0dmFyIHBvcyA9IGludGVycG9sYXRlKG1lLl90YWJsZSwgJ3RpbWUnLCB0aW1lLCAncG9zJyk7XG5cblx0XHRcdHJldHVybiBzdGFydCArIHNpemUgKiAobWUuX29mZnNldHMubGVmdCArIHBvcykgLyAobWUuX29mZnNldHMubGVmdCArIDEgKyBtZS5fb2Zmc2V0cy5yaWdodCk7XG5cdFx0fSxcblxuXHRcdGdldFBpeGVsRm9yVmFsdWU6IGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgZGF0YXNldEluZGV4KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIHRpbWUgPSBudWxsO1xuXG5cdFx0XHRpZiAoaW5kZXggIT09IHVuZGVmaW5lZCAmJiBkYXRhc2V0SW5kZXggIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHR0aW1lID0gbWUuX3RpbWVzdGFtcHMuZGF0YXNldHNbZGF0YXNldEluZGV4XVtpbmRleF07XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aW1lID09PSBudWxsKSB7XG5cdFx0XHRcdHRpbWUgPSBwYXJzZSh2YWx1ZSwgbWUpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGltZSAhPT0gbnVsbCkge1xuXHRcdFx0XHRyZXR1cm4gbWUuZ2V0UGl4ZWxGb3JPZmZzZXQodGltZSk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdGdldFBpeGVsRm9yVGljazogZnVuY3Rpb24oaW5kZXgpIHtcblx0XHRcdHZhciB0aWNrcyA9IHRoaXMuZ2V0VGlja3MoKTtcblx0XHRcdHJldHVybiBpbmRleCA+PSAwICYmIGluZGV4IDwgdGlja3MubGVuZ3RoID9cblx0XHRcdFx0dGhpcy5nZXRQaXhlbEZvck9mZnNldCh0aWNrc1tpbmRleF0udmFsdWUpIDpcblx0XHRcdFx0bnVsbDtcblx0XHR9LFxuXG5cdFx0Z2V0VmFsdWVGb3JQaXhlbDogZnVuY3Rpb24ocGl4ZWwpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgc2l6ZSA9IG1lLl9ob3Jpem9udGFsID8gbWUud2lkdGggOiBtZS5oZWlnaHQ7XG5cdFx0XHR2YXIgc3RhcnQgPSBtZS5faG9yaXpvbnRhbCA/IG1lLmxlZnQgOiBtZS50b3A7XG5cdFx0XHR2YXIgcG9zID0gKHNpemUgPyAocGl4ZWwgLSBzdGFydCkgLyBzaXplIDogMCkgKiAobWUuX29mZnNldHMubGVmdCArIDEgKyBtZS5fb2Zmc2V0cy5sZWZ0KSAtIG1lLl9vZmZzZXRzLnJpZ2h0O1xuXHRcdFx0dmFyIHRpbWUgPSBpbnRlcnBvbGF0ZShtZS5fdGFibGUsICdwb3MnLCBwb3MsICd0aW1lJyk7XG5cblx0XHRcdHJldHVybiBtb21lbnQodGltZSk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIENydWRlIGFwcHJveGltYXRpb24gb2Ygd2hhdCB0aGUgbGFiZWwgd2lkdGggbWlnaHQgYmVcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdGdldExhYmVsV2lkdGg6IGZ1bmN0aW9uKGxhYmVsKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIHRpY2tzT3B0cyA9IG1lLm9wdGlvbnMudGlja3M7XG5cdFx0XHR2YXIgdGlja0xhYmVsV2lkdGggPSBtZS5jdHgubWVhc3VyZVRleHQobGFiZWwpLndpZHRoO1xuXHRcdFx0dmFyIGFuZ2xlID0gaGVscGVycy50b1JhZGlhbnModGlja3NPcHRzLm1heFJvdGF0aW9uKTtcblx0XHRcdHZhciBjb3NSb3RhdGlvbiA9IE1hdGguY29zKGFuZ2xlKTtcblx0XHRcdHZhciBzaW5Sb3RhdGlvbiA9IE1hdGguc2luKGFuZ2xlKTtcblx0XHRcdHZhciB0aWNrRm9udFNpemUgPSBoZWxwZXJzLnZhbHVlT3JEZWZhdWx0KHRpY2tzT3B0cy5mb250U2l6ZSwgZGVmYXVsdHMuZ2xvYmFsLmRlZmF1bHRGb250U2l6ZSk7XG5cblx0XHRcdHJldHVybiAodGlja0xhYmVsV2lkdGggKiBjb3NSb3RhdGlvbikgKyAodGlja0ZvbnRTaXplICogc2luUm90YXRpb24pO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdGdldExhYmVsQ2FwYWNpdHk6IGZ1bmN0aW9uKGV4YW1wbGVUaW1lKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXG5cdFx0XHR2YXIgZm9ybWF0T3ZlcnJpZGUgPSBtZS5vcHRpb25zLnRpbWUuZGlzcGxheUZvcm1hdHMubWlsbGlzZWNvbmQ7XHQvLyBQaWNrIHRoZSBsb25nZXN0IGZvcm1hdCBmb3IgZ3Vlc3RpbWF0aW9uXG5cblx0XHRcdHZhciBleGFtcGxlTGFiZWwgPSBtZS50aWNrRm9ybWF0RnVuY3Rpb24obW9tZW50KGV4YW1wbGVUaW1lKSwgMCwgW10sIGZvcm1hdE92ZXJyaWRlKTtcblx0XHRcdHZhciB0aWNrTGFiZWxXaWR0aCA9IG1lLmdldExhYmVsV2lkdGgoZXhhbXBsZUxhYmVsKTtcblx0XHRcdHZhciBpbm5lcldpZHRoID0gbWUuaXNIb3Jpem9udGFsKCkgPyBtZS53aWR0aCA6IG1lLmhlaWdodDtcblxuXHRcdFx0dmFyIGNhcGFjaXR5ID0gTWF0aC5mbG9vcihpbm5lcldpZHRoIC8gdGlja0xhYmVsV2lkdGgpO1xuXHRcdFx0cmV0dXJuIGNhcGFjaXR5ID4gMCA/IGNhcGFjaXR5IDogMTtcblx0XHR9XG5cdH0pO1xuXG5cdHNjYWxlU2VydmljZS5yZWdpc3RlclNjYWxlVHlwZSgndGltZScsIFRpbWVTY2FsZSwgZGVmYXVsdENvbmZpZyk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///a87cc\n")},bd22:function(module,exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = function(Chart) {\n\n\tChart.Radar = function(context, config) {\n\t\tconfig.type = 'radar';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmQyMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY2hhcnRzL0NoYXJ0LlJhZGFyLmpzPzg5ODEiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKENoYXJ0KSB7XG5cblx0Q2hhcnQuUmFkYXIgPSBmdW5jdGlvbihjb250ZXh0LCBjb25maWcpIHtcblx0XHRjb25maWcudHlwZSA9ICdyYWRhcic7XG5cblx0XHRyZXR1cm4gbmV3IENoYXJ0KGNvbnRleHQsIGNvbmZpZyk7XG5cdH07XG5cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///bd22\n")},bd74:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar Element = __webpack_require__(/*! ../core/core.element */ \"4a45\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\nvar layouts = __webpack_require__(/*! ../core/core.layouts */ \"6705\");\n\nvar noop = helpers.noop;\n\ndefaults._set('global', {\n\ttitle: {\n\t\tdisplay: false,\n\t\tfontStyle: 'bold',\n\t\tfullWidth: true,\n\t\tlineHeight: 1.2,\n\t\tpadding: 10,\n\t\tposition: 'top',\n\t\ttext: '',\n\t\tweight: 2000         // by default greater than legend (1000) to be above\n\t}\n});\n\n/**\n * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required!\n */\nvar Title = Element.extend({\n\tinitialize: function(config) {\n\t\tvar me = this;\n\t\thelpers.extend(me, config);\n\n\t\t// Contains hit boxes for each dataset (in dataset order)\n\t\tme.legendHitBoxes = [];\n\t},\n\n\t// These methods are ordered by lifecycle. Utilities then follow.\n\n\tbeforeUpdate: noop,\n\tupdate: function(maxWidth, maxHeight, margins) {\n\t\tvar me = this;\n\n\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\tme.beforeUpdate();\n\n\t\t// Absorb the master measurements\n\t\tme.maxWidth = maxWidth;\n\t\tme.maxHeight = maxHeight;\n\t\tme.margins = margins;\n\n\t\t// Dimensions\n\t\tme.beforeSetDimensions();\n\t\tme.setDimensions();\n\t\tme.afterSetDimensions();\n\t\t// Labels\n\t\tme.beforeBuildLabels();\n\t\tme.buildLabels();\n\t\tme.afterBuildLabels();\n\n\t\t// Fit\n\t\tme.beforeFit();\n\t\tme.fit();\n\t\tme.afterFit();\n\t\t//\n\t\tme.afterUpdate();\n\n\t\treturn me.minSize;\n\n\t},\n\tafterUpdate: noop,\n\n\t//\n\n\tbeforeSetDimensions: noop,\n\tsetDimensions: function() {\n\t\tvar me = this;\n\t\t// Set the unconstrained dimension before label rotation\n\t\tif (me.isHorizontal()) {\n\t\t\t// Reset position before calculating rotation\n\t\t\tme.width = me.maxWidth;\n\t\t\tme.left = 0;\n\t\t\tme.right = me.width;\n\t\t} else {\n\t\t\tme.height = me.maxHeight;\n\n\t\t\t// Reset position before calculating rotation\n\t\t\tme.top = 0;\n\t\t\tme.bottom = me.height;\n\t\t}\n\n\t\t// Reset padding\n\t\tme.paddingLeft = 0;\n\t\tme.paddingTop = 0;\n\t\tme.paddingRight = 0;\n\t\tme.paddingBottom = 0;\n\n\t\t// Reset minSize\n\t\tme.minSize = {\n\t\t\twidth: 0,\n\t\t\theight: 0\n\t\t};\n\t},\n\tafterSetDimensions: noop,\n\n\t//\n\n\tbeforeBuildLabels: noop,\n\tbuildLabels: noop,\n\tafterBuildLabels: noop,\n\n\t//\n\n\tbeforeFit: noop,\n\tfit: function() {\n\t\tvar me = this;\n\t\tvar valueOrDefault = helpers.valueOrDefault;\n\t\tvar opts = me.options;\n\t\tvar display = opts.display;\n\t\tvar fontSize = valueOrDefault(opts.fontSize, defaults.global.defaultFontSize);\n\t\tvar minSize = me.minSize;\n\t\tvar lineCount = helpers.isArray(opts.text) ? opts.text.length : 1;\n\t\tvar lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize);\n\t\tvar textSize = display ? (lineCount * lineHeight) + (opts.padding * 2) : 0;\n\n\t\tif (me.isHorizontal()) {\n\t\t\tminSize.width = me.maxWidth; // fill all the width\n\t\t\tminSize.height = textSize;\n\t\t} else {\n\t\t\tminSize.width = textSize;\n\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t}\n\n\t\tme.width = minSize.width;\n\t\tme.height = minSize.height;\n\n\t},\n\tafterFit: noop,\n\n\t// Shared Methods\n\tisHorizontal: function() {\n\t\tvar pos = this.options.position;\n\t\treturn pos === 'top' || pos === 'bottom';\n\t},\n\n\t// Actually draw the title block on the canvas\n\tdraw: function() {\n\t\tvar me = this;\n\t\tvar ctx = me.ctx;\n\t\tvar valueOrDefault = helpers.valueOrDefault;\n\t\tvar opts = me.options;\n\t\tvar globalDefaults = defaults.global;\n\n\t\tif (opts.display) {\n\t\t\tvar fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize);\n\t\t\tvar fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle);\n\t\t\tvar fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily);\n\t\t\tvar titleFont = helpers.fontString(fontSize, fontStyle, fontFamily);\n\t\t\tvar lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize);\n\t\t\tvar offset = lineHeight / 2 + opts.padding;\n\t\t\tvar rotation = 0;\n\t\t\tvar top = me.top;\n\t\t\tvar left = me.left;\n\t\t\tvar bottom = me.bottom;\n\t\t\tvar right = me.right;\n\t\t\tvar maxWidth, titleX, titleY;\n\n\t\t\tctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour\n\t\t\tctx.font = titleFont;\n\n\t\t\t// Horizontal\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\ttitleX = left + ((right - left) / 2); // midpoint of the width\n\t\t\t\ttitleY = top + offset;\n\t\t\t\tmaxWidth = right - left;\n\t\t\t} else {\n\t\t\t\ttitleX = opts.position === 'left' ? left + offset : right - offset;\n\t\t\t\ttitleY = top + ((bottom - top) / 2);\n\t\t\t\tmaxWidth = bottom - top;\n\t\t\t\trotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);\n\t\t\t}\n\n\t\t\tctx.save();\n\t\t\tctx.translate(titleX, titleY);\n\t\t\tctx.rotate(rotation);\n\t\t\tctx.textAlign = 'center';\n\t\t\tctx.textBaseline = 'middle';\n\n\t\t\tvar text = opts.text;\n\t\t\tif (helpers.isArray(text)) {\n\t\t\t\tvar y = 0;\n\t\t\t\tfor (var i = 0; i < text.length; ++i) {\n\t\t\t\t\tctx.fillText(text[i], 0, y, maxWidth);\n\t\t\t\t\ty += lineHeight;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tctx.fillText(text, 0, 0, maxWidth);\n\t\t\t}\n\n\t\t\tctx.restore();\n\t\t}\n\t}\n});\n\nfunction createNewTitleBlockAndAttach(chart, titleOpts) {\n\tvar title = new Title({\n\t\tctx: chart.ctx,\n\t\toptions: titleOpts,\n\t\tchart: chart\n\t});\n\n\tlayouts.configure(chart, title, titleOpts);\n\tlayouts.addBox(chart, title);\n\tchart.titleBlock = title;\n}\n\nmodule.exports = {\n\tid: 'title',\n\n\t/**\n\t * Backward compatibility: since 2.1.5, the title is registered as a plugin, making\n\t * Chart.Title obsolete. To avoid a breaking change, we export the Title as part of\n\t * the plugin, which one will be re-exposed in the chart.js file.\n\t * https://github.com/chartjs/Chart.js/pull/2640\n\t * @private\n\t */\n\t_element: Title,\n\n\tbeforeInit: function(chart) {\n\t\tvar titleOpts = chart.options.title;\n\n\t\tif (titleOpts) {\n\t\t\tcreateNewTitleBlockAndAttach(chart, titleOpts);\n\t\t}\n\t},\n\n\tbeforeUpdate: function(chart) {\n\t\tvar titleOpts = chart.options.title;\n\t\tvar titleBlock = chart.titleBlock;\n\n\t\tif (titleOpts) {\n\t\t\thelpers.mergeIf(titleOpts, defaults.global.title);\n\n\t\t\tif (titleBlock) {\n\t\t\t\tlayouts.configure(chart, titleBlock, titleOpts);\n\t\t\t\ttitleBlock.options = titleOpts;\n\t\t\t} else {\n\t\t\t\tcreateNewTitleBlockAndAttach(chart, titleOpts);\n\t\t\t}\n\t\t} else if (titleBlock) {\n\t\t\tlayouts.removeBox(chart, titleBlock);\n\t\t\tdelete chart.titleBlock;\n\t\t}\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmQ3NC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4udGl0bGUuanM/OWEzNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5kZWZhdWx0cycpO1xudmFyIEVsZW1lbnQgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuZWxlbWVudCcpO1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2luZGV4Jyk7XG52YXIgbGF5b3V0cyA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5sYXlvdXRzJyk7XG5cbnZhciBub29wID0gaGVscGVycy5ub29wO1xuXG5kZWZhdWx0cy5fc2V0KCdnbG9iYWwnLCB7XG5cdHRpdGxlOiB7XG5cdFx0ZGlzcGxheTogZmFsc2UsXG5cdFx0Zm9udFN0eWxlOiAnYm9sZCcsXG5cdFx0ZnVsbFdpZHRoOiB0cnVlLFxuXHRcdGxpbmVIZWlnaHQ6IDEuMixcblx0XHRwYWRkaW5nOiAxMCxcblx0XHRwb3NpdGlvbjogJ3RvcCcsXG5cdFx0dGV4dDogJycsXG5cdFx0d2VpZ2h0OiAyMDAwICAgICAgICAgLy8gYnkgZGVmYXVsdCBncmVhdGVyIHRoYW4gbGVnZW5kICgxMDAwKSB0byBiZSBhYm92ZVxuXHR9XG59KTtcblxuLyoqXG4gKiBJTVBPUlRBTlQ6IHRoaXMgY2xhc3MgaXMgZXhwb3NlZCBwdWJsaWNseSBhcyBDaGFydC5MZWdlbmQsIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgcmVxdWlyZWQhXG4gKi9cbnZhciBUaXRsZSA9IEVsZW1lbnQuZXh0ZW5kKHtcblx0aW5pdGlhbGl6ZTogZnVuY3Rpb24oY29uZmlnKSB7XG5cdFx0dmFyIG1lID0gdGhpcztcblx0XHRoZWxwZXJzLmV4dGVuZChtZSwgY29uZmlnKTtcblxuXHRcdC8vIENvbnRhaW5zIGhpdCBib3hlcyBmb3IgZWFjaCBkYXRhc2V0IChpbiBkYXRhc2V0IG9yZGVyKVxuXHRcdG1lLmxlZ2VuZEhpdEJveGVzID0gW107XG5cdH0sXG5cblx0Ly8gVGhlc2UgbWV0aG9kcyBhcmUgb3JkZXJlZCBieSBsaWZlY3ljbGUuIFV0aWxpdGllcyB0aGVuIGZvbGxvdy5cblxuXHRiZWZvcmVVcGRhdGU6IG5vb3AsXG5cdHVwZGF0ZTogZnVuY3Rpb24obWF4V2lkdGgsIG1heEhlaWdodCwgbWFyZ2lucykge1xuXHRcdHZhciBtZSA9IHRoaXM7XG5cblx0XHQvLyBVcGRhdGUgTGlmZWN5Y2xlIC0gUHJvYmFibHkgZG9uJ3Qgd2FudCB0byBldmVyIGV4dGVuZCBvciBvdmVyd3JpdGUgdGhpcyBmdW5jdGlvbiA7KVxuXHRcdG1lLmJlZm9yZVVwZGF0ZSgpO1xuXG5cdFx0Ly8gQWJzb3JiIHRoZSBtYXN0ZXIgbWVhc3VyZW1lbnRzXG5cdFx0bWUubWF4V2lkdGggPSBtYXhXaWR0aDtcblx0XHRtZS5tYXhIZWlnaHQgPSBtYXhIZWlnaHQ7XG5cdFx0bWUubWFyZ2lucyA9IG1hcmdpbnM7XG5cblx0XHQvLyBEaW1lbnNpb25zXG5cdFx0bWUuYmVmb3JlU2V0RGltZW5zaW9ucygpO1xuXHRcdG1lLnNldERpbWVuc2lvbnMoKTtcblx0XHRtZS5hZnRlclNldERpbWVuc2lvbnMoKTtcblx0XHQvLyBMYWJlbHNcblx0XHRtZS5iZWZvcmVCdWlsZExhYmVscygpO1xuXHRcdG1lLmJ1aWxkTGFiZWxzKCk7XG5cdFx0bWUuYWZ0ZXJCdWlsZExhYmVscygpO1xuXG5cdFx0Ly8gRml0XG5cdFx0bWUuYmVmb3JlRml0KCk7XG5cdFx0bWUuZml0KCk7XG5cdFx0bWUuYWZ0ZXJGaXQoKTtcblx0XHQvL1xuXHRcdG1lLmFmdGVyVXBkYXRlKCk7XG5cblx0XHRyZXR1cm4gbWUubWluU2l6ZTtcblxuXHR9LFxuXHRhZnRlclVwZGF0ZTogbm9vcCxcblxuXHQvL1xuXG5cdGJlZm9yZVNldERpbWVuc2lvbnM6IG5vb3AsXG5cdHNldERpbWVuc2lvbnM6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0Ly8gU2V0IHRoZSB1bmNvbnN0cmFpbmVkIGRpbWVuc2lvbiBiZWZvcmUgbGFiZWwgcm90YXRpb25cblx0XHRpZiAobWUuaXNIb3Jpem9udGFsKCkpIHtcblx0XHRcdC8vIFJlc2V0IHBvc2l0aW9uIGJlZm9yZSBjYWxjdWxhdGluZyByb3RhdGlvblxuXHRcdFx0bWUud2lkdGggPSBtZS5tYXhXaWR0aDtcblx0XHRcdG1lLmxlZnQgPSAwO1xuXHRcdFx0bWUucmlnaHQgPSBtZS53aWR0aDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bWUuaGVpZ2h0ID0gbWUubWF4SGVpZ2h0O1xuXG5cdFx0XHQvLyBSZXNldCBwb3NpdGlvbiBiZWZvcmUgY2FsY3VsYXRpbmcgcm90YXRpb25cblx0XHRcdG1lLnRvcCA9IDA7XG5cdFx0XHRtZS5ib3R0b20gPSBtZS5oZWlnaHQ7XG5cdFx0fVxuXG5cdFx0Ly8gUmVzZXQgcGFkZGluZ1xuXHRcdG1lLnBhZGRpbmdMZWZ0ID0gMDtcblx0XHRtZS5wYWRkaW5nVG9wID0gMDtcblx0XHRtZS5wYWRkaW5nUmlnaHQgPSAwO1xuXHRcdG1lLnBhZGRpbmdCb3R0b20gPSAwO1xuXG5cdFx0Ly8gUmVzZXQgbWluU2l6ZVxuXHRcdG1lLm1pblNpemUgPSB7XG5cdFx0XHR3aWR0aDogMCxcblx0XHRcdGhlaWdodDogMFxuXHRcdH07XG5cdH0sXG5cdGFmdGVyU2V0RGltZW5zaW9uczogbm9vcCxcblxuXHQvL1xuXG5cdGJlZm9yZUJ1aWxkTGFiZWxzOiBub29wLFxuXHRidWlsZExhYmVsczogbm9vcCxcblx0YWZ0ZXJCdWlsZExhYmVsczogbm9vcCxcblxuXHQvL1xuXG5cdGJlZm9yZUZpdDogbm9vcCxcblx0Zml0OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciB2YWx1ZU9yRGVmYXVsdCA9IGhlbHBlcnMudmFsdWVPckRlZmF1bHQ7XG5cdFx0dmFyIG9wdHMgPSBtZS5vcHRpb25zO1xuXHRcdHZhciBkaXNwbGF5ID0gb3B0cy5kaXNwbGF5O1xuXHRcdHZhciBmb250U2l6ZSA9IHZhbHVlT3JEZWZhdWx0KG9wdHMuZm9udFNpemUsIGRlZmF1bHRzLmdsb2JhbC5kZWZhdWx0Rm9udFNpemUpO1xuXHRcdHZhciBtaW5TaXplID0gbWUubWluU2l6ZTtcblx0XHR2YXIgbGluZUNvdW50ID0gaGVscGVycy5pc0FycmF5KG9wdHMudGV4dCkgPyBvcHRzLnRleHQubGVuZ3RoIDogMTtcblx0XHR2YXIgbGluZUhlaWdodCA9IGhlbHBlcnMub3B0aW9ucy50b0xpbmVIZWlnaHQob3B0cy5saW5lSGVpZ2h0LCBmb250U2l6ZSk7XG5cdFx0dmFyIHRleHRTaXplID0gZGlzcGxheSA/IChsaW5lQ291bnQgKiBsaW5lSGVpZ2h0KSArIChvcHRzLnBhZGRpbmcgKiAyKSA6IDA7XG5cblx0XHRpZiAobWUuaXNIb3Jpem9udGFsKCkpIHtcblx0XHRcdG1pblNpemUud2lkdGggPSBtZS5tYXhXaWR0aDsgLy8gZmlsbCBhbGwgdGhlIHdpZHRoXG5cdFx0XHRtaW5TaXplLmhlaWdodCA9IHRleHRTaXplO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRtaW5TaXplLndpZHRoID0gdGV4dFNpemU7XG5cdFx0XHRtaW5TaXplLmhlaWdodCA9IG1lLm1heEhlaWdodDsgLy8gZmlsbCBhbGwgdGhlIGhlaWdodFxuXHRcdH1cblxuXHRcdG1lLndpZHRoID0gbWluU2l6ZS53aWR0aDtcblx0XHRtZS5oZWlnaHQgPSBtaW5TaXplLmhlaWdodDtcblxuXHR9LFxuXHRhZnRlckZpdDogbm9vcCxcblxuXHQvLyBTaGFyZWQgTWV0aG9kc1xuXHRpc0hvcml6b250YWw6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBwb3MgPSB0aGlzLm9wdGlvbnMucG9zaXRpb247XG5cdFx0cmV0dXJuIHBvcyA9PT0gJ3RvcCcgfHwgcG9zID09PSAnYm90dG9tJztcblx0fSxcblxuXHQvLyBBY3R1YWxseSBkcmF3IHRoZSB0aXRsZSBibG9jayBvbiB0aGUgY2FudmFzXG5cdGRyYXc6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0dmFyIGN0eCA9IG1lLmN0eDtcblx0XHR2YXIgdmFsdWVPckRlZmF1bHQgPSBoZWxwZXJzLnZhbHVlT3JEZWZhdWx0O1xuXHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcblx0XHR2YXIgZ2xvYmFsRGVmYXVsdHMgPSBkZWZhdWx0cy5nbG9iYWw7XG5cblx0XHRpZiAob3B0cy5kaXNwbGF5KSB7XG5cdFx0XHR2YXIgZm9udFNpemUgPSB2YWx1ZU9yRGVmYXVsdChvcHRzLmZvbnRTaXplLCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udFNpemUpO1xuXHRcdFx0dmFyIGZvbnRTdHlsZSA9IHZhbHVlT3JEZWZhdWx0KG9wdHMuZm9udFN0eWxlLCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udFN0eWxlKTtcblx0XHRcdHZhciBmb250RmFtaWx5ID0gdmFsdWVPckRlZmF1bHQob3B0cy5mb250RmFtaWx5LCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udEZhbWlseSk7XG5cdFx0XHR2YXIgdGl0bGVGb250ID0gaGVscGVycy5mb250U3RyaW5nKGZvbnRTaXplLCBmb250U3R5bGUsIGZvbnRGYW1pbHkpO1xuXHRcdFx0dmFyIGxpbmVIZWlnaHQgPSBoZWxwZXJzLm9wdGlvbnMudG9MaW5lSGVpZ2h0KG9wdHMubGluZUhlaWdodCwgZm9udFNpemUpO1xuXHRcdFx0dmFyIG9mZnNldCA9IGxpbmVIZWlnaHQgLyAyICsgb3B0cy5wYWRkaW5nO1xuXHRcdFx0dmFyIHJvdGF0aW9uID0gMDtcblx0XHRcdHZhciB0b3AgPSBtZS50b3A7XG5cdFx0XHR2YXIgbGVmdCA9IG1lLmxlZnQ7XG5cdFx0XHR2YXIgYm90dG9tID0gbWUuYm90dG9tO1xuXHRcdFx0dmFyIHJpZ2h0ID0gbWUucmlnaHQ7XG5cdFx0XHR2YXIgbWF4V2lkdGgsIHRpdGxlWCwgdGl0bGVZO1xuXG5cdFx0XHRjdHguZmlsbFN0eWxlID0gdmFsdWVPckRlZmF1bHQob3B0cy5mb250Q29sb3IsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250Q29sb3IpOyAvLyByZW5kZXIgaW4gY29ycmVjdCBjb2xvdXJcblx0XHRcdGN0eC5mb250ID0gdGl0bGVGb250O1xuXG5cdFx0XHQvLyBIb3Jpem9udGFsXG5cdFx0XHRpZiAobWUuaXNIb3Jpem9udGFsKCkpIHtcblx0XHRcdFx0dGl0bGVYID0gbGVmdCArICgocmlnaHQgLSBsZWZ0KSAvIDIpOyAvLyBtaWRwb2ludCBvZiB0aGUgd2lkdGhcblx0XHRcdFx0dGl0bGVZID0gdG9wICsgb2Zmc2V0O1xuXHRcdFx0XHRtYXhXaWR0aCA9IHJpZ2h0IC0gbGVmdDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRpdGxlWCA9IG9wdHMucG9zaXRpb24gPT09ICdsZWZ0JyA/IGxlZnQgKyBvZmZzZXQgOiByaWdodCAtIG9mZnNldDtcblx0XHRcdFx0dGl0bGVZID0gdG9wICsgKChib3R0b20gLSB0b3ApIC8gMik7XG5cdFx0XHRcdG1heFdpZHRoID0gYm90dG9tIC0gdG9wO1xuXHRcdFx0XHRyb3RhdGlvbiA9IE1hdGguUEkgKiAob3B0cy5wb3NpdGlvbiA9PT0gJ2xlZnQnID8gLTAuNSA6IDAuNSk7XG5cdFx0XHR9XG5cblx0XHRcdGN0eC5zYXZlKCk7XG5cdFx0XHRjdHgudHJhbnNsYXRlKHRpdGxlWCwgdGl0bGVZKTtcblx0XHRcdGN0eC5yb3RhdGUocm90YXRpb24pO1xuXHRcdFx0Y3R4LnRleHRBbGlnbiA9ICdjZW50ZXInO1xuXHRcdFx0Y3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuXG5cdFx0XHR2YXIgdGV4dCA9IG9wdHMudGV4dDtcblx0XHRcdGlmIChoZWxwZXJzLmlzQXJyYXkodGV4dCkpIHtcblx0XHRcdFx0dmFyIHkgPSAwO1xuXHRcdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHRleHQubGVuZ3RoOyArK2kpIHtcblx0XHRcdFx0XHRjdHguZmlsbFRleHQodGV4dFtpXSwgMCwgeSwgbWF4V2lkdGgpO1xuXHRcdFx0XHRcdHkgKz0gbGluZUhlaWdodDtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y3R4LmZpbGxUZXh0KHRleHQsIDAsIDAsIG1heFdpZHRoKTtcblx0XHRcdH1cblxuXHRcdFx0Y3R4LnJlc3RvcmUoKTtcblx0XHR9XG5cdH1cbn0pO1xuXG5mdW5jdGlvbiBjcmVhdGVOZXdUaXRsZUJsb2NrQW5kQXR0YWNoKGNoYXJ0LCB0aXRsZU9wdHMpIHtcblx0dmFyIHRpdGxlID0gbmV3IFRpdGxlKHtcblx0XHRjdHg6IGNoYXJ0LmN0eCxcblx0XHRvcHRpb25zOiB0aXRsZU9wdHMsXG5cdFx0Y2hhcnQ6IGNoYXJ0XG5cdH0pO1xuXG5cdGxheW91dHMuY29uZmlndXJlKGNoYXJ0LCB0aXRsZSwgdGl0bGVPcHRzKTtcblx0bGF5b3V0cy5hZGRCb3goY2hhcnQsIHRpdGxlKTtcblx0Y2hhcnQudGl0bGVCbG9jayA9IHRpdGxlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0aWQ6ICd0aXRsZScsXG5cblx0LyoqXG5cdCAqIEJhY2t3YXJkIGNvbXBhdGliaWxpdHk6IHNpbmNlIDIuMS41LCB0aGUgdGl0bGUgaXMgcmVnaXN0ZXJlZCBhcyBhIHBsdWdpbiwgbWFraW5nXG5cdCAqIENoYXJ0LlRpdGxlIG9ic29sZXRlLiBUbyBhdm9pZCBhIGJyZWFraW5nIGNoYW5nZSwgd2UgZXhwb3J0IHRoZSBUaXRsZSBhcyBwYXJ0IG9mXG5cdCAqIHRoZSBwbHVnaW4sIHdoaWNoIG9uZSB3aWxsIGJlIHJlLWV4cG9zZWQgaW4gdGhlIGNoYXJ0LmpzIGZpbGUuXG5cdCAqIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL3B1bGwvMjY0MFxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0X2VsZW1lbnQ6IFRpdGxlLFxuXG5cdGJlZm9yZUluaXQ6IGZ1bmN0aW9uKGNoYXJ0KSB7XG5cdFx0dmFyIHRpdGxlT3B0cyA9IGNoYXJ0Lm9wdGlvbnMudGl0bGU7XG5cblx0XHRpZiAodGl0bGVPcHRzKSB7XG5cdFx0XHRjcmVhdGVOZXdUaXRsZUJsb2NrQW5kQXR0YWNoKGNoYXJ0LCB0aXRsZU9wdHMpO1xuXHRcdH1cblx0fSxcblxuXHRiZWZvcmVVcGRhdGU6IGZ1bmN0aW9uKGNoYXJ0KSB7XG5cdFx0dmFyIHRpdGxlT3B0cyA9IGNoYXJ0Lm9wdGlvbnMudGl0bGU7XG5cdFx0dmFyIHRpdGxlQmxvY2sgPSBjaGFydC50aXRsZUJsb2NrO1xuXG5cdFx0aWYgKHRpdGxlT3B0cykge1xuXHRcdFx0aGVscGVycy5tZXJnZUlmKHRpdGxlT3B0cywgZGVmYXVsdHMuZ2xvYmFsLnRpdGxlKTtcblxuXHRcdFx0aWYgKHRpdGxlQmxvY2spIHtcblx0XHRcdFx0bGF5b3V0cy5jb25maWd1cmUoY2hhcnQsIHRpdGxlQmxvY2ssIHRpdGxlT3B0cyk7XG5cdFx0XHRcdHRpdGxlQmxvY2sub3B0aW9ucyA9IHRpdGxlT3B0cztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNyZWF0ZU5ld1RpdGxlQmxvY2tBbmRBdHRhY2goY2hhcnQsIHRpdGxlT3B0cyk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmICh0aXRsZUJsb2NrKSB7XG5cdFx0XHRsYXlvdXRzLnJlbW92ZUJveChjaGFydCwgdGl0bGVCbG9jayk7XG5cdFx0XHRkZWxldGUgY2hhcnQudGl0bGVCbG9jaztcblx0XHR9XG5cdH1cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///bd74\n")},beaa:function(module,exports,__webpack_require__){"use strict";eval('\n\nvar helpers = __webpack_require__(/*! ../helpers/index */ "66c8");\n\nmodule.exports = {\n\t/**\n\t * @private\n\t */\n\t_set: function(scope, values) {\n\t\treturn helpers.merge(this[scope] || (this[scope] = {}), values);\n\t}\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVhYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmRlZmF1bHRzLmpzPzA4MzIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0X3NldDogZnVuY3Rpb24oc2NvcGUsIHZhbHVlcykge1xuXHRcdHJldHVybiBoZWxwZXJzLm1lcmdlKHRoaXNbc2NvcGVdIHx8ICh0aGlzW3Njb3BlXSA9IHt9KSwgdmFsdWVzKTtcblx0fVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///beaa\n')},cb9d:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ./core.defaults */ \"beaa\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\ndefaults._set('global', {\n\tplugins: {}\n});\n\n/**\n * The plugin service singleton\n * @namespace Chart.plugins\n * @since 2.1.0\n */\nmodule.exports = {\n\t/**\n\t * Globally registered plugins.\n\t * @private\n\t */\n\t_plugins: [],\n\n\t/**\n\t * This identifier is used to invalidate the descriptors cache attached to each chart\n\t * when a global plugin is registered or unregistered. In this case, the cache ID is\n\t * incremented and descriptors are regenerated during following API calls.\n\t * @private\n\t */\n\t_cacheId: 0,\n\n\t/**\n\t * Registers the given plugin(s) if not already registered.\n\t * @param {Array|Object} plugins plugin instance(s).\n\t */\n\tregister: function(plugins) {\n\t\tvar p = this._plugins;\n\t\t([]).concat(plugins).forEach(function(plugin) {\n\t\t\tif (p.indexOf(plugin) === -1) {\n\t\t\t\tp.push(plugin);\n\t\t\t}\n\t\t});\n\n\t\tthis._cacheId++;\n\t},\n\n\t/**\n\t * Unregisters the given plugin(s) only if registered.\n\t * @param {Array|Object} plugins plugin instance(s).\n\t */\n\tunregister: function(plugins) {\n\t\tvar p = this._plugins;\n\t\t([]).concat(plugins).forEach(function(plugin) {\n\t\t\tvar idx = p.indexOf(plugin);\n\t\t\tif (idx !== -1) {\n\t\t\t\tp.splice(idx, 1);\n\t\t\t}\n\t\t});\n\n\t\tthis._cacheId++;\n\t},\n\n\t/**\n\t * Remove all registered plugins.\n\t * @since 2.1.5\n\t */\n\tclear: function() {\n\t\tthis._plugins = [];\n\t\tthis._cacheId++;\n\t},\n\n\t/**\n\t * Returns the number of registered plugins?\n\t * @returns {Number}\n\t * @since 2.1.5\n\t */\n\tcount: function() {\n\t\treturn this._plugins.length;\n\t},\n\n\t/**\n\t * Returns all registered plugin instances.\n\t * @returns {Array} array of plugin objects.\n\t * @since 2.1.5\n\t */\n\tgetAll: function() {\n\t\treturn this._plugins;\n\t},\n\n\t/**\n\t * Calls enabled plugins for `chart` on the specified hook and with the given args.\n\t * This method immediately returns as soon as a plugin explicitly returns false. The\n\t * returned value can be used, for instance, to interrupt the current action.\n\t * @param {Object} chart - The chart instance for which plugins should be called.\n\t * @param {String} hook - The name of the plugin method to call (e.g. 'beforeUpdate').\n\t * @param {Array} [args] - Extra arguments to apply to the hook call.\n\t * @returns {Boolean} false if any of the plugins return false, else returns true.\n\t */\n\tnotify: function(chart, hook, args) {\n\t\tvar descriptors = this.descriptors(chart);\n\t\tvar ilen = descriptors.length;\n\t\tvar i, descriptor, plugin, params, method;\n\n\t\tfor (i = 0; i < ilen; ++i) {\n\t\t\tdescriptor = descriptors[i];\n\t\t\tplugin = descriptor.plugin;\n\t\t\tmethod = plugin[hook];\n\t\t\tif (typeof method === 'function') {\n\t\t\t\tparams = [chart].concat(args || []);\n\t\t\t\tparams.push(descriptor.options);\n\t\t\t\tif (method.apply(plugin, params) === false) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t},\n\n\t/**\n\t * Returns descriptors of enabled plugins for the given chart.\n\t * @returns {Array} [{ plugin, options }]\n\t * @private\n\t */\n\tdescriptors: function(chart) {\n\t\tvar cache = chart.$plugins || (chart.$plugins = {});\n\t\tif (cache.id === this._cacheId) {\n\t\t\treturn cache.descriptors;\n\t\t}\n\n\t\tvar plugins = [];\n\t\tvar descriptors = [];\n\t\tvar config = (chart && chart.config) || {};\n\t\tvar options = (config.options && config.options.plugins) || {};\n\n\t\tthis._plugins.concat(config.plugins || []).forEach(function(plugin) {\n\t\t\tvar idx = plugins.indexOf(plugin);\n\t\t\tif (idx !== -1) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar id = plugin.id;\n\t\t\tvar opts = options[id];\n\t\t\tif (opts === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (opts === true) {\n\t\t\t\topts = helpers.clone(defaults.global.plugins[id]);\n\t\t\t}\n\n\t\t\tplugins.push(plugin);\n\t\t\tdescriptors.push({\n\t\t\t\tplugin: plugin,\n\t\t\t\toptions: opts || {}\n\t\t\t});\n\t\t});\n\n\t\tcache.descriptors = descriptors;\n\t\tcache.id = this._cacheId;\n\t\treturn descriptors;\n\t},\n\n\t/**\n\t * Invalidates cache for the given chart: descriptors hold a reference on plugin option,\n\t * but in some cases, this reference can be changed by the user when updating options.\n\t * https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167\n\t * @private\n\t */\n\t_invalidate: function(chart) {\n\t\tdelete chart.$plugins;\n\t}\n};\n\n/**\n * Plugin extension hooks.\n * @interface IPlugin\n * @since 2.1.0\n */\n/**\n * @method IPlugin#beforeInit\n * @desc Called before initializing `chart`.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#afterInit\n * @desc Called after `chart` has been initialized and before the first update.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#beforeUpdate\n * @desc Called before updating `chart`. If any plugin returns `false`, the update\n * is cancelled (and thus subsequent render(s)) until another `update` is triggered.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Object} options - The plugin options.\n * @returns {Boolean} `false` to cancel the chart update.\n */\n/**\n * @method IPlugin#afterUpdate\n * @desc Called after `chart` has been updated and before rendering. Note that this\n * hook will not be called if the chart update has been previously cancelled.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#beforeDatasetsUpdate\n * @desc Called before updating the `chart` datasets. If any plugin returns `false`,\n * the datasets update is cancelled until another `update` is triggered.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Object} options - The plugin options.\n * @returns {Boolean} false to cancel the datasets update.\n * @since version 2.1.5\n*/\n/**\n * @method IPlugin#afterDatasetsUpdate\n * @desc Called after the `chart` datasets have been updated. Note that this hook\n * will not be called if the datasets update has been previously cancelled.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Object} options - The plugin options.\n * @since version 2.1.5\n */\n/**\n * @method IPlugin#beforeDatasetUpdate\n * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin\n * returns `false`, the datasets update is cancelled until another `update` is triggered.\n * @param {Chart} chart - The chart instance.\n * @param {Object} args - The call arguments.\n * @param {Number} args.index - The dataset index.\n * @param {Object} args.meta - The dataset metadata.\n * @param {Object} options - The plugin options.\n * @returns {Boolean} `false` to cancel the chart datasets drawing.\n */\n/**\n * @method IPlugin#afterDatasetUpdate\n * @desc Called after the `chart` datasets at the given `args.index` has been updated. Note\n * that this hook will not be called if the datasets update has been previously cancelled.\n * @param {Chart} chart - The chart instance.\n * @param {Object} args - The call arguments.\n * @param {Number} args.index - The dataset index.\n * @param {Object} args.meta - The dataset metadata.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#beforeLayout\n * @desc Called before laying out `chart`. If any plugin returns `false`,\n * the layout update is cancelled until another `update` is triggered.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Object} options - The plugin options.\n * @returns {Boolean} `false` to cancel the chart layout.\n */\n/**\n * @method IPlugin#afterLayout\n * @desc Called after the `chart` has been layed out. Note that this hook will not\n * be called if the layout update has been previously cancelled.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#beforeRender\n * @desc Called before rendering `chart`. If any plugin returns `false`,\n * the rendering is cancelled until another `render` is triggered.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Object} options - The plugin options.\n * @returns {Boolean} `false` to cancel the chart rendering.\n */\n/**\n * @method IPlugin#afterRender\n * @desc Called after the `chart` has been fully rendered (and animation completed). Note\n * that this hook will not be called if the rendering has been previously cancelled.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#beforeDraw\n * @desc Called before drawing `chart` at every animation frame specified by the given\n * easing value. If any plugin returns `false`, the frame drawing is cancelled until\n * another `render` is triggered.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n * @param {Object} options - The plugin options.\n * @returns {Boolean} `false` to cancel the chart drawing.\n */\n/**\n * @method IPlugin#afterDraw\n * @desc Called after the `chart` has been drawn for the specific easing value. Note\n * that this hook will not be called if the drawing has been previously cancelled.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#beforeDatasetsDraw\n * @desc Called before drawing the `chart` datasets. If any plugin returns `false`,\n * the datasets drawing is cancelled until another `render` is triggered.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n * @param {Object} options - The plugin options.\n * @returns {Boolean} `false` to cancel the chart datasets drawing.\n */\n/**\n * @method IPlugin#afterDatasetsDraw\n * @desc Called after the `chart` datasets have been drawn. Note that this hook\n * will not be called if the datasets drawing has been previously cancelled.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#beforeDatasetDraw\n * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets\n * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing\n * is cancelled until another `render` is triggered.\n * @param {Chart} chart - The chart instance.\n * @param {Object} args - The call arguments.\n * @param {Number} args.index - The dataset index.\n * @param {Object} args.meta - The dataset metadata.\n * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.\n * @param {Object} options - The plugin options.\n * @returns {Boolean} `false` to cancel the chart datasets drawing.\n */\n/**\n * @method IPlugin#afterDatasetDraw\n * @desc Called after the `chart` datasets at the given `args.index` have been drawn\n * (datasets are drawn in the reverse order). Note that this hook will not be called\n * if the datasets drawing has been previously cancelled.\n * @param {Chart} chart - The chart instance.\n * @param {Object} args - The call arguments.\n * @param {Number} args.index - The dataset index.\n * @param {Object} args.meta - The dataset metadata.\n * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#beforeTooltipDraw\n * @desc Called before drawing the `tooltip`. If any plugin returns `false`,\n * the tooltip drawing is cancelled until another `render` is triggered.\n * @param {Chart} chart - The chart instance.\n * @param {Object} args - The call arguments.\n * @param {Object} args.tooltip - The tooltip.\n * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.\n * @param {Object} options - The plugin options.\n * @returns {Boolean} `false` to cancel the chart tooltip drawing.\n */\n/**\n * @method IPlugin#afterTooltipDraw\n * @desc Called after drawing the `tooltip`. Note that this hook will not\n * be called if the tooltip drawing has been previously cancelled.\n * @param {Chart} chart - The chart instance.\n * @param {Object} args - The call arguments.\n * @param {Object} args.tooltip - The tooltip.\n * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#beforeEvent\n * @desc Called before processing the specified `event`. If any plugin returns `false`,\n * the event will be discarded.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {IEvent} event - The event object.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#afterEvent\n * @desc Called after the `event` has been consumed. Note that this hook\n * will not be called if the `event` has been previously discarded.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {IEvent} event - The event object.\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#resize\n * @desc Called after the chart as been resized.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Number} size - The new canvas display size (eq. canvas.style width & height).\n * @param {Object} options - The plugin options.\n */\n/**\n * @method IPlugin#destroy\n * @desc Called after the chart as been destroyed.\n * @param {Chart.Controller} chart - The chart instance.\n * @param {Object} options - The plugin options.\n */\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2I5ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLnBsdWdpbnMuanM/NTYwMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4vY29yZS5kZWZhdWx0cycpO1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2luZGV4Jyk7XG5cbmRlZmF1bHRzLl9zZXQoJ2dsb2JhbCcsIHtcblx0cGx1Z2luczoge31cbn0pO1xuXG4vKipcbiAqIFRoZSBwbHVnaW4gc2VydmljZSBzaW5nbGV0b25cbiAqIEBuYW1lc3BhY2UgQ2hhcnQucGx1Z2luc1xuICogQHNpbmNlIDIuMS4wXG4gKi9cbm1vZHVsZS5leHBvcnRzID0ge1xuXHQvKipcblx0ICogR2xvYmFsbHkgcmVnaXN0ZXJlZCBwbHVnaW5zLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0X3BsdWdpbnM6IFtdLFxuXG5cdC8qKlxuXHQgKiBUaGlzIGlkZW50aWZpZXIgaXMgdXNlZCB0byBpbnZhbGlkYXRlIHRoZSBkZXNjcmlwdG9ycyBjYWNoZSBhdHRhY2hlZCB0byBlYWNoIGNoYXJ0XG5cdCAqIHdoZW4gYSBnbG9iYWwgcGx1Z2luIGlzIHJlZ2lzdGVyZWQgb3IgdW5yZWdpc3RlcmVkLiBJbiB0aGlzIGNhc2UsIHRoZSBjYWNoZSBJRCBpc1xuXHQgKiBpbmNyZW1lbnRlZCBhbmQgZGVzY3JpcHRvcnMgYXJlIHJlZ2VuZXJhdGVkIGR1cmluZyBmb2xsb3dpbmcgQVBJIGNhbGxzLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0X2NhY2hlSWQ6IDAsXG5cblx0LyoqXG5cdCAqIFJlZ2lzdGVycyB0aGUgZ2l2ZW4gcGx1Z2luKHMpIGlmIG5vdCBhbHJlYWR5IHJlZ2lzdGVyZWQuXG5cdCAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBwbHVnaW5zIHBsdWdpbiBpbnN0YW5jZShzKS5cblx0ICovXG5cdHJlZ2lzdGVyOiBmdW5jdGlvbihwbHVnaW5zKSB7XG5cdFx0dmFyIHAgPSB0aGlzLl9wbHVnaW5zO1xuXHRcdChbXSkuY29uY2F0KHBsdWdpbnMpLmZvckVhY2goZnVuY3Rpb24ocGx1Z2luKSB7XG5cdFx0XHRpZiAocC5pbmRleE9mKHBsdWdpbikgPT09IC0xKSB7XG5cdFx0XHRcdHAucHVzaChwbHVnaW4pO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0dGhpcy5fY2FjaGVJZCsrO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBVbnJlZ2lzdGVycyB0aGUgZ2l2ZW4gcGx1Z2luKHMpIG9ubHkgaWYgcmVnaXN0ZXJlZC5cblx0ICogQHBhcmFtIHtBcnJheXxPYmplY3R9IHBsdWdpbnMgcGx1Z2luIGluc3RhbmNlKHMpLlxuXHQgKi9cblx0dW5yZWdpc3RlcjogZnVuY3Rpb24ocGx1Z2lucykge1xuXHRcdHZhciBwID0gdGhpcy5fcGx1Z2lucztcblx0XHQoW10pLmNvbmNhdChwbHVnaW5zKS5mb3JFYWNoKGZ1bmN0aW9uKHBsdWdpbikge1xuXHRcdFx0dmFyIGlkeCA9IHAuaW5kZXhPZihwbHVnaW4pO1xuXHRcdFx0aWYgKGlkeCAhPT0gLTEpIHtcblx0XHRcdFx0cC5zcGxpY2UoaWR4LCAxKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdHRoaXMuX2NhY2hlSWQrKztcblx0fSxcblxuXHQvKipcblx0ICogUmVtb3ZlIGFsbCByZWdpc3RlcmVkIHBsdWdpbnMuXG5cdCAqIEBzaW5jZSAyLjEuNVxuXHQgKi9cblx0Y2xlYXI6IGZ1bmN0aW9uKCkge1xuXHRcdHRoaXMuX3BsdWdpbnMgPSBbXTtcblx0XHR0aGlzLl9jYWNoZUlkKys7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIG51bWJlciBvZiByZWdpc3RlcmVkIHBsdWdpbnM/XG5cdCAqIEByZXR1cm5zIHtOdW1iZXJ9XG5cdCAqIEBzaW5jZSAyLjEuNVxuXHQgKi9cblx0Y291bnQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLl9wbHVnaW5zLmxlbmd0aDtcblx0fSxcblxuXHQvKipcblx0ICogUmV0dXJucyBhbGwgcmVnaXN0ZXJlZCBwbHVnaW4gaW5zdGFuY2VzLlxuXHQgKiBAcmV0dXJucyB7QXJyYXl9IGFycmF5IG9mIHBsdWdpbiBvYmplY3RzLlxuXHQgKiBAc2luY2UgMi4xLjVcblx0ICovXG5cdGdldEFsbDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuX3BsdWdpbnM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENhbGxzIGVuYWJsZWQgcGx1Z2lucyBmb3IgYGNoYXJ0YCBvbiB0aGUgc3BlY2lmaWVkIGhvb2sgYW5kIHdpdGggdGhlIGdpdmVuIGFyZ3MuXG5cdCAqIFRoaXMgbWV0aG9kIGltbWVkaWF0ZWx5IHJldHVybnMgYXMgc29vbiBhcyBhIHBsdWdpbiBleHBsaWNpdGx5IHJldHVybnMgZmFsc2UuIFRoZVxuXHQgKiByZXR1cm5lZCB2YWx1ZSBjYW4gYmUgdXNlZCwgZm9yIGluc3RhbmNlLCB0byBpbnRlcnJ1cHQgdGhlIGN1cnJlbnQgYWN0aW9uLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gY2hhcnQgLSBUaGUgY2hhcnQgaW5zdGFuY2UgZm9yIHdoaWNoIHBsdWdpbnMgc2hvdWxkIGJlIGNhbGxlZC5cblx0ICogQHBhcmFtIHtTdHJpbmd9IGhvb2sgLSBUaGUgbmFtZSBvZiB0aGUgcGx1Z2luIG1ldGhvZCB0byBjYWxsIChlLmcuICdiZWZvcmVVcGRhdGUnKS5cblx0ICogQHBhcmFtIHtBcnJheX0gW2FyZ3NdIC0gRXh0cmEgYXJndW1lbnRzIHRvIGFwcGx5IHRvIHRoZSBob29rIGNhbGwuXG5cdCAqIEByZXR1cm5zIHtCb29sZWFufSBmYWxzZSBpZiBhbnkgb2YgdGhlIHBsdWdpbnMgcmV0dXJuIGZhbHNlLCBlbHNlIHJldHVybnMgdHJ1ZS5cblx0ICovXG5cdG5vdGlmeTogZnVuY3Rpb24oY2hhcnQsIGhvb2ssIGFyZ3MpIHtcblx0XHR2YXIgZGVzY3JpcHRvcnMgPSB0aGlzLmRlc2NyaXB0b3JzKGNoYXJ0KTtcblx0XHR2YXIgaWxlbiA9IGRlc2NyaXB0b3JzLmxlbmd0aDtcblx0XHR2YXIgaSwgZGVzY3JpcHRvciwgcGx1Z2luLCBwYXJhbXMsIG1ldGhvZDtcblxuXHRcdGZvciAoaSA9IDA7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yc1tpXTtcblx0XHRcdHBsdWdpbiA9IGRlc2NyaXB0b3IucGx1Z2luO1xuXHRcdFx0bWV0aG9kID0gcGx1Z2luW2hvb2tdO1xuXHRcdFx0aWYgKHR5cGVvZiBtZXRob2QgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0cGFyYW1zID0gW2NoYXJ0XS5jb25jYXQoYXJncyB8fCBbXSk7XG5cdFx0XHRcdHBhcmFtcy5wdXNoKGRlc2NyaXB0b3Iub3B0aW9ucyk7XG5cdFx0XHRcdGlmIChtZXRob2QuYXBwbHkocGx1Z2luLCBwYXJhbXMpID09PSBmYWxzZSkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0cnVlO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGRlc2NyaXB0b3JzIG9mIGVuYWJsZWQgcGx1Z2lucyBmb3IgdGhlIGdpdmVuIGNoYXJ0LlxuXHQgKiBAcmV0dXJucyB7QXJyYXl9IFt7IHBsdWdpbiwgb3B0aW9ucyB9XVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0ZGVzY3JpcHRvcnM6IGZ1bmN0aW9uKGNoYXJ0KSB7XG5cdFx0dmFyIGNhY2hlID0gY2hhcnQuJHBsdWdpbnMgfHwgKGNoYXJ0LiRwbHVnaW5zID0ge30pO1xuXHRcdGlmIChjYWNoZS5pZCA9PT0gdGhpcy5fY2FjaGVJZCkge1xuXHRcdFx0cmV0dXJuIGNhY2hlLmRlc2NyaXB0b3JzO1xuXHRcdH1cblxuXHRcdHZhciBwbHVnaW5zID0gW107XG5cdFx0dmFyIGRlc2NyaXB0b3JzID0gW107XG5cdFx0dmFyIGNvbmZpZyA9IChjaGFydCAmJiBjaGFydC5jb25maWcpIHx8IHt9O1xuXHRcdHZhciBvcHRpb25zID0gKGNvbmZpZy5vcHRpb25zICYmIGNvbmZpZy5vcHRpb25zLnBsdWdpbnMpIHx8IHt9O1xuXG5cdFx0dGhpcy5fcGx1Z2lucy5jb25jYXQoY29uZmlnLnBsdWdpbnMgfHwgW10pLmZvckVhY2goZnVuY3Rpb24ocGx1Z2luKSB7XG5cdFx0XHR2YXIgaWR4ID0gcGx1Z2lucy5pbmRleE9mKHBsdWdpbik7XG5cdFx0XHRpZiAoaWR4ICE9PSAtMSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHZhciBpZCA9IHBsdWdpbi5pZDtcblx0XHRcdHZhciBvcHRzID0gb3B0aW9uc1tpZF07XG5cdFx0XHRpZiAob3B0cyA9PT0gZmFsc2UpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAob3B0cyA9PT0gdHJ1ZSkge1xuXHRcdFx0XHRvcHRzID0gaGVscGVycy5jbG9uZShkZWZhdWx0cy5nbG9iYWwucGx1Z2luc1tpZF0pO1xuXHRcdFx0fVxuXG5cdFx0XHRwbHVnaW5zLnB1c2gocGx1Z2luKTtcblx0XHRcdGRlc2NyaXB0b3JzLnB1c2goe1xuXHRcdFx0XHRwbHVnaW46IHBsdWdpbixcblx0XHRcdFx0b3B0aW9uczogb3B0cyB8fCB7fVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHRjYWNoZS5kZXNjcmlwdG9ycyA9IGRlc2NyaXB0b3JzO1xuXHRcdGNhY2hlLmlkID0gdGhpcy5fY2FjaGVJZDtcblx0XHRyZXR1cm4gZGVzY3JpcHRvcnM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEludmFsaWRhdGVzIGNhY2hlIGZvciB0aGUgZ2l2ZW4gY2hhcnQ6IGRlc2NyaXB0b3JzIGhvbGQgYSByZWZlcmVuY2Ugb24gcGx1Z2luIG9wdGlvbixcblx0ICogYnV0IGluIHNvbWUgY2FzZXMsIHRoaXMgcmVmZXJlbmNlIGNhbiBiZSBjaGFuZ2VkIGJ5IHRoZSB1c2VyIHdoZW4gdXBkYXRpbmcgb3B0aW9ucy5cblx0ICogaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzUxMTEjaXNzdWVjb21tZW50LTM1NTkzNDE2N1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0X2ludmFsaWRhdGU6IGZ1bmN0aW9uKGNoYXJ0KSB7XG5cdFx0ZGVsZXRlIGNoYXJ0LiRwbHVnaW5zO1xuXHR9XG59O1xuXG4vKipcbiAqIFBsdWdpbiBleHRlbnNpb24gaG9va3MuXG4gKiBAaW50ZXJmYWNlIElQbHVnaW5cbiAqIEBzaW5jZSAyLjEuMFxuICovXG4vKipcbiAqIEBtZXRob2QgSVBsdWdpbiNiZWZvcmVJbml0XG4gKiBAZGVzYyBDYWxsZWQgYmVmb3JlIGluaXRpYWxpemluZyBgY2hhcnRgLlxuICogQHBhcmFtIHtDaGFydC5Db250cm9sbGVyfSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIHBsdWdpbiBvcHRpb25zLlxuICovXG4vKipcbiAqIEBtZXRob2QgSVBsdWdpbiNhZnRlckluaXRcbiAqIEBkZXNjIENhbGxlZCBhZnRlciBgY2hhcnRgIGhhcyBiZWVuIGluaXRpYWxpemVkIGFuZCBiZWZvcmUgdGhlIGZpcnN0IHVwZGF0ZS5cbiAqIEBwYXJhbSB7Q2hhcnQuQ29udHJvbGxlcn0gY2hhcnQgLSBUaGUgY2hhcnQgaW5zdGFuY2UuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBwbHVnaW4gb3B0aW9ucy5cbiAqL1xuLyoqXG4gKiBAbWV0aG9kIElQbHVnaW4jYmVmb3JlVXBkYXRlXG4gKiBAZGVzYyBDYWxsZWQgYmVmb3JlIHVwZGF0aW5nIGBjaGFydGAuIElmIGFueSBwbHVnaW4gcmV0dXJucyBgZmFsc2VgLCB0aGUgdXBkYXRlXG4gKiBpcyBjYW5jZWxsZWQgKGFuZCB0aHVzIHN1YnNlcXVlbnQgcmVuZGVyKHMpKSB1bnRpbCBhbm90aGVyIGB1cGRhdGVgIGlzIHRyaWdnZXJlZC5cbiAqIEBwYXJhbSB7Q2hhcnQuQ29udHJvbGxlcn0gY2hhcnQgLSBUaGUgY2hhcnQgaW5zdGFuY2UuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBwbHVnaW4gb3B0aW9ucy5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBgZmFsc2VgIHRvIGNhbmNlbCB0aGUgY2hhcnQgdXBkYXRlLlxuICovXG4vKipcbiAqIEBtZXRob2QgSVBsdWdpbiNhZnRlclVwZGF0ZVxuICogQGRlc2MgQ2FsbGVkIGFmdGVyIGBjaGFydGAgaGFzIGJlZW4gdXBkYXRlZCBhbmQgYmVmb3JlIHJlbmRlcmluZy4gTm90ZSB0aGF0IHRoaXNcbiAqIGhvb2sgd2lsbCBub3QgYmUgY2FsbGVkIGlmIHRoZSBjaGFydCB1cGRhdGUgaGFzIGJlZW4gcHJldmlvdXNseSBjYW5jZWxsZWQuXG4gKiBAcGFyYW0ge0NoYXJ0LkNvbnRyb2xsZXJ9IGNoYXJ0IC0gVGhlIGNoYXJ0IGluc3RhbmNlLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgcGx1Z2luIG9wdGlvbnMuXG4gKi9cbi8qKlxuICogQG1ldGhvZCBJUGx1Z2luI2JlZm9yZURhdGFzZXRzVXBkYXRlXG4gKiBAZGVzYyBDYWxsZWQgYmVmb3JlIHVwZGF0aW5nIHRoZSBgY2hhcnRgIGRhdGFzZXRzLiBJZiBhbnkgcGx1Z2luIHJldHVybnMgYGZhbHNlYCxcbiAqIHRoZSBkYXRhc2V0cyB1cGRhdGUgaXMgY2FuY2VsbGVkIHVudGlsIGFub3RoZXIgYHVwZGF0ZWAgaXMgdHJpZ2dlcmVkLlxuICogQHBhcmFtIHtDaGFydC5Db250cm9sbGVyfSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIHBsdWdpbiBvcHRpb25zLlxuICogQHJldHVybnMge0Jvb2xlYW59IGZhbHNlIHRvIGNhbmNlbCB0aGUgZGF0YXNldHMgdXBkYXRlLlxuICogQHNpbmNlIHZlcnNpb24gMi4xLjVcbiovXG4vKipcbiAqIEBtZXRob2QgSVBsdWdpbiNhZnRlckRhdGFzZXRzVXBkYXRlXG4gKiBAZGVzYyBDYWxsZWQgYWZ0ZXIgdGhlIGBjaGFydGAgZGF0YXNldHMgaGF2ZSBiZWVuIHVwZGF0ZWQuIE5vdGUgdGhhdCB0aGlzIGhvb2tcbiAqIHdpbGwgbm90IGJlIGNhbGxlZCBpZiB0aGUgZGF0YXNldHMgdXBkYXRlIGhhcyBiZWVuIHByZXZpb3VzbHkgY2FuY2VsbGVkLlxuICogQHBhcmFtIHtDaGFydC5Db250cm9sbGVyfSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIHBsdWdpbiBvcHRpb25zLlxuICogQHNpbmNlIHZlcnNpb24gMi4xLjVcbiAqL1xuLyoqXG4gKiBAbWV0aG9kIElQbHVnaW4jYmVmb3JlRGF0YXNldFVwZGF0ZVxuICogQGRlc2MgQ2FsbGVkIGJlZm9yZSB1cGRhdGluZyB0aGUgYGNoYXJ0YCBkYXRhc2V0IGF0IHRoZSBnaXZlbiBgYXJncy5pbmRleGAuIElmIGFueSBwbHVnaW5cbiAqIHJldHVybnMgYGZhbHNlYCwgdGhlIGRhdGFzZXRzIHVwZGF0ZSBpcyBjYW5jZWxsZWQgdW50aWwgYW5vdGhlciBgdXBkYXRlYCBpcyB0cmlnZ2VyZWQuXG4gKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBhcmdzIC0gVGhlIGNhbGwgYXJndW1lbnRzLlxuICogQHBhcmFtIHtOdW1iZXJ9IGFyZ3MuaW5kZXggLSBUaGUgZGF0YXNldCBpbmRleC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBhcmdzLm1ldGEgLSBUaGUgZGF0YXNldCBtZXRhZGF0YS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIHBsdWdpbiBvcHRpb25zLlxuICogQHJldHVybnMge0Jvb2xlYW59IGBmYWxzZWAgdG8gY2FuY2VsIHRoZSBjaGFydCBkYXRhc2V0cyBkcmF3aW5nLlxuICovXG4vKipcbiAqIEBtZXRob2QgSVBsdWdpbiNhZnRlckRhdGFzZXRVcGRhdGVcbiAqIEBkZXNjIENhbGxlZCBhZnRlciB0aGUgYGNoYXJ0YCBkYXRhc2V0cyBhdCB0aGUgZ2l2ZW4gYGFyZ3MuaW5kZXhgIGhhcyBiZWVuIHVwZGF0ZWQuIE5vdGVcbiAqIHRoYXQgdGhpcyBob29rIHdpbGwgbm90IGJlIGNhbGxlZCBpZiB0aGUgZGF0YXNldHMgdXBkYXRlIGhhcyBiZWVuIHByZXZpb3VzbHkgY2FuY2VsbGVkLlxuICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSBUaGUgY2hhcnQgaW5zdGFuY2UuXG4gKiBAcGFyYW0ge09iamVjdH0gYXJncyAtIFRoZSBjYWxsIGFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7TnVtYmVyfSBhcmdzLmluZGV4IC0gVGhlIGRhdGFzZXQgaW5kZXguXG4gKiBAcGFyYW0ge09iamVjdH0gYXJncy5tZXRhIC0gVGhlIGRhdGFzZXQgbWV0YWRhdGEuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBwbHVnaW4gb3B0aW9ucy5cbiAqL1xuLyoqXG4gKiBAbWV0aG9kIElQbHVnaW4jYmVmb3JlTGF5b3V0XG4gKiBAZGVzYyBDYWxsZWQgYmVmb3JlIGxheWluZyBvdXQgYGNoYXJ0YC4gSWYgYW55IHBsdWdpbiByZXR1cm5zIGBmYWxzZWAsXG4gKiB0aGUgbGF5b3V0IHVwZGF0ZSBpcyBjYW5jZWxsZWQgdW50aWwgYW5vdGhlciBgdXBkYXRlYCBpcyB0cmlnZ2VyZWQuXG4gKiBAcGFyYW0ge0NoYXJ0LkNvbnRyb2xsZXJ9IGNoYXJ0IC0gVGhlIGNoYXJ0IGluc3RhbmNlLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgcGx1Z2luIG9wdGlvbnMuXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gYGZhbHNlYCB0byBjYW5jZWwgdGhlIGNoYXJ0IGxheW91dC5cbiAqL1xuLyoqXG4gKiBAbWV0aG9kIElQbHVnaW4jYWZ0ZXJMYXlvdXRcbiAqIEBkZXNjIENhbGxlZCBhZnRlciB0aGUgYGNoYXJ0YCBoYXMgYmVlbiBsYXllZCBvdXQuIE5vdGUgdGhhdCB0aGlzIGhvb2sgd2lsbCBub3RcbiAqIGJlIGNhbGxlZCBpZiB0aGUgbGF5b3V0IHVwZGF0ZSBoYXMgYmVlbiBwcmV2aW91c2x5IGNhbmNlbGxlZC5cbiAqIEBwYXJhbSB7Q2hhcnQuQ29udHJvbGxlcn0gY2hhcnQgLSBUaGUgY2hhcnQgaW5zdGFuY2UuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBwbHVnaW4gb3B0aW9ucy5cbiAqL1xuLyoqXG4gKiBAbWV0aG9kIElQbHVnaW4jYmVmb3JlUmVuZGVyXG4gKiBAZGVzYyBDYWxsZWQgYmVmb3JlIHJlbmRlcmluZyBgY2hhcnRgLiBJZiBhbnkgcGx1Z2luIHJldHVybnMgYGZhbHNlYCxcbiAqIHRoZSByZW5kZXJpbmcgaXMgY2FuY2VsbGVkIHVudGlsIGFub3RoZXIgYHJlbmRlcmAgaXMgdHJpZ2dlcmVkLlxuICogQHBhcmFtIHtDaGFydC5Db250cm9sbGVyfSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIHBsdWdpbiBvcHRpb25zLlxuICogQHJldHVybnMge0Jvb2xlYW59IGBmYWxzZWAgdG8gY2FuY2VsIHRoZSBjaGFydCByZW5kZXJpbmcuXG4gKi9cbi8qKlxuICogQG1ldGhvZCBJUGx1Z2luI2FmdGVyUmVuZGVyXG4gKiBAZGVzYyBDYWxsZWQgYWZ0ZXIgdGhlIGBjaGFydGAgaGFzIGJlZW4gZnVsbHkgcmVuZGVyZWQgKGFuZCBhbmltYXRpb24gY29tcGxldGVkKS4gTm90ZVxuICogdGhhdCB0aGlzIGhvb2sgd2lsbCBub3QgYmUgY2FsbGVkIGlmIHRoZSByZW5kZXJpbmcgaGFzIGJlZW4gcHJldmlvdXNseSBjYW5jZWxsZWQuXG4gKiBAcGFyYW0ge0NoYXJ0LkNvbnRyb2xsZXJ9IGNoYXJ0IC0gVGhlIGNoYXJ0IGluc3RhbmNlLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgcGx1Z2luIG9wdGlvbnMuXG4gKi9cbi8qKlxuICogQG1ldGhvZCBJUGx1Z2luI2JlZm9yZURyYXdcbiAqIEBkZXNjIENhbGxlZCBiZWZvcmUgZHJhd2luZyBgY2hhcnRgIGF0IGV2ZXJ5IGFuaW1hdGlvbiBmcmFtZSBzcGVjaWZpZWQgYnkgdGhlIGdpdmVuXG4gKiBlYXNpbmcgdmFsdWUuIElmIGFueSBwbHVnaW4gcmV0dXJucyBgZmFsc2VgLCB0aGUgZnJhbWUgZHJhd2luZyBpcyBjYW5jZWxsZWQgdW50aWxcbiAqIGFub3RoZXIgYHJlbmRlcmAgaXMgdHJpZ2dlcmVkLlxuICogQHBhcmFtIHtDaGFydC5Db250cm9sbGVyfSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7TnVtYmVyfSBlYXNpbmdWYWx1ZSAtIFRoZSBjdXJyZW50IGFuaW1hdGlvbiB2YWx1ZSwgYmV0d2VlbiAwLjAgYW5kIDEuMC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIHBsdWdpbiBvcHRpb25zLlxuICogQHJldHVybnMge0Jvb2xlYW59IGBmYWxzZWAgdG8gY2FuY2VsIHRoZSBjaGFydCBkcmF3aW5nLlxuICovXG4vKipcbiAqIEBtZXRob2QgSVBsdWdpbiNhZnRlckRyYXdcbiAqIEBkZXNjIENhbGxlZCBhZnRlciB0aGUgYGNoYXJ0YCBoYXMgYmVlbiBkcmF3biBmb3IgdGhlIHNwZWNpZmljIGVhc2luZyB2YWx1ZS4gTm90ZVxuICogdGhhdCB0aGlzIGhvb2sgd2lsbCBub3QgYmUgY2FsbGVkIGlmIHRoZSBkcmF3aW5nIGhhcyBiZWVuIHByZXZpb3VzbHkgY2FuY2VsbGVkLlxuICogQHBhcmFtIHtDaGFydC5Db250cm9sbGVyfSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7TnVtYmVyfSBlYXNpbmdWYWx1ZSAtIFRoZSBjdXJyZW50IGFuaW1hdGlvbiB2YWx1ZSwgYmV0d2VlbiAwLjAgYW5kIDEuMC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIHBsdWdpbiBvcHRpb25zLlxuICovXG4vKipcbiAqIEBtZXRob2QgSVBsdWdpbiNiZWZvcmVEYXRhc2V0c0RyYXdcbiAqIEBkZXNjIENhbGxlZCBiZWZvcmUgZHJhd2luZyB0aGUgYGNoYXJ0YCBkYXRhc2V0cy4gSWYgYW55IHBsdWdpbiByZXR1cm5zIGBmYWxzZWAsXG4gKiB0aGUgZGF0YXNldHMgZHJhd2luZyBpcyBjYW5jZWxsZWQgdW50aWwgYW5vdGhlciBgcmVuZGVyYCBpcyB0cmlnZ2VyZWQuXG4gKiBAcGFyYW0ge0NoYXJ0LkNvbnRyb2xsZXJ9IGNoYXJ0IC0gVGhlIGNoYXJ0IGluc3RhbmNlLlxuICogQHBhcmFtIHtOdW1iZXJ9IGVhc2luZ1ZhbHVlIC0gVGhlIGN1cnJlbnQgYW5pbWF0aW9uIHZhbHVlLCBiZXR3ZWVuIDAuMCBhbmQgMS4wLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgcGx1Z2luIG9wdGlvbnMuXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gYGZhbHNlYCB0byBjYW5jZWwgdGhlIGNoYXJ0IGRhdGFzZXRzIGRyYXdpbmcuXG4gKi9cbi8qKlxuICogQG1ldGhvZCBJUGx1Z2luI2FmdGVyRGF0YXNldHNEcmF3XG4gKiBAZGVzYyBDYWxsZWQgYWZ0ZXIgdGhlIGBjaGFydGAgZGF0YXNldHMgaGF2ZSBiZWVuIGRyYXduLiBOb3RlIHRoYXQgdGhpcyBob29rXG4gKiB3aWxsIG5vdCBiZSBjYWxsZWQgaWYgdGhlIGRhdGFzZXRzIGRyYXdpbmcgaGFzIGJlZW4gcHJldmlvdXNseSBjYW5jZWxsZWQuXG4gKiBAcGFyYW0ge0NoYXJ0LkNvbnRyb2xsZXJ9IGNoYXJ0IC0gVGhlIGNoYXJ0IGluc3RhbmNlLlxuICogQHBhcmFtIHtOdW1iZXJ9IGVhc2luZ1ZhbHVlIC0gVGhlIGN1cnJlbnQgYW5pbWF0aW9uIHZhbHVlLCBiZXR3ZWVuIDAuMCBhbmQgMS4wLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgcGx1Z2luIG9wdGlvbnMuXG4gKi9cbi8qKlxuICogQG1ldGhvZCBJUGx1Z2luI2JlZm9yZURhdGFzZXREcmF3XG4gKiBAZGVzYyBDYWxsZWQgYmVmb3JlIGRyYXdpbmcgdGhlIGBjaGFydGAgZGF0YXNldCBhdCB0aGUgZ2l2ZW4gYGFyZ3MuaW5kZXhgIChkYXRhc2V0c1xuICogYXJlIGRyYXduIGluIHRoZSByZXZlcnNlIG9yZGVyKS4gSWYgYW55IHBsdWdpbiByZXR1cm5zIGBmYWxzZWAsIHRoZSBkYXRhc2V0cyBkcmF3aW5nXG4gKiBpcyBjYW5jZWxsZWQgdW50aWwgYW5vdGhlciBgcmVuZGVyYCBpcyB0cmlnZ2VyZWQuXG4gKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBhcmdzIC0gVGhlIGNhbGwgYXJndW1lbnRzLlxuICogQHBhcmFtIHtOdW1iZXJ9IGFyZ3MuaW5kZXggLSBUaGUgZGF0YXNldCBpbmRleC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBhcmdzLm1ldGEgLSBUaGUgZGF0YXNldCBtZXRhZGF0YS5cbiAqIEBwYXJhbSB7TnVtYmVyfSBhcmdzLmVhc2luZ1ZhbHVlIC0gVGhlIGN1cnJlbnQgYW5pbWF0aW9uIHZhbHVlLCBiZXR3ZWVuIDAuMCBhbmQgMS4wLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgcGx1Z2luIG9wdGlvbnMuXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gYGZhbHNlYCB0byBjYW5jZWwgdGhlIGNoYXJ0IGRhdGFzZXRzIGRyYXdpbmcuXG4gKi9cbi8qKlxuICogQG1ldGhvZCBJUGx1Z2luI2FmdGVyRGF0YXNldERyYXdcbiAqIEBkZXNjIENhbGxlZCBhZnRlciB0aGUgYGNoYXJ0YCBkYXRhc2V0cyBhdCB0aGUgZ2l2ZW4gYGFyZ3MuaW5kZXhgIGhhdmUgYmVlbiBkcmF3blxuICogKGRhdGFzZXRzIGFyZSBkcmF3biBpbiB0aGUgcmV2ZXJzZSBvcmRlcikuIE5vdGUgdGhhdCB0aGlzIGhvb2sgd2lsbCBub3QgYmUgY2FsbGVkXG4gKiBpZiB0aGUgZGF0YXNldHMgZHJhd2luZyBoYXMgYmVlbiBwcmV2aW91c2x5IGNhbmNlbGxlZC5cbiAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gVGhlIGNoYXJ0IGluc3RhbmNlLlxuICogQHBhcmFtIHtPYmplY3R9IGFyZ3MgLSBUaGUgY2FsbCBhcmd1bWVudHMuXG4gKiBAcGFyYW0ge051bWJlcn0gYXJncy5pbmRleCAtIFRoZSBkYXRhc2V0IGluZGV4LlxuICogQHBhcmFtIHtPYmplY3R9IGFyZ3MubWV0YSAtIFRoZSBkYXRhc2V0IG1ldGFkYXRhLlxuICogQHBhcmFtIHtOdW1iZXJ9IGFyZ3MuZWFzaW5nVmFsdWUgLSBUaGUgY3VycmVudCBhbmltYXRpb24gdmFsdWUsIGJldHdlZW4gMC4wIGFuZCAxLjAuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBwbHVnaW4gb3B0aW9ucy5cbiAqL1xuLyoqXG4gKiBAbWV0aG9kIElQbHVnaW4jYmVmb3JlVG9vbHRpcERyYXdcbiAqIEBkZXNjIENhbGxlZCBiZWZvcmUgZHJhd2luZyB0aGUgYHRvb2x0aXBgLiBJZiBhbnkgcGx1Z2luIHJldHVybnMgYGZhbHNlYCxcbiAqIHRoZSB0b29sdGlwIGRyYXdpbmcgaXMgY2FuY2VsbGVkIHVudGlsIGFub3RoZXIgYHJlbmRlcmAgaXMgdHJpZ2dlcmVkLlxuICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSBUaGUgY2hhcnQgaW5zdGFuY2UuXG4gKiBAcGFyYW0ge09iamVjdH0gYXJncyAtIFRoZSBjYWxsIGFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBhcmdzLnRvb2x0aXAgLSBUaGUgdG9vbHRpcC5cbiAqIEBwYXJhbSB7TnVtYmVyfSBhcmdzLmVhc2luZ1ZhbHVlIC0gVGhlIGN1cnJlbnQgYW5pbWF0aW9uIHZhbHVlLCBiZXR3ZWVuIDAuMCBhbmQgMS4wLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgcGx1Z2luIG9wdGlvbnMuXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gYGZhbHNlYCB0byBjYW5jZWwgdGhlIGNoYXJ0IHRvb2x0aXAgZHJhd2luZy5cbiAqL1xuLyoqXG4gKiBAbWV0aG9kIElQbHVnaW4jYWZ0ZXJUb29sdGlwRHJhd1xuICogQGRlc2MgQ2FsbGVkIGFmdGVyIGRyYXdpbmcgdGhlIGB0b29sdGlwYC4gTm90ZSB0aGF0IHRoaXMgaG9vayB3aWxsIG5vdFxuICogYmUgY2FsbGVkIGlmIHRoZSB0b29sdGlwIGRyYXdpbmcgaGFzIGJlZW4gcHJldmlvdXNseSBjYW5jZWxsZWQuXG4gKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBhcmdzIC0gVGhlIGNhbGwgYXJndW1lbnRzLlxuICogQHBhcmFtIHtPYmplY3R9IGFyZ3MudG9vbHRpcCAtIFRoZSB0b29sdGlwLlxuICogQHBhcmFtIHtOdW1iZXJ9IGFyZ3MuZWFzaW5nVmFsdWUgLSBUaGUgY3VycmVudCBhbmltYXRpb24gdmFsdWUsIGJldHdlZW4gMC4wIGFuZCAxLjAuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBwbHVnaW4gb3B0aW9ucy5cbiAqL1xuLyoqXG4gKiBAbWV0aG9kIElQbHVnaW4jYmVmb3JlRXZlbnRcbiAqIEBkZXNjIENhbGxlZCBiZWZvcmUgcHJvY2Vzc2luZyB0aGUgc3BlY2lmaWVkIGBldmVudGAuIElmIGFueSBwbHVnaW4gcmV0dXJucyBgZmFsc2VgLFxuICogdGhlIGV2ZW50IHdpbGwgYmUgZGlzY2FyZGVkLlxuICogQHBhcmFtIHtDaGFydC5Db250cm9sbGVyfSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7SUV2ZW50fSBldmVudCAtIFRoZSBldmVudCBvYmplY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBwbHVnaW4gb3B0aW9ucy5cbiAqL1xuLyoqXG4gKiBAbWV0aG9kIElQbHVnaW4jYWZ0ZXJFdmVudFxuICogQGRlc2MgQ2FsbGVkIGFmdGVyIHRoZSBgZXZlbnRgIGhhcyBiZWVuIGNvbnN1bWVkLiBOb3RlIHRoYXQgdGhpcyBob29rXG4gKiB3aWxsIG5vdCBiZSBjYWxsZWQgaWYgdGhlIGBldmVudGAgaGFzIGJlZW4gcHJldmlvdXNseSBkaXNjYXJkZWQuXG4gKiBAcGFyYW0ge0NoYXJ0LkNvbnRyb2xsZXJ9IGNoYXJ0IC0gVGhlIGNoYXJ0IGluc3RhbmNlLlxuICogQHBhcmFtIHtJRXZlbnR9IGV2ZW50IC0gVGhlIGV2ZW50IG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIHBsdWdpbiBvcHRpb25zLlxuICovXG4vKipcbiAqIEBtZXRob2QgSVBsdWdpbiNyZXNpemVcbiAqIEBkZXNjIENhbGxlZCBhZnRlciB0aGUgY2hhcnQgYXMgYmVlbiByZXNpemVkLlxuICogQHBhcmFtIHtDaGFydC5Db250cm9sbGVyfSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7TnVtYmVyfSBzaXplIC0gVGhlIG5ldyBjYW52YXMgZGlzcGxheSBzaXplIChlcS4gY2FudmFzLnN0eWxlIHdpZHRoICYgaGVpZ2h0KS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIHBsdWdpbiBvcHRpb25zLlxuICovXG4vKipcbiAqIEBtZXRob2QgSVBsdWdpbiNkZXN0cm95XG4gKiBAZGVzYyBDYWxsZWQgYWZ0ZXIgdGhlIGNoYXJ0IGFzIGJlZW4gZGVzdHJveWVkLlxuICogQHBhcmFtIHtDaGFydC5Db250cm9sbGVyfSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIHBsdWdpbiBvcHRpb25zLlxuICovXG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///cb9d\n")},cec9:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar Element = __webpack_require__(/*! ../core/core.element */ \"4a45\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\ndefaults._set('global', {\n\telements: {\n\t\tarc: {\n\t\t\tbackgroundColor: defaults.global.defaultColor,\n\t\t\tborderColor: '#fff',\n\t\t\tborderWidth: 2\n\t\t}\n\t}\n});\n\nmodule.exports = Element.extend({\n\tinLabelRange: function(mouseX) {\n\t\tvar vm = this._view;\n\n\t\tif (vm) {\n\t\t\treturn (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));\n\t\t}\n\t\treturn false;\n\t},\n\n\tinRange: function(chartX, chartY) {\n\t\tvar vm = this._view;\n\n\t\tif (vm) {\n\t\t\tvar pointRelativePosition = helpers.getAngleFromPoint(vm, {x: chartX, y: chartY});\n\t\t\tvar\tangle = pointRelativePosition.angle;\n\t\t\tvar distance = pointRelativePosition.distance;\n\n\t\t\t// Sanitise angle range\n\t\t\tvar startAngle = vm.startAngle;\n\t\t\tvar endAngle = vm.endAngle;\n\t\t\twhile (endAngle < startAngle) {\n\t\t\t\tendAngle += 2.0 * Math.PI;\n\t\t\t}\n\t\t\twhile (angle > endAngle) {\n\t\t\t\tangle -= 2.0 * Math.PI;\n\t\t\t}\n\t\t\twhile (angle < startAngle) {\n\t\t\t\tangle += 2.0 * Math.PI;\n\t\t\t}\n\n\t\t\t// Check if within the range of the open/close angle\n\t\t\tvar betweenAngles = (angle >= startAngle && angle <= endAngle);\n\t\t\tvar withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);\n\n\t\t\treturn (betweenAngles && withinRadius);\n\t\t}\n\t\treturn false;\n\t},\n\n\tgetCenterPoint: function() {\n\t\tvar vm = this._view;\n\t\tvar halfAngle = (vm.startAngle + vm.endAngle) / 2;\n\t\tvar halfRadius = (vm.innerRadius + vm.outerRadius) / 2;\n\t\treturn {\n\t\t\tx: vm.x + Math.cos(halfAngle) * halfRadius,\n\t\t\ty: vm.y + Math.sin(halfAngle) * halfRadius\n\t\t};\n\t},\n\n\tgetArea: function() {\n\t\tvar vm = this._view;\n\t\treturn Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));\n\t},\n\n\ttooltipPosition: function() {\n\t\tvar vm = this._view;\n\t\tvar centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2);\n\t\tvar rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;\n\n\t\treturn {\n\t\t\tx: vm.x + (Math.cos(centreAngle) * rangeFromCentre),\n\t\t\ty: vm.y + (Math.sin(centreAngle) * rangeFromCentre)\n\t\t};\n\t},\n\n\tdraw: function() {\n\t\tvar ctx = this._chart.ctx;\n\t\tvar vm = this._view;\n\t\tvar sA = vm.startAngle;\n\t\tvar eA = vm.endAngle;\n\n\t\tctx.beginPath();\n\n\t\tctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);\n\t\tctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);\n\n\t\tctx.closePath();\n\t\tctx.strokeStyle = vm.borderColor;\n\t\tctx.lineWidth = vm.borderWidth;\n\n\t\tctx.fillStyle = vm.backgroundColor;\n\n\t\tctx.fill();\n\t\tctx.lineJoin = 'bevel';\n\n\t\tif (vm.borderWidth) {\n\t\t\tctx.stroke();\n\t\t}\n\t}\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VjOS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvZWxlbWVudHMvZWxlbWVudC5hcmMuanM/NWZjMCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5kZWZhdWx0cycpO1xudmFyIEVsZW1lbnQgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuZWxlbWVudCcpO1xudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2luZGV4Jyk7XG5cbmRlZmF1bHRzLl9zZXQoJ2dsb2JhbCcsIHtcblx0ZWxlbWVudHM6IHtcblx0XHRhcmM6IHtcblx0XHRcdGJhY2tncm91bmRDb2xvcjogZGVmYXVsdHMuZ2xvYmFsLmRlZmF1bHRDb2xvcixcblx0XHRcdGJvcmRlckNvbG9yOiAnI2ZmZicsXG5cdFx0XHRib3JkZXJXaWR0aDogMlxuXHRcdH1cblx0fVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gRWxlbWVudC5leHRlbmQoe1xuXHRpbkxhYmVsUmFuZ2U6IGZ1bmN0aW9uKG1vdXNlWCkge1xuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XG5cblx0XHRpZiAodm0pIHtcblx0XHRcdHJldHVybiAoTWF0aC5wb3cobW91c2VYIC0gdm0ueCwgMikgPCBNYXRoLnBvdyh2bS5yYWRpdXMgKyB2bS5ob3ZlclJhZGl1cywgMikpO1xuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH0sXG5cblx0aW5SYW5nZTogZnVuY3Rpb24oY2hhcnRYLCBjaGFydFkpIHtcblx0XHR2YXIgdm0gPSB0aGlzLl92aWV3O1xuXG5cdFx0aWYgKHZtKSB7XG5cdFx0XHR2YXIgcG9pbnRSZWxhdGl2ZVBvc2l0aW9uID0gaGVscGVycy5nZXRBbmdsZUZyb21Qb2ludCh2bSwge3g6IGNoYXJ0WCwgeTogY2hhcnRZfSk7XG5cdFx0XHR2YXJcdGFuZ2xlID0gcG9pbnRSZWxhdGl2ZVBvc2l0aW9uLmFuZ2xlO1xuXHRcdFx0dmFyIGRpc3RhbmNlID0gcG9pbnRSZWxhdGl2ZVBvc2l0aW9uLmRpc3RhbmNlO1xuXG5cdFx0XHQvLyBTYW5pdGlzZSBhbmdsZSByYW5nZVxuXHRcdFx0dmFyIHN0YXJ0QW5nbGUgPSB2bS5zdGFydEFuZ2xlO1xuXHRcdFx0dmFyIGVuZEFuZ2xlID0gdm0uZW5kQW5nbGU7XG5cdFx0XHR3aGlsZSAoZW5kQW5nbGUgPCBzdGFydEFuZ2xlKSB7XG5cdFx0XHRcdGVuZEFuZ2xlICs9IDIuMCAqIE1hdGguUEk7XG5cdFx0XHR9XG5cdFx0XHR3aGlsZSAoYW5nbGUgPiBlbmRBbmdsZSkge1xuXHRcdFx0XHRhbmdsZSAtPSAyLjAgKiBNYXRoLlBJO1xuXHRcdFx0fVxuXHRcdFx0d2hpbGUgKGFuZ2xlIDwgc3RhcnRBbmdsZSkge1xuXHRcdFx0XHRhbmdsZSArPSAyLjAgKiBNYXRoLlBJO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDaGVjayBpZiB3aXRoaW4gdGhlIHJhbmdlIG9mIHRoZSBvcGVuL2Nsb3NlIGFuZ2xlXG5cdFx0XHR2YXIgYmV0d2VlbkFuZ2xlcyA9IChhbmdsZSA+PSBzdGFydEFuZ2xlICYmIGFuZ2xlIDw9IGVuZEFuZ2xlKTtcblx0XHRcdHZhciB3aXRoaW5SYWRpdXMgPSAoZGlzdGFuY2UgPj0gdm0uaW5uZXJSYWRpdXMgJiYgZGlzdGFuY2UgPD0gdm0ub3V0ZXJSYWRpdXMpO1xuXG5cdFx0XHRyZXR1cm4gKGJldHdlZW5BbmdsZXMgJiYgd2l0aGluUmFkaXVzKTtcblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9LFxuXG5cdGdldENlbnRlclBvaW50OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgdm0gPSB0aGlzLl92aWV3O1xuXHRcdHZhciBoYWxmQW5nbGUgPSAodm0uc3RhcnRBbmdsZSArIHZtLmVuZEFuZ2xlKSAvIDI7XG5cdFx0dmFyIGhhbGZSYWRpdXMgPSAodm0uaW5uZXJSYWRpdXMgKyB2bS5vdXRlclJhZGl1cykgLyAyO1xuXHRcdHJldHVybiB7XG5cdFx0XHR4OiB2bS54ICsgTWF0aC5jb3MoaGFsZkFuZ2xlKSAqIGhhbGZSYWRpdXMsXG5cdFx0XHR5OiB2bS55ICsgTWF0aC5zaW4oaGFsZkFuZ2xlKSAqIGhhbGZSYWRpdXNcblx0XHR9O1xuXHR9LFxuXG5cdGdldEFyZWE6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XG5cdFx0cmV0dXJuIE1hdGguUEkgKiAoKHZtLmVuZEFuZ2xlIC0gdm0uc3RhcnRBbmdsZSkgLyAoMiAqIE1hdGguUEkpKSAqIChNYXRoLnBvdyh2bS5vdXRlclJhZGl1cywgMikgLSBNYXRoLnBvdyh2bS5pbm5lclJhZGl1cywgMikpO1xuXHR9LFxuXG5cdHRvb2x0aXBQb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIHZtID0gdGhpcy5fdmlldztcblx0XHR2YXIgY2VudHJlQW5nbGUgPSB2bS5zdGFydEFuZ2xlICsgKCh2bS5lbmRBbmdsZSAtIHZtLnN0YXJ0QW5nbGUpIC8gMik7XG5cdFx0dmFyIHJhbmdlRnJvbUNlbnRyZSA9ICh2bS5vdXRlclJhZGl1cyAtIHZtLmlubmVyUmFkaXVzKSAvIDIgKyB2bS5pbm5lclJhZGl1cztcblxuXHRcdHJldHVybiB7XG5cdFx0XHR4OiB2bS54ICsgKE1hdGguY29zKGNlbnRyZUFuZ2xlKSAqIHJhbmdlRnJvbUNlbnRyZSksXG5cdFx0XHR5OiB2bS55ICsgKE1hdGguc2luKGNlbnRyZUFuZ2xlKSAqIHJhbmdlRnJvbUNlbnRyZSlcblx0XHR9O1xuXHR9LFxuXG5cdGRyYXc6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBjdHggPSB0aGlzLl9jaGFydC5jdHg7XG5cdFx0dmFyIHZtID0gdGhpcy5fdmlldztcblx0XHR2YXIgc0EgPSB2bS5zdGFydEFuZ2xlO1xuXHRcdHZhciBlQSA9IHZtLmVuZEFuZ2xlO1xuXG5cdFx0Y3R4LmJlZ2luUGF0aCgpO1xuXG5cdFx0Y3R4LmFyYyh2bS54LCB2bS55LCB2bS5vdXRlclJhZGl1cywgc0EsIGVBKTtcblx0XHRjdHguYXJjKHZtLngsIHZtLnksIHZtLmlubmVyUmFkaXVzLCBlQSwgc0EsIHRydWUpO1xuXG5cdFx0Y3R4LmNsb3NlUGF0aCgpO1xuXHRcdGN0eC5zdHJva2VTdHlsZSA9IHZtLmJvcmRlckNvbG9yO1xuXHRcdGN0eC5saW5lV2lkdGggPSB2bS5ib3JkZXJXaWR0aDtcblxuXHRcdGN0eC5maWxsU3R5bGUgPSB2bS5iYWNrZ3JvdW5kQ29sb3I7XG5cblx0XHRjdHguZmlsbCgpO1xuXHRcdGN0eC5saW5lSm9pbiA9ICdiZXZlbCc7XG5cblx0XHRpZiAodm0uYm9yZGVyV2lkdGgpIHtcblx0XHRcdGN0eC5zdHJva2UoKTtcblx0XHR9XG5cdH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///cec9\n")},d1b4:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ./core.defaults */ \"beaa\");\nvar Element = __webpack_require__(/*! ./core.element */ \"4a45\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\nvar Ticks = __webpack_require__(/*! ./core.ticks */ \"1220\");\n\ndefaults._set('scale', {\n\tdisplay: true,\n\tposition: 'left',\n\toffset: false,\n\n\t// grid line settings\n\tgridLines: {\n\t\tdisplay: true,\n\t\tcolor: 'rgba(0, 0, 0, 0.1)',\n\t\tlineWidth: 1,\n\t\tdrawBorder: true,\n\t\tdrawOnChartArea: true,\n\t\tdrawTicks: true,\n\t\ttickMarkLength: 10,\n\t\tzeroLineWidth: 1,\n\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\n\t\tzeroLineBorderDash: [],\n\t\tzeroLineBorderDashOffset: 0.0,\n\t\toffsetGridLines: false,\n\t\tborderDash: [],\n\t\tborderDashOffset: 0.0\n\t},\n\n\t// scale label\n\tscaleLabel: {\n\t\t// display property\n\t\tdisplay: false,\n\n\t\t// actual label\n\t\tlabelString: '',\n\n\t\t// line height\n\t\tlineHeight: 1.2,\n\n\t\t// top/bottom padding\n\t\tpadding: {\n\t\t\ttop: 4,\n\t\t\tbottom: 4\n\t\t}\n\t},\n\n\t// label settings\n\tticks: {\n\t\tbeginAtZero: false,\n\t\tminRotation: 0,\n\t\tmaxRotation: 50,\n\t\tmirror: false,\n\t\tpadding: 0,\n\t\treverse: false,\n\t\tdisplay: true,\n\t\tautoSkip: true,\n\t\tautoSkipPadding: 0,\n\t\tlabelOffset: 0,\n\t\t// We pass through arrays to be rendered as multiline labels, we convert Others to strings here.\n\t\tcallback: Ticks.formatters.values,\n\t\tminor: {},\n\t\tmajor: {}\n\t}\n});\n\nfunction labelsFromTicks(ticks) {\n\tvar labels = [];\n\tvar i, ilen;\n\n\tfor (i = 0, ilen = ticks.length; i < ilen; ++i) {\n\t\tlabels.push(ticks[i].label);\n\t}\n\n\treturn labels;\n}\n\nfunction getLineValue(scale, index, offsetGridLines) {\n\tvar lineValue = scale.getPixelForTick(index);\n\n\tif (offsetGridLines) {\n\t\tif (index === 0) {\n\t\t\tlineValue -= (scale.getPixelForTick(1) - lineValue) / 2;\n\t\t} else {\n\t\t\tlineValue -= (lineValue - scale.getPixelForTick(index - 1)) / 2;\n\t\t}\n\t}\n\treturn lineValue;\n}\n\nfunction computeTextSize(context, tick, font) {\n\treturn helpers.isArray(tick) ?\n\t\thelpers.longestText(context, font, tick) :\n\t\tcontext.measureText(tick).width;\n}\n\nfunction parseFontOptions(options) {\n\tvar valueOrDefault = helpers.valueOrDefault;\n\tvar globalDefaults = defaults.global;\n\tvar size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize);\n\tvar style = valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle);\n\tvar family = valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily);\n\n\treturn {\n\t\tsize: size,\n\t\tstyle: style,\n\t\tfamily: family,\n\t\tfont: helpers.fontString(size, style, family)\n\t};\n}\n\nfunction parseLineHeight(options) {\n\treturn helpers.options.toLineHeight(\n\t\thelpers.valueOrDefault(options.lineHeight, 1.2),\n\t\thelpers.valueOrDefault(options.fontSize, defaults.global.defaultFontSize));\n}\n\nmodule.exports = Element.extend({\n\t/**\n\t * Get the padding needed for the scale\n\t * @method getPadding\n\t * @private\n\t * @returns {Padding} the necessary padding\n\t */\n\tgetPadding: function() {\n\t\tvar me = this;\n\t\treturn {\n\t\t\tleft: me.paddingLeft || 0,\n\t\t\ttop: me.paddingTop || 0,\n\t\t\tright: me.paddingRight || 0,\n\t\t\tbottom: me.paddingBottom || 0\n\t\t};\n\t},\n\n\t/**\n\t * Returns the scale tick objects ({label, major})\n\t * @since 2.7\n\t */\n\tgetTicks: function() {\n\t\treturn this._ticks;\n\t},\n\n\t// These methods are ordered by lifecyle. Utilities then follow.\n\t// Any function defined here is inherited by all scale types.\n\t// Any function can be extended by the scale type\n\n\tmergeTicksOptions: function() {\n\t\tvar ticks = this.options.ticks;\n\t\tif (ticks.minor === false) {\n\t\t\tticks.minor = {\n\t\t\t\tdisplay: false\n\t\t\t};\n\t\t}\n\t\tif (ticks.major === false) {\n\t\t\tticks.major = {\n\t\t\t\tdisplay: false\n\t\t\t};\n\t\t}\n\t\tfor (var key in ticks) {\n\t\t\tif (key !== 'major' && key !== 'minor') {\n\t\t\t\tif (typeof ticks.minor[key] === 'undefined') {\n\t\t\t\t\tticks.minor[key] = ticks[key];\n\t\t\t\t}\n\t\t\t\tif (typeof ticks.major[key] === 'undefined') {\n\t\t\t\t\tticks.major[key] = ticks[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tbeforeUpdate: function() {\n\t\thelpers.callback(this.options.beforeUpdate, [this]);\n\t},\n\n\tupdate: function(maxWidth, maxHeight, margins) {\n\t\tvar me = this;\n\t\tvar i, ilen, labels, label, ticks, tick;\n\n\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\n\t\tme.beforeUpdate();\n\n\t\t// Absorb the master measurements\n\t\tme.maxWidth = maxWidth;\n\t\tme.maxHeight = maxHeight;\n\t\tme.margins = helpers.extend({\n\t\t\tleft: 0,\n\t\t\tright: 0,\n\t\t\ttop: 0,\n\t\t\tbottom: 0\n\t\t}, margins);\n\t\tme.longestTextCache = me.longestTextCache || {};\n\n\t\t// Dimensions\n\t\tme.beforeSetDimensions();\n\t\tme.setDimensions();\n\t\tme.afterSetDimensions();\n\n\t\t// Data min/max\n\t\tme.beforeDataLimits();\n\t\tme.determineDataLimits();\n\t\tme.afterDataLimits();\n\n\t\t// Ticks - `this.ticks` is now DEPRECATED!\n\t\t// Internal ticks are now stored as objects in the PRIVATE `this._ticks` member\n\t\t// and must not be accessed directly from outside this class. `this.ticks` being\n\t\t// around for long time and not marked as private, we can't change its structure\n\t\t// without unexpected breaking changes. If you need to access the scale ticks,\n\t\t// use scale.getTicks() instead.\n\n\t\tme.beforeBuildTicks();\n\n\t\t// New implementations should return an array of objects but for BACKWARD COMPAT,\n\t\t// we still support no return (`this.ticks` internally set by calling this method).\n\t\tticks = me.buildTicks() || [];\n\n\t\tme.afterBuildTicks();\n\n\t\tme.beforeTickToLabelConversion();\n\n\t\t// New implementations should return the formatted tick labels but for BACKWARD\n\t\t// COMPAT, we still support no return (`this.ticks` internally changed by calling\n\t\t// this method and supposed to contain only string values).\n\t\tlabels = me.convertTicksToLabels(ticks) || me.ticks;\n\n\t\tme.afterTickToLabelConversion();\n\n\t\tme.ticks = labels;   // BACKWARD COMPATIBILITY\n\n\t\t// IMPORTANT: from this point, we consider that `this.ticks` will NEVER change!\n\n\t\t// BACKWARD COMPAT: synchronize `_ticks` with labels (so potentially `this.ticks`)\n\t\tfor (i = 0, ilen = labels.length; i < ilen; ++i) {\n\t\t\tlabel = labels[i];\n\t\t\ttick = ticks[i];\n\t\t\tif (!tick) {\n\t\t\t\tticks.push(tick = {\n\t\t\t\t\tlabel: label,\n\t\t\t\t\tmajor: false\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\ttick.label = label;\n\t\t\t}\n\t\t}\n\n\t\tme._ticks = ticks;\n\n\t\t// Tick Rotation\n\t\tme.beforeCalculateTickRotation();\n\t\tme.calculateTickRotation();\n\t\tme.afterCalculateTickRotation();\n\t\t// Fit\n\t\tme.beforeFit();\n\t\tme.fit();\n\t\tme.afterFit();\n\t\t//\n\t\tme.afterUpdate();\n\n\t\treturn me.minSize;\n\n\t},\n\tafterUpdate: function() {\n\t\thelpers.callback(this.options.afterUpdate, [this]);\n\t},\n\n\t//\n\n\tbeforeSetDimensions: function() {\n\t\thelpers.callback(this.options.beforeSetDimensions, [this]);\n\t},\n\tsetDimensions: function() {\n\t\tvar me = this;\n\t\t// Set the unconstrained dimension before label rotation\n\t\tif (me.isHorizontal()) {\n\t\t\t// Reset position before calculating rotation\n\t\t\tme.width = me.maxWidth;\n\t\t\tme.left = 0;\n\t\t\tme.right = me.width;\n\t\t} else {\n\t\t\tme.height = me.maxHeight;\n\n\t\t\t// Reset position before calculating rotation\n\t\t\tme.top = 0;\n\t\t\tme.bottom = me.height;\n\t\t}\n\n\t\t// Reset padding\n\t\tme.paddingLeft = 0;\n\t\tme.paddingTop = 0;\n\t\tme.paddingRight = 0;\n\t\tme.paddingBottom = 0;\n\t},\n\tafterSetDimensions: function() {\n\t\thelpers.callback(this.options.afterSetDimensions, [this]);\n\t},\n\n\t// Data limits\n\tbeforeDataLimits: function() {\n\t\thelpers.callback(this.options.beforeDataLimits, [this]);\n\t},\n\tdetermineDataLimits: helpers.noop,\n\tafterDataLimits: function() {\n\t\thelpers.callback(this.options.afterDataLimits, [this]);\n\t},\n\n\t//\n\tbeforeBuildTicks: function() {\n\t\thelpers.callback(this.options.beforeBuildTicks, [this]);\n\t},\n\tbuildTicks: helpers.noop,\n\tafterBuildTicks: function() {\n\t\thelpers.callback(this.options.afterBuildTicks, [this]);\n\t},\n\n\tbeforeTickToLabelConversion: function() {\n\t\thelpers.callback(this.options.beforeTickToLabelConversion, [this]);\n\t},\n\tconvertTicksToLabels: function() {\n\t\tvar me = this;\n\t\t// Convert ticks to strings\n\t\tvar tickOpts = me.options.ticks;\n\t\tme.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback, this);\n\t},\n\tafterTickToLabelConversion: function() {\n\t\thelpers.callback(this.options.afterTickToLabelConversion, [this]);\n\t},\n\n\t//\n\n\tbeforeCalculateTickRotation: function() {\n\t\thelpers.callback(this.options.beforeCalculateTickRotation, [this]);\n\t},\n\tcalculateTickRotation: function() {\n\t\tvar me = this;\n\t\tvar context = me.ctx;\n\t\tvar tickOpts = me.options.ticks;\n\t\tvar labels = labelsFromTicks(me._ticks);\n\n\t\t// Get the width of each grid by calculating the difference\n\t\t// between x offsets between 0 and 1.\n\t\tvar tickFont = parseFontOptions(tickOpts);\n\t\tcontext.font = tickFont.font;\n\n\t\tvar labelRotation = tickOpts.minRotation || 0;\n\n\t\tif (labels.length && me.options.display && me.isHorizontal()) {\n\t\t\tvar originalLabelWidth = helpers.longestText(context, tickFont.font, labels, me.longestTextCache);\n\t\t\tvar labelWidth = originalLabelWidth;\n\t\t\tvar cosRotation, sinRotation;\n\n\t\t\t// Allow 3 pixels x2 padding either side for label readability\n\t\t\tvar tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;\n\n\t\t\t// Max label rotation can be set or default to 90 - also act as a loop counter\n\t\t\twhile (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) {\n\t\t\t\tvar angleRadians = helpers.toRadians(labelRotation);\n\t\t\t\tcosRotation = Math.cos(angleRadians);\n\t\t\t\tsinRotation = Math.sin(angleRadians);\n\n\t\t\t\tif (sinRotation * originalLabelWidth > me.maxHeight) {\n\t\t\t\t\t// go back one step\n\t\t\t\t\tlabelRotation--;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tlabelRotation++;\n\t\t\t\tlabelWidth = cosRotation * originalLabelWidth;\n\t\t\t}\n\t\t}\n\n\t\tme.labelRotation = labelRotation;\n\t},\n\tafterCalculateTickRotation: function() {\n\t\thelpers.callback(this.options.afterCalculateTickRotation, [this]);\n\t},\n\n\t//\n\n\tbeforeFit: function() {\n\t\thelpers.callback(this.options.beforeFit, [this]);\n\t},\n\tfit: function() {\n\t\tvar me = this;\n\t\t// Reset\n\t\tvar minSize = me.minSize = {\n\t\t\twidth: 0,\n\t\t\theight: 0\n\t\t};\n\n\t\tvar labels = labelsFromTicks(me._ticks);\n\n\t\tvar opts = me.options;\n\t\tvar tickOpts = opts.ticks;\n\t\tvar scaleLabelOpts = opts.scaleLabel;\n\t\tvar gridLineOpts = opts.gridLines;\n\t\tvar display = opts.display;\n\t\tvar isHorizontal = me.isHorizontal();\n\n\t\tvar tickFont = parseFontOptions(tickOpts);\n\t\tvar tickMarkLength = opts.gridLines.tickMarkLength;\n\n\t\t// Width\n\t\tif (isHorizontal) {\n\t\t\t// subtract the margins to line up with the chartArea if we are a full width scale\n\t\t\tminSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;\n\t\t} else {\n\t\t\tminSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0;\n\t\t}\n\n\t\t// height\n\t\tif (isHorizontal) {\n\t\t\tminSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;\n\t\t} else {\n\t\t\tminSize.height = me.maxHeight; // fill all the height\n\t\t}\n\n\t\t// Are we showing a title for the scale?\n\t\tif (scaleLabelOpts.display && display) {\n\t\t\tvar scaleLabelLineHeight = parseLineHeight(scaleLabelOpts);\n\t\t\tvar scaleLabelPadding = helpers.options.toPadding(scaleLabelOpts.padding);\n\t\t\tvar deltaHeight = scaleLabelLineHeight + scaleLabelPadding.height;\n\n\t\t\tif (isHorizontal) {\n\t\t\t\tminSize.height += deltaHeight;\n\t\t\t} else {\n\t\t\t\tminSize.width += deltaHeight;\n\t\t\t}\n\t\t}\n\n\t\t// Don't bother fitting the ticks if we are not showing them\n\t\tif (tickOpts.display && display) {\n\t\t\tvar largestTextWidth = helpers.longestText(me.ctx, tickFont.font, labels, me.longestTextCache);\n\t\t\tvar tallestLabelHeightInLines = helpers.numberOfLabelLines(labels);\n\t\t\tvar lineSpace = tickFont.size * 0.5;\n\t\t\tvar tickPadding = me.options.ticks.padding;\n\n\t\t\tif (isHorizontal) {\n\t\t\t\t// A horizontal axis is more constrained by the height.\n\t\t\t\tme.longestLabelWidth = largestTextWidth;\n\n\t\t\t\tvar angleRadians = helpers.toRadians(me.labelRotation);\n\t\t\t\tvar cosRotation = Math.cos(angleRadians);\n\t\t\t\tvar sinRotation = Math.sin(angleRadians);\n\n\t\t\t\t// TODO - improve this calculation\n\t\t\t\tvar labelHeight = (sinRotation * largestTextWidth)\n\t\t\t\t\t+ (tickFont.size * tallestLabelHeightInLines)\n\t\t\t\t\t+ (lineSpace * (tallestLabelHeightInLines - 1))\n\t\t\t\t\t+ lineSpace; // padding\n\n\t\t\t\tminSize.height = Math.min(me.maxHeight, minSize.height + labelHeight + tickPadding);\n\n\t\t\t\tme.ctx.font = tickFont.font;\n\t\t\t\tvar firstLabelWidth = computeTextSize(me.ctx, labels[0], tickFont.font);\n\t\t\t\tvar lastLabelWidth = computeTextSize(me.ctx, labels[labels.length - 1], tickFont.font);\n\n\t\t\t\t// Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned\n\t\t\t\t// which means that the right padding is dominated by the font height\n\t\t\t\tif (me.labelRotation !== 0) {\n\t\t\t\t\tme.paddingLeft = opts.position === 'bottom' ? (cosRotation * firstLabelWidth) + 3 : (cosRotation * lineSpace) + 3; // add 3 px to move away from canvas edges\n\t\t\t\t\tme.paddingRight = opts.position === 'bottom' ? (cosRotation * lineSpace) + 3 : (cosRotation * lastLabelWidth) + 3;\n\t\t\t\t} else {\n\t\t\t\t\tme.paddingLeft = firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges\n\t\t\t\t\tme.paddingRight = lastLabelWidth / 2 + 3;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// A vertical axis is more constrained by the width. Labels are the\n\t\t\t\t// dominant factor here, so get that length first and account for padding\n\t\t\t\tif (tickOpts.mirror) {\n\t\t\t\t\tlargestTextWidth = 0;\n\t\t\t\t} else {\n\t\t\t\t\t// use lineSpace for consistency with horizontal axis\n\t\t\t\t\t// tickPadding is not implemented for horizontal\n\t\t\t\t\tlargestTextWidth += tickPadding + lineSpace;\n\t\t\t\t}\n\n\t\t\t\tminSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth);\n\n\t\t\t\tme.paddingTop = tickFont.size / 2;\n\t\t\t\tme.paddingBottom = tickFont.size / 2;\n\t\t\t}\n\t\t}\n\n\t\tme.handleMargins();\n\n\t\tme.width = minSize.width;\n\t\tme.height = minSize.height;\n\t},\n\n\t/**\n\t * Handle margins and padding interactions\n\t * @private\n\t */\n\thandleMargins: function() {\n\t\tvar me = this;\n\t\tif (me.margins) {\n\t\t\tme.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);\n\t\t\tme.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);\n\t\t\tme.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);\n\t\t\tme.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);\n\t\t}\n\t},\n\n\tafterFit: function() {\n\t\thelpers.callback(this.options.afterFit, [this]);\n\t},\n\n\t// Shared Methods\n\tisHorizontal: function() {\n\t\treturn this.options.position === 'top' || this.options.position === 'bottom';\n\t},\n\tisFullWidth: function() {\n\t\treturn (this.options.fullWidth);\n\t},\n\n\t// Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not\n\tgetRightValue: function(rawValue) {\n\t\t// Null and undefined values first\n\t\tif (helpers.isNullOrUndef(rawValue)) {\n\t\t\treturn NaN;\n\t\t}\n\t\t// isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values\n\t\tif (typeof rawValue === 'number' && !isFinite(rawValue)) {\n\t\t\treturn NaN;\n\t\t}\n\t\t// If it is in fact an object, dive in one more level\n\t\tif (rawValue) {\n\t\t\tif (this.isHorizontal()) {\n\t\t\t\tif (rawValue.x !== undefined) {\n\t\t\t\t\treturn this.getRightValue(rawValue.x);\n\t\t\t\t}\n\t\t\t} else if (rawValue.y !== undefined) {\n\t\t\t\treturn this.getRightValue(rawValue.y);\n\t\t\t}\n\t\t}\n\n\t\t// Value is good, return it\n\t\treturn rawValue;\n\t},\n\n\t/**\n\t * Used to get the value to display in the tooltip for the data at the given index\n\t * @param index\n\t * @param datasetIndex\n\t */\n\tgetLabelForIndex: helpers.noop,\n\n\t/**\n\t * Returns the location of the given data point. Value can either be an index or a numerical value\n\t * The coordinate (0, 0) is at the upper-left corner of the canvas\n\t * @param value\n\t * @param index\n\t * @param datasetIndex\n\t */\n\tgetPixelForValue: helpers.noop,\n\n\t/**\n\t * Used to get the data value from a given pixel. This is the inverse of getPixelForValue\n\t * The coordinate (0, 0) is at the upper-left corner of the canvas\n\t * @param pixel\n\t */\n\tgetValueForPixel: helpers.noop,\n\n\t/**\n\t * Returns the location of the tick at the given index\n\t * The coordinate (0, 0) is at the upper-left corner of the canvas\n\t */\n\tgetPixelForTick: function(index) {\n\t\tvar me = this;\n\t\tvar offset = me.options.offset;\n\t\tif (me.isHorizontal()) {\n\t\t\tvar innerWidth = me.width - (me.paddingLeft + me.paddingRight);\n\t\t\tvar tickWidth = innerWidth / Math.max((me._ticks.length - (offset ? 0 : 1)), 1);\n\t\t\tvar pixel = (tickWidth * index) + me.paddingLeft;\n\n\t\t\tif (offset) {\n\t\t\t\tpixel += tickWidth / 2;\n\t\t\t}\n\n\t\t\tvar finalVal = me.left + Math.round(pixel);\n\t\t\tfinalVal += me.isFullWidth() ? me.margins.left : 0;\n\t\t\treturn finalVal;\n\t\t}\n\t\tvar innerHeight = me.height - (me.paddingTop + me.paddingBottom);\n\t\treturn me.top + (index * (innerHeight / (me._ticks.length - 1)));\n\t},\n\n\t/**\n\t * Utility for getting the pixel location of a percentage of scale\n\t * The coordinate (0, 0) is at the upper-left corner of the canvas\n\t */\n\tgetPixelForDecimal: function(decimal) {\n\t\tvar me = this;\n\t\tif (me.isHorizontal()) {\n\t\t\tvar innerWidth = me.width - (me.paddingLeft + me.paddingRight);\n\t\t\tvar valueOffset = (innerWidth * decimal) + me.paddingLeft;\n\n\t\t\tvar finalVal = me.left + Math.round(valueOffset);\n\t\t\tfinalVal += me.isFullWidth() ? me.margins.left : 0;\n\t\t\treturn finalVal;\n\t\t}\n\t\treturn me.top + (decimal * me.height);\n\t},\n\n\t/**\n\t * Returns the pixel for the minimum chart value\n\t * The coordinate (0, 0) is at the upper-left corner of the canvas\n\t */\n\tgetBasePixel: function() {\n\t\treturn this.getPixelForValue(this.getBaseValue());\n\t},\n\n\tgetBaseValue: function() {\n\t\tvar me = this;\n\t\tvar min = me.min;\n\t\tvar max = me.max;\n\n\t\treturn me.beginAtZero ? 0 :\n\t\t\tmin < 0 && max < 0 ? max :\n\t\t\tmin > 0 && max > 0 ? min :\n\t\t\t0;\n\t},\n\n\t/**\n\t * Returns a subset of ticks to be plotted to avoid overlapping labels.\n\t * @private\n\t */\n\t_autoSkip: function(ticks) {\n\t\tvar skipRatio;\n\t\tvar me = this;\n\t\tvar isHorizontal = me.isHorizontal();\n\t\tvar optionTicks = me.options.ticks.minor;\n\t\tvar tickCount = ticks.length;\n\t\tvar labelRotationRadians = helpers.toRadians(me.labelRotation);\n\t\tvar cosRotation = Math.cos(labelRotationRadians);\n\t\tvar longestRotatedLabel = me.longestLabelWidth * cosRotation;\n\t\tvar result = [];\n\t\tvar i, tick, shouldSkip;\n\n\t\t// figure out the maximum number of gridlines to show\n\t\tvar maxTicks;\n\t\tif (optionTicks.maxTicksLimit) {\n\t\t\tmaxTicks = optionTicks.maxTicksLimit;\n\t\t}\n\n\t\tif (isHorizontal) {\n\t\t\tskipRatio = false;\n\n\t\t\tif ((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount > (me.width - (me.paddingLeft + me.paddingRight))) {\n\t\t\t\tskipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount) / (me.width - (me.paddingLeft + me.paddingRight)));\n\t\t\t}\n\n\t\t\t// if they defined a max number of optionTicks,\n\t\t\t// increase skipRatio until that number is met\n\t\t\tif (maxTicks && tickCount > maxTicks) {\n\t\t\t\tskipRatio = Math.max(skipRatio, Math.floor(tickCount / maxTicks));\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < tickCount; i++) {\n\t\t\ttick = ticks[i];\n\n\t\t\t// Since we always show the last tick,we need may need to hide the last shown one before\n\t\t\tshouldSkip = (skipRatio > 1 && i % skipRatio > 0) || (i % skipRatio === 0 && i + skipRatio >= tickCount);\n\t\t\tif (shouldSkip && i !== tickCount - 1) {\n\t\t\t\t// leave tick in place but make sure it's not displayed (#4635)\n\t\t\t\tdelete tick.label;\n\t\t\t}\n\t\t\tresult.push(tick);\n\t\t}\n\t\treturn result;\n\t},\n\n\t// Actually draw the scale on the canvas\n\t// @param {rectangle} chartArea : the area of the chart to draw full grid lines on\n\tdraw: function(chartArea) {\n\t\tvar me = this;\n\t\tvar options = me.options;\n\t\tif (!options.display) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar context = me.ctx;\n\t\tvar globalDefaults = defaults.global;\n\t\tvar optionTicks = options.ticks.minor;\n\t\tvar optionMajorTicks = options.ticks.major || optionTicks;\n\t\tvar gridLines = options.gridLines;\n\t\tvar scaleLabel = options.scaleLabel;\n\n\t\tvar isRotated = me.labelRotation !== 0;\n\t\tvar isHorizontal = me.isHorizontal();\n\n\t\tvar ticks = optionTicks.autoSkip ? me._autoSkip(me.getTicks()) : me.getTicks();\n\t\tvar tickFontColor = helpers.valueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);\n\t\tvar tickFont = parseFontOptions(optionTicks);\n\t\tvar majorTickFontColor = helpers.valueOrDefault(optionMajorTicks.fontColor, globalDefaults.defaultFontColor);\n\t\tvar majorTickFont = parseFontOptions(optionMajorTicks);\n\n\t\tvar tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;\n\n\t\tvar scaleLabelFontColor = helpers.valueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);\n\t\tvar scaleLabelFont = parseFontOptions(scaleLabel);\n\t\tvar scaleLabelPadding = helpers.options.toPadding(scaleLabel.padding);\n\t\tvar labelRotationRadians = helpers.toRadians(me.labelRotation);\n\n\t\tvar itemsToDraw = [];\n\n\t\tvar axisWidth = me.options.gridLines.lineWidth;\n\t\tvar xTickStart = options.position === 'right' ? me.left : me.right - axisWidth - tl;\n\t\tvar xTickEnd = options.position === 'right' ? me.left + tl : me.right;\n\t\tvar yTickStart = options.position === 'bottom' ? me.top + axisWidth : me.bottom - tl - axisWidth;\n\t\tvar yTickEnd = options.position === 'bottom' ? me.top + axisWidth + tl : me.bottom + axisWidth;\n\n\t\thelpers.each(ticks, function(tick, index) {\n\t\t\t// autoskipper skipped this tick (#4635)\n\t\t\tif (helpers.isNullOrUndef(tick.label)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar label = tick.label;\n\t\t\tvar lineWidth, lineColor, borderDash, borderDashOffset;\n\t\t\tif (index === me.zeroLineIndex && options.offset === gridLines.offsetGridLines) {\n\t\t\t\t// Draw the first index specially\n\t\t\t\tlineWidth = gridLines.zeroLineWidth;\n\t\t\t\tlineColor = gridLines.zeroLineColor;\n\t\t\t\tborderDash = gridLines.zeroLineBorderDash;\n\t\t\t\tborderDashOffset = gridLines.zeroLineBorderDashOffset;\n\t\t\t} else {\n\t\t\t\tlineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, index);\n\t\t\t\tlineColor = helpers.valueAtIndexOrDefault(gridLines.color, index);\n\t\t\t\tborderDash = helpers.valueOrDefault(gridLines.borderDash, globalDefaults.borderDash);\n\t\t\t\tborderDashOffset = helpers.valueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset);\n\t\t\t}\n\n\t\t\t// Common properties\n\t\t\tvar tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;\n\t\t\tvar textAlign = 'middle';\n\t\t\tvar textBaseline = 'middle';\n\t\t\tvar tickPadding = optionTicks.padding;\n\n\t\t\tif (isHorizontal) {\n\t\t\t\tvar labelYOffset = tl + tickPadding;\n\n\t\t\t\tif (options.position === 'bottom') {\n\t\t\t\t\t// bottom\n\t\t\t\t\ttextBaseline = !isRotated ? 'top' : 'middle';\n\t\t\t\t\ttextAlign = !isRotated ? 'center' : 'right';\n\t\t\t\t\tlabelY = me.top + labelYOffset;\n\t\t\t\t} else {\n\t\t\t\t\t// top\n\t\t\t\t\ttextBaseline = !isRotated ? 'bottom' : 'middle';\n\t\t\t\t\ttextAlign = !isRotated ? 'center' : 'left';\n\t\t\t\t\tlabelY = me.bottom - labelYOffset;\n\t\t\t\t}\n\n\t\t\t\tvar xLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1);\n\t\t\t\tif (xLineValue < me.left) {\n\t\t\t\t\tlineColor = 'rgba(0,0,0,0)';\n\t\t\t\t}\n\t\t\t\txLineValue += helpers.aliasPixel(lineWidth);\n\n\t\t\t\tlabelX = me.getPixelForTick(index) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)\n\n\t\t\t\ttx1 = tx2 = x1 = x2 = xLineValue;\n\t\t\t\tty1 = yTickStart;\n\t\t\t\tty2 = yTickEnd;\n\t\t\t\ty1 = chartArea.top;\n\t\t\t\ty2 = chartArea.bottom + axisWidth;\n\t\t\t} else {\n\t\t\t\tvar isLeft = options.position === 'left';\n\t\t\t\tvar labelXOffset;\n\n\t\t\t\tif (optionTicks.mirror) {\n\t\t\t\t\ttextAlign = isLeft ? 'left' : 'right';\n\t\t\t\t\tlabelXOffset = tickPadding;\n\t\t\t\t} else {\n\t\t\t\t\ttextAlign = isLeft ? 'right' : 'left';\n\t\t\t\t\tlabelXOffset = tl + tickPadding;\n\t\t\t\t}\n\n\t\t\t\tlabelX = isLeft ? me.right - labelXOffset : me.left + labelXOffset;\n\n\t\t\t\tvar yLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1);\n\t\t\t\tif (yLineValue < me.top) {\n\t\t\t\t\tlineColor = 'rgba(0,0,0,0)';\n\t\t\t\t}\n\t\t\t\tyLineValue += helpers.aliasPixel(lineWidth);\n\n\t\t\t\tlabelY = me.getPixelForTick(index) + optionTicks.labelOffset;\n\n\t\t\t\ttx1 = xTickStart;\n\t\t\t\ttx2 = xTickEnd;\n\t\t\t\tx1 = chartArea.left;\n\t\t\t\tx2 = chartArea.right + axisWidth;\n\t\t\t\tty1 = ty2 = y1 = y2 = yLineValue;\n\t\t\t}\n\n\t\t\titemsToDraw.push({\n\t\t\t\ttx1: tx1,\n\t\t\t\tty1: ty1,\n\t\t\t\ttx2: tx2,\n\t\t\t\tty2: ty2,\n\t\t\t\tx1: x1,\n\t\t\t\ty1: y1,\n\t\t\t\tx2: x2,\n\t\t\t\ty2: y2,\n\t\t\t\tlabelX: labelX,\n\t\t\t\tlabelY: labelY,\n\t\t\t\tglWidth: lineWidth,\n\t\t\t\tglColor: lineColor,\n\t\t\t\tglBorderDash: borderDash,\n\t\t\t\tglBorderDashOffset: borderDashOffset,\n\t\t\t\trotation: -1 * labelRotationRadians,\n\t\t\t\tlabel: label,\n\t\t\t\tmajor: tick.major,\n\t\t\t\ttextBaseline: textBaseline,\n\t\t\t\ttextAlign: textAlign\n\t\t\t});\n\t\t});\n\n\t\t// Draw all of the tick labels, tick marks, and grid lines at the correct places\n\t\thelpers.each(itemsToDraw, function(itemToDraw) {\n\t\t\tif (gridLines.display) {\n\t\t\t\tcontext.save();\n\t\t\t\tcontext.lineWidth = itemToDraw.glWidth;\n\t\t\t\tcontext.strokeStyle = itemToDraw.glColor;\n\t\t\t\tif (context.setLineDash) {\n\t\t\t\t\tcontext.setLineDash(itemToDraw.glBorderDash);\n\t\t\t\t\tcontext.lineDashOffset = itemToDraw.glBorderDashOffset;\n\t\t\t\t}\n\n\t\t\t\tcontext.beginPath();\n\n\t\t\t\tif (gridLines.drawTicks) {\n\t\t\t\t\tcontext.moveTo(itemToDraw.tx1, itemToDraw.ty1);\n\t\t\t\t\tcontext.lineTo(itemToDraw.tx2, itemToDraw.ty2);\n\t\t\t\t}\n\n\t\t\t\tif (gridLines.drawOnChartArea) {\n\t\t\t\t\tcontext.moveTo(itemToDraw.x1, itemToDraw.y1);\n\t\t\t\t\tcontext.lineTo(itemToDraw.x2, itemToDraw.y2);\n\t\t\t\t}\n\n\t\t\t\tcontext.stroke();\n\t\t\t\tcontext.restore();\n\t\t\t}\n\n\t\t\tif (optionTicks.display) {\n\t\t\t\t// Make sure we draw text in the correct color and font\n\t\t\t\tcontext.save();\n\t\t\t\tcontext.translate(itemToDraw.labelX, itemToDraw.labelY);\n\t\t\t\tcontext.rotate(itemToDraw.rotation);\n\t\t\t\tcontext.font = itemToDraw.major ? majorTickFont.font : tickFont.font;\n\t\t\t\tcontext.fillStyle = itemToDraw.major ? majorTickFontColor : tickFontColor;\n\t\t\t\tcontext.textBaseline = itemToDraw.textBaseline;\n\t\t\t\tcontext.textAlign = itemToDraw.textAlign;\n\n\t\t\t\tvar label = itemToDraw.label;\n\t\t\t\tif (helpers.isArray(label)) {\n\t\t\t\t\tvar lineCount = label.length;\n\t\t\t\t\tvar lineHeight = tickFont.size * 1.5;\n\t\t\t\t\tvar y = me.isHorizontal() ? 0 : -lineHeight * (lineCount - 1) / 2;\n\n\t\t\t\t\tfor (var i = 0; i < lineCount; ++i) {\n\t\t\t\t\t\t// We just make sure the multiline element is a string here..\n\t\t\t\t\t\tcontext.fillText('' + label[i], 0, y);\n\t\t\t\t\t\t// apply same lineSpacing as calculated @ L#320\n\t\t\t\t\t\ty += lineHeight;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcontext.fillText(label, 0, 0);\n\t\t\t\t}\n\t\t\t\tcontext.restore();\n\t\t\t}\n\t\t});\n\n\t\tif (scaleLabel.display) {\n\t\t\t// Draw the scale label\n\t\t\tvar scaleLabelX;\n\t\t\tvar scaleLabelY;\n\t\t\tvar rotation = 0;\n\t\t\tvar halfLineHeight = parseLineHeight(scaleLabel) / 2;\n\n\t\t\tif (isHorizontal) {\n\t\t\t\tscaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width\n\t\t\t\tscaleLabelY = options.position === 'bottom'\n\t\t\t\t\t? me.bottom - halfLineHeight - scaleLabelPadding.bottom\n\t\t\t\t\t: me.top + halfLineHeight + scaleLabelPadding.top;\n\t\t\t} else {\n\t\t\t\tvar isLeft = options.position === 'left';\n\t\t\t\tscaleLabelX = isLeft\n\t\t\t\t\t? me.left + halfLineHeight + scaleLabelPadding.top\n\t\t\t\t\t: me.right - halfLineHeight - scaleLabelPadding.top;\n\t\t\t\tscaleLabelY = me.top + ((me.bottom - me.top) / 2);\n\t\t\t\trotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;\n\t\t\t}\n\n\t\t\tcontext.save();\n\t\t\tcontext.translate(scaleLabelX, scaleLabelY);\n\t\t\tcontext.rotate(rotation);\n\t\t\tcontext.textAlign = 'center';\n\t\t\tcontext.textBaseline = 'middle';\n\t\t\tcontext.fillStyle = scaleLabelFontColor; // render in correct colour\n\t\t\tcontext.font = scaleLabelFont.font;\n\t\t\tcontext.fillText(scaleLabel.labelString, 0, 0);\n\t\t\tcontext.restore();\n\t\t}\n\n\t\tif (gridLines.drawBorder) {\n\t\t\t// Draw the line at the edge of the axis\n\t\t\tcontext.lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, 0);\n\t\t\tcontext.strokeStyle = helpers.valueAtIndexOrDefault(gridLines.color, 0);\n\t\t\tvar x1 = me.left;\n\t\t\tvar x2 = me.right + axisWidth;\n\t\t\tvar y1 = me.top;\n\t\t\tvar y2 = me.bottom + axisWidth;\n\n\t\t\tvar aliasPixel = helpers.aliasPixel(context.lineWidth);\n\t\t\tif (isHorizontal) {\n\t\t\t\ty1 = y2 = options.position === 'top' ? me.bottom : me.top;\n\t\t\t\ty1 += aliasPixel;\n\t\t\t\ty2 += aliasPixel;\n\t\t\t} else {\n\t\t\t\tx1 = x2 = options.position === 'left' ? me.right : me.left;\n\t\t\t\tx1 += aliasPixel;\n\t\t\t\tx2 += aliasPixel;\n\t\t\t}\n\n\t\t\tcontext.beginPath();\n\t\t\tcontext.moveTo(x1, y1);\n\t\t\tcontext.lineTo(x2, y2);\n\t\t\tcontext.stroke();\n\t\t}\n\t}\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZDFiNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLnNjYWxlLmpzPzcxZGIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2NvcmUuZGVmYXVsdHMnKTtcbnZhciBFbGVtZW50ID0gcmVxdWlyZSgnLi9jb3JlLmVsZW1lbnQnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xudmFyIFRpY2tzID0gcmVxdWlyZSgnLi9jb3JlLnRpY2tzJyk7XG5cbmRlZmF1bHRzLl9zZXQoJ3NjYWxlJywge1xuXHRkaXNwbGF5OiB0cnVlLFxuXHRwb3NpdGlvbjogJ2xlZnQnLFxuXHRvZmZzZXQ6IGZhbHNlLFxuXG5cdC8vIGdyaWQgbGluZSBzZXR0aW5nc1xuXHRncmlkTGluZXM6IHtcblx0XHRkaXNwbGF5OiB0cnVlLFxuXHRcdGNvbG9yOiAncmdiYSgwLCAwLCAwLCAwLjEpJyxcblx0XHRsaW5lV2lkdGg6IDEsXG5cdFx0ZHJhd0JvcmRlcjogdHJ1ZSxcblx0XHRkcmF3T25DaGFydEFyZWE6IHRydWUsXG5cdFx0ZHJhd1RpY2tzOiB0cnVlLFxuXHRcdHRpY2tNYXJrTGVuZ3RoOiAxMCxcblx0XHR6ZXJvTGluZVdpZHRoOiAxLFxuXHRcdHplcm9MaW5lQ29sb3I6ICdyZ2JhKDAsMCwwLDAuMjUpJyxcblx0XHR6ZXJvTGluZUJvcmRlckRhc2g6IFtdLFxuXHRcdHplcm9MaW5lQm9yZGVyRGFzaE9mZnNldDogMC4wLFxuXHRcdG9mZnNldEdyaWRMaW5lczogZmFsc2UsXG5cdFx0Ym9yZGVyRGFzaDogW10sXG5cdFx0Ym9yZGVyRGFzaE9mZnNldDogMC4wXG5cdH0sXG5cblx0Ly8gc2NhbGUgbGFiZWxcblx0c2NhbGVMYWJlbDoge1xuXHRcdC8vIGRpc3BsYXkgcHJvcGVydHlcblx0XHRkaXNwbGF5OiBmYWxzZSxcblxuXHRcdC8vIGFjdHVhbCBsYWJlbFxuXHRcdGxhYmVsU3RyaW5nOiAnJyxcblxuXHRcdC8vIGxpbmUgaGVpZ2h0XG5cdFx0bGluZUhlaWdodDogMS4yLFxuXG5cdFx0Ly8gdG9wL2JvdHRvbSBwYWRkaW5nXG5cdFx0cGFkZGluZzoge1xuXHRcdFx0dG9wOiA0LFxuXHRcdFx0Ym90dG9tOiA0XG5cdFx0fVxuXHR9LFxuXG5cdC8vIGxhYmVsIHNldHRpbmdzXG5cdHRpY2tzOiB7XG5cdFx0YmVnaW5BdFplcm86IGZhbHNlLFxuXHRcdG1pblJvdGF0aW9uOiAwLFxuXHRcdG1heFJvdGF0aW9uOiA1MCxcblx0XHRtaXJyb3I6IGZhbHNlLFxuXHRcdHBhZGRpbmc6IDAsXG5cdFx0cmV2ZXJzZTogZmFsc2UsXG5cdFx0ZGlzcGxheTogdHJ1ZSxcblx0XHRhdXRvU2tpcDogdHJ1ZSxcblx0XHRhdXRvU2tpcFBhZGRpbmc6IDAsXG5cdFx0bGFiZWxPZmZzZXQ6IDAsXG5cdFx0Ly8gV2UgcGFzcyB0aHJvdWdoIGFycmF5cyB0byBiZSByZW5kZXJlZCBhcyBtdWx0aWxpbmUgbGFiZWxzLCB3ZSBjb252ZXJ0IE90aGVycyB0byBzdHJpbmdzIGhlcmUuXG5cdFx0Y2FsbGJhY2s6IFRpY2tzLmZvcm1hdHRlcnMudmFsdWVzLFxuXHRcdG1pbm9yOiB7fSxcblx0XHRtYWpvcjoge31cblx0fVxufSk7XG5cbmZ1bmN0aW9uIGxhYmVsc0Zyb21UaWNrcyh0aWNrcykge1xuXHR2YXIgbGFiZWxzID0gW107XG5cdHZhciBpLCBpbGVuO1xuXG5cdGZvciAoaSA9IDAsIGlsZW4gPSB0aWNrcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRsYWJlbHMucHVzaCh0aWNrc1tpXS5sYWJlbCk7XG5cdH1cblxuXHRyZXR1cm4gbGFiZWxzO1xufVxuXG5mdW5jdGlvbiBnZXRMaW5lVmFsdWUoc2NhbGUsIGluZGV4LCBvZmZzZXRHcmlkTGluZXMpIHtcblx0dmFyIGxpbmVWYWx1ZSA9IHNjYWxlLmdldFBpeGVsRm9yVGljayhpbmRleCk7XG5cblx0aWYgKG9mZnNldEdyaWRMaW5lcykge1xuXHRcdGlmIChpbmRleCA9PT0gMCkge1xuXHRcdFx0bGluZVZhbHVlIC09IChzY2FsZS5nZXRQaXhlbEZvclRpY2soMSkgLSBsaW5lVmFsdWUpIC8gMjtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bGluZVZhbHVlIC09IChsaW5lVmFsdWUgLSBzY2FsZS5nZXRQaXhlbEZvclRpY2soaW5kZXggLSAxKSkgLyAyO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gbGluZVZhbHVlO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlVGV4dFNpemUoY29udGV4dCwgdGljaywgZm9udCkge1xuXHRyZXR1cm4gaGVscGVycy5pc0FycmF5KHRpY2spID9cblx0XHRoZWxwZXJzLmxvbmdlc3RUZXh0KGNvbnRleHQsIGZvbnQsIHRpY2spIDpcblx0XHRjb250ZXh0Lm1lYXN1cmVUZXh0KHRpY2spLndpZHRoO1xufVxuXG5mdW5jdGlvbiBwYXJzZUZvbnRPcHRpb25zKG9wdGlvbnMpIHtcblx0dmFyIHZhbHVlT3JEZWZhdWx0ID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdDtcblx0dmFyIGdsb2JhbERlZmF1bHRzID0gZGVmYXVsdHMuZ2xvYmFsO1xuXHR2YXIgc2l6ZSA9IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMuZm9udFNpemUsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250U2l6ZSk7XG5cdHZhciBzdHlsZSA9IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMuZm9udFN0eWxlLCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udFN0eWxlKTtcblx0dmFyIGZhbWlseSA9IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMuZm9udEZhbWlseSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRGYW1pbHkpO1xuXG5cdHJldHVybiB7XG5cdFx0c2l6ZTogc2l6ZSxcblx0XHRzdHlsZTogc3R5bGUsXG5cdFx0ZmFtaWx5OiBmYW1pbHksXG5cdFx0Zm9udDogaGVscGVycy5mb250U3RyaW5nKHNpemUsIHN0eWxlLCBmYW1pbHkpXG5cdH07XG59XG5cbmZ1bmN0aW9uIHBhcnNlTGluZUhlaWdodChvcHRpb25zKSB7XG5cdHJldHVybiBoZWxwZXJzLm9wdGlvbnMudG9MaW5lSGVpZ2h0KFxuXHRcdGhlbHBlcnMudmFsdWVPckRlZmF1bHQob3B0aW9ucy5saW5lSGVpZ2h0LCAxLjIpLFxuXHRcdGhlbHBlcnMudmFsdWVPckRlZmF1bHQob3B0aW9ucy5mb250U2l6ZSwgZGVmYXVsdHMuZ2xvYmFsLmRlZmF1bHRGb250U2l6ZSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEVsZW1lbnQuZXh0ZW5kKHtcblx0LyoqXG5cdCAqIEdldCB0aGUgcGFkZGluZyBuZWVkZWQgZm9yIHRoZSBzY2FsZVxuXHQgKiBAbWV0aG9kIGdldFBhZGRpbmdcblx0ICogQHByaXZhdGVcblx0ICogQHJldHVybnMge1BhZGRpbmd9IHRoZSBuZWNlc3NhcnkgcGFkZGluZ1xuXHQgKi9cblx0Z2V0UGFkZGluZzogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIG1lID0gdGhpcztcblx0XHRyZXR1cm4ge1xuXHRcdFx0bGVmdDogbWUucGFkZGluZ0xlZnQgfHwgMCxcblx0XHRcdHRvcDogbWUucGFkZGluZ1RvcCB8fCAwLFxuXHRcdFx0cmlnaHQ6IG1lLnBhZGRpbmdSaWdodCB8fCAwLFxuXHRcdFx0Ym90dG9tOiBtZS5wYWRkaW5nQm90dG9tIHx8IDBcblx0XHR9O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBzY2FsZSB0aWNrIG9iamVjdHMgKHtsYWJlbCwgbWFqb3J9KVxuXHQgKiBAc2luY2UgMi43XG5cdCAqL1xuXHRnZXRUaWNrczogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuX3RpY2tzO1xuXHR9LFxuXG5cdC8vIFRoZXNlIG1ldGhvZHMgYXJlIG9yZGVyZWQgYnkgbGlmZWN5bGUuIFV0aWxpdGllcyB0aGVuIGZvbGxvdy5cblx0Ly8gQW55IGZ1bmN0aW9uIGRlZmluZWQgaGVyZSBpcyBpbmhlcml0ZWQgYnkgYWxsIHNjYWxlIHR5cGVzLlxuXHQvLyBBbnkgZnVuY3Rpb24gY2FuIGJlIGV4dGVuZGVkIGJ5IHRoZSBzY2FsZSB0eXBlXG5cblx0bWVyZ2VUaWNrc09wdGlvbnM6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciB0aWNrcyA9IHRoaXMub3B0aW9ucy50aWNrcztcblx0XHRpZiAodGlja3MubWlub3IgPT09IGZhbHNlKSB7XG5cdFx0XHR0aWNrcy5taW5vciA9IHtcblx0XHRcdFx0ZGlzcGxheTogZmFsc2Vcblx0XHRcdH07XG5cdFx0fVxuXHRcdGlmICh0aWNrcy5tYWpvciA9PT0gZmFsc2UpIHtcblx0XHRcdHRpY2tzLm1ham9yID0ge1xuXHRcdFx0XHRkaXNwbGF5OiBmYWxzZVxuXHRcdFx0fTtcblx0XHR9XG5cdFx0Zm9yICh2YXIga2V5IGluIHRpY2tzKSB7XG5cdFx0XHRpZiAoa2V5ICE9PSAnbWFqb3InICYmIGtleSAhPT0gJ21pbm9yJykge1xuXHRcdFx0XHRpZiAodHlwZW9mIHRpY2tzLm1pbm9yW2tleV0gPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdFx0dGlja3MubWlub3Jba2V5XSA9IHRpY2tzW2tleV07XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHR5cGVvZiB0aWNrcy5tYWpvcltrZXldID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHRcdHRpY2tzLm1ham9yW2tleV0gPSB0aWNrc1trZXldO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXHRiZWZvcmVVcGRhdGU6IGZ1bmN0aW9uKCkge1xuXHRcdGhlbHBlcnMuY2FsbGJhY2sodGhpcy5vcHRpb25zLmJlZm9yZVVwZGF0ZSwgW3RoaXNdKTtcblx0fSxcblxuXHR1cGRhdGU6IGZ1bmN0aW9uKG1heFdpZHRoLCBtYXhIZWlnaHQsIG1hcmdpbnMpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciBpLCBpbGVuLCBsYWJlbHMsIGxhYmVsLCB0aWNrcywgdGljaztcblxuXHRcdC8vIFVwZGF0ZSBMaWZlY3ljbGUgLSBQcm9iYWJseSBkb24ndCB3YW50IHRvIGV2ZXIgZXh0ZW5kIG9yIG92ZXJ3cml0ZSB0aGlzIGZ1bmN0aW9uIDspXG5cdFx0bWUuYmVmb3JlVXBkYXRlKCk7XG5cblx0XHQvLyBBYnNvcmIgdGhlIG1hc3RlciBtZWFzdXJlbWVudHNcblx0XHRtZS5tYXhXaWR0aCA9IG1heFdpZHRoO1xuXHRcdG1lLm1heEhlaWdodCA9IG1heEhlaWdodDtcblx0XHRtZS5tYXJnaW5zID0gaGVscGVycy5leHRlbmQoe1xuXHRcdFx0bGVmdDogMCxcblx0XHRcdHJpZ2h0OiAwLFxuXHRcdFx0dG9wOiAwLFxuXHRcdFx0Ym90dG9tOiAwXG5cdFx0fSwgbWFyZ2lucyk7XG5cdFx0bWUubG9uZ2VzdFRleHRDYWNoZSA9IG1lLmxvbmdlc3RUZXh0Q2FjaGUgfHwge307XG5cblx0XHQvLyBEaW1lbnNpb25zXG5cdFx0bWUuYmVmb3JlU2V0RGltZW5zaW9ucygpO1xuXHRcdG1lLnNldERpbWVuc2lvbnMoKTtcblx0XHRtZS5hZnRlclNldERpbWVuc2lvbnMoKTtcblxuXHRcdC8vIERhdGEgbWluL21heFxuXHRcdG1lLmJlZm9yZURhdGFMaW1pdHMoKTtcblx0XHRtZS5kZXRlcm1pbmVEYXRhTGltaXRzKCk7XG5cdFx0bWUuYWZ0ZXJEYXRhTGltaXRzKCk7XG5cblx0XHQvLyBUaWNrcyAtIGB0aGlzLnRpY2tzYCBpcyBub3cgREVQUkVDQVRFRCFcblx0XHQvLyBJbnRlcm5hbCB0aWNrcyBhcmUgbm93IHN0b3JlZCBhcyBvYmplY3RzIGluIHRoZSBQUklWQVRFIGB0aGlzLl90aWNrc2AgbWVtYmVyXG5cdFx0Ly8gYW5kIG11c3Qgbm90IGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gb3V0c2lkZSB0aGlzIGNsYXNzLiBgdGhpcy50aWNrc2AgYmVpbmdcblx0XHQvLyBhcm91bmQgZm9yIGxvbmcgdGltZSBhbmQgbm90IG1hcmtlZCBhcyBwcml2YXRlLCB3ZSBjYW4ndCBjaGFuZ2UgaXRzIHN0cnVjdHVyZVxuXHRcdC8vIHdpdGhvdXQgdW5leHBlY3RlZCBicmVha2luZyBjaGFuZ2VzLiBJZiB5b3UgbmVlZCB0byBhY2Nlc3MgdGhlIHNjYWxlIHRpY2tzLFxuXHRcdC8vIHVzZSBzY2FsZS5nZXRUaWNrcygpIGluc3RlYWQuXG5cblx0XHRtZS5iZWZvcmVCdWlsZFRpY2tzKCk7XG5cblx0XHQvLyBOZXcgaW1wbGVtZW50YXRpb25zIHNob3VsZCByZXR1cm4gYW4gYXJyYXkgb2Ygb2JqZWN0cyBidXQgZm9yIEJBQ0tXQVJEIENPTVBBVCxcblx0XHQvLyB3ZSBzdGlsbCBzdXBwb3J0IG5vIHJldHVybiAoYHRoaXMudGlja3NgIGludGVybmFsbHkgc2V0IGJ5IGNhbGxpbmcgdGhpcyBtZXRob2QpLlxuXHRcdHRpY2tzID0gbWUuYnVpbGRUaWNrcygpIHx8IFtdO1xuXG5cdFx0bWUuYWZ0ZXJCdWlsZFRpY2tzKCk7XG5cblx0XHRtZS5iZWZvcmVUaWNrVG9MYWJlbENvbnZlcnNpb24oKTtcblxuXHRcdC8vIE5ldyBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIHJldHVybiB0aGUgZm9ybWF0dGVkIHRpY2sgbGFiZWxzIGJ1dCBmb3IgQkFDS1dBUkRcblx0XHQvLyBDT01QQVQsIHdlIHN0aWxsIHN1cHBvcnQgbm8gcmV0dXJuIChgdGhpcy50aWNrc2AgaW50ZXJuYWxseSBjaGFuZ2VkIGJ5IGNhbGxpbmdcblx0XHQvLyB0aGlzIG1ldGhvZCBhbmQgc3VwcG9zZWQgdG8gY29udGFpbiBvbmx5IHN0cmluZyB2YWx1ZXMpLlxuXHRcdGxhYmVscyA9IG1lLmNvbnZlcnRUaWNrc1RvTGFiZWxzKHRpY2tzKSB8fCBtZS50aWNrcztcblxuXHRcdG1lLmFmdGVyVGlja1RvTGFiZWxDb252ZXJzaW9uKCk7XG5cblx0XHRtZS50aWNrcyA9IGxhYmVsczsgICAvLyBCQUNLV0FSRCBDT01QQVRJQklMSVRZXG5cblx0XHQvLyBJTVBPUlRBTlQ6IGZyb20gdGhpcyBwb2ludCwgd2UgY29uc2lkZXIgdGhhdCBgdGhpcy50aWNrc2Agd2lsbCBORVZFUiBjaGFuZ2UhXG5cblx0XHQvLyBCQUNLV0FSRCBDT01QQVQ6IHN5bmNocm9uaXplIGBfdGlja3NgIHdpdGggbGFiZWxzIChzbyBwb3RlbnRpYWxseSBgdGhpcy50aWNrc2ApXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IGxhYmVscy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdGxhYmVsID0gbGFiZWxzW2ldO1xuXHRcdFx0dGljayA9IHRpY2tzW2ldO1xuXHRcdFx0aWYgKCF0aWNrKSB7XG5cdFx0XHRcdHRpY2tzLnB1c2godGljayA9IHtcblx0XHRcdFx0XHRsYWJlbDogbGFiZWwsXG5cdFx0XHRcdFx0bWFqb3I6IGZhbHNlXG5cdFx0XHRcdH0pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGljay5sYWJlbCA9IGxhYmVsO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdG1lLl90aWNrcyA9IHRpY2tzO1xuXG5cdFx0Ly8gVGljayBSb3RhdGlvblxuXHRcdG1lLmJlZm9yZUNhbGN1bGF0ZVRpY2tSb3RhdGlvbigpO1xuXHRcdG1lLmNhbGN1bGF0ZVRpY2tSb3RhdGlvbigpO1xuXHRcdG1lLmFmdGVyQ2FsY3VsYXRlVGlja1JvdGF0aW9uKCk7XG5cdFx0Ly8gRml0XG5cdFx0bWUuYmVmb3JlRml0KCk7XG5cdFx0bWUuZml0KCk7XG5cdFx0bWUuYWZ0ZXJGaXQoKTtcblx0XHQvL1xuXHRcdG1lLmFmdGVyVXBkYXRlKCk7XG5cblx0XHRyZXR1cm4gbWUubWluU2l6ZTtcblxuXHR9LFxuXHRhZnRlclVwZGF0ZTogZnVuY3Rpb24oKSB7XG5cdFx0aGVscGVycy5jYWxsYmFjayh0aGlzLm9wdGlvbnMuYWZ0ZXJVcGRhdGUsIFt0aGlzXSk7XG5cdH0sXG5cblx0Ly9cblxuXHRiZWZvcmVTZXREaW1lbnNpb25zOiBmdW5jdGlvbigpIHtcblx0XHRoZWxwZXJzLmNhbGxiYWNrKHRoaXMub3B0aW9ucy5iZWZvcmVTZXREaW1lbnNpb25zLCBbdGhpc10pO1xuXHR9LFxuXHRzZXREaW1lbnNpb25zOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdC8vIFNldCB0aGUgdW5jb25zdHJhaW5lZCBkaW1lbnNpb24gYmVmb3JlIGxhYmVsIHJvdGF0aW9uXG5cdFx0aWYgKG1lLmlzSG9yaXpvbnRhbCgpKSB7XG5cdFx0XHQvLyBSZXNldCBwb3NpdGlvbiBiZWZvcmUgY2FsY3VsYXRpbmcgcm90YXRpb25cblx0XHRcdG1lLndpZHRoID0gbWUubWF4V2lkdGg7XG5cdFx0XHRtZS5sZWZ0ID0gMDtcblx0XHRcdG1lLnJpZ2h0ID0gbWUud2lkdGg7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG1lLmhlaWdodCA9IG1lLm1heEhlaWdodDtcblxuXHRcdFx0Ly8gUmVzZXQgcG9zaXRpb24gYmVmb3JlIGNhbGN1bGF0aW5nIHJvdGF0aW9uXG5cdFx0XHRtZS50b3AgPSAwO1xuXHRcdFx0bWUuYm90dG9tID0gbWUuaGVpZ2h0O1xuXHRcdH1cblxuXHRcdC8vIFJlc2V0IHBhZGRpbmdcblx0XHRtZS5wYWRkaW5nTGVmdCA9IDA7XG5cdFx0bWUucGFkZGluZ1RvcCA9IDA7XG5cdFx0bWUucGFkZGluZ1JpZ2h0ID0gMDtcblx0XHRtZS5wYWRkaW5nQm90dG9tID0gMDtcblx0fSxcblx0YWZ0ZXJTZXREaW1lbnNpb25zOiBmdW5jdGlvbigpIHtcblx0XHRoZWxwZXJzLmNhbGxiYWNrKHRoaXMub3B0aW9ucy5hZnRlclNldERpbWVuc2lvbnMsIFt0aGlzXSk7XG5cdH0sXG5cblx0Ly8gRGF0YSBsaW1pdHNcblx0YmVmb3JlRGF0YUxpbWl0czogZnVuY3Rpb24oKSB7XG5cdFx0aGVscGVycy5jYWxsYmFjayh0aGlzLm9wdGlvbnMuYmVmb3JlRGF0YUxpbWl0cywgW3RoaXNdKTtcblx0fSxcblx0ZGV0ZXJtaW5lRGF0YUxpbWl0czogaGVscGVycy5ub29wLFxuXHRhZnRlckRhdGFMaW1pdHM6IGZ1bmN0aW9uKCkge1xuXHRcdGhlbHBlcnMuY2FsbGJhY2sodGhpcy5vcHRpb25zLmFmdGVyRGF0YUxpbWl0cywgW3RoaXNdKTtcblx0fSxcblxuXHQvL1xuXHRiZWZvcmVCdWlsZFRpY2tzOiBmdW5jdGlvbigpIHtcblx0XHRoZWxwZXJzLmNhbGxiYWNrKHRoaXMub3B0aW9ucy5iZWZvcmVCdWlsZFRpY2tzLCBbdGhpc10pO1xuXHR9LFxuXHRidWlsZFRpY2tzOiBoZWxwZXJzLm5vb3AsXG5cdGFmdGVyQnVpbGRUaWNrczogZnVuY3Rpb24oKSB7XG5cdFx0aGVscGVycy5jYWxsYmFjayh0aGlzLm9wdGlvbnMuYWZ0ZXJCdWlsZFRpY2tzLCBbdGhpc10pO1xuXHR9LFxuXG5cdGJlZm9yZVRpY2tUb0xhYmVsQ29udmVyc2lvbjogZnVuY3Rpb24oKSB7XG5cdFx0aGVscGVycy5jYWxsYmFjayh0aGlzLm9wdGlvbnMuYmVmb3JlVGlja1RvTGFiZWxDb252ZXJzaW9uLCBbdGhpc10pO1xuXHR9LFxuXHRjb252ZXJ0VGlja3NUb0xhYmVsczogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIG1lID0gdGhpcztcblx0XHQvLyBDb252ZXJ0IHRpY2tzIHRvIHN0cmluZ3Ncblx0XHR2YXIgdGlja09wdHMgPSBtZS5vcHRpb25zLnRpY2tzO1xuXHRcdG1lLnRpY2tzID0gbWUudGlja3MubWFwKHRpY2tPcHRzLnVzZXJDYWxsYmFjayB8fCB0aWNrT3B0cy5jYWxsYmFjaywgdGhpcyk7XG5cdH0sXG5cdGFmdGVyVGlja1RvTGFiZWxDb252ZXJzaW9uOiBmdW5jdGlvbigpIHtcblx0XHRoZWxwZXJzLmNhbGxiYWNrKHRoaXMub3B0aW9ucy5hZnRlclRpY2tUb0xhYmVsQ29udmVyc2lvbiwgW3RoaXNdKTtcblx0fSxcblxuXHQvL1xuXG5cdGJlZm9yZUNhbGN1bGF0ZVRpY2tSb3RhdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0aGVscGVycy5jYWxsYmFjayh0aGlzLm9wdGlvbnMuYmVmb3JlQ2FsY3VsYXRlVGlja1JvdGF0aW9uLCBbdGhpc10pO1xuXHR9LFxuXHRjYWxjdWxhdGVUaWNrUm90YXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0dmFyIGNvbnRleHQgPSBtZS5jdHg7XG5cdFx0dmFyIHRpY2tPcHRzID0gbWUub3B0aW9ucy50aWNrcztcblx0XHR2YXIgbGFiZWxzID0gbGFiZWxzRnJvbVRpY2tzKG1lLl90aWNrcyk7XG5cblx0XHQvLyBHZXQgdGhlIHdpZHRoIG9mIGVhY2ggZ3JpZCBieSBjYWxjdWxhdGluZyB0aGUgZGlmZmVyZW5jZVxuXHRcdC8vIGJldHdlZW4geCBvZmZzZXRzIGJldHdlZW4gMCBhbmQgMS5cblx0XHR2YXIgdGlja0ZvbnQgPSBwYXJzZUZvbnRPcHRpb25zKHRpY2tPcHRzKTtcblx0XHRjb250ZXh0LmZvbnQgPSB0aWNrRm9udC5mb250O1xuXG5cdFx0dmFyIGxhYmVsUm90YXRpb24gPSB0aWNrT3B0cy5taW5Sb3RhdGlvbiB8fCAwO1xuXG5cdFx0aWYgKGxhYmVscy5sZW5ndGggJiYgbWUub3B0aW9ucy5kaXNwbGF5ICYmIG1lLmlzSG9yaXpvbnRhbCgpKSB7XG5cdFx0XHR2YXIgb3JpZ2luYWxMYWJlbFdpZHRoID0gaGVscGVycy5sb25nZXN0VGV4dChjb250ZXh0LCB0aWNrRm9udC5mb250LCBsYWJlbHMsIG1lLmxvbmdlc3RUZXh0Q2FjaGUpO1xuXHRcdFx0dmFyIGxhYmVsV2lkdGggPSBvcmlnaW5hbExhYmVsV2lkdGg7XG5cdFx0XHR2YXIgY29zUm90YXRpb24sIHNpblJvdGF0aW9uO1xuXG5cdFx0XHQvLyBBbGxvdyAzIHBpeGVscyB4MiBwYWRkaW5nIGVpdGhlciBzaWRlIGZvciBsYWJlbCByZWFkYWJpbGl0eVxuXHRcdFx0dmFyIHRpY2tXaWR0aCA9IG1lLmdldFBpeGVsRm9yVGljaygxKSAtIG1lLmdldFBpeGVsRm9yVGljaygwKSAtIDY7XG5cblx0XHRcdC8vIE1heCBsYWJlbCByb3RhdGlvbiBjYW4gYmUgc2V0IG9yIGRlZmF1bHQgdG8gOTAgLSBhbHNvIGFjdCBhcyBhIGxvb3AgY291bnRlclxuXHRcdFx0d2hpbGUgKGxhYmVsV2lkdGggPiB0aWNrV2lkdGggJiYgbGFiZWxSb3RhdGlvbiA8IHRpY2tPcHRzLm1heFJvdGF0aW9uKSB7XG5cdFx0XHRcdHZhciBhbmdsZVJhZGlhbnMgPSBoZWxwZXJzLnRvUmFkaWFucyhsYWJlbFJvdGF0aW9uKTtcblx0XHRcdFx0Y29zUm90YXRpb24gPSBNYXRoLmNvcyhhbmdsZVJhZGlhbnMpO1xuXHRcdFx0XHRzaW5Sb3RhdGlvbiA9IE1hdGguc2luKGFuZ2xlUmFkaWFucyk7XG5cblx0XHRcdFx0aWYgKHNpblJvdGF0aW9uICogb3JpZ2luYWxMYWJlbFdpZHRoID4gbWUubWF4SGVpZ2h0KSB7XG5cdFx0XHRcdFx0Ly8gZ28gYmFjayBvbmUgc3RlcFxuXHRcdFx0XHRcdGxhYmVsUm90YXRpb24tLTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGxhYmVsUm90YXRpb24rKztcblx0XHRcdFx0bGFiZWxXaWR0aCA9IGNvc1JvdGF0aW9uICogb3JpZ2luYWxMYWJlbFdpZHRoO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdG1lLmxhYmVsUm90YXRpb24gPSBsYWJlbFJvdGF0aW9uO1xuXHR9LFxuXHRhZnRlckNhbGN1bGF0ZVRpY2tSb3RhdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0aGVscGVycy5jYWxsYmFjayh0aGlzLm9wdGlvbnMuYWZ0ZXJDYWxjdWxhdGVUaWNrUm90YXRpb24sIFt0aGlzXSk7XG5cdH0sXG5cblx0Ly9cblxuXHRiZWZvcmVGaXQ6IGZ1bmN0aW9uKCkge1xuXHRcdGhlbHBlcnMuY2FsbGJhY2sodGhpcy5vcHRpb25zLmJlZm9yZUZpdCwgW3RoaXNdKTtcblx0fSxcblx0Zml0OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdC8vIFJlc2V0XG5cdFx0dmFyIG1pblNpemUgPSBtZS5taW5TaXplID0ge1xuXHRcdFx0d2lkdGg6IDAsXG5cdFx0XHRoZWlnaHQ6IDBcblx0XHR9O1xuXG5cdFx0dmFyIGxhYmVscyA9IGxhYmVsc0Zyb21UaWNrcyhtZS5fdGlja3MpO1xuXG5cdFx0dmFyIG9wdHMgPSBtZS5vcHRpb25zO1xuXHRcdHZhciB0aWNrT3B0cyA9IG9wdHMudGlja3M7XG5cdFx0dmFyIHNjYWxlTGFiZWxPcHRzID0gb3B0cy5zY2FsZUxhYmVsO1xuXHRcdHZhciBncmlkTGluZU9wdHMgPSBvcHRzLmdyaWRMaW5lcztcblx0XHR2YXIgZGlzcGxheSA9IG9wdHMuZGlzcGxheTtcblx0XHR2YXIgaXNIb3Jpem9udGFsID0gbWUuaXNIb3Jpem9udGFsKCk7XG5cblx0XHR2YXIgdGlja0ZvbnQgPSBwYXJzZUZvbnRPcHRpb25zKHRpY2tPcHRzKTtcblx0XHR2YXIgdGlja01hcmtMZW5ndGggPSBvcHRzLmdyaWRMaW5lcy50aWNrTWFya0xlbmd0aDtcblxuXHRcdC8vIFdpZHRoXG5cdFx0aWYgKGlzSG9yaXpvbnRhbCkge1xuXHRcdFx0Ly8gc3VidHJhY3QgdGhlIG1hcmdpbnMgdG8gbGluZSB1cCB3aXRoIHRoZSBjaGFydEFyZWEgaWYgd2UgYXJlIGEgZnVsbCB3aWR0aCBzY2FsZVxuXHRcdFx0bWluU2l6ZS53aWR0aCA9IG1lLmlzRnVsbFdpZHRoKCkgPyBtZS5tYXhXaWR0aCAtIG1lLm1hcmdpbnMubGVmdCAtIG1lLm1hcmdpbnMucmlnaHQgOiBtZS5tYXhXaWR0aDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bWluU2l6ZS53aWR0aCA9IGRpc3BsYXkgJiYgZ3JpZExpbmVPcHRzLmRyYXdUaWNrcyA/IHRpY2tNYXJrTGVuZ3RoIDogMDtcblx0XHR9XG5cblx0XHQvLyBoZWlnaHRcblx0XHRpZiAoaXNIb3Jpem9udGFsKSB7XG5cdFx0XHRtaW5TaXplLmhlaWdodCA9IGRpc3BsYXkgJiYgZ3JpZExpbmVPcHRzLmRyYXdUaWNrcyA/IHRpY2tNYXJrTGVuZ3RoIDogMDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bWluU2l6ZS5oZWlnaHQgPSBtZS5tYXhIZWlnaHQ7IC8vIGZpbGwgYWxsIHRoZSBoZWlnaHRcblx0XHR9XG5cblx0XHQvLyBBcmUgd2Ugc2hvd2luZyBhIHRpdGxlIGZvciB0aGUgc2NhbGU/XG5cdFx0aWYgKHNjYWxlTGFiZWxPcHRzLmRpc3BsYXkgJiYgZGlzcGxheSkge1xuXHRcdFx0dmFyIHNjYWxlTGFiZWxMaW5lSGVpZ2h0ID0gcGFyc2VMaW5lSGVpZ2h0KHNjYWxlTGFiZWxPcHRzKTtcblx0XHRcdHZhciBzY2FsZUxhYmVsUGFkZGluZyA9IGhlbHBlcnMub3B0aW9ucy50b1BhZGRpbmcoc2NhbGVMYWJlbE9wdHMucGFkZGluZyk7XG5cdFx0XHR2YXIgZGVsdGFIZWlnaHQgPSBzY2FsZUxhYmVsTGluZUhlaWdodCArIHNjYWxlTGFiZWxQYWRkaW5nLmhlaWdodDtcblxuXHRcdFx0aWYgKGlzSG9yaXpvbnRhbCkge1xuXHRcdFx0XHRtaW5TaXplLmhlaWdodCArPSBkZWx0YUhlaWdodDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG1pblNpemUud2lkdGggKz0gZGVsdGFIZWlnaHQ7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRG9uJ3QgYm90aGVyIGZpdHRpbmcgdGhlIHRpY2tzIGlmIHdlIGFyZSBub3Qgc2hvd2luZyB0aGVtXG5cdFx0aWYgKHRpY2tPcHRzLmRpc3BsYXkgJiYgZGlzcGxheSkge1xuXHRcdFx0dmFyIGxhcmdlc3RUZXh0V2lkdGggPSBoZWxwZXJzLmxvbmdlc3RUZXh0KG1lLmN0eCwgdGlja0ZvbnQuZm9udCwgbGFiZWxzLCBtZS5sb25nZXN0VGV4dENhY2hlKTtcblx0XHRcdHZhciB0YWxsZXN0TGFiZWxIZWlnaHRJbkxpbmVzID0gaGVscGVycy5udW1iZXJPZkxhYmVsTGluZXMobGFiZWxzKTtcblx0XHRcdHZhciBsaW5lU3BhY2UgPSB0aWNrRm9udC5zaXplICogMC41O1xuXHRcdFx0dmFyIHRpY2tQYWRkaW5nID0gbWUub3B0aW9ucy50aWNrcy5wYWRkaW5nO1xuXG5cdFx0XHRpZiAoaXNIb3Jpem9udGFsKSB7XG5cdFx0XHRcdC8vIEEgaG9yaXpvbnRhbCBheGlzIGlzIG1vcmUgY29uc3RyYWluZWQgYnkgdGhlIGhlaWdodC5cblx0XHRcdFx0bWUubG9uZ2VzdExhYmVsV2lkdGggPSBsYXJnZXN0VGV4dFdpZHRoO1xuXG5cdFx0XHRcdHZhciBhbmdsZVJhZGlhbnMgPSBoZWxwZXJzLnRvUmFkaWFucyhtZS5sYWJlbFJvdGF0aW9uKTtcblx0XHRcdFx0dmFyIGNvc1JvdGF0aW9uID0gTWF0aC5jb3MoYW5nbGVSYWRpYW5zKTtcblx0XHRcdFx0dmFyIHNpblJvdGF0aW9uID0gTWF0aC5zaW4oYW5nbGVSYWRpYW5zKTtcblxuXHRcdFx0XHQvLyBUT0RPIC0gaW1wcm92ZSB0aGlzIGNhbGN1bGF0aW9uXG5cdFx0XHRcdHZhciBsYWJlbEhlaWdodCA9IChzaW5Sb3RhdGlvbiAqIGxhcmdlc3RUZXh0V2lkdGgpXG5cdFx0XHRcdFx0KyAodGlja0ZvbnQuc2l6ZSAqIHRhbGxlc3RMYWJlbEhlaWdodEluTGluZXMpXG5cdFx0XHRcdFx0KyAobGluZVNwYWNlICogKHRhbGxlc3RMYWJlbEhlaWdodEluTGluZXMgLSAxKSlcblx0XHRcdFx0XHQrIGxpbmVTcGFjZTsgLy8gcGFkZGluZ1xuXG5cdFx0XHRcdG1pblNpemUuaGVpZ2h0ID0gTWF0aC5taW4obWUubWF4SGVpZ2h0LCBtaW5TaXplLmhlaWdodCArIGxhYmVsSGVpZ2h0ICsgdGlja1BhZGRpbmcpO1xuXG5cdFx0XHRcdG1lLmN0eC5mb250ID0gdGlja0ZvbnQuZm9udDtcblx0XHRcdFx0dmFyIGZpcnN0TGFiZWxXaWR0aCA9IGNvbXB1dGVUZXh0U2l6ZShtZS5jdHgsIGxhYmVsc1swXSwgdGlja0ZvbnQuZm9udCk7XG5cdFx0XHRcdHZhciBsYXN0TGFiZWxXaWR0aCA9IGNvbXB1dGVUZXh0U2l6ZShtZS5jdHgsIGxhYmVsc1tsYWJlbHMubGVuZ3RoIC0gMV0sIHRpY2tGb250LmZvbnQpO1xuXG5cdFx0XHRcdC8vIEVuc3VyZSB0aGF0IG91ciB0aWNrcyBhcmUgYWx3YXlzIGluc2lkZSB0aGUgY2FudmFzLiBXaGVuIHJvdGF0ZWQsIHRpY2tzIGFyZSByaWdodCBhbGlnbmVkXG5cdFx0XHRcdC8vIHdoaWNoIG1lYW5zIHRoYXQgdGhlIHJpZ2h0IHBhZGRpbmcgaXMgZG9taW5hdGVkIGJ5IHRoZSBmb250IGhlaWdodFxuXHRcdFx0XHRpZiAobWUubGFiZWxSb3RhdGlvbiAhPT0gMCkge1xuXHRcdFx0XHRcdG1lLnBhZGRpbmdMZWZ0ID0gb3B0cy5wb3NpdGlvbiA9PT0gJ2JvdHRvbScgPyAoY29zUm90YXRpb24gKiBmaXJzdExhYmVsV2lkdGgpICsgMyA6IChjb3NSb3RhdGlvbiAqIGxpbmVTcGFjZSkgKyAzOyAvLyBhZGQgMyBweCB0byBtb3ZlIGF3YXkgZnJvbSBjYW52YXMgZWRnZXNcblx0XHRcdFx0XHRtZS5wYWRkaW5nUmlnaHQgPSBvcHRzLnBvc2l0aW9uID09PSAnYm90dG9tJyA/IChjb3NSb3RhdGlvbiAqIGxpbmVTcGFjZSkgKyAzIDogKGNvc1JvdGF0aW9uICogbGFzdExhYmVsV2lkdGgpICsgMztcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRtZS5wYWRkaW5nTGVmdCA9IGZpcnN0TGFiZWxXaWR0aCAvIDIgKyAzOyAvLyBhZGQgMyBweCB0byBtb3ZlIGF3YXkgZnJvbSBjYW52YXMgZWRnZXNcblx0XHRcdFx0XHRtZS5wYWRkaW5nUmlnaHQgPSBsYXN0TGFiZWxXaWR0aCAvIDIgKyAzO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBBIHZlcnRpY2FsIGF4aXMgaXMgbW9yZSBjb25zdHJhaW5lZCBieSB0aGUgd2lkdGguIExhYmVscyBhcmUgdGhlXG5cdFx0XHRcdC8vIGRvbWluYW50IGZhY3RvciBoZXJlLCBzbyBnZXQgdGhhdCBsZW5ndGggZmlyc3QgYW5kIGFjY291bnQgZm9yIHBhZGRpbmdcblx0XHRcdFx0aWYgKHRpY2tPcHRzLm1pcnJvcikge1xuXHRcdFx0XHRcdGxhcmdlc3RUZXh0V2lkdGggPSAwO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIHVzZSBsaW5lU3BhY2UgZm9yIGNvbnNpc3RlbmN5IHdpdGggaG9yaXpvbnRhbCBheGlzXG5cdFx0XHRcdFx0Ly8gdGlja1BhZGRpbmcgaXMgbm90IGltcGxlbWVudGVkIGZvciBob3Jpem9udGFsXG5cdFx0XHRcdFx0bGFyZ2VzdFRleHRXaWR0aCArPSB0aWNrUGFkZGluZyArIGxpbmVTcGFjZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdG1pblNpemUud2lkdGggPSBNYXRoLm1pbihtZS5tYXhXaWR0aCwgbWluU2l6ZS53aWR0aCArIGxhcmdlc3RUZXh0V2lkdGgpO1xuXG5cdFx0XHRcdG1lLnBhZGRpbmdUb3AgPSB0aWNrRm9udC5zaXplIC8gMjtcblx0XHRcdFx0bWUucGFkZGluZ0JvdHRvbSA9IHRpY2tGb250LnNpemUgLyAyO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdG1lLmhhbmRsZU1hcmdpbnMoKTtcblxuXHRcdG1lLndpZHRoID0gbWluU2l6ZS53aWR0aDtcblx0XHRtZS5oZWlnaHQgPSBtaW5TaXplLmhlaWdodDtcblx0fSxcblxuXHQvKipcblx0ICogSGFuZGxlIG1hcmdpbnMgYW5kIHBhZGRpbmcgaW50ZXJhY3Rpb25zXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRoYW5kbGVNYXJnaW5zOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdGlmIChtZS5tYXJnaW5zKSB7XG5cdFx0XHRtZS5wYWRkaW5nTGVmdCA9IE1hdGgubWF4KG1lLnBhZGRpbmdMZWZ0IC0gbWUubWFyZ2lucy5sZWZ0LCAwKTtcblx0XHRcdG1lLnBhZGRpbmdUb3AgPSBNYXRoLm1heChtZS5wYWRkaW5nVG9wIC0gbWUubWFyZ2lucy50b3AsIDApO1xuXHRcdFx0bWUucGFkZGluZ1JpZ2h0ID0gTWF0aC5tYXgobWUucGFkZGluZ1JpZ2h0IC0gbWUubWFyZ2lucy5yaWdodCwgMCk7XG5cdFx0XHRtZS5wYWRkaW5nQm90dG9tID0gTWF0aC5tYXgobWUucGFkZGluZ0JvdHRvbSAtIG1lLm1hcmdpbnMuYm90dG9tLCAwKTtcblx0XHR9XG5cdH0sXG5cblx0YWZ0ZXJGaXQ6IGZ1bmN0aW9uKCkge1xuXHRcdGhlbHBlcnMuY2FsbGJhY2sodGhpcy5vcHRpb25zLmFmdGVyRml0LCBbdGhpc10pO1xuXHR9LFxuXG5cdC8vIFNoYXJlZCBNZXRob2RzXG5cdGlzSG9yaXpvbnRhbDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMub3B0aW9ucy5wb3NpdGlvbiA9PT0gJ3RvcCcgfHwgdGhpcy5vcHRpb25zLnBvc2l0aW9uID09PSAnYm90dG9tJztcblx0fSxcblx0aXNGdWxsV2lkdGg6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiAodGhpcy5vcHRpb25zLmZ1bGxXaWR0aCk7XG5cdH0sXG5cblx0Ly8gR2V0IHRoZSBjb3JyZWN0IHZhbHVlLiBOYU4gYmFkIGlucHV0cywgSWYgdGhlIHZhbHVlIHR5cGUgaXMgb2JqZWN0IGdldCB0aGUgeCBvciB5IGJhc2VkIG9uIHdoZXRoZXIgd2UgYXJlIGhvcml6b250YWwgb3Igbm90XG5cdGdldFJpZ2h0VmFsdWU6IGZ1bmN0aW9uKHJhd1ZhbHVlKSB7XG5cdFx0Ly8gTnVsbCBhbmQgdW5kZWZpbmVkIHZhbHVlcyBmaXJzdFxuXHRcdGlmIChoZWxwZXJzLmlzTnVsbE9yVW5kZWYocmF3VmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gTmFOO1xuXHRcdH1cblx0XHQvLyBpc05hTihvYmplY3QpIHJldHVybnMgdHJ1ZSwgc28gbWFrZSBzdXJlIE5hTiBpcyBjaGVja2luZyBmb3IgYSBudW1iZXI7IERpc2NhcmQgSW5maW5pdGUgdmFsdWVzXG5cdFx0aWYgKHR5cGVvZiByYXdWYWx1ZSA9PT0gJ251bWJlcicgJiYgIWlzRmluaXRlKHJhd1ZhbHVlKSkge1xuXHRcdFx0cmV0dXJuIE5hTjtcblx0XHR9XG5cdFx0Ly8gSWYgaXQgaXMgaW4gZmFjdCBhbiBvYmplY3QsIGRpdmUgaW4gb25lIG1vcmUgbGV2ZWxcblx0XHRpZiAocmF3VmFsdWUpIHtcblx0XHRcdGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG5cdFx0XHRcdGlmIChyYXdWYWx1ZS54ICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5nZXRSaWdodFZhbHVlKHJhd1ZhbHVlLngpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2UgaWYgKHJhd1ZhbHVlLnkgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5nZXRSaWdodFZhbHVlKHJhd1ZhbHVlLnkpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFZhbHVlIGlzIGdvb2QsIHJldHVybiBpdFxuXHRcdHJldHVybiByYXdWYWx1ZTtcblx0fSxcblxuXHQvKipcblx0ICogVXNlZCB0byBnZXQgdGhlIHZhbHVlIHRvIGRpc3BsYXkgaW4gdGhlIHRvb2x0aXAgZm9yIHRoZSBkYXRhIGF0IHRoZSBnaXZlbiBpbmRleFxuXHQgKiBAcGFyYW0gaW5kZXhcblx0ICogQHBhcmFtIGRhdGFzZXRJbmRleFxuXHQgKi9cblx0Z2V0TGFiZWxGb3JJbmRleDogaGVscGVycy5ub29wLFxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBsb2NhdGlvbiBvZiB0aGUgZ2l2ZW4gZGF0YSBwb2ludC4gVmFsdWUgY2FuIGVpdGhlciBiZSBhbiBpbmRleCBvciBhIG51bWVyaWNhbCB2YWx1ZVxuXHQgKiBUaGUgY29vcmRpbmF0ZSAoMCwgMCkgaXMgYXQgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZSBjYW52YXNcblx0ICogQHBhcmFtIHZhbHVlXG5cdCAqIEBwYXJhbSBpbmRleFxuXHQgKiBAcGFyYW0gZGF0YXNldEluZGV4XG5cdCAqL1xuXHRnZXRQaXhlbEZvclZhbHVlOiBoZWxwZXJzLm5vb3AsXG5cblx0LyoqXG5cdCAqIFVzZWQgdG8gZ2V0IHRoZSBkYXRhIHZhbHVlIGZyb20gYSBnaXZlbiBwaXhlbC4gVGhpcyBpcyB0aGUgaW52ZXJzZSBvZiBnZXRQaXhlbEZvclZhbHVlXG5cdCAqIFRoZSBjb29yZGluYXRlICgwLCAwKSBpcyBhdCB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlIGNhbnZhc1xuXHQgKiBAcGFyYW0gcGl4ZWxcblx0ICovXG5cdGdldFZhbHVlRm9yUGl4ZWw6IGhlbHBlcnMubm9vcCxcblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgbG9jYXRpb24gb2YgdGhlIHRpY2sgYXQgdGhlIGdpdmVuIGluZGV4XG5cdCAqIFRoZSBjb29yZGluYXRlICgwLCAwKSBpcyBhdCB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlIGNhbnZhc1xuXHQgKi9cblx0Z2V0UGl4ZWxGb3JUaWNrOiBmdW5jdGlvbihpbmRleCkge1xuXHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0dmFyIG9mZnNldCA9IG1lLm9wdGlvbnMub2Zmc2V0O1xuXHRcdGlmIChtZS5pc0hvcml6b250YWwoKSkge1xuXHRcdFx0dmFyIGlubmVyV2lkdGggPSBtZS53aWR0aCAtIChtZS5wYWRkaW5nTGVmdCArIG1lLnBhZGRpbmdSaWdodCk7XG5cdFx0XHR2YXIgdGlja1dpZHRoID0gaW5uZXJXaWR0aCAvIE1hdGgubWF4KChtZS5fdGlja3MubGVuZ3RoIC0gKG9mZnNldCA/IDAgOiAxKSksIDEpO1xuXHRcdFx0dmFyIHBpeGVsID0gKHRpY2tXaWR0aCAqIGluZGV4KSArIG1lLnBhZGRpbmdMZWZ0O1xuXG5cdFx0XHRpZiAob2Zmc2V0KSB7XG5cdFx0XHRcdHBpeGVsICs9IHRpY2tXaWR0aCAvIDI7XG5cdFx0XHR9XG5cblx0XHRcdHZhciBmaW5hbFZhbCA9IG1lLmxlZnQgKyBNYXRoLnJvdW5kKHBpeGVsKTtcblx0XHRcdGZpbmFsVmFsICs9IG1lLmlzRnVsbFdpZHRoKCkgPyBtZS5tYXJnaW5zLmxlZnQgOiAwO1xuXHRcdFx0cmV0dXJuIGZpbmFsVmFsO1xuXHRcdH1cblx0XHR2YXIgaW5uZXJIZWlnaHQgPSBtZS5oZWlnaHQgLSAobWUucGFkZGluZ1RvcCArIG1lLnBhZGRpbmdCb3R0b20pO1xuXHRcdHJldHVybiBtZS50b3AgKyAoaW5kZXggKiAoaW5uZXJIZWlnaHQgLyAobWUuX3RpY2tzLmxlbmd0aCAtIDEpKSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFV0aWxpdHkgZm9yIGdldHRpbmcgdGhlIHBpeGVsIGxvY2F0aW9uIG9mIGEgcGVyY2VudGFnZSBvZiBzY2FsZVxuXHQgKiBUaGUgY29vcmRpbmF0ZSAoMCwgMCkgaXMgYXQgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZSBjYW52YXNcblx0ICovXG5cdGdldFBpeGVsRm9yRGVjaW1hbDogZnVuY3Rpb24oZGVjaW1hbCkge1xuXHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0aWYgKG1lLmlzSG9yaXpvbnRhbCgpKSB7XG5cdFx0XHR2YXIgaW5uZXJXaWR0aCA9IG1lLndpZHRoIC0gKG1lLnBhZGRpbmdMZWZ0ICsgbWUucGFkZGluZ1JpZ2h0KTtcblx0XHRcdHZhciB2YWx1ZU9mZnNldCA9IChpbm5lcldpZHRoICogZGVjaW1hbCkgKyBtZS5wYWRkaW5nTGVmdDtcblxuXHRcdFx0dmFyIGZpbmFsVmFsID0gbWUubGVmdCArIE1hdGgucm91bmQodmFsdWVPZmZzZXQpO1xuXHRcdFx0ZmluYWxWYWwgKz0gbWUuaXNGdWxsV2lkdGgoKSA/IG1lLm1hcmdpbnMubGVmdCA6IDA7XG5cdFx0XHRyZXR1cm4gZmluYWxWYWw7XG5cdFx0fVxuXHRcdHJldHVybiBtZS50b3AgKyAoZGVjaW1hbCAqIG1lLmhlaWdodCk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIHBpeGVsIGZvciB0aGUgbWluaW11bSBjaGFydCB2YWx1ZVxuXHQgKiBUaGUgY29vcmRpbmF0ZSAoMCwgMCkgaXMgYXQgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZSBjYW52YXNcblx0ICovXG5cdGdldEJhc2VQaXhlbDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0UGl4ZWxGb3JWYWx1ZSh0aGlzLmdldEJhc2VWYWx1ZSgpKTtcblx0fSxcblxuXHRnZXRCYXNlVmFsdWU6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0dmFyIG1pbiA9IG1lLm1pbjtcblx0XHR2YXIgbWF4ID0gbWUubWF4O1xuXG5cdFx0cmV0dXJuIG1lLmJlZ2luQXRaZXJvID8gMCA6XG5cdFx0XHRtaW4gPCAwICYmIG1heCA8IDAgPyBtYXggOlxuXHRcdFx0bWluID4gMCAmJiBtYXggPiAwID8gbWluIDpcblx0XHRcdDA7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBzdWJzZXQgb2YgdGlja3MgdG8gYmUgcGxvdHRlZCB0byBhdm9pZCBvdmVybGFwcGluZyBsYWJlbHMuXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRfYXV0b1NraXA6IGZ1bmN0aW9uKHRpY2tzKSB7XG5cdFx0dmFyIHNraXBSYXRpbztcblx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdHZhciBpc0hvcml6b250YWwgPSBtZS5pc0hvcml6b250YWwoKTtcblx0XHR2YXIgb3B0aW9uVGlja3MgPSBtZS5vcHRpb25zLnRpY2tzLm1pbm9yO1xuXHRcdHZhciB0aWNrQ291bnQgPSB0aWNrcy5sZW5ndGg7XG5cdFx0dmFyIGxhYmVsUm90YXRpb25SYWRpYW5zID0gaGVscGVycy50b1JhZGlhbnMobWUubGFiZWxSb3RhdGlvbik7XG5cdFx0dmFyIGNvc1JvdGF0aW9uID0gTWF0aC5jb3MobGFiZWxSb3RhdGlvblJhZGlhbnMpO1xuXHRcdHZhciBsb25nZXN0Um90YXRlZExhYmVsID0gbWUubG9uZ2VzdExhYmVsV2lkdGggKiBjb3NSb3RhdGlvbjtcblx0XHR2YXIgcmVzdWx0ID0gW107XG5cdFx0dmFyIGksIHRpY2ssIHNob3VsZFNraXA7XG5cblx0XHQvLyBmaWd1cmUgb3V0IHRoZSBtYXhpbXVtIG51bWJlciBvZiBncmlkbGluZXMgdG8gc2hvd1xuXHRcdHZhciBtYXhUaWNrcztcblx0XHRpZiAob3B0aW9uVGlja3MubWF4VGlja3NMaW1pdCkge1xuXHRcdFx0bWF4VGlja3MgPSBvcHRpb25UaWNrcy5tYXhUaWNrc0xpbWl0O1xuXHRcdH1cblxuXHRcdGlmIChpc0hvcml6b250YWwpIHtcblx0XHRcdHNraXBSYXRpbyA9IGZhbHNlO1xuXG5cdFx0XHRpZiAoKGxvbmdlc3RSb3RhdGVkTGFiZWwgKyBvcHRpb25UaWNrcy5hdXRvU2tpcFBhZGRpbmcpICogdGlja0NvdW50ID4gKG1lLndpZHRoIC0gKG1lLnBhZGRpbmdMZWZ0ICsgbWUucGFkZGluZ1JpZ2h0KSkpIHtcblx0XHRcdFx0c2tpcFJhdGlvID0gMSArIE1hdGguZmxvb3IoKChsb25nZXN0Um90YXRlZExhYmVsICsgb3B0aW9uVGlja3MuYXV0b1NraXBQYWRkaW5nKSAqIHRpY2tDb3VudCkgLyAobWUud2lkdGggLSAobWUucGFkZGluZ0xlZnQgKyBtZS5wYWRkaW5nUmlnaHQpKSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGlmIHRoZXkgZGVmaW5lZCBhIG1heCBudW1iZXIgb2Ygb3B0aW9uVGlja3MsXG5cdFx0XHQvLyBpbmNyZWFzZSBza2lwUmF0aW8gdW50aWwgdGhhdCBudW1iZXIgaXMgbWV0XG5cdFx0XHRpZiAobWF4VGlja3MgJiYgdGlja0NvdW50ID4gbWF4VGlja3MpIHtcblx0XHRcdFx0c2tpcFJhdGlvID0gTWF0aC5tYXgoc2tpcFJhdGlvLCBNYXRoLmZsb29yKHRpY2tDb3VudCAvIG1heFRpY2tzKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMDsgaSA8IHRpY2tDb3VudDsgaSsrKSB7XG5cdFx0XHR0aWNrID0gdGlja3NbaV07XG5cblx0XHRcdC8vIFNpbmNlIHdlIGFsd2F5cyBzaG93IHRoZSBsYXN0IHRpY2ssd2UgbmVlZCBtYXkgbmVlZCB0byBoaWRlIHRoZSBsYXN0IHNob3duIG9uZSBiZWZvcmVcblx0XHRcdHNob3VsZFNraXAgPSAoc2tpcFJhdGlvID4gMSAmJiBpICUgc2tpcFJhdGlvID4gMCkgfHwgKGkgJSBza2lwUmF0aW8gPT09IDAgJiYgaSArIHNraXBSYXRpbyA+PSB0aWNrQ291bnQpO1xuXHRcdFx0aWYgKHNob3VsZFNraXAgJiYgaSAhPT0gdGlja0NvdW50IC0gMSkge1xuXHRcdFx0XHQvLyBsZWF2ZSB0aWNrIGluIHBsYWNlIGJ1dCBtYWtlIHN1cmUgaXQncyBub3QgZGlzcGxheWVkICgjNDYzNSlcblx0XHRcdFx0ZGVsZXRlIHRpY2subGFiZWw7XG5cdFx0XHR9XG5cdFx0XHRyZXN1bHQucHVzaCh0aWNrKTtcblx0XHR9XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fSxcblxuXHQvLyBBY3R1YWxseSBkcmF3IHRoZSBzY2FsZSBvbiB0aGUgY2FudmFzXG5cdC8vIEBwYXJhbSB7cmVjdGFuZ2xlfSBjaGFydEFyZWEgOiB0aGUgYXJlYSBvZiB0aGUgY2hhcnQgdG8gZHJhdyBmdWxsIGdyaWQgbGluZXMgb25cblx0ZHJhdzogZnVuY3Rpb24oY2hhcnRBcmVhKSB7XG5cdFx0dmFyIG1lID0gdGhpcztcblx0XHR2YXIgb3B0aW9ucyA9IG1lLm9wdGlvbnM7XG5cdFx0aWYgKCFvcHRpb25zLmRpc3BsYXkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgY29udGV4dCA9IG1lLmN0eDtcblx0XHR2YXIgZ2xvYmFsRGVmYXVsdHMgPSBkZWZhdWx0cy5nbG9iYWw7XG5cdFx0dmFyIG9wdGlvblRpY2tzID0gb3B0aW9ucy50aWNrcy5taW5vcjtcblx0XHR2YXIgb3B0aW9uTWFqb3JUaWNrcyA9IG9wdGlvbnMudGlja3MubWFqb3IgfHwgb3B0aW9uVGlja3M7XG5cdFx0dmFyIGdyaWRMaW5lcyA9IG9wdGlvbnMuZ3JpZExpbmVzO1xuXHRcdHZhciBzY2FsZUxhYmVsID0gb3B0aW9ucy5zY2FsZUxhYmVsO1xuXG5cdFx0dmFyIGlzUm90YXRlZCA9IG1lLmxhYmVsUm90YXRpb24gIT09IDA7XG5cdFx0dmFyIGlzSG9yaXpvbnRhbCA9IG1lLmlzSG9yaXpvbnRhbCgpO1xuXG5cdFx0dmFyIHRpY2tzID0gb3B0aW9uVGlja3MuYXV0b1NraXAgPyBtZS5fYXV0b1NraXAobWUuZ2V0VGlja3MoKSkgOiBtZS5nZXRUaWNrcygpO1xuXHRcdHZhciB0aWNrRm9udENvbG9yID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdChvcHRpb25UaWNrcy5mb250Q29sb3IsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250Q29sb3IpO1xuXHRcdHZhciB0aWNrRm9udCA9IHBhcnNlRm9udE9wdGlvbnMob3B0aW9uVGlja3MpO1xuXHRcdHZhciBtYWpvclRpY2tGb250Q29sb3IgPSBoZWxwZXJzLnZhbHVlT3JEZWZhdWx0KG9wdGlvbk1ham9yVGlja3MuZm9udENvbG9yLCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udENvbG9yKTtcblx0XHR2YXIgbWFqb3JUaWNrRm9udCA9IHBhcnNlRm9udE9wdGlvbnMob3B0aW9uTWFqb3JUaWNrcyk7XG5cblx0XHR2YXIgdGwgPSBncmlkTGluZXMuZHJhd1RpY2tzID8gZ3JpZExpbmVzLnRpY2tNYXJrTGVuZ3RoIDogMDtcblxuXHRcdHZhciBzY2FsZUxhYmVsRm9udENvbG9yID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdChzY2FsZUxhYmVsLmZvbnRDb2xvciwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRDb2xvcik7XG5cdFx0dmFyIHNjYWxlTGFiZWxGb250ID0gcGFyc2VGb250T3B0aW9ucyhzY2FsZUxhYmVsKTtcblx0XHR2YXIgc2NhbGVMYWJlbFBhZGRpbmcgPSBoZWxwZXJzLm9wdGlvbnMudG9QYWRkaW5nKHNjYWxlTGFiZWwucGFkZGluZyk7XG5cdFx0dmFyIGxhYmVsUm90YXRpb25SYWRpYW5zID0gaGVscGVycy50b1JhZGlhbnMobWUubGFiZWxSb3RhdGlvbik7XG5cblx0XHR2YXIgaXRlbXNUb0RyYXcgPSBbXTtcblxuXHRcdHZhciBheGlzV2lkdGggPSBtZS5vcHRpb25zLmdyaWRMaW5lcy5saW5lV2lkdGg7XG5cdFx0dmFyIHhUaWNrU3RhcnQgPSBvcHRpb25zLnBvc2l0aW9uID09PSAncmlnaHQnID8gbWUubGVmdCA6IG1lLnJpZ2h0IC0gYXhpc1dpZHRoIC0gdGw7XG5cdFx0dmFyIHhUaWNrRW5kID0gb3B0aW9ucy5wb3NpdGlvbiA9PT0gJ3JpZ2h0JyA/IG1lLmxlZnQgKyB0bCA6IG1lLnJpZ2h0O1xuXHRcdHZhciB5VGlja1N0YXJ0ID0gb3B0aW9ucy5wb3NpdGlvbiA9PT0gJ2JvdHRvbScgPyBtZS50b3AgKyBheGlzV2lkdGggOiBtZS5ib3R0b20gLSB0bCAtIGF4aXNXaWR0aDtcblx0XHR2YXIgeVRpY2tFbmQgPSBvcHRpb25zLnBvc2l0aW9uID09PSAnYm90dG9tJyA/IG1lLnRvcCArIGF4aXNXaWR0aCArIHRsIDogbWUuYm90dG9tICsgYXhpc1dpZHRoO1xuXG5cdFx0aGVscGVycy5lYWNoKHRpY2tzLCBmdW5jdGlvbih0aWNrLCBpbmRleCkge1xuXHRcdFx0Ly8gYXV0b3NraXBwZXIgc2tpcHBlZCB0aGlzIHRpY2sgKCM0NjM1KVxuXHRcdFx0aWYgKGhlbHBlcnMuaXNOdWxsT3JVbmRlZih0aWNrLmxhYmVsKSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHZhciBsYWJlbCA9IHRpY2subGFiZWw7XG5cdFx0XHR2YXIgbGluZVdpZHRoLCBsaW5lQ29sb3IsIGJvcmRlckRhc2gsIGJvcmRlckRhc2hPZmZzZXQ7XG5cdFx0XHRpZiAoaW5kZXggPT09IG1lLnplcm9MaW5lSW5kZXggJiYgb3B0aW9ucy5vZmZzZXQgPT09IGdyaWRMaW5lcy5vZmZzZXRHcmlkTGluZXMpIHtcblx0XHRcdFx0Ly8gRHJhdyB0aGUgZmlyc3QgaW5kZXggc3BlY2lhbGx5XG5cdFx0XHRcdGxpbmVXaWR0aCA9IGdyaWRMaW5lcy56ZXJvTGluZVdpZHRoO1xuXHRcdFx0XHRsaW5lQ29sb3IgPSBncmlkTGluZXMuemVyb0xpbmVDb2xvcjtcblx0XHRcdFx0Ym9yZGVyRGFzaCA9IGdyaWRMaW5lcy56ZXJvTGluZUJvcmRlckRhc2g7XG5cdFx0XHRcdGJvcmRlckRhc2hPZmZzZXQgPSBncmlkTGluZXMuemVyb0xpbmVCb3JkZXJEYXNoT2Zmc2V0O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGluZVdpZHRoID0gaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZ3JpZExpbmVzLmxpbmVXaWR0aCwgaW5kZXgpO1xuXHRcdFx0XHRsaW5lQ29sb3IgPSBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdChncmlkTGluZXMuY29sb3IsIGluZGV4KTtcblx0XHRcdFx0Ym9yZGVyRGFzaCA9IGhlbHBlcnMudmFsdWVPckRlZmF1bHQoZ3JpZExpbmVzLmJvcmRlckRhc2gsIGdsb2JhbERlZmF1bHRzLmJvcmRlckRhc2gpO1xuXHRcdFx0XHRib3JkZXJEYXNoT2Zmc2V0ID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdChncmlkTGluZXMuYm9yZGVyRGFzaE9mZnNldCwgZ2xvYmFsRGVmYXVsdHMuYm9yZGVyRGFzaE9mZnNldCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbW1vbiBwcm9wZXJ0aWVzXG5cdFx0XHR2YXIgdHgxLCB0eTEsIHR4MiwgdHkyLCB4MSwgeTEsIHgyLCB5MiwgbGFiZWxYLCBsYWJlbFk7XG5cdFx0XHR2YXIgdGV4dEFsaWduID0gJ21pZGRsZSc7XG5cdFx0XHR2YXIgdGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG5cdFx0XHR2YXIgdGlja1BhZGRpbmcgPSBvcHRpb25UaWNrcy5wYWRkaW5nO1xuXG5cdFx0XHRpZiAoaXNIb3Jpem9udGFsKSB7XG5cdFx0XHRcdHZhciBsYWJlbFlPZmZzZXQgPSB0bCArIHRpY2tQYWRkaW5nO1xuXG5cdFx0XHRcdGlmIChvcHRpb25zLnBvc2l0aW9uID09PSAnYm90dG9tJykge1xuXHRcdFx0XHRcdC8vIGJvdHRvbVxuXHRcdFx0XHRcdHRleHRCYXNlbGluZSA9ICFpc1JvdGF0ZWQgPyAndG9wJyA6ICdtaWRkbGUnO1xuXHRcdFx0XHRcdHRleHRBbGlnbiA9ICFpc1JvdGF0ZWQgPyAnY2VudGVyJyA6ICdyaWdodCc7XG5cdFx0XHRcdFx0bGFiZWxZID0gbWUudG9wICsgbGFiZWxZT2Zmc2V0O1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIHRvcFxuXHRcdFx0XHRcdHRleHRCYXNlbGluZSA9ICFpc1JvdGF0ZWQgPyAnYm90dG9tJyA6ICdtaWRkbGUnO1xuXHRcdFx0XHRcdHRleHRBbGlnbiA9ICFpc1JvdGF0ZWQgPyAnY2VudGVyJyA6ICdsZWZ0Jztcblx0XHRcdFx0XHRsYWJlbFkgPSBtZS5ib3R0b20gLSBsYWJlbFlPZmZzZXQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR2YXIgeExpbmVWYWx1ZSA9IGdldExpbmVWYWx1ZShtZSwgaW5kZXgsIGdyaWRMaW5lcy5vZmZzZXRHcmlkTGluZXMgJiYgdGlja3MubGVuZ3RoID4gMSk7XG5cdFx0XHRcdGlmICh4TGluZVZhbHVlIDwgbWUubGVmdCkge1xuXHRcdFx0XHRcdGxpbmVDb2xvciA9ICdyZ2JhKDAsMCwwLDApJztcblx0XHRcdFx0fVxuXHRcdFx0XHR4TGluZVZhbHVlICs9IGhlbHBlcnMuYWxpYXNQaXhlbChsaW5lV2lkdGgpO1xuXG5cdFx0XHRcdGxhYmVsWCA9IG1lLmdldFBpeGVsRm9yVGljayhpbmRleCkgKyBvcHRpb25UaWNrcy5sYWJlbE9mZnNldDsgLy8geCB2YWx1ZXMgZm9yIG9wdGlvblRpY2tzIChuZWVkIHRvIGNvbnNpZGVyIG9mZnNldExhYmVsIG9wdGlvbilcblxuXHRcdFx0XHR0eDEgPSB0eDIgPSB4MSA9IHgyID0geExpbmVWYWx1ZTtcblx0XHRcdFx0dHkxID0geVRpY2tTdGFydDtcblx0XHRcdFx0dHkyID0geVRpY2tFbmQ7XG5cdFx0XHRcdHkxID0gY2hhcnRBcmVhLnRvcDtcblx0XHRcdFx0eTIgPSBjaGFydEFyZWEuYm90dG9tICsgYXhpc1dpZHRoO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dmFyIGlzTGVmdCA9IG9wdGlvbnMucG9zaXRpb24gPT09ICdsZWZ0Jztcblx0XHRcdFx0dmFyIGxhYmVsWE9mZnNldDtcblxuXHRcdFx0XHRpZiAob3B0aW9uVGlja3MubWlycm9yKSB7XG5cdFx0XHRcdFx0dGV4dEFsaWduID0gaXNMZWZ0ID8gJ2xlZnQnIDogJ3JpZ2h0Jztcblx0XHRcdFx0XHRsYWJlbFhPZmZzZXQgPSB0aWNrUGFkZGluZztcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0ZXh0QWxpZ24gPSBpc0xlZnQgPyAncmlnaHQnIDogJ2xlZnQnO1xuXHRcdFx0XHRcdGxhYmVsWE9mZnNldCA9IHRsICsgdGlja1BhZGRpbmc7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRsYWJlbFggPSBpc0xlZnQgPyBtZS5yaWdodCAtIGxhYmVsWE9mZnNldCA6IG1lLmxlZnQgKyBsYWJlbFhPZmZzZXQ7XG5cblx0XHRcdFx0dmFyIHlMaW5lVmFsdWUgPSBnZXRMaW5lVmFsdWUobWUsIGluZGV4LCBncmlkTGluZXMub2Zmc2V0R3JpZExpbmVzICYmIHRpY2tzLmxlbmd0aCA+IDEpO1xuXHRcdFx0XHRpZiAoeUxpbmVWYWx1ZSA8IG1lLnRvcCkge1xuXHRcdFx0XHRcdGxpbmVDb2xvciA9ICdyZ2JhKDAsMCwwLDApJztcblx0XHRcdFx0fVxuXHRcdFx0XHR5TGluZVZhbHVlICs9IGhlbHBlcnMuYWxpYXNQaXhlbChsaW5lV2lkdGgpO1xuXG5cdFx0XHRcdGxhYmVsWSA9IG1lLmdldFBpeGVsRm9yVGljayhpbmRleCkgKyBvcHRpb25UaWNrcy5sYWJlbE9mZnNldDtcblxuXHRcdFx0XHR0eDEgPSB4VGlja1N0YXJ0O1xuXHRcdFx0XHR0eDIgPSB4VGlja0VuZDtcblx0XHRcdFx0eDEgPSBjaGFydEFyZWEubGVmdDtcblx0XHRcdFx0eDIgPSBjaGFydEFyZWEucmlnaHQgKyBheGlzV2lkdGg7XG5cdFx0XHRcdHR5MSA9IHR5MiA9IHkxID0geTIgPSB5TGluZVZhbHVlO1xuXHRcdFx0fVxuXG5cdFx0XHRpdGVtc1RvRHJhdy5wdXNoKHtcblx0XHRcdFx0dHgxOiB0eDEsXG5cdFx0XHRcdHR5MTogdHkxLFxuXHRcdFx0XHR0eDI6IHR4Mixcblx0XHRcdFx0dHkyOiB0eTIsXG5cdFx0XHRcdHgxOiB4MSxcblx0XHRcdFx0eTE6IHkxLFxuXHRcdFx0XHR4MjogeDIsXG5cdFx0XHRcdHkyOiB5Mixcblx0XHRcdFx0bGFiZWxYOiBsYWJlbFgsXG5cdFx0XHRcdGxhYmVsWTogbGFiZWxZLFxuXHRcdFx0XHRnbFdpZHRoOiBsaW5lV2lkdGgsXG5cdFx0XHRcdGdsQ29sb3I6IGxpbmVDb2xvcixcblx0XHRcdFx0Z2xCb3JkZXJEYXNoOiBib3JkZXJEYXNoLFxuXHRcdFx0XHRnbEJvcmRlckRhc2hPZmZzZXQ6IGJvcmRlckRhc2hPZmZzZXQsXG5cdFx0XHRcdHJvdGF0aW9uOiAtMSAqIGxhYmVsUm90YXRpb25SYWRpYW5zLFxuXHRcdFx0XHRsYWJlbDogbGFiZWwsXG5cdFx0XHRcdG1ham9yOiB0aWNrLm1ham9yLFxuXHRcdFx0XHR0ZXh0QmFzZWxpbmU6IHRleHRCYXNlbGluZSxcblx0XHRcdFx0dGV4dEFsaWduOiB0ZXh0QWxpZ25cblx0XHRcdH0pO1xuXHRcdH0pO1xuXG5cdFx0Ly8gRHJhdyBhbGwgb2YgdGhlIHRpY2sgbGFiZWxzLCB0aWNrIG1hcmtzLCBhbmQgZ3JpZCBsaW5lcyBhdCB0aGUgY29ycmVjdCBwbGFjZXNcblx0XHRoZWxwZXJzLmVhY2goaXRlbXNUb0RyYXcsIGZ1bmN0aW9uKGl0ZW1Ub0RyYXcpIHtcblx0XHRcdGlmIChncmlkTGluZXMuZGlzcGxheSkge1xuXHRcdFx0XHRjb250ZXh0LnNhdmUoKTtcblx0XHRcdFx0Y29udGV4dC5saW5lV2lkdGggPSBpdGVtVG9EcmF3LmdsV2lkdGg7XG5cdFx0XHRcdGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBpdGVtVG9EcmF3LmdsQ29sb3I7XG5cdFx0XHRcdGlmIChjb250ZXh0LnNldExpbmVEYXNoKSB7XG5cdFx0XHRcdFx0Y29udGV4dC5zZXRMaW5lRGFzaChpdGVtVG9EcmF3LmdsQm9yZGVyRGFzaCk7XG5cdFx0XHRcdFx0Y29udGV4dC5saW5lRGFzaE9mZnNldCA9IGl0ZW1Ub0RyYXcuZ2xCb3JkZXJEYXNoT2Zmc2V0O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29udGV4dC5iZWdpblBhdGgoKTtcblxuXHRcdFx0XHRpZiAoZ3JpZExpbmVzLmRyYXdUaWNrcykge1xuXHRcdFx0XHRcdGNvbnRleHQubW92ZVRvKGl0ZW1Ub0RyYXcudHgxLCBpdGVtVG9EcmF3LnR5MSk7XG5cdFx0XHRcdFx0Y29udGV4dC5saW5lVG8oaXRlbVRvRHJhdy50eDIsIGl0ZW1Ub0RyYXcudHkyKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChncmlkTGluZXMuZHJhd09uQ2hhcnRBcmVhKSB7XG5cdFx0XHRcdFx0Y29udGV4dC5tb3ZlVG8oaXRlbVRvRHJhdy54MSwgaXRlbVRvRHJhdy55MSk7XG5cdFx0XHRcdFx0Y29udGV4dC5saW5lVG8oaXRlbVRvRHJhdy54MiwgaXRlbVRvRHJhdy55Mik7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRjb250ZXh0LnN0cm9rZSgpO1xuXHRcdFx0XHRjb250ZXh0LnJlc3RvcmUoKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKG9wdGlvblRpY2tzLmRpc3BsYXkpIHtcblx0XHRcdFx0Ly8gTWFrZSBzdXJlIHdlIGRyYXcgdGV4dCBpbiB0aGUgY29ycmVjdCBjb2xvciBhbmQgZm9udFxuXHRcdFx0XHRjb250ZXh0LnNhdmUoKTtcblx0XHRcdFx0Y29udGV4dC50cmFuc2xhdGUoaXRlbVRvRHJhdy5sYWJlbFgsIGl0ZW1Ub0RyYXcubGFiZWxZKTtcblx0XHRcdFx0Y29udGV4dC5yb3RhdGUoaXRlbVRvRHJhdy5yb3RhdGlvbik7XG5cdFx0XHRcdGNvbnRleHQuZm9udCA9IGl0ZW1Ub0RyYXcubWFqb3IgPyBtYWpvclRpY2tGb250LmZvbnQgOiB0aWNrRm9udC5mb250O1xuXHRcdFx0XHRjb250ZXh0LmZpbGxTdHlsZSA9IGl0ZW1Ub0RyYXcubWFqb3IgPyBtYWpvclRpY2tGb250Q29sb3IgOiB0aWNrRm9udENvbG9yO1xuXHRcdFx0XHRjb250ZXh0LnRleHRCYXNlbGluZSA9IGl0ZW1Ub0RyYXcudGV4dEJhc2VsaW5lO1xuXHRcdFx0XHRjb250ZXh0LnRleHRBbGlnbiA9IGl0ZW1Ub0RyYXcudGV4dEFsaWduO1xuXG5cdFx0XHRcdHZhciBsYWJlbCA9IGl0ZW1Ub0RyYXcubGFiZWw7XG5cdFx0XHRcdGlmIChoZWxwZXJzLmlzQXJyYXkobGFiZWwpKSB7XG5cdFx0XHRcdFx0dmFyIGxpbmVDb3VudCA9IGxhYmVsLmxlbmd0aDtcblx0XHRcdFx0XHR2YXIgbGluZUhlaWdodCA9IHRpY2tGb250LnNpemUgKiAxLjU7XG5cdFx0XHRcdFx0dmFyIHkgPSBtZS5pc0hvcml6b250YWwoKSA/IDAgOiAtbGluZUhlaWdodCAqIChsaW5lQ291bnQgLSAxKSAvIDI7XG5cblx0XHRcdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVDb3VudDsgKytpKSB7XG5cdFx0XHRcdFx0XHQvLyBXZSBqdXN0IG1ha2Ugc3VyZSB0aGUgbXVsdGlsaW5lIGVsZW1lbnQgaXMgYSBzdHJpbmcgaGVyZS4uXG5cdFx0XHRcdFx0XHRjb250ZXh0LmZpbGxUZXh0KCcnICsgbGFiZWxbaV0sIDAsIHkpO1xuXHRcdFx0XHRcdFx0Ly8gYXBwbHkgc2FtZSBsaW5lU3BhY2luZyBhcyBjYWxjdWxhdGVkIEAgTCMzMjBcblx0XHRcdFx0XHRcdHkgKz0gbGluZUhlaWdodDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y29udGV4dC5maWxsVGV4dChsYWJlbCwgMCwgMCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y29udGV4dC5yZXN0b3JlKCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRpZiAoc2NhbGVMYWJlbC5kaXNwbGF5KSB7XG5cdFx0XHQvLyBEcmF3IHRoZSBzY2FsZSBsYWJlbFxuXHRcdFx0dmFyIHNjYWxlTGFiZWxYO1xuXHRcdFx0dmFyIHNjYWxlTGFiZWxZO1xuXHRcdFx0dmFyIHJvdGF0aW9uID0gMDtcblx0XHRcdHZhciBoYWxmTGluZUhlaWdodCA9IHBhcnNlTGluZUhlaWdodChzY2FsZUxhYmVsKSAvIDI7XG5cblx0XHRcdGlmIChpc0hvcml6b250YWwpIHtcblx0XHRcdFx0c2NhbGVMYWJlbFggPSBtZS5sZWZ0ICsgKChtZS5yaWdodCAtIG1lLmxlZnQpIC8gMik7IC8vIG1pZHBvaW50IG9mIHRoZSB3aWR0aFxuXHRcdFx0XHRzY2FsZUxhYmVsWSA9IG9wdGlvbnMucG9zaXRpb24gPT09ICdib3R0b20nXG5cdFx0XHRcdFx0PyBtZS5ib3R0b20gLSBoYWxmTGluZUhlaWdodCAtIHNjYWxlTGFiZWxQYWRkaW5nLmJvdHRvbVxuXHRcdFx0XHRcdDogbWUudG9wICsgaGFsZkxpbmVIZWlnaHQgKyBzY2FsZUxhYmVsUGFkZGluZy50b3A7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR2YXIgaXNMZWZ0ID0gb3B0aW9ucy5wb3NpdGlvbiA9PT0gJ2xlZnQnO1xuXHRcdFx0XHRzY2FsZUxhYmVsWCA9IGlzTGVmdFxuXHRcdFx0XHRcdD8gbWUubGVmdCArIGhhbGZMaW5lSGVpZ2h0ICsgc2NhbGVMYWJlbFBhZGRpbmcudG9wXG5cdFx0XHRcdFx0OiBtZS5yaWdodCAtIGhhbGZMaW5lSGVpZ2h0IC0gc2NhbGVMYWJlbFBhZGRpbmcudG9wO1xuXHRcdFx0XHRzY2FsZUxhYmVsWSA9IG1lLnRvcCArICgobWUuYm90dG9tIC0gbWUudG9wKSAvIDIpO1xuXHRcdFx0XHRyb3RhdGlvbiA9IGlzTGVmdCA/IC0wLjUgKiBNYXRoLlBJIDogMC41ICogTWF0aC5QSTtcblx0XHRcdH1cblxuXHRcdFx0Y29udGV4dC5zYXZlKCk7XG5cdFx0XHRjb250ZXh0LnRyYW5zbGF0ZShzY2FsZUxhYmVsWCwgc2NhbGVMYWJlbFkpO1xuXHRcdFx0Y29udGV4dC5yb3RhdGUocm90YXRpb24pO1xuXHRcdFx0Y29udGV4dC50ZXh0QWxpZ24gPSAnY2VudGVyJztcblx0XHRcdGNvbnRleHQudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG5cdFx0XHRjb250ZXh0LmZpbGxTdHlsZSA9IHNjYWxlTGFiZWxGb250Q29sb3I7IC8vIHJlbmRlciBpbiBjb3JyZWN0IGNvbG91clxuXHRcdFx0Y29udGV4dC5mb250ID0gc2NhbGVMYWJlbEZvbnQuZm9udDtcblx0XHRcdGNvbnRleHQuZmlsbFRleHQoc2NhbGVMYWJlbC5sYWJlbFN0cmluZywgMCwgMCk7XG5cdFx0XHRjb250ZXh0LnJlc3RvcmUoKTtcblx0XHR9XG5cblx0XHRpZiAoZ3JpZExpbmVzLmRyYXdCb3JkZXIpIHtcblx0XHRcdC8vIERyYXcgdGhlIGxpbmUgYXQgdGhlIGVkZ2Ugb2YgdGhlIGF4aXNcblx0XHRcdGNvbnRleHQubGluZVdpZHRoID0gaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZ3JpZExpbmVzLmxpbmVXaWR0aCwgMCk7XG5cdFx0XHRjb250ZXh0LnN0cm9rZVN0eWxlID0gaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZ3JpZExpbmVzLmNvbG9yLCAwKTtcblx0XHRcdHZhciB4MSA9IG1lLmxlZnQ7XG5cdFx0XHR2YXIgeDIgPSBtZS5yaWdodCArIGF4aXNXaWR0aDtcblx0XHRcdHZhciB5MSA9IG1lLnRvcDtcblx0XHRcdHZhciB5MiA9IG1lLmJvdHRvbSArIGF4aXNXaWR0aDtcblxuXHRcdFx0dmFyIGFsaWFzUGl4ZWwgPSBoZWxwZXJzLmFsaWFzUGl4ZWwoY29udGV4dC5saW5lV2lkdGgpO1xuXHRcdFx0aWYgKGlzSG9yaXpvbnRhbCkge1xuXHRcdFx0XHR5MSA9IHkyID0gb3B0aW9ucy5wb3NpdGlvbiA9PT0gJ3RvcCcgPyBtZS5ib3R0b20gOiBtZS50b3A7XG5cdFx0XHRcdHkxICs9IGFsaWFzUGl4ZWw7XG5cdFx0XHRcdHkyICs9IGFsaWFzUGl4ZWw7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR4MSA9IHgyID0gb3B0aW9ucy5wb3NpdGlvbiA9PT0gJ2xlZnQnID8gbWUucmlnaHQgOiBtZS5sZWZ0O1xuXHRcdFx0XHR4MSArPSBhbGlhc1BpeGVsO1xuXHRcdFx0XHR4MiArPSBhbGlhc1BpeGVsO1xuXHRcdFx0fVxuXG5cdFx0XHRjb250ZXh0LmJlZ2luUGF0aCgpO1xuXHRcdFx0Y29udGV4dC5tb3ZlVG8oeDEsIHkxKTtcblx0XHRcdGNvbnRleHQubGluZVRvKHgyLCB5Mik7XG5cdFx0XHRjb250ZXh0LnN0cm9rZSgpO1xuXHRcdH1cblx0fVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///d1b4\n")},db1a:function(module,exports,__webpack_require__){"use strict";eval("/**\n * Chart.Platform implementation for targeting a web browser\n */\n\n\n\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\nvar EXPANDO_KEY = '$chartjs';\nvar CSS_PREFIX = 'chartjs-';\nvar CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor';\nvar CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation';\nvar ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart'];\n\n/**\n * DOM event types -> Chart.js event types.\n * Note: only events with different types are mapped.\n * @see https://developer.mozilla.org/en-US/docs/Web/Events\n */\nvar EVENT_TYPES = {\n\ttouchstart: 'mousedown',\n\ttouchmove: 'mousemove',\n\ttouchend: 'mouseup',\n\tpointerenter: 'mouseenter',\n\tpointerdown: 'mousedown',\n\tpointermove: 'mousemove',\n\tpointerup: 'mouseup',\n\tpointerleave: 'mouseout',\n\tpointerout: 'mouseout'\n};\n\n/**\n * The \"used\" size is the final value of a dimension property after all calculations have\n * been performed. This method uses the computed style of `element` but returns undefined\n * if the computed style is not expressed in pixels. That can happen in some cases where\n * `element` has a size relative to its parent and this last one is not yet displayed,\n * for example because of `display: none` on a parent node.\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value\n * @returns {Number} Size in pixels or undefined if unknown.\n */\nfunction readUsedSize(element, property) {\n\tvar value = helpers.getStyle(element, property);\n\tvar matches = value && value.match(/^(\\d+)(\\.\\d+)?px$/);\n\treturn matches ? Number(matches[1]) : undefined;\n}\n\n/**\n * Initializes the canvas style and render size without modifying the canvas display size,\n * since responsiveness is handled by the controller.resize() method. The config is used\n * to determine the aspect ratio to apply in case no explicit height has been specified.\n */\nfunction initCanvas(canvas, config) {\n\tvar style = canvas.style;\n\n\t// NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it\n\t// returns null or '' if no explicit value has been set to the canvas attribute.\n\tvar renderHeight = canvas.getAttribute('height');\n\tvar renderWidth = canvas.getAttribute('width');\n\n\t// Chart.js modifies some canvas values that we want to restore on destroy\n\tcanvas[EXPANDO_KEY] = {\n\t\tinitial: {\n\t\t\theight: renderHeight,\n\t\t\twidth: renderWidth,\n\t\t\tstyle: {\n\t\t\t\tdisplay: style.display,\n\t\t\t\theight: style.height,\n\t\t\t\twidth: style.width\n\t\t\t}\n\t\t}\n\t};\n\n\t// Force canvas to display as block to avoid extra space caused by inline\n\t// elements, which would interfere with the responsive resize process.\n\t// https://github.com/chartjs/Chart.js/issues/2538\n\tstyle.display = style.display || 'block';\n\n\tif (renderWidth === null || renderWidth === '') {\n\t\tvar displayWidth = readUsedSize(canvas, 'width');\n\t\tif (displayWidth !== undefined) {\n\t\t\tcanvas.width = displayWidth;\n\t\t}\n\t}\n\n\tif (renderHeight === null || renderHeight === '') {\n\t\tif (canvas.style.height === '') {\n\t\t\t// If no explicit render height and style height, let's apply the aspect ratio,\n\t\t\t// which one can be specified by the user but also by charts as default option\n\t\t\t// (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.\n\t\t\tcanvas.height = canvas.width / (config.options.aspectRatio || 2);\n\t\t} else {\n\t\t\tvar displayHeight = readUsedSize(canvas, 'height');\n\t\t\tif (displayWidth !== undefined) {\n\t\t\t\tcanvas.height = displayHeight;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn canvas;\n}\n\n/**\n * Detects support for options object argument in addEventListener.\n * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support\n * @private\n */\nvar supportsEventListenerOptions = (function() {\n\tvar supports = false;\n\ttry {\n\t\tvar options = Object.defineProperty({}, 'passive', {\n\t\t\tget: function() {\n\t\t\t\tsupports = true;\n\t\t\t}\n\t\t});\n\t\twindow.addEventListener('e', null, options);\n\t} catch (e) {\n\t\t// continue regardless of error\n\t}\n\treturn supports;\n}());\n\n// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events.\n// https://github.com/chartjs/Chart.js/issues/4287\nvar eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false;\n\nfunction addEventListener(node, type, listener) {\n\tnode.addEventListener(type, listener, eventListenerOptions);\n}\n\nfunction removeEventListener(node, type, listener) {\n\tnode.removeEventListener(type, listener, eventListenerOptions);\n}\n\nfunction createEvent(type, chart, x, y, nativeEvent) {\n\treturn {\n\t\ttype: type,\n\t\tchart: chart,\n\t\tnative: nativeEvent || null,\n\t\tx: x !== undefined ? x : null,\n\t\ty: y !== undefined ? y : null,\n\t};\n}\n\nfunction fromNativeEvent(event, chart) {\n\tvar type = EVENT_TYPES[event.type] || event.type;\n\tvar pos = helpers.getRelativePosition(event, chart);\n\treturn createEvent(type, chart, pos.x, pos.y, event);\n}\n\nfunction throttled(fn, thisArg) {\n\tvar ticking = false;\n\tvar args = [];\n\n\treturn function() {\n\t\targs = Array.prototype.slice.call(arguments);\n\t\tthisArg = thisArg || this;\n\n\t\tif (!ticking) {\n\t\t\tticking = true;\n\t\t\thelpers.requestAnimFrame.call(window, function() {\n\t\t\t\tticking = false;\n\t\t\t\tfn.apply(thisArg, args);\n\t\t\t});\n\t\t}\n\t};\n}\n\n// Implementation based on https://github.com/marcj/css-element-queries\nfunction createResizer(handler) {\n\tvar resizer = document.createElement('div');\n\tvar cls = CSS_PREFIX + 'size-monitor';\n\tvar maxSize = 1000000;\n\tvar style =\n\t\t'position:absolute;' +\n\t\t'left:0;' +\n\t\t'top:0;' +\n\t\t'right:0;' +\n\t\t'bottom:0;' +\n\t\t'overflow:hidden;' +\n\t\t'pointer-events:none;' +\n\t\t'visibility:hidden;' +\n\t\t'z-index:-1;';\n\n\tresizer.style.cssText = style;\n\tresizer.className = cls;\n\tresizer.innerHTML =\n\t\t'<div class=\"' + cls + '-expand\" style=\"' + style + '\">' +\n\t\t\t'<div style=\"' +\n\t\t\t\t'position:absolute;' +\n\t\t\t\t'width:' + maxSize + 'px;' +\n\t\t\t\t'height:' + maxSize + 'px;' +\n\t\t\t\t'left:0;' +\n\t\t\t\t'top:0\">' +\n\t\t\t'</div>' +\n\t\t'</div>' +\n\t\t'<div class=\"' + cls + '-shrink\" style=\"' + style + '\">' +\n\t\t\t'<div style=\"' +\n\t\t\t\t'position:absolute;' +\n\t\t\t\t'width:200%;' +\n\t\t\t\t'height:200%;' +\n\t\t\t\t'left:0; ' +\n\t\t\t\t'top:0\">' +\n\t\t\t'</div>' +\n\t\t'</div>';\n\n\tvar expand = resizer.childNodes[0];\n\tvar shrink = resizer.childNodes[1];\n\n\tresizer._reset = function() {\n\t\texpand.scrollLeft = maxSize;\n\t\texpand.scrollTop = maxSize;\n\t\tshrink.scrollLeft = maxSize;\n\t\tshrink.scrollTop = maxSize;\n\t};\n\tvar onScroll = function() {\n\t\tresizer._reset();\n\t\thandler();\n\t};\n\n\taddEventListener(expand, 'scroll', onScroll.bind(expand, 'expand'));\n\taddEventListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink'));\n\n\treturn resizer;\n}\n\n// https://davidwalsh.name/detect-node-insertion\nfunction watchForRender(node, handler) {\n\tvar expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});\n\tvar proxy = expando.renderProxy = function(e) {\n\t\tif (e.animationName === CSS_RENDER_ANIMATION) {\n\t\t\thandler();\n\t\t}\n\t};\n\n\thelpers.each(ANIMATION_START_EVENTS, function(type) {\n\t\taddEventListener(node, type, proxy);\n\t});\n\n\t// #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class\n\t// is removed then added back immediately (same animation frame?). Accessing the\n\t// `offsetParent` property will force a reflow and re-evaluate the CSS animation.\n\t// https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics\n\t// https://github.com/chartjs/Chart.js/issues/4737\n\texpando.reflow = !!node.offsetParent;\n\n\tnode.classList.add(CSS_RENDER_MONITOR);\n}\n\nfunction unwatchForRender(node) {\n\tvar expando = node[EXPANDO_KEY] || {};\n\tvar proxy = expando.renderProxy;\n\n\tif (proxy) {\n\t\thelpers.each(ANIMATION_START_EVENTS, function(type) {\n\t\t\tremoveEventListener(node, type, proxy);\n\t\t});\n\n\t\tdelete expando.renderProxy;\n\t}\n\n\tnode.classList.remove(CSS_RENDER_MONITOR);\n}\n\nfunction addResizeListener(node, listener, chart) {\n\tvar expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});\n\n\t// Let's keep track of this added resizer and thus avoid DOM query when removing it.\n\tvar resizer = expando.resizer = createResizer(throttled(function() {\n\t\tif (expando.resizer) {\n\t\t\treturn listener(createEvent('resize', chart));\n\t\t}\n\t}));\n\n\t// The resizer needs to be attached to the node parent, so we first need to be\n\t// sure that `node` is attached to the DOM before injecting the resizer element.\n\twatchForRender(node, function() {\n\t\tif (expando.resizer) {\n\t\t\tvar container = node.parentNode;\n\t\t\tif (container && container !== resizer.parentNode) {\n\t\t\t\tcontainer.insertBefore(resizer, container.firstChild);\n\t\t\t}\n\n\t\t\t// The container size might have changed, let's reset the resizer state.\n\t\t\tresizer._reset();\n\t\t}\n\t});\n}\n\nfunction removeResizeListener(node) {\n\tvar expando = node[EXPANDO_KEY] || {};\n\tvar resizer = expando.resizer;\n\n\tdelete expando.resizer;\n\tunwatchForRender(node);\n\n\tif (resizer && resizer.parentNode) {\n\t\tresizer.parentNode.removeChild(resizer);\n\t}\n}\n\nfunction injectCSS(platform, css) {\n\t// http://stackoverflow.com/q/3922139\n\tvar style = platform._style || document.createElement('style');\n\tif (!platform._style) {\n\t\tplatform._style = style;\n\t\tcss = '/* Chart.js */\\n' + css;\n\t\tstyle.setAttribute('type', 'text/css');\n\t\tdocument.getElementsByTagName('head')[0].appendChild(style);\n\t}\n\n\tstyle.appendChild(document.createTextNode(css));\n}\n\nmodule.exports = {\n\t/**\n\t * This property holds whether this platform is enabled for the current environment.\n\t * Currently used by platform.js to select the proper implementation.\n\t * @private\n\t */\n\t_enabled: typeof window !== 'undefined' && typeof document !== 'undefined',\n\n\tinitialize: function() {\n\t\tvar keyframes = 'from{opacity:0.99}to{opacity:1}';\n\n\t\tinjectCSS(this,\n\t\t\t// DOM rendering detection\n\t\t\t// https://davidwalsh.name/detect-node-insertion\n\t\t\t'@-webkit-keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' +\n\t\t\t'@keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' +\n\t\t\t'.' + CSS_RENDER_MONITOR + '{' +\n\t\t\t\t'-webkit-animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' +\n\t\t\t\t'animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' +\n\t\t\t'}'\n\t\t);\n\t},\n\n\tacquireContext: function(item, config) {\n\t\tif (typeof item === 'string') {\n\t\t\titem = document.getElementById(item);\n\t\t} else if (item.length) {\n\t\t\t// Support for array based queries (such as jQuery)\n\t\t\titem = item[0];\n\t\t}\n\n\t\tif (item && item.canvas) {\n\t\t\t// Support for any object associated to a canvas (including a context2d)\n\t\t\titem = item.canvas;\n\t\t}\n\n\t\t// To prevent canvas fingerprinting, some add-ons undefine the getContext\n\t\t// method, for example: https://github.com/kkapsner/CanvasBlocker\n\t\t// https://github.com/chartjs/Chart.js/issues/2807\n\t\tvar context = item && item.getContext && item.getContext('2d');\n\n\t\t// `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is\n\t\t// inside an iframe or when running in a protected environment. We could guess the\n\t\t// types from their toString() value but let's keep things flexible and assume it's\n\t\t// a sufficient condition if the item has a context2D which has item as `canvas`.\n\t\t// https://github.com/chartjs/Chart.js/issues/3887\n\t\t// https://github.com/chartjs/Chart.js/issues/4102\n\t\t// https://github.com/chartjs/Chart.js/issues/4152\n\t\tif (context && context.canvas === item) {\n\t\t\tinitCanvas(item, config);\n\t\t\treturn context;\n\t\t}\n\n\t\treturn null;\n\t},\n\n\treleaseContext: function(context) {\n\t\tvar canvas = context.canvas;\n\t\tif (!canvas[EXPANDO_KEY]) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar initial = canvas[EXPANDO_KEY].initial;\n\t\t['height', 'width'].forEach(function(prop) {\n\t\t\tvar value = initial[prop];\n\t\t\tif (helpers.isNullOrUndef(value)) {\n\t\t\t\tcanvas.removeAttribute(prop);\n\t\t\t} else {\n\t\t\t\tcanvas.setAttribute(prop, value);\n\t\t\t}\n\t\t});\n\n\t\thelpers.each(initial.style || {}, function(value, key) {\n\t\t\tcanvas.style[key] = value;\n\t\t});\n\n\t\t// The canvas render size might have been changed (and thus the state stack discarded),\n\t\t// we can't use save() and restore() to restore the initial state. So make sure that at\n\t\t// least the canvas context is reset to the default state by setting the canvas width.\n\t\t// https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html\n\t\tcanvas.width = canvas.width;\n\n\t\tdelete canvas[EXPANDO_KEY];\n\t},\n\n\taddEventListener: function(chart, type, listener) {\n\t\tvar canvas = chart.canvas;\n\t\tif (type === 'resize') {\n\t\t\t// Note: the resize event is not supported on all browsers.\n\t\t\taddResizeListener(canvas, listener, chart);\n\t\t\treturn;\n\t\t}\n\n\t\tvar expando = listener[EXPANDO_KEY] || (listener[EXPANDO_KEY] = {});\n\t\tvar proxies = expando.proxies || (expando.proxies = {});\n\t\tvar proxy = proxies[chart.id + '_' + type] = function(event) {\n\t\t\tlistener(fromNativeEvent(event, chart));\n\t\t};\n\n\t\taddEventListener(canvas, type, proxy);\n\t},\n\n\tremoveEventListener: function(chart, type, listener) {\n\t\tvar canvas = chart.canvas;\n\t\tif (type === 'resize') {\n\t\t\t// Note: the resize event is not supported on all browsers.\n\t\t\tremoveResizeListener(canvas, listener);\n\t\t\treturn;\n\t\t}\n\n\t\tvar expando = listener[EXPANDO_KEY] || {};\n\t\tvar proxies = expando.proxies || {};\n\t\tvar proxy = proxies[chart.id + '_' + type];\n\t\tif (!proxy) {\n\t\t\treturn;\n\t\t}\n\n\t\tremoveEventListener(canvas, type, proxy);\n\t}\n};\n\n// DEPRECATIONS\n\n/**\n * Provided for backward compatibility, use EventTarget.addEventListener instead.\n * EventTarget.addEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener\n * @function Chart.helpers.addEvent\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers.addEvent = addEventListener;\n\n/**\n * Provided for backward compatibility, use EventTarget.removeEventListener instead.\n * EventTarget.removeEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener\n * @function Chart.helpers.removeEvent\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers.removeEvent = removeEventListener;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGIxYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGxhdGZvcm1zL3BsYXRmb3JtLmRvbS5qcz9hYmMxIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2hhcnQuUGxhdGZvcm0gaW1wbGVtZW50YXRpb24gZm9yIHRhcmdldGluZyBhIHdlYiBicm93c2VyXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcblxudmFyIEVYUEFORE9fS0VZID0gJyRjaGFydGpzJztcbnZhciBDU1NfUFJFRklYID0gJ2NoYXJ0anMtJztcbnZhciBDU1NfUkVOREVSX01PTklUT1IgPSBDU1NfUFJFRklYICsgJ3JlbmRlci1tb25pdG9yJztcbnZhciBDU1NfUkVOREVSX0FOSU1BVElPTiA9IENTU19QUkVGSVggKyAncmVuZGVyLWFuaW1hdGlvbic7XG52YXIgQU5JTUFUSU9OX1NUQVJUX0VWRU5UUyA9IFsnYW5pbWF0aW9uc3RhcnQnLCAnd2Via2l0QW5pbWF0aW9uU3RhcnQnXTtcblxuLyoqXG4gKiBET00gZXZlbnQgdHlwZXMgLT4gQ2hhcnQuanMgZXZlbnQgdHlwZXMuXG4gKiBOb3RlOiBvbmx5IGV2ZW50cyB3aXRoIGRpZmZlcmVudCB0eXBlcyBhcmUgbWFwcGVkLlxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9FdmVudHNcbiAqL1xudmFyIEVWRU5UX1RZUEVTID0ge1xuXHR0b3VjaHN0YXJ0OiAnbW91c2Vkb3duJyxcblx0dG91Y2htb3ZlOiAnbW91c2Vtb3ZlJyxcblx0dG91Y2hlbmQ6ICdtb3VzZXVwJyxcblx0cG9pbnRlcmVudGVyOiAnbW91c2VlbnRlcicsXG5cdHBvaW50ZXJkb3duOiAnbW91c2Vkb3duJyxcblx0cG9pbnRlcm1vdmU6ICdtb3VzZW1vdmUnLFxuXHRwb2ludGVydXA6ICdtb3VzZXVwJyxcblx0cG9pbnRlcmxlYXZlOiAnbW91c2VvdXQnLFxuXHRwb2ludGVyb3V0OiAnbW91c2VvdXQnXG59O1xuXG4vKipcbiAqIFRoZSBcInVzZWRcIiBzaXplIGlzIHRoZSBmaW5hbCB2YWx1ZSBvZiBhIGRpbWVuc2lvbiBwcm9wZXJ0eSBhZnRlciBhbGwgY2FsY3VsYXRpb25zIGhhdmVcbiAqIGJlZW4gcGVyZm9ybWVkLiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBjb21wdXRlZCBzdHlsZSBvZiBgZWxlbWVudGAgYnV0IHJldHVybnMgdW5kZWZpbmVkXG4gKiBpZiB0aGUgY29tcHV0ZWQgc3R5bGUgaXMgbm90IGV4cHJlc3NlZCBpbiBwaXhlbHMuIFRoYXQgY2FuIGhhcHBlbiBpbiBzb21lIGNhc2VzIHdoZXJlXG4gKiBgZWxlbWVudGAgaGFzIGEgc2l6ZSByZWxhdGl2ZSB0byBpdHMgcGFyZW50IGFuZCB0aGlzIGxhc3Qgb25lIGlzIG5vdCB5ZXQgZGlzcGxheWVkLFxuICogZm9yIGV4YW1wbGUgYmVjYXVzZSBvZiBgZGlzcGxheTogbm9uZWAgb24gYSBwYXJlbnQgbm9kZS5cbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL3VzZWRfdmFsdWVcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFNpemUgaW4gcGl4ZWxzIG9yIHVuZGVmaW5lZCBpZiB1bmtub3duLlxuICovXG5mdW5jdGlvbiByZWFkVXNlZFNpemUoZWxlbWVudCwgcHJvcGVydHkpIHtcblx0dmFyIHZhbHVlID0gaGVscGVycy5nZXRTdHlsZShlbGVtZW50LCBwcm9wZXJ0eSk7XG5cdHZhciBtYXRjaGVzID0gdmFsdWUgJiYgdmFsdWUubWF0Y2goL14oXFxkKykoXFwuXFxkKyk/cHgkLyk7XG5cdHJldHVybiBtYXRjaGVzID8gTnVtYmVyKG1hdGNoZXNbMV0pIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEluaXRpYWxpemVzIHRoZSBjYW52YXMgc3R5bGUgYW5kIHJlbmRlciBzaXplIHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSBjYW52YXMgZGlzcGxheSBzaXplLFxuICogc2luY2UgcmVzcG9uc2l2ZW5lc3MgaXMgaGFuZGxlZCBieSB0aGUgY29udHJvbGxlci5yZXNpemUoKSBtZXRob2QuIFRoZSBjb25maWcgaXMgdXNlZFxuICogdG8gZGV0ZXJtaW5lIHRoZSBhc3BlY3QgcmF0aW8gdG8gYXBwbHkgaW4gY2FzZSBubyBleHBsaWNpdCBoZWlnaHQgaGFzIGJlZW4gc3BlY2lmaWVkLlxuICovXG5mdW5jdGlvbiBpbml0Q2FudmFzKGNhbnZhcywgY29uZmlnKSB7XG5cdHZhciBzdHlsZSA9IGNhbnZhcy5zdHlsZTtcblxuXHQvLyBOT1RFKFNCKSBjYW52YXMuZ2V0QXR0cmlidXRlKCd3aWR0aCcpICE9PSBjYW52YXMud2lkdGg6IGluIHRoZSBmaXJzdCBjYXNlIGl0XG5cdC8vIHJldHVybnMgbnVsbCBvciAnJyBpZiBubyBleHBsaWNpdCB2YWx1ZSBoYXMgYmVlbiBzZXQgdG8gdGhlIGNhbnZhcyBhdHRyaWJ1dGUuXG5cdHZhciByZW5kZXJIZWlnaHQgPSBjYW52YXMuZ2V0QXR0cmlidXRlKCdoZWlnaHQnKTtcblx0dmFyIHJlbmRlcldpZHRoID0gY2FudmFzLmdldEF0dHJpYnV0ZSgnd2lkdGgnKTtcblxuXHQvLyBDaGFydC5qcyBtb2RpZmllcyBzb21lIGNhbnZhcyB2YWx1ZXMgdGhhdCB3ZSB3YW50IHRvIHJlc3RvcmUgb24gZGVzdHJveVxuXHRjYW52YXNbRVhQQU5ET19LRVldID0ge1xuXHRcdGluaXRpYWw6IHtcblx0XHRcdGhlaWdodDogcmVuZGVySGVpZ2h0LFxuXHRcdFx0d2lkdGg6IHJlbmRlcldpZHRoLFxuXHRcdFx0c3R5bGU6IHtcblx0XHRcdFx0ZGlzcGxheTogc3R5bGUuZGlzcGxheSxcblx0XHRcdFx0aGVpZ2h0OiBzdHlsZS5oZWlnaHQsXG5cdFx0XHRcdHdpZHRoOiBzdHlsZS53aWR0aFxuXHRcdFx0fVxuXHRcdH1cblx0fTtcblxuXHQvLyBGb3JjZSBjYW52YXMgdG8gZGlzcGxheSBhcyBibG9jayB0byBhdm9pZCBleHRyYSBzcGFjZSBjYXVzZWQgYnkgaW5saW5lXG5cdC8vIGVsZW1lbnRzLCB3aGljaCB3b3VsZCBpbnRlcmZlcmUgd2l0aCB0aGUgcmVzcG9uc2l2ZSByZXNpemUgcHJvY2Vzcy5cblx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzI1Mzhcblx0c3R5bGUuZGlzcGxheSA9IHN0eWxlLmRpc3BsYXkgfHwgJ2Jsb2NrJztcblxuXHRpZiAocmVuZGVyV2lkdGggPT09IG51bGwgfHwgcmVuZGVyV2lkdGggPT09ICcnKSB7XG5cdFx0dmFyIGRpc3BsYXlXaWR0aCA9IHJlYWRVc2VkU2l6ZShjYW52YXMsICd3aWR0aCcpO1xuXHRcdGlmIChkaXNwbGF5V2lkdGggIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0Y2FudmFzLndpZHRoID0gZGlzcGxheVdpZHRoO1xuXHRcdH1cblx0fVxuXG5cdGlmIChyZW5kZXJIZWlnaHQgPT09IG51bGwgfHwgcmVuZGVySGVpZ2h0ID09PSAnJykge1xuXHRcdGlmIChjYW52YXMuc3R5bGUuaGVpZ2h0ID09PSAnJykge1xuXHRcdFx0Ly8gSWYgbm8gZXhwbGljaXQgcmVuZGVyIGhlaWdodCBhbmQgc3R5bGUgaGVpZ2h0LCBsZXQncyBhcHBseSB0aGUgYXNwZWN0IHJhdGlvLFxuXHRcdFx0Ly8gd2hpY2ggb25lIGNhbiBiZSBzcGVjaWZpZWQgYnkgdGhlIHVzZXIgYnV0IGFsc28gYnkgY2hhcnRzIGFzIGRlZmF1bHQgb3B0aW9uXG5cdFx0XHQvLyAoaS5lLiBvcHRpb25zLmFzcGVjdFJhdGlvKS4gSWYgbm90IHNwZWNpZmllZCwgdXNlIGNhbnZhcyBhc3BlY3QgcmF0aW8gb2YgMi5cblx0XHRcdGNhbnZhcy5oZWlnaHQgPSBjYW52YXMud2lkdGggLyAoY29uZmlnLm9wdGlvbnMuYXNwZWN0UmF0aW8gfHwgMik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHZhciBkaXNwbGF5SGVpZ2h0ID0gcmVhZFVzZWRTaXplKGNhbnZhcywgJ2hlaWdodCcpO1xuXHRcdFx0aWYgKGRpc3BsYXlXaWR0aCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdGNhbnZhcy5oZWlnaHQgPSBkaXNwbGF5SGVpZ2h0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBjYW52YXM7XG59XG5cbi8qKlxuICogRGV0ZWN0cyBzdXBwb3J0IGZvciBvcHRpb25zIG9iamVjdCBhcmd1bWVudCBpbiBhZGRFdmVudExpc3RlbmVyLlxuICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0V2ZW50VGFyZ2V0L2FkZEV2ZW50TGlzdGVuZXIjU2FmZWx5X2RldGVjdGluZ19vcHRpb25fc3VwcG9ydFxuICogQHByaXZhdGVcbiAqL1xudmFyIHN1cHBvcnRzRXZlbnRMaXN0ZW5lck9wdGlvbnMgPSAoZnVuY3Rpb24oKSB7XG5cdHZhciBzdXBwb3J0cyA9IGZhbHNlO1xuXHR0cnkge1xuXHRcdHZhciBvcHRpb25zID0gT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAncGFzc2l2ZScsIHtcblx0XHRcdGdldDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHN1cHBvcnRzID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignZScsIG51bGwsIG9wdGlvbnMpO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gY29udGludWUgcmVnYXJkbGVzcyBvZiBlcnJvclxuXHR9XG5cdHJldHVybiBzdXBwb3J0cztcbn0oKSk7XG5cbi8vIERlZmF1bHQgcGFzc2l2ZSB0byB0cnVlIGFzIGV4cGVjdGVkIGJ5IENocm9tZSBmb3IgJ3RvdWNoc3RhcnQnIGFuZCAndG91Y2hlbmQnIGV2ZW50cy5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy80Mjg3XG52YXIgZXZlbnRMaXN0ZW5lck9wdGlvbnMgPSBzdXBwb3J0c0V2ZW50TGlzdGVuZXJPcHRpb25zID8ge3Bhc3NpdmU6IHRydWV9IDogZmFsc2U7XG5cbmZ1bmN0aW9uIGFkZEV2ZW50TGlzdGVuZXIobm9kZSwgdHlwZSwgbGlzdGVuZXIpIHtcblx0bm9kZS5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCBldmVudExpc3RlbmVyT3B0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUV2ZW50TGlzdGVuZXIobm9kZSwgdHlwZSwgbGlzdGVuZXIpIHtcblx0bm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCBldmVudExpc3RlbmVyT3B0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUV2ZW50KHR5cGUsIGNoYXJ0LCB4LCB5LCBuYXRpdmVFdmVudCkge1xuXHRyZXR1cm4ge1xuXHRcdHR5cGU6IHR5cGUsXG5cdFx0Y2hhcnQ6IGNoYXJ0LFxuXHRcdG5hdGl2ZTogbmF0aXZlRXZlbnQgfHwgbnVsbCxcblx0XHR4OiB4ICE9PSB1bmRlZmluZWQgPyB4IDogbnVsbCxcblx0XHR5OiB5ICE9PSB1bmRlZmluZWQgPyB5IDogbnVsbCxcblx0fTtcbn1cblxuZnVuY3Rpb24gZnJvbU5hdGl2ZUV2ZW50KGV2ZW50LCBjaGFydCkge1xuXHR2YXIgdHlwZSA9IEVWRU5UX1RZUEVTW2V2ZW50LnR5cGVdIHx8IGV2ZW50LnR5cGU7XG5cdHZhciBwb3MgPSBoZWxwZXJzLmdldFJlbGF0aXZlUG9zaXRpb24oZXZlbnQsIGNoYXJ0KTtcblx0cmV0dXJuIGNyZWF0ZUV2ZW50KHR5cGUsIGNoYXJ0LCBwb3MueCwgcG9zLnksIGV2ZW50KTtcbn1cblxuZnVuY3Rpb24gdGhyb3R0bGVkKGZuLCB0aGlzQXJnKSB7XG5cdHZhciB0aWNraW5nID0gZmFsc2U7XG5cdHZhciBhcmdzID0gW107XG5cblx0cmV0dXJuIGZ1bmN0aW9uKCkge1xuXHRcdGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXHRcdHRoaXNBcmcgPSB0aGlzQXJnIHx8IHRoaXM7XG5cblx0XHRpZiAoIXRpY2tpbmcpIHtcblx0XHRcdHRpY2tpbmcgPSB0cnVlO1xuXHRcdFx0aGVscGVycy5yZXF1ZXN0QW5pbUZyYW1lLmNhbGwod2luZG93LCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dGlja2luZyA9IGZhbHNlO1xuXHRcdFx0XHRmbi5hcHBseSh0aGlzQXJnLCBhcmdzKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fTtcbn1cblxuLy8gSW1wbGVtZW50YXRpb24gYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL21hcmNqL2Nzcy1lbGVtZW50LXF1ZXJpZXNcbmZ1bmN0aW9uIGNyZWF0ZVJlc2l6ZXIoaGFuZGxlcikge1xuXHR2YXIgcmVzaXplciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHR2YXIgY2xzID0gQ1NTX1BSRUZJWCArICdzaXplLW1vbml0b3InO1xuXHR2YXIgbWF4U2l6ZSA9IDEwMDAwMDA7XG5cdHZhciBzdHlsZSA9XG5cdFx0J3Bvc2l0aW9uOmFic29sdXRlOycgK1xuXHRcdCdsZWZ0OjA7JyArXG5cdFx0J3RvcDowOycgK1xuXHRcdCdyaWdodDowOycgK1xuXHRcdCdib3R0b206MDsnICtcblx0XHQnb3ZlcmZsb3c6aGlkZGVuOycgK1xuXHRcdCdwb2ludGVyLWV2ZW50czpub25lOycgK1xuXHRcdCd2aXNpYmlsaXR5OmhpZGRlbjsnICtcblx0XHQnei1pbmRleDotMTsnO1xuXG5cdHJlc2l6ZXIuc3R5bGUuY3NzVGV4dCA9IHN0eWxlO1xuXHRyZXNpemVyLmNsYXNzTmFtZSA9IGNscztcblx0cmVzaXplci5pbm5lckhUTUwgPVxuXHRcdCc8ZGl2IGNsYXNzPVwiJyArIGNscyArICctZXhwYW5kXCIgc3R5bGU9XCInICsgc3R5bGUgKyAnXCI+JyArXG5cdFx0XHQnPGRpdiBzdHlsZT1cIicgK1xuXHRcdFx0XHQncG9zaXRpb246YWJzb2x1dGU7JyArXG5cdFx0XHRcdCd3aWR0aDonICsgbWF4U2l6ZSArICdweDsnICtcblx0XHRcdFx0J2hlaWdodDonICsgbWF4U2l6ZSArICdweDsnICtcblx0XHRcdFx0J2xlZnQ6MDsnICtcblx0XHRcdFx0J3RvcDowXCI+JyArXG5cdFx0XHQnPC9kaXY+JyArXG5cdFx0JzwvZGl2PicgK1xuXHRcdCc8ZGl2IGNsYXNzPVwiJyArIGNscyArICctc2hyaW5rXCIgc3R5bGU9XCInICsgc3R5bGUgKyAnXCI+JyArXG5cdFx0XHQnPGRpdiBzdHlsZT1cIicgK1xuXHRcdFx0XHQncG9zaXRpb246YWJzb2x1dGU7JyArXG5cdFx0XHRcdCd3aWR0aDoyMDAlOycgK1xuXHRcdFx0XHQnaGVpZ2h0OjIwMCU7JyArXG5cdFx0XHRcdCdsZWZ0OjA7ICcgK1xuXHRcdFx0XHQndG9wOjBcIj4nICtcblx0XHRcdCc8L2Rpdj4nICtcblx0XHQnPC9kaXY+JztcblxuXHR2YXIgZXhwYW5kID0gcmVzaXplci5jaGlsZE5vZGVzWzBdO1xuXHR2YXIgc2hyaW5rID0gcmVzaXplci5jaGlsZE5vZGVzWzFdO1xuXG5cdHJlc2l6ZXIuX3Jlc2V0ID0gZnVuY3Rpb24oKSB7XG5cdFx0ZXhwYW5kLnNjcm9sbExlZnQgPSBtYXhTaXplO1xuXHRcdGV4cGFuZC5zY3JvbGxUb3AgPSBtYXhTaXplO1xuXHRcdHNocmluay5zY3JvbGxMZWZ0ID0gbWF4U2l6ZTtcblx0XHRzaHJpbmsuc2Nyb2xsVG9wID0gbWF4U2l6ZTtcblx0fTtcblx0dmFyIG9uU2Nyb2xsID0gZnVuY3Rpb24oKSB7XG5cdFx0cmVzaXplci5fcmVzZXQoKTtcblx0XHRoYW5kbGVyKCk7XG5cdH07XG5cblx0YWRkRXZlbnRMaXN0ZW5lcihleHBhbmQsICdzY3JvbGwnLCBvblNjcm9sbC5iaW5kKGV4cGFuZCwgJ2V4cGFuZCcpKTtcblx0YWRkRXZlbnRMaXN0ZW5lcihzaHJpbmssICdzY3JvbGwnLCBvblNjcm9sbC5iaW5kKHNocmluaywgJ3NocmluaycpKTtcblxuXHRyZXR1cm4gcmVzaXplcjtcbn1cblxuLy8gaHR0cHM6Ly9kYXZpZHdhbHNoLm5hbWUvZGV0ZWN0LW5vZGUtaW5zZXJ0aW9uXG5mdW5jdGlvbiB3YXRjaEZvclJlbmRlcihub2RlLCBoYW5kbGVyKSB7XG5cdHZhciBleHBhbmRvID0gbm9kZVtFWFBBTkRPX0tFWV0gfHwgKG5vZGVbRVhQQU5ET19LRVldID0ge30pO1xuXHR2YXIgcHJveHkgPSBleHBhbmRvLnJlbmRlclByb3h5ID0gZnVuY3Rpb24oZSkge1xuXHRcdGlmIChlLmFuaW1hdGlvbk5hbWUgPT09IENTU19SRU5ERVJfQU5JTUFUSU9OKSB7XG5cdFx0XHRoYW5kbGVyKCk7XG5cdFx0fVxuXHR9O1xuXG5cdGhlbHBlcnMuZWFjaChBTklNQVRJT05fU1RBUlRfRVZFTlRTLCBmdW5jdGlvbih0eXBlKSB7XG5cdFx0YWRkRXZlbnRMaXN0ZW5lcihub2RlLCB0eXBlLCBwcm94eSk7XG5cdH0pO1xuXG5cdC8vICM0NzM3OiBDaHJvbWUgbWlnaHQgc2tpcCB0aGUgQ1NTIGFuaW1hdGlvbiB3aGVuIHRoZSBDU1NfUkVOREVSX01PTklUT1IgY2xhc3Ncblx0Ly8gaXMgcmVtb3ZlZCB0aGVuIGFkZGVkIGJhY2sgaW1tZWRpYXRlbHkgKHNhbWUgYW5pbWF0aW9uIGZyYW1lPykuIEFjY2Vzc2luZyB0aGVcblx0Ly8gYG9mZnNldFBhcmVudGAgcHJvcGVydHkgd2lsbCBmb3JjZSBhIHJlZmxvdyBhbmQgcmUtZXZhbHVhdGUgdGhlIENTUyBhbmltYXRpb24uXG5cdC8vIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL3BhdWxpcmlzaC81ZDUyZmIwODFiMzU3MGM4MWUzYSNib3gtbWV0cmljc1xuXHQvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvNDczN1xuXHRleHBhbmRvLnJlZmxvdyA9ICEhbm9kZS5vZmZzZXRQYXJlbnQ7XG5cblx0bm9kZS5jbGFzc0xpc3QuYWRkKENTU19SRU5ERVJfTU9OSVRPUik7XG59XG5cbmZ1bmN0aW9uIHVud2F0Y2hGb3JSZW5kZXIobm9kZSkge1xuXHR2YXIgZXhwYW5kbyA9IG5vZGVbRVhQQU5ET19LRVldIHx8IHt9O1xuXHR2YXIgcHJveHkgPSBleHBhbmRvLnJlbmRlclByb3h5O1xuXG5cdGlmIChwcm94eSkge1xuXHRcdGhlbHBlcnMuZWFjaChBTklNQVRJT05fU1RBUlRfRVZFTlRTLCBmdW5jdGlvbih0eXBlKSB7XG5cdFx0XHRyZW1vdmVFdmVudExpc3RlbmVyKG5vZGUsIHR5cGUsIHByb3h5KTtcblx0XHR9KTtcblxuXHRcdGRlbGV0ZSBleHBhbmRvLnJlbmRlclByb3h5O1xuXHR9XG5cblx0bm9kZS5jbGFzc0xpc3QucmVtb3ZlKENTU19SRU5ERVJfTU9OSVRPUik7XG59XG5cbmZ1bmN0aW9uIGFkZFJlc2l6ZUxpc3RlbmVyKG5vZGUsIGxpc3RlbmVyLCBjaGFydCkge1xuXHR2YXIgZXhwYW5kbyA9IG5vZGVbRVhQQU5ET19LRVldIHx8IChub2RlW0VYUEFORE9fS0VZXSA9IHt9KTtcblxuXHQvLyBMZXQncyBrZWVwIHRyYWNrIG9mIHRoaXMgYWRkZWQgcmVzaXplciBhbmQgdGh1cyBhdm9pZCBET00gcXVlcnkgd2hlbiByZW1vdmluZyBpdC5cblx0dmFyIHJlc2l6ZXIgPSBleHBhbmRvLnJlc2l6ZXIgPSBjcmVhdGVSZXNpemVyKHRocm90dGxlZChmdW5jdGlvbigpIHtcblx0XHRpZiAoZXhwYW5kby5yZXNpemVyKSB7XG5cdFx0XHRyZXR1cm4gbGlzdGVuZXIoY3JlYXRlRXZlbnQoJ3Jlc2l6ZScsIGNoYXJ0KSk7XG5cdFx0fVxuXHR9KSk7XG5cblx0Ly8gVGhlIHJlc2l6ZXIgbmVlZHMgdG8gYmUgYXR0YWNoZWQgdG8gdGhlIG5vZGUgcGFyZW50LCBzbyB3ZSBmaXJzdCBuZWVkIHRvIGJlXG5cdC8vIHN1cmUgdGhhdCBgbm9kZWAgaXMgYXR0YWNoZWQgdG8gdGhlIERPTSBiZWZvcmUgaW5qZWN0aW5nIHRoZSByZXNpemVyIGVsZW1lbnQuXG5cdHdhdGNoRm9yUmVuZGVyKG5vZGUsIGZ1bmN0aW9uKCkge1xuXHRcdGlmIChleHBhbmRvLnJlc2l6ZXIpIHtcblx0XHRcdHZhciBjb250YWluZXIgPSBub2RlLnBhcmVudE5vZGU7XG5cdFx0XHRpZiAoY29udGFpbmVyICYmIGNvbnRhaW5lciAhPT0gcmVzaXplci5wYXJlbnROb2RlKSB7XG5cdFx0XHRcdGNvbnRhaW5lci5pbnNlcnRCZWZvcmUocmVzaXplciwgY29udGFpbmVyLmZpcnN0Q2hpbGQpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBUaGUgY29udGFpbmVyIHNpemUgbWlnaHQgaGF2ZSBjaGFuZ2VkLCBsZXQncyByZXNldCB0aGUgcmVzaXplciBzdGF0ZS5cblx0XHRcdHJlc2l6ZXIuX3Jlc2V0KCk7XG5cdFx0fVxuXHR9KTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlUmVzaXplTGlzdGVuZXIobm9kZSkge1xuXHR2YXIgZXhwYW5kbyA9IG5vZGVbRVhQQU5ET19LRVldIHx8IHt9O1xuXHR2YXIgcmVzaXplciA9IGV4cGFuZG8ucmVzaXplcjtcblxuXHRkZWxldGUgZXhwYW5kby5yZXNpemVyO1xuXHR1bndhdGNoRm9yUmVuZGVyKG5vZGUpO1xuXG5cdGlmIChyZXNpemVyICYmIHJlc2l6ZXIucGFyZW50Tm9kZSkge1xuXHRcdHJlc2l6ZXIucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChyZXNpemVyKTtcblx0fVxufVxuXG5mdW5jdGlvbiBpbmplY3RDU1MocGxhdGZvcm0sIGNzcykge1xuXHQvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcS8zOTIyMTM5XG5cdHZhciBzdHlsZSA9IHBsYXRmb3JtLl9zdHlsZSB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuXHRpZiAoIXBsYXRmb3JtLl9zdHlsZSkge1xuXHRcdHBsYXRmb3JtLl9zdHlsZSA9IHN0eWxlO1xuXHRcdGNzcyA9ICcvKiBDaGFydC5qcyAqL1xcbicgKyBjc3M7XG5cdFx0c3R5bGUuc2V0QXR0cmlidXRlKCd0eXBlJywgJ3RleHQvY3NzJyk7XG5cdFx0ZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXS5hcHBlbmRDaGlsZChzdHlsZSk7XG5cdH1cblxuXHRzdHlsZS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShjc3MpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdC8qKlxuXHQgKiBUaGlzIHByb3BlcnR5IGhvbGRzIHdoZXRoZXIgdGhpcyBwbGF0Zm9ybSBpcyBlbmFibGVkIGZvciB0aGUgY3VycmVudCBlbnZpcm9ubWVudC5cblx0ICogQ3VycmVudGx5IHVzZWQgYnkgcGxhdGZvcm0uanMgdG8gc2VsZWN0IHRoZSBwcm9wZXIgaW1wbGVtZW50YXRpb24uXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRfZW5hYmxlZDogdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyxcblxuXHRpbml0aWFsaXplOiBmdW5jdGlvbigpIHtcblx0XHR2YXIga2V5ZnJhbWVzID0gJ2Zyb217b3BhY2l0eTowLjk5fXRve29wYWNpdHk6MX0nO1xuXG5cdFx0aW5qZWN0Q1NTKHRoaXMsXG5cdFx0XHQvLyBET00gcmVuZGVyaW5nIGRldGVjdGlvblxuXHRcdFx0Ly8gaHR0cHM6Ly9kYXZpZHdhbHNoLm5hbWUvZGV0ZWN0LW5vZGUtaW5zZXJ0aW9uXG5cdFx0XHQnQC13ZWJraXQta2V5ZnJhbWVzICcgKyBDU1NfUkVOREVSX0FOSU1BVElPTiArICd7JyArIGtleWZyYW1lcyArICd9JyArXG5cdFx0XHQnQGtleWZyYW1lcyAnICsgQ1NTX1JFTkRFUl9BTklNQVRJT04gKyAneycgKyBrZXlmcmFtZXMgKyAnfScgK1xuXHRcdFx0Jy4nICsgQ1NTX1JFTkRFUl9NT05JVE9SICsgJ3snICtcblx0XHRcdFx0Jy13ZWJraXQtYW5pbWF0aW9uOicgKyBDU1NfUkVOREVSX0FOSU1BVElPTiArICcgMC4wMDFzOycgK1xuXHRcdFx0XHQnYW5pbWF0aW9uOicgKyBDU1NfUkVOREVSX0FOSU1BVElPTiArICcgMC4wMDFzOycgK1xuXHRcdFx0J30nXG5cdFx0KTtcblx0fSxcblxuXHRhY3F1aXJlQ29udGV4dDogZnVuY3Rpb24oaXRlbSwgY29uZmlnKSB7XG5cdFx0aWYgKHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuXHRcdFx0aXRlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGl0ZW0pO1xuXHRcdH0gZWxzZSBpZiAoaXRlbS5sZW5ndGgpIHtcblx0XHRcdC8vIFN1cHBvcnQgZm9yIGFycmF5IGJhc2VkIHF1ZXJpZXMgKHN1Y2ggYXMgalF1ZXJ5KVxuXHRcdFx0aXRlbSA9IGl0ZW1bMF07XG5cdFx0fVxuXG5cdFx0aWYgKGl0ZW0gJiYgaXRlbS5jYW52YXMpIHtcblx0XHRcdC8vIFN1cHBvcnQgZm9yIGFueSBvYmplY3QgYXNzb2NpYXRlZCB0byBhIGNhbnZhcyAoaW5jbHVkaW5nIGEgY29udGV4dDJkKVxuXHRcdFx0aXRlbSA9IGl0ZW0uY2FudmFzO1xuXHRcdH1cblxuXHRcdC8vIFRvIHByZXZlbnQgY2FudmFzIGZpbmdlcnByaW50aW5nLCBzb21lIGFkZC1vbnMgdW5kZWZpbmUgdGhlIGdldENvbnRleHRcblx0XHQvLyBtZXRob2QsIGZvciBleGFtcGxlOiBodHRwczovL2dpdGh1Yi5jb20va2thcHNuZXIvQ2FudmFzQmxvY2tlclxuXHRcdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8yODA3XG5cdFx0dmFyIGNvbnRleHQgPSBpdGVtICYmIGl0ZW0uZ2V0Q29udGV4dCAmJiBpdGVtLmdldENvbnRleHQoJzJkJyk7XG5cblx0XHQvLyBgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudC9DYW52YXNSZW5kZXJpbmdDb250ZXh0MkRgIGZhaWxzIHdoZW4gdGhlIGl0ZW0gaXNcblx0XHQvLyBpbnNpZGUgYW4gaWZyYW1lIG9yIHdoZW4gcnVubmluZyBpbiBhIHByb3RlY3RlZCBlbnZpcm9ubWVudC4gV2UgY291bGQgZ3Vlc3MgdGhlXG5cdFx0Ly8gdHlwZXMgZnJvbSB0aGVpciB0b1N0cmluZygpIHZhbHVlIGJ1dCBsZXQncyBrZWVwIHRoaW5ncyBmbGV4aWJsZSBhbmQgYXNzdW1lIGl0J3Ncblx0XHQvLyBhIHN1ZmZpY2llbnQgY29uZGl0aW9uIGlmIHRoZSBpdGVtIGhhcyBhIGNvbnRleHQyRCB3aGljaCBoYXMgaXRlbSBhcyBgY2FudmFzYC5cblx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvMzg4N1xuXHRcdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy80MTAyXG5cdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzQxNTJcblx0XHRpZiAoY29udGV4dCAmJiBjb250ZXh0LmNhbnZhcyA9PT0gaXRlbSkge1xuXHRcdFx0aW5pdENhbnZhcyhpdGVtLCBjb25maWcpO1xuXHRcdFx0cmV0dXJuIGNvbnRleHQ7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG51bGw7XG5cdH0sXG5cblx0cmVsZWFzZUNvbnRleHQ6IGZ1bmN0aW9uKGNvbnRleHQpIHtcblx0XHR2YXIgY2FudmFzID0gY29udGV4dC5jYW52YXM7XG5cdFx0aWYgKCFjYW52YXNbRVhQQU5ET19LRVldKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIGluaXRpYWwgPSBjYW52YXNbRVhQQU5ET19LRVldLmluaXRpYWw7XG5cdFx0WydoZWlnaHQnLCAnd2lkdGgnXS5mb3JFYWNoKGZ1bmN0aW9uKHByb3ApIHtcblx0XHRcdHZhciB2YWx1ZSA9IGluaXRpYWxbcHJvcF07XG5cdFx0XHRpZiAoaGVscGVycy5pc051bGxPclVuZGVmKHZhbHVlKSkge1xuXHRcdFx0XHRjYW52YXMucmVtb3ZlQXR0cmlidXRlKHByb3ApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2FudmFzLnNldEF0dHJpYnV0ZShwcm9wLCB2YWx1ZSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRoZWxwZXJzLmVhY2goaW5pdGlhbC5zdHlsZSB8fCB7fSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuXHRcdFx0Y2FudmFzLnN0eWxlW2tleV0gPSB2YWx1ZTtcblx0XHR9KTtcblxuXHRcdC8vIFRoZSBjYW52YXMgcmVuZGVyIHNpemUgbWlnaHQgaGF2ZSBiZWVuIGNoYW5nZWQgKGFuZCB0aHVzIHRoZSBzdGF0ZSBzdGFjayBkaXNjYXJkZWQpLFxuXHRcdC8vIHdlIGNhbid0IHVzZSBzYXZlKCkgYW5kIHJlc3RvcmUoKSB0byByZXN0b3JlIHRoZSBpbml0aWFsIHN0YXRlLiBTbyBtYWtlIHN1cmUgdGhhdCBhdFxuXHRcdC8vIGxlYXN0IHRoZSBjYW52YXMgY29udGV4dCBpcyByZXNldCB0byB0aGUgZGVmYXVsdCBzdGF0ZSBieSBzZXR0aW5nIHRoZSBjYW52YXMgd2lkdGguXG5cdFx0Ly8gaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMTEvV0QtaHRtbDUtMjAxMTA1MjUvdGhlLWNhbnZhcy1lbGVtZW50Lmh0bWxcblx0XHRjYW52YXMud2lkdGggPSBjYW52YXMud2lkdGg7XG5cblx0XHRkZWxldGUgY2FudmFzW0VYUEFORE9fS0VZXTtcblx0fSxcblxuXHRhZGRFdmVudExpc3RlbmVyOiBmdW5jdGlvbihjaGFydCwgdHlwZSwgbGlzdGVuZXIpIHtcblx0XHR2YXIgY2FudmFzID0gY2hhcnQuY2FudmFzO1xuXHRcdGlmICh0eXBlID09PSAncmVzaXplJykge1xuXHRcdFx0Ly8gTm90ZTogdGhlIHJlc2l6ZSBldmVudCBpcyBub3Qgc3VwcG9ydGVkIG9uIGFsbCBicm93c2Vycy5cblx0XHRcdGFkZFJlc2l6ZUxpc3RlbmVyKGNhbnZhcywgbGlzdGVuZXIsIGNoYXJ0KTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgZXhwYW5kbyA9IGxpc3RlbmVyW0VYUEFORE9fS0VZXSB8fCAobGlzdGVuZXJbRVhQQU5ET19LRVldID0ge30pO1xuXHRcdHZhciBwcm94aWVzID0gZXhwYW5kby5wcm94aWVzIHx8IChleHBhbmRvLnByb3hpZXMgPSB7fSk7XG5cdFx0dmFyIHByb3h5ID0gcHJveGllc1tjaGFydC5pZCArICdfJyArIHR5cGVdID0gZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRcdGxpc3RlbmVyKGZyb21OYXRpdmVFdmVudChldmVudCwgY2hhcnQpKTtcblx0XHR9O1xuXG5cdFx0YWRkRXZlbnRMaXN0ZW5lcihjYW52YXMsIHR5cGUsIHByb3h5KTtcblx0fSxcblxuXHRyZW1vdmVFdmVudExpc3RlbmVyOiBmdW5jdGlvbihjaGFydCwgdHlwZSwgbGlzdGVuZXIpIHtcblx0XHR2YXIgY2FudmFzID0gY2hhcnQuY2FudmFzO1xuXHRcdGlmICh0eXBlID09PSAncmVzaXplJykge1xuXHRcdFx0Ly8gTm90ZTogdGhlIHJlc2l6ZSBldmVudCBpcyBub3Qgc3VwcG9ydGVkIG9uIGFsbCBicm93c2Vycy5cblx0XHRcdHJlbW92ZVJlc2l6ZUxpc3RlbmVyKGNhbnZhcywgbGlzdGVuZXIpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBleHBhbmRvID0gbGlzdGVuZXJbRVhQQU5ET19LRVldIHx8IHt9O1xuXHRcdHZhciBwcm94aWVzID0gZXhwYW5kby5wcm94aWVzIHx8IHt9O1xuXHRcdHZhciBwcm94eSA9IHByb3hpZXNbY2hhcnQuaWQgKyAnXycgKyB0eXBlXTtcblx0XHRpZiAoIXByb3h5KSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0cmVtb3ZlRXZlbnRMaXN0ZW5lcihjYW52YXMsIHR5cGUsIHByb3h5KTtcblx0fVxufTtcblxuLy8gREVQUkVDQVRJT05TXG5cbi8qKlxuICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHVzZSBFdmVudFRhcmdldC5hZGRFdmVudExpc3RlbmVyIGluc3RlYWQuXG4gKiBFdmVudFRhcmdldC5hZGRFdmVudExpc3RlbmVyIGNvbXBhdGliaWxpdHk6IENocm9tZSwgT3BlcmEgNywgU2FmYXJpLCBGRjEuNSssIElFOStcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0V2ZW50VGFyZ2V0L2FkZEV2ZW50TGlzdGVuZXJcbiAqIEBmdW5jdGlvbiBDaGFydC5oZWxwZXJzLmFkZEV2ZW50XG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNy4wXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXG4gKiBAcHJpdmF0ZVxuICovXG5oZWxwZXJzLmFkZEV2ZW50ID0gYWRkRXZlbnRMaXN0ZW5lcjtcblxuLyoqXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIEV2ZW50VGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIgaW5zdGVhZC5cbiAqIEV2ZW50VGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIgY29tcGF0aWJpbGl0eTogQ2hyb21lLCBPcGVyYSA3LCBTYWZhcmksIEZGMS41KywgSUU5K1xuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvcmVtb3ZlRXZlbnRMaXN0ZW5lclxuICogQGZ1bmN0aW9uIENoYXJ0LmhlbHBlcnMucmVtb3ZlRXZlbnRcbiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi43LjBcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcbiAqIEBwcml2YXRlXG4gKi9cbmhlbHBlcnMucmVtb3ZlRXZlbnQgPSByZW1vdmVFdmVudExpc3RlbmVyO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///db1a\n")},e866:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\nvar scaleService = __webpack_require__(/*! ../core/core.scaleService */ \"7c56\");\nvar Ticks = __webpack_require__(/*! ../core/core.ticks */ \"1220\");\n\nmodule.exports = function(Chart) {\n\n\tvar defaultConfig = {\n\t\tposition: 'left',\n\t\tticks: {\n\t\t\tcallback: Ticks.formatters.linear\n\t\t}\n\t};\n\n\tvar LinearScale = Chart.LinearScaleBase.extend({\n\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar chart = me.chart;\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tvar DEFAULT_MIN = 0;\n\t\t\tvar DEFAULT_MAX = 1;\n\n\t\t\tfunction IDMatches(meta) {\n\t\t\t\treturn isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\n\t\t\t}\n\n\t\t\t// First Calculate the range\n\t\t\tme.min = null;\n\t\t\tme.max = null;\n\n\t\t\tvar hasStacks = opts.stacked;\n\t\t\tif (hasStacks === undefined) {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tif (hasStacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&\n\t\t\t\t\t\tmeta.stack !== undefined) {\n\t\t\t\t\t\thasStacks = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (opts.stacked || hasStacks) {\n\t\t\t\tvar valuesPerStack = {};\n\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tvar key = [\n\t\t\t\t\t\tmeta.type,\n\t\t\t\t\t\t// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined\n\t\t\t\t\t\t((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),\n\t\t\t\t\t\tmeta.stack\n\t\t\t\t\t].join('.');\n\n\t\t\t\t\tif (valuesPerStack[key] === undefined) {\n\t\t\t\t\t\tvaluesPerStack[key] = {\n\t\t\t\t\t\t\tpositiveValues: [],\n\t\t\t\t\t\t\tnegativeValues: []\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Store these per type\n\t\t\t\t\tvar positiveValues = valuesPerStack[key].positiveValues;\n\t\t\t\t\tvar negativeValues = valuesPerStack[key].negativeValues;\n\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tpositiveValues[index] = positiveValues[index] || 0;\n\t\t\t\t\t\t\tnegativeValues[index] = negativeValues[index] || 0;\n\n\t\t\t\t\t\t\tif (opts.relativePoints) {\n\t\t\t\t\t\t\t\tpositiveValues[index] = 100;\n\t\t\t\t\t\t\t} else if (value < 0) {\n\t\t\t\t\t\t\t\tnegativeValues[index] += value;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tpositiveValues[index] += value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\thelpers.each(valuesPerStack, function(valuesForType) {\n\t\t\t\t\tvar values = valuesForType.positiveValues.concat(valuesForType.negativeValues);\n\t\t\t\t\tvar minVal = helpers.min(values);\n\t\t\t\t\tvar maxVal = helpers.max(values);\n\t\t\t\t\tme.min = me.min === null ? minVal : Math.min(me.min, minVal);\n\t\t\t\t\tme.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\n\t\t\t\t});\n\n\t\t\t} else {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.min === null) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t} else if (value < me.min) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.max === null) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t} else if (value > me.max) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tme.min = isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN;\n\t\t\tme.max = isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX;\n\n\t\t\t// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\n\t\t\tthis.handleTickRangeOptions();\n\t\t},\n\t\tgetTickLimit: function() {\n\t\t\tvar maxTicks;\n\t\t\tvar me = this;\n\t\t\tvar tickOpts = me.options.ticks;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tmaxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));\n\t\t\t} else {\n\t\t\t\t// The factor of 2 used to scale the font size has been experimentally determined.\n\t\t\t\tvar tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, defaults.global.defaultFontSize);\n\t\t\t\tmaxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));\n\t\t\t}\n\n\t\t\treturn maxTicks;\n\t\t},\n\t\t// Called after the ticks are built. We need\n\t\thandleDirectionalChanges: function() {\n\t\t\tif (!this.isHorizontal()) {\n\t\t\t\t// We are in a vertical orientation. The top value is the highest. So reverse the array\n\t\t\t\tthis.ticks.reverse();\n\t\t\t}\n\t\t},\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\t// Utils\n\t\tgetPixelForValue: function(value) {\n\t\t\t// This must be called after fit has been run so that\n\t\t\t// this.left, this.top, this.right, and this.bottom have been defined\n\t\t\tvar me = this;\n\t\t\tvar start = me.start;\n\n\t\t\tvar rightValue = +me.getRightValue(value);\n\t\t\tvar pixel;\n\t\t\tvar range = me.end - start;\n\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tpixel = me.left + (me.width / range * (rightValue - start));\n\t\t\t} else {\n\t\t\t\tpixel = me.bottom - (me.height / range * (rightValue - start));\n\t\t\t}\n\t\t\treturn pixel;\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tvar innerDimension = isHorizontal ? me.width : me.height;\n\t\t\tvar offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension;\n\t\t\treturn me.start + ((me.end - me.start) * offset);\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForValue(this.ticksAsNumbers[index]);\n\t\t}\n\t});\n\n\tscaleService.registerScaleType('linear', LinearScale, defaultConfig);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTg2Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvc2NhbGVzL3NjYWxlLmxpbmVhci5qcz82MTJiIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmF1bHRzID0gcmVxdWlyZSgnLi4vY29yZS9jb3JlLmRlZmF1bHRzJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcbnZhciBzY2FsZVNlcnZpY2UgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuc2NhbGVTZXJ2aWNlJyk7XG52YXIgVGlja3MgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUudGlja3MnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDaGFydCkge1xuXG5cdHZhciBkZWZhdWx0Q29uZmlnID0ge1xuXHRcdHBvc2l0aW9uOiAnbGVmdCcsXG5cdFx0dGlja3M6IHtcblx0XHRcdGNhbGxiYWNrOiBUaWNrcy5mb3JtYXR0ZXJzLmxpbmVhclxuXHRcdH1cblx0fTtcblxuXHR2YXIgTGluZWFyU2NhbGUgPSBDaGFydC5MaW5lYXJTY2FsZUJhc2UuZXh0ZW5kKHtcblxuXHRcdGRldGVybWluZURhdGFMaW1pdHM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcblx0XHRcdHZhciBjaGFydCA9IG1lLmNoYXJ0O1xuXHRcdFx0dmFyIGRhdGEgPSBjaGFydC5kYXRhO1xuXHRcdFx0dmFyIGRhdGFzZXRzID0gZGF0YS5kYXRhc2V0cztcblx0XHRcdHZhciBpc0hvcml6b250YWwgPSBtZS5pc0hvcml6b250YWwoKTtcblx0XHRcdHZhciBERUZBVUxUX01JTiA9IDA7XG5cdFx0XHR2YXIgREVGQVVMVF9NQVggPSAxO1xuXG5cdFx0XHRmdW5jdGlvbiBJRE1hdGNoZXMobWV0YSkge1xuXHRcdFx0XHRyZXR1cm4gaXNIb3Jpem9udGFsID8gbWV0YS54QXhpc0lEID09PSBtZS5pZCA6IG1ldGEueUF4aXNJRCA9PT0gbWUuaWQ7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZpcnN0IENhbGN1bGF0ZSB0aGUgcmFuZ2Vcblx0XHRcdG1lLm1pbiA9IG51bGw7XG5cdFx0XHRtZS5tYXggPSBudWxsO1xuXG5cdFx0XHR2YXIgaGFzU3RhY2tzID0gb3B0cy5zdGFja2VkO1xuXHRcdFx0aWYgKGhhc1N0YWNrcyA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdGhlbHBlcnMuZWFjaChkYXRhc2V0cywgZnVuY3Rpb24oZGF0YXNldCwgZGF0YXNldEluZGV4KSB7XG5cdFx0XHRcdFx0aWYgKGhhc1N0YWNrcykge1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHZhciBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcblx0XHRcdFx0XHRpZiAoY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShkYXRhc2V0SW5kZXgpICYmIElETWF0Y2hlcyhtZXRhKSAmJlxuXHRcdFx0XHRcdFx0bWV0YS5zdGFjayAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHRoYXNTdGFja3MgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChvcHRzLnN0YWNrZWQgfHwgaGFzU3RhY2tzKSB7XG5cdFx0XHRcdHZhciB2YWx1ZXNQZXJTdGFjayA9IHt9O1xuXG5cdFx0XHRcdGhlbHBlcnMuZWFjaChkYXRhc2V0cywgZnVuY3Rpb24oZGF0YXNldCwgZGF0YXNldEluZGV4KSB7XG5cdFx0XHRcdFx0dmFyIG1ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpO1xuXHRcdFx0XHRcdHZhciBrZXkgPSBbXG5cdFx0XHRcdFx0XHRtZXRhLnR5cGUsXG5cdFx0XHRcdFx0XHQvLyB3ZSBoYXZlIGEgc2VwYXJhdGUgc3RhY2sgZm9yIHN0YWNrPXVuZGVmaW5lZCBkYXRhc2V0cyB3aGVuIHRoZSBvcHRzLnN0YWNrZWQgaXMgdW5kZWZpbmVkXG5cdFx0XHRcdFx0XHQoKG9wdHMuc3RhY2tlZCA9PT0gdW5kZWZpbmVkICYmIG1ldGEuc3RhY2sgPT09IHVuZGVmaW5lZCkgPyBkYXRhc2V0SW5kZXggOiAnJyksXG5cdFx0XHRcdFx0XHRtZXRhLnN0YWNrXG5cdFx0XHRcdFx0XS5qb2luKCcuJyk7XG5cblx0XHRcdFx0XHRpZiAodmFsdWVzUGVyU3RhY2tba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHR2YWx1ZXNQZXJTdGFja1trZXldID0ge1xuXHRcdFx0XHRcdFx0XHRwb3NpdGl2ZVZhbHVlczogW10sXG5cdFx0XHRcdFx0XHRcdG5lZ2F0aXZlVmFsdWVzOiBbXVxuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBTdG9yZSB0aGVzZSBwZXIgdHlwZVxuXHRcdFx0XHRcdHZhciBwb3NpdGl2ZVZhbHVlcyA9IHZhbHVlc1BlclN0YWNrW2tleV0ucG9zaXRpdmVWYWx1ZXM7XG5cdFx0XHRcdFx0dmFyIG5lZ2F0aXZlVmFsdWVzID0gdmFsdWVzUGVyU3RhY2tba2V5XS5uZWdhdGl2ZVZhbHVlcztcblxuXHRcdFx0XHRcdGlmIChjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGRhdGFzZXRJbmRleCkgJiYgSURNYXRjaGVzKG1ldGEpKSB7XG5cdFx0XHRcdFx0XHRoZWxwZXJzLmVhY2goZGF0YXNldC5kYXRhLCBmdW5jdGlvbihyYXdWYWx1ZSwgaW5kZXgpIHtcblx0XHRcdFx0XHRcdFx0dmFyIHZhbHVlID0gK21lLmdldFJpZ2h0VmFsdWUocmF3VmFsdWUpO1xuXHRcdFx0XHRcdFx0XHRpZiAoaXNOYU4odmFsdWUpIHx8IG1ldGEuZGF0YVtpbmRleF0uaGlkZGVuKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0cG9zaXRpdmVWYWx1ZXNbaW5kZXhdID0gcG9zaXRpdmVWYWx1ZXNbaW5kZXhdIHx8IDA7XG5cdFx0XHRcdFx0XHRcdG5lZ2F0aXZlVmFsdWVzW2luZGV4XSA9IG5lZ2F0aXZlVmFsdWVzW2luZGV4XSB8fCAwO1xuXG5cdFx0XHRcdFx0XHRcdGlmIChvcHRzLnJlbGF0aXZlUG9pbnRzKSB7XG5cdFx0XHRcdFx0XHRcdFx0cG9zaXRpdmVWYWx1ZXNbaW5kZXhdID0gMTAwO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKHZhbHVlIDwgMCkge1xuXHRcdFx0XHRcdFx0XHRcdG5lZ2F0aXZlVmFsdWVzW2luZGV4XSArPSB2YWx1ZTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRwb3NpdGl2ZVZhbHVlc1tpbmRleF0gKz0gdmFsdWU7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cblx0XHRcdFx0aGVscGVycy5lYWNoKHZhbHVlc1BlclN0YWNrLCBmdW5jdGlvbih2YWx1ZXNGb3JUeXBlKSB7XG5cdFx0XHRcdFx0dmFyIHZhbHVlcyA9IHZhbHVlc0ZvclR5cGUucG9zaXRpdmVWYWx1ZXMuY29uY2F0KHZhbHVlc0ZvclR5cGUubmVnYXRpdmVWYWx1ZXMpO1xuXHRcdFx0XHRcdHZhciBtaW5WYWwgPSBoZWxwZXJzLm1pbih2YWx1ZXMpO1xuXHRcdFx0XHRcdHZhciBtYXhWYWwgPSBoZWxwZXJzLm1heCh2YWx1ZXMpO1xuXHRcdFx0XHRcdG1lLm1pbiA9IG1lLm1pbiA9PT0gbnVsbCA/IG1pblZhbCA6IE1hdGgubWluKG1lLm1pbiwgbWluVmFsKTtcblx0XHRcdFx0XHRtZS5tYXggPSBtZS5tYXggPT09IG51bGwgPyBtYXhWYWwgOiBNYXRoLm1heChtZS5tYXgsIG1heFZhbCk7XG5cdFx0XHRcdH0pO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRoZWxwZXJzLmVhY2goZGF0YXNldHMsIGZ1bmN0aW9uKGRhdGFzZXQsIGRhdGFzZXRJbmRleCkge1xuXHRcdFx0XHRcdHZhciBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcblx0XHRcdFx0XHRpZiAoY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShkYXRhc2V0SW5kZXgpICYmIElETWF0Y2hlcyhtZXRhKSkge1xuXHRcdFx0XHRcdFx0aGVscGVycy5lYWNoKGRhdGFzZXQuZGF0YSwgZnVuY3Rpb24ocmF3VmFsdWUsIGluZGV4KSB7XG5cdFx0XHRcdFx0XHRcdHZhciB2YWx1ZSA9ICttZS5nZXRSaWdodFZhbHVlKHJhd1ZhbHVlKTtcblx0XHRcdFx0XHRcdFx0aWYgKGlzTmFOKHZhbHVlKSB8fCBtZXRhLmRhdGFbaW5kZXhdLmhpZGRlbikge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGlmIChtZS5taW4gPT09IG51bGwpIHtcblx0XHRcdFx0XHRcdFx0XHRtZS5taW4gPSB2YWx1ZTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICh2YWx1ZSA8IG1lLm1pbikge1xuXHRcdFx0XHRcdFx0XHRcdG1lLm1pbiA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0aWYgKG1lLm1heCA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0XHRcdG1lLm1heCA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKHZhbHVlID4gbWUubWF4KSB7XG5cdFx0XHRcdFx0XHRcdFx0bWUubWF4ID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdG1lLm1pbiA9IGlzRmluaXRlKG1lLm1pbikgJiYgIWlzTmFOKG1lLm1pbikgPyBtZS5taW4gOiBERUZBVUxUX01JTjtcblx0XHRcdG1lLm1heCA9IGlzRmluaXRlKG1lLm1heCkgJiYgIWlzTmFOKG1lLm1heCkgPyBtZS5tYXggOiBERUZBVUxUX01BWDtcblxuXHRcdFx0Ly8gQ29tbW9uIGJhc2UgaW1wbGVtZW50YXRpb24gdG8gaGFuZGxlIHRpY2tzLm1pbiwgdGlja3MubWF4LCB0aWNrcy5iZWdpbkF0WmVyb1xuXHRcdFx0dGhpcy5oYW5kbGVUaWNrUmFuZ2VPcHRpb25zKCk7XG5cdFx0fSxcblx0XHRnZXRUaWNrTGltaXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1heFRpY2tzO1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciB0aWNrT3B0cyA9IG1lLm9wdGlvbnMudGlja3M7XG5cblx0XHRcdGlmIChtZS5pc0hvcml6b250YWwoKSkge1xuXHRcdFx0XHRtYXhUaWNrcyA9IE1hdGgubWluKHRpY2tPcHRzLm1heFRpY2tzTGltaXQgPyB0aWNrT3B0cy5tYXhUaWNrc0xpbWl0IDogMTEsIE1hdGguY2VpbChtZS53aWR0aCAvIDUwKSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBUaGUgZmFjdG9yIG9mIDIgdXNlZCB0byBzY2FsZSB0aGUgZm9udCBzaXplIGhhcyBiZWVuIGV4cGVyaW1lbnRhbGx5IGRldGVybWluZWQuXG5cdFx0XHRcdHZhciB0aWNrRm9udFNpemUgPSBoZWxwZXJzLnZhbHVlT3JEZWZhdWx0KHRpY2tPcHRzLmZvbnRTaXplLCBkZWZhdWx0cy5nbG9iYWwuZGVmYXVsdEZvbnRTaXplKTtcblx0XHRcdFx0bWF4VGlja3MgPSBNYXRoLm1pbih0aWNrT3B0cy5tYXhUaWNrc0xpbWl0ID8gdGlja09wdHMubWF4VGlja3NMaW1pdCA6IDExLCBNYXRoLmNlaWwobWUuaGVpZ2h0IC8gKDIgKiB0aWNrRm9udFNpemUpKSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBtYXhUaWNrcztcblx0XHR9LFxuXHRcdC8vIENhbGxlZCBhZnRlciB0aGUgdGlja3MgYXJlIGJ1aWx0LiBXZSBuZWVkXG5cdFx0aGFuZGxlRGlyZWN0aW9uYWxDaGFuZ2VzOiBmdW5jdGlvbigpIHtcblx0XHRcdGlmICghdGhpcy5pc0hvcml6b250YWwoKSkge1xuXHRcdFx0XHQvLyBXZSBhcmUgaW4gYSB2ZXJ0aWNhbCBvcmllbnRhdGlvbi4gVGhlIHRvcCB2YWx1ZSBpcyB0aGUgaGlnaGVzdC4gU28gcmV2ZXJzZSB0aGUgYXJyYXlcblx0XHRcdFx0dGhpcy50aWNrcy5yZXZlcnNlKCk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRnZXRMYWJlbEZvckluZGV4OiBmdW5jdGlvbihpbmRleCwgZGF0YXNldEluZGV4KSB7XG5cdFx0XHRyZXR1cm4gK3RoaXMuZ2V0UmlnaHRWYWx1ZSh0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XS5kYXRhW2luZGV4XSk7XG5cdFx0fSxcblx0XHQvLyBVdGlsc1xuXHRcdGdldFBpeGVsRm9yVmFsdWU6IGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHQvLyBUaGlzIG11c3QgYmUgY2FsbGVkIGFmdGVyIGZpdCBoYXMgYmVlbiBydW4gc28gdGhhdFxuXHRcdFx0Ly8gdGhpcy5sZWZ0LCB0aGlzLnRvcCwgdGhpcy5yaWdodCwgYW5kIHRoaXMuYm90dG9tIGhhdmUgYmVlbiBkZWZpbmVkXG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIHN0YXJ0ID0gbWUuc3RhcnQ7XG5cblx0XHRcdHZhciByaWdodFZhbHVlID0gK21lLmdldFJpZ2h0VmFsdWUodmFsdWUpO1xuXHRcdFx0dmFyIHBpeGVsO1xuXHRcdFx0dmFyIHJhbmdlID0gbWUuZW5kIC0gc3RhcnQ7XG5cblx0XHRcdGlmIChtZS5pc0hvcml6b250YWwoKSkge1xuXHRcdFx0XHRwaXhlbCA9IG1lLmxlZnQgKyAobWUud2lkdGggLyByYW5nZSAqIChyaWdodFZhbHVlIC0gc3RhcnQpKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHBpeGVsID0gbWUuYm90dG9tIC0gKG1lLmhlaWdodCAvIHJhbmdlICogKHJpZ2h0VmFsdWUgLSBzdGFydCkpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHBpeGVsO1xuXHRcdH0sXG5cdFx0Z2V0VmFsdWVGb3JQaXhlbDogZnVuY3Rpb24ocGl4ZWwpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgaXNIb3Jpem9udGFsID0gbWUuaXNIb3Jpem9udGFsKCk7XG5cdFx0XHR2YXIgaW5uZXJEaW1lbnNpb24gPSBpc0hvcml6b250YWwgPyBtZS53aWR0aCA6IG1lLmhlaWdodDtcblx0XHRcdHZhciBvZmZzZXQgPSAoaXNIb3Jpem9udGFsID8gcGl4ZWwgLSBtZS5sZWZ0IDogbWUuYm90dG9tIC0gcGl4ZWwpIC8gaW5uZXJEaW1lbnNpb247XG5cdFx0XHRyZXR1cm4gbWUuc3RhcnQgKyAoKG1lLmVuZCAtIG1lLnN0YXJ0KSAqIG9mZnNldCk7XG5cdFx0fSxcblx0XHRnZXRQaXhlbEZvclRpY2s6IGZ1bmN0aW9uKGluZGV4KSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5nZXRQaXhlbEZvclZhbHVlKHRoaXMudGlja3NBc051bWJlcnNbaW5kZXhdKTtcblx0XHR9XG5cdH0pO1xuXG5cdHNjYWxlU2VydmljZS5yZWdpc3RlclNjYWxlVHlwZSgnbGluZWFyJywgTGluZWFyU2NhbGUsIGRlZmF1bHRDb25maWcpO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///e866\n")},f0d9:function(module,exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = function(Chart) {\n\n\tChart.Bar = function(context, config) {\n\t\tconfig.type = 'bar';\n\n\t\treturn new Chart(context, config);\n\t};\n\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZjBkOS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY2hhcnRzL0NoYXJ0LkJhci5qcz8zODM3Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDaGFydCkge1xuXG5cdENoYXJ0LkJhciA9IGZ1bmN0aW9uKGNvbnRleHQsIGNvbmZpZykge1xuXHRcdGNvbmZpZy50eXBlID0gJ2Jhcic7XG5cblx0XHRyZXR1cm4gbmV3IENoYXJ0KGNvbnRleHQsIGNvbmZpZyk7XG5cdH07XG5cbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///f0d9\n")},f1c0:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\nvar Scale = __webpack_require__(/*! ../core/core.scale */ \"d1b4\");\nvar scaleService = __webpack_require__(/*! ../core/core.scaleService */ \"7c56\");\nvar Ticks = __webpack_require__(/*! ../core/core.ticks */ \"1220\");\n\n/**\n * Generate a set of logarithmic ticks\n * @param generationOptions the options used to generate the ticks\n * @param dataRange the range of the data\n * @returns {Array<Number>} array of tick values\n */\nfunction generateTicks(generationOptions, dataRange) {\n\tvar ticks = [];\n\tvar valueOrDefault = helpers.valueOrDefault;\n\n\t// Figure out what the max number of ticks we can support it is based on the size of\n\t// the axis area. For now, we say that the minimum tick spacing in pixels must be 50\n\t// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\n\t// the graph\n\tvar tickVal = valueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min))));\n\n\tvar endExp = Math.floor(helpers.log10(dataRange.max));\n\tvar endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));\n\tvar exp, significand;\n\n\tif (tickVal === 0) {\n\t\texp = Math.floor(helpers.log10(dataRange.minNotZero));\n\t\tsignificand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));\n\n\t\tticks.push(tickVal);\n\t\ttickVal = significand * Math.pow(10, exp);\n\t} else {\n\t\texp = Math.floor(helpers.log10(tickVal));\n\t\tsignificand = Math.floor(tickVal / Math.pow(10, exp));\n\t}\n\tvar precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1;\n\n\tdo {\n\t\tticks.push(tickVal);\n\n\t\t++significand;\n\t\tif (significand === 10) {\n\t\t\tsignificand = 1;\n\t\t\t++exp;\n\t\t\tprecision = exp >= 0 ? 1 : precision;\n\t\t}\n\n\t\ttickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision;\n\t} while (exp < endExp || (exp === endExp && significand < endSignificand));\n\n\tvar lastTick = valueOrDefault(generationOptions.max, tickVal);\n\tticks.push(lastTick);\n\n\treturn ticks;\n}\n\n\nmodule.exports = function(Chart) {\n\n\tvar defaultConfig = {\n\t\tposition: 'left',\n\n\t\t// label settings\n\t\tticks: {\n\t\t\tcallback: Ticks.formatters.logarithmic\n\t\t}\n\t};\n\n\tvar LogarithmicScale = Scale.extend({\n\t\tdetermineDataLimits: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar chart = me.chart;\n\t\t\tvar data = chart.data;\n\t\t\tvar datasets = data.datasets;\n\t\t\tvar isHorizontal = me.isHorizontal();\n\t\t\tfunction IDMatches(meta) {\n\t\t\t\treturn isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\n\t\t\t}\n\n\t\t\t// Calculate Range\n\t\t\tme.min = null;\n\t\t\tme.max = null;\n\t\t\tme.minNotZero = null;\n\n\t\t\tvar hasStacks = opts.stacked;\n\t\t\tif (hasStacks === undefined) {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tif (hasStacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&\n\t\t\t\t\t\tmeta.stack !== undefined) {\n\t\t\t\t\t\thasStacks = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (opts.stacked || hasStacks) {\n\t\t\t\tvar valuesPerStack = {};\n\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tvar key = [\n\t\t\t\t\t\tmeta.type,\n\t\t\t\t\t\t// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined\n\t\t\t\t\t\t((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),\n\t\t\t\t\t\tmeta.stack\n\t\t\t\t\t].join('.');\n\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\tif (valuesPerStack[key] === undefined) {\n\t\t\t\t\t\t\tvaluesPerStack[key] = [];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar values = valuesPerStack[key];\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\t// invalid, hidden and negative values are ignored\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden || value < 0) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvalues[index] = values[index] || 0;\n\t\t\t\t\t\t\tvalues[index] += value;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\thelpers.each(valuesPerStack, function(valuesForType) {\n\t\t\t\t\tif (valuesForType.length > 0) {\n\t\t\t\t\t\tvar minVal = helpers.min(valuesForType);\n\t\t\t\t\t\tvar maxVal = helpers.max(valuesForType);\n\t\t\t\t\t\tme.min = me.min === null ? minVal : Math.min(me.min, minVal);\n\t\t\t\t\t\tme.max = me.max === null ? maxVal : Math.max(me.max, maxVal);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t} else {\n\t\t\t\thelpers.each(datasets, function(dataset, datasetIndex) {\n\t\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\n\t\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\n\t\t\t\t\t\thelpers.each(dataset.data, function(rawValue, index) {\n\t\t\t\t\t\t\tvar value = +me.getRightValue(rawValue);\n\t\t\t\t\t\t\t// invalid, hidden and negative values are ignored\n\t\t\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden || value < 0) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.min === null) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t} else if (value < me.min) {\n\t\t\t\t\t\t\t\tme.min = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (me.max === null) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t} else if (value > me.max) {\n\t\t\t\t\t\t\t\tme.max = value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) {\n\t\t\t\t\t\t\t\tme.minNotZero = value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Common base implementation to handle ticks.min, ticks.max\n\t\t\tthis.handleTickRangeOptions();\n\t\t},\n\t\thandleTickRangeOptions: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar valueOrDefault = helpers.valueOrDefault;\n\t\t\tvar DEFAULT_MIN = 1;\n\t\t\tvar DEFAULT_MAX = 10;\n\n\t\t\tme.min = valueOrDefault(tickOpts.min, me.min);\n\t\t\tme.max = valueOrDefault(tickOpts.max, me.max);\n\n\t\t\tif (me.min === me.max) {\n\t\t\t\tif (me.min !== 0 && me.min !== null) {\n\t\t\t\t\tme.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);\n\t\t\t\t\tme.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);\n\t\t\t\t} else {\n\t\t\t\t\tme.min = DEFAULT_MIN;\n\t\t\t\t\tme.max = DEFAULT_MAX;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (me.min === null) {\n\t\t\t\tme.min = Math.pow(10, Math.floor(helpers.log10(me.max)) - 1);\n\t\t\t}\n\t\t\tif (me.max === null) {\n\t\t\t\tme.max = me.min !== 0\n\t\t\t\t\t? Math.pow(10, Math.floor(helpers.log10(me.min)) + 1)\n\t\t\t\t\t: DEFAULT_MAX;\n\t\t\t}\n\t\t\tif (me.minNotZero === null) {\n\t\t\t\tif (me.min > 0) {\n\t\t\t\t\tme.minNotZero = me.min;\n\t\t\t\t} else if (me.max < 1) {\n\t\t\t\t\tme.minNotZero = Math.pow(10, Math.floor(helpers.log10(me.max)));\n\t\t\t\t} else {\n\t\t\t\t\tme.minNotZero = DEFAULT_MIN;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tbuildTicks: function() {\n\t\t\tvar me = this;\n\t\t\tvar opts = me.options;\n\t\t\tvar tickOpts = opts.ticks;\n\t\t\tvar reverse = !me.isHorizontal();\n\n\t\t\tvar generationOptions = {\n\t\t\t\tmin: tickOpts.min,\n\t\t\t\tmax: tickOpts.max\n\t\t\t};\n\t\t\tvar ticks = me.ticks = generateTicks(generationOptions, me);\n\n\t\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\n\t\t\t// range of the scale\n\t\t\tme.max = helpers.max(ticks);\n\t\t\tme.min = helpers.min(ticks);\n\n\t\t\tif (tickOpts.reverse) {\n\t\t\t\treverse = !reverse;\n\t\t\t\tme.start = me.max;\n\t\t\t\tme.end = me.min;\n\t\t\t} else {\n\t\t\t\tme.start = me.min;\n\t\t\t\tme.end = me.max;\n\t\t\t}\n\t\t\tif (reverse) {\n\t\t\t\tticks.reverse();\n\t\t\t}\n\t\t},\n\t\tconvertTicksToLabels: function() {\n\t\t\tthis.tickValues = this.ticks.slice();\n\n\t\t\tScale.prototype.convertTicksToLabels.call(this);\n\t\t},\n\t\t// Get the correct tooltip label\n\t\tgetLabelForIndex: function(index, datasetIndex) {\n\t\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\n\t\t},\n\t\tgetPixelForTick: function(index) {\n\t\t\treturn this.getPixelForValue(this.tickValues[index]);\n\t\t},\n\t\t/**\n\t\t * Returns the value of the first tick.\n\t\t * @param {Number} value - The minimum not zero value.\n\t\t * @return {Number} The first tick value.\n\t\t * @private\n\t\t */\n\t\t_getFirstTickValue: function(value) {\n\t\t\tvar exp = Math.floor(helpers.log10(value));\n\t\t\tvar significand = Math.floor(value / Math.pow(10, exp));\n\n\t\t\treturn significand * Math.pow(10, exp);\n\t\t},\n\t\tgetPixelForValue: function(value) {\n\t\t\tvar me = this;\n\t\t\tvar reverse = me.options.ticks.reverse;\n\t\t\tvar log10 = helpers.log10;\n\t\t\tvar firstTickValue = me._getFirstTickValue(me.minNotZero);\n\t\t\tvar offset = 0;\n\t\t\tvar innerDimension, pixel, start, end, sign;\n\n\t\t\tvalue = +me.getRightValue(value);\n\t\t\tif (reverse) {\n\t\t\t\tstart = me.end;\n\t\t\t\tend = me.start;\n\t\t\t\tsign = -1;\n\t\t\t} else {\n\t\t\t\tstart = me.start;\n\t\t\t\tend = me.end;\n\t\t\t\tsign = 1;\n\t\t\t}\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tinnerDimension = me.width;\n\t\t\t\tpixel = reverse ? me.right : me.left;\n\t\t\t} else {\n\t\t\t\tinnerDimension = me.height;\n\t\t\t\tsign *= -1; // invert, since the upper-left corner of the canvas is at pixel (0, 0)\n\t\t\t\tpixel = reverse ? me.top : me.bottom;\n\t\t\t}\n\t\t\tif (value !== start) {\n\t\t\t\tif (start === 0) { // include zero tick\n\t\t\t\t\toffset = helpers.getValueOrDefault(\n\t\t\t\t\t\tme.options.ticks.fontSize,\n\t\t\t\t\t\tChart.defaults.global.defaultFontSize\n\t\t\t\t\t);\n\t\t\t\t\tinnerDimension -= offset;\n\t\t\t\t\tstart = firstTickValue;\n\t\t\t\t}\n\t\t\t\tif (value !== 0) {\n\t\t\t\t\toffset += innerDimension / (log10(end) - log10(start)) * (log10(value) - log10(start));\n\t\t\t\t}\n\t\t\t\tpixel += sign * offset;\n\t\t\t}\n\t\t\treturn pixel;\n\t\t},\n\t\tgetValueForPixel: function(pixel) {\n\t\t\tvar me = this;\n\t\t\tvar reverse = me.options.ticks.reverse;\n\t\t\tvar log10 = helpers.log10;\n\t\t\tvar firstTickValue = me._getFirstTickValue(me.minNotZero);\n\t\t\tvar innerDimension, start, end, value;\n\n\t\t\tif (reverse) {\n\t\t\t\tstart = me.end;\n\t\t\t\tend = me.start;\n\t\t\t} else {\n\t\t\t\tstart = me.start;\n\t\t\t\tend = me.end;\n\t\t\t}\n\t\t\tif (me.isHorizontal()) {\n\t\t\t\tinnerDimension = me.width;\n\t\t\t\tvalue = reverse ? me.right - pixel : pixel - me.left;\n\t\t\t} else {\n\t\t\t\tinnerDimension = me.height;\n\t\t\t\tvalue = reverse ? pixel - me.top : me.bottom - pixel;\n\t\t\t}\n\t\t\tif (value !== start) {\n\t\t\t\tif (start === 0) { // include zero tick\n\t\t\t\t\tvar offset = helpers.getValueOrDefault(\n\t\t\t\t\t\tme.options.ticks.fontSize,\n\t\t\t\t\t\tChart.defaults.global.defaultFontSize\n\t\t\t\t\t);\n\t\t\t\t\tvalue -= offset;\n\t\t\t\t\tinnerDimension -= offset;\n\t\t\t\t\tstart = firstTickValue;\n\t\t\t\t}\n\t\t\t\tvalue *= log10(end) - log10(start);\n\t\t\t\tvalue /= innerDimension;\n\t\t\t\tvalue = Math.pow(10, log10(start) + value);\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t});\n\n\tscaleService.registerScaleType('logarithmic', LogarithmicScale, defaultConfig);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZjFjMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvc2NhbGVzL3NjYWxlLmxvZ2FyaXRobWljLmpzPzYzODQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcbnZhciBTY2FsZSA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5zY2FsZScpO1xudmFyIHNjYWxlU2VydmljZSA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5zY2FsZVNlcnZpY2UnKTtcbnZhciBUaWNrcyA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS50aWNrcycpO1xuXG4vKipcbiAqIEdlbmVyYXRlIGEgc2V0IG9mIGxvZ2FyaXRobWljIHRpY2tzXG4gKiBAcGFyYW0gZ2VuZXJhdGlvbk9wdGlvbnMgdGhlIG9wdGlvbnMgdXNlZCB0byBnZW5lcmF0ZSB0aGUgdGlja3NcbiAqIEBwYXJhbSBkYXRhUmFuZ2UgdGhlIHJhbmdlIG9mIHRoZSBkYXRhXG4gKiBAcmV0dXJucyB7QXJyYXk8TnVtYmVyPn0gYXJyYXkgb2YgdGljayB2YWx1ZXNcbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVUaWNrcyhnZW5lcmF0aW9uT3B0aW9ucywgZGF0YVJhbmdlKSB7XG5cdHZhciB0aWNrcyA9IFtdO1xuXHR2YXIgdmFsdWVPckRlZmF1bHQgPSBoZWxwZXJzLnZhbHVlT3JEZWZhdWx0O1xuXG5cdC8vIEZpZ3VyZSBvdXQgd2hhdCB0aGUgbWF4IG51bWJlciBvZiB0aWNrcyB3ZSBjYW4gc3VwcG9ydCBpdCBpcyBiYXNlZCBvbiB0aGUgc2l6ZSBvZlxuXHQvLyB0aGUgYXhpcyBhcmVhLiBGb3Igbm93LCB3ZSBzYXkgdGhhdCB0aGUgbWluaW11bSB0aWNrIHNwYWNpbmcgaW4gcGl4ZWxzIG11c3QgYmUgNTBcblx0Ly8gV2UgYWxzbyBsaW1pdCB0aGUgbWF4aW11bSBudW1iZXIgb2YgdGlja3MgdG8gMTEgd2hpY2ggZ2l2ZXMgYSBuaWNlIDEwIHNxdWFyZXMgb25cblx0Ly8gdGhlIGdyYXBoXG5cdHZhciB0aWNrVmFsID0gdmFsdWVPckRlZmF1bHQoZ2VuZXJhdGlvbk9wdGlvbnMubWluLCBNYXRoLnBvdygxMCwgTWF0aC5mbG9vcihoZWxwZXJzLmxvZzEwKGRhdGFSYW5nZS5taW4pKSkpO1xuXG5cdHZhciBlbmRFeHAgPSBNYXRoLmZsb29yKGhlbHBlcnMubG9nMTAoZGF0YVJhbmdlLm1heCkpO1xuXHR2YXIgZW5kU2lnbmlmaWNhbmQgPSBNYXRoLmNlaWwoZGF0YVJhbmdlLm1heCAvIE1hdGgucG93KDEwLCBlbmRFeHApKTtcblx0dmFyIGV4cCwgc2lnbmlmaWNhbmQ7XG5cblx0aWYgKHRpY2tWYWwgPT09IDApIHtcblx0XHRleHAgPSBNYXRoLmZsb29yKGhlbHBlcnMubG9nMTAoZGF0YVJhbmdlLm1pbk5vdFplcm8pKTtcblx0XHRzaWduaWZpY2FuZCA9IE1hdGguZmxvb3IoZGF0YVJhbmdlLm1pbk5vdFplcm8gLyBNYXRoLnBvdygxMCwgZXhwKSk7XG5cblx0XHR0aWNrcy5wdXNoKHRpY2tWYWwpO1xuXHRcdHRpY2tWYWwgPSBzaWduaWZpY2FuZCAqIE1hdGgucG93KDEwLCBleHApO1xuXHR9IGVsc2Uge1xuXHRcdGV4cCA9IE1hdGguZmxvb3IoaGVscGVycy5sb2cxMCh0aWNrVmFsKSk7XG5cdFx0c2lnbmlmaWNhbmQgPSBNYXRoLmZsb29yKHRpY2tWYWwgLyBNYXRoLnBvdygxMCwgZXhwKSk7XG5cdH1cblx0dmFyIHByZWNpc2lvbiA9IGV4cCA8IDAgPyBNYXRoLnBvdygxMCwgTWF0aC5hYnMoZXhwKSkgOiAxO1xuXG5cdGRvIHtcblx0XHR0aWNrcy5wdXNoKHRpY2tWYWwpO1xuXG5cdFx0KytzaWduaWZpY2FuZDtcblx0XHRpZiAoc2lnbmlmaWNhbmQgPT09IDEwKSB7XG5cdFx0XHRzaWduaWZpY2FuZCA9IDE7XG5cdFx0XHQrK2V4cDtcblx0XHRcdHByZWNpc2lvbiA9IGV4cCA+PSAwID8gMSA6IHByZWNpc2lvbjtcblx0XHR9XG5cblx0XHR0aWNrVmFsID0gTWF0aC5yb3VuZChzaWduaWZpY2FuZCAqIE1hdGgucG93KDEwLCBleHApICogcHJlY2lzaW9uKSAvIHByZWNpc2lvbjtcblx0fSB3aGlsZSAoZXhwIDwgZW5kRXhwIHx8IChleHAgPT09IGVuZEV4cCAmJiBzaWduaWZpY2FuZCA8IGVuZFNpZ25pZmljYW5kKSk7XG5cblx0dmFyIGxhc3RUaWNrID0gdmFsdWVPckRlZmF1bHQoZ2VuZXJhdGlvbk9wdGlvbnMubWF4LCB0aWNrVmFsKTtcblx0dGlja3MucHVzaChsYXN0VGljayk7XG5cblx0cmV0dXJuIHRpY2tzO1xufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oQ2hhcnQpIHtcblxuXHR2YXIgZGVmYXVsdENvbmZpZyA9IHtcblx0XHRwb3NpdGlvbjogJ2xlZnQnLFxuXG5cdFx0Ly8gbGFiZWwgc2V0dGluZ3Ncblx0XHR0aWNrczoge1xuXHRcdFx0Y2FsbGJhY2s6IFRpY2tzLmZvcm1hdHRlcnMubG9nYXJpdGhtaWNcblx0XHR9XG5cdH07XG5cblx0dmFyIExvZ2FyaXRobWljU2NhbGUgPSBTY2FsZS5leHRlbmQoe1xuXHRcdGRldGVybWluZURhdGFMaW1pdHM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcblx0XHRcdHZhciBjaGFydCA9IG1lLmNoYXJ0O1xuXHRcdFx0dmFyIGRhdGEgPSBjaGFydC5kYXRhO1xuXHRcdFx0dmFyIGRhdGFzZXRzID0gZGF0YS5kYXRhc2V0cztcblx0XHRcdHZhciBpc0hvcml6b250YWwgPSBtZS5pc0hvcml6b250YWwoKTtcblx0XHRcdGZ1bmN0aW9uIElETWF0Y2hlcyhtZXRhKSB7XG5cdFx0XHRcdHJldHVybiBpc0hvcml6b250YWwgPyBtZXRhLnhBeGlzSUQgPT09IG1lLmlkIDogbWV0YS55QXhpc0lEID09PSBtZS5pZDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2FsY3VsYXRlIFJhbmdlXG5cdFx0XHRtZS5taW4gPSBudWxsO1xuXHRcdFx0bWUubWF4ID0gbnVsbDtcblx0XHRcdG1lLm1pbk5vdFplcm8gPSBudWxsO1xuXG5cdFx0XHR2YXIgaGFzU3RhY2tzID0gb3B0cy5zdGFja2VkO1xuXHRcdFx0aWYgKGhhc1N0YWNrcyA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdGhlbHBlcnMuZWFjaChkYXRhc2V0cywgZnVuY3Rpb24oZGF0YXNldCwgZGF0YXNldEluZGV4KSB7XG5cdFx0XHRcdFx0aWYgKGhhc1N0YWNrcykge1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHZhciBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcblx0XHRcdFx0XHRpZiAoY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShkYXRhc2V0SW5kZXgpICYmIElETWF0Y2hlcyhtZXRhKSAmJlxuXHRcdFx0XHRcdFx0bWV0YS5zdGFjayAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHRoYXNTdGFja3MgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChvcHRzLnN0YWNrZWQgfHwgaGFzU3RhY2tzKSB7XG5cdFx0XHRcdHZhciB2YWx1ZXNQZXJTdGFjayA9IHt9O1xuXG5cdFx0XHRcdGhlbHBlcnMuZWFjaChkYXRhc2V0cywgZnVuY3Rpb24oZGF0YXNldCwgZGF0YXNldEluZGV4KSB7XG5cdFx0XHRcdFx0dmFyIG1ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpO1xuXHRcdFx0XHRcdHZhciBrZXkgPSBbXG5cdFx0XHRcdFx0XHRtZXRhLnR5cGUsXG5cdFx0XHRcdFx0XHQvLyB3ZSBoYXZlIGEgc2VwYXJhdGUgc3RhY2sgZm9yIHN0YWNrPXVuZGVmaW5lZCBkYXRhc2V0cyB3aGVuIHRoZSBvcHRzLnN0YWNrZWQgaXMgdW5kZWZpbmVkXG5cdFx0XHRcdFx0XHQoKG9wdHMuc3RhY2tlZCA9PT0gdW5kZWZpbmVkICYmIG1ldGEuc3RhY2sgPT09IHVuZGVmaW5lZCkgPyBkYXRhc2V0SW5kZXggOiAnJyksXG5cdFx0XHRcdFx0XHRtZXRhLnN0YWNrXG5cdFx0XHRcdFx0XS5qb2luKCcuJyk7XG5cblx0XHRcdFx0XHRpZiAoY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShkYXRhc2V0SW5kZXgpICYmIElETWF0Y2hlcyhtZXRhKSkge1xuXHRcdFx0XHRcdFx0aWYgKHZhbHVlc1BlclN0YWNrW2tleV0gPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdFx0XHR2YWx1ZXNQZXJTdGFja1trZXldID0gW107XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGhlbHBlcnMuZWFjaChkYXRhc2V0LmRhdGEsIGZ1bmN0aW9uKHJhd1ZhbHVlLCBpbmRleCkge1xuXHRcdFx0XHRcdFx0XHR2YXIgdmFsdWVzID0gdmFsdWVzUGVyU3RhY2tba2V5XTtcblx0XHRcdFx0XHRcdFx0dmFyIHZhbHVlID0gK21lLmdldFJpZ2h0VmFsdWUocmF3VmFsdWUpO1xuXHRcdFx0XHRcdFx0XHQvLyBpbnZhbGlkLCBoaWRkZW4gYW5kIG5lZ2F0aXZlIHZhbHVlcyBhcmUgaWdub3JlZFxuXHRcdFx0XHRcdFx0XHRpZiAoaXNOYU4odmFsdWUpIHx8IG1ldGEuZGF0YVtpbmRleF0uaGlkZGVuIHx8IHZhbHVlIDwgMCkge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR2YWx1ZXNbaW5kZXhdID0gdmFsdWVzW2luZGV4XSB8fCAwO1xuXHRcdFx0XHRcdFx0XHR2YWx1ZXNbaW5kZXhdICs9IHZhbHVlO1xuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHRoZWxwZXJzLmVhY2godmFsdWVzUGVyU3RhY2ssIGZ1bmN0aW9uKHZhbHVlc0ZvclR5cGUpIHtcblx0XHRcdFx0XHRpZiAodmFsdWVzRm9yVHlwZS5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0XHR2YXIgbWluVmFsID0gaGVscGVycy5taW4odmFsdWVzRm9yVHlwZSk7XG5cdFx0XHRcdFx0XHR2YXIgbWF4VmFsID0gaGVscGVycy5tYXgodmFsdWVzRm9yVHlwZSk7XG5cdFx0XHRcdFx0XHRtZS5taW4gPSBtZS5taW4gPT09IG51bGwgPyBtaW5WYWwgOiBNYXRoLm1pbihtZS5taW4sIG1pblZhbCk7XG5cdFx0XHRcdFx0XHRtZS5tYXggPSBtZS5tYXggPT09IG51bGwgPyBtYXhWYWwgOiBNYXRoLm1heChtZS5tYXgsIG1heFZhbCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aGVscGVycy5lYWNoKGRhdGFzZXRzLCBmdW5jdGlvbihkYXRhc2V0LCBkYXRhc2V0SW5kZXgpIHtcblx0XHRcdFx0XHR2YXIgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XG5cdFx0XHRcdFx0aWYgKGNoYXJ0LmlzRGF0YXNldFZpc2libGUoZGF0YXNldEluZGV4KSAmJiBJRE1hdGNoZXMobWV0YSkpIHtcblx0XHRcdFx0XHRcdGhlbHBlcnMuZWFjaChkYXRhc2V0LmRhdGEsIGZ1bmN0aW9uKHJhd1ZhbHVlLCBpbmRleCkge1xuXHRcdFx0XHRcdFx0XHR2YXIgdmFsdWUgPSArbWUuZ2V0UmlnaHRWYWx1ZShyYXdWYWx1ZSk7XG5cdFx0XHRcdFx0XHRcdC8vIGludmFsaWQsIGhpZGRlbiBhbmQgbmVnYXRpdmUgdmFsdWVzIGFyZSBpZ25vcmVkXG5cdFx0XHRcdFx0XHRcdGlmIChpc05hTih2YWx1ZSkgfHwgbWV0YS5kYXRhW2luZGV4XS5oaWRkZW4gfHwgdmFsdWUgPCAwKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0aWYgKG1lLm1pbiA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0XHRcdG1lLm1pbiA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKHZhbHVlIDwgbWUubWluKSB7XG5cdFx0XHRcdFx0XHRcdFx0bWUubWluID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRpZiAobWUubWF4ID09PSBudWxsKSB7XG5cdFx0XHRcdFx0XHRcdFx0bWUubWF4ID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAodmFsdWUgPiBtZS5tYXgpIHtcblx0XHRcdFx0XHRcdFx0XHRtZS5tYXggPSB2YWx1ZTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGlmICh2YWx1ZSAhPT0gMCAmJiAobWUubWluTm90WmVybyA9PT0gbnVsbCB8fCB2YWx1ZSA8IG1lLm1pbk5vdFplcm8pKSB7XG5cdFx0XHRcdFx0XHRcdFx0bWUubWluTm90WmVybyA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDb21tb24gYmFzZSBpbXBsZW1lbnRhdGlvbiB0byBoYW5kbGUgdGlja3MubWluLCB0aWNrcy5tYXhcblx0XHRcdHRoaXMuaGFuZGxlVGlja1JhbmdlT3B0aW9ucygpO1xuXHRcdH0sXG5cdFx0aGFuZGxlVGlja1JhbmdlT3B0aW9uczogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG9wdHMgPSBtZS5vcHRpb25zO1xuXHRcdFx0dmFyIHRpY2tPcHRzID0gb3B0cy50aWNrcztcblx0XHRcdHZhciB2YWx1ZU9yRGVmYXVsdCA9IGhlbHBlcnMudmFsdWVPckRlZmF1bHQ7XG5cdFx0XHR2YXIgREVGQVVMVF9NSU4gPSAxO1xuXHRcdFx0dmFyIERFRkFVTFRfTUFYID0gMTA7XG5cblx0XHRcdG1lLm1pbiA9IHZhbHVlT3JEZWZhdWx0KHRpY2tPcHRzLm1pbiwgbWUubWluKTtcblx0XHRcdG1lLm1heCA9IHZhbHVlT3JEZWZhdWx0KHRpY2tPcHRzLm1heCwgbWUubWF4KTtcblxuXHRcdFx0aWYgKG1lLm1pbiA9PT0gbWUubWF4KSB7XG5cdFx0XHRcdGlmIChtZS5taW4gIT09IDAgJiYgbWUubWluICE9PSBudWxsKSB7XG5cdFx0XHRcdFx0bWUubWluID0gTWF0aC5wb3coMTAsIE1hdGguZmxvb3IoaGVscGVycy5sb2cxMChtZS5taW4pKSAtIDEpO1xuXHRcdFx0XHRcdG1lLm1heCA9IE1hdGgucG93KDEwLCBNYXRoLmZsb29yKGhlbHBlcnMubG9nMTAobWUubWF4KSkgKyAxKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRtZS5taW4gPSBERUZBVUxUX01JTjtcblx0XHRcdFx0XHRtZS5tYXggPSBERUZBVUxUX01BWDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKG1lLm1pbiA9PT0gbnVsbCkge1xuXHRcdFx0XHRtZS5taW4gPSBNYXRoLnBvdygxMCwgTWF0aC5mbG9vcihoZWxwZXJzLmxvZzEwKG1lLm1heCkpIC0gMSk7XG5cdFx0XHR9XG5cdFx0XHRpZiAobWUubWF4ID09PSBudWxsKSB7XG5cdFx0XHRcdG1lLm1heCA9IG1lLm1pbiAhPT0gMFxuXHRcdFx0XHRcdD8gTWF0aC5wb3coMTAsIE1hdGguZmxvb3IoaGVscGVycy5sb2cxMChtZS5taW4pKSArIDEpXG5cdFx0XHRcdFx0OiBERUZBVUxUX01BWDtcblx0XHRcdH1cblx0XHRcdGlmIChtZS5taW5Ob3RaZXJvID09PSBudWxsKSB7XG5cdFx0XHRcdGlmIChtZS5taW4gPiAwKSB7XG5cdFx0XHRcdFx0bWUubWluTm90WmVybyA9IG1lLm1pbjtcblx0XHRcdFx0fSBlbHNlIGlmIChtZS5tYXggPCAxKSB7XG5cdFx0XHRcdFx0bWUubWluTm90WmVybyA9IE1hdGgucG93KDEwLCBNYXRoLmZsb29yKGhlbHBlcnMubG9nMTAobWUubWF4KSkpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdG1lLm1pbk5vdFplcm8gPSBERUZBVUxUX01JTjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0sXG5cdFx0YnVpbGRUaWNrczogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG9wdHMgPSBtZS5vcHRpb25zO1xuXHRcdFx0dmFyIHRpY2tPcHRzID0gb3B0cy50aWNrcztcblx0XHRcdHZhciByZXZlcnNlID0gIW1lLmlzSG9yaXpvbnRhbCgpO1xuXG5cdFx0XHR2YXIgZ2VuZXJhdGlvbk9wdGlvbnMgPSB7XG5cdFx0XHRcdG1pbjogdGlja09wdHMubWluLFxuXHRcdFx0XHRtYXg6IHRpY2tPcHRzLm1heFxuXHRcdFx0fTtcblx0XHRcdHZhciB0aWNrcyA9IG1lLnRpY2tzID0gZ2VuZXJhdGVUaWNrcyhnZW5lcmF0aW9uT3B0aW9ucywgbWUpO1xuXG5cdFx0XHQvLyBBdCB0aGlzIHBvaW50LCB3ZSBuZWVkIHRvIHVwZGF0ZSBvdXIgbWF4IGFuZCBtaW4gZ2l2ZW4gdGhlIHRpY2sgdmFsdWVzIHNpbmNlIHdlIGhhdmUgZXhwYW5kZWQgdGhlXG5cdFx0XHQvLyByYW5nZSBvZiB0aGUgc2NhbGVcblx0XHRcdG1lLm1heCA9IGhlbHBlcnMubWF4KHRpY2tzKTtcblx0XHRcdG1lLm1pbiA9IGhlbHBlcnMubWluKHRpY2tzKTtcblxuXHRcdFx0aWYgKHRpY2tPcHRzLnJldmVyc2UpIHtcblx0XHRcdFx0cmV2ZXJzZSA9ICFyZXZlcnNlO1xuXHRcdFx0XHRtZS5zdGFydCA9IG1lLm1heDtcblx0XHRcdFx0bWUuZW5kID0gbWUubWluO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bWUuc3RhcnQgPSBtZS5taW47XG5cdFx0XHRcdG1lLmVuZCA9IG1lLm1heDtcblx0XHRcdH1cblx0XHRcdGlmIChyZXZlcnNlKSB7XG5cdFx0XHRcdHRpY2tzLnJldmVyc2UoKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdGNvbnZlcnRUaWNrc1RvTGFiZWxzOiBmdW5jdGlvbigpIHtcblx0XHRcdHRoaXMudGlja1ZhbHVlcyA9IHRoaXMudGlja3Muc2xpY2UoKTtcblxuXHRcdFx0U2NhbGUucHJvdG90eXBlLmNvbnZlcnRUaWNrc1RvTGFiZWxzLmNhbGwodGhpcyk7XG5cdFx0fSxcblx0XHQvLyBHZXQgdGhlIGNvcnJlY3QgdG9vbHRpcCBsYWJlbFxuXHRcdGdldExhYmVsRm9ySW5kZXg6IGZ1bmN0aW9uKGluZGV4LCBkYXRhc2V0SW5kZXgpIHtcblx0XHRcdHJldHVybiArdGhpcy5nZXRSaWdodFZhbHVlKHRoaXMuY2hhcnQuZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdLmRhdGFbaW5kZXhdKTtcblx0XHR9LFxuXHRcdGdldFBpeGVsRm9yVGljazogZnVuY3Rpb24oaW5kZXgpIHtcblx0XHRcdHJldHVybiB0aGlzLmdldFBpeGVsRm9yVmFsdWUodGhpcy50aWNrVmFsdWVzW2luZGV4XSk7XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgdGljay5cblx0XHQgKiBAcGFyYW0ge051bWJlcn0gdmFsdWUgLSBUaGUgbWluaW11bSBub3QgemVybyB2YWx1ZS5cblx0XHQgKiBAcmV0dXJuIHtOdW1iZXJ9IFRoZSBmaXJzdCB0aWNrIHZhbHVlLlxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0X2dldEZpcnN0VGlja1ZhbHVlOiBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdFx0dmFyIGV4cCA9IE1hdGguZmxvb3IoaGVscGVycy5sb2cxMCh2YWx1ZSkpO1xuXHRcdFx0dmFyIHNpZ25pZmljYW5kID0gTWF0aC5mbG9vcih2YWx1ZSAvIE1hdGgucG93KDEwLCBleHApKTtcblxuXHRcdFx0cmV0dXJuIHNpZ25pZmljYW5kICogTWF0aC5wb3coMTAsIGV4cCk7XG5cdFx0fSxcblx0XHRnZXRQaXhlbEZvclZhbHVlOiBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciByZXZlcnNlID0gbWUub3B0aW9ucy50aWNrcy5yZXZlcnNlO1xuXHRcdFx0dmFyIGxvZzEwID0gaGVscGVycy5sb2cxMDtcblx0XHRcdHZhciBmaXJzdFRpY2tWYWx1ZSA9IG1lLl9nZXRGaXJzdFRpY2tWYWx1ZShtZS5taW5Ob3RaZXJvKTtcblx0XHRcdHZhciBvZmZzZXQgPSAwO1xuXHRcdFx0dmFyIGlubmVyRGltZW5zaW9uLCBwaXhlbCwgc3RhcnQsIGVuZCwgc2lnbjtcblxuXHRcdFx0dmFsdWUgPSArbWUuZ2V0UmlnaHRWYWx1ZSh2YWx1ZSk7XG5cdFx0XHRpZiAocmV2ZXJzZSkge1xuXHRcdFx0XHRzdGFydCA9IG1lLmVuZDtcblx0XHRcdFx0ZW5kID0gbWUuc3RhcnQ7XG5cdFx0XHRcdHNpZ24gPSAtMTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHN0YXJ0ID0gbWUuc3RhcnQ7XG5cdFx0XHRcdGVuZCA9IG1lLmVuZDtcblx0XHRcdFx0c2lnbiA9IDE7XG5cdFx0XHR9XG5cdFx0XHRpZiAobWUuaXNIb3Jpem9udGFsKCkpIHtcblx0XHRcdFx0aW5uZXJEaW1lbnNpb24gPSBtZS53aWR0aDtcblx0XHRcdFx0cGl4ZWwgPSByZXZlcnNlID8gbWUucmlnaHQgOiBtZS5sZWZ0O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aW5uZXJEaW1lbnNpb24gPSBtZS5oZWlnaHQ7XG5cdFx0XHRcdHNpZ24gKj0gLTE7IC8vIGludmVydCwgc2luY2UgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZSBjYW52YXMgaXMgYXQgcGl4ZWwgKDAsIDApXG5cdFx0XHRcdHBpeGVsID0gcmV2ZXJzZSA/IG1lLnRvcCA6IG1lLmJvdHRvbTtcblx0XHRcdH1cblx0XHRcdGlmICh2YWx1ZSAhPT0gc3RhcnQpIHtcblx0XHRcdFx0aWYgKHN0YXJ0ID09PSAwKSB7IC8vIGluY2x1ZGUgemVybyB0aWNrXG5cdFx0XHRcdFx0b2Zmc2V0ID0gaGVscGVycy5nZXRWYWx1ZU9yRGVmYXVsdChcblx0XHRcdFx0XHRcdG1lLm9wdGlvbnMudGlja3MuZm9udFNpemUsXG5cdFx0XHRcdFx0XHRDaGFydC5kZWZhdWx0cy5nbG9iYWwuZGVmYXVsdEZvbnRTaXplXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRpbm5lckRpbWVuc2lvbiAtPSBvZmZzZXQ7XG5cdFx0XHRcdFx0c3RhcnQgPSBmaXJzdFRpY2tWYWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAodmFsdWUgIT09IDApIHtcblx0XHRcdFx0XHRvZmZzZXQgKz0gaW5uZXJEaW1lbnNpb24gLyAobG9nMTAoZW5kKSAtIGxvZzEwKHN0YXJ0KSkgKiAobG9nMTAodmFsdWUpIC0gbG9nMTAoc3RhcnQpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRwaXhlbCArPSBzaWduICogb2Zmc2V0O1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHBpeGVsO1xuXHRcdH0sXG5cdFx0Z2V0VmFsdWVGb3JQaXhlbDogZnVuY3Rpb24ocGl4ZWwpIHtcblx0XHRcdHZhciBtZSA9IHRoaXM7XG5cdFx0XHR2YXIgcmV2ZXJzZSA9IG1lLm9wdGlvbnMudGlja3MucmV2ZXJzZTtcblx0XHRcdHZhciBsb2cxMCA9IGhlbHBlcnMubG9nMTA7XG5cdFx0XHR2YXIgZmlyc3RUaWNrVmFsdWUgPSBtZS5fZ2V0Rmlyc3RUaWNrVmFsdWUobWUubWluTm90WmVybyk7XG5cdFx0XHR2YXIgaW5uZXJEaW1lbnNpb24sIHN0YXJ0LCBlbmQsIHZhbHVlO1xuXG5cdFx0XHRpZiAocmV2ZXJzZSkge1xuXHRcdFx0XHRzdGFydCA9IG1lLmVuZDtcblx0XHRcdFx0ZW5kID0gbWUuc3RhcnQ7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzdGFydCA9IG1lLnN0YXJ0O1xuXHRcdFx0XHRlbmQgPSBtZS5lbmQ7XG5cdFx0XHR9XG5cdFx0XHRpZiAobWUuaXNIb3Jpem9udGFsKCkpIHtcblx0XHRcdFx0aW5uZXJEaW1lbnNpb24gPSBtZS53aWR0aDtcblx0XHRcdFx0dmFsdWUgPSByZXZlcnNlID8gbWUucmlnaHQgLSBwaXhlbCA6IHBpeGVsIC0gbWUubGVmdDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGlubmVyRGltZW5zaW9uID0gbWUuaGVpZ2h0O1xuXHRcdFx0XHR2YWx1ZSA9IHJldmVyc2UgPyBwaXhlbCAtIG1lLnRvcCA6IG1lLmJvdHRvbSAtIHBpeGVsO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHZhbHVlICE9PSBzdGFydCkge1xuXHRcdFx0XHRpZiAoc3RhcnQgPT09IDApIHsgLy8gaW5jbHVkZSB6ZXJvIHRpY2tcblx0XHRcdFx0XHR2YXIgb2Zmc2V0ID0gaGVscGVycy5nZXRWYWx1ZU9yRGVmYXVsdChcblx0XHRcdFx0XHRcdG1lLm9wdGlvbnMudGlja3MuZm9udFNpemUsXG5cdFx0XHRcdFx0XHRDaGFydC5kZWZhdWx0cy5nbG9iYWwuZGVmYXVsdEZvbnRTaXplXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR2YWx1ZSAtPSBvZmZzZXQ7XG5cdFx0XHRcdFx0aW5uZXJEaW1lbnNpb24gLT0gb2Zmc2V0O1xuXHRcdFx0XHRcdHN0YXJ0ID0gZmlyc3RUaWNrVmFsdWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0dmFsdWUgKj0gbG9nMTAoZW5kKSAtIGxvZzEwKHN0YXJ0KTtcblx0XHRcdFx0dmFsdWUgLz0gaW5uZXJEaW1lbnNpb247XG5cdFx0XHRcdHZhbHVlID0gTWF0aC5wb3coMTAsIGxvZzEwKHN0YXJ0KSArIHZhbHVlKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHR9XG5cdH0pO1xuXG5cdHNjYWxlU2VydmljZS5yZWdpc3RlclNjYWxlVHlwZSgnbG9nYXJpdGhtaWMnLCBMb2dhcml0aG1pY1NjYWxlLCBkZWZhdWx0Q29uZmlnKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///f1c0\n")},f3c1:function(module,exports,__webpack_require__){"use strict";eval("\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ \"beaa\");\nvar elements = __webpack_require__(/*! ../elements/index */ \"0687\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\n\ndefaults._set('line', {\n\tshowLines: true,\n\tspanGaps: false,\n\n\thover: {\n\t\tmode: 'label'\n\t},\n\n\tscales: {\n\t\txAxes: [{\n\t\t\ttype: 'category',\n\t\t\tid: 'x-axis-0'\n\t\t}],\n\t\tyAxes: [{\n\t\t\ttype: 'linear',\n\t\t\tid: 'y-axis-0'\n\t\t}]\n\t}\n});\n\nmodule.exports = function(Chart) {\n\n\tfunction lineEnabled(dataset, options) {\n\t\treturn helpers.valueOrDefault(dataset.showLine, options.showLines);\n\t}\n\n\tChart.controllers.line = Chart.DatasetController.extend({\n\n\t\tdatasetElementType: elements.Line,\n\n\t\tdataElementType: elements.Point,\n\n\t\tupdate: function(reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar line = meta.dataset;\n\t\t\tvar points = meta.data || [];\n\t\t\tvar options = me.chart.options;\n\t\t\tvar lineElementOptions = options.elements.line;\n\t\t\tvar scale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar i, ilen, custom;\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar showLine = lineEnabled(dataset, options);\n\n\t\t\t// Update Line\n\t\t\tif (showLine) {\n\t\t\t\tcustom = line.custom || {};\n\n\t\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\t\tif ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {\n\t\t\t\t\tdataset.lineTension = dataset.tension;\n\t\t\t\t}\n\n\t\t\t\t// Utility\n\t\t\t\tline._scale = scale;\n\t\t\t\tline._datasetIndex = me.index;\n\t\t\t\t// Data\n\t\t\t\tline._children = points;\n\t\t\t\t// Model\n\t\t\t\tline._model = {\n\t\t\t\t\t// Appearance\n\t\t\t\t\t// The default behavior of lines is to break at null values, according\n\t\t\t\t\t// to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158\n\t\t\t\t\t// This option gives lines the ability to span gaps\n\t\t\t\t\tspanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,\n\t\t\t\t\ttension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension),\n\t\t\t\t\tbackgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),\n\t\t\t\t\tborderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),\n\t\t\t\t\tborderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),\n\t\t\t\t\tborderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),\n\t\t\t\t\tborderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),\n\t\t\t\t\tborderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),\n\t\t\t\t\tborderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),\n\t\t\t\t\tfill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),\n\t\t\t\t\tsteppedLine: custom.steppedLine ? custom.steppedLine : helpers.valueOrDefault(dataset.steppedLine, lineElementOptions.stepped),\n\t\t\t\t\tcubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.valueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode),\n\t\t\t\t};\n\n\t\t\t\tline.pivot();\n\t\t\t}\n\n\t\t\t// Update Points\n\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\tme.updateElement(points[i], i, reset);\n\t\t\t}\n\n\t\t\tif (showLine && line._model.tension !== 0) {\n\t\t\t\tme.updateBezierControlPoints();\n\t\t\t}\n\n\t\t\t// Now pivot the point for animation\n\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\tpoints[i].pivot();\n\t\t\t}\n\t\t},\n\n\t\tgetPointBackgroundColor: function(point, index) {\n\t\t\tvar backgroundColor = this.chart.options.elements.point.backgroundColor;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (custom.backgroundColor) {\n\t\t\t\tbackgroundColor = custom.backgroundColor;\n\t\t\t} else if (dataset.pointBackgroundColor) {\n\t\t\t\tbackgroundColor = helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);\n\t\t\t} else if (dataset.backgroundColor) {\n\t\t\t\tbackgroundColor = dataset.backgroundColor;\n\t\t\t}\n\n\t\t\treturn backgroundColor;\n\t\t},\n\n\t\tgetPointBorderColor: function(point, index) {\n\t\t\tvar borderColor = this.chart.options.elements.point.borderColor;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (custom.borderColor) {\n\t\t\t\tborderColor = custom.borderColor;\n\t\t\t} else if (dataset.pointBorderColor) {\n\t\t\t\tborderColor = helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);\n\t\t\t} else if (dataset.borderColor) {\n\t\t\t\tborderColor = dataset.borderColor;\n\t\t\t}\n\n\t\t\treturn borderColor;\n\t\t},\n\n\t\tgetPointBorderWidth: function(point, index) {\n\t\t\tvar borderWidth = this.chart.options.elements.point.borderWidth;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (!isNaN(custom.borderWidth)) {\n\t\t\t\tborderWidth = custom.borderWidth;\n\t\t\t} else if (!isNaN(dataset.pointBorderWidth) || helpers.isArray(dataset.pointBorderWidth)) {\n\t\t\t\tborderWidth = helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);\n\t\t\t} else if (!isNaN(dataset.borderWidth)) {\n\t\t\t\tborderWidth = dataset.borderWidth;\n\t\t\t}\n\n\t\t\treturn borderWidth;\n\t\t},\n\n\t\tgetPointRotation: function(point, index) {\n\t\t\tvar pointRotation = this.chart.options.elements.point.rotation;\n\t\t\tvar dataset = this.getDataset();\n\t\t\tvar custom = point.custom || {};\n\n\t\t\tif (!isNaN(custom.rotation)) {\n\t\t\t\tpointRotation = custom.rotation;\n\t\t\t} else if (!isNaN(dataset.pointRotation) || helpers.isArray(dataset.pointRotation)) {\n\t\t\t\tpointRotation = helpers.valueAtIndexOrDefault(dataset.pointRotation, index, pointRotation);\n\t\t\t}\n\t\t\treturn pointRotation;\n\t\t},\n\n\t\tupdateElement: function(point, index, reset) {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar custom = point.custom || {};\n\t\t\tvar dataset = me.getDataset();\n\t\t\tvar datasetIndex = me.index;\n\t\t\tvar value = dataset.data[index];\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar xScale = me.getScaleForId(meta.xAxisID);\n\t\t\tvar pointOptions = me.chart.options.elements.point;\n\t\t\tvar x, y;\n\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {\n\t\t\t\tdataset.pointRadius = dataset.radius;\n\t\t\t}\n\t\t\tif ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {\n\t\t\t\tdataset.pointHitRadius = dataset.hitRadius;\n\t\t\t}\n\n\t\t\tx = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex);\n\t\t\ty = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);\n\n\t\t\t// Utility\n\t\t\tpoint._xScale = xScale;\n\t\t\tpoint._yScale = yScale;\n\t\t\tpoint._datasetIndex = datasetIndex;\n\t\t\tpoint._index = index;\n\n\t\t\t// Desired view properties\n\t\t\tpoint._model = {\n\t\t\t\tx: x,\n\t\t\t\ty: y,\n\t\t\t\tskip: custom.skip || isNaN(x) || isNaN(y),\n\t\t\t\t// Appearance\n\t\t\t\tradius: custom.radius || helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),\n\t\t\t\tpointStyle: custom.pointStyle || helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),\n\t\t\t\trotation: me.getPointRotation(point, index),\n\t\t\t\tbackgroundColor: me.getPointBackgroundColor(point, index),\n\t\t\t\tborderColor: me.getPointBorderColor(point, index),\n\t\t\t\tborderWidth: me.getPointBorderWidth(point, index),\n\t\t\t\ttension: meta.dataset._model ? meta.dataset._model.tension : 0,\n\t\t\t\tsteppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,\n\t\t\t\t// Tooltip\n\t\t\t\thitRadius: custom.hitRadius || helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)\n\t\t\t};\n\t\t},\n\n\t\tcalculatePointY: function(value, index, datasetIndex) {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\t\t\tvar sumPos = 0;\n\t\t\tvar sumNeg = 0;\n\t\t\tvar i, ds, dsMeta;\n\n\t\t\tif (yScale.options.stacked) {\n\t\t\t\tfor (i = 0; i < datasetIndex; i++) {\n\t\t\t\t\tds = chart.data.datasets[i];\n\t\t\t\t\tdsMeta = chart.getDatasetMeta(i);\n\t\t\t\t\tif (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {\n\t\t\t\t\t\tvar stackedRightValue = Number(yScale.getRightValue(ds.data[index]));\n\t\t\t\t\t\tif (stackedRightValue < 0) {\n\t\t\t\t\t\t\tsumNeg += stackedRightValue || 0;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsumPos += stackedRightValue || 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar rightValue = Number(yScale.getRightValue(value));\n\t\t\t\tif (rightValue < 0) {\n\t\t\t\t\treturn yScale.getPixelForValue(sumNeg + rightValue);\n\t\t\t\t}\n\t\t\t\treturn yScale.getPixelForValue(sumPos + rightValue);\n\t\t\t}\n\n\t\t\treturn yScale.getPixelForValue(value);\n\t\t},\n\n\t\tupdateBezierControlPoints: function() {\n\t\t\tvar me = this;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar area = me.chart.chartArea;\n\t\t\tvar points = (meta.data || []);\n\t\t\tvar i, ilen, point, model, controlPoints;\n\n\t\t\t// Only consider points that are drawn in case the spanGaps option is used\n\t\t\tif (meta.dataset._model.spanGaps) {\n\t\t\t\tpoints = points.filter(function(pt) {\n\t\t\t\t\treturn !pt._model.skip;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction capControlPoint(pt, min, max) {\n\t\t\t\treturn Math.max(Math.min(pt, max), min);\n\t\t\t}\n\n\t\t\tif (meta.dataset._model.cubicInterpolationMode === 'monotone') {\n\t\t\t\thelpers.splineCurveMonotone(points);\n\t\t\t} else {\n\t\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\t\tpoint = points[i];\n\t\t\t\t\tmodel = point._model;\n\t\t\t\t\tcontrolPoints = helpers.splineCurve(\n\t\t\t\t\t\thelpers.previousItem(points, i)._model,\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\thelpers.nextItem(points, i)._model,\n\t\t\t\t\t\tmeta.dataset._model.tension\n\t\t\t\t\t);\n\t\t\t\t\tmodel.controlPointPreviousX = controlPoints.previous.x;\n\t\t\t\t\tmodel.controlPointPreviousY = controlPoints.previous.y;\n\t\t\t\t\tmodel.controlPointNextX = controlPoints.next.x;\n\t\t\t\t\tmodel.controlPointNextY = controlPoints.next.y;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (me.chart.options.elements.line.capBezierPoints) {\n\t\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\t\tmodel = points[i]._model;\n\t\t\t\t\tmodel.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);\n\t\t\t\t\tmodel.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);\n\t\t\t\t\tmodel.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);\n\t\t\t\t\tmodel.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tdraw: function() {\n\t\t\tvar me = this;\n\t\t\tvar chart = me.chart;\n\t\t\tvar meta = me.getMeta();\n\t\t\tvar points = meta.data || [];\n\t\t\tvar area = chart.chartArea;\n\t\t\tvar ilen = points.length;\n\t\t\tvar halfBorderWidth;\n\t\t\tvar i = 0;\n\n\t\t\tif (lineEnabled(me.getDataset(), chart.options)) {\n\t\t\t\thalfBorderWidth = (meta.dataset._model.borderWidth || 0) / 2;\n\n\t\t\t\thelpers.canvas.clipArea(chart.ctx, {\n\t\t\t\t\tleft: area.left,\n\t\t\t\t\tright: area.right,\n\t\t\t\t\ttop: area.top - halfBorderWidth,\n\t\t\t\t\tbottom: area.bottom + halfBorderWidth\n\t\t\t\t});\n\n\t\t\t\tmeta.dataset.draw();\n\n\t\t\t\thelpers.canvas.unclipArea(chart.ctx);\n\t\t\t}\n\n\t\t\t// Draw the points\n\t\t\tfor (; i < ilen; ++i) {\n\t\t\t\tpoints[i].draw(area);\n\t\t\t}\n\t\t},\n\n\t\tsetHoverStyle: function(element) {\n\t\t\t// Point\n\t\t\tvar dataset = this.chart.data.datasets[element._datasetIndex];\n\t\t\tvar index = element._index;\n\t\t\tvar custom = element.custom || {};\n\t\t\tvar model = element._model;\n\n\t\t\telement.$previousStyle = {\n\t\t\t\tbackgroundColor: model.backgroundColor,\n\t\t\t\tborderColor: model.borderColor,\n\t\t\t\tborderWidth: model.borderWidth,\n\t\t\t\tradius: model.radius\n\t\t\t};\n\n\t\t\tmodel.backgroundColor = custom.hoverBackgroundColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));\n\t\t\tmodel.borderColor = custom.hoverBorderColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));\n\t\t\tmodel.borderWidth = custom.hoverBorderWidth || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);\n\t\t\tmodel.radius = custom.hoverRadius || helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);\n\t\t},\n\t});\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZjNjMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5saW5lLmpzPzFiNDQiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuLi9jb3JlL2NvcmUuZGVmYXVsdHMnKTtcbnZhciBlbGVtZW50cyA9IHJlcXVpcmUoJy4uL2VsZW1lbnRzL2luZGV4Jyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcblxuZGVmYXVsdHMuX3NldCgnbGluZScsIHtcblx0c2hvd0xpbmVzOiB0cnVlLFxuXHRzcGFuR2FwczogZmFsc2UsXG5cblx0aG92ZXI6IHtcblx0XHRtb2RlOiAnbGFiZWwnXG5cdH0sXG5cblx0c2NhbGVzOiB7XG5cdFx0eEF4ZXM6IFt7XG5cdFx0XHR0eXBlOiAnY2F0ZWdvcnknLFxuXHRcdFx0aWQ6ICd4LWF4aXMtMCdcblx0XHR9XSxcblx0XHR5QXhlczogW3tcblx0XHRcdHR5cGU6ICdsaW5lYXInLFxuXHRcdFx0aWQ6ICd5LWF4aXMtMCdcblx0XHR9XVxuXHR9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDaGFydCkge1xuXG5cdGZ1bmN0aW9uIGxpbmVFbmFibGVkKGRhdGFzZXQsIG9wdGlvbnMpIHtcblx0XHRyZXR1cm4gaGVscGVycy52YWx1ZU9yRGVmYXVsdChkYXRhc2V0LnNob3dMaW5lLCBvcHRpb25zLnNob3dMaW5lcyk7XG5cdH1cblxuXHRDaGFydC5jb250cm9sbGVycy5saW5lID0gQ2hhcnQuRGF0YXNldENvbnRyb2xsZXIuZXh0ZW5kKHtcblxuXHRcdGRhdGFzZXRFbGVtZW50VHlwZTogZWxlbWVudHMuTGluZSxcblxuXHRcdGRhdGFFbGVtZW50VHlwZTogZWxlbWVudHMuUG9pbnQsXG5cblx0XHR1cGRhdGU6IGZ1bmN0aW9uKHJlc2V0KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIG1ldGEgPSBtZS5nZXRNZXRhKCk7XG5cdFx0XHR2YXIgbGluZSA9IG1ldGEuZGF0YXNldDtcblx0XHRcdHZhciBwb2ludHMgPSBtZXRhLmRhdGEgfHwgW107XG5cdFx0XHR2YXIgb3B0aW9ucyA9IG1lLmNoYXJ0Lm9wdGlvbnM7XG5cdFx0XHR2YXIgbGluZUVsZW1lbnRPcHRpb25zID0gb3B0aW9ucy5lbGVtZW50cy5saW5lO1xuXHRcdFx0dmFyIHNjYWxlID0gbWUuZ2V0U2NhbGVGb3JJZChtZXRhLnlBeGlzSUQpO1xuXHRcdFx0dmFyIGksIGlsZW4sIGN1c3RvbTtcblx0XHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xuXHRcdFx0dmFyIHNob3dMaW5lID0gbGluZUVuYWJsZWQoZGF0YXNldCwgb3B0aW9ucyk7XG5cblx0XHRcdC8vIFVwZGF0ZSBMaW5lXG5cdFx0XHRpZiAoc2hvd0xpbmUpIHtcblx0XHRcdFx0Y3VzdG9tID0gbGluZS5jdXN0b20gfHwge307XG5cblx0XHRcdFx0Ly8gQ29tcGF0aWJpbGl0eTogSWYgdGhlIHByb3BlcnRpZXMgYXJlIGRlZmluZWQgd2l0aCBvbmx5IHRoZSBvbGQgbmFtZSwgdXNlIHRob3NlIHZhbHVlc1xuXHRcdFx0XHRpZiAoKGRhdGFzZXQudGVuc2lvbiAhPT0gdW5kZWZpbmVkKSAmJiAoZGF0YXNldC5saW5lVGVuc2lvbiA9PT0gdW5kZWZpbmVkKSkge1xuXHRcdFx0XHRcdGRhdGFzZXQubGluZVRlbnNpb24gPSBkYXRhc2V0LnRlbnNpb247XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBVdGlsaXR5XG5cdFx0XHRcdGxpbmUuX3NjYWxlID0gc2NhbGU7XG5cdFx0XHRcdGxpbmUuX2RhdGFzZXRJbmRleCA9IG1lLmluZGV4O1xuXHRcdFx0XHQvLyBEYXRhXG5cdFx0XHRcdGxpbmUuX2NoaWxkcmVuID0gcG9pbnRzO1xuXHRcdFx0XHQvLyBNb2RlbFxuXHRcdFx0XHRsaW5lLl9tb2RlbCA9IHtcblx0XHRcdFx0XHQvLyBBcHBlYXJhbmNlXG5cdFx0XHRcdFx0Ly8gVGhlIGRlZmF1bHQgYmVoYXZpb3Igb2YgbGluZXMgaXMgdG8gYnJlYWsgYXQgbnVsbCB2YWx1ZXMsIGFjY29yZGluZ1xuXHRcdFx0XHRcdC8vIHRvIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8yNDM1I2lzc3VlY29tbWVudC0yMTY3MTgxNThcblx0XHRcdFx0XHQvLyBUaGlzIG9wdGlvbiBnaXZlcyBsaW5lcyB0aGUgYWJpbGl0eSB0byBzcGFuIGdhcHNcblx0XHRcdFx0XHRzcGFuR2FwczogZGF0YXNldC5zcGFuR2FwcyA/IGRhdGFzZXQuc3BhbkdhcHMgOiBvcHRpb25zLnNwYW5HYXBzLFxuXHRcdFx0XHRcdHRlbnNpb246IGN1c3RvbS50ZW5zaW9uID8gY3VzdG9tLnRlbnNpb24gOiBoZWxwZXJzLnZhbHVlT3JEZWZhdWx0KGRhdGFzZXQubGluZVRlbnNpb24sIGxpbmVFbGVtZW50T3B0aW9ucy50ZW5zaW9uKSxcblx0XHRcdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IGN1c3RvbS5iYWNrZ3JvdW5kQ29sb3IgPyBjdXN0b20uYmFja2dyb3VuZENvbG9yIDogKGRhdGFzZXQuYmFja2dyb3VuZENvbG9yIHx8IGxpbmVFbGVtZW50T3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IpLFxuXHRcdFx0XHRcdGJvcmRlcldpZHRoOiBjdXN0b20uYm9yZGVyV2lkdGggPyBjdXN0b20uYm9yZGVyV2lkdGggOiAoZGF0YXNldC5ib3JkZXJXaWR0aCB8fCBsaW5lRWxlbWVudE9wdGlvbnMuYm9yZGVyV2lkdGgpLFxuXHRcdFx0XHRcdGJvcmRlckNvbG9yOiBjdXN0b20uYm9yZGVyQ29sb3IgPyBjdXN0b20uYm9yZGVyQ29sb3IgOiAoZGF0YXNldC5ib3JkZXJDb2xvciB8fCBsaW5lRWxlbWVudE9wdGlvbnMuYm9yZGVyQ29sb3IpLFxuXHRcdFx0XHRcdGJvcmRlckNhcFN0eWxlOiBjdXN0b20uYm9yZGVyQ2FwU3R5bGUgPyBjdXN0b20uYm9yZGVyQ2FwU3R5bGUgOiAoZGF0YXNldC5ib3JkZXJDYXBTdHlsZSB8fCBsaW5lRWxlbWVudE9wdGlvbnMuYm9yZGVyQ2FwU3R5bGUpLFxuXHRcdFx0XHRcdGJvcmRlckRhc2g6IGN1c3RvbS5ib3JkZXJEYXNoID8gY3VzdG9tLmJvcmRlckRhc2ggOiAoZGF0YXNldC5ib3JkZXJEYXNoIHx8IGxpbmVFbGVtZW50T3B0aW9ucy5ib3JkZXJEYXNoKSxcblx0XHRcdFx0XHRib3JkZXJEYXNoT2Zmc2V0OiBjdXN0b20uYm9yZGVyRGFzaE9mZnNldCA/IGN1c3RvbS5ib3JkZXJEYXNoT2Zmc2V0IDogKGRhdGFzZXQuYm9yZGVyRGFzaE9mZnNldCB8fCBsaW5lRWxlbWVudE9wdGlvbnMuYm9yZGVyRGFzaE9mZnNldCksXG5cdFx0XHRcdFx0Ym9yZGVySm9pblN0eWxlOiBjdXN0b20uYm9yZGVySm9pblN0eWxlID8gY3VzdG9tLmJvcmRlckpvaW5TdHlsZSA6IChkYXRhc2V0LmJvcmRlckpvaW5TdHlsZSB8fCBsaW5lRWxlbWVudE9wdGlvbnMuYm9yZGVySm9pblN0eWxlKSxcblx0XHRcdFx0XHRmaWxsOiBjdXN0b20uZmlsbCA/IGN1c3RvbS5maWxsIDogKGRhdGFzZXQuZmlsbCAhPT0gdW5kZWZpbmVkID8gZGF0YXNldC5maWxsIDogbGluZUVsZW1lbnRPcHRpb25zLmZpbGwpLFxuXHRcdFx0XHRcdHN0ZXBwZWRMaW5lOiBjdXN0b20uc3RlcHBlZExpbmUgPyBjdXN0b20uc3RlcHBlZExpbmUgOiBoZWxwZXJzLnZhbHVlT3JEZWZhdWx0KGRhdGFzZXQuc3RlcHBlZExpbmUsIGxpbmVFbGVtZW50T3B0aW9ucy5zdGVwcGVkKSxcblx0XHRcdFx0XHRjdWJpY0ludGVycG9sYXRpb25Nb2RlOiBjdXN0b20uY3ViaWNJbnRlcnBvbGF0aW9uTW9kZSA/IGN1c3RvbS5jdWJpY0ludGVycG9sYXRpb25Nb2RlIDogaGVscGVycy52YWx1ZU9yRGVmYXVsdChkYXRhc2V0LmN1YmljSW50ZXJwb2xhdGlvbk1vZGUsIGxpbmVFbGVtZW50T3B0aW9ucy5jdWJpY0ludGVycG9sYXRpb25Nb2RlKSxcblx0XHRcdFx0fTtcblxuXHRcdFx0XHRsaW5lLnBpdm90KCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFVwZGF0ZSBQb2ludHNcblx0XHRcdGZvciAoaSA9IDAsIGlsZW4gPSBwb2ludHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG5cdFx0XHRcdG1lLnVwZGF0ZUVsZW1lbnQocG9pbnRzW2ldLCBpLCByZXNldCk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChzaG93TGluZSAmJiBsaW5lLl9tb2RlbC50ZW5zaW9uICE9PSAwKSB7XG5cdFx0XHRcdG1lLnVwZGF0ZUJlemllckNvbnRyb2xQb2ludHMoKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTm93IHBpdm90IHRoZSBwb2ludCBmb3IgYW5pbWF0aW9uXG5cdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuXHRcdFx0XHRwb2ludHNbaV0ucGl2b3QoKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0Z2V0UG9pbnRCYWNrZ3JvdW5kQ29sb3I6IGZ1bmN0aW9uKHBvaW50LCBpbmRleCkge1xuXHRcdFx0dmFyIGJhY2tncm91bmRDb2xvciA9IHRoaXMuY2hhcnQub3B0aW9ucy5lbGVtZW50cy5wb2ludC5iYWNrZ3JvdW5kQ29sb3I7XG5cdFx0XHR2YXIgZGF0YXNldCA9IHRoaXMuZ2V0RGF0YXNldCgpO1xuXHRcdFx0dmFyIGN1c3RvbSA9IHBvaW50LmN1c3RvbSB8fCB7fTtcblxuXHRcdFx0aWYgKGN1c3RvbS5iYWNrZ3JvdW5kQ29sb3IpIHtcblx0XHRcdFx0YmFja2dyb3VuZENvbG9yID0gY3VzdG9tLmJhY2tncm91bmRDb2xvcjtcblx0XHRcdH0gZWxzZSBpZiAoZGF0YXNldC5wb2ludEJhY2tncm91bmRDb2xvcikge1xuXHRcdFx0XHRiYWNrZ3JvdW5kQ29sb3IgPSBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdChkYXRhc2V0LnBvaW50QmFja2dyb3VuZENvbG9yLCBpbmRleCwgYmFja2dyb3VuZENvbG9yKTtcblx0XHRcdH0gZWxzZSBpZiAoZGF0YXNldC5iYWNrZ3JvdW5kQ29sb3IpIHtcblx0XHRcdFx0YmFja2dyb3VuZENvbG9yID0gZGF0YXNldC5iYWNrZ3JvdW5kQ29sb3I7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBiYWNrZ3JvdW5kQ29sb3I7XG5cdFx0fSxcblxuXHRcdGdldFBvaW50Qm9yZGVyQ29sb3I6IGZ1bmN0aW9uKHBvaW50LCBpbmRleCkge1xuXHRcdFx0dmFyIGJvcmRlckNvbG9yID0gdGhpcy5jaGFydC5vcHRpb25zLmVsZW1lbnRzLnBvaW50LmJvcmRlckNvbG9yO1xuXHRcdFx0dmFyIGRhdGFzZXQgPSB0aGlzLmdldERhdGFzZXQoKTtcblx0XHRcdHZhciBjdXN0b20gPSBwb2ludC5jdXN0b20gfHwge307XG5cblx0XHRcdGlmIChjdXN0b20uYm9yZGVyQ29sb3IpIHtcblx0XHRcdFx0Ym9yZGVyQ29sb3IgPSBjdXN0b20uYm9yZGVyQ29sb3I7XG5cdFx0XHR9IGVsc2UgaWYgKGRhdGFzZXQucG9pbnRCb3JkZXJDb2xvcikge1xuXHRcdFx0XHRib3JkZXJDb2xvciA9IGhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0KGRhdGFzZXQucG9pbnRCb3JkZXJDb2xvciwgaW5kZXgsIGJvcmRlckNvbG9yKTtcblx0XHRcdH0gZWxzZSBpZiAoZGF0YXNldC5ib3JkZXJDb2xvcikge1xuXHRcdFx0XHRib3JkZXJDb2xvciA9IGRhdGFzZXQuYm9yZGVyQ29sb3I7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBib3JkZXJDb2xvcjtcblx0XHR9LFxuXG5cdFx0Z2V0UG9pbnRCb3JkZXJXaWR0aDogZnVuY3Rpb24ocG9pbnQsIGluZGV4KSB7XG5cdFx0XHR2YXIgYm9yZGVyV2lkdGggPSB0aGlzLmNoYXJ0Lm9wdGlvbnMuZWxlbWVudHMucG9pbnQuYm9yZGVyV2lkdGg7XG5cdFx0XHR2YXIgZGF0YXNldCA9IHRoaXMuZ2V0RGF0YXNldCgpO1xuXHRcdFx0dmFyIGN1c3RvbSA9IHBvaW50LmN1c3RvbSB8fCB7fTtcblxuXHRcdFx0aWYgKCFpc05hTihjdXN0b20uYm9yZGVyV2lkdGgpKSB7XG5cdFx0XHRcdGJvcmRlcldpZHRoID0gY3VzdG9tLmJvcmRlcldpZHRoO1xuXHRcdFx0fSBlbHNlIGlmICghaXNOYU4oZGF0YXNldC5wb2ludEJvcmRlcldpZHRoKSB8fCBoZWxwZXJzLmlzQXJyYXkoZGF0YXNldC5wb2ludEJvcmRlcldpZHRoKSkge1xuXHRcdFx0XHRib3JkZXJXaWR0aCA9IGhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0KGRhdGFzZXQucG9pbnRCb3JkZXJXaWR0aCwgaW5kZXgsIGJvcmRlcldpZHRoKTtcblx0XHRcdH0gZWxzZSBpZiAoIWlzTmFOKGRhdGFzZXQuYm9yZGVyV2lkdGgpKSB7XG5cdFx0XHRcdGJvcmRlcldpZHRoID0gZGF0YXNldC5ib3JkZXJXaWR0aDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGJvcmRlcldpZHRoO1xuXHRcdH0sXG5cblx0XHRnZXRQb2ludFJvdGF0aW9uOiBmdW5jdGlvbihwb2ludCwgaW5kZXgpIHtcblx0XHRcdHZhciBwb2ludFJvdGF0aW9uID0gdGhpcy5jaGFydC5vcHRpb25zLmVsZW1lbnRzLnBvaW50LnJvdGF0aW9uO1xuXHRcdFx0dmFyIGRhdGFzZXQgPSB0aGlzLmdldERhdGFzZXQoKTtcblx0XHRcdHZhciBjdXN0b20gPSBwb2ludC5jdXN0b20gfHwge307XG5cblx0XHRcdGlmICghaXNOYU4oY3VzdG9tLnJvdGF0aW9uKSkge1xuXHRcdFx0XHRwb2ludFJvdGF0aW9uID0gY3VzdG9tLnJvdGF0aW9uO1xuXHRcdFx0fSBlbHNlIGlmICghaXNOYU4oZGF0YXNldC5wb2ludFJvdGF0aW9uKSB8fCBoZWxwZXJzLmlzQXJyYXkoZGF0YXNldC5wb2ludFJvdGF0aW9uKSkge1xuXHRcdFx0XHRwb2ludFJvdGF0aW9uID0gaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZGF0YXNldC5wb2ludFJvdGF0aW9uLCBpbmRleCwgcG9pbnRSb3RhdGlvbik7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcG9pbnRSb3RhdGlvbjtcblx0XHR9LFxuXG5cdFx0dXBkYXRlRWxlbWVudDogZnVuY3Rpb24ocG9pbnQsIGluZGV4LCByZXNldCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xuXHRcdFx0dmFyIGN1c3RvbSA9IHBvaW50LmN1c3RvbSB8fCB7fTtcblx0XHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xuXHRcdFx0dmFyIGRhdGFzZXRJbmRleCA9IG1lLmluZGV4O1xuXHRcdFx0dmFyIHZhbHVlID0gZGF0YXNldC5kYXRhW2luZGV4XTtcblx0XHRcdHZhciB5U2NhbGUgPSBtZS5nZXRTY2FsZUZvcklkKG1ldGEueUF4aXNJRCk7XG5cdFx0XHR2YXIgeFNjYWxlID0gbWUuZ2V0U2NhbGVGb3JJZChtZXRhLnhBeGlzSUQpO1xuXHRcdFx0dmFyIHBvaW50T3B0aW9ucyA9IG1lLmNoYXJ0Lm9wdGlvbnMuZWxlbWVudHMucG9pbnQ7XG5cdFx0XHR2YXIgeCwgeTtcblxuXHRcdFx0Ly8gQ29tcGF0aWJpbGl0eTogSWYgdGhlIHByb3BlcnRpZXMgYXJlIGRlZmluZWQgd2l0aCBvbmx5IHRoZSBvbGQgbmFtZSwgdXNlIHRob3NlIHZhbHVlc1xuXHRcdFx0aWYgKChkYXRhc2V0LnJhZGl1cyAhPT0gdW5kZWZpbmVkKSAmJiAoZGF0YXNldC5wb2ludFJhZGl1cyA9PT0gdW5kZWZpbmVkKSkge1xuXHRcdFx0XHRkYXRhc2V0LnBvaW50UmFkaXVzID0gZGF0YXNldC5yYWRpdXM7XG5cdFx0XHR9XG5cdFx0XHRpZiAoKGRhdGFzZXQuaGl0UmFkaXVzICE9PSB1bmRlZmluZWQpICYmIChkYXRhc2V0LnBvaW50SGl0UmFkaXVzID09PSB1bmRlZmluZWQpKSB7XG5cdFx0XHRcdGRhdGFzZXQucG9pbnRIaXRSYWRpdXMgPSBkYXRhc2V0LmhpdFJhZGl1cztcblx0XHRcdH1cblxuXHRcdFx0eCA9IHhTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgPyB2YWx1ZSA6IE5hTiwgaW5kZXgsIGRhdGFzZXRJbmRleCk7XG5cdFx0XHR5ID0gcmVzZXQgPyB5U2NhbGUuZ2V0QmFzZVBpeGVsKCkgOiBtZS5jYWxjdWxhdGVQb2ludFkodmFsdWUsIGluZGV4LCBkYXRhc2V0SW5kZXgpO1xuXG5cdFx0XHQvLyBVdGlsaXR5XG5cdFx0XHRwb2ludC5feFNjYWxlID0geFNjYWxlO1xuXHRcdFx0cG9pbnQuX3lTY2FsZSA9IHlTY2FsZTtcblx0XHRcdHBvaW50Ll9kYXRhc2V0SW5kZXggPSBkYXRhc2V0SW5kZXg7XG5cdFx0XHRwb2ludC5faW5kZXggPSBpbmRleDtcblxuXHRcdFx0Ly8gRGVzaXJlZCB2aWV3IHByb3BlcnRpZXNcblx0XHRcdHBvaW50Ll9tb2RlbCA9IHtcblx0XHRcdFx0eDogeCxcblx0XHRcdFx0eTogeSxcblx0XHRcdFx0c2tpcDogY3VzdG9tLnNraXAgfHwgaXNOYU4oeCkgfHwgaXNOYU4oeSksXG5cdFx0XHRcdC8vIEFwcGVhcmFuY2Vcblx0XHRcdFx0cmFkaXVzOiBjdXN0b20ucmFkaXVzIHx8IGhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0KGRhdGFzZXQucG9pbnRSYWRpdXMsIGluZGV4LCBwb2ludE9wdGlvbnMucmFkaXVzKSxcblx0XHRcdFx0cG9pbnRTdHlsZTogY3VzdG9tLnBvaW50U3R5bGUgfHwgaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZGF0YXNldC5wb2ludFN0eWxlLCBpbmRleCwgcG9pbnRPcHRpb25zLnBvaW50U3R5bGUpLFxuXHRcdFx0XHRyb3RhdGlvbjogbWUuZ2V0UG9pbnRSb3RhdGlvbihwb2ludCwgaW5kZXgpLFxuXHRcdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IG1lLmdldFBvaW50QmFja2dyb3VuZENvbG9yKHBvaW50LCBpbmRleCksXG5cdFx0XHRcdGJvcmRlckNvbG9yOiBtZS5nZXRQb2ludEJvcmRlckNvbG9yKHBvaW50LCBpbmRleCksXG5cdFx0XHRcdGJvcmRlcldpZHRoOiBtZS5nZXRQb2ludEJvcmRlcldpZHRoKHBvaW50LCBpbmRleCksXG5cdFx0XHRcdHRlbnNpb246IG1ldGEuZGF0YXNldC5fbW9kZWwgPyBtZXRhLmRhdGFzZXQuX21vZGVsLnRlbnNpb24gOiAwLFxuXHRcdFx0XHRzdGVwcGVkTGluZTogbWV0YS5kYXRhc2V0Ll9tb2RlbCA/IG1ldGEuZGF0YXNldC5fbW9kZWwuc3RlcHBlZExpbmUgOiBmYWxzZSxcblx0XHRcdFx0Ly8gVG9vbHRpcFxuXHRcdFx0XHRoaXRSYWRpdXM6IGN1c3RvbS5oaXRSYWRpdXMgfHwgaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZGF0YXNldC5wb2ludEhpdFJhZGl1cywgaW5kZXgsIHBvaW50T3B0aW9ucy5oaXRSYWRpdXMpXG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRjYWxjdWxhdGVQb2ludFk6IGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgZGF0YXNldEluZGV4KSB7XG5cdFx0XHR2YXIgbWUgPSB0aGlzO1xuXHRcdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XG5cdFx0XHR2YXIgbWV0YSA9IG1lLmdldE1ldGEoKTtcblx0XHRcdHZhciB5U2NhbGUgPSBtZS5nZXRTY2FsZUZvcklkKG1ldGEueUF4aXNJRCk7XG5cdFx0XHR2YXIgc3VtUG9zID0gMDtcblx0XHRcdHZhciBzdW1OZWcgPSAwO1xuXHRcdFx0dmFyIGksIGRzLCBkc01ldGE7XG5cblx0XHRcdGlmICh5U2NhbGUub3B0aW9ucy5zdGFja2VkKSB7XG5cdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBkYXRhc2V0SW5kZXg7IGkrKykge1xuXHRcdFx0XHRcdGRzID0gY2hhcnQuZGF0YS5kYXRhc2V0c1tpXTtcblx0XHRcdFx0XHRkc01ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YShpKTtcblx0XHRcdFx0XHRpZiAoZHNNZXRhLnR5cGUgPT09ICdsaW5lJyAmJiBkc01ldGEueUF4aXNJRCA9PT0geVNjYWxlLmlkICYmIGNoYXJ0LmlzRGF0YXNldFZpc2libGUoaSkpIHtcblx0XHRcdFx0XHRcdHZhciBzdGFja2VkUmlnaHRWYWx1ZSA9IE51bWJlcih5U2NhbGUuZ2V0UmlnaHRWYWx1ZShkcy5kYXRhW2luZGV4XSkpO1xuXHRcdFx0XHRcdFx0aWYgKHN0YWNrZWRSaWdodFZhbHVlIDwgMCkge1xuXHRcdFx0XHRcdFx0XHRzdW1OZWcgKz0gc3RhY2tlZFJpZ2h0VmFsdWUgfHwgMDtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHN1bVBvcyArPSBzdGFja2VkUmlnaHRWYWx1ZSB8fCAwO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHZhciByaWdodFZhbHVlID0gTnVtYmVyKHlTY2FsZS5nZXRSaWdodFZhbHVlKHZhbHVlKSk7XG5cdFx0XHRcdGlmIChyaWdodFZhbHVlIDwgMCkge1xuXHRcdFx0XHRcdHJldHVybiB5U2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShzdW1OZWcgKyByaWdodFZhbHVlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4geVNjYWxlLmdldFBpeGVsRm9yVmFsdWUoc3VtUG9zICsgcmlnaHRWYWx1ZSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB5U2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZSh2YWx1ZSk7XG5cdFx0fSxcblxuXHRcdHVwZGF0ZUJlemllckNvbnRyb2xQb2ludHM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xuXHRcdFx0dmFyIGFyZWEgPSBtZS5jaGFydC5jaGFydEFyZWE7XG5cdFx0XHR2YXIgcG9pbnRzID0gKG1ldGEuZGF0YSB8fCBbXSk7XG5cdFx0XHR2YXIgaSwgaWxlbiwgcG9pbnQsIG1vZGVsLCBjb250cm9sUG9pbnRzO1xuXG5cdFx0XHQvLyBPbmx5IGNvbnNpZGVyIHBvaW50cyB0aGF0IGFyZSBkcmF3biBpbiBjYXNlIHRoZSBzcGFuR2FwcyBvcHRpb24gaXMgdXNlZFxuXHRcdFx0aWYgKG1ldGEuZGF0YXNldC5fbW9kZWwuc3BhbkdhcHMpIHtcblx0XHRcdFx0cG9pbnRzID0gcG9pbnRzLmZpbHRlcihmdW5jdGlvbihwdCkge1xuXHRcdFx0XHRcdHJldHVybiAhcHQuX21vZGVsLnNraXA7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHRmdW5jdGlvbiBjYXBDb250cm9sUG9pbnQocHQsIG1pbiwgbWF4KSB7XG5cdFx0XHRcdHJldHVybiBNYXRoLm1heChNYXRoLm1pbihwdCwgbWF4KSwgbWluKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKG1ldGEuZGF0YXNldC5fbW9kZWwuY3ViaWNJbnRlcnBvbGF0aW9uTW9kZSA9PT0gJ21vbm90b25lJykge1xuXHRcdFx0XHRoZWxwZXJzLnNwbGluZUN1cnZlTW9ub3RvbmUocG9pbnRzKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoaSA9IDAsIGlsZW4gPSBwb2ludHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG5cdFx0XHRcdFx0cG9pbnQgPSBwb2ludHNbaV07XG5cdFx0XHRcdFx0bW9kZWwgPSBwb2ludC5fbW9kZWw7XG5cdFx0XHRcdFx0Y29udHJvbFBvaW50cyA9IGhlbHBlcnMuc3BsaW5lQ3VydmUoXG5cdFx0XHRcdFx0XHRoZWxwZXJzLnByZXZpb3VzSXRlbShwb2ludHMsIGkpLl9tb2RlbCxcblx0XHRcdFx0XHRcdG1vZGVsLFxuXHRcdFx0XHRcdFx0aGVscGVycy5uZXh0SXRlbShwb2ludHMsIGkpLl9tb2RlbCxcblx0XHRcdFx0XHRcdG1ldGEuZGF0YXNldC5fbW9kZWwudGVuc2lvblxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0bW9kZWwuY29udHJvbFBvaW50UHJldmlvdXNYID0gY29udHJvbFBvaW50cy5wcmV2aW91cy54O1xuXHRcdFx0XHRcdG1vZGVsLmNvbnRyb2xQb2ludFByZXZpb3VzWSA9IGNvbnRyb2xQb2ludHMucHJldmlvdXMueTtcblx0XHRcdFx0XHRtb2RlbC5jb250cm9sUG9pbnROZXh0WCA9IGNvbnRyb2xQb2ludHMubmV4dC54O1xuXHRcdFx0XHRcdG1vZGVsLmNvbnRyb2xQb2ludE5leHRZID0gY29udHJvbFBvaW50cy5uZXh0Lnk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aWYgKG1lLmNoYXJ0Lm9wdGlvbnMuZWxlbWVudHMubGluZS5jYXBCZXppZXJQb2ludHMpIHtcblx0XHRcdFx0Zm9yIChpID0gMCwgaWxlbiA9IHBvaW50cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdFx0XHRtb2RlbCA9IHBvaW50c1tpXS5fbW9kZWw7XG5cdFx0XHRcdFx0bW9kZWwuY29udHJvbFBvaW50UHJldmlvdXNYID0gY2FwQ29udHJvbFBvaW50KG1vZGVsLmNvbnRyb2xQb2ludFByZXZpb3VzWCwgYXJlYS5sZWZ0LCBhcmVhLnJpZ2h0KTtcblx0XHRcdFx0XHRtb2RlbC5jb250cm9sUG9pbnRQcmV2aW91c1kgPSBjYXBDb250cm9sUG9pbnQobW9kZWwuY29udHJvbFBvaW50UHJldmlvdXNZLCBhcmVhLnRvcCwgYXJlYS5ib3R0b20pO1xuXHRcdFx0XHRcdG1vZGVsLmNvbnRyb2xQb2ludE5leHRYID0gY2FwQ29udHJvbFBvaW50KG1vZGVsLmNvbnRyb2xQb2ludE5leHRYLCBhcmVhLmxlZnQsIGFyZWEucmlnaHQpO1xuXHRcdFx0XHRcdG1vZGVsLmNvbnRyb2xQb2ludE5leHRZID0gY2FwQ29udHJvbFBvaW50KG1vZGVsLmNvbnRyb2xQb2ludE5leHRZLCBhcmVhLnRvcCwgYXJlYS5ib3R0b20pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdGRyYXc6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG1lID0gdGhpcztcblx0XHRcdHZhciBjaGFydCA9IG1lLmNoYXJ0O1xuXHRcdFx0dmFyIG1ldGEgPSBtZS5nZXRNZXRhKCk7XG5cdFx0XHR2YXIgcG9pbnRzID0gbWV0YS5kYXRhIHx8IFtdO1xuXHRcdFx0dmFyIGFyZWEgPSBjaGFydC5jaGFydEFyZWE7XG5cdFx0XHR2YXIgaWxlbiA9IHBvaW50cy5sZW5ndGg7XG5cdFx0XHR2YXIgaGFsZkJvcmRlcldpZHRoO1xuXHRcdFx0dmFyIGkgPSAwO1xuXG5cdFx0XHRpZiAobGluZUVuYWJsZWQobWUuZ2V0RGF0YXNldCgpLCBjaGFydC5vcHRpb25zKSkge1xuXHRcdFx0XHRoYWxmQm9yZGVyV2lkdGggPSAobWV0YS5kYXRhc2V0Ll9tb2RlbC5ib3JkZXJXaWR0aCB8fCAwKSAvIDI7XG5cblx0XHRcdFx0aGVscGVycy5jYW52YXMuY2xpcEFyZWEoY2hhcnQuY3R4LCB7XG5cdFx0XHRcdFx0bGVmdDogYXJlYS5sZWZ0LFxuXHRcdFx0XHRcdHJpZ2h0OiBhcmVhLnJpZ2h0LFxuXHRcdFx0XHRcdHRvcDogYXJlYS50b3AgLSBoYWxmQm9yZGVyV2lkdGgsXG5cdFx0XHRcdFx0Ym90dG9tOiBhcmVhLmJvdHRvbSArIGhhbGZCb3JkZXJXaWR0aFxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHRtZXRhLmRhdGFzZXQuZHJhdygpO1xuXG5cdFx0XHRcdGhlbHBlcnMuY2FudmFzLnVuY2xpcEFyZWEoY2hhcnQuY3R4KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRHJhdyB0aGUgcG9pbnRzXG5cdFx0XHRmb3IgKDsgaSA8IGlsZW47ICsraSkge1xuXHRcdFx0XHRwb2ludHNbaV0uZHJhdyhhcmVhKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0c2V0SG92ZXJTdHlsZTogZnVuY3Rpb24oZWxlbWVudCkge1xuXHRcdFx0Ly8gUG9pbnRcblx0XHRcdHZhciBkYXRhc2V0ID0gdGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzW2VsZW1lbnQuX2RhdGFzZXRJbmRleF07XG5cdFx0XHR2YXIgaW5kZXggPSBlbGVtZW50Ll9pbmRleDtcblx0XHRcdHZhciBjdXN0b20gPSBlbGVtZW50LmN1c3RvbSB8fCB7fTtcblx0XHRcdHZhciBtb2RlbCA9IGVsZW1lbnQuX21vZGVsO1xuXG5cdFx0XHRlbGVtZW50LiRwcmV2aW91c1N0eWxlID0ge1xuXHRcdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IG1vZGVsLmJhY2tncm91bmRDb2xvcixcblx0XHRcdFx0Ym9yZGVyQ29sb3I6IG1vZGVsLmJvcmRlckNvbG9yLFxuXHRcdFx0XHRib3JkZXJXaWR0aDogbW9kZWwuYm9yZGVyV2lkdGgsXG5cdFx0XHRcdHJhZGl1czogbW9kZWwucmFkaXVzXG5cdFx0XHR9O1xuXG5cdFx0XHRtb2RlbC5iYWNrZ3JvdW5kQ29sb3IgPSBjdXN0b20uaG92ZXJCYWNrZ3JvdW5kQ29sb3IgfHwgaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQoZGF0YXNldC5wb2ludEhvdmVyQmFja2dyb3VuZENvbG9yLCBpbmRleCwgaGVscGVycy5nZXRIb3ZlckNvbG9yKG1vZGVsLmJhY2tncm91bmRDb2xvcikpO1xuXHRcdFx0bW9kZWwuYm9yZGVyQ29sb3IgPSBjdXN0b20uaG92ZXJCb3JkZXJDb2xvciB8fCBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdChkYXRhc2V0LnBvaW50SG92ZXJCb3JkZXJDb2xvciwgaW5kZXgsIGhlbHBlcnMuZ2V0SG92ZXJDb2xvcihtb2RlbC5ib3JkZXJDb2xvcikpO1xuXHRcdFx0bW9kZWwuYm9yZGVyV2lkdGggPSBjdXN0b20uaG92ZXJCb3JkZXJXaWR0aCB8fCBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdChkYXRhc2V0LnBvaW50SG92ZXJCb3JkZXJXaWR0aCwgaW5kZXgsIG1vZGVsLmJvcmRlcldpZHRoKTtcblx0XHRcdG1vZGVsLnJhZGl1cyA9IGN1c3RvbS5ob3ZlclJhZGl1cyB8fCBoZWxwZXJzLnZhbHVlQXRJbmRleE9yRGVmYXVsdChkYXRhc2V0LnBvaW50SG92ZXJSYWRpdXMsIGluZGV4LCB0aGlzLmNoYXJ0Lm9wdGlvbnMuZWxlbWVudHMucG9pbnQuaG92ZXJSYWRpdXMpO1xuXHRcdH0sXG5cdH0pO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///f3c1\n")},f974:function(module,exports,__webpack_require__){"use strict";eval('\n\nvar helpers = __webpack_require__(/*! ./helpers.core */ "7d23");\n\n/**\n * Easing functions adapted from Robert Penner\'s easing equations.\n * @namespace Chart.helpers.easingEffects\n * @see http://www.robertpenner.com/easing/\n */\nvar effects = {\n\tlinear: function(t) {\n\t\treturn t;\n\t},\n\n\teaseInQuad: function(t) {\n\t\treturn t * t;\n\t},\n\n\teaseOutQuad: function(t) {\n\t\treturn -t * (t - 2);\n\t},\n\n\teaseInOutQuad: function(t) {\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * t * t;\n\t\t}\n\t\treturn -0.5 * ((--t) * (t - 2) - 1);\n\t},\n\n\teaseInCubic: function(t) {\n\t\treturn t * t * t;\n\t},\n\n\teaseOutCubic: function(t) {\n\t\treturn (t = t - 1) * t * t + 1;\n\t},\n\n\teaseInOutCubic: function(t) {\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * t * t * t;\n\t\t}\n\t\treturn 0.5 * ((t -= 2) * t * t + 2);\n\t},\n\n\teaseInQuart: function(t) {\n\t\treturn t * t * t * t;\n\t},\n\n\teaseOutQuart: function(t) {\n\t\treturn -((t = t - 1) * t * t * t - 1);\n\t},\n\n\teaseInOutQuart: function(t) {\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * t * t * t * t;\n\t\t}\n\t\treturn -0.5 * ((t -= 2) * t * t * t - 2);\n\t},\n\n\teaseInQuint: function(t) {\n\t\treturn t * t * t * t * t;\n\t},\n\n\teaseOutQuint: function(t) {\n\t\treturn (t = t - 1) * t * t * t * t + 1;\n\t},\n\n\teaseInOutQuint: function(t) {\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * t * t * t * t * t;\n\t\t}\n\t\treturn 0.5 * ((t -= 2) * t * t * t * t + 2);\n\t},\n\n\teaseInSine: function(t) {\n\t\treturn -Math.cos(t * (Math.PI / 2)) + 1;\n\t},\n\n\teaseOutSine: function(t) {\n\t\treturn Math.sin(t * (Math.PI / 2));\n\t},\n\n\teaseInOutSine: function(t) {\n\t\treturn -0.5 * (Math.cos(Math.PI * t) - 1);\n\t},\n\n\teaseInExpo: function(t) {\n\t\treturn (t === 0) ? 0 : Math.pow(2, 10 * (t - 1));\n\t},\n\n\teaseOutExpo: function(t) {\n\t\treturn (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1;\n\t},\n\n\teaseInOutExpo: function(t) {\n\t\tif (t === 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (t === 1) {\n\t\t\treturn 1;\n\t\t}\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * Math.pow(2, 10 * (t - 1));\n\t\t}\n\t\treturn 0.5 * (-Math.pow(2, -10 * --t) + 2);\n\t},\n\n\teaseInCirc: function(t) {\n\t\tif (t >= 1) {\n\t\t\treturn t;\n\t\t}\n\t\treturn -(Math.sqrt(1 - t * t) - 1);\n\t},\n\n\teaseOutCirc: function(t) {\n\t\treturn Math.sqrt(1 - (t = t - 1) * t);\n\t},\n\n\teaseInOutCirc: function(t) {\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn -0.5 * (Math.sqrt(1 - t * t) - 1);\n\t\t}\n\t\treturn 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1);\n\t},\n\n\teaseInElastic: function(t) {\n\t\tvar s = 1.70158;\n\t\tvar p = 0;\n\t\tvar a = 1;\n\t\tif (t === 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (t === 1) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (!p) {\n\t\t\tp = 0.3;\n\t\t}\n\t\tif (a < 1) {\n\t\t\ta = 1;\n\t\t\ts = p / 4;\n\t\t} else {\n\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t}\n\t\treturn -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));\n\t},\n\n\teaseOutElastic: function(t) {\n\t\tvar s = 1.70158;\n\t\tvar p = 0;\n\t\tvar a = 1;\n\t\tif (t === 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (t === 1) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (!p) {\n\t\t\tp = 0.3;\n\t\t}\n\t\tif (a < 1) {\n\t\t\ta = 1;\n\t\t\ts = p / 4;\n\t\t} else {\n\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t}\n\t\treturn a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1;\n\t},\n\n\teaseInOutElastic: function(t) {\n\t\tvar s = 1.70158;\n\t\tvar p = 0;\n\t\tvar a = 1;\n\t\tif (t === 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif ((t /= 0.5) === 2) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (!p) {\n\t\t\tp = 0.45;\n\t\t}\n\t\tif (a < 1) {\n\t\t\ta = 1;\n\t\t\ts = p / 4;\n\t\t} else {\n\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t}\n\t\tif (t < 1) {\n\t\t\treturn -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));\n\t\t}\n\t\treturn a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1;\n\t},\n\teaseInBack: function(t) {\n\t\tvar s = 1.70158;\n\t\treturn t * t * ((s + 1) * t - s);\n\t},\n\n\teaseOutBack: function(t) {\n\t\tvar s = 1.70158;\n\t\treturn (t = t - 1) * t * ((s + 1) * t + s) + 1;\n\t},\n\n\teaseInOutBack: function(t) {\n\t\tvar s = 1.70158;\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s));\n\t\t}\n\t\treturn 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\n\t},\n\n\teaseInBounce: function(t) {\n\t\treturn 1 - effects.easeOutBounce(1 - t);\n\t},\n\n\teaseOutBounce: function(t) {\n\t\tif (t < (1 / 2.75)) {\n\t\t\treturn 7.5625 * t * t;\n\t\t}\n\t\tif (t < (2 / 2.75)) {\n\t\t\treturn 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75;\n\t\t}\n\t\tif (t < (2.5 / 2.75)) {\n\t\t\treturn 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375;\n\t\t}\n\t\treturn 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375;\n\t},\n\n\teaseInOutBounce: function(t) {\n\t\tif (t < 0.5) {\n\t\t\treturn effects.easeInBounce(t * 2) * 0.5;\n\t\t}\n\t\treturn effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5;\n\t}\n};\n\nmodule.exports = {\n\teffects: effects\n};\n\n// DEPRECATIONS\n\n/**\n * Provided for backward compatibility, use Chart.helpers.easing.effects instead.\n * @function Chart.helpers.easingEffects\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers.easingEffects = effects;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZjk3NC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLmVhc2luZy5qcz9iYjQzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMuY29yZScpO1xuXG4vKipcbiAqIEVhc2luZyBmdW5jdGlvbnMgYWRhcHRlZCBmcm9tIFJvYmVydCBQZW5uZXIncyBlYXNpbmcgZXF1YXRpb25zLlxuICogQG5hbWVzcGFjZSBDaGFydC5oZWxwZXJzLmVhc2luZ0VmZmVjdHNcbiAqIEBzZWUgaHR0cDovL3d3dy5yb2JlcnRwZW5uZXIuY29tL2Vhc2luZy9cbiAqL1xudmFyIGVmZmVjdHMgPSB7XG5cdGxpbmVhcjogZnVuY3Rpb24odCkge1xuXHRcdHJldHVybiB0O1xuXHR9LFxuXG5cdGVhc2VJblF1YWQ6IGZ1bmN0aW9uKHQpIHtcblx0XHRyZXR1cm4gdCAqIHQ7XG5cdH0sXG5cblx0ZWFzZU91dFF1YWQ6IGZ1bmN0aW9uKHQpIHtcblx0XHRyZXR1cm4gLXQgKiAodCAtIDIpO1xuXHR9LFxuXG5cdGVhc2VJbk91dFF1YWQ6IGZ1bmN0aW9uKHQpIHtcblx0XHRpZiAoKHQgLz0gMC41KSA8IDEpIHtcblx0XHRcdHJldHVybiAwLjUgKiB0ICogdDtcblx0XHR9XG5cdFx0cmV0dXJuIC0wLjUgKiAoKC0tdCkgKiAodCAtIDIpIC0gMSk7XG5cdH0sXG5cblx0ZWFzZUluQ3ViaWM6IGZ1bmN0aW9uKHQpIHtcblx0XHRyZXR1cm4gdCAqIHQgKiB0O1xuXHR9LFxuXG5cdGVhc2VPdXRDdWJpYzogZnVuY3Rpb24odCkge1xuXHRcdHJldHVybiAodCA9IHQgLSAxKSAqIHQgKiB0ICsgMTtcblx0fSxcblxuXHRlYXNlSW5PdXRDdWJpYzogZnVuY3Rpb24odCkge1xuXHRcdGlmICgodCAvPSAwLjUpIDwgMSkge1xuXHRcdFx0cmV0dXJuIDAuNSAqIHQgKiB0ICogdDtcblx0XHR9XG5cdFx0cmV0dXJuIDAuNSAqICgodCAtPSAyKSAqIHQgKiB0ICsgMik7XG5cdH0sXG5cblx0ZWFzZUluUXVhcnQ6IGZ1bmN0aW9uKHQpIHtcblx0XHRyZXR1cm4gdCAqIHQgKiB0ICogdDtcblx0fSxcblxuXHRlYXNlT3V0UXVhcnQ6IGZ1bmN0aW9uKHQpIHtcblx0XHRyZXR1cm4gLSgodCA9IHQgLSAxKSAqIHQgKiB0ICogdCAtIDEpO1xuXHR9LFxuXG5cdGVhc2VJbk91dFF1YXJ0OiBmdW5jdGlvbih0KSB7XG5cdFx0aWYgKCh0IC89IDAuNSkgPCAxKSB7XG5cdFx0XHRyZXR1cm4gMC41ICogdCAqIHQgKiB0ICogdDtcblx0XHR9XG5cdFx0cmV0dXJuIC0wLjUgKiAoKHQgLT0gMikgKiB0ICogdCAqIHQgLSAyKTtcblx0fSxcblxuXHRlYXNlSW5RdWludDogZnVuY3Rpb24odCkge1xuXHRcdHJldHVybiB0ICogdCAqIHQgKiB0ICogdDtcblx0fSxcblxuXHRlYXNlT3V0UXVpbnQ6IGZ1bmN0aW9uKHQpIHtcblx0XHRyZXR1cm4gKHQgPSB0IC0gMSkgKiB0ICogdCAqIHQgKiB0ICsgMTtcblx0fSxcblxuXHRlYXNlSW5PdXRRdWludDogZnVuY3Rpb24odCkge1xuXHRcdGlmICgodCAvPSAwLjUpIDwgMSkge1xuXHRcdFx0cmV0dXJuIDAuNSAqIHQgKiB0ICogdCAqIHQgKiB0O1xuXHRcdH1cblx0XHRyZXR1cm4gMC41ICogKCh0IC09IDIpICogdCAqIHQgKiB0ICogdCArIDIpO1xuXHR9LFxuXG5cdGVhc2VJblNpbmU6IGZ1bmN0aW9uKHQpIHtcblx0XHRyZXR1cm4gLU1hdGguY29zKHQgKiAoTWF0aC5QSSAvIDIpKSArIDE7XG5cdH0sXG5cblx0ZWFzZU91dFNpbmU6IGZ1bmN0aW9uKHQpIHtcblx0XHRyZXR1cm4gTWF0aC5zaW4odCAqIChNYXRoLlBJIC8gMikpO1xuXHR9LFxuXG5cdGVhc2VJbk91dFNpbmU6IGZ1bmN0aW9uKHQpIHtcblx0XHRyZXR1cm4gLTAuNSAqIChNYXRoLmNvcyhNYXRoLlBJICogdCkgLSAxKTtcblx0fSxcblxuXHRlYXNlSW5FeHBvOiBmdW5jdGlvbih0KSB7XG5cdFx0cmV0dXJuICh0ID09PSAwKSA/IDAgOiBNYXRoLnBvdygyLCAxMCAqICh0IC0gMSkpO1xuXHR9LFxuXG5cdGVhc2VPdXRFeHBvOiBmdW5jdGlvbih0KSB7XG5cdFx0cmV0dXJuICh0ID09PSAxKSA/IDEgOiAtTWF0aC5wb3coMiwgLTEwICogdCkgKyAxO1xuXHR9LFxuXG5cdGVhc2VJbk91dEV4cG86IGZ1bmN0aW9uKHQpIHtcblx0XHRpZiAodCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXHRcdGlmICh0ID09PSAxKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdFx0aWYgKCh0IC89IDAuNSkgPCAxKSB7XG5cdFx0XHRyZXR1cm4gMC41ICogTWF0aC5wb3coMiwgMTAgKiAodCAtIDEpKTtcblx0XHR9XG5cdFx0cmV0dXJuIDAuNSAqICgtTWF0aC5wb3coMiwgLTEwICogLS10KSArIDIpO1xuXHR9LFxuXG5cdGVhc2VJbkNpcmM6IGZ1bmN0aW9uKHQpIHtcblx0XHRpZiAodCA+PSAxKSB7XG5cdFx0XHRyZXR1cm4gdDtcblx0XHR9XG5cdFx0cmV0dXJuIC0oTWF0aC5zcXJ0KDEgLSB0ICogdCkgLSAxKTtcblx0fSxcblxuXHRlYXNlT3V0Q2lyYzogZnVuY3Rpb24odCkge1xuXHRcdHJldHVybiBNYXRoLnNxcnQoMSAtICh0ID0gdCAtIDEpICogdCk7XG5cdH0sXG5cblx0ZWFzZUluT3V0Q2lyYzogZnVuY3Rpb24odCkge1xuXHRcdGlmICgodCAvPSAwLjUpIDwgMSkge1xuXHRcdFx0cmV0dXJuIC0wLjUgKiAoTWF0aC5zcXJ0KDEgLSB0ICogdCkgLSAxKTtcblx0XHR9XG5cdFx0cmV0dXJuIDAuNSAqIChNYXRoLnNxcnQoMSAtICh0IC09IDIpICogdCkgKyAxKTtcblx0fSxcblxuXHRlYXNlSW5FbGFzdGljOiBmdW5jdGlvbih0KSB7XG5cdFx0dmFyIHMgPSAxLjcwMTU4O1xuXHRcdHZhciBwID0gMDtcblx0XHR2YXIgYSA9IDE7XG5cdFx0aWYgKHQgPT09IDApIHtcblx0XHRcdHJldHVybiAwO1xuXHRcdH1cblx0XHRpZiAodCA9PT0gMSkge1xuXHRcdFx0cmV0dXJuIDE7XG5cdFx0fVxuXHRcdGlmICghcCkge1xuXHRcdFx0cCA9IDAuMztcblx0XHR9XG5cdFx0aWYgKGEgPCAxKSB7XG5cdFx0XHRhID0gMTtcblx0XHRcdHMgPSBwIC8gNDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cyA9IHAgLyAoMiAqIE1hdGguUEkpICogTWF0aC5hc2luKDEgLyBhKTtcblx0XHR9XG5cdFx0cmV0dXJuIC0oYSAqIE1hdGgucG93KDIsIDEwICogKHQgLT0gMSkpICogTWF0aC5zaW4oKHQgLSBzKSAqICgyICogTWF0aC5QSSkgLyBwKSk7XG5cdH0sXG5cblx0ZWFzZU91dEVsYXN0aWM6IGZ1bmN0aW9uKHQpIHtcblx0XHR2YXIgcyA9IDEuNzAxNTg7XG5cdFx0dmFyIHAgPSAwO1xuXHRcdHZhciBhID0gMTtcblx0XHRpZiAodCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXHRcdGlmICh0ID09PSAxKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdFx0aWYgKCFwKSB7XG5cdFx0XHRwID0gMC4zO1xuXHRcdH1cblx0XHRpZiAoYSA8IDEpIHtcblx0XHRcdGEgPSAxO1xuXHRcdFx0cyA9IHAgLyA0O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRzID0gcCAvICgyICogTWF0aC5QSSkgKiBNYXRoLmFzaW4oMSAvIGEpO1xuXHRcdH1cblx0XHRyZXR1cm4gYSAqIE1hdGgucG93KDIsIC0xMCAqIHQpICogTWF0aC5zaW4oKHQgLSBzKSAqICgyICogTWF0aC5QSSkgLyBwKSArIDE7XG5cdH0sXG5cblx0ZWFzZUluT3V0RWxhc3RpYzogZnVuY3Rpb24odCkge1xuXHRcdHZhciBzID0gMS43MDE1ODtcblx0XHR2YXIgcCA9IDA7XG5cdFx0dmFyIGEgPSAxO1xuXHRcdGlmICh0ID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cdFx0aWYgKCh0IC89IDAuNSkgPT09IDIpIHtcblx0XHRcdHJldHVybiAxO1xuXHRcdH1cblx0XHRpZiAoIXApIHtcblx0XHRcdHAgPSAwLjQ1O1xuXHRcdH1cblx0XHRpZiAoYSA8IDEpIHtcblx0XHRcdGEgPSAxO1xuXHRcdFx0cyA9IHAgLyA0O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRzID0gcCAvICgyICogTWF0aC5QSSkgKiBNYXRoLmFzaW4oMSAvIGEpO1xuXHRcdH1cblx0XHRpZiAodCA8IDEpIHtcblx0XHRcdHJldHVybiAtMC41ICogKGEgKiBNYXRoLnBvdygyLCAxMCAqICh0IC09IDEpKSAqIE1hdGguc2luKCh0IC0gcykgKiAoMiAqIE1hdGguUEkpIC8gcCkpO1xuXHRcdH1cblx0XHRyZXR1cm4gYSAqIE1hdGgucG93KDIsIC0xMCAqICh0IC09IDEpKSAqIE1hdGguc2luKCh0IC0gcykgKiAoMiAqIE1hdGguUEkpIC8gcCkgKiAwLjUgKyAxO1xuXHR9LFxuXHRlYXNlSW5CYWNrOiBmdW5jdGlvbih0KSB7XG5cdFx0dmFyIHMgPSAxLjcwMTU4O1xuXHRcdHJldHVybiB0ICogdCAqICgocyArIDEpICogdCAtIHMpO1xuXHR9LFxuXG5cdGVhc2VPdXRCYWNrOiBmdW5jdGlvbih0KSB7XG5cdFx0dmFyIHMgPSAxLjcwMTU4O1xuXHRcdHJldHVybiAodCA9IHQgLSAxKSAqIHQgKiAoKHMgKyAxKSAqIHQgKyBzKSArIDE7XG5cdH0sXG5cblx0ZWFzZUluT3V0QmFjazogZnVuY3Rpb24odCkge1xuXHRcdHZhciBzID0gMS43MDE1ODtcblx0XHRpZiAoKHQgLz0gMC41KSA8IDEpIHtcblx0XHRcdHJldHVybiAwLjUgKiAodCAqIHQgKiAoKChzICo9ICgxLjUyNSkpICsgMSkgKiB0IC0gcykpO1xuXHRcdH1cblx0XHRyZXR1cm4gMC41ICogKCh0IC09IDIpICogdCAqICgoKHMgKj0gKDEuNTI1KSkgKyAxKSAqIHQgKyBzKSArIDIpO1xuXHR9LFxuXG5cdGVhc2VJbkJvdW5jZTogZnVuY3Rpb24odCkge1xuXHRcdHJldHVybiAxIC0gZWZmZWN0cy5lYXNlT3V0Qm91bmNlKDEgLSB0KTtcblx0fSxcblxuXHRlYXNlT3V0Qm91bmNlOiBmdW5jdGlvbih0KSB7XG5cdFx0aWYgKHQgPCAoMSAvIDIuNzUpKSB7XG5cdFx0XHRyZXR1cm4gNy41NjI1ICogdCAqIHQ7XG5cdFx0fVxuXHRcdGlmICh0IDwgKDIgLyAyLjc1KSkge1xuXHRcdFx0cmV0dXJuIDcuNTYyNSAqICh0IC09ICgxLjUgLyAyLjc1KSkgKiB0ICsgMC43NTtcblx0XHR9XG5cdFx0aWYgKHQgPCAoMi41IC8gMi43NSkpIHtcblx0XHRcdHJldHVybiA3LjU2MjUgKiAodCAtPSAoMi4yNSAvIDIuNzUpKSAqIHQgKyAwLjkzNzU7XG5cdFx0fVxuXHRcdHJldHVybiA3LjU2MjUgKiAodCAtPSAoMi42MjUgLyAyLjc1KSkgKiB0ICsgMC45ODQzNzU7XG5cdH0sXG5cblx0ZWFzZUluT3V0Qm91bmNlOiBmdW5jdGlvbih0KSB7XG5cdFx0aWYgKHQgPCAwLjUpIHtcblx0XHRcdHJldHVybiBlZmZlY3RzLmVhc2VJbkJvdW5jZSh0ICogMikgKiAwLjU7XG5cdFx0fVxuXHRcdHJldHVybiBlZmZlY3RzLmVhc2VPdXRCb3VuY2UodCAqIDIgLSAxKSAqIDAuNSArIDAuNTtcblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdGVmZmVjdHM6IGVmZmVjdHNcbn07XG5cbi8vIERFUFJFQ0FUSU9OU1xuXG4vKipcbiAqIFByb3ZpZGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB1c2UgQ2hhcnQuaGVscGVycy5lYXNpbmcuZWZmZWN0cyBpbnN0ZWFkLlxuICogQGZ1bmN0aW9uIENoYXJ0LmhlbHBlcnMuZWFzaW5nRWZmZWN0c1xuICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjcuMFxuICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xuICogQHByaXZhdGVcbiAqL1xuaGVscGVycy5lYXNpbmdFZmZlY3RzID0gZWZmZWN0cztcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///f974\n')},fbd8:function(module,exports,__webpack_require__){"use strict";eval("/* global window: false */\n/* global document: false */\n\n\nvar color = __webpack_require__(/*! chartjs-color */ \"f02b\");\nvar defaults = __webpack_require__(/*! ./core.defaults */ \"beaa\");\nvar helpers = __webpack_require__(/*! ../helpers/index */ \"66c8\");\nvar scaleService = __webpack_require__(/*! ../core/core.scaleService */ \"7c56\");\n\nmodule.exports = function() {\n\n\t// -- Basic js utility methods\n\n\thelpers.configMerge = function(/* objects ... */) {\n\t\treturn helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), {\n\t\t\tmerger: function(key, target, source, options) {\n\t\t\t\tvar tval = target[key] || {};\n\t\t\t\tvar sval = source[key];\n\n\t\t\t\tif (key === 'scales') {\n\t\t\t\t\t// scale config merging is complex. Add our own function here for that\n\t\t\t\t\ttarget[key] = helpers.scaleMerge(tval, sval);\n\t\t\t\t} else if (key === 'scale') {\n\t\t\t\t\t// used in polar area & radar charts since there is only one scale\n\t\t\t\t\ttarget[key] = helpers.merge(tval, [scaleService.getScaleDefaults(sval.type), sval]);\n\t\t\t\t} else {\n\t\t\t\t\thelpers._merger(key, target, source, options);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t};\n\n\thelpers.scaleMerge = function(/* objects ... */) {\n\t\treturn helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), {\n\t\t\tmerger: function(key, target, source, options) {\n\t\t\t\tif (key === 'xAxes' || key === 'yAxes') {\n\t\t\t\t\tvar slen = source[key].length;\n\t\t\t\t\tvar i, type, scale;\n\n\t\t\t\t\tif (!target[key]) {\n\t\t\t\t\t\ttarget[key] = [];\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (i = 0; i < slen; ++i) {\n\t\t\t\t\t\tscale = source[key][i];\n\t\t\t\t\t\ttype = helpers.valueOrDefault(scale.type, key === 'xAxes' ? 'category' : 'linear');\n\n\t\t\t\t\t\tif (i >= target[key].length) {\n\t\t\t\t\t\t\ttarget[key].push({});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!target[key][i].type || (scale.type && scale.type !== target[key][i].type)) {\n\t\t\t\t\t\t\t// new/untyped scale or type changed: let's apply the new defaults\n\t\t\t\t\t\t\t// then merge source scale to correctly overwrite the defaults.\n\t\t\t\t\t\t\thelpers.merge(target[key][i], [scaleService.getScaleDefaults(type), scale]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// scales type are the same\n\t\t\t\t\t\t\thelpers.merge(target[key][i], scale);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\thelpers._merger(key, target, source, options);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t};\n\n\thelpers.where = function(collection, filterCallback) {\n\t\tif (helpers.isArray(collection) && Array.prototype.filter) {\n\t\t\treturn collection.filter(filterCallback);\n\t\t}\n\t\tvar filtered = [];\n\n\t\thelpers.each(collection, function(item) {\n\t\t\tif (filterCallback(item)) {\n\t\t\t\tfiltered.push(item);\n\t\t\t}\n\t\t});\n\n\t\treturn filtered;\n\t};\n\thelpers.findIndex = Array.prototype.findIndex ?\n\t\tfunction(array, callback, scope) {\n\t\t\treturn array.findIndex(callback, scope);\n\t\t} :\n\t\tfunction(array, callback, scope) {\n\t\t\tscope = scope === undefined ? array : scope;\n\t\t\tfor (var i = 0, ilen = array.length; i < ilen; ++i) {\n\t\t\t\tif (callback.call(scope, array[i], i, array)) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t};\n\thelpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {\n\t\t// Default to start of the array\n\t\tif (helpers.isNullOrUndef(startIndex)) {\n\t\t\tstartIndex = -1;\n\t\t}\n\t\tfor (var i = startIndex + 1; i < arrayToSearch.length; i++) {\n\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\tif (filterCallback(currentItem)) {\n\t\t\t\treturn currentItem;\n\t\t\t}\n\t\t}\n\t};\n\thelpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {\n\t\t// Default to end of the array\n\t\tif (helpers.isNullOrUndef(startIndex)) {\n\t\t\tstartIndex = arrayToSearch.length;\n\t\t}\n\t\tfor (var i = startIndex - 1; i >= 0; i--) {\n\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\tif (filterCallback(currentItem)) {\n\t\t\t\treturn currentItem;\n\t\t\t}\n\t\t}\n\t};\n\n\t// -- Math methods\n\thelpers.isNumber = function(n) {\n\t\treturn !isNaN(parseFloat(n)) && isFinite(n);\n\t};\n\thelpers.almostEquals = function(x, y, epsilon) {\n\t\treturn Math.abs(x - y) < epsilon;\n\t};\n\thelpers.almostWhole = function(x, epsilon) {\n\t\tvar rounded = Math.round(x);\n\t\treturn (((rounded - epsilon) < x) && ((rounded + epsilon) > x));\n\t};\n\thelpers.max = function(array) {\n\t\treturn array.reduce(function(max, value) {\n\t\t\tif (!isNaN(value)) {\n\t\t\t\treturn Math.max(max, value);\n\t\t\t}\n\t\t\treturn max;\n\t\t}, Number.NEGATIVE_INFINITY);\n\t};\n\thelpers.min = function(array) {\n\t\treturn array.reduce(function(min, value) {\n\t\t\tif (!isNaN(value)) {\n\t\t\t\treturn Math.min(min, value);\n\t\t\t}\n\t\t\treturn min;\n\t\t}, Number.POSITIVE_INFINITY);\n\t};\n\thelpers.sign = Math.sign ?\n\t\tfunction(x) {\n\t\t\treturn Math.sign(x);\n\t\t} :\n\t\tfunction(x) {\n\t\t\tx = +x; // convert to a number\n\t\t\tif (x === 0 || isNaN(x)) {\n\t\t\t\treturn x;\n\t\t\t}\n\t\t\treturn x > 0 ? 1 : -1;\n\t\t};\n\thelpers.log10 = Math.log10 ?\n\t\tfunction(x) {\n\t\t\treturn Math.log10(x);\n\t\t} :\n\t\tfunction(x) {\n\t\t\tvar exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10.\n\t\t\t// Check for whole powers of 10,\n\t\t\t// which due to floating point rounding error should be corrected.\n\t\t\tvar powerOf10 = Math.round(exponent);\n\t\t\tvar isPowerOf10 = x === Math.pow(10, powerOf10);\n\n\t\t\treturn isPowerOf10 ? powerOf10 : exponent;\n\t\t};\n\thelpers.toRadians = function(degrees) {\n\t\treturn degrees * (Math.PI / 180);\n\t};\n\thelpers.toDegrees = function(radians) {\n\t\treturn radians * (180 / Math.PI);\n\t};\n\t// Gets the angle from vertical upright to the point about a centre.\n\thelpers.getAngleFromPoint = function(centrePoint, anglePoint) {\n\t\tvar distanceFromXCenter = anglePoint.x - centrePoint.x;\n\t\tvar distanceFromYCenter = anglePoint.y - centrePoint.y;\n\t\tvar radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\n\n\t\tvar angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);\n\n\t\tif (angle < (-0.5 * Math.PI)) {\n\t\t\tangle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]\n\t\t}\n\n\t\treturn {\n\t\t\tangle: angle,\n\t\t\tdistance: radialDistanceFromCenter\n\t\t};\n\t};\n\thelpers.distanceBetweenPoints = function(pt1, pt2) {\n\t\treturn Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));\n\t};\n\thelpers.aliasPixel = function(pixelWidth) {\n\t\treturn (pixelWidth % 2 === 0) ? 0 : 0.5;\n\t};\n\thelpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {\n\t\t// Props to Rob Spencer at scaled innovation for his post on splining between points\n\t\t// http://scaledinnovation.com/analytics/splines/aboutSplines.html\n\n\t\t// This function must also respect \"skipped\" points\n\n\t\tvar previous = firstPoint.skip ? middlePoint : firstPoint;\n\t\tvar current = middlePoint;\n\t\tvar next = afterPoint.skip ? middlePoint : afterPoint;\n\n\t\tvar d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));\n\t\tvar d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));\n\n\t\tvar s01 = d01 / (d01 + d12);\n\t\tvar s12 = d12 / (d01 + d12);\n\n\t\t// If all points are the same, s01 & s02 will be inf\n\t\ts01 = isNaN(s01) ? 0 : s01;\n\t\ts12 = isNaN(s12) ? 0 : s12;\n\n\t\tvar fa = t * s01; // scaling factor for triangle Ta\n\t\tvar fb = t * s12;\n\n\t\treturn {\n\t\t\tprevious: {\n\t\t\t\tx: current.x - fa * (next.x - previous.x),\n\t\t\t\ty: current.y - fa * (next.y - previous.y)\n\t\t\t},\n\t\t\tnext: {\n\t\t\t\tx: current.x + fb * (next.x - previous.x),\n\t\t\t\ty: current.y + fb * (next.y - previous.y)\n\t\t\t}\n\t\t};\n\t};\n\thelpers.EPSILON = Number.EPSILON || 1e-14;\n\thelpers.splineCurveMonotone = function(points) {\n\t\t// This function calculates BĂ©zier control points in a similar way than |splineCurve|,\n\t\t// but preserves monotonicity of the provided data and ensures no local extremums are added\n\t\t// between the dataset discrete points due to the interpolation.\n\t\t// See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation\n\n\t\tvar pointsWithTangents = (points || []).map(function(point) {\n\t\t\treturn {\n\t\t\t\tmodel: point._model,\n\t\t\t\tdeltaK: 0,\n\t\t\t\tmK: 0\n\t\t\t};\n\t\t});\n\n\t\t// Calculate slopes (deltaK) and initialize tangents (mK)\n\t\tvar pointsLen = pointsWithTangents.length;\n\t\tvar i, pointBefore, pointCurrent, pointAfter;\n\t\tfor (i = 0; i < pointsLen; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tif (pointCurrent.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpointBefore = i > 0 ? pointsWithTangents[i - 1] : null;\n\t\t\tpointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;\n\t\t\tif (pointAfter && !pointAfter.model.skip) {\n\t\t\t\tvar slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x);\n\n\t\t\t\t// In the case of two points that appear at the same x pixel, slopeDeltaX is 0\n\t\t\t\tpointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0;\n\t\t\t}\n\n\t\t\tif (!pointBefore || pointBefore.model.skip) {\n\t\t\t\tpointCurrent.mK = pointCurrent.deltaK;\n\t\t\t} else if (!pointAfter || pointAfter.model.skip) {\n\t\t\t\tpointCurrent.mK = pointBefore.deltaK;\n\t\t\t} else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) {\n\t\t\t\tpointCurrent.mK = 0;\n\t\t\t} else {\n\t\t\t\tpointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2;\n\t\t\t}\n\t\t}\n\n\t\t// Adjust tangents to ensure monotonic properties\n\t\tvar alphaK, betaK, tauK, squaredMagnitude;\n\t\tfor (i = 0; i < pointsLen - 1; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tpointAfter = pointsWithTangents[i + 1];\n\t\t\tif (pointCurrent.model.skip || pointAfter.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) {\n\t\t\t\tpointCurrent.mK = pointAfter.mK = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\talphaK = pointCurrent.mK / pointCurrent.deltaK;\n\t\t\tbetaK = pointAfter.mK / pointCurrent.deltaK;\n\t\t\tsquaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);\n\t\t\tif (squaredMagnitude <= 9) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttauK = 3 / Math.sqrt(squaredMagnitude);\n\t\t\tpointCurrent.mK = alphaK * tauK * pointCurrent.deltaK;\n\t\t\tpointAfter.mK = betaK * tauK * pointCurrent.deltaK;\n\t\t}\n\n\t\t// Compute control points\n\t\tvar deltaX;\n\t\tfor (i = 0; i < pointsLen; ++i) {\n\t\t\tpointCurrent = pointsWithTangents[i];\n\t\t\tif (pointCurrent.model.skip) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpointBefore = i > 0 ? pointsWithTangents[i - 1] : null;\n\t\t\tpointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;\n\t\t\tif (pointBefore && !pointBefore.model.skip) {\n\t\t\t\tdeltaX = (pointCurrent.model.x - pointBefore.model.x) / 3;\n\t\t\t\tpointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX;\n\t\t\t\tpointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK;\n\t\t\t}\n\t\t\tif (pointAfter && !pointAfter.model.skip) {\n\t\t\t\tdeltaX = (pointAfter.model.x - pointCurrent.model.x) / 3;\n\t\t\t\tpointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX;\n\t\t\t\tpointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK;\n\t\t\t}\n\t\t}\n\t};\n\thelpers.nextItem = function(collection, index, loop) {\n\t\tif (loop) {\n\t\t\treturn index >= collection.length - 1 ? collection[0] : collection[index + 1];\n\t\t}\n\t\treturn index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];\n\t};\n\thelpers.previousItem = function(collection, index, loop) {\n\t\tif (loop) {\n\t\t\treturn index <= 0 ? collection[collection.length - 1] : collection[index - 1];\n\t\t}\n\t\treturn index <= 0 ? collection[0] : collection[index - 1];\n\t};\n\t// Implementation of the nice number algorithm used in determining where axis labels will go\n\thelpers.niceNum = function(range, round) {\n\t\tvar exponent = Math.floor(helpers.log10(range));\n\t\tvar fraction = range / Math.pow(10, exponent);\n\t\tvar niceFraction;\n\n\t\tif (round) {\n\t\t\tif (fraction < 1.5) {\n\t\t\t\tniceFraction = 1;\n\t\t\t} else if (fraction < 3) {\n\t\t\t\tniceFraction = 2;\n\t\t\t} else if (fraction < 7) {\n\t\t\t\tniceFraction = 5;\n\t\t\t} else {\n\t\t\t\tniceFraction = 10;\n\t\t\t}\n\t\t} else if (fraction <= 1.0) {\n\t\t\tniceFraction = 1;\n\t\t} else if (fraction <= 2) {\n\t\t\tniceFraction = 2;\n\t\t} else if (fraction <= 5) {\n\t\t\tniceFraction = 5;\n\t\t} else {\n\t\t\tniceFraction = 10;\n\t\t}\n\n\t\treturn niceFraction * Math.pow(10, exponent);\n\t};\n\t// Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/\n\thelpers.requestAnimFrame = (function() {\n\t\tif (typeof window === 'undefined') {\n\t\t\treturn function(callback) {\n\t\t\t\tcallback();\n\t\t\t};\n\t\t}\n\t\treturn window.requestAnimationFrame ||\n\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\twindow.oRequestAnimationFrame ||\n\t\t\twindow.msRequestAnimationFrame ||\n\t\t\tfunction(callback) {\n\t\t\t\treturn window.setTimeout(callback, 1000 / 60);\n\t\t\t};\n\t}());\n\t// -- DOM methods\n\thelpers.getRelativePosition = function(evt, chart) {\n\t\tvar mouseX, mouseY;\n\t\tvar e = evt.originalEvent || evt;\n\t\tvar canvas = evt.target || evt.srcElement;\n\t\tvar boundingRect = canvas.getBoundingClientRect();\n\n\t\tvar touches = e.touches;\n\t\tif (touches && touches.length > 0) {\n\t\t\tmouseX = touches[0].clientX;\n\t\t\tmouseY = touches[0].clientY;\n\n\t\t} else {\n\t\t\tmouseX = e.clientX;\n\t\t\tmouseY = e.clientY;\n\t\t}\n\n\t\t// Scale mouse coordinates into canvas coordinates\n\t\t// by following the pattern laid out by 'jerryj' in the comments of\n\t\t// http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/\n\t\tvar paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));\n\t\tvar paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));\n\t\tvar paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));\n\t\tvar paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));\n\t\tvar width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;\n\t\tvar height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;\n\n\t\t// We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However\n\t\t// the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here\n\t\tmouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);\n\t\tmouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);\n\n\t\treturn {\n\t\t\tx: mouseX,\n\t\t\ty: mouseY\n\t\t};\n\n\t};\n\n\t// Private helper function to convert max-width/max-height values that may be percentages into a number\n\tfunction parseMaxStyle(styleValue, node, parentProperty) {\n\t\tvar valueInPixels;\n\t\tif (typeof styleValue === 'string') {\n\t\t\tvalueInPixels = parseInt(styleValue, 10);\n\n\t\t\tif (styleValue.indexOf('%') !== -1) {\n\t\t\t\t// percentage * size in dimension\n\t\t\t\tvalueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];\n\t\t\t}\n\t\t} else {\n\t\t\tvalueInPixels = styleValue;\n\t\t}\n\n\t\treturn valueInPixels;\n\t}\n\n\t/**\n\t * Returns if the given value contains an effective constraint.\n\t * @private\n\t */\n\tfunction isConstrainedValue(value) {\n\t\treturn value !== undefined && value !== null && value !== 'none';\n\t}\n\n\t// Private helper to get a constraint dimension\n\t// @param domNode : the node to check the constraint on\n\t// @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)\n\t// @param percentageProperty : property of parent to use when calculating width as a percentage\n\t// @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser\n\tfunction getConstraintDimension(domNode, maxStyle, percentageProperty) {\n\t\tvar view = document.defaultView;\n\t\tvar parentNode = helpers._getParentNode(domNode);\n\t\tvar constrainedNode = view.getComputedStyle(domNode)[maxStyle];\n\t\tvar constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];\n\t\tvar hasCNode = isConstrainedValue(constrainedNode);\n\t\tvar hasCContainer = isConstrainedValue(constrainedContainer);\n\t\tvar infinity = Number.POSITIVE_INFINITY;\n\n\t\tif (hasCNode || hasCContainer) {\n\t\t\treturn Math.min(\n\t\t\t\thasCNode ? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,\n\t\t\t\thasCContainer ? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);\n\t\t}\n\n\t\treturn 'none';\n\t}\n\t// returns Number or undefined if no constraint\n\thelpers.getConstraintWidth = function(domNode) {\n\t\treturn getConstraintDimension(domNode, 'max-width', 'clientWidth');\n\t};\n\t// returns Number or undefined if no constraint\n\thelpers.getConstraintHeight = function(domNode) {\n\t\treturn getConstraintDimension(domNode, 'max-height', 'clientHeight');\n\t};\n\t/**\n\t * @private\n \t */\n\thelpers._calculatePadding = function(container, padding, parentDimension) {\n\t\tpadding = helpers.getStyle(container, padding);\n\n\t\treturn padding.indexOf('%') > -1 ? parentDimension / parseInt(padding, 10) : parseInt(padding, 10);\n\t};\n\t/**\n\t * @private\n\t */\n\thelpers._getParentNode = function(domNode) {\n\t\tvar parent = domNode.parentNode;\n\t\tif (parent && parent.host) {\n\t\t\tparent = parent.host;\n\t\t}\n\t\treturn parent;\n\t};\n\thelpers.getMaximumWidth = function(domNode) {\n\t\tvar container = helpers._getParentNode(domNode);\n\t\tif (!container) {\n\t\t\treturn domNode.clientWidth;\n\t\t}\n\n\t\tvar clientWidth = container.clientWidth;\n\t\tvar paddingLeft = helpers._calculatePadding(container, 'padding-left', clientWidth);\n\t\tvar paddingRight = helpers._calculatePadding(container, 'padding-right', clientWidth);\n\n\t\tvar w = clientWidth - paddingLeft - paddingRight;\n\t\tvar cw = helpers.getConstraintWidth(domNode);\n\t\treturn isNaN(cw) ? w : Math.min(w, cw);\n\t};\n\thelpers.getMaximumHeight = function(domNode) {\n\t\tvar container = helpers._getParentNode(domNode);\n\t\tif (!container) {\n\t\t\treturn domNode.clientHeight;\n\t\t}\n\n\t\tvar clientHeight = container.clientHeight;\n\t\tvar paddingTop = helpers._calculatePadding(container, 'padding-top', clientHeight);\n\t\tvar paddingBottom = helpers._calculatePadding(container, 'padding-bottom', clientHeight);\n\n\t\tvar h = clientHeight - paddingTop - paddingBottom;\n\t\tvar ch = helpers.getConstraintHeight(domNode);\n\t\treturn isNaN(ch) ? h : Math.min(h, ch);\n\t};\n\thelpers.getStyle = function(el, property) {\n\t\treturn el.currentStyle ?\n\t\t\tel.currentStyle[property] :\n\t\t\tdocument.defaultView.getComputedStyle(el, null).getPropertyValue(property);\n\t};\n\thelpers.retinaScale = function(chart, forceRatio) {\n\t\tvar pixelRatio = chart.currentDevicePixelRatio = forceRatio || (typeof window !== 'undefined' && window.devicePixelRatio) || 1;\n\t\tif (pixelRatio === 1) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar canvas = chart.canvas;\n\t\tvar height = chart.height;\n\t\tvar width = chart.width;\n\n\t\tcanvas.height = height * pixelRatio;\n\t\tcanvas.width = width * pixelRatio;\n\t\tchart.ctx.scale(pixelRatio, pixelRatio);\n\n\t\t// If no style has been set on the canvas, the render size is used as display size,\n\t\t// making the chart visually bigger, so let's enforce it to the \"correct\" values.\n\t\t// See https://github.com/chartjs/Chart.js/issues/3575\n\t\tif (!canvas.style.height && !canvas.style.width) {\n\t\t\tcanvas.style.height = height + 'px';\n\t\t\tcanvas.style.width = width + 'px';\n\t\t}\n\t};\n\t// -- Canvas methods\n\thelpers.fontString = function(pixelSize, fontStyle, fontFamily) {\n\t\treturn fontStyle + ' ' + pixelSize + 'px ' + fontFamily;\n\t};\n\thelpers.longestText = function(ctx, font, arrayOfThings, cache) {\n\t\tcache = cache || {};\n\t\tvar data = cache.data = cache.data || {};\n\t\tvar gc = cache.garbageCollect = cache.garbageCollect || [];\n\n\t\tif (cache.font !== font) {\n\t\t\tdata = cache.data = {};\n\t\t\tgc = cache.garbageCollect = [];\n\t\t\tcache.font = font;\n\t\t}\n\n\t\tctx.font = font;\n\t\tvar longest = 0;\n\t\thelpers.each(arrayOfThings, function(thing) {\n\t\t\t// Undefined strings and arrays should not be measured\n\t\t\tif (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {\n\t\t\t\tlongest = helpers.measureText(ctx, data, gc, longest, thing);\n\t\t\t} else if (helpers.isArray(thing)) {\n\t\t\t\t// if it is an array lets measure each element\n\t\t\t\t// to do maybe simplify this function a bit so we can do this more recursively?\n\t\t\t\thelpers.each(thing, function(nestedThing) {\n\t\t\t\t\t// Undefined strings and arrays should not be measured\n\t\t\t\t\tif (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {\n\t\t\t\t\t\tlongest = helpers.measureText(ctx, data, gc, longest, nestedThing);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tvar gcLen = gc.length / 2;\n\t\tif (gcLen > arrayOfThings.length) {\n\t\t\tfor (var i = 0; i < gcLen; i++) {\n\t\t\t\tdelete data[gc[i]];\n\t\t\t}\n\t\t\tgc.splice(0, gcLen);\n\t\t}\n\t\treturn longest;\n\t};\n\thelpers.measureText = function(ctx, data, gc, longest, string) {\n\t\tvar textWidth = data[string];\n\t\tif (!textWidth) {\n\t\t\ttextWidth = data[string] = ctx.measureText(string).width;\n\t\t\tgc.push(string);\n\t\t}\n\t\tif (textWidth > longest) {\n\t\t\tlongest = textWidth;\n\t\t}\n\t\treturn longest;\n\t};\n\thelpers.numberOfLabelLines = function(arrayOfThings) {\n\t\tvar numberOfLines = 1;\n\t\thelpers.each(arrayOfThings, function(thing) {\n\t\t\tif (helpers.isArray(thing)) {\n\t\t\t\tif (thing.length > numberOfLines) {\n\t\t\t\t\tnumberOfLines = thing.length;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn numberOfLines;\n\t};\n\n\thelpers.color = !color ?\n\t\tfunction(value) {\n\t\t\tconsole.error('Color.js not found!');\n\t\t\treturn value;\n\t\t} :\n\t\tfunction(value) {\n\t\t\t/* global CanvasGradient */\n\t\t\tif (value instanceof CanvasGradient) {\n\t\t\t\tvalue = defaults.global.defaultColor;\n\t\t\t}\n\n\t\t\treturn color(value);\n\t\t};\n\n\thelpers.getHoverColor = function(colorValue) {\n\t\t/* global CanvasPattern */\n\t\treturn (colorValue instanceof CanvasPattern) ?\n\t\t\tcolorValue :\n\t\t\thelpers.color(colorValue).saturate(0.5).darken(0.1).rgbString();\n\t};\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmJkOC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmhlbHBlcnMuanM/OWMzNSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBnbG9iYWwgd2luZG93OiBmYWxzZSAqL1xuLyogZ2xvYmFsIGRvY3VtZW50OiBmYWxzZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgY29sb3IgPSByZXF1aXJlKCdjaGFydGpzLWNvbG9yJyk7XG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2NvcmUuZGVmYXVsdHMnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9pbmRleCcpO1xudmFyIHNjYWxlU2VydmljZSA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5zY2FsZVNlcnZpY2UnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcblxuXHQvLyAtLSBCYXNpYyBqcyB1dGlsaXR5IG1ldGhvZHNcblxuXHRoZWxwZXJzLmNvbmZpZ01lcmdlID0gZnVuY3Rpb24oLyogb2JqZWN0cyAuLi4gKi8pIHtcblx0XHRyZXR1cm4gaGVscGVycy5tZXJnZShoZWxwZXJzLmNsb25lKGFyZ3VtZW50c1swXSksIFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSwge1xuXHRcdFx0bWVyZ2VyOiBmdW5jdGlvbihrZXksIHRhcmdldCwgc291cmNlLCBvcHRpb25zKSB7XG5cdFx0XHRcdHZhciB0dmFsID0gdGFyZ2V0W2tleV0gfHwge307XG5cdFx0XHRcdHZhciBzdmFsID0gc291cmNlW2tleV07XG5cblx0XHRcdFx0aWYgKGtleSA9PT0gJ3NjYWxlcycpIHtcblx0XHRcdFx0XHQvLyBzY2FsZSBjb25maWcgbWVyZ2luZyBpcyBjb21wbGV4LiBBZGQgb3VyIG93biBmdW5jdGlvbiBoZXJlIGZvciB0aGF0XG5cdFx0XHRcdFx0dGFyZ2V0W2tleV0gPSBoZWxwZXJzLnNjYWxlTWVyZ2UodHZhbCwgc3ZhbCk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoa2V5ID09PSAnc2NhbGUnKSB7XG5cdFx0XHRcdFx0Ly8gdXNlZCBpbiBwb2xhciBhcmVhICYgcmFkYXIgY2hhcnRzIHNpbmNlIHRoZXJlIGlzIG9ubHkgb25lIHNjYWxlXG5cdFx0XHRcdFx0dGFyZ2V0W2tleV0gPSBoZWxwZXJzLm1lcmdlKHR2YWwsIFtzY2FsZVNlcnZpY2UuZ2V0U2NhbGVEZWZhdWx0cyhzdmFsLnR5cGUpLCBzdmFsXSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aGVscGVycy5fbWVyZ2VyKGtleSwgdGFyZ2V0LCBzb3VyY2UsIG9wdGlvbnMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH07XG5cblx0aGVscGVycy5zY2FsZU1lcmdlID0gZnVuY3Rpb24oLyogb2JqZWN0cyAuLi4gKi8pIHtcblx0XHRyZXR1cm4gaGVscGVycy5tZXJnZShoZWxwZXJzLmNsb25lKGFyZ3VtZW50c1swXSksIFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSwge1xuXHRcdFx0bWVyZ2VyOiBmdW5jdGlvbihrZXksIHRhcmdldCwgc291cmNlLCBvcHRpb25zKSB7XG5cdFx0XHRcdGlmIChrZXkgPT09ICd4QXhlcycgfHwga2V5ID09PSAneUF4ZXMnKSB7XG5cdFx0XHRcdFx0dmFyIHNsZW4gPSBzb3VyY2Vba2V5XS5sZW5ndGg7XG5cdFx0XHRcdFx0dmFyIGksIHR5cGUsIHNjYWxlO1xuXG5cdFx0XHRcdFx0aWYgKCF0YXJnZXRba2V5XSkge1xuXHRcdFx0XHRcdFx0dGFyZ2V0W2tleV0gPSBbXTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRmb3IgKGkgPSAwOyBpIDwgc2xlbjsgKytpKSB7XG5cdFx0XHRcdFx0XHRzY2FsZSA9IHNvdXJjZVtrZXldW2ldO1xuXHRcdFx0XHRcdFx0dHlwZSA9IGhlbHBlcnMudmFsdWVPckRlZmF1bHQoc2NhbGUudHlwZSwga2V5ID09PSAneEF4ZXMnID8gJ2NhdGVnb3J5JyA6ICdsaW5lYXInKTtcblxuXHRcdFx0XHRcdFx0aWYgKGkgPj0gdGFyZ2V0W2tleV0ubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdHRhcmdldFtrZXldLnB1c2goe30pO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRpZiAoIXRhcmdldFtrZXldW2ldLnR5cGUgfHwgKHNjYWxlLnR5cGUgJiYgc2NhbGUudHlwZSAhPT0gdGFyZ2V0W2tleV1baV0udHlwZSkpIHtcblx0XHRcdFx0XHRcdFx0Ly8gbmV3L3VudHlwZWQgc2NhbGUgb3IgdHlwZSBjaGFuZ2VkOiBsZXQncyBhcHBseSB0aGUgbmV3IGRlZmF1bHRzXG5cdFx0XHRcdFx0XHRcdC8vIHRoZW4gbWVyZ2Ugc291cmNlIHNjYWxlIHRvIGNvcnJlY3RseSBvdmVyd3JpdGUgdGhlIGRlZmF1bHRzLlxuXHRcdFx0XHRcdFx0XHRoZWxwZXJzLm1lcmdlKHRhcmdldFtrZXldW2ldLCBbc2NhbGVTZXJ2aWNlLmdldFNjYWxlRGVmYXVsdHModHlwZSksIHNjYWxlXSk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHQvLyBzY2FsZXMgdHlwZSBhcmUgdGhlIHNhbWVcblx0XHRcdFx0XHRcdFx0aGVscGVycy5tZXJnZSh0YXJnZXRba2V5XVtpXSwgc2NhbGUpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRoZWxwZXJzLl9tZXJnZXIoa2V5LCB0YXJnZXQsIHNvdXJjZSwgb3B0aW9ucyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0fTtcblxuXHRoZWxwZXJzLndoZXJlID0gZnVuY3Rpb24oY29sbGVjdGlvbiwgZmlsdGVyQ2FsbGJhY2spIHtcblx0XHRpZiAoaGVscGVycy5pc0FycmF5KGNvbGxlY3Rpb24pICYmIEFycmF5LnByb3RvdHlwZS5maWx0ZXIpIHtcblx0XHRcdHJldHVybiBjb2xsZWN0aW9uLmZpbHRlcihmaWx0ZXJDYWxsYmFjayk7XG5cdFx0fVxuXHRcdHZhciBmaWx0ZXJlZCA9IFtdO1xuXG5cdFx0aGVscGVycy5lYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKGl0ZW0pIHtcblx0XHRcdGlmIChmaWx0ZXJDYWxsYmFjayhpdGVtKSkge1xuXHRcdFx0XHRmaWx0ZXJlZC5wdXNoKGl0ZW0pO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIGZpbHRlcmVkO1xuXHR9O1xuXHRoZWxwZXJzLmZpbmRJbmRleCA9IEFycmF5LnByb3RvdHlwZS5maW5kSW5kZXggP1xuXHRcdGZ1bmN0aW9uKGFycmF5LCBjYWxsYmFjaywgc2NvcGUpIHtcblx0XHRcdHJldHVybiBhcnJheS5maW5kSW5kZXgoY2FsbGJhY2ssIHNjb3BlKTtcblx0XHR9IDpcblx0XHRmdW5jdGlvbihhcnJheSwgY2FsbGJhY2ssIHNjb3BlKSB7XG5cdFx0XHRzY29wZSA9IHNjb3BlID09PSB1bmRlZmluZWQgPyBhcnJheSA6IHNjb3BlO1xuXHRcdFx0Zm9yICh2YXIgaSA9IDAsIGlsZW4gPSBhcnJheS5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcblx0XHRcdFx0aWYgKGNhbGxiYWNrLmNhbGwoc2NvcGUsIGFycmF5W2ldLCBpLCBhcnJheSkpIHtcblx0XHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH07XG5cdGhlbHBlcnMuZmluZE5leHRXaGVyZSA9IGZ1bmN0aW9uKGFycmF5VG9TZWFyY2gsIGZpbHRlckNhbGxiYWNrLCBzdGFydEluZGV4KSB7XG5cdFx0Ly8gRGVmYXVsdCB0byBzdGFydCBvZiB0aGUgYXJyYXlcblx0XHRpZiAoaGVscGVycy5pc051bGxPclVuZGVmKHN0YXJ0SW5kZXgpKSB7XG5cdFx0XHRzdGFydEluZGV4ID0gLTE7XG5cdFx0fVxuXHRcdGZvciAodmFyIGkgPSBzdGFydEluZGV4ICsgMTsgaSA8IGFycmF5VG9TZWFyY2gubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBjdXJyZW50SXRlbSA9IGFycmF5VG9TZWFyY2hbaV07XG5cdFx0XHRpZiAoZmlsdGVyQ2FsbGJhY2soY3VycmVudEl0ZW0pKSB7XG5cdFx0XHRcdHJldHVybiBjdXJyZW50SXRlbTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cdGhlbHBlcnMuZmluZFByZXZpb3VzV2hlcmUgPSBmdW5jdGlvbihhcnJheVRvU2VhcmNoLCBmaWx0ZXJDYWxsYmFjaywgc3RhcnRJbmRleCkge1xuXHRcdC8vIERlZmF1bHQgdG8gZW5kIG9mIHRoZSBhcnJheVxuXHRcdGlmIChoZWxwZXJzLmlzTnVsbE9yVW5kZWYoc3RhcnRJbmRleCkpIHtcblx0XHRcdHN0YXJ0SW5kZXggPSBhcnJheVRvU2VhcmNoLmxlbmd0aDtcblx0XHR9XG5cdFx0Zm9yICh2YXIgaSA9IHN0YXJ0SW5kZXggLSAxOyBpID49IDA7IGktLSkge1xuXHRcdFx0dmFyIGN1cnJlbnRJdGVtID0gYXJyYXlUb1NlYXJjaFtpXTtcblx0XHRcdGlmIChmaWx0ZXJDYWxsYmFjayhjdXJyZW50SXRlbSkpIHtcblx0XHRcdFx0cmV0dXJuIGN1cnJlbnRJdGVtO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblxuXHQvLyAtLSBNYXRoIG1ldGhvZHNcblx0aGVscGVycy5pc051bWJlciA9IGZ1bmN0aW9uKG4pIHtcblx0XHRyZXR1cm4gIWlzTmFOKHBhcnNlRmxvYXQobikpICYmIGlzRmluaXRlKG4pO1xuXHR9O1xuXHRoZWxwZXJzLmFsbW9zdEVxdWFscyA9IGZ1bmN0aW9uKHgsIHksIGVwc2lsb24pIHtcblx0XHRyZXR1cm4gTWF0aC5hYnMoeCAtIHkpIDwgZXBzaWxvbjtcblx0fTtcblx0aGVscGVycy5hbG1vc3RXaG9sZSA9IGZ1bmN0aW9uKHgsIGVwc2lsb24pIHtcblx0XHR2YXIgcm91bmRlZCA9IE1hdGgucm91bmQoeCk7XG5cdFx0cmV0dXJuICgoKHJvdW5kZWQgLSBlcHNpbG9uKSA8IHgpICYmICgocm91bmRlZCArIGVwc2lsb24pID4geCkpO1xuXHR9O1xuXHRoZWxwZXJzLm1heCA9IGZ1bmN0aW9uKGFycmF5KSB7XG5cdFx0cmV0dXJuIGFycmF5LnJlZHVjZShmdW5jdGlvbihtYXgsIHZhbHVlKSB7XG5cdFx0XHRpZiAoIWlzTmFOKHZhbHVlKSkge1xuXHRcdFx0XHRyZXR1cm4gTWF0aC5tYXgobWF4LCB2YWx1ZSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF4O1xuXHRcdH0sIE51bWJlci5ORUdBVElWRV9JTkZJTklUWSk7XG5cdH07XG5cdGhlbHBlcnMubWluID0gZnVuY3Rpb24oYXJyYXkpIHtcblx0XHRyZXR1cm4gYXJyYXkucmVkdWNlKGZ1bmN0aW9uKG1pbiwgdmFsdWUpIHtcblx0XHRcdGlmICghaXNOYU4odmFsdWUpKSB7XG5cdFx0XHRcdHJldHVybiBNYXRoLm1pbihtaW4sIHZhbHVlKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtaW47XG5cdFx0fSwgTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKTtcblx0fTtcblx0aGVscGVycy5zaWduID0gTWF0aC5zaWduID9cblx0XHRmdW5jdGlvbih4KSB7XG5cdFx0XHRyZXR1cm4gTWF0aC5zaWduKHgpO1xuXHRcdH0gOlxuXHRcdGZ1bmN0aW9uKHgpIHtcblx0XHRcdHggPSAreDsgLy8gY29udmVydCB0byBhIG51bWJlclxuXHRcdFx0aWYgKHggPT09IDAgfHwgaXNOYU4oeCkpIHtcblx0XHRcdFx0cmV0dXJuIHg7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4geCA+IDAgPyAxIDogLTE7XG5cdFx0fTtcblx0aGVscGVycy5sb2cxMCA9IE1hdGgubG9nMTAgP1xuXHRcdGZ1bmN0aW9uKHgpIHtcblx0XHRcdHJldHVybiBNYXRoLmxvZzEwKHgpO1xuXHRcdH0gOlxuXHRcdGZ1bmN0aW9uKHgpIHtcblx0XHRcdHZhciBleHBvbmVudCA9IE1hdGgubG9nKHgpICogTWF0aC5MT0cxMEU7IC8vIE1hdGguTE9HMTBFID0gMSAvIE1hdGguTE4xMC5cblx0XHRcdC8vIENoZWNrIGZvciB3aG9sZSBwb3dlcnMgb2YgMTAsXG5cdFx0XHQvLyB3aGljaCBkdWUgdG8gZmxvYXRpbmcgcG9pbnQgcm91bmRpbmcgZXJyb3Igc2hvdWxkIGJlIGNvcnJlY3RlZC5cblx0XHRcdHZhciBwb3dlck9mMTAgPSBNYXRoLnJvdW5kKGV4cG9uZW50KTtcblx0XHRcdHZhciBpc1Bvd2VyT2YxMCA9IHggPT09IE1hdGgucG93KDEwLCBwb3dlck9mMTApO1xuXG5cdFx0XHRyZXR1cm4gaXNQb3dlck9mMTAgPyBwb3dlck9mMTAgOiBleHBvbmVudDtcblx0XHR9O1xuXHRoZWxwZXJzLnRvUmFkaWFucyA9IGZ1bmN0aW9uKGRlZ3JlZXMpIHtcblx0XHRyZXR1cm4gZGVncmVlcyAqIChNYXRoLlBJIC8gMTgwKTtcblx0fTtcblx0aGVscGVycy50b0RlZ3JlZXMgPSBmdW5jdGlvbihyYWRpYW5zKSB7XG5cdFx0cmV0dXJuIHJhZGlhbnMgKiAoMTgwIC8gTWF0aC5QSSk7XG5cdH07XG5cdC8vIEdldHMgdGhlIGFuZ2xlIGZyb20gdmVydGljYWwgdXByaWdodCB0byB0aGUgcG9pbnQgYWJvdXQgYSBjZW50cmUuXG5cdGhlbHBlcnMuZ2V0QW5nbGVGcm9tUG9pbnQgPSBmdW5jdGlvbihjZW50cmVQb2ludCwgYW5nbGVQb2ludCkge1xuXHRcdHZhciBkaXN0YW5jZUZyb21YQ2VudGVyID0gYW5nbGVQb2ludC54IC0gY2VudHJlUG9pbnQueDtcblx0XHR2YXIgZGlzdGFuY2VGcm9tWUNlbnRlciA9IGFuZ2xlUG9pbnQueSAtIGNlbnRyZVBvaW50Lnk7XG5cdFx0dmFyIHJhZGlhbERpc3RhbmNlRnJvbUNlbnRlciA9IE1hdGguc3FydChkaXN0YW5jZUZyb21YQ2VudGVyICogZGlzdGFuY2VGcm9tWENlbnRlciArIGRpc3RhbmNlRnJvbVlDZW50ZXIgKiBkaXN0YW5jZUZyb21ZQ2VudGVyKTtcblxuXHRcdHZhciBhbmdsZSA9IE1hdGguYXRhbjIoZGlzdGFuY2VGcm9tWUNlbnRlciwgZGlzdGFuY2VGcm9tWENlbnRlcik7XG5cblx0XHRpZiAoYW5nbGUgPCAoLTAuNSAqIE1hdGguUEkpKSB7XG5cdFx0XHRhbmdsZSArPSAyLjAgKiBNYXRoLlBJOyAvLyBtYWtlIHN1cmUgdGhlIHJldHVybmVkIGFuZ2xlIGlzIGluIHRoZSByYW5nZSBvZiAoLVBJLzIsIDNQSS8yXVxuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRhbmdsZTogYW5nbGUsXG5cdFx0XHRkaXN0YW5jZTogcmFkaWFsRGlzdGFuY2VGcm9tQ2VudGVyXG5cdFx0fTtcblx0fTtcblx0aGVscGVycy5kaXN0YW5jZUJldHdlZW5Qb2ludHMgPSBmdW5jdGlvbihwdDEsIHB0Mikge1xuXHRcdHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3cocHQyLnggLSBwdDEueCwgMikgKyBNYXRoLnBvdyhwdDIueSAtIHB0MS55LCAyKSk7XG5cdH07XG5cdGhlbHBlcnMuYWxpYXNQaXhlbCA9IGZ1bmN0aW9uKHBpeGVsV2lkdGgpIHtcblx0XHRyZXR1cm4gKHBpeGVsV2lkdGggJSAyID09PSAwKSA/IDAgOiAwLjU7XG5cdH07XG5cdGhlbHBlcnMuc3BsaW5lQ3VydmUgPSBmdW5jdGlvbihmaXJzdFBvaW50LCBtaWRkbGVQb2ludCwgYWZ0ZXJQb2ludCwgdCkge1xuXHRcdC8vIFByb3BzIHRvIFJvYiBTcGVuY2VyIGF0IHNjYWxlZCBpbm5vdmF0aW9uIGZvciBoaXMgcG9zdCBvbiBzcGxpbmluZyBiZXR3ZWVuIHBvaW50c1xuXHRcdC8vIGh0dHA6Ly9zY2FsZWRpbm5vdmF0aW9uLmNvbS9hbmFseXRpY3Mvc3BsaW5lcy9hYm91dFNwbGluZXMuaHRtbFxuXG5cdFx0Ly8gVGhpcyBmdW5jdGlvbiBtdXN0IGFsc28gcmVzcGVjdCBcInNraXBwZWRcIiBwb2ludHNcblxuXHRcdHZhciBwcmV2aW91cyA9IGZpcnN0UG9pbnQuc2tpcCA/IG1pZGRsZVBvaW50IDogZmlyc3RQb2ludDtcblx0XHR2YXIgY3VycmVudCA9IG1pZGRsZVBvaW50O1xuXHRcdHZhciBuZXh0ID0gYWZ0ZXJQb2ludC5za2lwID8gbWlkZGxlUG9pbnQgOiBhZnRlclBvaW50O1xuXG5cdFx0dmFyIGQwMSA9IE1hdGguc3FydChNYXRoLnBvdyhjdXJyZW50LnggLSBwcmV2aW91cy54LCAyKSArIE1hdGgucG93KGN1cnJlbnQueSAtIHByZXZpb3VzLnksIDIpKTtcblx0XHR2YXIgZDEyID0gTWF0aC5zcXJ0KE1hdGgucG93KG5leHQueCAtIGN1cnJlbnQueCwgMikgKyBNYXRoLnBvdyhuZXh0LnkgLSBjdXJyZW50LnksIDIpKTtcblxuXHRcdHZhciBzMDEgPSBkMDEgLyAoZDAxICsgZDEyKTtcblx0XHR2YXIgczEyID0gZDEyIC8gKGQwMSArIGQxMik7XG5cblx0XHQvLyBJZiBhbGwgcG9pbnRzIGFyZSB0aGUgc2FtZSwgczAxICYgczAyIHdpbGwgYmUgaW5mXG5cdFx0czAxID0gaXNOYU4oczAxKSA/IDAgOiBzMDE7XG5cdFx0czEyID0gaXNOYU4oczEyKSA/IDAgOiBzMTI7XG5cblx0XHR2YXIgZmEgPSB0ICogczAxOyAvLyBzY2FsaW5nIGZhY3RvciBmb3IgdHJpYW5nbGUgVGFcblx0XHR2YXIgZmIgPSB0ICogczEyO1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdHByZXZpb3VzOiB7XG5cdFx0XHRcdHg6IGN1cnJlbnQueCAtIGZhICogKG5leHQueCAtIHByZXZpb3VzLngpLFxuXHRcdFx0XHR5OiBjdXJyZW50LnkgLSBmYSAqIChuZXh0LnkgLSBwcmV2aW91cy55KVxuXHRcdFx0fSxcblx0XHRcdG5leHQ6IHtcblx0XHRcdFx0eDogY3VycmVudC54ICsgZmIgKiAobmV4dC54IC0gcHJldmlvdXMueCksXG5cdFx0XHRcdHk6IGN1cnJlbnQueSArIGZiICogKG5leHQueSAtIHByZXZpb3VzLnkpXG5cdFx0XHR9XG5cdFx0fTtcblx0fTtcblx0aGVscGVycy5FUFNJTE9OID0gTnVtYmVyLkVQU0lMT04gfHwgMWUtMTQ7XG5cdGhlbHBlcnMuc3BsaW5lQ3VydmVNb25vdG9uZSA9IGZ1bmN0aW9uKHBvaW50cykge1xuXHRcdC8vIFRoaXMgZnVuY3Rpb24gY2FsY3VsYXRlcyBCw6l6aWVyIGNvbnRyb2wgcG9pbnRzIGluIGEgc2ltaWxhciB3YXkgdGhhbiB8c3BsaW5lQ3VydmV8LFxuXHRcdC8vIGJ1dCBwcmVzZXJ2ZXMgbW9ub3RvbmljaXR5IG9mIHRoZSBwcm92aWRlZCBkYXRhIGFuZCBlbnN1cmVzIG5vIGxvY2FsIGV4dHJlbXVtcyBhcmUgYWRkZWRcblx0XHQvLyBiZXR3ZWVuIHRoZSBkYXRhc2V0IGRpc2NyZXRlIHBvaW50cyBkdWUgdG8gdGhlIGludGVycG9sYXRpb24uXG5cdFx0Ly8gU2VlIDogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTW9ub3RvbmVfY3ViaWNfaW50ZXJwb2xhdGlvblxuXG5cdFx0dmFyIHBvaW50c1dpdGhUYW5nZW50cyA9IChwb2ludHMgfHwgW10pLm1hcChmdW5jdGlvbihwb2ludCkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0bW9kZWw6IHBvaW50Ll9tb2RlbCxcblx0XHRcdFx0ZGVsdGFLOiAwLFxuXHRcdFx0XHRtSzogMFxuXHRcdFx0fTtcblx0XHR9KTtcblxuXHRcdC8vIENhbGN1bGF0ZSBzbG9wZXMgKGRlbHRhSykgYW5kIGluaXRpYWxpemUgdGFuZ2VudHMgKG1LKVxuXHRcdHZhciBwb2ludHNMZW4gPSBwb2ludHNXaXRoVGFuZ2VudHMubGVuZ3RoO1xuXHRcdHZhciBpLCBwb2ludEJlZm9yZSwgcG9pbnRDdXJyZW50LCBwb2ludEFmdGVyO1xuXHRcdGZvciAoaSA9IDA7IGkgPCBwb2ludHNMZW47ICsraSkge1xuXHRcdFx0cG9pbnRDdXJyZW50ID0gcG9pbnRzV2l0aFRhbmdlbnRzW2ldO1xuXHRcdFx0aWYgKHBvaW50Q3VycmVudC5tb2RlbC5za2lwKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRwb2ludEJlZm9yZSA9IGkgPiAwID8gcG9pbnRzV2l0aFRhbmdlbnRzW2kgLSAxXSA6IG51bGw7XG5cdFx0XHRwb2ludEFmdGVyID0gaSA8IHBvaW50c0xlbiAtIDEgPyBwb2ludHNXaXRoVGFuZ2VudHNbaSArIDFdIDogbnVsbDtcblx0XHRcdGlmIChwb2ludEFmdGVyICYmICFwb2ludEFmdGVyLm1vZGVsLnNraXApIHtcblx0XHRcdFx0dmFyIHNsb3BlRGVsdGFYID0gKHBvaW50QWZ0ZXIubW9kZWwueCAtIHBvaW50Q3VycmVudC5tb2RlbC54KTtcblxuXHRcdFx0XHQvLyBJbiB0aGUgY2FzZSBvZiB0d28gcG9pbnRzIHRoYXQgYXBwZWFyIGF0IHRoZSBzYW1lIHggcGl4ZWwsIHNsb3BlRGVsdGFYIGlzIDBcblx0XHRcdFx0cG9pbnRDdXJyZW50LmRlbHRhSyA9IHNsb3BlRGVsdGFYICE9PSAwID8gKHBvaW50QWZ0ZXIubW9kZWwueSAtIHBvaW50Q3VycmVudC5tb2RlbC55KSAvIHNsb3BlRGVsdGFYIDogMDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCFwb2ludEJlZm9yZSB8fCBwb2ludEJlZm9yZS5tb2RlbC5za2lwKSB7XG5cdFx0XHRcdHBvaW50Q3VycmVudC5tSyA9IHBvaW50Q3VycmVudC5kZWx0YUs7XG5cdFx0XHR9IGVsc2UgaWYgKCFwb2ludEFmdGVyIHx8IHBvaW50QWZ0ZXIubW9kZWwuc2tpcCkge1xuXHRcdFx0XHRwb2ludEN1cnJlbnQubUsgPSBwb2ludEJlZm9yZS5kZWx0YUs7XG5cdFx0XHR9IGVsc2UgaWYgKHRoaXMuc2lnbihwb2ludEJlZm9yZS5kZWx0YUspICE9PSB0aGlzLnNpZ24ocG9pbnRDdXJyZW50LmRlbHRhSykpIHtcblx0XHRcdFx0cG9pbnRDdXJyZW50Lm1LID0gMDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHBvaW50Q3VycmVudC5tSyA9IChwb2ludEJlZm9yZS5kZWx0YUsgKyBwb2ludEN1cnJlbnQuZGVsdGFLKSAvIDI7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQWRqdXN0IHRhbmdlbnRzIHRvIGVuc3VyZSBtb25vdG9uaWMgcHJvcGVydGllc1xuXHRcdHZhciBhbHBoYUssIGJldGFLLCB0YXVLLCBzcXVhcmVkTWFnbml0dWRlO1xuXHRcdGZvciAoaSA9IDA7IGkgPCBwb2ludHNMZW4gLSAxOyArK2kpIHtcblx0XHRcdHBvaW50Q3VycmVudCA9IHBvaW50c1dpdGhUYW5nZW50c1tpXTtcblx0XHRcdHBvaW50QWZ0ZXIgPSBwb2ludHNXaXRoVGFuZ2VudHNbaSArIDFdO1xuXHRcdFx0aWYgKHBvaW50Q3VycmVudC5tb2RlbC5za2lwIHx8IHBvaW50QWZ0ZXIubW9kZWwuc2tpcCkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGhlbHBlcnMuYWxtb3N0RXF1YWxzKHBvaW50Q3VycmVudC5kZWx0YUssIDAsIHRoaXMuRVBTSUxPTikpIHtcblx0XHRcdFx0cG9pbnRDdXJyZW50Lm1LID0gcG9pbnRBZnRlci5tSyA9IDA7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRhbHBoYUsgPSBwb2ludEN1cnJlbnQubUsgLyBwb2ludEN1cnJlbnQuZGVsdGFLO1xuXHRcdFx0YmV0YUsgPSBwb2ludEFmdGVyLm1LIC8gcG9pbnRDdXJyZW50LmRlbHRhSztcblx0XHRcdHNxdWFyZWRNYWduaXR1ZGUgPSBNYXRoLnBvdyhhbHBoYUssIDIpICsgTWF0aC5wb3coYmV0YUssIDIpO1xuXHRcdFx0aWYgKHNxdWFyZWRNYWduaXR1ZGUgPD0gOSkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0dGF1SyA9IDMgLyBNYXRoLnNxcnQoc3F1YXJlZE1hZ25pdHVkZSk7XG5cdFx0XHRwb2ludEN1cnJlbnQubUsgPSBhbHBoYUsgKiB0YXVLICogcG9pbnRDdXJyZW50LmRlbHRhSztcblx0XHRcdHBvaW50QWZ0ZXIubUsgPSBiZXRhSyAqIHRhdUsgKiBwb2ludEN1cnJlbnQuZGVsdGFLO1xuXHRcdH1cblxuXHRcdC8vIENvbXB1dGUgY29udHJvbCBwb2ludHNcblx0XHR2YXIgZGVsdGFYO1xuXHRcdGZvciAoaSA9IDA7IGkgPCBwb2ludHNMZW47ICsraSkge1xuXHRcdFx0cG9pbnRDdXJyZW50ID0gcG9pbnRzV2l0aFRhbmdlbnRzW2ldO1xuXHRcdFx0aWYgKHBvaW50Q3VycmVudC5tb2RlbC5za2lwKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRwb2ludEJlZm9yZSA9IGkgPiAwID8gcG9pbnRzV2l0aFRhbmdlbnRzW2kgLSAxXSA6IG51bGw7XG5cdFx0XHRwb2ludEFmdGVyID0gaSA8IHBvaW50c0xlbiAtIDEgPyBwb2ludHNXaXRoVGFuZ2VudHNbaSArIDFdIDogbnVsbDtcblx0XHRcdGlmIChwb2ludEJlZm9yZSAmJiAhcG9pbnRCZWZvcmUubW9kZWwuc2tpcCkge1xuXHRcdFx0XHRkZWx0YVggPSAocG9pbnRDdXJyZW50Lm1vZGVsLnggLSBwb2ludEJlZm9yZS5tb2RlbC54KSAvIDM7XG5cdFx0XHRcdHBvaW50Q3VycmVudC5tb2RlbC5jb250cm9sUG9pbnRQcmV2aW91c1ggPSBwb2ludEN1cnJlbnQubW9kZWwueCAtIGRlbHRhWDtcblx0XHRcdFx0cG9pbnRDdXJyZW50Lm1vZGVsLmNvbnRyb2xQb2ludFByZXZpb3VzWSA9IHBvaW50Q3VycmVudC5tb2RlbC55IC0gZGVsdGFYICogcG9pbnRDdXJyZW50Lm1LO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHBvaW50QWZ0ZXIgJiYgIXBvaW50QWZ0ZXIubW9kZWwuc2tpcCkge1xuXHRcdFx0XHRkZWx0YVggPSAocG9pbnRBZnRlci5tb2RlbC54IC0gcG9pbnRDdXJyZW50Lm1vZGVsLngpIC8gMztcblx0XHRcdFx0cG9pbnRDdXJyZW50Lm1vZGVsLmNvbnRyb2xQb2ludE5leHRYID0gcG9pbnRDdXJyZW50Lm1vZGVsLnggKyBkZWx0YVg7XG5cdFx0XHRcdHBvaW50Q3VycmVudC5tb2RlbC5jb250cm9sUG9pbnROZXh0WSA9IHBvaW50Q3VycmVudC5tb2RlbC55ICsgZGVsdGFYICogcG9pbnRDdXJyZW50Lm1LO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0aGVscGVycy5uZXh0SXRlbSA9IGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGluZGV4LCBsb29wKSB7XG5cdFx0aWYgKGxvb3ApIHtcblx0XHRcdHJldHVybiBpbmRleCA+PSBjb2xsZWN0aW9uLmxlbmd0aCAtIDEgPyBjb2xsZWN0aW9uWzBdIDogY29sbGVjdGlvbltpbmRleCArIDFdO1xuXHRcdH1cblx0XHRyZXR1cm4gaW5kZXggPj0gY29sbGVjdGlvbi5sZW5ndGggLSAxID8gY29sbGVjdGlvbltjb2xsZWN0aW9uLmxlbmd0aCAtIDFdIDogY29sbGVjdGlvbltpbmRleCArIDFdO1xuXHR9O1xuXHRoZWxwZXJzLnByZXZpb3VzSXRlbSA9IGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGluZGV4LCBsb29wKSB7XG5cdFx0aWYgKGxvb3ApIHtcblx0XHRcdHJldHVybiBpbmRleCA8PSAwID8gY29sbGVjdGlvbltjb2xsZWN0aW9uLmxlbmd0aCAtIDFdIDogY29sbGVjdGlvbltpbmRleCAtIDFdO1xuXHRcdH1cblx0XHRyZXR1cm4gaW5kZXggPD0gMCA/IGNvbGxlY3Rpb25bMF0gOiBjb2xsZWN0aW9uW2luZGV4IC0gMV07XG5cdH07XG5cdC8vIEltcGxlbWVudGF0aW9uIG9mIHRoZSBuaWNlIG51bWJlciBhbGdvcml0aG0gdXNlZCBpbiBkZXRlcm1pbmluZyB3aGVyZSBheGlzIGxhYmVscyB3aWxsIGdvXG5cdGhlbHBlcnMubmljZU51bSA9IGZ1bmN0aW9uKHJhbmdlLCByb3VuZCkge1xuXHRcdHZhciBleHBvbmVudCA9IE1hdGguZmxvb3IoaGVscGVycy5sb2cxMChyYW5nZSkpO1xuXHRcdHZhciBmcmFjdGlvbiA9IHJhbmdlIC8gTWF0aC5wb3coMTAsIGV4cG9uZW50KTtcblx0XHR2YXIgbmljZUZyYWN0aW9uO1xuXG5cdFx0aWYgKHJvdW5kKSB7XG5cdFx0XHRpZiAoZnJhY3Rpb24gPCAxLjUpIHtcblx0XHRcdFx0bmljZUZyYWN0aW9uID0gMTtcblx0XHRcdH0gZWxzZSBpZiAoZnJhY3Rpb24gPCAzKSB7XG5cdFx0XHRcdG5pY2VGcmFjdGlvbiA9IDI7XG5cdFx0XHR9IGVsc2UgaWYgKGZyYWN0aW9uIDwgNykge1xuXHRcdFx0XHRuaWNlRnJhY3Rpb24gPSA1O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bmljZUZyYWN0aW9uID0gMTA7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChmcmFjdGlvbiA8PSAxLjApIHtcblx0XHRcdG5pY2VGcmFjdGlvbiA9IDE7XG5cdFx0fSBlbHNlIGlmIChmcmFjdGlvbiA8PSAyKSB7XG5cdFx0XHRuaWNlRnJhY3Rpb24gPSAyO1xuXHRcdH0gZWxzZSBpZiAoZnJhY3Rpb24gPD0gNSkge1xuXHRcdFx0bmljZUZyYWN0aW9uID0gNTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bmljZUZyYWN0aW9uID0gMTA7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG5pY2VGcmFjdGlvbiAqIE1hdGgucG93KDEwLCBleHBvbmVudCk7XG5cdH07XG5cdC8vIFJlcXVlc3QgYW5pbWF0aW9uIHBvbHlmaWxsIC0gaHR0cDovL3d3dy5wYXVsaXJpc2guY29tLzIwMTEvcmVxdWVzdGFuaW1hdGlvbmZyYW1lLWZvci1zbWFydC1hbmltYXRpbmcvXG5cdGhlbHBlcnMucmVxdWVzdEFuaW1GcmFtZSA9IChmdW5jdGlvbigpIHtcblx0XHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbihjYWxsYmFjaykge1xuXHRcdFx0XHRjYWxsYmFjaygpO1xuXHRcdFx0fTtcblx0XHR9XG5cdFx0cmV0dXJuIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcblx0XHRcdHdpbmRvdy53ZWJraXRSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcblx0XHRcdHdpbmRvdy5tb3pSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcblx0XHRcdHdpbmRvdy5vUmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XG5cdFx0XHR3aW5kb3cubXNSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcblx0XHRcdGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG5cdFx0XHRcdHJldHVybiB3aW5kb3cuc2V0VGltZW91dChjYWxsYmFjaywgMTAwMCAvIDYwKTtcblx0XHRcdH07XG5cdH0oKSk7XG5cdC8vIC0tIERPTSBtZXRob2RzXG5cdGhlbHBlcnMuZ2V0UmVsYXRpdmVQb3NpdGlvbiA9IGZ1bmN0aW9uKGV2dCwgY2hhcnQpIHtcblx0XHR2YXIgbW91c2VYLCBtb3VzZVk7XG5cdFx0dmFyIGUgPSBldnQub3JpZ2luYWxFdmVudCB8fCBldnQ7XG5cdFx0dmFyIGNhbnZhcyA9IGV2dC50YXJnZXQgfHwgZXZ0LnNyY0VsZW1lbnQ7XG5cdFx0dmFyIGJvdW5kaW5nUmVjdCA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuXHRcdHZhciB0b3VjaGVzID0gZS50b3VjaGVzO1xuXHRcdGlmICh0b3VjaGVzICYmIHRvdWNoZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0bW91c2VYID0gdG91Y2hlc1swXS5jbGllbnRYO1xuXHRcdFx0bW91c2VZID0gdG91Y2hlc1swXS5jbGllbnRZO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdG1vdXNlWCA9IGUuY2xpZW50WDtcblx0XHRcdG1vdXNlWSA9IGUuY2xpZW50WTtcblx0XHR9XG5cblx0XHQvLyBTY2FsZSBtb3VzZSBjb29yZGluYXRlcyBpbnRvIGNhbnZhcyBjb29yZGluYXRlc1xuXHRcdC8vIGJ5IGZvbGxvd2luZyB0aGUgcGF0dGVybiBsYWlkIG91dCBieSAnamVycnlqJyBpbiB0aGUgY29tbWVudHMgb2Zcblx0XHQvLyBodHRwOi8vd3d3Lmh0bWw1Y2FudmFzdHV0b3JpYWxzLmNvbS9hZHZhbmNlZC9odG1sNS1jYW52YXMtbW91c2UtY29vcmRpbmF0ZXMvXG5cdFx0dmFyIHBhZGRpbmdMZWZ0ID0gcGFyc2VGbG9hdChoZWxwZXJzLmdldFN0eWxlKGNhbnZhcywgJ3BhZGRpbmctbGVmdCcpKTtcblx0XHR2YXIgcGFkZGluZ1RvcCA9IHBhcnNlRmxvYXQoaGVscGVycy5nZXRTdHlsZShjYW52YXMsICdwYWRkaW5nLXRvcCcpKTtcblx0XHR2YXIgcGFkZGluZ1JpZ2h0ID0gcGFyc2VGbG9hdChoZWxwZXJzLmdldFN0eWxlKGNhbnZhcywgJ3BhZGRpbmctcmlnaHQnKSk7XG5cdFx0dmFyIHBhZGRpbmdCb3R0b20gPSBwYXJzZUZsb2F0KGhlbHBlcnMuZ2V0U3R5bGUoY2FudmFzLCAncGFkZGluZy1ib3R0b20nKSk7XG5cdFx0dmFyIHdpZHRoID0gYm91bmRpbmdSZWN0LnJpZ2h0IC0gYm91bmRpbmdSZWN0LmxlZnQgLSBwYWRkaW5nTGVmdCAtIHBhZGRpbmdSaWdodDtcblx0XHR2YXIgaGVpZ2h0ID0gYm91bmRpbmdSZWN0LmJvdHRvbSAtIGJvdW5kaW5nUmVjdC50b3AgLSBwYWRkaW5nVG9wIC0gcGFkZGluZ0JvdHRvbTtcblxuXHRcdC8vIFdlIGRpdmlkZSBieSB0aGUgY3VycmVudCBkZXZpY2UgcGl4ZWwgcmF0aW8sIGJlY2F1c2UgdGhlIGNhbnZhcyBpcyBzY2FsZWQgdXAgYnkgdGhhdCBhbW91bnQgaW4gZWFjaCBkaXJlY3Rpb24uIEhvd2V2ZXJcblx0XHQvLyB0aGUgYmFja2VuZCBtb2RlbCBpcyBpbiB1bnNjYWxlZCBjb29yZGluYXRlcy4gU2luY2Ugd2UgYXJlIGdvaW5nIHRvIGRlYWwgd2l0aCBvdXIgbW9kZWwgY29vcmRpbmF0ZXMsIHdlIGdvIGJhY2sgaGVyZVxuXHRcdG1vdXNlWCA9IE1hdGgucm91bmQoKG1vdXNlWCAtIGJvdW5kaW5nUmVjdC5sZWZ0IC0gcGFkZGluZ0xlZnQpIC8gKHdpZHRoKSAqIGNhbnZhcy53aWR0aCAvIGNoYXJ0LmN1cnJlbnREZXZpY2VQaXhlbFJhdGlvKTtcblx0XHRtb3VzZVkgPSBNYXRoLnJvdW5kKChtb3VzZVkgLSBib3VuZGluZ1JlY3QudG9wIC0gcGFkZGluZ1RvcCkgLyAoaGVpZ2h0KSAqIGNhbnZhcy5oZWlnaHQgLyBjaGFydC5jdXJyZW50RGV2aWNlUGl4ZWxSYXRpbyk7XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0eDogbW91c2VYLFxuXHRcdFx0eTogbW91c2VZXG5cdFx0fTtcblxuXHR9O1xuXG5cdC8vIFByaXZhdGUgaGVscGVyIGZ1bmN0aW9uIHRvIGNvbnZlcnQgbWF4LXdpZHRoL21heC1oZWlnaHQgdmFsdWVzIHRoYXQgbWF5IGJlIHBlcmNlbnRhZ2VzIGludG8gYSBudW1iZXJcblx0ZnVuY3Rpb24gcGFyc2VNYXhTdHlsZShzdHlsZVZhbHVlLCBub2RlLCBwYXJlbnRQcm9wZXJ0eSkge1xuXHRcdHZhciB2YWx1ZUluUGl4ZWxzO1xuXHRcdGlmICh0eXBlb2Ygc3R5bGVWYWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0XHRcdHZhbHVlSW5QaXhlbHMgPSBwYXJzZUludChzdHlsZVZhbHVlLCAxMCk7XG5cblx0XHRcdGlmIChzdHlsZVZhbHVlLmluZGV4T2YoJyUnKSAhPT0gLTEpIHtcblx0XHRcdFx0Ly8gcGVyY2VudGFnZSAqIHNpemUgaW4gZGltZW5zaW9uXG5cdFx0XHRcdHZhbHVlSW5QaXhlbHMgPSB2YWx1ZUluUGl4ZWxzIC8gMTAwICogbm9kZS5wYXJlbnROb2RlW3BhcmVudFByb3BlcnR5XTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFsdWVJblBpeGVscyA9IHN0eWxlVmFsdWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHZhbHVlSW5QaXhlbHM7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyBpZiB0aGUgZ2l2ZW4gdmFsdWUgY29udGFpbnMgYW4gZWZmZWN0aXZlIGNvbnN0cmFpbnQuXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRmdW5jdGlvbiBpc0NvbnN0cmFpbmVkVmFsdWUodmFsdWUpIHtcblx0XHRyZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gJ25vbmUnO1xuXHR9XG5cblx0Ly8gUHJpdmF0ZSBoZWxwZXIgdG8gZ2V0IGEgY29uc3RyYWludCBkaW1lbnNpb25cblx0Ly8gQHBhcmFtIGRvbU5vZGUgOiB0aGUgbm9kZSB0byBjaGVjayB0aGUgY29uc3RyYWludCBvblxuXHQvLyBAcGFyYW0gbWF4U3R5bGUgOiB0aGUgc3R5bGUgdGhhdCBkZWZpbmVzIHRoZSBtYXhpbXVtIGZvciB0aGUgZGlyZWN0aW9uIHdlIGFyZSB1c2luZyAobWF4V2lkdGggLyBtYXhIZWlnaHQpXG5cdC8vIEBwYXJhbSBwZXJjZW50YWdlUHJvcGVydHkgOiBwcm9wZXJ0eSBvZiBwYXJlbnQgdG8gdXNlIHdoZW4gY2FsY3VsYXRpbmcgd2lkdGggYXMgYSBwZXJjZW50YWdlXG5cdC8vIEBzZWUgaHR0cDovL3d3dy5uYXRoYW5hZWxqb25lcy5jb20vYmxvZy8yMDEzL3JlYWRpbmctbWF4LXdpZHRoLWNyb3NzLWJyb3dzZXJcblx0ZnVuY3Rpb24gZ2V0Q29uc3RyYWludERpbWVuc2lvbihkb21Ob2RlLCBtYXhTdHlsZSwgcGVyY2VudGFnZVByb3BlcnR5KSB7XG5cdFx0dmFyIHZpZXcgPSBkb2N1bWVudC5kZWZhdWx0Vmlldztcblx0XHR2YXIgcGFyZW50Tm9kZSA9IGhlbHBlcnMuX2dldFBhcmVudE5vZGUoZG9tTm9kZSk7XG5cdFx0dmFyIGNvbnN0cmFpbmVkTm9kZSA9IHZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShkb21Ob2RlKVttYXhTdHlsZV07XG5cdFx0dmFyIGNvbnN0cmFpbmVkQ29udGFpbmVyID0gdmlldy5nZXRDb21wdXRlZFN0eWxlKHBhcmVudE5vZGUpW21heFN0eWxlXTtcblx0XHR2YXIgaGFzQ05vZGUgPSBpc0NvbnN0cmFpbmVkVmFsdWUoY29uc3RyYWluZWROb2RlKTtcblx0XHR2YXIgaGFzQ0NvbnRhaW5lciA9IGlzQ29uc3RyYWluZWRWYWx1ZShjb25zdHJhaW5lZENvbnRhaW5lcik7XG5cdFx0dmFyIGluZmluaXR5ID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuXG5cdFx0aWYgKGhhc0NOb2RlIHx8IGhhc0NDb250YWluZXIpIHtcblx0XHRcdHJldHVybiBNYXRoLm1pbihcblx0XHRcdFx0aGFzQ05vZGUgPyBwYXJzZU1heFN0eWxlKGNvbnN0cmFpbmVkTm9kZSwgZG9tTm9kZSwgcGVyY2VudGFnZVByb3BlcnR5KSA6IGluZmluaXR5LFxuXHRcdFx0XHRoYXNDQ29udGFpbmVyID8gcGFyc2VNYXhTdHlsZShjb25zdHJhaW5lZENvbnRhaW5lciwgcGFyZW50Tm9kZSwgcGVyY2VudGFnZVByb3BlcnR5KSA6IGluZmluaXR5KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gJ25vbmUnO1xuXHR9XG5cdC8vIHJldHVybnMgTnVtYmVyIG9yIHVuZGVmaW5lZCBpZiBubyBjb25zdHJhaW50XG5cdGhlbHBlcnMuZ2V0Q29uc3RyYWludFdpZHRoID0gZnVuY3Rpb24oZG9tTm9kZSkge1xuXHRcdHJldHVybiBnZXRDb25zdHJhaW50RGltZW5zaW9uKGRvbU5vZGUsICdtYXgtd2lkdGgnLCAnY2xpZW50V2lkdGgnKTtcblx0fTtcblx0Ly8gcmV0dXJucyBOdW1iZXIgb3IgdW5kZWZpbmVkIGlmIG5vIGNvbnN0cmFpbnRcblx0aGVscGVycy5nZXRDb25zdHJhaW50SGVpZ2h0ID0gZnVuY3Rpb24oZG9tTm9kZSkge1xuXHRcdHJldHVybiBnZXRDb25zdHJhaW50RGltZW5zaW9uKGRvbU5vZGUsICdtYXgtaGVpZ2h0JywgJ2NsaWVudEhlaWdodCcpO1xuXHR9O1xuXHQvKipcblx0ICogQHByaXZhdGVcbiBcdCAqL1xuXHRoZWxwZXJzLl9jYWxjdWxhdGVQYWRkaW5nID0gZnVuY3Rpb24oY29udGFpbmVyLCBwYWRkaW5nLCBwYXJlbnREaW1lbnNpb24pIHtcblx0XHRwYWRkaW5nID0gaGVscGVycy5nZXRTdHlsZShjb250YWluZXIsIHBhZGRpbmcpO1xuXG5cdFx0cmV0dXJuIHBhZGRpbmcuaW5kZXhPZignJScpID4gLTEgPyBwYXJlbnREaW1lbnNpb24gLyBwYXJzZUludChwYWRkaW5nLCAxMCkgOiBwYXJzZUludChwYWRkaW5nLCAxMCk7XG5cdH07XG5cdC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0aGVscGVycy5fZ2V0UGFyZW50Tm9kZSA9IGZ1bmN0aW9uKGRvbU5vZGUpIHtcblx0XHR2YXIgcGFyZW50ID0gZG9tTm9kZS5wYXJlbnROb2RlO1xuXHRcdGlmIChwYXJlbnQgJiYgcGFyZW50Lmhvc3QpIHtcblx0XHRcdHBhcmVudCA9IHBhcmVudC5ob3N0O1xuXHRcdH1cblx0XHRyZXR1cm4gcGFyZW50O1xuXHR9O1xuXHRoZWxwZXJzLmdldE1heGltdW1XaWR0aCA9IGZ1bmN0aW9uKGRvbU5vZGUpIHtcblx0XHR2YXIgY29udGFpbmVyID0gaGVscGVycy5fZ2V0UGFyZW50Tm9kZShkb21Ob2RlKTtcblx0XHRpZiAoIWNvbnRhaW5lcikge1xuXHRcdFx0cmV0dXJuIGRvbU5vZGUuY2xpZW50V2lkdGg7XG5cdFx0fVxuXG5cdFx0dmFyIGNsaWVudFdpZHRoID0gY29udGFpbmVyLmNsaWVudFdpZHRoO1xuXHRcdHZhciBwYWRkaW5nTGVmdCA9IGhlbHBlcnMuX2NhbGN1bGF0ZVBhZGRpbmcoY29udGFpbmVyLCAncGFkZGluZy1sZWZ0JywgY2xpZW50V2lkdGgpO1xuXHRcdHZhciBwYWRkaW5nUmlnaHQgPSBoZWxwZXJzLl9jYWxjdWxhdGVQYWRkaW5nKGNvbnRhaW5lciwgJ3BhZGRpbmctcmlnaHQnLCBjbGllbnRXaWR0aCk7XG5cblx0XHR2YXIgdyA9IGNsaWVudFdpZHRoIC0gcGFkZGluZ0xlZnQgLSBwYWRkaW5nUmlnaHQ7XG5cdFx0dmFyIGN3ID0gaGVscGVycy5nZXRDb25zdHJhaW50V2lkdGgoZG9tTm9kZSk7XG5cdFx0cmV0dXJuIGlzTmFOKGN3KSA/IHcgOiBNYXRoLm1pbih3LCBjdyk7XG5cdH07XG5cdGhlbHBlcnMuZ2V0TWF4aW11bUhlaWdodCA9IGZ1bmN0aW9uKGRvbU5vZGUpIHtcblx0XHR2YXIgY29udGFpbmVyID0gaGVscGVycy5fZ2V0UGFyZW50Tm9kZShkb21Ob2RlKTtcblx0XHRpZiAoIWNvbnRhaW5lcikge1xuXHRcdFx0cmV0dXJuIGRvbU5vZGUuY2xpZW50SGVpZ2h0O1xuXHRcdH1cblxuXHRcdHZhciBjbGllbnRIZWlnaHQgPSBjb250YWluZXIuY2xpZW50SGVpZ2h0O1xuXHRcdHZhciBwYWRkaW5nVG9wID0gaGVscGVycy5fY2FsY3VsYXRlUGFkZGluZyhjb250YWluZXIsICdwYWRkaW5nLXRvcCcsIGNsaWVudEhlaWdodCk7XG5cdFx0dmFyIHBhZGRpbmdCb3R0b20gPSBoZWxwZXJzLl9jYWxjdWxhdGVQYWRkaW5nKGNvbnRhaW5lciwgJ3BhZGRpbmctYm90dG9tJywgY2xpZW50SGVpZ2h0KTtcblxuXHRcdHZhciBoID0gY2xpZW50SGVpZ2h0IC0gcGFkZGluZ1RvcCAtIHBhZGRpbmdCb3R0b207XG5cdFx0dmFyIGNoID0gaGVscGVycy5nZXRDb25zdHJhaW50SGVpZ2h0KGRvbU5vZGUpO1xuXHRcdHJldHVybiBpc05hTihjaCkgPyBoIDogTWF0aC5taW4oaCwgY2gpO1xuXHR9O1xuXHRoZWxwZXJzLmdldFN0eWxlID0gZnVuY3Rpb24oZWwsIHByb3BlcnR5KSB7XG5cdFx0cmV0dXJuIGVsLmN1cnJlbnRTdHlsZSA/XG5cdFx0XHRlbC5jdXJyZW50U3R5bGVbcHJvcGVydHldIDpcblx0XHRcdGRvY3VtZW50LmRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGUoZWwsIG51bGwpLmdldFByb3BlcnR5VmFsdWUocHJvcGVydHkpO1xuXHR9O1xuXHRoZWxwZXJzLnJldGluYVNjYWxlID0gZnVuY3Rpb24oY2hhcnQsIGZvcmNlUmF0aW8pIHtcblx0XHR2YXIgcGl4ZWxSYXRpbyA9IGNoYXJ0LmN1cnJlbnREZXZpY2VQaXhlbFJhdGlvID0gZm9yY2VSYXRpbyB8fCAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmRldmljZVBpeGVsUmF0aW8pIHx8IDE7XG5cdFx0aWYgKHBpeGVsUmF0aW8gPT09IDEpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgY2FudmFzID0gY2hhcnQuY2FudmFzO1xuXHRcdHZhciBoZWlnaHQgPSBjaGFydC5oZWlnaHQ7XG5cdFx0dmFyIHdpZHRoID0gY2hhcnQud2lkdGg7XG5cblx0XHRjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0ICogcGl4ZWxSYXRpbztcblx0XHRjYW52YXMud2lkdGggPSB3aWR0aCAqIHBpeGVsUmF0aW87XG5cdFx0Y2hhcnQuY3R4LnNjYWxlKHBpeGVsUmF0aW8sIHBpeGVsUmF0aW8pO1xuXG5cdFx0Ly8gSWYgbm8gc3R5bGUgaGFzIGJlZW4gc2V0IG9uIHRoZSBjYW52YXMsIHRoZSByZW5kZXIgc2l6ZSBpcyB1c2VkIGFzIGRpc3BsYXkgc2l6ZSxcblx0XHQvLyBtYWtpbmcgdGhlIGNoYXJ0IHZpc3VhbGx5IGJpZ2dlciwgc28gbGV0J3MgZW5mb3JjZSBpdCB0byB0aGUgXCJjb3JyZWN0XCIgdmFsdWVzLlxuXHRcdC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvMzU3NVxuXHRcdGlmICghY2FudmFzLnN0eWxlLmhlaWdodCAmJiAhY2FudmFzLnN0eWxlLndpZHRoKSB7XG5cdFx0XHRjYW52YXMuc3R5bGUuaGVpZ2h0ID0gaGVpZ2h0ICsgJ3B4Jztcblx0XHRcdGNhbnZhcy5zdHlsZS53aWR0aCA9IHdpZHRoICsgJ3B4Jztcblx0XHR9XG5cdH07XG5cdC8vIC0tIENhbnZhcyBtZXRob2RzXG5cdGhlbHBlcnMuZm9udFN0cmluZyA9IGZ1bmN0aW9uKHBpeGVsU2l6ZSwgZm9udFN0eWxlLCBmb250RmFtaWx5KSB7XG5cdFx0cmV0dXJuIGZvbnRTdHlsZSArICcgJyArIHBpeGVsU2l6ZSArICdweCAnICsgZm9udEZhbWlseTtcblx0fTtcblx0aGVscGVycy5sb25nZXN0VGV4dCA9IGZ1bmN0aW9uKGN0eCwgZm9udCwgYXJyYXlPZlRoaW5ncywgY2FjaGUpIHtcblx0XHRjYWNoZSA9IGNhY2hlIHx8IHt9O1xuXHRcdHZhciBkYXRhID0gY2FjaGUuZGF0YSA9IGNhY2hlLmRhdGEgfHwge307XG5cdFx0dmFyIGdjID0gY2FjaGUuZ2FyYmFnZUNvbGxlY3QgPSBjYWNoZS5nYXJiYWdlQ29sbGVjdCB8fCBbXTtcblxuXHRcdGlmIChjYWNoZS5mb250ICE9PSBmb250KSB7XG5cdFx0XHRkYXRhID0gY2FjaGUuZGF0YSA9IHt9O1xuXHRcdFx0Z2MgPSBjYWNoZS5nYXJiYWdlQ29sbGVjdCA9IFtdO1xuXHRcdFx0Y2FjaGUuZm9udCA9IGZvbnQ7XG5cdFx0fVxuXG5cdFx0Y3R4LmZvbnQgPSBmb250O1xuXHRcdHZhciBsb25nZXN0ID0gMDtcblx0XHRoZWxwZXJzLmVhY2goYXJyYXlPZlRoaW5ncywgZnVuY3Rpb24odGhpbmcpIHtcblx0XHRcdC8vIFVuZGVmaW5lZCBzdHJpbmdzIGFuZCBhcnJheXMgc2hvdWxkIG5vdCBiZSBtZWFzdXJlZFxuXHRcdFx0aWYgKHRoaW5nICE9PSB1bmRlZmluZWQgJiYgdGhpbmcgIT09IG51bGwgJiYgaGVscGVycy5pc0FycmF5KHRoaW5nKSAhPT0gdHJ1ZSkge1xuXHRcdFx0XHRsb25nZXN0ID0gaGVscGVycy5tZWFzdXJlVGV4dChjdHgsIGRhdGEsIGdjLCBsb25nZXN0LCB0aGluZyk7XG5cdFx0XHR9IGVsc2UgaWYgKGhlbHBlcnMuaXNBcnJheSh0aGluZykpIHtcblx0XHRcdFx0Ly8gaWYgaXQgaXMgYW4gYXJyYXkgbGV0cyBtZWFzdXJlIGVhY2ggZWxlbWVudFxuXHRcdFx0XHQvLyB0byBkbyBtYXliZSBzaW1wbGlmeSB0aGlzIGZ1bmN0aW9uIGEgYml0IHNvIHdlIGNhbiBkbyB0aGlzIG1vcmUgcmVjdXJzaXZlbHk/XG5cdFx0XHRcdGhlbHBlcnMuZWFjaCh0aGluZywgZnVuY3Rpb24obmVzdGVkVGhpbmcpIHtcblx0XHRcdFx0XHQvLyBVbmRlZmluZWQgc3RyaW5ncyBhbmQgYXJyYXlzIHNob3VsZCBub3QgYmUgbWVhc3VyZWRcblx0XHRcdFx0XHRpZiAobmVzdGVkVGhpbmcgIT09IHVuZGVmaW5lZCAmJiBuZXN0ZWRUaGluZyAhPT0gbnVsbCAmJiAhaGVscGVycy5pc0FycmF5KG5lc3RlZFRoaW5nKSkge1xuXHRcdFx0XHRcdFx0bG9uZ2VzdCA9IGhlbHBlcnMubWVhc3VyZVRleHQoY3R4LCBkYXRhLCBnYywgbG9uZ2VzdCwgbmVzdGVkVGhpbmcpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHR2YXIgZ2NMZW4gPSBnYy5sZW5ndGggLyAyO1xuXHRcdGlmIChnY0xlbiA+IGFycmF5T2ZUaGluZ3MubGVuZ3RoKSB7XG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGdjTGVuOyBpKyspIHtcblx0XHRcdFx0ZGVsZXRlIGRhdGFbZ2NbaV1dO1xuXHRcdFx0fVxuXHRcdFx0Z2Muc3BsaWNlKDAsIGdjTGVuKTtcblx0XHR9XG5cdFx0cmV0dXJuIGxvbmdlc3Q7XG5cdH07XG5cdGhlbHBlcnMubWVhc3VyZVRleHQgPSBmdW5jdGlvbihjdHgsIGRhdGEsIGdjLCBsb25nZXN0LCBzdHJpbmcpIHtcblx0XHR2YXIgdGV4dFdpZHRoID0gZGF0YVtzdHJpbmddO1xuXHRcdGlmICghdGV4dFdpZHRoKSB7XG5cdFx0XHR0ZXh0V2lkdGggPSBkYXRhW3N0cmluZ10gPSBjdHgubWVhc3VyZVRleHQoc3RyaW5nKS53aWR0aDtcblx0XHRcdGdjLnB1c2goc3RyaW5nKTtcblx0XHR9XG5cdFx0aWYgKHRleHRXaWR0aCA+IGxvbmdlc3QpIHtcblx0XHRcdGxvbmdlc3QgPSB0ZXh0V2lkdGg7XG5cdFx0fVxuXHRcdHJldHVybiBsb25nZXN0O1xuXHR9O1xuXHRoZWxwZXJzLm51bWJlck9mTGFiZWxMaW5lcyA9IGZ1bmN0aW9uKGFycmF5T2ZUaGluZ3MpIHtcblx0XHR2YXIgbnVtYmVyT2ZMaW5lcyA9IDE7XG5cdFx0aGVscGVycy5lYWNoKGFycmF5T2ZUaGluZ3MsIGZ1bmN0aW9uKHRoaW5nKSB7XG5cdFx0XHRpZiAoaGVscGVycy5pc0FycmF5KHRoaW5nKSkge1xuXHRcdFx0XHRpZiAodGhpbmcubGVuZ3RoID4gbnVtYmVyT2ZMaW5lcykge1xuXHRcdFx0XHRcdG51bWJlck9mTGluZXMgPSB0aGluZy5sZW5ndGg7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0XHRyZXR1cm4gbnVtYmVyT2ZMaW5lcztcblx0fTtcblxuXHRoZWxwZXJzLmNvbG9yID0gIWNvbG9yID9cblx0XHRmdW5jdGlvbih2YWx1ZSkge1xuXHRcdFx0Y29uc29sZS5lcnJvcignQ29sb3IuanMgbm90IGZvdW5kIScpO1xuXHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdH0gOlxuXHRcdGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHQvKiBnbG9iYWwgQ2FudmFzR3JhZGllbnQgKi9cblx0XHRcdGlmICh2YWx1ZSBpbnN0YW5jZW9mIENhbnZhc0dyYWRpZW50KSB7XG5cdFx0XHRcdHZhbHVlID0gZGVmYXVsdHMuZ2xvYmFsLmRlZmF1bHRDb2xvcjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGNvbG9yKHZhbHVlKTtcblx0XHR9O1xuXG5cdGhlbHBlcnMuZ2V0SG92ZXJDb2xvciA9IGZ1bmN0aW9uKGNvbG9yVmFsdWUpIHtcblx0XHQvKiBnbG9iYWwgQ2FudmFzUGF0dGVybiAqL1xuXHRcdHJldHVybiAoY29sb3JWYWx1ZSBpbnN0YW5jZW9mIENhbnZhc1BhdHRlcm4pID9cblx0XHRcdGNvbG9yVmFsdWUgOlxuXHRcdFx0aGVscGVycy5jb2xvcihjb2xvclZhbHVlKS5zYXR1cmF0ZSgwLjUpLmRhcmtlbigwLjEpLnJnYlN0cmluZygpO1xuXHR9O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///fbd8\n")},ff98:function(module,exports,__webpack_require__){"use strict";eval('\n\nvar defaults = __webpack_require__(/*! ../core/core.defaults */ "beaa");\nvar Element = __webpack_require__(/*! ../core/core.element */ "4a45");\nvar helpers = __webpack_require__(/*! ../helpers/index */ "66c8");\n\nvar defaultColor = defaults.global.defaultColor;\n\ndefaults._set(\'global\', {\n\telements: {\n\t\tpoint: {\n\t\t\tradius: 3,\n\t\t\tpointStyle: \'circle\',\n\t\t\tbackgroundColor: defaultColor,\n\t\t\tborderColor: defaultColor,\n\t\t\tborderWidth: 1,\n\t\t\t// Hover\n\t\t\thitRadius: 1,\n\t\t\thoverRadius: 4,\n\t\t\thoverBorderWidth: 1\n\t\t}\n\t}\n});\n\nfunction xRange(mouseX) {\n\tvar vm = this._view;\n\treturn vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false;\n}\n\nfunction yRange(mouseY) {\n\tvar vm = this._view;\n\treturn vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false;\n}\n\nmodule.exports = Element.extend({\n\tinRange: function(mouseX, mouseY) {\n\t\tvar vm = this._view;\n\t\treturn vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;\n\t},\n\n\tinLabelRange: xRange,\n\tinXRange: xRange,\n\tinYRange: yRange,\n\n\tgetCenterPoint: function() {\n\t\tvar vm = this._view;\n\t\treturn {\n\t\t\tx: vm.x,\n\t\t\ty: vm.y\n\t\t};\n\t},\n\n\tgetArea: function() {\n\t\treturn Math.PI * Math.pow(this._view.radius, 2);\n\t},\n\n\ttooltipPosition: function() {\n\t\tvar vm = this._view;\n\t\treturn {\n\t\t\tx: vm.x,\n\t\t\ty: vm.y,\n\t\t\tpadding: vm.radius + vm.borderWidth\n\t\t};\n\t},\n\n\tdraw: function(chartArea) {\n\t\tvar vm = this._view;\n\t\tvar model = this._model;\n\t\tvar ctx = this._chart.ctx;\n\t\tvar pointStyle = vm.pointStyle;\n\t\tvar rotation = vm.rotation;\n\t\tvar radius = vm.radius;\n\t\tvar x = vm.x;\n\t\tvar y = vm.y;\n\t\tvar errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.)\n\n\t\tif (vm.skip) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clipping for Points.\n\t\tif (chartArea === undefined || (model.x >= chartArea.left && chartArea.right * errMargin >= model.x && model.y >= chartArea.top && chartArea.bottom * errMargin >= model.y)) {\n\t\t\tctx.strokeStyle = vm.borderColor || defaultColor;\n\t\t\tctx.lineWidth = helpers.valueOrDefault(vm.borderWidth, defaults.global.elements.point.borderWidth);\n\t\t\tctx.fillStyle = vm.backgroundColor || defaultColor;\n\t\t\thelpers.canvas.drawPoint(ctx, pointStyle, radius, x, y, rotation);\n\t\t}\n\t}\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmY5OC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvZWxlbWVudHMvZWxlbWVudC5wb2ludC5qcz8zOTc2Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGRlZmF1bHRzID0gcmVxdWlyZSgnLi4vY29yZS9jb3JlLmRlZmF1bHRzJyk7XG52YXIgRWxlbWVudCA9IHJlcXVpcmUoJy4uL2NvcmUvY29yZS5lbGVtZW50Jyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvaW5kZXgnKTtcblxudmFyIGRlZmF1bHRDb2xvciA9IGRlZmF1bHRzLmdsb2JhbC5kZWZhdWx0Q29sb3I7XG5cbmRlZmF1bHRzLl9zZXQoJ2dsb2JhbCcsIHtcblx0ZWxlbWVudHM6IHtcblx0XHRwb2ludDoge1xuXHRcdFx0cmFkaXVzOiAzLFxuXHRcdFx0cG9pbnRTdHlsZTogJ2NpcmNsZScsXG5cdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IGRlZmF1bHRDb2xvcixcblx0XHRcdGJvcmRlckNvbG9yOiBkZWZhdWx0Q29sb3IsXG5cdFx0XHRib3JkZXJXaWR0aDogMSxcblx0XHRcdC8vIEhvdmVyXG5cdFx0XHRoaXRSYWRpdXM6IDEsXG5cdFx0XHRob3ZlclJhZGl1czogNCxcblx0XHRcdGhvdmVyQm9yZGVyV2lkdGg6IDFcblx0XHR9XG5cdH1cbn0pO1xuXG5mdW5jdGlvbiB4UmFuZ2UobW91c2VYKSB7XG5cdHZhciB2bSA9IHRoaXMuX3ZpZXc7XG5cdHJldHVybiB2bSA/IChNYXRoLmFicyhtb3VzZVggLSB2bS54KSA8IHZtLnJhZGl1cyArIHZtLmhpdFJhZGl1cykgOiBmYWxzZTtcbn1cblxuZnVuY3Rpb24geVJhbmdlKG1vdXNlWSkge1xuXHR2YXIgdm0gPSB0aGlzLl92aWV3O1xuXHRyZXR1cm4gdm0gPyAoTWF0aC5hYnMobW91c2VZIC0gdm0ueSkgPCB2bS5yYWRpdXMgKyB2bS5oaXRSYWRpdXMpIDogZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRWxlbWVudC5leHRlbmQoe1xuXHRpblJhbmdlOiBmdW5jdGlvbihtb3VzZVgsIG1vdXNlWSkge1xuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XG5cdFx0cmV0dXJuIHZtID8gKChNYXRoLnBvdyhtb3VzZVggLSB2bS54LCAyKSArIE1hdGgucG93KG1vdXNlWSAtIHZtLnksIDIpKSA8IE1hdGgucG93KHZtLmhpdFJhZGl1cyArIHZtLnJhZGl1cywgMikpIDogZmFsc2U7XG5cdH0sXG5cblx0aW5MYWJlbFJhbmdlOiB4UmFuZ2UsXG5cdGluWFJhbmdlOiB4UmFuZ2UsXG5cdGluWVJhbmdlOiB5UmFuZ2UsXG5cblx0Z2V0Q2VudGVyUG9pbnQ6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHg6IHZtLngsXG5cdFx0XHR5OiB2bS55XG5cdFx0fTtcblx0fSxcblxuXHRnZXRBcmVhOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gTWF0aC5QSSAqIE1hdGgucG93KHRoaXMuX3ZpZXcucmFkaXVzLCAyKTtcblx0fSxcblxuXHR0b29sdGlwUG9zaXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHg6IHZtLngsXG5cdFx0XHR5OiB2bS55LFxuXHRcdFx0cGFkZGluZzogdm0ucmFkaXVzICsgdm0uYm9yZGVyV2lkdGhcblx0XHR9O1xuXHR9LFxuXG5cdGRyYXc6IGZ1bmN0aW9uKGNoYXJ0QXJlYSkge1xuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XG5cdFx0dmFyIG1vZGVsID0gdGhpcy5fbW9kZWw7XG5cdFx0dmFyIGN0eCA9IHRoaXMuX2NoYXJ0LmN0eDtcblx0XHR2YXIgcG9pbnRTdHlsZSA9IHZtLnBvaW50U3R5bGU7XG5cdFx0dmFyIHJvdGF0aW9uID0gdm0ucm90YXRpb247XG5cdFx0dmFyIHJhZGl1cyA9IHZtLnJhZGl1cztcblx0XHR2YXIgeCA9IHZtLng7XG5cdFx0dmFyIHkgPSB2bS55O1xuXHRcdHZhciBlcnJNYXJnaW4gPSAxLjAxOyAvLyAxLjAxIGlzIG1hcmdpbiBmb3IgQWNjdW11bGF0ZWQgZXJyb3IuIChFc3BlY2lhbGx5IEVkZ2UsIElFLilcblxuXHRcdGlmICh2bS5za2lwKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gQ2xpcHBpbmcgZm9yIFBvaW50cy5cblx0XHRpZiAoY2hhcnRBcmVhID09PSB1bmRlZmluZWQgfHwgKG1vZGVsLnggPj0gY2hhcnRBcmVhLmxlZnQgJiYgY2hhcnRBcmVhLnJpZ2h0ICogZXJyTWFyZ2luID49IG1vZGVsLnggJiYgbW9kZWwueSA+PSBjaGFydEFyZWEudG9wICYmIGNoYXJ0QXJlYS5ib3R0b20gKiBlcnJNYXJnaW4gPj0gbW9kZWwueSkpIHtcblx0XHRcdGN0eC5zdHJva2VTdHlsZSA9IHZtLmJvcmRlckNvbG9yIHx8IGRlZmF1bHRDb2xvcjtcblx0XHRcdGN0eC5saW5lV2lkdGggPSBoZWxwZXJzLnZhbHVlT3JEZWZhdWx0KHZtLmJvcmRlcldpZHRoLCBkZWZhdWx0cy5nbG9iYWwuZWxlbWVudHMucG9pbnQuYm9yZGVyV2lkdGgpO1xuXHRcdFx0Y3R4LmZpbGxTdHlsZSA9IHZtLmJhY2tncm91bmRDb2xvciB8fCBkZWZhdWx0Q29sb3I7XG5cdFx0XHRoZWxwZXJzLmNhbnZhcy5kcmF3UG9pbnQoY3R4LCBwb2ludFN0eWxlLCByYWRpdXMsIHgsIHksIHJvdGF0aW9uKTtcblx0XHR9XG5cdH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///ff98\n')}}]);

TODO found
Open

(window.webpackJsonp=window.webpackJsonp||[]).push([["npm.spot-framework"],{"0056":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Group = __webpack_require__(/*! ./group */ \"9083\");\n\nfunction setOrdering (groups, ordering) {\n  if (ordering === 'count') {\n    groups.comparator = function (a, b) {\n      if (a.count === b.count) {\n        return a.value < b.value ? -1 : 1;\n      } else {\n        return b.count - a.count;\n      }\n    };\n  } else if (ordering === 'value') {\n    groups.comparator = 'value';\n  } else {\n    console.error('Ordering not implemented for partition: ', ordering);\n  }\n  groups.sort();\n}\n\nmodule.exports = Collection.extend({\n  indexes: ['value', 'label', 'group', 'groupIndex'],\n  model: Group,\n  comparator: 'label',\n  initialize: function (models, options) {\n    var groups = this;\n    var partition = options.parent;\n\n    // update group index on resort\n    this.on('sort', function () {\n      this.forEach(function (group, i) {\n        group.groupIndex = i;\n      });\n    }, this);\n\n    // this.parent := partition\n    if (partition) {\n      setOrdering(groups, partition.ordering);\n\n      partition.on('change ordering', function () {\n        setOrdering(groups, partition.ordering);\n      });\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDA1Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2dyb3VwLWNvbGxlY3Rpb24uanM/OGM1ZiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgR3JvdXAgPSByZXF1aXJlKCcuL2dyb3VwJyk7XG5cbmZ1bmN0aW9uIHNldE9yZGVyaW5nIChncm91cHMsIG9yZGVyaW5nKSB7XG4gIGlmIChvcmRlcmluZyA9PT0gJ2NvdW50Jykge1xuICAgIGdyb3Vwcy5jb21wYXJhdG9yID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIGlmIChhLmNvdW50ID09PSBiLmNvdW50KSB7XG4gICAgICAgIHJldHVybiBhLnZhbHVlIDwgYi52YWx1ZSA/IC0xIDogMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBiLmNvdW50IC0gYS5jb3VudDtcbiAgICAgIH1cbiAgICB9O1xuICB9IGVsc2UgaWYgKG9yZGVyaW5nID09PSAndmFsdWUnKSB7XG4gICAgZ3JvdXBzLmNvbXBhcmF0b3IgPSAndmFsdWUnO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUuZXJyb3IoJ09yZGVyaW5nIG5vdCBpbXBsZW1lbnRlZCBmb3IgcGFydGl0aW9uOiAnLCBvcmRlcmluZyk7XG4gIH1cbiAgZ3JvdXBzLnNvcnQoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDb2xsZWN0aW9uLmV4dGVuZCh7XG4gIGluZGV4ZXM6IFsndmFsdWUnLCAnbGFiZWwnLCAnZ3JvdXAnLCAnZ3JvdXBJbmRleCddLFxuICBtb2RlbDogR3JvdXAsXG4gIGNvbXBhcmF0b3I6ICdsYWJlbCcsXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uIChtb2RlbHMsIG9wdGlvbnMpIHtcbiAgICB2YXIgZ3JvdXBzID0gdGhpcztcbiAgICB2YXIgcGFydGl0aW9uID0gb3B0aW9ucy5wYXJlbnQ7XG5cbiAgICAvLyB1cGRhdGUgZ3JvdXAgaW5kZXggb24gcmVzb3J0XG4gICAgdGhpcy5vbignc29ydCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZ3JvdXAsIGkpIHtcbiAgICAgICAgZ3JvdXAuZ3JvdXBJbmRleCA9IGk7XG4gICAgICB9KTtcbiAgICB9LCB0aGlzKTtcblxuICAgIC8vIHRoaXMucGFyZW50IDo9IHBhcnRpdGlvblxuICAgIGlmIChwYXJ0aXRpb24pIHtcbiAgICAgIHNldE9yZGVyaW5nKGdyb3VwcywgcGFydGl0aW9uLm9yZGVyaW5nKTtcblxuICAgICAgcGFydGl0aW9uLm9uKCdjaGFuZ2Ugb3JkZXJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNldE9yZGVyaW5nKGdyb3VwcywgcGFydGl0aW9uLm9yZGVyaW5nKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///0056\n")},"0112":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar transports = __webpack_require__(/*! ./transports/index */ \"834b\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:socket');\nvar index = __webpack_require__(/*! indexof */ \"3294\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar parseuri = __webpack_require__(/*! parseuri */ \"64a0\");\nvar parsejson = __webpack_require__(/*! parsejson */ \"185c\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = Socket;\n\n/**\n * Socket constructor.\n *\n * @param {String|Object} uri or options\n * @param {Object} options\n * @api public\n */\n\nfunction Socket (uri, opts) {\n  if (!(this instanceof Socket)) return new Socket(uri, opts);\n\n  opts = opts || {};\n\n  if (uri && 'object' === typeof uri) {\n    opts = uri;\n    uri = null;\n  }\n\n  if (uri) {\n    uri = parseuri(uri);\n    opts.hostname = uri.host;\n    opts.secure = uri.protocol === 'https' || uri.protocol === 'wss';\n    opts.port = uri.port;\n    if (uri.query) opts.query = uri.query;\n  } else if (opts.host) {\n    opts.hostname = parseuri(opts.host).host;\n  }\n\n  this.secure = null != opts.secure ? opts.secure\n    : (global.location && 'https:' === location.protocol);\n\n  if (opts.hostname && !opts.port) {\n    // if no port is specified manually, use the protocol default\n    opts.port = this.secure ? '443' : '80';\n  }\n\n  this.agent = opts.agent || false;\n  this.hostname = opts.hostname ||\n    (global.location ? location.hostname : 'localhost');\n  this.port = opts.port || (global.location && location.port\n      ? location.port\n      : (this.secure ? 443 : 80));\n  this.query = opts.query || {};\n  if ('string' === typeof this.query) this.query = parseqs.decode(this.query);\n  this.upgrade = false !== opts.upgrade;\n  this.path = (opts.path || '/engine.io').replace(/\\/$/, '') + '/';\n  this.forceJSONP = !!opts.forceJSONP;\n  this.jsonp = false !== opts.jsonp;\n  this.forceBase64 = !!opts.forceBase64;\n  this.enablesXDR = !!opts.enablesXDR;\n  this.timestampParam = opts.timestampParam || 't';\n  this.timestampRequests = opts.timestampRequests;\n  this.transports = opts.transports || ['polling', 'websocket'];\n  this.readyState = '';\n  this.writeBuffer = [];\n  this.prevBufferLen = 0;\n  this.policyPort = opts.policyPort || 843;\n  this.rememberUpgrade = opts.rememberUpgrade || false;\n  this.binaryType = null;\n  this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;\n  this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || {}) : false;\n\n  if (true === this.perMessageDeflate) this.perMessageDeflate = {};\n  if (this.perMessageDeflate && null == this.perMessageDeflate.threshold) {\n    this.perMessageDeflate.threshold = 1024;\n  }\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx || null;\n  this.key = opts.key || null;\n  this.passphrase = opts.passphrase || null;\n  this.cert = opts.cert || null;\n  this.ca = opts.ca || null;\n  this.ciphers = opts.ciphers || null;\n  this.rejectUnauthorized = opts.rejectUnauthorized === undefined ? null : opts.rejectUnauthorized;\n  this.forceNode = !!opts.forceNode;\n\n  // other options for Node.js client\n  var freeGlobal = typeof global === 'object' && global;\n  if (freeGlobal.global === freeGlobal) {\n    if (opts.extraHeaders && Object.keys(opts.extraHeaders).length > 0) {\n      this.extraHeaders = opts.extraHeaders;\n    }\n\n    if (opts.localAddress) {\n      this.localAddress = opts.localAddress;\n    }\n  }\n\n  // set on handshake\n  this.id = null;\n  this.upgrades = null;\n  this.pingInterval = null;\n  this.pingTimeout = null;\n\n  // set on heartbeat\n  this.pingIntervalTimer = null;\n  this.pingTimeoutTimer = null;\n\n  this.open();\n}\n\nSocket.priorWebsocketSuccess = false;\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Socket.prototype);\n\n/**\n * Protocol version.\n *\n * @api public\n */\n\nSocket.protocol = parser.protocol; // this is an int\n\n/**\n * Expose deps for legacy compatibility\n * and standalone browser access.\n */\n\nSocket.Socket = Socket;\nSocket.Transport = __webpack_require__(/*! ./transport */ \"0d97\");\nSocket.transports = __webpack_require__(/*! ./transports/index */ \"834b\");\nSocket.parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\n\n/**\n * Creates transport of the given type.\n *\n * @param {String} transport name\n * @return {Transport}\n * @api private\n */\n\nSocket.prototype.createTransport = function (name) {\n  debug('creating transport \"%s\"', name);\n  var query = clone(this.query);\n\n  // append engine.io protocol identifier\n  query.EIO = parser.protocol;\n\n  // transport name\n  query.transport = name;\n\n  // session id if we already have one\n  if (this.id) query.sid = this.id;\n\n  var transport = new transports[name]({\n    agent: this.agent,\n    hostname: this.hostname,\n    port: this.port,\n    secure: this.secure,\n    path: this.path,\n    query: query,\n    forceJSONP: this.forceJSONP,\n    jsonp: this.jsonp,\n    forceBase64: this.forceBase64,\n    enablesXDR: this.enablesXDR,\n    timestampRequests: this.timestampRequests,\n    timestampParam: this.timestampParam,\n    policyPort: this.policyPort,\n    socket: this,\n    pfx: this.pfx,\n    key: this.key,\n    passphrase: this.passphrase,\n    cert: this.cert,\n    ca: this.ca,\n    ciphers: this.ciphers,\n    rejectUnauthorized: this.rejectUnauthorized,\n    perMessageDeflate: this.perMessageDeflate,\n    extraHeaders: this.extraHeaders,\n    forceNode: this.forceNode,\n    localAddress: this.localAddress\n  });\n\n  return transport;\n};\n\nfunction clone (obj) {\n  var o = {};\n  for (var i in obj) {\n    if (obj.hasOwnProperty(i)) {\n      o[i] = obj[i];\n    }\n  }\n  return o;\n}\n\n/**\n * Initializes transport to use and starts probe.\n *\n * @api private\n */\nSocket.prototype.open = function () {\n  var transport;\n  if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') !== -1) {\n    transport = 'websocket';\n  } else if (0 === this.transports.length) {\n    // Emit error on next tick so it can be listened to\n    var self = this;\n    setTimeout(function () {\n      self.emit('error', 'No transports available');\n    }, 0);\n    return;\n  } else {\n    transport = this.transports[0];\n  }\n  this.readyState = 'opening';\n\n  // Retry with the next transport if the transport is disabled (jsonp: false)\n  try {\n    transport = this.createTransport(transport);\n  } catch (e) {\n    this.transports.shift();\n    this.open();\n    return;\n  }\n\n  transport.open();\n  this.setTransport(transport);\n};\n\n/**\n * Sets the current transport. Disables the existing one (if any).\n *\n * @api private\n */\n\nSocket.prototype.setTransport = function (transport) {\n  debug('setting transport %s', transport.name);\n  var self = this;\n\n  if (this.transport) {\n    debug('clearing existing transport %s', this.transport.name);\n    this.transport.removeAllListeners();\n  }\n\n  // set up transport\n  this.transport = transport;\n\n  // set up transport listeners\n  transport\n  .on('drain', function () {\n    self.onDrain();\n  })\n  .on('packet', function (packet) {\n    self.onPacket(packet);\n  })\n  .on('error', function (e) {\n    self.onError(e);\n  })\n  .on('close', function () {\n    self.onClose('transport close');\n  });\n};\n\n/**\n * Probes a transport.\n *\n * @param {String} transport name\n * @api private\n */\n\nSocket.prototype.probe = function (name) {\n  debug('probing transport \"%s\"', name);\n  var transport = this.createTransport(name, { probe: 1 });\n  var failed = false;\n  var self = this;\n\n  Socket.priorWebsocketSuccess = false;\n\n  function onTransportOpen () {\n    if (self.onlyBinaryUpgrades) {\n      var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;\n      failed = failed || upgradeLosesBinary;\n    }\n    if (failed) return;\n\n    debug('probe transport \"%s\" opened', name);\n    transport.send([{ type: 'ping', data: 'probe' }]);\n    transport.once('packet', function (msg) {\n      if (failed) return;\n      if ('pong' === msg.type && 'probe' === msg.data) {\n        debug('probe transport \"%s\" pong', name);\n        self.upgrading = true;\n        self.emit('upgrading', transport);\n        if (!transport) return;\n        Socket.priorWebsocketSuccess = 'websocket' === transport.name;\n\n        debug('pausing current transport \"%s\"', self.transport.name);\n        self.transport.pause(function () {\n          if (failed) return;\n          if ('closed' === self.readyState) return;\n          debug('changing transport and sending upgrade packet');\n\n          cleanup();\n\n          self.setTransport(transport);\n          transport.send([{ type: 'upgrade' }]);\n          self.emit('upgrade', transport);\n          transport = null;\n          self.upgrading = false;\n          self.flush();\n        });\n      } else {\n        debug('probe transport \"%s\" failed', name);\n        var err = new Error('probe error');\n        err.transport = transport.name;\n        self.emit('upgradeError', err);\n      }\n    });\n  }\n\n  function freezeTransport () {\n    if (failed) return;\n\n    // Any callback called by transport should be ignored since now\n    failed = true;\n\n    cleanup();\n\n    transport.close();\n    transport = null;\n  }\n\n  // Handle any error that happens while probing\n  function onerror (err) {\n    var error = new Error('probe error: ' + err);\n    error.transport = transport.name;\n\n    freezeTransport();\n\n    debug('probe transport \"%s\" failed because of error: %s', name, err);\n\n    self.emit('upgradeError', error);\n  }\n\n  function onTransportClose () {\n    onerror('transport closed');\n  }\n\n  // When the socket is closed while we're probing\n  function onclose () {\n    onerror('socket closed');\n  }\n\n  // When the socket is upgraded while we're probing\n  function onupgrade (to) {\n    if (transport && to.name !== transport.name) {\n      debug('\"%s\" works - aborting \"%s\"', to.name, transport.name);\n      freezeTransport();\n    }\n  }\n\n  // Remove all listeners on the transport and on self\n  function cleanup () {\n    transport.removeListener('open', onTransportOpen);\n    transport.removeListener('error', onerror);\n    transport.removeListener('close', onTransportClose);\n    self.removeListener('close', onclose);\n    self.removeListener('upgrading', onupgrade);\n  }\n\n  transport.once('open', onTransportOpen);\n  transport.once('error', onerror);\n  transport.once('close', onTransportClose);\n\n  this.once('close', onclose);\n  this.once('upgrading', onupgrade);\n\n  transport.open();\n};\n\n/**\n * Called when connection is deemed open.\n *\n * @api public\n */\n\nSocket.prototype.onOpen = function () {\n  debug('socket open');\n  this.readyState = 'open';\n  Socket.priorWebsocketSuccess = 'websocket' === this.transport.name;\n  this.emit('open');\n  this.flush();\n\n  // we check for `readyState` in case an `open`\n  // listener already closed the socket\n  if ('open' === this.readyState && this.upgrade && this.transport.pause) {\n    debug('starting upgrade probes');\n    for (var i = 0, l = this.upgrades.length; i < l; i++) {\n      this.probe(this.upgrades[i]);\n    }\n  }\n};\n\n/**\n * Handles a packet.\n *\n * @api private\n */\n\nSocket.prototype.onPacket = function (packet) {\n  if ('opening' === this.readyState || 'open' === this.readyState ||\n      'closing' === this.readyState) {\n    debug('socket receive: type \"%s\", data \"%s\"', packet.type, packet.data);\n\n    this.emit('packet', packet);\n\n    // Socket is live - any packet counts\n    this.emit('heartbeat');\n\n    switch (packet.type) {\n      case 'open':\n        this.onHandshake(parsejson(packet.data));\n        break;\n\n      case 'pong':\n        this.setPing();\n        this.emit('pong');\n        break;\n\n      case 'error':\n        var err = new Error('server error');\n        err.code = packet.data;\n        this.onError(err);\n        break;\n\n      case 'message':\n        this.emit('data', packet.data);\n        this.emit('message', packet.data);\n        break;\n    }\n  } else {\n    debug('packet received with socket readyState \"%s\"', this.readyState);\n  }\n};\n\n/**\n * Called upon handshake completion.\n *\n * @param {Object} handshake obj\n * @api private\n */\n\nSocket.prototype.onHandshake = function (data) {\n  this.emit('handshake', data);\n  this.id = data.sid;\n  this.transport.query.sid = data.sid;\n  this.upgrades = this.filterUpgrades(data.upgrades);\n  this.pingInterval = data.pingInterval;\n  this.pingTimeout = data.pingTimeout;\n  this.onOpen();\n  // In case open handler closes socket\n  if ('closed' === this.readyState) return;\n  this.setPing();\n\n  // Prolong liveness of socket on heartbeat\n  this.removeListener('heartbeat', this.onHeartbeat);\n  this.on('heartbeat', this.onHeartbeat);\n};\n\n/**\n * Resets ping timeout.\n *\n * @api private\n */\n\nSocket.prototype.onHeartbeat = function (timeout) {\n  clearTimeout(this.pingTimeoutTimer);\n  var self = this;\n  self.pingTimeoutTimer = setTimeout(function () {\n    if ('closed' === self.readyState) return;\n    self.onClose('ping timeout');\n  }, timeout || (self.pingInterval + self.pingTimeout));\n};\n\n/**\n * Pings server every `this.pingInterval` and expects response\n * within `this.pingTimeout` or closes connection.\n *\n * @api private\n */\n\nSocket.prototype.setPing = function () {\n  var self = this;\n  clearTimeout(self.pingIntervalTimer);\n  self.pingIntervalTimer = setTimeout(function () {\n    debug('writing ping packet - expecting pong within %sms', self.pingTimeout);\n    self.ping();\n    self.onHeartbeat(self.pingTimeout);\n  }, self.pingInterval);\n};\n\n/**\n* Sends a ping packet.\n*\n* @api private\n*/\n\nSocket.prototype.ping = function () {\n  var self = this;\n  this.sendPacket('ping', function () {\n    self.emit('ping');\n  });\n};\n\n/**\n * Called on `drain` event\n *\n * @api private\n */\n\nSocket.prototype.onDrain = function () {\n  this.writeBuffer.splice(0, this.prevBufferLen);\n\n  // setting prevBufferLen = 0 is very important\n  // for example, when upgrading, upgrade packet is sent over,\n  // and a nonzero prevBufferLen could cause problems on `drain`\n  this.prevBufferLen = 0;\n\n  if (0 === this.writeBuffer.length) {\n    this.emit('drain');\n  } else {\n    this.flush();\n  }\n};\n\n/**\n * Flush write buffers.\n *\n * @api private\n */\n\nSocket.prototype.flush = function () {\n  if ('closed' !== this.readyState && this.transport.writable &&\n    !this.upgrading && this.writeBuffer.length) {\n    debug('flushing %d packets in socket', this.writeBuffer.length);\n    this.transport.send(this.writeBuffer);\n    // keep track of current length of writeBuffer\n    // splice writeBuffer and callbackBuffer on `drain`\n    this.prevBufferLen = this.writeBuffer.length;\n    this.emit('flush');\n  }\n};\n\n/**\n * Sends a message.\n *\n * @param {String} message.\n * @param {Function} callback function.\n * @param {Object} options.\n * @return {Socket} for chaining.\n * @api public\n */\n\nSocket.prototype.write =\nSocket.prototype.send = function (msg, options, fn) {\n  this.sendPacket('message', msg, options, fn);\n  return this;\n};\n\n/**\n * Sends a packet.\n *\n * @param {String} packet type.\n * @param {String} data.\n * @param {Object} options.\n * @param {Function} callback function.\n * @api private\n */\n\nSocket.prototype.sendPacket = function (type, data, options, fn) {\n  if ('function' === typeof data) {\n    fn = data;\n    data = undefined;\n  }\n\n  if ('function' === typeof options) {\n    fn = options;\n    options = null;\n  }\n\n  if ('closing' === this.readyState || 'closed' === this.readyState) {\n    return;\n  }\n\n  options = options || {};\n  options.compress = false !== options.compress;\n\n  var packet = {\n    type: type,\n    data: data,\n    options: options\n  };\n  this.emit('packetCreate', packet);\n  this.writeBuffer.push(packet);\n  if (fn) this.once('flush', fn);\n  this.flush();\n};\n\n/**\n * Closes the connection.\n *\n * @api private\n */\n\nSocket.prototype.close = function () {\n  if ('opening' === this.readyState || 'open' === this.readyState) {\n    this.readyState = 'closing';\n\n    var self = this;\n\n    if (this.writeBuffer.length) {\n      this.once('drain', function () {\n        if (this.upgrading) {\n          waitForUpgrade();\n        } else {\n          close();\n        }\n      });\n    } else if (this.upgrading) {\n      waitForUpgrade();\n    } else {\n      close();\n    }\n  }\n\n  function close () {\n    self.onClose('forced close');\n    debug('socket closing - telling transport to close');\n    self.transport.close();\n  }\n\n  function cleanupAndClose () {\n    self.removeListener('upgrade', cleanupAndClose);\n    self.removeListener('upgradeError', cleanupAndClose);\n    close();\n  }\n\n  function waitForUpgrade () {\n    // wait for upgrade to finish since we can't send packets while pausing a transport\n    self.once('upgrade', cleanupAndClose);\n    self.once('upgradeError', cleanupAndClose);\n  }\n\n  return this;\n};\n\n/**\n * Called upon transport error\n *\n * @api private\n */\n\nSocket.prototype.onError = function (err) {\n  debug('socket error %j', err);\n  Socket.priorWebsocketSuccess = false;\n  this.emit('error', err);\n  this.onClose('transport error', err);\n};\n\n/**\n * Called upon transport close.\n *\n * @api private\n */\n\nSocket.prototype.onClose = function (reason, desc) {\n  if ('opening' === this.readyState || 'open' === this.readyState || 'closing' === this.readyState) {\n    debug('socket close with reason: \"%s\"', reason);\n    var self = this;\n\n    // clear timers\n    clearTimeout(this.pingIntervalTimer);\n    clearTimeout(this.pingTimeoutTimer);\n\n    // stop event from firing again for transport\n    this.transport.removeAllListeners('close');\n\n    // ensure transport won't stay open\n    this.transport.close();\n\n    // ignore further transport communication\n    this.transport.removeAllListeners();\n\n    // set ready state\n    this.readyState = 'closed';\n\n    // clear session id\n    this.id = null;\n\n    // emit close event\n    this.emit('close', reason, desc);\n\n    // clean buffers after, so users can still\n    // grab the buffers on `close` event\n    self.writeBuffer = [];\n    self.prevBufferLen = 0;\n  }\n};\n\n/**\n * Filters upgrades, returning only those matching client transports.\n *\n * @param {Array} server upgrades\n * @api private\n *\n */\n\nSocket.prototype.filterUpgrades = function (upgrades) {\n  var filteredUpgrades = [];\n  for (var i = 0, j = upgrades.length; i < j; i++) {\n    if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);\n  }\n  return filteredUpgrades;\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDExMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvc29ja2V0LmpzPzM1YjUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL2luZGV4Jyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnNvY2tldCcpO1xudmFyIGluZGV4ID0gcmVxdWlyZSgnaW5kZXhvZicpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBwYXJzZXVyaSA9IHJlcXVpcmUoJ3BhcnNldXJpJyk7XG52YXIgcGFyc2Vqc29uID0gcmVxdWlyZSgncGFyc2Vqc29uJyk7XG52YXIgcGFyc2VxcyA9IHJlcXVpcmUoJ3BhcnNlcXMnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNvY2tldDtcblxuLyoqXG4gKiBTb2NrZXQgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSB1cmkgb3Igb3B0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gU29ja2V0ICh1cmksIG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNvY2tldCkpIHJldHVybiBuZXcgU29ja2V0KHVyaSwgb3B0cyk7XG5cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgaWYgKHVyaSAmJiAnb2JqZWN0JyA9PT0gdHlwZW9mIHVyaSkge1xuICAgIG9wdHMgPSB1cmk7XG4gICAgdXJpID0gbnVsbDtcbiAgfVxuXG4gIGlmICh1cmkpIHtcbiAgICB1cmkgPSBwYXJzZXVyaSh1cmkpO1xuICAgIG9wdHMuaG9zdG5hbWUgPSB1cmkuaG9zdDtcbiAgICBvcHRzLnNlY3VyZSA9IHVyaS5wcm90b2NvbCA9PT0gJ2h0dHBzJyB8fCB1cmkucHJvdG9jb2wgPT09ICd3c3MnO1xuICAgIG9wdHMucG9ydCA9IHVyaS5wb3J0O1xuICAgIGlmICh1cmkucXVlcnkpIG9wdHMucXVlcnkgPSB1cmkucXVlcnk7XG4gIH0gZWxzZSBpZiAob3B0cy5ob3N0KSB7XG4gICAgb3B0cy5ob3N0bmFtZSA9IHBhcnNldXJpKG9wdHMuaG9zdCkuaG9zdDtcbiAgfVxuXG4gIHRoaXMuc2VjdXJlID0gbnVsbCAhPSBvcHRzLnNlY3VyZSA/IG9wdHMuc2VjdXJlXG4gICAgOiAoZ2xvYmFsLmxvY2F0aW9uICYmICdodHRwczonID09PSBsb2NhdGlvbi5wcm90b2NvbCk7XG5cbiAgaWYgKG9wdHMuaG9zdG5hbWUgJiYgIW9wdHMucG9ydCkge1xuICAgIC8vIGlmIG5vIHBvcnQgaXMgc3BlY2lmaWVkIG1hbnVhbGx5LCB1c2UgdGhlIHByb3RvY29sIGRlZmF1bHRcbiAgICBvcHRzLnBvcnQgPSB0aGlzLnNlY3VyZSA/ICc0NDMnIDogJzgwJztcbiAgfVxuXG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50IHx8IGZhbHNlO1xuICB0aGlzLmhvc3RuYW1lID0gb3B0cy5ob3N0bmFtZSB8fFxuICAgIChnbG9iYWwubG9jYXRpb24gPyBsb2NhdGlvbi5ob3N0bmFtZSA6ICdsb2NhbGhvc3QnKTtcbiAgdGhpcy5wb3J0ID0gb3B0cy5wb3J0IHx8IChnbG9iYWwubG9jYXRpb24gJiYgbG9jYXRpb24ucG9ydFxuICAgICAgPyBsb2NhdGlvbi5wb3J0XG4gICAgICA6ICh0aGlzLnNlY3VyZSA/IDQ0MyA6IDgwKSk7XG4gIHRoaXMucXVlcnkgPSBvcHRzLnF1ZXJ5IHx8IHt9O1xuICBpZiAoJ3N0cmluZycgPT09IHR5cGVvZiB0aGlzLnF1ZXJ5KSB0aGlzLnF1ZXJ5ID0gcGFyc2Vxcy5kZWNvZGUodGhpcy5xdWVyeSk7XG4gIHRoaXMudXBncmFkZSA9IGZhbHNlICE9PSBvcHRzLnVwZ3JhZGU7XG4gIHRoaXMucGF0aCA9IChvcHRzLnBhdGggfHwgJy9lbmdpbmUuaW8nKS5yZXBsYWNlKC9cXC8kLywgJycpICsgJy8nO1xuICB0aGlzLmZvcmNlSlNPTlAgPSAhIW9wdHMuZm9yY2VKU09OUDtcbiAgdGhpcy5qc29ucCA9IGZhbHNlICE9PSBvcHRzLmpzb25wO1xuICB0aGlzLmZvcmNlQmFzZTY0ID0gISFvcHRzLmZvcmNlQmFzZTY0O1xuICB0aGlzLmVuYWJsZXNYRFIgPSAhIW9wdHMuZW5hYmxlc1hEUjtcbiAgdGhpcy50aW1lc3RhbXBQYXJhbSA9IG9wdHMudGltZXN0YW1wUGFyYW0gfHwgJ3QnO1xuICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgdGhpcy50cmFuc3BvcnRzID0gb3B0cy50cmFuc3BvcnRzIHx8IFsncG9sbGluZycsICd3ZWJzb2NrZXQnXTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gIHRoaXMud3JpdGVCdWZmZXIgPSBbXTtcbiAgdGhpcy5wcmV2QnVmZmVyTGVuID0gMDtcbiAgdGhpcy5wb2xpY3lQb3J0ID0gb3B0cy5wb2xpY3lQb3J0IHx8IDg0MztcbiAgdGhpcy5yZW1lbWJlclVwZ3JhZGUgPSBvcHRzLnJlbWVtYmVyVXBncmFkZSB8fCBmYWxzZTtcbiAgdGhpcy5iaW5hcnlUeXBlID0gbnVsbDtcbiAgdGhpcy5vbmx5QmluYXJ5VXBncmFkZXMgPSBvcHRzLm9ubHlCaW5hcnlVcGdyYWRlcztcbiAgdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZSA9IGZhbHNlICE9PSBvcHRzLnBlck1lc3NhZ2VEZWZsYXRlID8gKG9wdHMucGVyTWVzc2FnZURlZmxhdGUgfHwge30pIDogZmFsc2U7XG5cbiAgaWYgKHRydWUgPT09IHRoaXMucGVyTWVzc2FnZURlZmxhdGUpIHRoaXMucGVyTWVzc2FnZURlZmxhdGUgPSB7fTtcbiAgaWYgKHRoaXMucGVyTWVzc2FnZURlZmxhdGUgJiYgbnVsbCA9PSB0aGlzLnBlck1lc3NhZ2VEZWZsYXRlLnRocmVzaG9sZCkge1xuICAgIHRoaXMucGVyTWVzc2FnZURlZmxhdGUudGhyZXNob2xkID0gMTAyNDtcbiAgfVxuXG4gIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLnBmeCA9IG9wdHMucGZ4IHx8IG51bGw7XG4gIHRoaXMua2V5ID0gb3B0cy5rZXkgfHwgbnVsbDtcbiAgdGhpcy5wYXNzcGhyYXNlID0gb3B0cy5wYXNzcGhyYXNlIHx8IG51bGw7XG4gIHRoaXMuY2VydCA9IG9wdHMuY2VydCB8fCBudWxsO1xuICB0aGlzLmNhID0gb3B0cy5jYSB8fCBudWxsO1xuICB0aGlzLmNpcGhlcnMgPSBvcHRzLmNpcGhlcnMgfHwgbnVsbDtcbiAgdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQgPSBvcHRzLnJlamVjdFVuYXV0aG9yaXplZCA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IG9wdHMucmVqZWN0VW5hdXRob3JpemVkO1xuICB0aGlzLmZvcmNlTm9kZSA9ICEhb3B0cy5mb3JjZU5vZGU7XG5cbiAgLy8gb3RoZXIgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgdmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09PSAnb2JqZWN0JyAmJiBnbG9iYWw7XG4gIGlmIChmcmVlR2xvYmFsLmdsb2JhbCA9PT0gZnJlZUdsb2JhbCkge1xuICAgIGlmIChvcHRzLmV4dHJhSGVhZGVycyAmJiBPYmplY3Qua2V5cyhvcHRzLmV4dHJhSGVhZGVycykubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5leHRyYUhlYWRlcnMgPSBvcHRzLmV4dHJhSGVhZGVycztcbiAgICB9XG5cbiAgICBpZiAob3B0cy5sb2NhbEFkZHJlc3MpIHtcbiAgICAgIHRoaXMubG9jYWxBZGRyZXNzID0gb3B0cy5sb2NhbEFkZHJlc3M7XG4gICAgfVxuICB9XG5cbiAgLy8gc2V0IG9uIGhhbmRzaGFrZVxuICB0aGlzLmlkID0gbnVsbDtcbiAgdGhpcy51cGdyYWRlcyA9IG51bGw7XG4gIHRoaXMucGluZ0ludGVydmFsID0gbnVsbDtcbiAgdGhpcy5waW5nVGltZW91dCA9IG51bGw7XG5cbiAgLy8gc2V0IG9uIGhlYXJ0YmVhdFxuICB0aGlzLnBpbmdJbnRlcnZhbFRpbWVyID0gbnVsbDtcbiAgdGhpcy5waW5nVGltZW91dFRpbWVyID0gbnVsbDtcblxuICB0aGlzLm9wZW4oKTtcbn1cblxuU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuXG4vKipcbiAqIE1peCBpbiBgRW1pdHRlcmAuXG4gKi9cblxuRW1pdHRlcihTb2NrZXQucHJvdG90eXBlKTtcblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sOyAvLyB0aGlzIGlzIGFuIGludFxuXG4vKipcbiAqIEV4cG9zZSBkZXBzIGZvciBsZWdhY3kgY29tcGF0aWJpbGl0eVxuICogYW5kIHN0YW5kYWxvbmUgYnJvd3NlciBhY2Nlc3MuXG4gKi9cblxuU29ja2V0LlNvY2tldCA9IFNvY2tldDtcblNvY2tldC5UcmFuc3BvcnQgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpO1xuU29ja2V0LnRyYW5zcG9ydHMgPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMvaW5kZXgnKTtcblNvY2tldC5wYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyB0cmFuc3BvcnQgb2YgdGhlIGdpdmVuIHR5cGUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHRyYW5zcG9ydCBuYW1lXG4gKiBAcmV0dXJuIHtUcmFuc3BvcnR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNyZWF0ZVRyYW5zcG9ydCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlYnVnKCdjcmVhdGluZyB0cmFuc3BvcnQgXCIlc1wiJywgbmFtZSk7XG4gIHZhciBxdWVyeSA9IGNsb25lKHRoaXMucXVlcnkpO1xuXG4gIC8vIGFwcGVuZCBlbmdpbmUuaW8gcHJvdG9jb2wgaWRlbnRpZmllclxuICBxdWVyeS5FSU8gPSBwYXJzZXIucHJvdG9jb2w7XG5cbiAgLy8gdHJhbnNwb3J0IG5hbWVcbiAgcXVlcnkudHJhbnNwb3J0ID0gbmFtZTtcblxuICAvLyBzZXNzaW9uIGlkIGlmIHdlIGFscmVhZHkgaGF2ZSBvbmVcbiAgaWYgKHRoaXMuaWQpIHF1ZXJ5LnNpZCA9IHRoaXMuaWQ7XG5cbiAgdmFyIHRyYW5zcG9ydCA9IG5ldyB0cmFuc3BvcnRzW25hbWVdKHtcbiAgICBhZ2VudDogdGhpcy5hZ2VudCxcbiAgICBob3N0bmFtZTogdGhpcy5ob3N0bmFtZSxcbiAgICBwb3J0OiB0aGlzLnBvcnQsXG4gICAgc2VjdXJlOiB0aGlzLnNlY3VyZSxcbiAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgcXVlcnk6IHF1ZXJ5LFxuICAgIGZvcmNlSlNPTlA6IHRoaXMuZm9yY2VKU09OUCxcbiAgICBqc29ucDogdGhpcy5qc29ucCxcbiAgICBmb3JjZUJhc2U2NDogdGhpcy5mb3JjZUJhc2U2NCxcbiAgICBlbmFibGVzWERSOiB0aGlzLmVuYWJsZXNYRFIsXG4gICAgdGltZXN0YW1wUmVxdWVzdHM6IHRoaXMudGltZXN0YW1wUmVxdWVzdHMsXG4gICAgdGltZXN0YW1wUGFyYW06IHRoaXMudGltZXN0YW1wUGFyYW0sXG4gICAgcG9saWN5UG9ydDogdGhpcy5wb2xpY3lQb3J0LFxuICAgIHNvY2tldDogdGhpcyxcbiAgICBwZng6IHRoaXMucGZ4LFxuICAgIGtleTogdGhpcy5rZXksXG4gICAgcGFzc3BocmFzZTogdGhpcy5wYXNzcGhyYXNlLFxuICAgIGNlcnQ6IHRoaXMuY2VydCxcbiAgICBjYTogdGhpcy5jYSxcbiAgICBjaXBoZXJzOiB0aGlzLmNpcGhlcnMsXG4gICAgcmVqZWN0VW5hdXRob3JpemVkOiB0aGlzLnJlamVjdFVuYXV0aG9yaXplZCxcbiAgICBwZXJNZXNzYWdlRGVmbGF0ZTogdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZSxcbiAgICBleHRyYUhlYWRlcnM6IHRoaXMuZXh0cmFIZWFkZXJzLFxuICAgIGZvcmNlTm9kZTogdGhpcy5mb3JjZU5vZGUsXG4gICAgbG9jYWxBZGRyZXNzOiB0aGlzLmxvY2FsQWRkcmVzc1xuICB9KTtcblxuICByZXR1cm4gdHJhbnNwb3J0O1xufTtcblxuZnVuY3Rpb24gY2xvbmUgKG9iaikge1xuICB2YXIgbyA9IHt9O1xuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgIG9baV0gPSBvYmpbaV07XG4gICAgfVxuICB9XG4gIHJldHVybiBvO1xufVxuXG4vKipcbiAqIEluaXRpYWxpemVzIHRyYW5zcG9ydCB0byB1c2UgYW5kIHN0YXJ0cyBwcm9iZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuU29ja2V0LnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdHJhbnNwb3J0O1xuICBpZiAodGhpcy5yZW1lbWJlclVwZ3JhZGUgJiYgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyAmJiB0aGlzLnRyYW5zcG9ydHMuaW5kZXhPZignd2Vic29ja2V0JykgIT09IC0xKSB7XG4gICAgdHJhbnNwb3J0ID0gJ3dlYnNvY2tldCc7XG4gIH0gZWxzZSBpZiAoMCA9PT0gdGhpcy50cmFuc3BvcnRzLmxlbmd0aCkge1xuICAgIC8vIEVtaXQgZXJyb3Igb24gbmV4dCB0aWNrIHNvIGl0IGNhbiBiZSBsaXN0ZW5lZCB0b1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCAnTm8gdHJhbnNwb3J0cyBhdmFpbGFibGUnKTtcbiAgICB9LCAwKTtcbiAgICByZXR1cm47XG4gIH0gZWxzZSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy50cmFuc3BvcnRzWzBdO1xuICB9XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcblxuICAvLyBSZXRyeSB3aXRoIHRoZSBuZXh0IHRyYW5zcG9ydCBpZiB0aGUgdHJhbnNwb3J0IGlzIGRpc2FibGVkIChqc29ucDogZmFsc2UpXG4gIHRyeSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy5jcmVhdGVUcmFuc3BvcnQodHJhbnNwb3J0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRoaXMudHJhbnNwb3J0cy5zaGlmdCgpO1xuICAgIHRoaXMub3BlbigpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyYW5zcG9ydC5vcGVuKCk7XG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGN1cnJlbnQgdHJhbnNwb3J0LiBEaXNhYmxlcyB0aGUgZXhpc3Rpbmcgb25lIChpZiBhbnkpLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24gKHRyYW5zcG9ydCkge1xuICBkZWJ1Zygnc2V0dGluZyB0cmFuc3BvcnQgJXMnLCB0cmFuc3BvcnQubmFtZSk7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAodGhpcy50cmFuc3BvcnQpIHtcbiAgICBkZWJ1ZygnY2xlYXJpbmcgZXhpc3RpbmcgdHJhbnNwb3J0ICVzJywgdGhpcy50cmFuc3BvcnQubmFtZSk7XG4gICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gIH1cblxuICAvLyBzZXQgdXAgdHJhbnNwb3J0XG4gIHRoaXMudHJhbnNwb3J0ID0gdHJhbnNwb3J0O1xuXG4gIC8vIHNldCB1cCB0cmFuc3BvcnQgbGlzdGVuZXJzXG4gIHRyYW5zcG9ydFxuICAub24oJ2RyYWluJywgZnVuY3Rpb24gKCkge1xuICAgIHNlbGYub25EcmFpbigpO1xuICB9KVxuICAub24oJ3BhY2tldCcsIGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgICBzZWxmLm9uUGFja2V0KHBhY2tldCk7XG4gIH0pXG4gIC5vbignZXJyb3InLCBmdW5jdGlvbiAoZSkge1xuICAgIHNlbGYub25FcnJvcihlKTtcbiAgfSlcbiAgLm9uKCdjbG9zZScsIGZ1bmN0aW9uICgpIHtcbiAgICBzZWxmLm9uQ2xvc2UoJ3RyYW5zcG9ydCBjbG9zZScpO1xuICB9KTtcbn07XG5cbi8qKlxuICogUHJvYmVzIGEgdHJhbnNwb3J0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0cmFuc3BvcnQgbmFtZVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5wcm9iZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlYnVnKCdwcm9iaW5nIHRyYW5zcG9ydCBcIiVzXCInLCBuYW1lKTtcbiAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuY3JlYXRlVHJhbnNwb3J0KG5hbWUsIHsgcHJvYmU6IDEgfSk7XG4gIHZhciBmYWlsZWQgPSBmYWxzZTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIFNvY2tldC5wcmlvcldlYnNvY2tldFN1Y2Nlc3MgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBvblRyYW5zcG9ydE9wZW4gKCkge1xuICAgIGlmIChzZWxmLm9ubHlCaW5hcnlVcGdyYWRlcykge1xuICAgICAgdmFyIHVwZ3JhZGVMb3Nlc0JpbmFyeSA9ICF0aGlzLnN1cHBvcnRzQmluYXJ5ICYmIHNlbGYudHJhbnNwb3J0LnN1cHBvcnRzQmluYXJ5O1xuICAgICAgZmFpbGVkID0gZmFpbGVkIHx8IHVwZ3JhZGVMb3Nlc0JpbmFyeTtcbiAgICB9XG4gICAgaWYgKGZhaWxlZCkgcmV0dXJuO1xuXG4gICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgb3BlbmVkJywgbmFtZSk7XG4gICAgdHJhbnNwb3J0LnNlbmQoW3sgdHlwZTogJ3BpbmcnLCBkYXRhOiAncHJvYmUnIH1dKTtcbiAgICB0cmFuc3BvcnQub25jZSgncGFja2V0JywgZnVuY3Rpb24gKG1zZykge1xuICAgICAgaWYgKGZhaWxlZCkgcmV0dXJuO1xuICAgICAgaWYgKCdwb25nJyA9PT0gbXNnLnR5cGUgJiYgJ3Byb2JlJyA9PT0gbXNnLmRhdGEpIHtcbiAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgcG9uZycsIG5hbWUpO1xuICAgICAgICBzZWxmLnVwZ3JhZGluZyA9IHRydWU7XG4gICAgICAgIHNlbGYuZW1pdCgndXBncmFkaW5nJywgdHJhbnNwb3J0KTtcbiAgICAgICAgaWYgKCF0cmFuc3BvcnQpIHJldHVybjtcbiAgICAgICAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9ICd3ZWJzb2NrZXQnID09PSB0cmFuc3BvcnQubmFtZTtcblxuICAgICAgICBkZWJ1ZygncGF1c2luZyBjdXJyZW50IHRyYW5zcG9ydCBcIiVzXCInLCBzZWxmLnRyYW5zcG9ydC5uYW1lKTtcbiAgICAgICAgc2VsZi50cmFuc3BvcnQucGF1c2UoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmIChmYWlsZWQpIHJldHVybjtcbiAgICAgICAgICBpZiAoJ2Nsb3NlZCcgPT09IHNlbGYucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICAgIGRlYnVnKCdjaGFuZ2luZyB0cmFuc3BvcnQgYW5kIHNlbmRpbmcgdXBncmFkZSBwYWNrZXQnKTtcblxuICAgICAgICAgIGNsZWFudXAoKTtcblxuICAgICAgICAgIHNlbGYuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG4gICAgICAgICAgdHJhbnNwb3J0LnNlbmQoW3sgdHlwZTogJ3VwZ3JhZGUnIH1dKTtcbiAgICAgICAgICBzZWxmLmVtaXQoJ3VwZ3JhZGUnLCB0cmFuc3BvcnQpO1xuICAgICAgICAgIHRyYW5zcG9ydCA9IG51bGw7XG4gICAgICAgICAgc2VsZi51cGdyYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLmZsdXNoKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgZmFpbGVkJywgbmFtZSk7XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3Byb2JlIGVycm9yJyk7XG4gICAgICAgIGVyci50cmFuc3BvcnQgPSB0cmFuc3BvcnQubmFtZTtcbiAgICAgICAgc2VsZi5lbWl0KCd1cGdyYWRlRXJyb3InLCBlcnIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZnJlZXplVHJhbnNwb3J0ICgpIHtcbiAgICBpZiAoZmFpbGVkKSByZXR1cm47XG5cbiAgICAvLyBBbnkgY2FsbGJhY2sgY2FsbGVkIGJ5IHRyYW5zcG9ydCBzaG91bGQgYmUgaWdub3JlZCBzaW5jZSBub3dcbiAgICBmYWlsZWQgPSB0cnVlO1xuXG4gICAgY2xlYW51cCgpO1xuXG4gICAgdHJhbnNwb3J0LmNsb3NlKCk7XG4gICAgdHJhbnNwb3J0ID0gbnVsbDtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhbnkgZXJyb3IgdGhhdCBoYXBwZW5zIHdoaWxlIHByb2JpbmdcbiAgZnVuY3Rpb24gb25lcnJvciAoZXJyKSB7XG4gICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdwcm9iZSBlcnJvcjogJyArIGVycik7XG4gICAgZXJyb3IudHJhbnNwb3J0ID0gdHJhbnNwb3J0Lm5hbWU7XG5cbiAgICBmcmVlemVUcmFuc3BvcnQoKTtcblxuICAgIGRlYnVnKCdwcm9iZSB0cmFuc3BvcnQgXCIlc1wiIGZhaWxlZCBiZWNhdXNlIG9mIGVycm9yOiAlcycsIG5hbWUsIGVycik7XG5cbiAgICBzZWxmLmVtaXQoJ3VwZ3JhZGVFcnJvcicsIGVycm9yKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVHJhbnNwb3J0Q2xvc2UgKCkge1xuICAgIG9uZXJyb3IoJ3RyYW5zcG9ydCBjbG9zZWQnKTtcbiAgfVxuXG4gIC8vIFdoZW4gdGhlIHNvY2tldCBpcyBjbG9zZWQgd2hpbGUgd2UncmUgcHJvYmluZ1xuICBmdW5jdGlvbiBvbmNsb3NlICgpIHtcbiAgICBvbmVycm9yKCdzb2NrZXQgY2xvc2VkJyk7XG4gIH1cblxuICAvLyBXaGVuIHRoZSBzb2NrZXQgaXMgdXBncmFkZWQgd2hpbGUgd2UncmUgcHJvYmluZ1xuICBmdW5jdGlvbiBvbnVwZ3JhZGUgKHRvKSB7XG4gICAgaWYgKHRyYW5zcG9ydCAmJiB0by5uYW1lICE9PSB0cmFuc3BvcnQubmFtZSkge1xuICAgICAgZGVidWcoJ1wiJXNcIiB3b3JrcyAtIGFib3J0aW5nIFwiJXNcIicsIHRvLm5hbWUsIHRyYW5zcG9ydC5uYW1lKTtcbiAgICAgIGZyZWV6ZVRyYW5zcG9ydCgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIG9uIHRoZSB0cmFuc3BvcnQgYW5kIG9uIHNlbGZcbiAgZnVuY3Rpb24gY2xlYW51cCAoKSB7XG4gICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdvcGVuJywgb25UcmFuc3BvcnRPcGVuKTtcbiAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uVHJhbnNwb3J0Q2xvc2UpO1xuICAgIHNlbGYucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkaW5nJywgb251cGdyYWRlKTtcbiAgfVxuXG4gIHRyYW5zcG9ydC5vbmNlKCdvcGVuJywgb25UcmFuc3BvcnRPcGVuKTtcbiAgdHJhbnNwb3J0Lm9uY2UoJ2Vycm9yJywgb25lcnJvcik7XG4gIHRyYW5zcG9ydC5vbmNlKCdjbG9zZScsIG9uVHJhbnNwb3J0Q2xvc2UpO1xuXG4gIHRoaXMub25jZSgnY2xvc2UnLCBvbmNsb3NlKTtcbiAgdGhpcy5vbmNlKCd1cGdyYWRpbmcnLCBvbnVwZ3JhZGUpO1xuXG4gIHRyYW5zcG9ydC5vcGVuKCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aGVuIGNvbm5lY3Rpb24gaXMgZGVlbWVkIG9wZW4uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgZGVidWcoJ3NvY2tldCBvcGVuJyk7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuJztcbiAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9ICd3ZWJzb2NrZXQnID09PSB0aGlzLnRyYW5zcG9ydC5uYW1lO1xuICB0aGlzLmVtaXQoJ29wZW4nKTtcbiAgdGhpcy5mbHVzaCgpO1xuXG4gIC8vIHdlIGNoZWNrIGZvciBgcmVhZHlTdGF0ZWAgaW4gY2FzZSBhbiBgb3BlbmBcbiAgLy8gbGlzdGVuZXIgYWxyZWFkeSBjbG9zZWQgdGhlIHNvY2tldFxuICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgJiYgdGhpcy51cGdyYWRlICYmIHRoaXMudHJhbnNwb3J0LnBhdXNlKSB7XG4gICAgZGVidWcoJ3N0YXJ0aW5nIHVwZ3JhZGUgcHJvYmVzJyk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLnVwZ3JhZGVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdGhpcy5wcm9iZSh0aGlzLnVwZ3JhZGVzW2ldKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogSGFuZGxlcyBhIHBhY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uUGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICBpZiAoJ29wZW5pbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgfHxcbiAgICAgICdjbG9zaW5nJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgZGVidWcoJ3NvY2tldCByZWNlaXZlOiB0eXBlIFwiJXNcIiwgZGF0YSBcIiVzXCInLCBwYWNrZXQudHlwZSwgcGFja2V0LmRhdGEpO1xuXG4gICAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xuXG4gICAgLy8gU29ja2V0IGlzIGxpdmUgLSBhbnkgcGFja2V0IGNvdW50c1xuICAgIHRoaXMuZW1pdCgnaGVhcnRiZWF0Jyk7XG5cbiAgICBzd2l0Y2ggKHBhY2tldC50eXBlKSB7XG4gICAgICBjYXNlICdvcGVuJzpcbiAgICAgICAgdGhpcy5vbkhhbmRzaGFrZShwYXJzZWpzb24ocGFja2V0LmRhdGEpKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3BvbmcnOlxuICAgICAgICB0aGlzLnNldFBpbmcoKTtcbiAgICAgICAgdGhpcy5lbWl0KCdwb25nJyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3NlcnZlciBlcnJvcicpO1xuICAgICAgICBlcnIuY29kZSA9IHBhY2tldC5kYXRhO1xuICAgICAgICB0aGlzLm9uRXJyb3IoZXJyKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ21lc3NhZ2UnOlxuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBwYWNrZXQuZGF0YSk7XG4gICAgICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIHBhY2tldC5kYXRhKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGRlYnVnKCdwYWNrZXQgcmVjZWl2ZWQgd2l0aCBzb2NrZXQgcmVhZHlTdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGhhbmRzaGFrZSBjb21wbGV0aW9uLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBoYW5kc2hha2Ugb2JqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uSGFuZHNoYWtlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5lbWl0KCdoYW5kc2hha2UnLCBkYXRhKTtcbiAgdGhpcy5pZCA9IGRhdGEuc2lkO1xuICB0aGlzLnRyYW5zcG9ydC5xdWVyeS5zaWQgPSBkYXRhLnNpZDtcbiAgdGhpcy51cGdyYWRlcyA9IHRoaXMuZmlsdGVyVXBncmFkZXMoZGF0YS51cGdyYWRlcyk7XG4gIHRoaXMucGluZ0ludGVydmFsID0gZGF0YS5waW5nSW50ZXJ2YWw7XG4gIHRoaXMucGluZ1RpbWVvdXQgPSBkYXRhLnBpbmdUaW1lb3V0O1xuICB0aGlzLm9uT3BlbigpO1xuICAvLyBJbiBjYXNlIG9wZW4gaGFuZGxlciBjbG9zZXMgc29ja2V0XG4gIGlmICgnY2xvc2VkJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSByZXR1cm47XG4gIHRoaXMuc2V0UGluZygpO1xuXG4gIC8vIFByb2xvbmcgbGl2ZW5lc3Mgb2Ygc29ja2V0IG9uIGhlYXJ0YmVhdFxuICB0aGlzLnJlbW92ZUxpc3RlbmVyKCdoZWFydGJlYXQnLCB0aGlzLm9uSGVhcnRiZWF0KTtcbiAgdGhpcy5vbignaGVhcnRiZWF0JywgdGhpcy5vbkhlYXJ0YmVhdCk7XG59O1xuXG4vKipcbiAqIFJlc2V0cyBwaW5nIHRpbWVvdXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkhlYXJ0YmVhdCA9IGZ1bmN0aW9uICh0aW1lb3V0KSB7XG4gIGNsZWFyVGltZW91dCh0aGlzLnBpbmdUaW1lb3V0VGltZXIpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHNlbGYucGluZ1RpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGlmICgnY2xvc2VkJyA9PT0gc2VsZi5yZWFkeVN0YXRlKSByZXR1cm47XG4gICAgc2VsZi5vbkNsb3NlKCdwaW5nIHRpbWVvdXQnKTtcbiAgfSwgdGltZW91dCB8fCAoc2VsZi5waW5nSW50ZXJ2YWwgKyBzZWxmLnBpbmdUaW1lb3V0KSk7XG59O1xuXG4vKipcbiAqIFBpbmdzIHNlcnZlciBldmVyeSBgdGhpcy5waW5nSW50ZXJ2YWxgIGFuZCBleHBlY3RzIHJlc3BvbnNlXG4gKiB3aXRoaW4gYHRoaXMucGluZ1RpbWVvdXRgIG9yIGNsb3NlcyBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2V0UGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBjbGVhclRpbWVvdXQoc2VsZi5waW5nSW50ZXJ2YWxUaW1lcik7XG4gIHNlbGYucGluZ0ludGVydmFsVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JpdGluZyBwaW5nIHBhY2tldCAtIGV4cGVjdGluZyBwb25nIHdpdGhpbiAlc21zJywgc2VsZi5waW5nVGltZW91dCk7XG4gICAgc2VsZi5waW5nKCk7XG4gICAgc2VsZi5vbkhlYXJ0YmVhdChzZWxmLnBpbmdUaW1lb3V0KTtcbiAgfSwgc2VsZi5waW5nSW50ZXJ2YWwpO1xufTtcblxuLyoqXG4qIFNlbmRzIGEgcGluZyBwYWNrZXQuXG4qXG4qIEBhcGkgcHJpdmF0ZVxuKi9cblxuU29ja2V0LnByb3RvdHlwZS5waW5nID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuc2VuZFBhY2tldCgncGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBzZWxmLmVtaXQoJ3BpbmcnKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIENhbGxlZCBvbiBgZHJhaW5gIGV2ZW50XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkRyYWluID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLndyaXRlQnVmZmVyLnNwbGljZSgwLCB0aGlzLnByZXZCdWZmZXJMZW4pO1xuXG4gIC8vIHNldHRpbmcgcHJldkJ1ZmZlckxlbiA9IDAgaXMgdmVyeSBpbXBvcnRhbnRcbiAgLy8gZm9yIGV4YW1wbGUsIHdoZW4gdXBncmFkaW5nLCB1cGdyYWRlIHBhY2tldCBpcyBzZW50IG92ZXIsXG4gIC8vIGFuZCBhIG5vbnplcm8gcHJldkJ1ZmZlckxlbiBjb3VsZCBjYXVzZSBwcm9ibGVtcyBvbiBgZHJhaW5gXG4gIHRoaXMucHJldkJ1ZmZlckxlbiA9IDA7XG5cbiAgaWYgKDAgPT09IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgdGhpcy5lbWl0KCdkcmFpbicpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuZmx1c2goKTtcbiAgfVxufTtcblxuLyoqXG4gKiBGbHVzaCB3cml0ZSBidWZmZXJzLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnY2xvc2VkJyAhPT0gdGhpcy5yZWFkeVN0YXRlICYmIHRoaXMudHJhbnNwb3J0LndyaXRhYmxlICYmXG4gICAgIXRoaXMudXBncmFkaW5nICYmIHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgZGVidWcoJ2ZsdXNoaW5nICVkIHBhY2tldHMgaW4gc29ja2V0JywgdGhpcy53cml0ZUJ1ZmZlci5sZW5ndGgpO1xuICAgIHRoaXMudHJhbnNwb3J0LnNlbmQodGhpcy53cml0ZUJ1ZmZlcik7XG4gICAgLy8ga2VlcCB0cmFjayBvZiBjdXJyZW50IGxlbmd0aCBvZiB3cml0ZUJ1ZmZlclxuICAgIC8vIHNwbGljZSB3cml0ZUJ1ZmZlciBhbmQgY2FsbGJhY2tCdWZmZXIgb24gYGRyYWluYFxuICAgIHRoaXMucHJldkJ1ZmZlckxlbiA9IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoO1xuICAgIHRoaXMuZW1pdCgnZmx1c2gnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZW5kcyBhIG1lc3NhZ2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQHJldHVybiB7U29ja2V0fSBmb3IgY2hhaW5pbmcuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUud3JpdGUgPVxuU29ja2V0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKG1zZywgb3B0aW9ucywgZm4pIHtcbiAgdGhpcy5zZW5kUGFja2V0KCdtZXNzYWdlJywgbXNnLCBvcHRpb25zLCBmbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZW5kcyBhIHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFja2V0IHR5cGUuXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgZnVuY3Rpb24uXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNlbmRQYWNrZXQgPSBmdW5jdGlvbiAodHlwZSwgZGF0YSwgb3B0aW9ucywgZm4pIHtcbiAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBkYXRhKSB7XG4gICAgZm4gPSBkYXRhO1xuICAgIGRhdGEgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIG9wdGlvbnMpIHtcbiAgICBmbiA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9IG51bGw7XG4gIH1cblxuICBpZiAoJ2Nsb3NpbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ2Nsb3NlZCcgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBvcHRpb25zLmNvbXByZXNzID0gZmFsc2UgIT09IG9wdGlvbnMuY29tcHJlc3M7XG5cbiAgdmFyIHBhY2tldCA9IHtcbiAgICB0eXBlOiB0eXBlLFxuICAgIGRhdGE6IGRhdGEsXG4gICAgb3B0aW9uczogb3B0aW9uc1xuICB9O1xuICB0aGlzLmVtaXQoJ3BhY2tldENyZWF0ZScsIHBhY2tldCk7XG4gIHRoaXMud3JpdGVCdWZmZXIucHVzaChwYWNrZXQpO1xuICBpZiAoZm4pIHRoaXMub25jZSgnZmx1c2gnLCBmbik7XG4gIHRoaXMuZmx1c2goKTtcbn07XG5cbi8qKlxuICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zaW5nJztcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIGlmICh0aGlzLndyaXRlQnVmZmVyLmxlbmd0aCkge1xuICAgICAgdGhpcy5vbmNlKCdkcmFpbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMudXBncmFkaW5nKSB7XG4gICAgICAgICAgd2FpdEZvclVwZ3JhZGUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjbG9zZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudXBncmFkaW5nKSB7XG4gICAgICB3YWl0Rm9yVXBncmFkZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNsb3NlICgpIHtcbiAgICBzZWxmLm9uQ2xvc2UoJ2ZvcmNlZCBjbG9zZScpO1xuICAgIGRlYnVnKCdzb2NrZXQgY2xvc2luZyAtIHRlbGxpbmcgdHJhbnNwb3J0IHRvIGNsb3NlJyk7XG4gICAgc2VsZi50cmFuc3BvcnQuY2xvc2UoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsZWFudXBBbmRDbG9zZSAoKSB7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkZScsIGNsZWFudXBBbmRDbG9zZSk7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkZUVycm9yJywgY2xlYW51cEFuZENsb3NlKTtcbiAgICBjbG9zZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gd2FpdEZvclVwZ3JhZGUgKCkge1xuICAgIC8vIHdhaXQgZm9yIHVwZ3JhZGUgdG8gZmluaXNoIHNpbmNlIHdlIGNhbid0IHNlbmQgcGFja2V0cyB3aGlsZSBwYXVzaW5nIGEgdHJhbnNwb3J0XG4gICAgc2VsZi5vbmNlKCd1cGdyYWRlJywgY2xlYW51cEFuZENsb3NlKTtcbiAgICBzZWxmLm9uY2UoJ3VwZ3JhZGVFcnJvcicsIGNsZWFudXBBbmRDbG9zZSk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IGVycm9yXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKGVycikge1xuICBkZWJ1Zygnc29ja2V0IGVycm9yICVqJywgZXJyKTtcbiAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5vbkNsb3NlKCd0cmFuc3BvcnQgZXJyb3InLCBlcnIpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiB0cmFuc3BvcnQgY2xvc2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbiwgZGVzYykge1xuICBpZiAoJ29wZW5pbmcnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ2Nsb3NpbmcnID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICBkZWJ1Zygnc29ja2V0IGNsb3NlIHdpdGggcmVhc29uOiBcIiVzXCInLCByZWFzb24pO1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIC8vIGNsZWFyIHRpbWVyc1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnBpbmdJbnRlcnZhbFRpbWVyKTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nVGltZW91dFRpbWVyKTtcblxuICAgIC8vIHN0b3AgZXZlbnQgZnJvbSBmaXJpbmcgYWdhaW4gZm9yIHRyYW5zcG9ydFxuICAgIHRoaXMudHJhbnNwb3J0LnJlbW92ZUFsbExpc3RlbmVycygnY2xvc2UnKTtcblxuICAgIC8vIGVuc3VyZSB0cmFuc3BvcnQgd29uJ3Qgc3RheSBvcGVuXG4gICAgdGhpcy50cmFuc3BvcnQuY2xvc2UoKTtcblxuICAgIC8vIGlnbm9yZSBmdXJ0aGVyIHRyYW5zcG9ydCBjb21tdW5pY2F0aW9uXG4gICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG5cbiAgICAvLyBzZXQgcmVhZHkgc3RhdGVcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcblxuICAgIC8vIGNsZWFyIHNlc3Npb24gaWRcbiAgICB0aGlzLmlkID0gbnVsbDtcblxuICAgIC8vIGVtaXQgY2xvc2UgZXZlbnRcbiAgICB0aGlzLmVtaXQoJ2Nsb3NlJywgcmVhc29uLCBkZXNjKTtcblxuICAgIC8vIGNsZWFuIGJ1ZmZlcnMgYWZ0ZXIsIHNvIHVzZXJzIGNhbiBzdGlsbFxuICAgIC8vIGdyYWIgdGhlIGJ1ZmZlcnMgb24gYGNsb3NlYCBldmVudFxuICAgIHNlbGYud3JpdGVCdWZmZXIgPSBbXTtcbiAgICBzZWxmLnByZXZCdWZmZXJMZW4gPSAwO1xuICB9XG59O1xuXG4vKipcbiAqIEZpbHRlcnMgdXBncmFkZXMsIHJldHVybmluZyBvbmx5IHRob3NlIG1hdGNoaW5nIGNsaWVudCB0cmFuc3BvcnRzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHNlcnZlciB1cGdyYWRlc1xuICogQGFwaSBwcml2YXRlXG4gKlxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZmlsdGVyVXBncmFkZXMgPSBmdW5jdGlvbiAodXBncmFkZXMpIHtcbiAgdmFyIGZpbHRlcmVkVXBncmFkZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGogPSB1cGdyYWRlcy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcbiAgICBpZiAofmluZGV4KHRoaXMudHJhbnNwb3J0cywgdXBncmFkZXNbaV0pKSBmaWx0ZXJlZFVwZ3JhZGVzLnB1c2godXBncmFkZXNbaV0pO1xuICB9XG4gIHJldHVybiBmaWx0ZXJlZFVwZ3JhZGVzO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0112\n")},"0352":function(module,exports,__webpack_require__){eval('// https://crossfilter.github.io/crossfilter/ v1.5.4 Copyright 2020 Mike Bostock\n!function(r,e){ true?module.exports=e():undefined}(this,(function(){"use strict";let r=o,e=o,n=o,t=f,u=i;function o(r){for(var e=new Array(r),n=-1;++n<r;)e[n]=0;return e}function f(r,e){for(var n=r.length;n<e;)r[n++]=0;return r}function i(r,e){if(e>32)throw new Error("invalid array width!");return r}function a(e){this.length=e,this.subarrays=1,this.width=8,this.masks={0:0},this[0]=r(e)}"undefined"!=typeof Uint8Array&&(r=function(r){return new Uint8Array(r)},e=function(r){return new Uint16Array(r)},n=function(r){return new Uint32Array(r)},t=function(r,e){if(r.length>=e)return r;var n=new r.constructor(e);return n.set(r),n},u=function(r,t){var u;switch(t){case 16:u=e(r.length);break;case 32:u=n(r.length);break;default:throw new Error("invalid array width!")}return u.set(r),u}),a.prototype.lengthen=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)this[e]=t(this[e],r);this.length=r},a.prototype.add=function(){var e,n,t,o,f;for(o=0,f=this.subarrays;o<f;++o)if(t=(~(e=this.masks[o])&e+1)>>>0,!((n=this.width-32*o)>=32)||t)return n<32&&t&1<<n&&(this[o]=u(this[o],n<<=1),this.width=32*o+n),this.masks[o]|=t,{offset:o,one:t};return this[this.subarrays]=r(this.length),this.masks[this.subarrays]=1,this.width+=8,{offset:this.subarrays++,one:1}},a.prototype.copy=function(r,e){var n,t;for(n=0,t=this.subarrays;n<t;++n)this[n][r]=this[n][e]},a.prototype.truncate=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)for(var t=this.length-1;t>=r;t--)this[e][t]=0;this.length=r},a.prototype.zero=function(r){var e,n;for(e=0,n=this.subarrays;e<n;++e)if(this[e][r])return!1;return!0},a.prototype.zeroExcept=function(r,e,n){var t,u;for(t=0,u=this.subarrays;t<u;++t)if(t===e?this[t][r]&n:this[t][r])return!1;return!0},a.prototype.zeroExceptMask=function(r,e){var n,t;for(n=0,t=this.subarrays;n<t;++n)if(this[n][r]&e[n])return!1;return!0},a.prototype.only=function(r,e,n){var t,u;for(t=0,u=this.subarrays;t<u;++t)if(this[t][r]!=(t===e?n:0))return!1;return!0},a.prototype.onlyExcept=function(r,e,n,t,u){var o,f,i;for(f=0,i=this.subarrays;f<i;++f)if(o=this[f][r],f===e&&(o=(o&n)>>>0),o!=(f===t?u:0))return!1;return!0};var l={array8:o,array16:o,array32:o,arrayLengthen:f,arrayWiden:i,bitarray:a};var s={filterExact:(r,e)=>(function(n){var t=n.length;return[r.left(n,e,0,t),r.right(n,e,0,t)]}),filterRange:(r,e)=>{var n=e[0],t=e[1];return function(e){var u=e.length;return[r.left(e,n,0,u),r.left(e,t,0,u)]}},filterAll:r=>[0,r.length]},c=r=>r,h=()=>null,v=()=>0;function p(r){function e(r,e,t){for(var u=t-e,o=1+(u>>>1);--o>0;)n(r,o,u,e);return r}function n(e,n,t,u){for(var o,f=e[--u+n],i=r(f);(o=n<<1)<=t&&(o<t&&r(e[u+o])>r(e[u+o+1])&&o++,!(i<=r(e[u+o])));)e[u+n]=e[u+o],n=o;e[u+n]=f}return e.sort=function(r,e,t){for(var u,o=t-e;--o>0;)u=r[e],r[e]=r[e+o],r[e+o]=u,n(r,1,o,e);return r},e}const d=p(c);function g(r){var e=d.by(r);return function(n,t,u,o){var f,i,a,l=new Array(o=Math.min(u-t,o));for(i=0;i<o;++i)l[i]=n[t++];if(e(l,0,o),t<u){f=r(l[0]);do{r(a=n[t])>f&&(l[0]=a,f=r(e(l,0,o)[0]))}while(++t<u)}return l}}d.by=p;const y=g(c);function x(r){function e(e,n,t,u){for(;t<u;){var o=t+u>>>1;n<r(e[o])?u=o:t=o+1}return t}return e.right=e,e.left=function(e,n,t,u){for(;t<u;){var o=t+u>>>1;r(e[o])<n?t=o+1:u=o}return t},e}y.by=g;const b=x(c);b.by=x;var m=(r,e,n)=>{for(var t=0,u=e.length,o=n?JSON.parse(JSON.stringify(r)):new Array(u);t<u;++t)o[t]=r[e[t]];return o};var E={reduceIncrement:r=>r+1,reduceDecrement:r=>r-1,reduceAdd:r=>(function(e,n){return e+ +r(n)}),reduceSubtract:r=>(function(e,n){return e-r(n)})};const w=(r,e)=>{const n=r[e];return"function"==typeof n?n.call(r):n},A=/\\[([\\w\\d]+)\\]/g;var z=(r,e)=>(function(r,e,n,t,u){for(u in t=(n=n.split(".")).splice(-1,1),n)e=e[n[u]]=e[n[u]]||{};return r(e,t)})(w,r,e.replace(A,".$1")),k=-1;function O(){var r,e={add:a,remove:function(e){for(var o=new Array(t),i=[],a="function"==typeof e,l=0,s=0;l<t;++l)c=l,(a?e(n[c],c):r.zero(c))?(i.push(l),o[l]=k):o[l]=s++;var c;u.forEach((function(r){r(-1,-1,[],i,!0)})),f.forEach((function(r){r(o)}));for(var h=0,v=0;h<t;++h)o[h]!==k&&(h!==v&&(r.copy(v,h),n[v]=n[h]),++v);n.length=t=v,r.truncate(v),g("dataRemoved")},dimension:function(e,i){if("string"==typeof e){var a=e;e=function(r){return z(r,a)}}var p,x,w,A,O,F,N,R,U,D,I,L,W,J,j={filter:function(r){return null==r?er():Array.isArray(r)?rr(r):"function"==typeof r?nr(r):_(r)},filterExact:_,filterRange:rr,filterFunction:nr,filterAll:er,currentFilter:function(){return L},hasCurrentFilter:function(){return W},top:function(e,t){var u,o=[],f=P,a=0;t&&t>0&&(a=t);for(;--f>=K&&e>0;)r.zero(u=F[f])&&(a>0?--a:(o.push(n[u]),--e));if(i)for(f=0;f<$.length&&e>0;f++)r.zero(u=$[f])&&(a>0?--a:(o.push(n[u]),--e));return o},bottom:function(e,t){var u,o,f=[],a=0;t&&t>0&&(a=t);if(i)for(u=0;u<$.length&&e>0;u++)r.zero(o=$[u])&&(a>0?--a:(f.push(n[o]),--e));u=K;for(;u<P&&e>0;)r.zero(o=F[u])&&(a>0?--a:(f.push(n[o]),--e)),u++;return f},group:ur,groupAll:function(){var r=ur(h),e=r.all;return delete r.all,delete r.top,delete r.order,delete r.orderNatural,delete r.size,r.value=function(){return e()[0].value},r},dispose:or,remove:or,accessor:e,id:function(){return A}},$=[],q=function(r){return S(r).sort((function(r,e){var n=N[r],t=N[e];return n<t?-1:n>t?1:r-e}))},B=s.filterAll,G=[],H=[],K=0,P=0,Q=0;o.unshift(V),o.push(X),f.push(Y);var T=r.add();function V(n,u,o){var f,a;if(i){Q=0,G=0,J=[];for(var s=0;s<n.length;s++)for(G=0,J=e(n[s]);G<J.length;G++)Q++;N=[],f=S(n.length),a=M(Q,1);for(var c=S(Q),h=0,v=0;v<n.length;v++)if((J=e(n[v])).length)for(f[v]=J.length,G=0;G<J.length;G++)N.push(J[G]),c[h]=v,h++;else f[v]=0,$.push(v+u);var d=q(Q);N=m(N,d),R=m(c,d)}else N=n.map(e),R=q(o),N=m(N,R);var g,y,x,b=B(N),E=b[0],A=b[1];if(i)if(o=Q,I)for(g=0;g<o;++g)I(N[g],g)||(0==--f[R[g]]&&(r[w][R[g]+u]|=p),a[g]=1);else{for(y=0;y<E;++y)0==--f[R[y]]&&(r[w][R[y]+u]|=p),a[y]=1;for(x=A;x<o;++x)0==--f[R[x]]&&(r[w][R[x]+u]|=p),a[x]=1}else if(I)for(g=0;g<o;++g)I(N[g],g)||(r[w][R[g]+u]|=p);else{for(y=0;y<E;++y)r[w][R[y]+u]|=p;for(x=A;x<o;++x)r[w][R[x]+u]|=p}if(!u)return O=N,F=R,U=f,D=a,K=E,void(P=A);var z,k=O,C=F,L=D,W=0;if(s=0,i&&(z=u,u=k.length,o=Q),O=new Array(i?u+o:t),F=i?new Array(u+o):M(t,t),i&&(D=M(u+o,1)),i){var j=U.length;U=l.arrayLengthen(U,t);for(var G=0;G+j<t;G++)U[G+j]=f[G]}for(var H=0;s<u&&W<o;++H)k[s]<N[W]?(O[H]=k[s],i&&(D[H]=L[s]),F[H]=C[s++]):(O[H]=N[W],i&&(D[H]=a[W]),F[H]=R[W++]+(i?z:u));for(;s<u;++s,++H)O[H]=k[s],i&&(D[H]=L[s]),F[H]=C[s];for(;W<o;++W,++H)O[H]=N[W],i&&(D[H]=a[W]),F[H]=R[W]+(i?z:u);b=B(O),K=b[0],P=b[1]}function X(r,e,n){G.forEach((function(r){r(N,R,e,n)})),N=R=null}function Y(r){if(i){for(var e=0,n=0;e<$.length;e++)r[$[e]]!==k&&($[n]=r[$[e]],n++);for($.length=n,e=0,n=0;e<t;e++)r[e]!==k&&(n!==e&&(U[n]=U[e]),n++);U=U.slice(0,n)}for(var u,o=O.length,f=0,a=0;f<o;++f)r[u=F[f]]!==k&&(f!==a&&(O[a]=O[f]),F[a]=r[u],i&&(D[a]=D[f]),++a);for(O.length=a,i&&(D=D.slice(0,a));a<o;)F[a++]=0;var l=B(O);K=l[0],P=l[1]}function Z(e){var n=e[0],t=e[1];if(I)return I=null,tr((function(r,e){return n<=e&&e<t}),0===e[0]&&e[1]===O.length),K=n,P=t,j;var o,f,a,l=[],c=[],h=[],v=[];if(n<K)for(o=n,f=Math.min(K,t);o<f;++o)l.push(F[o]),h.push(o);else if(n>K)for(o=K,f=Math.min(n,P);o<f;++o)c.push(F[o]),v.push(o);if(t>P)for(o=Math.max(n,P),f=t;o<f;++o)l.push(F[o]),h.push(o);else if(t<P)for(o=Math.max(K,t),f=P;o<f;++o)c.push(F[o]),v.push(o);if(i){var d=[],y=[];for(o=0;o<l.length;o++)U[l[o]]++,D[h[o]]=0,1===U[l[o]]&&(r[w][l[o]]^=p,d.push(l[o]));for(o=0;o<c.length;o++)U[c[o]]--,D[v[o]]=1,0===U[c[o]]&&(r[w][c[o]]^=p,y.push(c[o]));if(l=d,c=y,B===s.filterAll)for(o=0;o<$.length;o++)r[w][a=$[o]]&p&&(r[w][a]^=p,l.push(a));else for(o=0;o<$.length;o++)r[w][a=$[o]]&p||(r[w][a]^=p,c.push(a))}else{for(o=0;o<l.length;o++)r[w][l[o]]^=p;for(o=0;o<c.length;o++)r[w][c[o]]^=p}return K=n,P=t,u.forEach((function(r){r(p,w,l,c)})),g("filtered"),j}function _(r){return L=r,W=!0,Z((B=s.filterExact(b,r))(O))}function rr(r){return L=r,W=!0,Z((B=s.filterRange(b,r))(O))}function er(){return L=void 0,W=!1,Z((B=s.filterAll)(O))}function nr(r){L=r,W=!0,I=r,B=s.filterAll,tr(r,!1);var e=B(O);return K=e[0],P=e[1],j}function tr(e,n){var t,o,f,a=[],l=[],s=[],c=[],h=O.length;if(!i)for(t=0;t<h;++t)!(r[w][o=F[t]]&p)^!!(f=e(O[t],t))&&(f?a.push(o):l.push(o));if(i)for(t=0;t<h;++t)e(O[t],t)?(a.push(F[t]),s.push(t)):(l.push(F[t]),c.push(t));if(i){var v=[],d=[];for(t=0;t<a.length;t++)1===D[s[t]]&&(U[a[t]]++,D[s[t]]=0,1===U[a[t]]&&(r[w][a[t]]^=p,v.push(a[t])));for(t=0;t<l.length;t++)0===D[c[t]]&&(U[l[t]]--,D[c[t]]=1,0===U[l[t]]&&(r[w][l[t]]^=p,d.push(l[t])));if(a=v,l=d,n)for(t=0;t<$.length;t++)r[w][o=$[t]]&p&&(r[w][o]^=p,a.push(o));else for(t=0;t<$.length;t++)r[w][o=$[t]]&p||(r[w][o]^=p,l.push(o))}else{for(t=0;t<a.length;t++)r[w][a[t]]&p&&(r[w][a[t]]&=x);for(t=0;t<l.length;t++)r[w][l[t]]&p||(r[w][l[t]]|=p)}u.forEach((function(r){r(p,w,a,l)})),g("filtered")}function ur(e){var o={top:function(r){var e=g(P(),0,a.length,r);return b.sort(e,0,e.length)},all:P,reduce:Q,reduceCount:T,reduceSum:function(r){return Q(E.reduceAdd(r),E.reduceSubtract(r),v)},order:V,orderNatural:function(){return V(c)},size:function(){return U},dispose:X,remove:X};H.push(o);var a,s,g,b,m,A,z,S,N=8,R=C(N),U=0,D=h,I=h,L=!0,W=e===h;function J(o,f,c,v){i&&(S=c,c=O.length-o.length,v=o.length);var p,d,g,y,b,E,k=a,F=i?[]:M(U,R),J=m,j=A,G=z,H=U,P=0,Q=0;for(L&&(J=G=h),L&&(j=G=h),a=new Array(U),U=0,s=i?H?s:[]:H>1?l.arrayLengthen(s,t):M(t,R),H&&(g=(d=k[0]).key);Q<v&&!((y=e(o[Q]))>=y);)++Q;for(;Q<v;){for(d&&g<=y?(b=d,E=g,F[P]=U,(d=k[++P])&&(g=d.key)):(b={key:y,value:G()},E=y),a[U]=b;y<=E&&(p=f[Q]+(i?S:c),i?s[p]?s[p].push(U):s[p]=[U]:s[p]=U,b.value=J(b.value,n[p],!0),r.zeroExcept(p,w,x)||(b.value=j(b.value,n[p],!1)),!(++Q>=v));)y=e(o[Q]);V()}for(;P<H;)a[F[P]=U]=k[P++],V();if(i)for(var T=0;T<t;T++)s[T]||(s[T]=[]);if(U>P)if(i)for(P=0;P<S;++P)for(T=0;T<s[P].length;T++)s[P][T]=F[s[P][T]];else for(P=0;P<c;++P)s[P]=F[s[P]];function V(){i?U++:++U===R&&(F=l.arrayWiden(F,N<<=1),s=l.arrayWiden(s,N),R=C(N))}p=u.indexOf(D),U>1||i?(D=$,I=B):(!U&&W&&(U=1,a=[{key:null,value:G()}]),1===U?(D=q,I=K):(D=h,I=h),s=null),u[p]=D}function j(r){if(U>1||i){var e,n,o,f=U,l=a,c=M(f,f);if(i){for(e=0,o=0;e<t;++e)if(r[e]!==k){for(s[o]=s[e],n=0;n<s[o].length;n++)c[s[o][n]]=1;++o}s=s.slice(0,o)}else for(e=0,o=0;e<t;++e)r[e]!==k&&(c[s[o]=s[e]]=1,++o);for(a=[],U=0,e=0;e<f;++e)c[e]&&(c[e]=U++,a.push(l[e]));if(U>1||i)if(i)for(e=0;e<o;++e)for(n=0;n<s[e].length;++n)s[e][n]=c[s[e][n]];else for(e=0;e<o;++e)s[e]=c[s[e]];else s=null;u[u.indexOf(D)]=U>1||i?(I=B,D=$):1===U?(I=K,D=q):I=D=h}else if(1===U){if(W)return;for(var v=0;v<t;++v)if(r[v]!==k)return;a=[],U=0,u[u.indexOf(D)]=D=I=h}}function $(e,t,u,o,f){var l,c,h,v,d;if(!(e===p&&t===w||L))if(i){for(l=0,v=u.length;l<v;++l)if(r.zeroExcept(h=u[l],w,x))for(c=0;c<s[h].length;c++)(d=a[s[h][c]]).value=m(d.value,n[h],!1,c);for(l=0,v=o.length;l<v;++l)if(r.onlyExcept(h=o[l],w,x,t,e))for(c=0;c<s[h].length;c++)(d=a[s[h][c]]).value=A(d.value,n[h],f,c)}else{for(l=0,v=u.length;l<v;++l)r.zeroExcept(h=u[l],w,x)&&((d=a[s[h]]).value=m(d.value,n[h],!1));for(l=0,v=o.length;l<v;++l)r.onlyExcept(h=o[l],w,x,t,e)&&((d=a[s[h]]).value=A(d.value,n[h],f))}}function q(e,t,u,o,f){if(!(e===p&&t===w||L)){var i,l,s,c=a[0];for(i=0,s=u.length;i<s;++i)r.zeroExcept(l=u[i],w,x)&&(c.value=m(c.value,n[l],!1));for(i=0,s=o.length;i<s;++i)r.onlyExcept(l=o[i],w,x,t,e)&&(c.value=A(c.value,n[l],f))}}function B(){var e,u,o;for(e=0;e<U;++e)a[e].value=z();if(i){for(e=0;e<t;++e)for(u=0;u<s[e].length;u++)(o=a[s[e][u]]).value=m(o.value,n[e],!0,u);for(e=0;e<t;++e)if(!r.zeroExcept(e,w,x))for(u=0;u<s[e].length;u++)(o=a[s[e][u]]).value=A(o.value,n[e],!1,u)}else{for(e=0;e<t;++e)(o=a[s[e]]).value=m(o.value,n[e],!0);for(e=0;e<t;++e)r.zeroExcept(e,w,x)||((o=a[s[e]]).value=A(o.value,n[e],!1))}}function K(){var e,u=a[0];for(u.value=z(),e=0;e<t;++e)u.value=m(u.value,n[e],!0);for(e=0;e<t;++e)r.zeroExcept(e,w,x)||(u.value=A(u.value,n[e],!1))}function P(){return L&&(I(),L=!1),a}function Q(r,e,n){return m=r,A=e,z=n,L=!0,o}function T(){return Q(E.reduceIncrement,E.reduceDecrement,v)}function V(r){function e(e){return r(e.value)}return g=y.by(e),b=d.by(e),o}function X(){var r=u.indexOf(D);return r>=0&&u.splice(r,1),(r=G.indexOf(J))>=0&&G.splice(r,1),(r=f.indexOf(j))>=0&&f.splice(r,1),(r=H.indexOf(o))>=0&&H.splice(r,1),o}return arguments.length<1&&(e=c),u.push(D),G.push(J),f.push(j),J(O,F,0,t),T().orderNatural()}function or(){H.forEach((function(r){r.dispose()}));var e=o.indexOf(V);return e>=0&&o.splice(e,1),(e=o.indexOf(X))>=0&&o.splice(e,1),(e=f.indexOf(Y))>=0&&f.splice(e,1),r.masks[w]&=x,er()}return w=T.offset,p=T.one,x=~p,A=w<<7|Math.log(p)/Math.log(2),V(n,0,t),X(n,0,t),j},groupAll:function(){var e,f,i,a,l={reduce:p,reduceCount:d,reduceSum:function(r){return p(E.reduceAdd(r),E.reduceSubtract(r),v)},value:function(){s&&(function(){var u;for(e=a(),u=0;u<t;++u)e=f(e,n[u],!0),r.zero(u)||(e=i(e,n[u],!1))}(),s=!1);return e},dispose:g,remove:g},s=!0;function c(u,o){var a;if(!s)for(a=o;a<t;++a)e=f(e,n[a],!0),r.zero(a)||(e=i(e,n[a],!1))}function h(t,u,o,a,l){var c,h,v;if(!s){for(c=0,v=o.length;c<v;++c)r.zero(h=o[c])&&(e=f(e,n[h],l));for(c=0,v=a.length;c<v;++c)r.only(h=a[c],u,t)&&(e=i(e,n[h],l))}}function p(r,e,n){return f=r,i=e,a=n,s=!0,l}function d(){return p(E.reduceIncrement,E.reduceDecrement,v)}function g(){var r=u.indexOf(h);return r>=0&&u.splice(r,1),(r=o.indexOf(c))>=0&&o.splice(r,1),l}return(u.push(h),o.push(c),c(n,0),d())},size:function(){return t},all:function(){return n},allFiltered:function(e){var u=[],o=0,f=p(e||[]);for(o=0;o<t;o++)r.zeroExceptMask(o,f)&&u.push(n[o]);return u},onChange:function(r){if("function"!=typeof r)return void console.warn("onChange callback parameter must be a function!");return i.push(r),function(){i.splice(i.indexOf(r),1)}},isElementFiltered:function(e,n){var t=p(n||[]);return r.zeroExceptMask(e,t)}},n=[],t=0,u=[],o=[],f=[],i=[];function a(u){var f=t,i=u.length;return i&&(n=n.concat(u),r.lengthen(t+=i),o.forEach((function(r){r(u,f,i)})),g("dataAdded")),e}function p(e){var n,t,u,o,f=Array(r.subarrays);for(n=0;n<r.subarrays;n++)f[n]=-1;for(t=0,u=e.length;t<u;t++)f[(o=e[t].id())>>7]&=~(1<<(63&o));return f}function g(r){for(var e=0;e<i.length;e++)i[e](r)}return r=new l.bitarray(0),arguments.length?a(arguments[0]):e}function M(r,e){return(e<257?l.array8:e<65537?l.array16:l.array32)(r)}function S(r){for(var e=M(r,r),n=-1;++n<r;)e[n]=n;return e}function C(r){return 8===r?256:16===r?65536:4294967296}O.heap=d,O.heapselect=y,O.bisect=b,O.permute=m;return O.version="1.5.4",O}));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDM1Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvY3Jvc3NmaWx0ZXIyL2Nyb3NzZmlsdGVyLm1pbi5qcz82ZTBjIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIGh0dHBzOi8vY3Jvc3NmaWx0ZXIuZ2l0aHViLmlvL2Nyb3NzZmlsdGVyLyB2MS41LjQgQ29weXJpZ2h0IDIwMjAgTWlrZSBCb3N0b2NrXG4hZnVuY3Rpb24ocixlKXtcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1lKCk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShlKToocj1yfHxzZWxmKS5jcm9zc2ZpbHRlcj1lKCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7bGV0IHI9byxlPW8sbj1vLHQ9Zix1PWk7ZnVuY3Rpb24gbyhyKXtmb3IodmFyIGU9bmV3IEFycmF5KHIpLG49LTE7KytuPHI7KWVbbl09MDtyZXR1cm4gZX1mdW5jdGlvbiBmKHIsZSl7Zm9yKHZhciBuPXIubGVuZ3RoO248ZTspcltuKytdPTA7cmV0dXJuIHJ9ZnVuY3Rpb24gaShyLGUpe2lmKGU+MzIpdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBhcnJheSB3aWR0aCFcIik7cmV0dXJuIHJ9ZnVuY3Rpb24gYShlKXt0aGlzLmxlbmd0aD1lLHRoaXMuc3ViYXJyYXlzPTEsdGhpcy53aWR0aD04LHRoaXMubWFza3M9ezA6MH0sdGhpc1swXT1yKGUpfVwidW5kZWZpbmVkXCIhPXR5cGVvZiBVaW50OEFycmF5JiYocj1mdW5jdGlvbihyKXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkocil9LGU9ZnVuY3Rpb24ocil7cmV0dXJuIG5ldyBVaW50MTZBcnJheShyKX0sbj1mdW5jdGlvbihyKXtyZXR1cm4gbmV3IFVpbnQzMkFycmF5KHIpfSx0PWZ1bmN0aW9uKHIsZSl7aWYoci5sZW5ndGg+PWUpcmV0dXJuIHI7dmFyIG49bmV3IHIuY29uc3RydWN0b3IoZSk7cmV0dXJuIG4uc2V0KHIpLG59LHU9ZnVuY3Rpb24ocix0KXt2YXIgdTtzd2l0Y2godCl7Y2FzZSAxNjp1PWUoci5sZW5ndGgpO2JyZWFrO2Nhc2UgMzI6dT1uKHIubGVuZ3RoKTticmVhaztkZWZhdWx0OnRocm93IG5ldyBFcnJvcihcImludmFsaWQgYXJyYXkgd2lkdGghXCIpfXJldHVybiB1LnNldChyKSx1fSksYS5wcm90b3R5cGUubGVuZ3RoZW49ZnVuY3Rpb24ocil7dmFyIGUsbjtmb3IoZT0wLG49dGhpcy5zdWJhcnJheXM7ZTxuOysrZSl0aGlzW2VdPXQodGhpc1tlXSxyKTt0aGlzLmxlbmd0aD1yfSxhLnByb3RvdHlwZS5hZGQ9ZnVuY3Rpb24oKXt2YXIgZSxuLHQsbyxmO2ZvcihvPTAsZj10aGlzLnN1YmFycmF5cztvPGY7KytvKWlmKHQ9KH4oZT10aGlzLm1hc2tzW29dKSZlKzEpPj4+MCwhKChuPXRoaXMud2lkdGgtMzIqbyk+PTMyKXx8dClyZXR1cm4gbjwzMiYmdCYxPDxuJiYodGhpc1tvXT11KHRoaXNbb10sbjw8PTEpLHRoaXMud2lkdGg9MzIqbytuKSx0aGlzLm1hc2tzW29dfD10LHtvZmZzZXQ6byxvbmU6dH07cmV0dXJuIHRoaXNbdGhpcy5zdWJhcnJheXNdPXIodGhpcy5sZW5ndGgpLHRoaXMubWFza3NbdGhpcy5zdWJhcnJheXNdPTEsdGhpcy53aWR0aCs9OCx7b2Zmc2V0OnRoaXMuc3ViYXJyYXlzKyssb25lOjF9fSxhLnByb3RvdHlwZS5jb3B5PWZ1bmN0aW9uKHIsZSl7dmFyIG4sdDtmb3Iobj0wLHQ9dGhpcy5zdWJhcnJheXM7bjx0Oysrbil0aGlzW25dW3JdPXRoaXNbbl1bZV19LGEucHJvdG90eXBlLnRydW5jYXRlPWZ1bmN0aW9uKHIpe3ZhciBlLG47Zm9yKGU9MCxuPXRoaXMuc3ViYXJyYXlzO2U8bjsrK2UpZm9yKHZhciB0PXRoaXMubGVuZ3RoLTE7dD49cjt0LS0pdGhpc1tlXVt0XT0wO3RoaXMubGVuZ3RoPXJ9LGEucHJvdG90eXBlLnplcm89ZnVuY3Rpb24ocil7dmFyIGUsbjtmb3IoZT0wLG49dGhpcy5zdWJhcnJheXM7ZTxuOysrZSlpZih0aGlzW2VdW3JdKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS56ZXJvRXhjZXB0PWZ1bmN0aW9uKHIsZSxuKXt2YXIgdCx1O2Zvcih0PTAsdT10aGlzLnN1YmFycmF5czt0PHU7Kyt0KWlmKHQ9PT1lP3RoaXNbdF1bcl0mbjp0aGlzW3RdW3JdKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS56ZXJvRXhjZXB0TWFzaz1mdW5jdGlvbihyLGUpe3ZhciBuLHQ7Zm9yKG49MCx0PXRoaXMuc3ViYXJyYXlzO248dDsrK24paWYodGhpc1tuXVtyXSZlW25dKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS5vbmx5PWZ1bmN0aW9uKHIsZSxuKXt2YXIgdCx1O2Zvcih0PTAsdT10aGlzLnN1YmFycmF5czt0PHU7Kyt0KWlmKHRoaXNbdF1bcl0hPSh0PT09ZT9uOjApKXJldHVybiExO3JldHVybiEwfSxhLnByb3RvdHlwZS5vbmx5RXhjZXB0PWZ1bmN0aW9uKHIsZSxuLHQsdSl7dmFyIG8sZixpO2ZvcihmPTAsaT10aGlzLnN1YmFycmF5cztmPGk7KytmKWlmKG89dGhpc1tmXVtyXSxmPT09ZSYmKG89KG8mbik+Pj4wKSxvIT0oZj09PXQ/dTowKSlyZXR1cm4hMTtyZXR1cm4hMH07dmFyIGw9e2FycmF5ODpvLGFycmF5MTY6byxhcnJheTMyOm8sYXJyYXlMZW5ndGhlbjpmLGFycmF5V2lkZW46aSxiaXRhcnJheTphfTt2YXIgcz17ZmlsdGVyRXhhY3Q6KHIsZSk9PihmdW5jdGlvbihuKXt2YXIgdD1uLmxlbmd0aDtyZXR1cm5bci5sZWZ0KG4sZSwwLHQpLHIucmlnaHQobixlLDAsdCldfSksZmlsdGVyUmFuZ2U6KHIsZSk9Pnt2YXIgbj1lWzBdLHQ9ZVsxXTtyZXR1cm4gZnVuY3Rpb24oZSl7dmFyIHU9ZS5sZW5ndGg7cmV0dXJuW3IubGVmdChlLG4sMCx1KSxyLmxlZnQoZSx0LDAsdSldfX0sZmlsdGVyQWxsOnI9PlswLHIubGVuZ3RoXX0sYz1yPT5yLGg9KCk9Pm51bGwsdj0oKT0+MDtmdW5jdGlvbiBwKHIpe2Z1bmN0aW9uIGUocixlLHQpe2Zvcih2YXIgdT10LWUsbz0xKyh1Pj4+MSk7LS1vPjA7KW4ocixvLHUsZSk7cmV0dXJuIHJ9ZnVuY3Rpb24gbihlLG4sdCx1KXtmb3IodmFyIG8sZj1lWy0tdStuXSxpPXIoZik7KG89bjw8MSk8PXQmJihvPHQmJnIoZVt1K29dKT5yKGVbdStvKzFdKSYmbysrLCEoaTw9cihlW3Urb10pKSk7KWVbdStuXT1lW3Urb10sbj1vO2VbdStuXT1mfXJldHVybiBlLnNvcnQ9ZnVuY3Rpb24ocixlLHQpe2Zvcih2YXIgdSxvPXQtZTstLW8+MDspdT1yW2VdLHJbZV09cltlK29dLHJbZStvXT11LG4ociwxLG8sZSk7cmV0dXJuIHJ9LGV9Y29uc3QgZD1wKGMpO2Z1bmN0aW9uIGcocil7dmFyIGU9ZC5ieShyKTtyZXR1cm4gZnVuY3Rpb24obix0LHUsbyl7dmFyIGYsaSxhLGw9bmV3IEFycmF5KG89TWF0aC5taW4odS10LG8pKTtmb3IoaT0wO2k8bzsrK2kpbFtpXT1uW3QrK107aWYoZShsLDAsbyksdDx1KXtmPXIobFswXSk7ZG97cihhPW5bdF0pPmYmJihsWzBdPWEsZj1yKGUobCwwLG8pWzBdKSl9d2hpbGUoKyt0PHUpfXJldHVybiBsfX1kLmJ5PXA7Y29uc3QgeT1nKGMpO2Z1bmN0aW9uIHgocil7ZnVuY3Rpb24gZShlLG4sdCx1KXtmb3IoO3Q8dTspe3ZhciBvPXQrdT4+PjE7bjxyKGVbb10pP3U9bzp0PW8rMX1yZXR1cm4gdH1yZXR1cm4gZS5yaWdodD1lLGUubGVmdD1mdW5jdGlvbihlLG4sdCx1KXtmb3IoO3Q8dTspe3ZhciBvPXQrdT4+PjE7cihlW29dKTxuP3Q9bysxOnU9b31yZXR1cm4gdH0sZX15LmJ5PWc7Y29uc3QgYj14KGMpO2IuYnk9eDt2YXIgbT0ocixlLG4pPT57Zm9yKHZhciB0PTAsdT1lLmxlbmd0aCxvPW4/SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyKSk6bmV3IEFycmF5KHUpO3Q8dTsrK3Qpb1t0XT1yW2VbdF1dO3JldHVybiBvfTt2YXIgRT17cmVkdWNlSW5jcmVtZW50OnI9PnIrMSxyZWR1Y2VEZWNyZW1lbnQ6cj0+ci0xLHJlZHVjZUFkZDpyPT4oZnVuY3Rpb24oZSxuKXtyZXR1cm4gZSsgK3Iobil9KSxyZWR1Y2VTdWJ0cmFjdDpyPT4oZnVuY3Rpb24oZSxuKXtyZXR1cm4gZS1yKG4pfSl9O2NvbnN0IHc9KHIsZSk9Pntjb25zdCBuPXJbZV07cmV0dXJuXCJmdW5jdGlvblwiPT10eXBlb2Ygbj9uLmNhbGwocik6bn0sQT0vXFxbKFtcXHdcXGRdKylcXF0vZzt2YXIgej0ocixlKT0+KGZ1bmN0aW9uKHIsZSxuLHQsdSl7Zm9yKHUgaW4gdD0obj1uLnNwbGl0KFwiLlwiKSkuc3BsaWNlKC0xLDEpLG4pZT1lW25bdV1dPWVbblt1XV18fHt9O3JldHVybiByKGUsdCl9KSh3LHIsZS5yZXBsYWNlKEEsXCIuJDFcIikpLGs9LTE7ZnVuY3Rpb24gTygpe3ZhciByLGU9e2FkZDphLHJlbW92ZTpmdW5jdGlvbihlKXtmb3IodmFyIG89bmV3IEFycmF5KHQpLGk9W10sYT1cImZ1bmN0aW9uXCI9PXR5cGVvZiBlLGw9MCxzPTA7bDx0OysrbCljPWwsKGE/ZShuW2NdLGMpOnIuemVybyhjKSk/KGkucHVzaChsKSxvW2xdPWspOm9bbF09cysrO3ZhciBjO3UuZm9yRWFjaCgoZnVuY3Rpb24ocil7cigtMSwtMSxbXSxpLCEwKX0pKSxmLmZvckVhY2goKGZ1bmN0aW9uKHIpe3Iobyl9KSk7Zm9yKHZhciBoPTAsdj0wO2g8dDsrK2gpb1toXSE9PWsmJihoIT09diYmKHIuY29weSh2LGgpLG5bdl09bltoXSksKyt2KTtuLmxlbmd0aD10PXYsci50cnVuY2F0ZSh2KSxnKFwiZGF0YVJlbW92ZWRcIil9LGRpbWVuc2lvbjpmdW5jdGlvbihlLGkpe2lmKFwic3RyaW5nXCI9PXR5cGVvZiBlKXt2YXIgYT1lO2U9ZnVuY3Rpb24ocil7cmV0dXJuIHoocixhKX19dmFyIHAseCx3LEEsTyxGLE4sUixVLEQsSSxMLFcsSixqPXtmaWx0ZXI6ZnVuY3Rpb24ocil7cmV0dXJuIG51bGw9PXI/ZXIoKTpBcnJheS5pc0FycmF5KHIpP3JyKHIpOlwiZnVuY3Rpb25cIj09dHlwZW9mIHI/bnIocik6XyhyKX0sZmlsdGVyRXhhY3Q6XyxmaWx0ZXJSYW5nZTpycixmaWx0ZXJGdW5jdGlvbjpucixmaWx0ZXJBbGw6ZXIsY3VycmVudEZpbHRlcjpmdW5jdGlvbigpe3JldHVybiBMfSxoYXNDdXJyZW50RmlsdGVyOmZ1bmN0aW9uKCl7cmV0dXJuIFd9LHRvcDpmdW5jdGlvbihlLHQpe3ZhciB1LG89W10sZj1QLGE9MDt0JiZ0PjAmJihhPXQpO2Zvcig7LS1mPj1LJiZlPjA7KXIuemVybyh1PUZbZl0pJiYoYT4wPy0tYTooby5wdXNoKG5bdV0pLC0tZSkpO2lmKGkpZm9yKGY9MDtmPCQubGVuZ3RoJiZlPjA7ZisrKXIuemVybyh1PSRbZl0pJiYoYT4wPy0tYTooby5wdXNoKG5bdV0pLC0tZSkpO3JldHVybiBvfSxib3R0b206ZnVuY3Rpb24oZSx0KXt2YXIgdSxvLGY9W10sYT0wO3QmJnQ+MCYmKGE9dCk7aWYoaSlmb3IodT0wO3U8JC5sZW5ndGgmJmU+MDt1Kyspci56ZXJvKG89JFt1XSkmJihhPjA/LS1hOihmLnB1c2gobltvXSksLS1lKSk7dT1LO2Zvcig7dTxQJiZlPjA7KXIuemVybyhvPUZbdV0pJiYoYT4wPy0tYTooZi5wdXNoKG5bb10pLC0tZSkpLHUrKztyZXR1cm4gZn0sZ3JvdXA6dXIsZ3JvdXBBbGw6ZnVuY3Rpb24oKXt2YXIgcj11cihoKSxlPXIuYWxsO3JldHVybiBkZWxldGUgci5hbGwsZGVsZXRlIHIudG9wLGRlbGV0ZSByLm9yZGVyLGRlbGV0ZSByLm9yZGVyTmF0dXJhbCxkZWxldGUgci5zaXplLHIudmFsdWU9ZnVuY3Rpb24oKXtyZXR1cm4gZSgpWzBdLnZhbHVlfSxyfSxkaXNwb3NlOm9yLHJlbW92ZTpvcixhY2Nlc3NvcjplLGlkOmZ1bmN0aW9uKCl7cmV0dXJuIEF9fSwkPVtdLHE9ZnVuY3Rpb24ocil7cmV0dXJuIFMocikuc29ydCgoZnVuY3Rpb24ocixlKXt2YXIgbj1OW3JdLHQ9TltlXTtyZXR1cm4gbjx0Py0xOm4+dD8xOnItZX0pKX0sQj1zLmZpbHRlckFsbCxHPVtdLEg9W10sSz0wLFA9MCxRPTA7by51bnNoaWZ0KFYpLG8ucHVzaChYKSxmLnB1c2goWSk7dmFyIFQ9ci5hZGQoKTtmdW5jdGlvbiBWKG4sdSxvKXt2YXIgZixhO2lmKGkpe1E9MCxHPTAsSj1bXTtmb3IodmFyIHM9MDtzPG4ubGVuZ3RoO3MrKylmb3IoRz0wLEo9ZShuW3NdKTtHPEoubGVuZ3RoO0crKylRKys7Tj1bXSxmPVMobi5sZW5ndGgpLGE9TShRLDEpO2Zvcih2YXIgYz1TKFEpLGg9MCx2PTA7djxuLmxlbmd0aDt2KyspaWYoKEo9ZShuW3ZdKSkubGVuZ3RoKWZvcihmW3ZdPUoubGVuZ3RoLEc9MDtHPEoubGVuZ3RoO0crKylOLnB1c2goSltHXSksY1toXT12LGgrKztlbHNlIGZbdl09MCwkLnB1c2godit1KTt2YXIgZD1xKFEpO049bShOLGQpLFI9bShjLGQpfWVsc2UgTj1uLm1hcChlKSxSPXEobyksTj1tKE4sUik7dmFyIGcseSx4LGI9QihOKSxFPWJbMF0sQT1iWzFdO2lmKGkpaWYobz1RLEkpZm9yKGc9MDtnPG87KytnKUkoTltnXSxnKXx8KDA9PS0tZltSW2ddXSYmKHJbd11bUltnXSt1XXw9cCksYVtnXT0xKTtlbHNle2Zvcih5PTA7eTxFOysreSkwPT0tLWZbUlt5XV0mJihyW3ddW1JbeV0rdV18PXApLGFbeV09MTtmb3IoeD1BO3g8bzsrK3gpMD09LS1mW1JbeF1dJiYoclt3XVtSW3hdK3VdfD1wKSxhW3hdPTF9ZWxzZSBpZihJKWZvcihnPTA7ZzxvOysrZylJKE5bZ10sZyl8fChyW3ddW1JbZ10rdV18PXApO2Vsc2V7Zm9yKHk9MDt5PEU7Kyt5KXJbd11bUlt5XSt1XXw9cDtmb3IoeD1BO3g8bzsrK3gpclt3XVtSW3hdK3VdfD1wfWlmKCF1KXJldHVybiBPPU4sRj1SLFU9ZixEPWEsSz1FLHZvaWQoUD1BKTt2YXIgeixrPU8sQz1GLEw9RCxXPTA7aWYocz0wLGkmJih6PXUsdT1rLmxlbmd0aCxvPVEpLE89bmV3IEFycmF5KGk/dStvOnQpLEY9aT9uZXcgQXJyYXkodStvKTpNKHQsdCksaSYmKEQ9TSh1K28sMSkpLGkpe3ZhciBqPVUubGVuZ3RoO1U9bC5hcnJheUxlbmd0aGVuKFUsdCk7Zm9yKHZhciBHPTA7RytqPHQ7RysrKVVbRytqXT1mW0ddfWZvcih2YXIgSD0wO3M8dSYmVzxvOysrSClrW3NdPE5bV10/KE9bSF09a1tzXSxpJiYoRFtIXT1MW3NdKSxGW0hdPUNbcysrXSk6KE9bSF09TltXXSxpJiYoRFtIXT1hW1ddKSxGW0hdPVJbVysrXSsoaT96OnUpKTtmb3IoO3M8dTsrK3MsKytIKU9bSF09a1tzXSxpJiYoRFtIXT1MW3NdKSxGW0hdPUNbc107Zm9yKDtXPG87KytXLCsrSClPW0hdPU5bV10saSYmKERbSF09YVtXXSksRltIXT1SW1ddKyhpP3o6dSk7Yj1CKE8pLEs9YlswXSxQPWJbMV19ZnVuY3Rpb24gWChyLGUsbil7Ry5mb3JFYWNoKChmdW5jdGlvbihyKXtyKE4sUixlLG4pfSkpLE49Uj1udWxsfWZ1bmN0aW9uIFkocil7aWYoaSl7Zm9yKHZhciBlPTAsbj0wO2U8JC5sZW5ndGg7ZSsrKXJbJFtlXV0hPT1rJiYoJFtuXT1yWyRbZV1dLG4rKyk7Zm9yKCQubGVuZ3RoPW4sZT0wLG49MDtlPHQ7ZSsrKXJbZV0hPT1rJiYobiE9PWUmJihVW25dPVVbZV0pLG4rKyk7VT1VLnNsaWNlKDAsbil9Zm9yKHZhciB1LG89Ty5sZW5ndGgsZj0wLGE9MDtmPG87KytmKXJbdT1GW2ZdXSE9PWsmJihmIT09YSYmKE9bYV09T1tmXSksRlthXT1yW3VdLGkmJihEW2FdPURbZl0pLCsrYSk7Zm9yKE8ubGVuZ3RoPWEsaSYmKEQ9RC5zbGljZSgwLGEpKTthPG87KUZbYSsrXT0wO3ZhciBsPUIoTyk7Sz1sWzBdLFA9bFsxXX1mdW5jdGlvbiBaKGUpe3ZhciBuPWVbMF0sdD1lWzFdO2lmKEkpcmV0dXJuIEk9bnVsbCx0cigoZnVuY3Rpb24ocixlKXtyZXR1cm4gbjw9ZSYmZTx0fSksMD09PWVbMF0mJmVbMV09PT1PLmxlbmd0aCksSz1uLFA9dCxqO3ZhciBvLGYsYSxsPVtdLGM9W10saD1bXSx2PVtdO2lmKG48Sylmb3Iobz1uLGY9TWF0aC5taW4oSyx0KTtvPGY7KytvKWwucHVzaChGW29dKSxoLnB1c2gobyk7ZWxzZSBpZihuPkspZm9yKG89SyxmPU1hdGgubWluKG4sUCk7bzxmOysrbyljLnB1c2goRltvXSksdi5wdXNoKG8pO2lmKHQ+UClmb3Iobz1NYXRoLm1heChuLFApLGY9dDtvPGY7KytvKWwucHVzaChGW29dKSxoLnB1c2gobyk7ZWxzZSBpZih0PFApZm9yKG89TWF0aC5tYXgoSyx0KSxmPVA7bzxmOysrbyljLnB1c2goRltvXSksdi5wdXNoKG8pO2lmKGkpe3ZhciBkPVtdLHk9W107Zm9yKG89MDtvPGwubGVuZ3RoO28rKylVW2xbb11dKyssRFtoW29dXT0wLDE9PT1VW2xbb11dJiYoclt3XVtsW29dXV49cCxkLnB1c2gobFtvXSkpO2ZvcihvPTA7bzxjLmxlbmd0aDtvKyspVVtjW29dXS0tLERbdltvXV09MSwwPT09VVtjW29dXSYmKHJbd11bY1tvXV1ePXAseS5wdXNoKGNbb10pKTtpZihsPWQsYz15LEI9PT1zLmZpbHRlckFsbClmb3Iobz0wO288JC5sZW5ndGg7bysrKXJbd11bYT0kW29dXSZwJiYoclt3XVthXV49cCxsLnB1c2goYSkpO2Vsc2UgZm9yKG89MDtvPCQubGVuZ3RoO28rKylyW3ddW2E9JFtvXV0mcHx8KHJbd11bYV1ePXAsYy5wdXNoKGEpKX1lbHNle2ZvcihvPTA7bzxsLmxlbmd0aDtvKyspclt3XVtsW29dXV49cDtmb3Iobz0wO288Yy5sZW5ndGg7bysrKXJbd11bY1tvXV1ePXB9cmV0dXJuIEs9bixQPXQsdS5mb3JFYWNoKChmdW5jdGlvbihyKXtyKHAsdyxsLGMpfSkpLGcoXCJmaWx0ZXJlZFwiKSxqfWZ1bmN0aW9uIF8ocil7cmV0dXJuIEw9cixXPSEwLFooKEI9cy5maWx0ZXJFeGFjdChiLHIpKShPKSl9ZnVuY3Rpb24gcnIocil7cmV0dXJuIEw9cixXPSEwLFooKEI9cy5maWx0ZXJSYW5nZShiLHIpKShPKSl9ZnVuY3Rpb24gZXIoKXtyZXR1cm4gTD12b2lkIDAsVz0hMSxaKChCPXMuZmlsdGVyQWxsKShPKSl9ZnVuY3Rpb24gbnIocil7TD1yLFc9ITAsST1yLEI9cy5maWx0ZXJBbGwsdHIociwhMSk7dmFyIGU9QihPKTtyZXR1cm4gSz1lWzBdLFA9ZVsxXSxqfWZ1bmN0aW9uIHRyKGUsbil7dmFyIHQsbyxmLGE9W10sbD1bXSxzPVtdLGM9W10saD1PLmxlbmd0aDtpZighaSlmb3IodD0wO3Q8aDsrK3QpIShyW3ddW289Rlt0XV0mcCleISEoZj1lKE9bdF0sdCkpJiYoZj9hLnB1c2gobyk6bC5wdXNoKG8pKTtpZihpKWZvcih0PTA7dDxoOysrdCllKE9bdF0sdCk/KGEucHVzaChGW3RdKSxzLnB1c2godCkpOihsLnB1c2goRlt0XSksYy5wdXNoKHQpKTtpZihpKXt2YXIgdj1bXSxkPVtdO2Zvcih0PTA7dDxhLmxlbmd0aDt0KyspMT09PURbc1t0XV0mJihVW2FbdF1dKyssRFtzW3RdXT0wLDE9PT1VW2FbdF1dJiYoclt3XVthW3RdXV49cCx2LnB1c2goYVt0XSkpKTtmb3IodD0wO3Q8bC5sZW5ndGg7dCsrKTA9PT1EW2NbdF1dJiYoVVtsW3RdXS0tLERbY1t0XV09MSwwPT09VVtsW3RdXSYmKHJbd11bbFt0XV1ePXAsZC5wdXNoKGxbdF0pKSk7aWYoYT12LGw9ZCxuKWZvcih0PTA7dDwkLmxlbmd0aDt0Kyspclt3XVtvPSRbdF1dJnAmJihyW3ddW29dXj1wLGEucHVzaChvKSk7ZWxzZSBmb3IodD0wO3Q8JC5sZW5ndGg7dCsrKXJbd11bbz0kW3RdXSZwfHwoclt3XVtvXV49cCxsLnB1c2gobykpfWVsc2V7Zm9yKHQ9MDt0PGEubGVuZ3RoO3QrKylyW3ddW2FbdF1dJnAmJihyW3ddW2FbdF1dJj14KTtmb3IodD0wO3Q8bC5sZW5ndGg7dCsrKXJbd11bbFt0XV0mcHx8KHJbd11bbFt0XV18PXApfXUuZm9yRWFjaCgoZnVuY3Rpb24ocil7cihwLHcsYSxsKX0pKSxnKFwiZmlsdGVyZWRcIil9ZnVuY3Rpb24gdXIoZSl7dmFyIG89e3RvcDpmdW5jdGlvbihyKXt2YXIgZT1nKFAoKSwwLGEubGVuZ3RoLHIpO3JldHVybiBiLnNvcnQoZSwwLGUubGVuZ3RoKX0sYWxsOlAscmVkdWNlOlEscmVkdWNlQ291bnQ6VCxyZWR1Y2VTdW06ZnVuY3Rpb24ocil7cmV0dXJuIFEoRS5yZWR1Y2VBZGQociksRS5yZWR1Y2VTdWJ0cmFjdChyKSx2KX0sb3JkZXI6VixvcmRlck5hdHVyYWw6ZnVuY3Rpb24oKXtyZXR1cm4gVihjKX0sc2l6ZTpmdW5jdGlvbigpe3JldHVybiBVfSxkaXNwb3NlOlgscmVtb3ZlOlh9O0gucHVzaChvKTt2YXIgYSxzLGcsYixtLEEseixTLE49OCxSPUMoTiksVT0wLEQ9aCxJPWgsTD0hMCxXPWU9PT1oO2Z1bmN0aW9uIEoobyxmLGMsdil7aSYmKFM9YyxjPU8ubGVuZ3RoLW8ubGVuZ3RoLHY9by5sZW5ndGgpO3ZhciBwLGQsZyx5LGIsRSxrPWEsRj1pP1tdOk0oVSxSKSxKPW0saj1BLEc9eixIPVUsUD0wLFE9MDtmb3IoTCYmKEo9Rz1oKSxMJiYoaj1HPWgpLGE9bmV3IEFycmF5KFUpLFU9MCxzPWk/SD9zOltdOkg+MT9sLmFycmF5TGVuZ3RoZW4ocyx0KTpNKHQsUiksSCYmKGc9KGQ9a1swXSkua2V5KTtRPHYmJiEoKHk9ZShvW1FdKSk+PXkpOykrK1E7Zm9yKDtRPHY7KXtmb3IoZCYmZzw9eT8oYj1kLEU9ZyxGW1BdPVUsKGQ9a1srK1BdKSYmKGc9ZC5rZXkpKTooYj17a2V5OnksdmFsdWU6RygpfSxFPXkpLGFbVV09Yjt5PD1FJiYocD1mW1FdKyhpP1M6YyksaT9zW3BdP3NbcF0ucHVzaChVKTpzW3BdPVtVXTpzW3BdPVUsYi52YWx1ZT1KKGIudmFsdWUsbltwXSwhMCksci56ZXJvRXhjZXB0KHAsdyx4KXx8KGIudmFsdWU9aihiLnZhbHVlLG5bcF0sITEpKSwhKCsrUT49dikpOyl5PWUob1tRXSk7VigpfWZvcig7UDxIOylhW0ZbUF09VV09a1tQKytdLFYoKTtpZihpKWZvcih2YXIgVD0wO1Q8dDtUKyspc1tUXXx8KHNbVF09W10pO2lmKFU+UClpZihpKWZvcihQPTA7UDxTOysrUClmb3IoVD0wO1Q8c1tQXS5sZW5ndGg7VCsrKXNbUF1bVF09RltzW1BdW1RdXTtlbHNlIGZvcihQPTA7UDxjOysrUClzW1BdPUZbc1tQXV07ZnVuY3Rpb24gVigpe2k/VSsrOisrVT09PVImJihGPWwuYXJyYXlXaWRlbihGLE48PD0xKSxzPWwuYXJyYXlXaWRlbihzLE4pLFI9QyhOKSl9cD11LmluZGV4T2YoRCksVT4xfHxpPyhEPSQsST1CKTooIVUmJlcmJihVPTEsYT1be2tleTpudWxsLHZhbHVlOkcoKX1dKSwxPT09VT8oRD1xLEk9Syk6KEQ9aCxJPWgpLHM9bnVsbCksdVtwXT1EfWZ1bmN0aW9uIGoocil7aWYoVT4xfHxpKXt2YXIgZSxuLG8sZj1VLGw9YSxjPU0oZixmKTtpZihpKXtmb3IoZT0wLG89MDtlPHQ7KytlKWlmKHJbZV0hPT1rKXtmb3Ioc1tvXT1zW2VdLG49MDtuPHNbb10ubGVuZ3RoO24rKyljW3Nbb11bbl1dPTE7KytvfXM9cy5zbGljZSgwLG8pfWVsc2UgZm9yKGU9MCxvPTA7ZTx0OysrZSlyW2VdIT09ayYmKGNbc1tvXT1zW2VdXT0xLCsrbyk7Zm9yKGE9W10sVT0wLGU9MDtlPGY7KytlKWNbZV0mJihjW2VdPVUrKyxhLnB1c2gobFtlXSkpO2lmKFU+MXx8aSlpZihpKWZvcihlPTA7ZTxvOysrZSlmb3Iobj0wO248c1tlXS5sZW5ndGg7KytuKXNbZV1bbl09Y1tzW2VdW25dXTtlbHNlIGZvcihlPTA7ZTxvOysrZSlzW2VdPWNbc1tlXV07ZWxzZSBzPW51bGw7dVt1LmluZGV4T2YoRCldPVU+MXx8aT8oST1CLEQ9JCk6MT09PVU/KEk9SyxEPXEpOkk9RD1ofWVsc2UgaWYoMT09PVUpe2lmKFcpcmV0dXJuO2Zvcih2YXIgdj0wO3Y8dDsrK3YpaWYoclt2XSE9PWspcmV0dXJuO2E9W10sVT0wLHVbdS5pbmRleE9mKEQpXT1EPUk9aH19ZnVuY3Rpb24gJChlLHQsdSxvLGYpe3ZhciBsLGMsaCx2LGQ7aWYoIShlPT09cCYmdD09PXd8fEwpKWlmKGkpe2ZvcihsPTAsdj11Lmxlbmd0aDtsPHY7KytsKWlmKHIuemVyb0V4Y2VwdChoPXVbbF0sdyx4KSlmb3IoYz0wO2M8c1toXS5sZW5ndGg7YysrKShkPWFbc1toXVtjXV0pLnZhbHVlPW0oZC52YWx1ZSxuW2hdLCExLGMpO2ZvcihsPTAsdj1vLmxlbmd0aDtsPHY7KytsKWlmKHIub25seUV4Y2VwdChoPW9bbF0sdyx4LHQsZSkpZm9yKGM9MDtjPHNbaF0ubGVuZ3RoO2MrKykoZD1hW3NbaF1bY11dKS52YWx1ZT1BKGQudmFsdWUsbltoXSxmLGMpfWVsc2V7Zm9yKGw9MCx2PXUubGVuZ3RoO2w8djsrK2wpci56ZXJvRXhjZXB0KGg9dVtsXSx3LHgpJiYoKGQ9YVtzW2hdXSkudmFsdWU9bShkLnZhbHVlLG5baF0sITEpKTtmb3IobD0wLHY9by5sZW5ndGg7bDx2OysrbClyLm9ubHlFeGNlcHQoaD1vW2xdLHcseCx0LGUpJiYoKGQ9YVtzW2hdXSkudmFsdWU9QShkLnZhbHVlLG5baF0sZikpfX1mdW5jdGlvbiBxKGUsdCx1LG8sZil7aWYoIShlPT09cCYmdD09PXd8fEwpKXt2YXIgaSxsLHMsYz1hWzBdO2ZvcihpPTAscz11Lmxlbmd0aDtpPHM7KytpKXIuemVyb0V4Y2VwdChsPXVbaV0sdyx4KSYmKGMudmFsdWU9bShjLnZhbHVlLG5bbF0sITEpKTtmb3IoaT0wLHM9by5sZW5ndGg7aTxzOysraSlyLm9ubHlFeGNlcHQobD1vW2ldLHcseCx0LGUpJiYoYy52YWx1ZT1BKGMudmFsdWUsbltsXSxmKSl9fWZ1bmN0aW9uIEIoKXt2YXIgZSx1LG87Zm9yKGU9MDtlPFU7KytlKWFbZV0udmFsdWU9eigpO2lmKGkpe2ZvcihlPTA7ZTx0OysrZSlmb3IodT0wO3U8c1tlXS5sZW5ndGg7dSsrKShvPWFbc1tlXVt1XV0pLnZhbHVlPW0oby52YWx1ZSxuW2VdLCEwLHUpO2ZvcihlPTA7ZTx0OysrZSlpZighci56ZXJvRXhjZXB0KGUsdyx4KSlmb3IodT0wO3U8c1tlXS5sZW5ndGg7dSsrKShvPWFbc1tlXVt1XV0pLnZhbHVlPUEoby52YWx1ZSxuW2VdLCExLHUpfWVsc2V7Zm9yKGU9MDtlPHQ7KytlKShvPWFbc1tlXV0pLnZhbHVlPW0oby52YWx1ZSxuW2VdLCEwKTtmb3IoZT0wO2U8dDsrK2Upci56ZXJvRXhjZXB0KGUsdyx4KXx8KChvPWFbc1tlXV0pLnZhbHVlPUEoby52YWx1ZSxuW2VdLCExKSl9fWZ1bmN0aW9uIEsoKXt2YXIgZSx1PWFbMF07Zm9yKHUudmFsdWU9eigpLGU9MDtlPHQ7KytlKXUudmFsdWU9bSh1LnZhbHVlLG5bZV0sITApO2ZvcihlPTA7ZTx0OysrZSlyLnplcm9FeGNlcHQoZSx3LHgpfHwodS52YWx1ZT1BKHUudmFsdWUsbltlXSwhMSkpfWZ1bmN0aW9uIFAoKXtyZXR1cm4gTCYmKEkoKSxMPSExKSxhfWZ1bmN0aW9uIFEocixlLG4pe3JldHVybiBtPXIsQT1lLHo9bixMPSEwLG99ZnVuY3Rpb24gVCgpe3JldHVybiBRKEUucmVkdWNlSW5jcmVtZW50LEUucmVkdWNlRGVjcmVtZW50LHYpfWZ1bmN0aW9uIFYocil7ZnVuY3Rpb24gZShlKXtyZXR1cm4gcihlLnZhbHVlKX1yZXR1cm4gZz15LmJ5KGUpLGI9ZC5ieShlKSxvfWZ1bmN0aW9uIFgoKXt2YXIgcj11LmluZGV4T2YoRCk7cmV0dXJuIHI+PTAmJnUuc3BsaWNlKHIsMSksKHI9Ry5pbmRleE9mKEopKT49MCYmRy5zcGxpY2UociwxKSwocj1mLmluZGV4T2YoaikpPj0wJiZmLnNwbGljZShyLDEpLChyPUguaW5kZXhPZihvKSk+PTAmJkguc3BsaWNlKHIsMSksb31yZXR1cm4gYXJndW1lbnRzLmxlbmd0aDwxJiYoZT1jKSx1LnB1c2goRCksRy5wdXNoKEopLGYucHVzaChqKSxKKE8sRiwwLHQpLFQoKS5vcmRlck5hdHVyYWwoKX1mdW5jdGlvbiBvcigpe0guZm9yRWFjaCgoZnVuY3Rpb24ocil7ci5kaXNwb3NlKCl9KSk7dmFyIGU9by5pbmRleE9mKFYpO3JldHVybiBlPj0wJiZvLnNwbGljZShlLDEpLChlPW8uaW5kZXhPZihYKSk+PTAmJm8uc3BsaWNlKGUsMSksKGU9Zi5pbmRleE9mKFkpKT49MCYmZi5zcGxpY2UoZSwxKSxyLm1hc2tzW3ddJj14LGVyKCl9cmV0dXJuIHc9VC5vZmZzZXQscD1ULm9uZSx4PX5wLEE9dzw8N3xNYXRoLmxvZyhwKS9NYXRoLmxvZygyKSxWKG4sMCx0KSxYKG4sMCx0KSxqfSxncm91cEFsbDpmdW5jdGlvbigpe3ZhciBlLGYsaSxhLGw9e3JlZHVjZTpwLHJlZHVjZUNvdW50OmQscmVkdWNlU3VtOmZ1bmN0aW9uKHIpe3JldHVybiBwKEUucmVkdWNlQWRkKHIpLEUucmVkdWNlU3VidHJhY3Qociksdil9LHZhbHVlOmZ1bmN0aW9uKCl7cyYmKGZ1bmN0aW9uKCl7dmFyIHU7Zm9yKGU9YSgpLHU9MDt1PHQ7Kyt1KWU9ZihlLG5bdV0sITApLHIuemVybyh1KXx8KGU9aShlLG5bdV0sITEpKX0oKSxzPSExKTtyZXR1cm4gZX0sZGlzcG9zZTpnLHJlbW92ZTpnfSxzPSEwO2Z1bmN0aW9uIGModSxvKXt2YXIgYTtpZighcylmb3IoYT1vO2E8dDsrK2EpZT1mKGUsblthXSwhMCksci56ZXJvKGEpfHwoZT1pKGUsblthXSwhMSkpfWZ1bmN0aW9uIGgodCx1LG8sYSxsKXt2YXIgYyxoLHY7aWYoIXMpe2ZvcihjPTAsdj1vLmxlbmd0aDtjPHY7KytjKXIuemVybyhoPW9bY10pJiYoZT1mKGUsbltoXSxsKSk7Zm9yKGM9MCx2PWEubGVuZ3RoO2M8djsrK2Mpci5vbmx5KGg9YVtjXSx1LHQpJiYoZT1pKGUsbltoXSxsKSl9fWZ1bmN0aW9uIHAocixlLG4pe3JldHVybiBmPXIsaT1lLGE9bixzPSEwLGx9ZnVuY3Rpb24gZCgpe3JldHVybiBwKEUucmVkdWNlSW5jcmVtZW50LEUucmVkdWNlRGVjcmVtZW50LHYpfWZ1bmN0aW9uIGcoKXt2YXIgcj11LmluZGV4T2YoaCk7cmV0dXJuIHI+PTAmJnUuc3BsaWNlKHIsMSksKHI9by5pbmRleE9mKGMpKT49MCYmby5zcGxpY2UociwxKSxsfXJldHVybih1LnB1c2goaCksby5wdXNoKGMpLGMobiwwKSxkKCkpfSxzaXplOmZ1bmN0aW9uKCl7cmV0dXJuIHR9LGFsbDpmdW5jdGlvbigpe3JldHVybiBufSxhbGxGaWx0ZXJlZDpmdW5jdGlvbihlKXt2YXIgdT1bXSxvPTAsZj1wKGV8fFtdKTtmb3Iobz0wO288dDtvKyspci56ZXJvRXhjZXB0TWFzayhvLGYpJiZ1LnB1c2gobltvXSk7cmV0dXJuIHV9LG9uQ2hhbmdlOmZ1bmN0aW9uKHIpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHIpcmV0dXJuIHZvaWQgY29uc29sZS53YXJuKFwib25DaGFuZ2UgY2FsbGJhY2sgcGFyYW1ldGVyIG11c3QgYmUgYSBmdW5jdGlvbiFcIik7cmV0dXJuIGkucHVzaChyKSxmdW5jdGlvbigpe2kuc3BsaWNlKGkuaW5kZXhPZihyKSwxKX19LGlzRWxlbWVudEZpbHRlcmVkOmZ1bmN0aW9uKGUsbil7dmFyIHQ9cChufHxbXSk7cmV0dXJuIHIuemVyb0V4Y2VwdE1hc2soZSx0KX19LG49W10sdD0wLHU9W10sbz1bXSxmPVtdLGk9W107ZnVuY3Rpb24gYSh1KXt2YXIgZj10LGk9dS5sZW5ndGg7cmV0dXJuIGkmJihuPW4uY29uY2F0KHUpLHIubGVuZ3RoZW4odCs9aSksby5mb3JFYWNoKChmdW5jdGlvbihyKXtyKHUsZixpKX0pKSxnKFwiZGF0YUFkZGVkXCIpKSxlfWZ1bmN0aW9uIHAoZSl7dmFyIG4sdCx1LG8sZj1BcnJheShyLnN1YmFycmF5cyk7Zm9yKG49MDtuPHIuc3ViYXJyYXlzO24rKylmW25dPS0xO2Zvcih0PTAsdT1lLmxlbmd0aDt0PHU7dCsrKWZbKG89ZVt0XS5pZCgpKT4+N10mPX4oMTw8KDYzJm8pKTtyZXR1cm4gZn1mdW5jdGlvbiBnKHIpe2Zvcih2YXIgZT0wO2U8aS5sZW5ndGg7ZSsrKWlbZV0ocil9cmV0dXJuIHI9bmV3IGwuYml0YXJyYXkoMCksYXJndW1lbnRzLmxlbmd0aD9hKGFyZ3VtZW50c1swXSk6ZX1mdW5jdGlvbiBNKHIsZSl7cmV0dXJuKGU8MjU3P2wuYXJyYXk4OmU8NjU1Mzc/bC5hcnJheTE2OmwuYXJyYXkzMikocil9ZnVuY3Rpb24gUyhyKXtmb3IodmFyIGU9TShyLHIpLG49LTE7KytuPHI7KWVbbl09bjtyZXR1cm4gZX1mdW5jdGlvbiBDKHIpe3JldHVybiA4PT09cj8yNTY6MTY9PT1yPzY1NTM2OjQyOTQ5NjcyOTZ9Ty5oZWFwPWQsTy5oZWFwc2VsZWN0PXksTy5iaXNlY3Q9YixPLnBlcm11dGU9bTtyZXR1cm4gTy52ZXJzaW9uPVwiMS41LjRcIixPfSkpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0352\n')},"072d":function(module,exports){eval("/**\n * Server side filtering\n *\n * Implementation of a dataset backed by a server, which in turn uses fi. postgreSQL\n * Fully asynchronous, based on socketIO.\n *\n * Most methods below result in a message with the methodName and a data object, containing:\n *  * `datasets` and `dataview`, or `dataset`\n *  * `filterId` or `facetId`\n *\n * Data can be requested using the dataview.getData() method\n * responds with a `newData` message containing `filterId` and `data`.\n *\n * @module driver/server\n */\n\n/**\n * Autoconfigure a dataset\n *\n * @param {Dataset} dataset\n */\nfunction scan (dataset) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    // spot-server will not respond so no use requesting a scan\n    return;\n  }\n\n  spot.socket.emit('scanData', {\n    dataset: dataset.toJSON()\n  });\n}\n\n/**\n * setMinMax sets the range of a continuous or time facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setMinMax (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    spot.socket.emit('setMinMax', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setMinMax', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * setCategories finds finds all values on an ordinal (categorial) axis\n * Updates the categorialTransform of the facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setCategories (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  facet.categorialTransform.rules.reset();\n  if (spot.isLockedDown) {\n    spot.socket.emit('setCategories', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setCategories', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * Calculate 100 percentiles (ie. 1,2,3,4 etc.), and initialize the `facet.continuousTransform`\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setPercentiles (dataset, facet) {\n  // Dataset -> Datasets -> Spot\n  var spot = dataset.collection.parent;\n\n  if (spot.isLockedDown) {\n    spot.socket.emit('setPercentiles', {\n      datasetId: dataset.getId(),\n      facetId: facet.getId()\n    });\n  } else {\n    spot.socket.emit('setPercentiles', {\n      datasetId: dataset.getId(),\n      dataset: dataset.toJSON(),\n      facetId: facet.getId()\n    });\n  }\n}\n\n/**\n * Initialize the data filter, and construct the getData callback function on the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction initDataFilter (dataview, filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n * related to the filter.\n * @param {Filter} filter\n */\nfunction releaseDataFilter (filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * Change the filter parameters for an initialized filter\n * @param {Filter} filter\n */\nfunction updateDataFilter (filter) {\n  // as the SQL server implementation is stateless, nothing to do here\n}\n\n/**\n * Get data for every filter, and trigger a 'newData' event\n *\n * Returns a Promise that resolves to the dataview when all data and metadata has been updated\n *\n * @param {Dataview} dataview\n * @returns {Promise}\n */\nfunction getData (dataview) {\n  var spot = dataview.parent;\n\n  return new Promise(function (resolve, reject) {\n    if (spot.isLockedDown) {\n      spot.socket.emit('getData', {\n        dataview: dataview.toJSON()\n      });\n    } else {\n      spot.socket.emit('getData', {\n        datasets: spot.cachedDatasets,\n        dataview: dataview.toJSON()\n      });\n    }\n\n    dataview.once('newMetaData', function () {\n      resolve(dataview);\n    });\n  });\n}\n\nmodule.exports = {\n  driverType: 'server',\n  scan: scan,\n  setMinMax: setMinMax,\n  setCategories: setCategories,\n  setPercentiles: setPercentiles,\n  initDataFilter: initDataFilter,\n  releaseDataFilter: releaseDataFilter,\n  updateDataFilter: updateDataFilter,\n  getData: getData\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDcyZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZHJpdmVyL3NlcnZlci5qcz9lMzc3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2VydmVyIHNpZGUgZmlsdGVyaW5nXG4gKlxuICogSW1wbGVtZW50YXRpb24gb2YgYSBkYXRhc2V0IGJhY2tlZCBieSBhIHNlcnZlciwgd2hpY2ggaW4gdHVybiB1c2VzIGZpLiBwb3N0Z3JlU1FMXG4gKiBGdWxseSBhc3luY2hyb25vdXMsIGJhc2VkIG9uIHNvY2tldElPLlxuICpcbiAqIE1vc3QgbWV0aG9kcyBiZWxvdyByZXN1bHQgaW4gYSBtZXNzYWdlIHdpdGggdGhlIG1ldGhvZE5hbWUgYW5kIGEgZGF0YSBvYmplY3QsIGNvbnRhaW5pbmc6XG4gKiAgKiBgZGF0YXNldHNgIGFuZCBgZGF0YXZpZXdgLCBvciBgZGF0YXNldGBcbiAqICAqIGBmaWx0ZXJJZGAgb3IgYGZhY2V0SWRgXG4gKlxuICogRGF0YSBjYW4gYmUgcmVxdWVzdGVkIHVzaW5nIHRoZSBkYXRhdmlldy5nZXREYXRhKCkgbWV0aG9kXG4gKiByZXNwb25kcyB3aXRoIGEgYG5ld0RhdGFgIG1lc3NhZ2UgY29udGFpbmluZyBgZmlsdGVySWRgIGFuZCBgZGF0YWAuXG4gKlxuICogQG1vZHVsZSBkcml2ZXIvc2VydmVyXG4gKi9cblxuLyoqXG4gKiBBdXRvY29uZmlndXJlIGEgZGF0YXNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICovXG5mdW5jdGlvbiBzY2FuIChkYXRhc2V0KSB7XG4gIC8vIERhdGFzZXQgLT4gRGF0YXNldHMgLT4gU3BvdFxuICB2YXIgc3BvdCA9IGRhdGFzZXQuY29sbGVjdGlvbi5wYXJlbnQ7XG5cbiAgaWYgKHNwb3QuaXNMb2NrZWREb3duKSB7XG4gICAgLy8gc3BvdC1zZXJ2ZXIgd2lsbCBub3QgcmVzcG9uZCBzbyBubyB1c2UgcmVxdWVzdGluZyBhIHNjYW5cbiAgICByZXR1cm47XG4gIH1cblxuICBzcG90LnNvY2tldC5lbWl0KCdzY2FuRGF0YScsIHtcbiAgICBkYXRhc2V0OiBkYXRhc2V0LnRvSlNPTigpXG4gIH0pO1xufVxuXG4vKipcbiAqIHNldE1pbk1heCBzZXRzIHRoZSByYW5nZSBvZiBhIGNvbnRpbnVvdXMgb3IgdGltZSBmYWNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqL1xuZnVuY3Rpb24gc2V0TWluTWF4IChkYXRhc2V0LCBmYWNldCkge1xuICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgdmFyIHNwb3QgPSBkYXRhc2V0LmNvbGxlY3Rpb24ucGFyZW50O1xuXG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldE1pbk1heCcsIHtcbiAgICAgIGRhdGFzZXRJZDogZGF0YXNldC5nZXRJZCgpLFxuICAgICAgZmFjZXRJZDogZmFjZXQuZ2V0SWQoKVxuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldE1pbk1heCcsIHtcbiAgICAgIGRhdGFzZXRJZDogZGF0YXNldC5nZXRJZCgpLFxuICAgICAgZGF0YXNldDogZGF0YXNldC50b0pTT04oKSxcbiAgICAgIGZhY2V0SWQ6IGZhY2V0LmdldElkKClcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIHNldENhdGVnb3JpZXMgZmluZHMgZmluZHMgYWxsIHZhbHVlcyBvbiBhbiBvcmRpbmFsIChjYXRlZ29yaWFsKSBheGlzXG4gKiBVcGRhdGVzIHRoZSBjYXRlZ29yaWFsVHJhbnNmb3JtIG9mIHRoZSBmYWNldFxuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqL1xuZnVuY3Rpb24gc2V0Q2F0ZWdvcmllcyAoZGF0YXNldCwgZmFjZXQpIHtcbiAgLy8gRGF0YXNldCAtPiBEYXRhc2V0cyAtPiBTcG90XG4gIHZhciBzcG90ID0gZGF0YXNldC5jb2xsZWN0aW9uLnBhcmVudDtcblxuICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLnJlc2V0KCk7XG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldENhdGVnb3JpZXMnLCB7XG4gICAgICBkYXRhc2V0SWQ6IGRhdGFzZXQuZ2V0SWQoKSxcbiAgICAgIGZhY2V0SWQ6IGZhY2V0LmdldElkKClcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBzcG90LnNvY2tldC5lbWl0KCdzZXRDYXRlZ29yaWVzJywge1xuICAgICAgZGF0YXNldElkOiBkYXRhc2V0LmdldElkKCksXG4gICAgICBkYXRhc2V0OiBkYXRhc2V0LnRvSlNPTigpLFxuICAgICAgZmFjZXRJZDogZmFjZXQuZ2V0SWQoKVxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIDEwMCBwZXJjZW50aWxlcyAoaWUuIDEsMiwzLDQgZXRjLiksIGFuZCBpbml0aWFsaXplIHRoZSBgZmFjZXQuY29udGludW91c1RyYW5zZm9ybWBcbiAqXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXRcbiAqIEBwYXJhbSB7RmFjZXR9IGZhY2V0XG4gKi9cbmZ1bmN0aW9uIHNldFBlcmNlbnRpbGVzIChkYXRhc2V0LCBmYWNldCkge1xuICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgdmFyIHNwb3QgPSBkYXRhc2V0LmNvbGxlY3Rpb24ucGFyZW50O1xuXG4gIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgIHNwb3Quc29ja2V0LmVtaXQoJ3NldFBlcmNlbnRpbGVzJywge1xuICAgICAgZGF0YXNldElkOiBkYXRhc2V0LmdldElkKCksXG4gICAgICBmYWNldElkOiBmYWNldC5nZXRJZCgpXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgc3BvdC5zb2NrZXQuZW1pdCgnc2V0UGVyY2VudGlsZXMnLCB7XG4gICAgICBkYXRhc2V0SWQ6IGRhdGFzZXQuZ2V0SWQoKSxcbiAgICAgIGRhdGFzZXQ6IGRhdGFzZXQudG9KU09OKCksXG4gICAgICBmYWNldElkOiBmYWNldC5nZXRJZCgpXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gaW5pdERhdGFGaWx0ZXIgKGRhdGF2aWV3LCBmaWx0ZXIpIHtcbiAgLy8gYXMgdGhlIFNRTCBzZXJ2ZXIgaW1wbGVtZW50YXRpb24gaXMgc3RhdGVsZXNzLCBub3RoaW5nIHRvIGRvIGhlcmVcbn1cblxuLyoqXG4gKiBUaGUgb3Bwb3NpdGUgb3IgaW5pdERhdGFGaWx0ZXIsIGl0IHNob3VsZCByZW1vdmUgdGhlIGZpbHRlciBhbmQgZGVhbGxvY2F0ZSBvdGhlciBjb25maWd1cmF0aW9uXG4gKiByZWxhdGVkIHRvIHRoZSBmaWx0ZXIuXG4gKiBAcGFyYW0ge0ZpbHRlcn0gZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHJlbGVhc2VEYXRhRmlsdGVyIChmaWx0ZXIpIHtcbiAgLy8gYXMgdGhlIFNRTCBzZXJ2ZXIgaW1wbGVtZW50YXRpb24gaXMgc3RhdGVsZXNzLCBub3RoaW5nIHRvIGRvIGhlcmVcbn1cblxuLyoqXG4gKiBDaGFuZ2UgdGhlIGZpbHRlciBwYXJhbWV0ZXJzIGZvciBhbiBpbml0aWFsaXplZCBmaWx0ZXJcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGF0YUZpbHRlciAoZmlsdGVyKSB7XG4gIC8vIGFzIHRoZSBTUUwgc2VydmVyIGltcGxlbWVudGF0aW9uIGlzIHN0YXRlbGVzcywgbm90aGluZyB0byBkbyBoZXJlXG59XG5cbi8qKlxuICogR2V0IGRhdGEgZm9yIGV2ZXJ5IGZpbHRlciwgYW5kIHRyaWdnZXIgYSAnbmV3RGF0YScgZXZlbnRcbiAqXG4gKiBSZXR1cm5zIGEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkYXRhdmlldyB3aGVuIGFsbCBkYXRhIGFuZCBtZXRhZGF0YSBoYXMgYmVlbiB1cGRhdGVkXG4gKlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEByZXR1cm5zIHtQcm9taXNlfVxuICovXG5mdW5jdGlvbiBnZXREYXRhIChkYXRhdmlldykge1xuICB2YXIgc3BvdCA9IGRhdGF2aWV3LnBhcmVudDtcblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGlmIChzcG90LmlzTG9ja2VkRG93bikge1xuICAgICAgc3BvdC5zb2NrZXQuZW1pdCgnZ2V0RGF0YScsIHtcbiAgICAgICAgZGF0YXZpZXc6IGRhdGF2aWV3LnRvSlNPTigpXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3BvdC5zb2NrZXQuZW1pdCgnZ2V0RGF0YScsIHtcbiAgICAgICAgZGF0YXNldHM6IHNwb3QuY2FjaGVkRGF0YXNldHMsXG4gICAgICAgIGRhdGF2aWV3OiBkYXRhdmlldy50b0pTT04oKVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZGF0YXZpZXcub25jZSgnbmV3TWV0YURhdGEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXNvbHZlKGRhdGF2aWV3KTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBkcml2ZXJUeXBlOiAnc2VydmVyJyxcbiAgc2Nhbjogc2NhbixcbiAgc2V0TWluTWF4OiBzZXRNaW5NYXgsXG4gIHNldENhdGVnb3JpZXM6IHNldENhdGVnb3JpZXMsXG4gIHNldFBlcmNlbnRpbGVzOiBzZXRQZXJjZW50aWxlcyxcbiAgaW5pdERhdGFGaWx0ZXI6IGluaXREYXRhRmlsdGVyLFxuICByZWxlYXNlRGF0YUZpbHRlcjogcmVsZWFzZURhdGFGaWx0ZXIsXG4gIHVwZGF0ZURhdGFGaWx0ZXI6IHVwZGF0ZURhdGFGaWx0ZXIsXG4gIGdldERhdGE6IGdldERhdGFcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///072d\n")},"09c5":function(module,exports,__webpack_require__){eval("/**\n * A single control point for a continuous transform\n *\n * @class ControlPoint\n */\nvar BaseModel = __webpack_require__(/*! ../util/base */ \"3902\");\n\n// Data structure for mapping categorial (and textual) data on groups\nmodule.exports = BaseModel.extend({\n  props: {\n    /**\n     * Value\n     * @type {number}\n     * @memberof! ContinuousRule\n     */\n    x: 'number',\n\n    /**\n     * Transformed value\n     * @type {number}\n     * @memberof! ContinuousRule\n     */\n    fx: 'number'\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDljNS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29udHJvbC1wb2ludC5qcz82OTJiIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQSBzaW5nbGUgY29udHJvbCBwb2ludCBmb3IgYSBjb250aW51b3VzIHRyYW5zZm9ybVxuICpcbiAqIEBjbGFzcyBDb250cm9sUG9pbnRcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4uL3V0aWwvYmFzZScpO1xuXG4vLyBEYXRhIHN0cnVjdHVyZSBmb3IgbWFwcGluZyBjYXRlZ29yaWFsIChhbmQgdGV4dHVhbCkgZGF0YSBvbiBncm91cHNcbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVmFsdWVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1J1bGVcbiAgICAgKi9cbiAgICB4OiAnbnVtYmVyJyxcblxuICAgIC8qKlxuICAgICAqIFRyYW5zZm9ybWVkIHZhbHVlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNSdWxlXG4gICAgICovXG4gICAgZng6ICdudW1iZXInXG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///09c5\n")},"0b10":function(module,exports){eval("/**\n * Helpers.\n */\n\nvar s = 1000\nvar m = s * 60\nvar h = m * 60\nvar d = h * 24\nvar y = d * 365.25\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function (val, options) {\n  options = options || {}\n  var type = typeof val\n  if (type === 'string' && val.length > 0) {\n    return parse(val)\n  } else if (type === 'number' && isNaN(val) === false) {\n    return options.long ?\n\t\t\tfmtLong(val) :\n\t\t\tfmtShort(val)\n  }\n  throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val))\n}\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n  str = String(str)\n  if (str.length > 10000) {\n    return\n  }\n  var match = /^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str)\n  if (!match) {\n    return\n  }\n  var n = parseFloat(match[1])\n  var type = (match[2] || 'ms').toLowerCase()\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'yrs':\n    case 'yr':\n    case 'y':\n      return n * y\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d\n    case 'hours':\n    case 'hour':\n    case 'hrs':\n    case 'hr':\n    case 'h':\n      return n * h\n    case 'minutes':\n    case 'minute':\n    case 'mins':\n    case 'min':\n    case 'm':\n      return n * m\n    case 'seconds':\n    case 'second':\n    case 'secs':\n    case 'sec':\n    case 's':\n      return n * s\n    case 'milliseconds':\n    case 'millisecond':\n    case 'msecs':\n    case 'msec':\n    case 'ms':\n      return n\n    default:\n      return undefined\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtShort(ms) {\n  if (ms >= d) {\n    return Math.round(ms / d) + 'd'\n  }\n  if (ms >= h) {\n    return Math.round(ms / h) + 'h'\n  }\n  if (ms >= m) {\n    return Math.round(ms / m) + 'm'\n  }\n  if (ms >= s) {\n    return Math.round(ms / s) + 's'\n  }\n  return ms + 'ms'\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtLong(ms) {\n  return plural(ms, d, 'day') ||\n    plural(ms, h, 'hour') ||\n    plural(ms, m, 'minute') ||\n    plural(ms, s, 'second') ||\n    ms + ' ms'\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, n, name) {\n  if (ms < n) {\n    return\n  }\n  if (ms < n * 1.5) {\n    return Math.floor(ms / n) + ' ' + name\n  }\n  return Math.ceil(ms / n) + ' ' + name + 's'\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMGIxMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvbXMvaW5kZXguanM/YjZlOCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhlbHBlcnMuXG4gKi9cblxudmFyIHMgPSAxMDAwXG52YXIgbSA9IHMgKiA2MFxudmFyIGggPSBtICogNjBcbnZhciBkID0gaCAqIDI0XG52YXIgeSA9IGQgKiAzNjUuMjVcblxuLyoqXG4gKiBQYXJzZSBvciBmb3JtYXQgdGhlIGdpdmVuIGB2YWxgLlxuICpcbiAqIE9wdGlvbnM6XG4gKlxuICogIC0gYGxvbmdgIHZlcmJvc2UgZm9ybWF0dGluZyBbZmFsc2VdXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSB2YWxcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAdGhyb3dzIHtFcnJvcn0gdGhyb3cgYW4gZXJyb3IgaWYgdmFsIGlzIG5vdCBhIG5vbi1lbXB0eSBzdHJpbmcgb3IgYSBudW1iZXJcbiAqIEByZXR1cm4ge1N0cmluZ3xOdW1iZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHZhbCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWxcbiAgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIHZhbC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHBhcnNlKHZhbClcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBpc05hTih2YWwpID09PSBmYWxzZSkge1xuICAgIHJldHVybiBvcHRpb25zLmxvbmcgP1xuXHRcdFx0Zm10TG9uZyh2YWwpIDpcblx0XHRcdGZtdFNob3J0KHZhbClcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ3ZhbCBpcyBub3QgYSBub24tZW1wdHkgc3RyaW5nIG9yIGEgdmFsaWQgbnVtYmVyLiB2YWw9JyArIEpTT04uc3RyaW5naWZ5KHZhbCkpXG59XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGBzdHJgIGFuZCByZXR1cm4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlKHN0cikge1xuICBzdHIgPSBTdHJpbmcoc3RyKVxuICBpZiAoc3RyLmxlbmd0aCA+IDEwMDAwKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIG1hdGNoID0gL14oKD86XFxkKyk/XFwuP1xcZCspICoobWlsbGlzZWNvbmRzP3xtc2Vjcz98bXN8c2Vjb25kcz98c2Vjcz98c3xtaW51dGVzP3xtaW5zP3xtfGhvdXJzP3xocnM/fGh8ZGF5cz98ZHx5ZWFycz98eXJzP3x5KT8kL2kuZXhlYyhzdHIpXG4gIGlmICghbWF0Y2gpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgbiA9IHBhcnNlRmxvYXQobWF0Y2hbMV0pXG4gIHZhciB0eXBlID0gKG1hdGNoWzJdIHx8ICdtcycpLnRvTG93ZXJDYXNlKClcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAneWVhcnMnOlxuICAgIGNhc2UgJ3llYXInOlxuICAgIGNhc2UgJ3lycyc6XG4gICAgY2FzZSAneXInOlxuICAgIGNhc2UgJ3knOlxuICAgICAgcmV0dXJuIG4gKiB5XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZFxuICAgIGNhc2UgJ2hvdXJzJzpcbiAgICBjYXNlICdob3VyJzpcbiAgICBjYXNlICdocnMnOlxuICAgIGNhc2UgJ2hyJzpcbiAgICBjYXNlICdoJzpcbiAgICAgIHJldHVybiBuICogaFxuICAgIGNhc2UgJ21pbnV0ZXMnOlxuICAgIGNhc2UgJ21pbnV0ZSc6XG4gICAgY2FzZSAnbWlucyc6XG4gICAgY2FzZSAnbWluJzpcbiAgICBjYXNlICdtJzpcbiAgICAgIHJldHVybiBuICogbVxuICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgY2FzZSAnc2Vjcyc6XG4gICAgY2FzZSAnc2VjJzpcbiAgICBjYXNlICdzJzpcbiAgICAgIHJldHVybiBuICogc1xuICAgIGNhc2UgJ21pbGxpc2Vjb25kcyc6XG4gICAgY2FzZSAnbWlsbGlzZWNvbmQnOlxuICAgIGNhc2UgJ21zZWNzJzpcbiAgICBjYXNlICdtc2VjJzpcbiAgICBjYXNlICdtcyc6XG4gICAgICByZXR1cm4gblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuLyoqXG4gKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBmbXRTaG9ydChtcykge1xuICBpZiAobXMgPj0gZCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gZCkgKyAnZCdcbiAgfVxuICBpZiAobXMgPj0gaCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gaCkgKyAnaCdcbiAgfVxuICBpZiAobXMgPj0gbSkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gbSkgKyAnbSdcbiAgfVxuICBpZiAobXMgPj0gcykge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gcykgKyAncydcbiAgfVxuICByZXR1cm4gbXMgKyAnbXMnXG59XG5cbi8qKlxuICogTG9uZyBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBmbXRMb25nKG1zKSB7XG4gIHJldHVybiBwbHVyYWwobXMsIGQsICdkYXknKSB8fFxuICAgIHBsdXJhbChtcywgaCwgJ2hvdXInKSB8fFxuICAgIHBsdXJhbChtcywgbSwgJ21pbnV0ZScpIHx8XG4gICAgcGx1cmFsKG1zLCBzLCAnc2Vjb25kJykgfHxcbiAgICBtcyArICcgbXMnXG59XG5cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi9cblxuZnVuY3Rpb24gcGx1cmFsKG1zLCBuLCBuYW1lKSB7XG4gIGlmIChtcyA8IG4pIHtcbiAgICByZXR1cm5cbiAgfVxuICBpZiAobXMgPCBuICogMS41KSB7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IobXMgLyBuKSArICcgJyArIG5hbWVcbiAgfVxuICByZXR1cm4gTWF0aC5jZWlsKG1zIC8gbikgKyAnICcgKyBuYW1lICsgJ3MnXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0b10\n")},"0d97":function(module,exports,__webpack_require__){eval("/**\n * Module dependencies.\n */\n\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = Transport;\n\n/**\n * Transport abstract constructor.\n *\n * @param {Object} options.\n * @api private\n */\n\nfunction Transport (opts) {\n  this.path = opts.path;\n  this.hostname = opts.hostname;\n  this.port = opts.port;\n  this.secure = opts.secure;\n  this.query = opts.query;\n  this.timestampParam = opts.timestampParam;\n  this.timestampRequests = opts.timestampRequests;\n  this.readyState = '';\n  this.agent = opts.agent || false;\n  this.socket = opts.socket;\n  this.enablesXDR = opts.enablesXDR;\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx;\n  this.key = opts.key;\n  this.passphrase = opts.passphrase;\n  this.cert = opts.cert;\n  this.ca = opts.ca;\n  this.ciphers = opts.ciphers;\n  this.rejectUnauthorized = opts.rejectUnauthorized;\n  this.forceNode = opts.forceNode;\n\n  // other options for Node.js client\n  this.extraHeaders = opts.extraHeaders;\n  this.localAddress = opts.localAddress;\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Transport.prototype);\n\n/**\n * Emits an error.\n *\n * @param {String} str\n * @return {Transport} for chaining\n * @api public\n */\n\nTransport.prototype.onError = function (msg, desc) {\n  var err = new Error(msg);\n  err.type = 'TransportError';\n  err.description = desc;\n  this.emit('error', err);\n  return this;\n};\n\n/**\n * Opens the transport.\n *\n * @api public\n */\n\nTransport.prototype.open = function () {\n  if ('closed' === this.readyState || '' === this.readyState) {\n    this.readyState = 'opening';\n    this.doOpen();\n  }\n\n  return this;\n};\n\n/**\n * Closes the transport.\n *\n * @api private\n */\n\nTransport.prototype.close = function () {\n  if ('opening' === this.readyState || 'open' === this.readyState) {\n    this.doClose();\n    this.onClose();\n  }\n\n  return this;\n};\n\n/**\n * Sends multiple packets.\n *\n * @param {Array} packets\n * @api private\n */\n\nTransport.prototype.send = function (packets) {\n  if ('open' === this.readyState) {\n    this.write(packets);\n  } else {\n    throw new Error('Transport not open');\n  }\n};\n\n/**\n * Called upon open\n *\n * @api private\n */\n\nTransport.prototype.onOpen = function () {\n  this.readyState = 'open';\n  this.writable = true;\n  this.emit('open');\n};\n\n/**\n * Called with data.\n *\n * @param {String} data\n * @api private\n */\n\nTransport.prototype.onData = function (data) {\n  var packet = parser.decodePacket(data, this.socket.binaryType);\n  this.onPacket(packet);\n};\n\n/**\n * Called with a decoded packet.\n */\n\nTransport.prototype.onPacket = function (packet) {\n  this.emit('packet', packet);\n};\n\n/**\n * Called upon close.\n *\n * @api private\n */\n\nTransport.prototype.onClose = function () {\n  this.readyState = 'closed';\n  this.emit('close');\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMGQ5Ny5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0LmpzPzMxMmIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBwYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc3BvcnQ7XG5cbi8qKlxuICogVHJhbnNwb3J0IGFic3RyYWN0IGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gVHJhbnNwb3J0IChvcHRzKSB7XG4gIHRoaXMucGF0aCA9IG9wdHMucGF0aDtcbiAgdGhpcy5ob3N0bmFtZSA9IG9wdHMuaG9zdG5hbWU7XG4gIHRoaXMucG9ydCA9IG9wdHMucG9ydDtcbiAgdGhpcy5zZWN1cmUgPSBvcHRzLnNlY3VyZTtcbiAgdGhpcy5xdWVyeSA9IG9wdHMucXVlcnk7XG4gIHRoaXMudGltZXN0YW1wUGFyYW0gPSBvcHRzLnRpbWVzdGFtcFBhcmFtO1xuICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50IHx8IGZhbHNlO1xuICB0aGlzLnNvY2tldCA9IG9wdHMuc29ja2V0O1xuICB0aGlzLmVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG5cbiAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIHRoaXMucGZ4ID0gb3B0cy5wZng7XG4gIHRoaXMua2V5ID0gb3B0cy5rZXk7XG4gIHRoaXMucGFzc3BocmFzZSA9IG9wdHMucGFzc3BocmFzZTtcbiAgdGhpcy5jZXJ0ID0gb3B0cy5jZXJ0O1xuICB0aGlzLmNhID0gb3B0cy5jYTtcbiAgdGhpcy5jaXBoZXJzID0gb3B0cy5jaXBoZXJzO1xuICB0aGlzLnJlamVjdFVuYXV0aG9yaXplZCA9IG9wdHMucmVqZWN0VW5hdXRob3JpemVkO1xuICB0aGlzLmZvcmNlTm9kZSA9IG9wdHMuZm9yY2VOb2RlO1xuXG4gIC8vIG90aGVyIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIHRoaXMuZXh0cmFIZWFkZXJzID0gb3B0cy5leHRyYUhlYWRlcnM7XG4gIHRoaXMubG9jYWxBZGRyZXNzID0gb3B0cy5sb2NhbEFkZHJlc3M7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFRyYW5zcG9ydC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIEVtaXRzIGFuIGVycm9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge1RyYW5zcG9ydH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uIChtc2csIGRlc2MpIHtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcihtc2cpO1xuICBlcnIudHlwZSA9ICdUcmFuc3BvcnRFcnJvcic7XG4gIGVyci5kZXNjcmlwdGlvbiA9IGRlc2M7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3BlbnMgdGhlIHRyYW5zcG9ydC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCdjbG9zZWQnID09PSB0aGlzLnJlYWR5U3RhdGUgfHwgJycgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcbiAgICB0aGlzLmRvT3BlbigpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENsb3NlcyB0aGUgdHJhbnNwb3J0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMuZG9DbG9zZSgpO1xuICAgIHRoaXMub25DbG9zZSgpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIG11bHRpcGxlIHBhY2tldHMuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFja2V0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuVHJhbnNwb3J0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKHBhY2tldHMpIHtcbiAgaWYgKCdvcGVuJyA9PT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgdGhpcy53cml0ZShwYWNrZXRzKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zcG9ydCBub3Qgb3BlbicpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIG9wZW5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW4nO1xuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcbiAgdGhpcy5lbWl0KCdvcGVuJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIGRhdGEuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGFcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdmFyIHBhY2tldCA9IHBhcnNlci5kZWNvZGVQYWNrZXQoZGF0YSwgdGhpcy5zb2NrZXQuYmluYXJ5VHlwZSk7XG4gIHRoaXMub25QYWNrZXQocGFja2V0KTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHdpdGggYSBkZWNvZGVkIHBhY2tldC5cbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uUGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICB0aGlzLmVtaXQoJ3BhY2tldCcsIHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGNsb3NlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0d97\n")},"108d":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module requirements.\n */\n\nvar XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ \"86e3\");\nvar Polling = __webpack_require__(/*! ./polling */ \"181d\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:polling-xhr');\n\n/**\n * Module exports.\n */\n\nmodule.exports = XHR;\nmodule.exports.Request = Request;\n\n/**\n * Empty function\n */\n\nfunction empty () {}\n\n/**\n * XHR Polling constructor.\n *\n * @param {Object} opts\n * @api public\n */\n\nfunction XHR (opts) {\n  Polling.call(this, opts);\n  this.requestTimeout = opts.requestTimeout;\n\n  if (global.location) {\n    var isSSL = 'https:' === location.protocol;\n    var port = location.port;\n\n    // some user agents have empty `location.port`\n    if (!port) {\n      port = isSSL ? 443 : 80;\n    }\n\n    this.xd = opts.hostname !== global.location.hostname ||\n      port !== opts.port;\n    this.xs = opts.secure !== isSSL;\n  } else {\n    this.extraHeaders = opts.extraHeaders;\n  }\n}\n\n/**\n * Inherits from Polling.\n */\n\ninherit(XHR, Polling);\n\n/**\n * XHR supports binary\n */\n\nXHR.prototype.supportsBinary = true;\n\n/**\n * Creates a request.\n *\n * @param {String} method\n * @api private\n */\n\nXHR.prototype.request = function (opts) {\n  opts = opts || {};\n  opts.uri = this.uri();\n  opts.xd = this.xd;\n  opts.xs = this.xs;\n  opts.agent = this.agent || false;\n  opts.supportsBinary = this.supportsBinary;\n  opts.enablesXDR = this.enablesXDR;\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n  opts.requestTimeout = this.requestTimeout;\n\n  // other options for Node.js client\n  opts.extraHeaders = this.extraHeaders;\n\n  return new Request(opts);\n};\n\n/**\n * Sends data.\n *\n * @param {String} data to send.\n * @param {Function} called upon flush.\n * @api private\n */\n\nXHR.prototype.doWrite = function (data, fn) {\n  var isBinary = typeof data !== 'string' && data !== undefined;\n  var req = this.request({ method: 'POST', data: data, isBinary: isBinary });\n  var self = this;\n  req.on('success', fn);\n  req.on('error', function (err) {\n    self.onError('xhr post error', err);\n  });\n  this.sendXhr = req;\n};\n\n/**\n * Starts a poll cycle.\n *\n * @api private\n */\n\nXHR.prototype.doPoll = function () {\n  debug('xhr poll');\n  var req = this.request();\n  var self = this;\n  req.on('data', function (data) {\n    self.onData(data);\n  });\n  req.on('error', function (err) {\n    self.onError('xhr poll error', err);\n  });\n  this.pollXhr = req;\n};\n\n/**\n * Request constructor\n *\n * @param {Object} options\n * @api public\n */\n\nfunction Request (opts) {\n  this.method = opts.method || 'GET';\n  this.uri = opts.uri;\n  this.xd = !!opts.xd;\n  this.xs = !!opts.xs;\n  this.async = false !== opts.async;\n  this.data = undefined !== opts.data ? opts.data : null;\n  this.agent = opts.agent;\n  this.isBinary = opts.isBinary;\n  this.supportsBinary = opts.supportsBinary;\n  this.enablesXDR = opts.enablesXDR;\n  this.requestTimeout = opts.requestTimeout;\n\n  // SSL options for Node.js client\n  this.pfx = opts.pfx;\n  this.key = opts.key;\n  this.passphrase = opts.passphrase;\n  this.cert = opts.cert;\n  this.ca = opts.ca;\n  this.ciphers = opts.ciphers;\n  this.rejectUnauthorized = opts.rejectUnauthorized;\n\n  // other options for Node.js client\n  this.extraHeaders = opts.extraHeaders;\n\n  this.create();\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Request.prototype);\n\n/**\n * Creates the XHR object and sends the request.\n *\n * @api private\n */\n\nRequest.prototype.create = function () {\n  var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR };\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n\n  var xhr = this.xhr = new XMLHttpRequest(opts);\n  var self = this;\n\n  try {\n    debug('xhr open %s: %s', this.method, this.uri);\n    xhr.open(this.method, this.uri, this.async);\n    try {\n      if (this.extraHeaders) {\n        xhr.setDisableHeaderCheck(true);\n        for (var i in this.extraHeaders) {\n          if (this.extraHeaders.hasOwnProperty(i)) {\n            xhr.setRequestHeader(i, this.extraHeaders[i]);\n          }\n        }\n      }\n    } catch (e) {}\n    if (this.supportsBinary) {\n      // This has to be done after open because Firefox is stupid\n      // http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension\n      xhr.responseType = 'arraybuffer';\n    }\n\n    if ('POST' === this.method) {\n      try {\n        if (this.isBinary) {\n          xhr.setRequestHeader('Content-type', 'application/octet-stream');\n        } else {\n          xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');\n        }\n      } catch (e) {}\n    }\n\n    try {\n      xhr.setRequestHeader('Accept', '*/*');\n    } catch (e) {}\n\n    // ie6 check\n    if ('withCredentials' in xhr) {\n      xhr.withCredentials = true;\n    }\n\n    if (this.requestTimeout) {\n      xhr.timeout = this.requestTimeout;\n    }\n\n    if (this.hasXDR()) {\n      xhr.onload = function () {\n        self.onLoad();\n      };\n      xhr.onerror = function () {\n        self.onError(xhr.responseText);\n      };\n    } else {\n      xhr.onreadystatechange = function () {\n        if (4 !== xhr.readyState) return;\n        if (200 === xhr.status || 1223 === xhr.status) {\n          self.onLoad();\n        } else {\n          // make sure the `error` event handler that's user-set\n          // does not throw in the same tick and gets caught here\n          setTimeout(function () {\n            self.onError(xhr.status);\n          }, 0);\n        }\n      };\n    }\n\n    debug('xhr data %s', this.data);\n    xhr.send(this.data);\n  } catch (e) {\n    // Need to defer since .create() is called directly fhrom the constructor\n    // and thus the 'error' event can only be only bound *after* this exception\n    // occurs.  Therefore, also, we cannot throw here at all.\n    setTimeout(function () {\n      self.onError(e);\n    }, 0);\n    return;\n  }\n\n  if (global.document) {\n    this.index = Request.requestsCount++;\n    Request.requests[this.index] = this;\n  }\n};\n\n/**\n * Called upon successful response.\n *\n * @api private\n */\n\nRequest.prototype.onSuccess = function () {\n  this.emit('success');\n  this.cleanup();\n};\n\n/**\n * Called if we have data.\n *\n * @api private\n */\n\nRequest.prototype.onData = function (data) {\n  this.emit('data', data);\n  this.onSuccess();\n};\n\n/**\n * Called upon error.\n *\n * @api private\n */\n\nRequest.prototype.onError = function (err) {\n  this.emit('error', err);\n  this.cleanup(true);\n};\n\n/**\n * Cleans up house.\n *\n * @api private\n */\n\nRequest.prototype.cleanup = function (fromError) {\n  if ('undefined' === typeof this.xhr || null === this.xhr) {\n    return;\n  }\n  // xmlhttprequest\n  if (this.hasXDR()) {\n    this.xhr.onload = this.xhr.onerror = empty;\n  } else {\n    this.xhr.onreadystatechange = empty;\n  }\n\n  if (fromError) {\n    try {\n      this.xhr.abort();\n    } catch (e) {}\n  }\n\n  if (global.document) {\n    delete Request.requests[this.index];\n  }\n\n  this.xhr = null;\n};\n\n/**\n * Called upon load.\n *\n * @api private\n */\n\nRequest.prototype.onLoad = function () {\n  var data;\n  try {\n    var contentType;\n    try {\n      contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0];\n    } catch (e) {}\n    if (contentType === 'application/octet-stream') {\n      data = this.xhr.response || this.xhr.responseText;\n    } else {\n      if (!this.supportsBinary) {\n        data = this.xhr.responseText;\n      } else {\n        try {\n          data = String.fromCharCode.apply(null, new Uint8Array(this.xhr.response));\n        } catch (e) {\n          var ui8Arr = new Uint8Array(this.xhr.response);\n          var dataArray = [];\n          for (var idx = 0, length = ui8Arr.length; idx < length; idx++) {\n            dataArray.push(ui8Arr[idx]);\n          }\n\n          data = String.fromCharCode.apply(null, dataArray);\n        }\n      }\n    }\n  } catch (e) {\n    this.onError(e);\n  }\n  if (null != data) {\n    this.onData(data);\n  }\n};\n\n/**\n * Check if it has XDomainRequest.\n *\n * @api private\n */\n\nRequest.prototype.hasXDR = function () {\n  return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR;\n};\n\n/**\n * Aborts the request.\n *\n * @api public\n */\n\nRequest.prototype.abort = function () {\n  this.cleanup();\n};\n\n/**\n * Aborts pending requests when unloading the window. This is needed to prevent\n * memory leaks (e.g. when using IE) and to ensure that no spurious error is\n * emitted.\n */\n\nRequest.requestsCount = 0;\nRequest.requests = {};\n\nif (global.document) {\n  if (global.attachEvent) {\n    global.attachEvent('onunload', unloadHandler);\n  } else if (global.addEventListener) {\n    global.addEventListener('beforeunload', unloadHandler, false);\n  }\n}\n\nfunction unloadHandler () {\n  for (var i in Request.requests) {\n    if (Request.requests.hasOwnProperty(i)) {\n      Request.requests[i].abort();\n    }\n  }\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA4ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLXhoci5qcz9mYmY3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAqL1xuXG52YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdC1zc2wnKTtcbnZhciBQb2xsaW5nID0gcmVxdWlyZSgnLi9wb2xsaW5nJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgaW5oZXJpdCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1pbmhlcml0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnBvbGxpbmcteGhyJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBYSFI7XG5tb2R1bGUuZXhwb3J0cy5SZXF1ZXN0ID0gUmVxdWVzdDtcblxuLyoqXG4gKiBFbXB0eSBmdW5jdGlvblxuICovXG5cbmZ1bmN0aW9uIGVtcHR5ICgpIHt9XG5cbi8qKlxuICogWEhSIFBvbGxpbmcgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gWEhSIChvcHRzKSB7XG4gIFBvbGxpbmcuY2FsbCh0aGlzLCBvcHRzKTtcbiAgdGhpcy5yZXF1ZXN0VGltZW91dCA9IG9wdHMucmVxdWVzdFRpbWVvdXQ7XG5cbiAgaWYgKGdsb2JhbC5sb2NhdGlvbikge1xuICAgIHZhciBpc1NTTCA9ICdodHRwczonID09PSBsb2NhdGlvbi5wcm90b2NvbDtcbiAgICB2YXIgcG9ydCA9IGxvY2F0aW9uLnBvcnQ7XG5cbiAgICAvLyBzb21lIHVzZXIgYWdlbnRzIGhhdmUgZW1wdHkgYGxvY2F0aW9uLnBvcnRgXG4gICAgaWYgKCFwb3J0KSB7XG4gICAgICBwb3J0ID0gaXNTU0wgPyA0NDMgOiA4MDtcbiAgICB9XG5cbiAgICB0aGlzLnhkID0gb3B0cy5ob3N0bmFtZSAhPT0gZ2xvYmFsLmxvY2F0aW9uLmhvc3RuYW1lIHx8XG4gICAgICBwb3J0ICE9PSBvcHRzLnBvcnQ7XG4gICAgdGhpcy54cyA9IG9wdHMuc2VjdXJlICE9PSBpc1NTTDtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuICB9XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBQb2xsaW5nLlxuICovXG5cbmluaGVyaXQoWEhSLCBQb2xsaW5nKTtcblxuLyoqXG4gKiBYSFIgc3VwcG9ydHMgYmluYXJ5XG4gKi9cblxuWEhSLnByb3RvdHlwZS5zdXBwb3J0c0JpbmFyeSA9IHRydWU7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHJlcXVlc3QuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuWEhSLnByb3RvdHlwZS5yZXF1ZXN0ID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgb3B0cyA9IG9wdHMgfHwge307XG4gIG9wdHMudXJpID0gdGhpcy51cmkoKTtcbiAgb3B0cy54ZCA9IHRoaXMueGQ7XG4gIG9wdHMueHMgPSB0aGlzLnhzO1xuICBvcHRzLmFnZW50ID0gdGhpcy5hZ2VudCB8fCBmYWxzZTtcbiAgb3B0cy5zdXBwb3J0c0JpbmFyeSA9IHRoaXMuc3VwcG9ydHNCaW5hcnk7XG4gIG9wdHMuZW5hYmxlc1hEUiA9IHRoaXMuZW5hYmxlc1hEUjtcblxuICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgb3B0cy5wZnggPSB0aGlzLnBmeDtcbiAgb3B0cy5rZXkgPSB0aGlzLmtleTtcbiAgb3B0cy5wYXNzcGhyYXNlID0gdGhpcy5wYXNzcGhyYXNlO1xuICBvcHRzLmNlcnQgPSB0aGlzLmNlcnQ7XG4gIG9wdHMuY2EgPSB0aGlzLmNhO1xuICBvcHRzLmNpcGhlcnMgPSB0aGlzLmNpcGhlcnM7XG4gIG9wdHMucmVqZWN0VW5hdXRob3JpemVkID0gdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQ7XG4gIG9wdHMucmVxdWVzdFRpbWVvdXQgPSB0aGlzLnJlcXVlc3RUaW1lb3V0O1xuXG4gIC8vIG90aGVyIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIG9wdHMuZXh0cmFIZWFkZXJzID0gdGhpcy5leHRyYUhlYWRlcnM7XG5cbiAgcmV0dXJuIG5ldyBSZXF1ZXN0KG9wdHMpO1xufTtcblxuLyoqXG4gKiBTZW5kcyBkYXRhLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIHRvIHNlbmQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblhIUi5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uIChkYXRhLCBmbikge1xuICB2YXIgaXNCaW5hcnkgPSB0eXBlb2YgZGF0YSAhPT0gJ3N0cmluZycgJiYgZGF0YSAhPT0gdW5kZWZpbmVkO1xuICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KHsgbWV0aG9kOiAnUE9TVCcsIGRhdGE6IGRhdGEsIGlzQmluYXJ5OiBpc0JpbmFyeSB9KTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICByZXEub24oJ3N1Y2Nlc3MnLCBmbik7XG4gIHJlcS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgc2VsZi5vbkVycm9yKCd4aHIgcG9zdCBlcnJvcicsIGVycik7XG4gIH0pO1xuICB0aGlzLnNlbmRYaHIgPSByZXE7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuWEhSLnByb3RvdHlwZS5kb1BvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCd4aHIgcG9sbCcpO1xuICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KCk7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgcmVxLm9uKCdkYXRhJywgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBzZWxmLm9uRGF0YShkYXRhKTtcbiAgfSk7XG4gIHJlcS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgc2VsZi5vbkVycm9yKCd4aHIgcG9sbCBlcnJvcicsIGVycik7XG4gIH0pO1xuICB0aGlzLnBvbGxYaHIgPSByZXE7XG59O1xuXG4vKipcbiAqIFJlcXVlc3QgY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0IChvcHRzKSB7XG4gIHRoaXMubWV0aG9kID0gb3B0cy5tZXRob2QgfHwgJ0dFVCc7XG4gIHRoaXMudXJpID0gb3B0cy51cmk7XG4gIHRoaXMueGQgPSAhIW9wdHMueGQ7XG4gIHRoaXMueHMgPSAhIW9wdHMueHM7XG4gIHRoaXMuYXN5bmMgPSBmYWxzZSAhPT0gb3B0cy5hc3luYztcbiAgdGhpcy5kYXRhID0gdW5kZWZpbmVkICE9PSBvcHRzLmRhdGEgPyBvcHRzLmRhdGEgOiBudWxsO1xuICB0aGlzLmFnZW50ID0gb3B0cy5hZ2VudDtcbiAgdGhpcy5pc0JpbmFyeSA9IG9wdHMuaXNCaW5hcnk7XG4gIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSBvcHRzLnN1cHBvcnRzQmluYXJ5O1xuICB0aGlzLmVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG4gIHRoaXMucmVxdWVzdFRpbWVvdXQgPSBvcHRzLnJlcXVlc3RUaW1lb3V0O1xuXG4gIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLnBmeCA9IG9wdHMucGZ4O1xuICB0aGlzLmtleSA9IG9wdHMua2V5O1xuICB0aGlzLnBhc3NwaHJhc2UgPSBvcHRzLnBhc3NwaHJhc2U7XG4gIHRoaXMuY2VydCA9IG9wdHMuY2VydDtcbiAgdGhpcy5jYSA9IG9wdHMuY2E7XG4gIHRoaXMuY2lwaGVycyA9IG9wdHMuY2lwaGVycztcbiAgdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQgPSBvcHRzLnJlamVjdFVuYXV0aG9yaXplZDtcblxuICAvLyBvdGhlciBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuXG4gIHRoaXMuY3JlYXRlKCk7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFJlcXVlc3QucHJvdG90eXBlKTtcblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBYSFIgb2JqZWN0IGFuZCBzZW5kcyB0aGUgcmVxdWVzdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBvcHRzID0geyBhZ2VudDogdGhpcy5hZ2VudCwgeGRvbWFpbjogdGhpcy54ZCwgeHNjaGVtZTogdGhpcy54cywgZW5hYmxlc1hEUjogdGhpcy5lbmFibGVzWERSIH07XG5cbiAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIG9wdHMucGZ4ID0gdGhpcy5wZng7XG4gIG9wdHMua2V5ID0gdGhpcy5rZXk7XG4gIG9wdHMucGFzc3BocmFzZSA9IHRoaXMucGFzc3BocmFzZTtcbiAgb3B0cy5jZXJ0ID0gdGhpcy5jZXJ0O1xuICBvcHRzLmNhID0gdGhpcy5jYTtcbiAgb3B0cy5jaXBoZXJzID0gdGhpcy5jaXBoZXJzO1xuICBvcHRzLnJlamVjdFVuYXV0aG9yaXplZCA9IHRoaXMucmVqZWN0VW5hdXRob3JpemVkO1xuXG4gIHZhciB4aHIgPSB0aGlzLnhociA9IG5ldyBYTUxIdHRwUmVxdWVzdChvcHRzKTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRyeSB7XG4gICAgZGVidWcoJ3hociBvcGVuICVzOiAlcycsIHRoaXMubWV0aG9kLCB0aGlzLnVyaSk7XG4gICAgeGhyLm9wZW4odGhpcy5tZXRob2QsIHRoaXMudXJpLCB0aGlzLmFzeW5jKTtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuZXh0cmFIZWFkZXJzKSB7XG4gICAgICAgIHhoci5zZXREaXNhYmxlSGVhZGVyQ2hlY2sodHJ1ZSk7XG4gICAgICAgIGZvciAodmFyIGkgaW4gdGhpcy5leHRyYUhlYWRlcnMpIHtcbiAgICAgICAgICBpZiAodGhpcy5leHRyYUhlYWRlcnMuaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGksIHRoaXMuZXh0cmFIZWFkZXJzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIGlmICh0aGlzLnN1cHBvcnRzQmluYXJ5KSB7XG4gICAgICAvLyBUaGlzIGhhcyB0byBiZSBkb25lIGFmdGVyIG9wZW4gYmVjYXVzZSBGaXJlZm94IGlzIHN0dXBpZFxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMzIxNjkwMy9nZXQtYmluYXJ5LWRhdGEtd2l0aC14bWxodHRwcmVxdWVzdC1pbi1hLWZpcmVmb3gtZXh0ZW5zaW9uXG4gICAgICB4aHIucmVzcG9uc2VUeXBlID0gJ2FycmF5YnVmZmVyJztcbiAgICB9XG5cbiAgICBpZiAoJ1BPU1QnID09PSB0aGlzLm1ldGhvZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHRoaXMuaXNCaW5hcnkpIHtcbiAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdBY2NlcHQnLCAnKi8qJyk7XG4gICAgfSBjYXRjaCAoZSkge31cblxuICAgIC8vIGllNiBjaGVja1xuICAgIGlmICgnd2l0aENyZWRlbnRpYWxzJyBpbiB4aHIpIHtcbiAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnJlcXVlc3RUaW1lb3V0KSB7XG4gICAgICB4aHIudGltZW91dCA9IHRoaXMucmVxdWVzdFRpbWVvdXQ7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaGFzWERSKCkpIHtcbiAgICAgIHhoci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYub25Mb2FkKCk7XG4gICAgICB9O1xuICAgICAgeGhyLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYub25FcnJvcih4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICg0ICE9PSB4aHIucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICBpZiAoMjAwID09PSB4aHIuc3RhdHVzIHx8IDEyMjMgPT09IHhoci5zdGF0dXMpIHtcbiAgICAgICAgICBzZWxmLm9uTG9hZCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgYGVycm9yYCBldmVudCBoYW5kbGVyIHRoYXQncyB1c2VyLXNldFxuICAgICAgICAgIC8vIGRvZXMgbm90IHRocm93IGluIHRoZSBzYW1lIHRpY2sgYW5kIGdldHMgY2F1Z2h0IGhlcmVcbiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNlbGYub25FcnJvcih4aHIuc3RhdHVzKTtcbiAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBkZWJ1ZygneGhyIGRhdGEgJXMnLCB0aGlzLmRhdGEpO1xuICAgIHhoci5zZW5kKHRoaXMuZGF0YSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBOZWVkIHRvIGRlZmVyIHNpbmNlIC5jcmVhdGUoKSBpcyBjYWxsZWQgZGlyZWN0bHkgZmhyb20gdGhlIGNvbnN0cnVjdG9yXG4gICAgLy8gYW5kIHRodXMgdGhlICdlcnJvcicgZXZlbnQgY2FuIG9ubHkgYmUgb25seSBib3VuZCAqYWZ0ZXIqIHRoaXMgZXhjZXB0aW9uXG4gICAgLy8gb2NjdXJzLiAgVGhlcmVmb3JlLCBhbHNvLCB3ZSBjYW5ub3QgdGhyb3cgaGVyZSBhdCBhbGwuXG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBzZWxmLm9uRXJyb3IoZSk7XG4gICAgfSwgMCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGdsb2JhbC5kb2N1bWVudCkge1xuICAgIHRoaXMuaW5kZXggPSBSZXF1ZXN0LnJlcXVlc3RzQ291bnQrKztcbiAgICBSZXF1ZXN0LnJlcXVlc3RzW3RoaXMuaW5kZXhdID0gdGhpcztcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzdWNjZXNzZnVsIHJlc3BvbnNlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLm9uU3VjY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0KCdzdWNjZXNzJyk7XG4gIHRoaXMuY2xlYW51cCgpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgaWYgd2UgaGF2ZSBkYXRhLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuZW1pdCgnZGF0YScsIGRhdGEpO1xuICB0aGlzLm9uU3VjY2VzcygpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKGVycikge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5jbGVhbnVwKHRydWUpO1xufTtcblxuLyoqXG4gKiBDbGVhbnMgdXAgaG91c2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuY2xlYW51cCA9IGZ1bmN0aW9uIChmcm9tRXJyb3IpIHtcbiAgaWYgKCd1bmRlZmluZWQnID09PSB0eXBlb2YgdGhpcy54aHIgfHwgbnVsbCA9PT0gdGhpcy54aHIpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8geG1saHR0cHJlcXVlc3RcbiAgaWYgKHRoaXMuaGFzWERSKCkpIHtcbiAgICB0aGlzLnhoci5vbmxvYWQgPSB0aGlzLnhoci5vbmVycm9yID0gZW1wdHk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZW1wdHk7XG4gIH1cblxuICBpZiAoZnJvbUVycm9yKSB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMueGhyLmFib3J0KCk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfVxuXG4gIGlmIChnbG9iYWwuZG9jdW1lbnQpIHtcbiAgICBkZWxldGUgUmVxdWVzdC5yZXF1ZXN0c1t0aGlzLmluZGV4XTtcbiAgfVxuXG4gIHRoaXMueGhyID0gbnVsbDtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gbG9hZC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vbkxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBkYXRhO1xuICB0cnkge1xuICAgIHZhciBjb250ZW50VHlwZTtcbiAgICB0cnkge1xuICAgICAgY29udGVudFR5cGUgPSB0aGlzLnhoci5nZXRSZXNwb25zZUhlYWRlcignQ29udGVudC1UeXBlJykuc3BsaXQoJzsnKVswXTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIGlmIChjb250ZW50VHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpIHtcbiAgICAgIGRhdGEgPSB0aGlzLnhoci5yZXNwb25zZSB8fCB0aGlzLnhoci5yZXNwb25zZVRleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy5zdXBwb3J0c0JpbmFyeSkge1xuICAgICAgICBkYXRhID0gdGhpcy54aHIucmVzcG9uc2VUZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDhBcnJheSh0aGlzLnhoci5yZXNwb25zZSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdmFyIHVpOEFyciA9IG5ldyBVaW50OEFycmF5KHRoaXMueGhyLnJlc3BvbnNlKTtcbiAgICAgICAgICB2YXIgZGF0YUFycmF5ID0gW107XG4gICAgICAgICAgZm9yICh2YXIgaWR4ID0gMCwgbGVuZ3RoID0gdWk4QXJyLmxlbmd0aDsgaWR4IDwgbGVuZ3RoOyBpZHgrKykge1xuICAgICAgICAgICAgZGF0YUFycmF5LnB1c2godWk4QXJyW2lkeF0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGRhdGFBcnJheSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aGlzLm9uRXJyb3IoZSk7XG4gIH1cbiAgaWYgKG51bGwgIT0gZGF0YSkge1xuICAgIHRoaXMub25EYXRhKGRhdGEpO1xuICB9XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIGl0IGhhcyBYRG9tYWluUmVxdWVzdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5oYXNYRFIgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGdsb2JhbC5YRG9tYWluUmVxdWVzdCAmJiAhdGhpcy54cyAmJiB0aGlzLmVuYWJsZXNYRFI7XG59O1xuXG4vKipcbiAqIEFib3J0cyB0aGUgcmVxdWVzdC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmFib3J0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmNsZWFudXAoKTtcbn07XG5cbi8qKlxuICogQWJvcnRzIHBlbmRpbmcgcmVxdWVzdHMgd2hlbiB1bmxvYWRpbmcgdGhlIHdpbmRvdy4gVGhpcyBpcyBuZWVkZWQgdG8gcHJldmVudFxuICogbWVtb3J5IGxlYWtzIChlLmcuIHdoZW4gdXNpbmcgSUUpIGFuZCB0byBlbnN1cmUgdGhhdCBubyBzcHVyaW91cyBlcnJvciBpc1xuICogZW1pdHRlZC5cbiAqL1xuXG5SZXF1ZXN0LnJlcXVlc3RzQ291bnQgPSAwO1xuUmVxdWVzdC5yZXF1ZXN0cyA9IHt9O1xuXG5pZiAoZ2xvYmFsLmRvY3VtZW50KSB7XG4gIGlmIChnbG9iYWwuYXR0YWNoRXZlbnQpIHtcbiAgICBnbG9iYWwuYXR0YWNoRXZlbnQoJ29udW5sb2FkJywgdW5sb2FkSGFuZGxlcik7XG4gIH0gZWxzZSBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgdW5sb2FkSGFuZGxlciwgZmFsc2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVubG9hZEhhbmRsZXIgKCkge1xuICBmb3IgKHZhciBpIGluIFJlcXVlc3QucmVxdWVzdHMpIHtcbiAgICBpZiAoUmVxdWVzdC5yZXF1ZXN0cy5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgUmVxdWVzdC5yZXF1ZXN0c1tpXS5hYm9ydCgpO1xuICAgIH1cbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///108d\n")},1278:function(module,exports,__webpack_require__){eval("/**\n * Selection\n * @module client/util-selection\n */\nvar misval = __webpack_require__(/*! ./misval */ \"bff6\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\n/*\n * Set a categorial 1D filter function\n * @param {Partition} partition\n */\nfunction filterFunctionCategorial1D (partition) {\n  var haystack = {};\n\n  if (!partition.selected || !partition.selected.length) {\n    partition.groups.forEach(function (group) {\n      haystack[group.value] = true;\n    });\n  } else {\n    partition.selected.forEach(function (h) {\n      haystack[h] = true;\n    });\n  }\n\n  return function (d) {\n    var needle = d;\n    if (!(needle instanceof Array)) {\n      needle = [d];\n    }\n\n    var selected = false;\n    needle.forEach(function (s) {\n      selected = selected | haystack[s];\n    });\n    return !!selected;\n  };\n}\n\n/*\n * Set a text filter function\n * @param {Partition} partition\n */\nfunction filterFunctionText (partition) {\n  var haystack = {};\n\n  // nothing selected, so all selected\n  if (partition.selected.length === 0) {\n    return function () {\n      return true;\n    };\n  }\n\n  partition.selected.forEach(function (h) {\n    haystack[h] = true;\n  });\n\n  return function (d) {\n    var needle = d;\n    if (!(needle instanceof Array)) {\n      needle = [d];\n    }\n\n    var selected = false;\n    needle.forEach(function (s) {\n      selected = selected | haystack[s];\n    });\n    return !!selected;\n  };\n}\n\n/*\n * Set a continuous 1D filter function\n * @param {Partition} partition\n */\nfunction filterFunctionContinuous1D (partition) {\n  var edge = partition.maxval;\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = partition.minval;\n    max = partition.maxval;\n    return function (d) {\n      return ((d >= min && d <= max) && (d !== misval));\n    };\n  } else {\n    min = partition.selected[0];\n    max = partition.selected[1];\n    return function (d) {\n      return ((d >= min && d < max) || ((d === edge) && (max === edge))) && (d !== misval);\n    };\n  }\n}\n\n/*\n * Set a continuous 1D filter function on a datetime dimension\n * @param {Partition} partition\n */\nfunction filterFunctionDatetime1D (partition) {\n  var edge = moment(partition.maxval);\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = moment(partition.minval);\n    max = moment(partition.maxval);\n\n    return function (d) {\n      var m = moment(d);\n      return (m !== misval) && !m.isBefore(min) && !m.isAfter(max);\n    };\n  } else {\n    min = moment(partition.selected[0]);\n    max = moment(partition.selected[1]);\n    return function (d) {\n      var m = moment(d);\n      return (m !== misval) && !min.isAfter(m) && (m.isBefore(max) || (max.isSame(edge) && max.isSame(m)));\n    };\n  }\n}\n\n/*\n * Set a continuous 1D filter function on a duration dimension\n * @param {Partition} partition\n */\nfunction filterFunctionDuration1D (partition) {\n  var edge = partition.maxval;\n  var min;\n  var max;\n\n  if (!partition.selected || !partition.selected.length) {\n    min = partition.minval;\n    max = partition.maxval;\n\n    return function (d) {\n      if (d === misval) {\n        return false;\n      }\n      var m = moment.duration(d);\n      return moment.isDuration(m) && m >= min && m <= max;\n    };\n  } else {\n    min = moment.duration(partition.selected[0]);\n    max = moment.duration(partition.selected[1]);\n    return function (d) {\n      if (d === misval) {\n        return false;\n      }\n      var m = moment.duration(d);\n      return moment.isDuration(m) && m >= min && (m < max || (m <= max && max >= edge));\n    };\n  }\n}\n\n/**\n * A filter function based for a single partition\n * @function\n * @returns {boolean} selected True if the datapoint is currently selected\n * @param {Partition} partition\n * @param {Object} datapoint\n * @memberof! Selection\n */\nfunction filterFunction (partition) {\n  if (partition.isCategorial || partition.isConstant) {\n    return filterFunctionCategorial1D(partition);\n  } else if (partition.isContinuous) {\n    return filterFunctionContinuous1D(partition);\n  } else if (partition.isDatetime) {\n    return filterFunctionDatetime1D(partition);\n  } else if (partition.isDuration) {\n    return filterFunctionDuration1D(partition);\n  } else if (partition.isText) {\n    return filterFunctionText(partition);\n  } else {\n    console.error('Cannot make filterfunction for partition', partition);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateCategorial1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // 1. none selected:\n    selected.push(group.value);\n  } else if (selected.length === 1) {\n    if (selected[0] === group.value) {\n      // 2. one selected and the group is the same:\n      selected.splice(0, selected.length);\n      partition.groups.forEach(function (g) {\n        if (g.value !== group.value) {\n          selected.push(g.value);\n        }\n      });\n    } else {\n      // 3. one selected and the group is different:\n      selected.push(group.value);\n    }\n  } else {\n    var i;\n    i = selected.indexOf(group.value);\n    if (i > -1) {\n      // 4. more than one selected and the group is in the selection:\n      selected.splice(i, 1);\n    } else {\n      // 5. more than one selected and the group is not in the selection:\n      selected.push(group.value);\n    }\n  }\n\n  // after add: if filters == groups, reset and dont filter\n  if (selected.length === partition.groups.length) {\n    selected.splice(0, selected.length);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateText (partition, group) {\n  var selected = partition.selected;\n\n  var i;\n  i = selected.indexOf(group.value);\n  if (i > -1) {\n    // 1. in the selection, remove it\n    selected.splice(i, 1);\n  } else {\n    // 2. not in the selection, add it\n    selected.push(group.value);\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateContinuous1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min;\n    selected[1] = group.max;\n  } else if (group.min >= selected[1]) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max;\n  } else if (group.max <= selected[0]) {\n    // clicked outside to the left of selection\n    selected[0] = group.min;\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    if (partition.groupLog) {\n      d1 = Math.abs(Math.log(selected[0]) - Math.log(group.min));\n      d2 = Math.abs(Math.log(selected[1]) - Math.log(group.max));\n    } else {\n      d1 = Math.abs(selected[0] - group.min);\n      d2 = Math.abs(selected[1] - group.max);\n    }\n    if (d1 < d2) {\n      selected[0] = group.min;\n    } else {\n      selected[1] = group.max;\n    }\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateDatetime1D (partition, group) {\n  var selected = partition.selected;\n\n  if (!selected || selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min.toISOString();\n    selected[1] = group.max.toISOString();\n    return;\n  }\n\n  var selectionStart = moment(selected[0]);\n  var selectionEnd = moment(selected[1]);\n\n  if (!group.min.isBefore(selectionEnd)) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max.toISOString();\n  } else if (!group.max.isAfter(selectionStart)) {\n    // clicked outside to the left of selection\n    selected[0] = group.min.toISOString();\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    d1 = Math.abs(selectionStart.diff(group.min));\n    d2 = Math.abs(selectionEnd.diff(group.max));\n\n    if (d1 < d2) {\n      selected[0] = group.max.toISOString();\n    } else {\n      selected[1] = group.min.toISOString();\n    }\n  }\n}\n\n/*\n * @param {Group} group - The group to add or remove from the filter\n */\nfunction updateDuration1D (partition, group) {\n  var selected = partition.selected;\n\n  if (selected.length === 0) {\n    // nothing selected, start a range\n    selected[0] = group.min.toISOString();\n    selected[1] = group.max.toISOString();\n    return;\n  }\n\n  var selectionStart = moment.duration(selected[0]);\n  var selectionEnd = moment.duration(selected[1]);\n\n  if (group.min >= selectionEnd) {\n    // clicked outside to the rigth of selection\n    selected[1] = group.max.toISOString();\n  } else if (group.max <= selectionStart) {\n    // clicked outside to the left of selection\n    selected[0] = group.min.toISOString();\n  } else {\n    // clicked inside selection\n    var d1, d2;\n    d1 = Math.abs(selectionStart - group.min);\n    d2 = Math.abs(selectionEnd - group.max);\n\n    if (d1 < d2) {\n      selected[0] = group.max.toISOString();\n    } else {\n      selected[1] = group.min.toISOString();\n    }\n  }\n}\n\n/**\n * Update the selection with a given group or interval\n * or, if no group is given, clear the selection.\n *\n * For categorial selections the following rules are used:\n * 1. none selected:\n *    add the group to the selection\n * 2. one selected and the group is the same:\n *    invert the selection\n * 3. one selected and the group is different:\n *    add the group to the selection\n * 4. more than one selected and the group is in the selection:\n *    remove the group from the selection\n * 5. more than one selected and the group is not in the selection:\n *    add the group to the selection\n *\n * For continuous selections the following rules are used:\n * 1. no range selected\n *    set the range equal to that of the group\n * 2. a range selected and the group is outside the selection:\n *    extend the selection to include the group\n * 3. a range selected and the group is inside the selection:\n *    set the endpoint closest to the group to that of the group\n *\n * @function\n * @param {Partition} Partition to update\n * @param {(string|number[])} Group or interval\n */\nfunction updateSelection (partition, group) {\n  if (!group) {\n    // Clear the selection (ie. all points are selected)\n    partition.selected.splice(0, partition.selected.length);\n  } else {\n    // Update the selection\n    if (partition.type === 'categorial' || partition.type === 'constant') {\n      updateCategorial1D(partition, group);\n    } else if (partition.type === 'continuous') {\n      updateContinuous1D(partition, group);\n    } else if (partition.type === 'datetime') {\n      updateDatetime1D(partition, group);\n    } else if (partition.type === 'duration') {\n      updateDuration1D(partition, group);\n    } else if (partition.type === 'text') {\n      updateText(partition, group);\n    } else {\n      console.error('Cannot update selection', partition.type);\n    }\n  }\n}\n\nmodule.exports = {\n  filterFunction: filterFunction,\n  updateSelection: updateSelection\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTI3OC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9zZWxlY3Rpb24uanM/NGY5ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNlbGVjdGlvblxuICogQG1vZHVsZSBjbGllbnQvdXRpbC1zZWxlY3Rpb25cbiAqL1xudmFyIG1pc3ZhbCA9IHJlcXVpcmUoJy4vbWlzdmFsJyk7XG52YXIgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50LXRpbWV6b25lJyk7XG5cbi8qXG4gKiBTZXQgYSBjYXRlZ29yaWFsIDFEIGZpbHRlciBmdW5jdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkNhdGVnb3JpYWwxRCAocGFydGl0aW9uKSB7XG4gIHZhciBoYXlzdGFjayA9IHt9O1xuXG4gIGlmICghcGFydGl0aW9uLnNlbGVjdGVkIHx8ICFwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKSB7XG4gICAgcGFydGl0aW9uLmdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgaGF5c3RhY2tbZ3JvdXAudmFsdWVdID0gdHJ1ZTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBwYXJ0aXRpb24uc2VsZWN0ZWQuZm9yRWFjaChmdW5jdGlvbiAoaCkge1xuICAgICAgaGF5c3RhY2tbaF0gPSB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgdmFyIG5lZWRsZSA9IGQ7XG4gICAgaWYgKCEobmVlZGxlIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICBuZWVkbGUgPSBbZF07XG4gICAgfVxuXG4gICAgdmFyIHNlbGVjdGVkID0gZmFsc2U7XG4gICAgbmVlZGxlLmZvckVhY2goZnVuY3Rpb24gKHMpIHtcbiAgICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQgfCBoYXlzdGFja1tzXTtcbiAgICB9KTtcbiAgICByZXR1cm4gISFzZWxlY3RlZDtcbiAgfTtcbn1cblxuLypcbiAqIFNldCBhIHRleHQgZmlsdGVyIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uVGV4dCAocGFydGl0aW9uKSB7XG4gIHZhciBoYXlzdGFjayA9IHt9O1xuXG4gIC8vIG5vdGhpbmcgc2VsZWN0ZWQsIHNvIGFsbCBzZWxlY3RlZFxuICBpZiAocGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuICB9XG5cbiAgcGFydGl0aW9uLnNlbGVjdGVkLmZvckVhY2goZnVuY3Rpb24gKGgpIHtcbiAgICBoYXlzdGFja1toXSA9IHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIHZhciBuZWVkbGUgPSBkO1xuICAgIGlmICghKG5lZWRsZSBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgbmVlZGxlID0gW2RdO1xuICAgIH1cblxuICAgIHZhciBzZWxlY3RlZCA9IGZhbHNlO1xuICAgIG5lZWRsZS5mb3JFYWNoKGZ1bmN0aW9uIChzKSB7XG4gICAgICBzZWxlY3RlZCA9IHNlbGVjdGVkIHwgaGF5c3RhY2tbc107XG4gICAgfSk7XG4gICAgcmV0dXJuICEhc2VsZWN0ZWQ7XG4gIH07XG59XG5cbi8qXG4gKiBTZXQgYSBjb250aW51b3VzIDFEIGZpbHRlciBmdW5jdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkNvbnRpbnVvdXMxRCAocGFydGl0aW9uKSB7XG4gIHZhciBlZGdlID0gcGFydGl0aW9uLm1heHZhbDtcbiAgdmFyIG1pbjtcbiAgdmFyIG1heDtcblxuICBpZiAoIXBhcnRpdGlvbi5zZWxlY3RlZCB8fCAhcGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCkge1xuICAgIG1pbiA9IHBhcnRpdGlvbi5taW52YWw7XG4gICAgbWF4ID0gcGFydGl0aW9uLm1heHZhbDtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHJldHVybiAoKGQgPj0gbWluICYmIGQgPD0gbWF4KSAmJiAoZCAhPT0gbWlzdmFsKSk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBwYXJ0aXRpb24uc2VsZWN0ZWRbMF07XG4gICAgbWF4ID0gcGFydGl0aW9uLnNlbGVjdGVkWzFdO1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgcmV0dXJuICgoZCA+PSBtaW4gJiYgZCA8IG1heCkgfHwgKChkID09PSBlZGdlKSAmJiAobWF4ID09PSBlZGdlKSkpICYmIChkICE9PSBtaXN2YWwpO1xuICAgIH07XG4gIH1cbn1cblxuLypcbiAqIFNldCBhIGNvbnRpbnVvdXMgMUQgZmlsdGVyIGZ1bmN0aW9uIG9uIGEgZGF0ZXRpbWUgZGltZW5zaW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uRGF0ZXRpbWUxRCAocGFydGl0aW9uKSB7XG4gIHZhciBlZGdlID0gbW9tZW50KHBhcnRpdGlvbi5tYXh2YWwpO1xuICB2YXIgbWluO1xuICB2YXIgbWF4O1xuXG4gIGlmICghcGFydGl0aW9uLnNlbGVjdGVkIHx8ICFwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKSB7XG4gICAgbWluID0gbW9tZW50KHBhcnRpdGlvbi5taW52YWwpO1xuICAgIG1heCA9IG1vbWVudChwYXJ0aXRpb24ubWF4dmFsKTtcblxuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIG0gPSBtb21lbnQoZCk7XG4gICAgICByZXR1cm4gKG0gIT09IG1pc3ZhbCkgJiYgIW0uaXNCZWZvcmUobWluKSAmJiAhbS5pc0FmdGVyKG1heCk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBtb21lbnQocGFydGl0aW9uLnNlbGVjdGVkWzBdKTtcbiAgICBtYXggPSBtb21lbnQocGFydGl0aW9uLnNlbGVjdGVkWzFdKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciBtID0gbW9tZW50KGQpO1xuICAgICAgcmV0dXJuIChtICE9PSBtaXN2YWwpICYmICFtaW4uaXNBZnRlcihtKSAmJiAobS5pc0JlZm9yZShtYXgpIHx8IChtYXguaXNTYW1lKGVkZ2UpICYmIG1heC5pc1NhbWUobSkpKTtcbiAgICB9O1xuICB9XG59XG5cbi8qXG4gKiBTZXQgYSBjb250aW51b3VzIDFEIGZpbHRlciBmdW5jdGlvbiBvbiBhIGR1cmF0aW9uIGRpbWVuc2lvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBmaWx0ZXJGdW5jdGlvbkR1cmF0aW9uMUQgKHBhcnRpdGlvbikge1xuICB2YXIgZWRnZSA9IHBhcnRpdGlvbi5tYXh2YWw7XG4gIHZhciBtaW47XG4gIHZhciBtYXg7XG5cbiAgaWYgKCFwYXJ0aXRpb24uc2VsZWN0ZWQgfHwgIXBhcnRpdGlvbi5zZWxlY3RlZC5sZW5ndGgpIHtcbiAgICBtaW4gPSBwYXJ0aXRpb24ubWludmFsO1xuICAgIG1heCA9IHBhcnRpdGlvbi5tYXh2YWw7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIG0gPSBtb21lbnQuZHVyYXRpb24oZCk7XG4gICAgICByZXR1cm4gbW9tZW50LmlzRHVyYXRpb24obSkgJiYgbSA+PSBtaW4gJiYgbSA8PSBtYXg7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBtaW4gPSBtb21lbnQuZHVyYXRpb24ocGFydGl0aW9uLnNlbGVjdGVkWzBdKTtcbiAgICBtYXggPSBtb21lbnQuZHVyYXRpb24ocGFydGl0aW9uLnNlbGVjdGVkWzFdKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIG0gPSBtb21lbnQuZHVyYXRpb24oZCk7XG4gICAgICByZXR1cm4gbW9tZW50LmlzRHVyYXRpb24obSkgJiYgbSA+PSBtaW4gJiYgKG0gPCBtYXggfHwgKG0gPD0gbWF4ICYmIG1heCA+PSBlZGdlKSk7XG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIEEgZmlsdGVyIGZ1bmN0aW9uIGJhc2VkIGZvciBhIHNpbmdsZSBwYXJ0aXRpb25cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge2Jvb2xlYW59IHNlbGVjdGVkIFRydWUgaWYgdGhlIGRhdGFwb2ludCBpcyBjdXJyZW50bHkgc2VsZWN0ZWRcbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhcG9pbnRcbiAqIEBtZW1iZXJvZiEgU2VsZWN0aW9uXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgaWYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwgfHwgcGFydGl0aW9uLmlzQ29uc3RhbnQpIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25DYXRlZ29yaWFsMUQocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNDb250aW51b3VzKSB7XG4gICAgcmV0dXJuIGZpbHRlckZ1bmN0aW9uQ29udGludW91czFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzRGF0ZXRpbWUpIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25EYXRldGltZTFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzRHVyYXRpb24pIHtcbiAgICByZXR1cm4gZmlsdGVyRnVuY3Rpb25EdXJhdGlvbjFEKHBhcnRpdGlvbik7XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzVGV4dCkge1xuICAgIHJldHVybiBmaWx0ZXJGdW5jdGlvblRleHQocGFydGl0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zb2xlLmVycm9yKCdDYW5ub3QgbWFrZSBmaWx0ZXJmdW5jdGlvbiBmb3IgcGFydGl0aW9uJywgcGFydGl0aW9uKTtcbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlQ2F0ZWdvcmlhbDFEIChwYXJ0aXRpb24sIGdyb3VwKSB7XG4gIHZhciBzZWxlY3RlZCA9IHBhcnRpdGlvbi5zZWxlY3RlZDtcblxuICBpZiAoc2VsZWN0ZWQubGVuZ3RoID09PSAwKSB7XG4gICAgLy8gMS4gbm9uZSBzZWxlY3RlZDpcbiAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgfSBlbHNlIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDEpIHtcbiAgICBpZiAoc2VsZWN0ZWRbMF0gPT09IGdyb3VwLnZhbHVlKSB7XG4gICAgICAvLyAyLiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyB0aGUgc2FtZTpcbiAgICAgIHNlbGVjdGVkLnNwbGljZSgwLCBzZWxlY3RlZC5sZW5ndGgpO1xuICAgICAgcGFydGl0aW9uLmdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChnKSB7XG4gICAgICAgIGlmIChnLnZhbHVlICE9PSBncm91cC52YWx1ZSkge1xuICAgICAgICAgIHNlbGVjdGVkLnB1c2goZy52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyAzLiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyBkaWZmZXJlbnQ6XG4gICAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGk7XG4gICAgaSA9IHNlbGVjdGVkLmluZGV4T2YoZ3JvdXAudmFsdWUpO1xuICAgIGlmIChpID4gLTEpIHtcbiAgICAgIC8vIDQuIG1vcmUgdGhhbiBvbmUgc2VsZWN0ZWQgYW5kIHRoZSBncm91cCBpcyBpbiB0aGUgc2VsZWN0aW9uOlxuICAgICAgc2VsZWN0ZWQuc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyA1LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgbm90IGluIHRoZSBzZWxlY3Rpb246XG4gICAgICBzZWxlY3RlZC5wdXNoKGdyb3VwLnZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvLyBhZnRlciBhZGQ6IGlmIGZpbHRlcnMgPT0gZ3JvdXBzLCByZXNldCBhbmQgZG9udCBmaWx0ZXJcbiAgaWYgKHNlbGVjdGVkLmxlbmd0aCA9PT0gcGFydGl0aW9uLmdyb3Vwcy5sZW5ndGgpIHtcbiAgICBzZWxlY3RlZC5zcGxpY2UoMCwgc2VsZWN0ZWQubGVuZ3RoKTtcbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlVGV4dCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgdmFyIGk7XG4gIGkgPSBzZWxlY3RlZC5pbmRleE9mKGdyb3VwLnZhbHVlKTtcbiAgaWYgKGkgPiAtMSkge1xuICAgIC8vIDEuIGluIHRoZSBzZWxlY3Rpb24sIHJlbW92ZSBpdFxuICAgIHNlbGVjdGVkLnNwbGljZShpLCAxKTtcbiAgfSBlbHNlIHtcbiAgICAvLyAyLiBub3QgaW4gdGhlIHNlbGVjdGlvbiwgYWRkIGl0XG4gICAgc2VsZWN0ZWQucHVzaChncm91cC52YWx1ZSk7XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7R3JvdXB9IGdyb3VwIC0gVGhlIGdyb3VwIHRvIGFkZCBvciByZW1vdmUgZnJvbSB0aGUgZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZUNvbnRpbnVvdXMxRCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgaWYgKHNlbGVjdGVkLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIG5vdGhpbmcgc2VsZWN0ZWQsIHN0YXJ0IGEgcmFuZ2VcbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbjtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heDtcbiAgfSBlbHNlIGlmIChncm91cC5taW4gPj0gc2VsZWN0ZWRbMV0pIHtcbiAgICAvLyBjbGlja2VkIG91dHNpZGUgdG8gdGhlIHJpZ3RoIG9mIHNlbGVjdGlvblxuICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4O1xuICB9IGVsc2UgaWYgKGdyb3VwLm1heCA8PSBzZWxlY3RlZFswXSkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbjtcbiAgfSBlbHNlIHtcbiAgICAvLyBjbGlja2VkIGluc2lkZSBzZWxlY3Rpb25cbiAgICB2YXIgZDEsIGQyO1xuICAgIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAgIGQxID0gTWF0aC5hYnMoTWF0aC5sb2coc2VsZWN0ZWRbMF0pIC0gTWF0aC5sb2coZ3JvdXAubWluKSk7XG4gICAgICBkMiA9IE1hdGguYWJzKE1hdGgubG9nKHNlbGVjdGVkWzFdKSAtIE1hdGgubG9nKGdyb3VwLm1heCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkMSA9IE1hdGguYWJzKHNlbGVjdGVkWzBdIC0gZ3JvdXAubWluKTtcbiAgICAgIGQyID0gTWF0aC5hYnMoc2VsZWN0ZWRbMV0gLSBncm91cC5tYXgpO1xuICAgIH1cbiAgICBpZiAoZDEgPCBkMikge1xuICAgICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW47XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4O1xuICAgIH1cbiAgfVxufVxuXG4vKlxuICogQHBhcmFtIHtHcm91cH0gZ3JvdXAgLSBUaGUgZ3JvdXAgdG8gYWRkIG9yIHJlbW92ZSBmcm9tIHRoZSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gdXBkYXRlRGF0ZXRpbWUxRCAocGFydGl0aW9uLCBncm91cCkge1xuICB2YXIgc2VsZWN0ZWQgPSBwYXJ0aXRpb24uc2VsZWN0ZWQ7XG5cbiAgaWYgKCFzZWxlY3RlZCB8fCBzZWxlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICAvLyBub3RoaW5nIHNlbGVjdGVkLCBzdGFydCBhIHJhbmdlXG4gICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxlY3Rpb25TdGFydCA9IG1vbWVudChzZWxlY3RlZFswXSk7XG4gIHZhciBzZWxlY3Rpb25FbmQgPSBtb21lbnQoc2VsZWN0ZWRbMV0pO1xuXG4gIGlmICghZ3JvdXAubWluLmlzQmVmb3JlKHNlbGVjdGlvbkVuZCkpIHtcbiAgICAvLyBjbGlja2VkIG91dHNpZGUgdG8gdGhlIHJpZ3RoIG9mIHNlbGVjdGlvblxuICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWF4LnRvSVNPU3RyaW5nKCk7XG4gIH0gZWxzZSBpZiAoIWdyb3VwLm1heC5pc0FmdGVyKHNlbGVjdGlvblN0YXJ0KSkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbi50b0lTT1N0cmluZygpO1xuICB9IGVsc2Uge1xuICAgIC8vIGNsaWNrZWQgaW5zaWRlIHNlbGVjdGlvblxuICAgIHZhciBkMSwgZDI7XG4gICAgZDEgPSBNYXRoLmFicyhzZWxlY3Rpb25TdGFydC5kaWZmKGdyb3VwLm1pbikpO1xuICAgIGQyID0gTWF0aC5hYnMoc2VsZWN0aW9uRW5kLmRpZmYoZ3JvdXAubWF4KSk7XG5cbiAgICBpZiAoZDEgPCBkMikge1xuICAgICAgc2VsZWN0ZWRbMF0gPSBncm91cC5tYXgudG9JU09TdHJpbmcoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZWN0ZWRbMV0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICB9XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7R3JvdXB9IGdyb3VwIC0gVGhlIGdyb3VwIHRvIGFkZCBvciByZW1vdmUgZnJvbSB0aGUgZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZUR1cmF0aW9uMUQgKHBhcnRpdGlvbiwgZ3JvdXApIHtcbiAgdmFyIHNlbGVjdGVkID0gcGFydGl0aW9uLnNlbGVjdGVkO1xuXG4gIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICAvLyBub3RoaW5nIHNlbGVjdGVkLCBzdGFydCBhIHJhbmdlXG4gICAgc2VsZWN0ZWRbMF0gPSBncm91cC5taW4udG9JU09TdHJpbmcoKTtcbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxlY3Rpb25TdGFydCA9IG1vbWVudC5kdXJhdGlvbihzZWxlY3RlZFswXSk7XG4gIHZhciBzZWxlY3Rpb25FbmQgPSBtb21lbnQuZHVyYXRpb24oc2VsZWN0ZWRbMV0pO1xuXG4gIGlmIChncm91cC5taW4gPj0gc2VsZWN0aW9uRW5kKSB7XG4gICAgLy8gY2xpY2tlZCBvdXRzaWRlIHRvIHRoZSByaWd0aCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFsxXSA9IGdyb3VwLm1heC50b0lTT1N0cmluZygpO1xuICB9IGVsc2UgaWYgKGdyb3VwLm1heCA8PSBzZWxlY3Rpb25TdGFydCkge1xuICAgIC8vIGNsaWNrZWQgb3V0c2lkZSB0byB0aGUgbGVmdCBvZiBzZWxlY3Rpb25cbiAgICBzZWxlY3RlZFswXSA9IGdyb3VwLm1pbi50b0lTT1N0cmluZygpO1xuICB9IGVsc2Uge1xuICAgIC8vIGNsaWNrZWQgaW5zaWRlIHNlbGVjdGlvblxuICAgIHZhciBkMSwgZDI7XG4gICAgZDEgPSBNYXRoLmFicyhzZWxlY3Rpb25TdGFydCAtIGdyb3VwLm1pbik7XG4gICAgZDIgPSBNYXRoLmFicyhzZWxlY3Rpb25FbmQgLSBncm91cC5tYXgpO1xuXG4gICAgaWYgKGQxIDwgZDIpIHtcbiAgICAgIHNlbGVjdGVkWzBdID0gZ3JvdXAubWF4LnRvSVNPU3RyaW5nKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGVjdGVkWzFdID0gZ3JvdXAubWluLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVXBkYXRlIHRoZSBzZWxlY3Rpb24gd2l0aCBhIGdpdmVuIGdyb3VwIG9yIGludGVydmFsXG4gKiBvciwgaWYgbm8gZ3JvdXAgaXMgZ2l2ZW4sIGNsZWFyIHRoZSBzZWxlY3Rpb24uXG4gKlxuICogRm9yIGNhdGVnb3JpYWwgc2VsZWN0aW9ucyB0aGUgZm9sbG93aW5nIHJ1bGVzIGFyZSB1c2VkOlxuICogMS4gbm9uZSBzZWxlY3RlZDpcbiAqICAgIGFkZCB0aGUgZ3JvdXAgdG8gdGhlIHNlbGVjdGlvblxuICogMi4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgdGhlIHNhbWU6XG4gKiAgICBpbnZlcnQgdGhlIHNlbGVjdGlvblxuICogMy4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgZGlmZmVyZW50OlxuICogICAgYWRkIHRoZSBncm91cCB0byB0aGUgc2VsZWN0aW9uXG4gKiA0LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgaW4gdGhlIHNlbGVjdGlvbjpcbiAqICAgIHJlbW92ZSB0aGUgZ3JvdXAgZnJvbSB0aGUgc2VsZWN0aW9uXG4gKiA1LiBtb3JlIHRoYW4gb25lIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgbm90IGluIHRoZSBzZWxlY3Rpb246XG4gKiAgICBhZGQgdGhlIGdyb3VwIHRvIHRoZSBzZWxlY3Rpb25cbiAqXG4gKiBGb3IgY29udGludW91cyBzZWxlY3Rpb25zIHRoZSBmb2xsb3dpbmcgcnVsZXMgYXJlIHVzZWQ6XG4gKiAxLiBubyByYW5nZSBzZWxlY3RlZFxuICogICAgc2V0IHRoZSByYW5nZSBlcXVhbCB0byB0aGF0IG9mIHRoZSBncm91cFxuICogMi4gYSByYW5nZSBzZWxlY3RlZCBhbmQgdGhlIGdyb3VwIGlzIG91dHNpZGUgdGhlIHNlbGVjdGlvbjpcbiAqICAgIGV4dGVuZCB0aGUgc2VsZWN0aW9uIHRvIGluY2x1ZGUgdGhlIGdyb3VwXG4gKiAzLiBhIHJhbmdlIHNlbGVjdGVkIGFuZCB0aGUgZ3JvdXAgaXMgaW5zaWRlIHRoZSBzZWxlY3Rpb246XG4gKiAgICBzZXQgdGhlIGVuZHBvaW50IGNsb3Nlc3QgdG8gdGhlIGdyb3VwIHRvIHRoYXQgb2YgdGhlIGdyb3VwXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gUGFydGl0aW9uIHRvIHVwZGF0ZVxuICogQHBhcmFtIHsoc3RyaW5nfG51bWJlcltdKX0gR3JvdXAgb3IgaW50ZXJ2YWxcbiAqL1xuZnVuY3Rpb24gdXBkYXRlU2VsZWN0aW9uIChwYXJ0aXRpb24sIGdyb3VwKSB7XG4gIGlmICghZ3JvdXApIHtcbiAgICAvLyBDbGVhciB0aGUgc2VsZWN0aW9uIChpZS4gYWxsIHBvaW50cyBhcmUgc2VsZWN0ZWQpXG4gICAgcGFydGl0aW9uLnNlbGVjdGVkLnNwbGljZSgwLCBwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBVcGRhdGUgdGhlIHNlbGVjdGlvblxuICAgIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2NhdGVnb3JpYWwnIHx8IHBhcnRpdGlvbi50eXBlID09PSAnY29uc3RhbnQnKSB7XG4gICAgICB1cGRhdGVDYXRlZ29yaWFsMUQocGFydGl0aW9uLCBncm91cCk7XG4gICAgfSBlbHNlIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2NvbnRpbnVvdXMnKSB7XG4gICAgICB1cGRhdGVDb250aW51b3VzMUQocGFydGl0aW9uLCBncm91cCk7XG4gICAgfSBlbHNlIGlmIChwYXJ0aXRpb24udHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgdXBkYXRlRGF0ZXRpbWUxRChwYXJ0aXRpb24sIGdyb3VwKTtcbiAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi50eXBlID09PSAnZHVyYXRpb24nKSB7XG4gICAgICB1cGRhdGVEdXJhdGlvbjFEKHBhcnRpdGlvbiwgZ3JvdXApO1xuICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLnR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgdXBkYXRlVGV4dChwYXJ0aXRpb24sIGdyb3VwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcignQ2Fubm90IHVwZGF0ZSBzZWxlY3Rpb24nLCBwYXJ0aXRpb24udHlwZSk7XG4gICAgfVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBmaWx0ZXJGdW5jdGlvbjogZmlsdGVyRnVuY3Rpb24sXG4gIHVwZGF0ZVNlbGVjdGlvbjogdXBkYXRlU2VsZWN0aW9uXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1278\n")},"181d":function(module,exports,__webpack_require__){eval("/**\n * Module dependencies.\n */\n\nvar Transport = __webpack_require__(/*! ../transport */ \"0d97\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar yeast = __webpack_require__(/*! yeast */ \"c16d\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:polling');\n\n/**\n * Module exports.\n */\n\nmodule.exports = Polling;\n\n/**\n * Is XHR2 supported?\n */\n\nvar hasXHR2 = (function () {\n  var XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ \"86e3\");\n  var xhr = new XMLHttpRequest({ xdomain: false });\n  return null != xhr.responseType;\n})();\n\n/**\n * Polling interface.\n *\n * @param {Object} opts\n * @api private\n */\n\nfunction Polling (opts) {\n  var forceBase64 = (opts && opts.forceBase64);\n  if (!hasXHR2 || forceBase64) {\n    this.supportsBinary = false;\n  }\n  Transport.call(this, opts);\n}\n\n/**\n * Inherits from Transport.\n */\n\ninherit(Polling, Transport);\n\n/**\n * Transport name.\n */\n\nPolling.prototype.name = 'polling';\n\n/**\n * Opens the socket (triggers polling). We write a PING message to determine\n * when the transport is open.\n *\n * @api private\n */\n\nPolling.prototype.doOpen = function () {\n  this.poll();\n};\n\n/**\n * Pauses polling.\n *\n * @param {Function} callback upon buffers are flushed and transport is paused\n * @api private\n */\n\nPolling.prototype.pause = function (onPause) {\n  var self = this;\n\n  this.readyState = 'pausing';\n\n  function pause () {\n    debug('paused');\n    self.readyState = 'paused';\n    onPause();\n  }\n\n  if (this.polling || !this.writable) {\n    var total = 0;\n\n    if (this.polling) {\n      debug('we are currently polling - waiting to pause');\n      total++;\n      this.once('pollComplete', function () {\n        debug('pre-pause polling complete');\n        --total || pause();\n      });\n    }\n\n    if (!this.writable) {\n      debug('we are currently writing - waiting to pause');\n      total++;\n      this.once('drain', function () {\n        debug('pre-pause writing complete');\n        --total || pause();\n      });\n    }\n  } else {\n    pause();\n  }\n};\n\n/**\n * Starts polling cycle.\n *\n * @api public\n */\n\nPolling.prototype.poll = function () {\n  debug('polling');\n  this.polling = true;\n  this.doPoll();\n  this.emit('poll');\n};\n\n/**\n * Overloads onData to detect payloads.\n *\n * @api private\n */\n\nPolling.prototype.onData = function (data) {\n  var self = this;\n  debug('polling got data %s', data);\n  var callback = function (packet, index, total) {\n    // if its the first message we consider the transport open\n    if ('opening' === self.readyState) {\n      self.onOpen();\n    }\n\n    // if its a close packet, we close the ongoing requests\n    if ('close' === packet.type) {\n      self.onClose();\n      return false;\n    }\n\n    // otherwise bypass onData and handle the message\n    self.onPacket(packet);\n  };\n\n  // decode payload\n  parser.decodePayload(data, this.socket.binaryType, callback);\n\n  // if an event did not trigger closing\n  if ('closed' !== this.readyState) {\n    // if we got data we're not polling\n    this.polling = false;\n    this.emit('pollComplete');\n\n    if ('open' === this.readyState) {\n      this.poll();\n    } else {\n      debug('ignoring poll - transport state \"%s\"', this.readyState);\n    }\n  }\n};\n\n/**\n * For polling, send a close packet.\n *\n * @api private\n */\n\nPolling.prototype.doClose = function () {\n  var self = this;\n\n  function close () {\n    debug('writing close packet');\n    self.write([{ type: 'close' }]);\n  }\n\n  if ('open' === this.readyState) {\n    debug('transport open - closing');\n    close();\n  } else {\n    // in case we're trying to close while\n    // handshaking is in progress (GH-164)\n    debug('transport not open - deferring close');\n    this.once('open', close);\n  }\n};\n\n/**\n * Writes a packets payload.\n *\n * @param {Array} data packets\n * @param {Function} drain callback\n * @api private\n */\n\nPolling.prototype.write = function (packets) {\n  var self = this;\n  this.writable = false;\n  var callbackfn = function () {\n    self.writable = true;\n    self.emit('drain');\n  };\n\n  parser.encodePayload(packets, this.supportsBinary, function (data) {\n    self.doWrite(data, callbackfn);\n  });\n};\n\n/**\n * Generates uri for connection.\n *\n * @api private\n */\n\nPolling.prototype.uri = function () {\n  var query = this.query || {};\n  var schema = this.secure ? 'https' : 'http';\n  var port = '';\n\n  // cache busting is forced\n  if (false !== this.timestampRequests) {\n    query[this.timestampParam] = yeast();\n  }\n\n  if (!this.supportsBinary && !query.sid) {\n    query.b64 = 1;\n  }\n\n  query = parseqs.encode(query);\n\n  // avoid port if default for schema\n  if (this.port && (('https' === schema && Number(this.port) !== 443) ||\n     ('http' === schema && Number(this.port) !== 80))) {\n    port = ':' + this.port;\n  }\n\n  // prepend ? to query\n  if (query.length) {\n    query = '?' + query;\n  }\n\n  var ipv6 = this.hostname.indexOf(':') !== -1;\n  return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTgxZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLmpzP2U1ZjkiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBUcmFuc3BvcnQgPSByZXF1aXJlKCcuLi90cmFuc3BvcnQnKTtcbnZhciBwYXJzZXFzID0gcmVxdWlyZSgncGFyc2VxcycpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcbnZhciB5ZWFzdCA9IHJlcXVpcmUoJ3llYXN0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnBvbGxpbmcnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBvbGxpbmc7XG5cbi8qKlxuICogSXMgWEhSMiBzdXBwb3J0ZWQ/XG4gKi9cblxudmFyIGhhc1hIUjIgPSAoZnVuY3Rpb24gKCkge1xuICB2YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdC1zc2wnKTtcbiAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCh7IHhkb21haW46IGZhbHNlIH0pO1xuICByZXR1cm4gbnVsbCAhPSB4aHIucmVzcG9uc2VUeXBlO1xufSkoKTtcblxuLyoqXG4gKiBQb2xsaW5nIGludGVyZmFjZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gUG9sbGluZyAob3B0cykge1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKCFoYXNYSFIyIHx8IGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIFRyYW5zcG9ydC5jYWxsKHRoaXMsIG9wdHMpO1xufVxuXG4vKipcbiAqIEluaGVyaXRzIGZyb20gVHJhbnNwb3J0LlxuICovXG5cbmluaGVyaXQoUG9sbGluZywgVHJhbnNwb3J0KTtcblxuLyoqXG4gKiBUcmFuc3BvcnQgbmFtZS5cbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5uYW1lID0gJ3BvbGxpbmcnO1xuXG4vKipcbiAqIE9wZW5zIHRoZSBzb2NrZXQgKHRyaWdnZXJzIHBvbGxpbmcpLiBXZSB3cml0ZSBhIFBJTkcgbWVzc2FnZSB0byBkZXRlcm1pbmVcbiAqIHdoZW4gdGhlIHRyYW5zcG9ydCBpcyBvcGVuLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLmRvT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5wb2xsKCk7XG59O1xuXG4vKipcbiAqIFBhdXNlcyBwb2xsaW5nLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHVwb24gYnVmZmVycyBhcmUgZmx1c2hlZCBhbmQgdHJhbnNwb3J0IGlzIHBhdXNlZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAob25QYXVzZSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5yZWFkeVN0YXRlID0gJ3BhdXNpbmcnO1xuXG4gIGZ1bmN0aW9uIHBhdXNlICgpIHtcbiAgICBkZWJ1ZygncGF1c2VkJyk7XG4gICAgc2VsZi5yZWFkeVN0YXRlID0gJ3BhdXNlZCc7XG4gICAgb25QYXVzZSgpO1xuICB9XG5cbiAgaWYgKHRoaXMucG9sbGluZyB8fCAhdGhpcy53cml0YWJsZSkge1xuICAgIHZhciB0b3RhbCA9IDA7XG5cbiAgICBpZiAodGhpcy5wb2xsaW5nKSB7XG4gICAgICBkZWJ1Zygnd2UgYXJlIGN1cnJlbnRseSBwb2xsaW5nIC0gd2FpdGluZyB0byBwYXVzZScpO1xuICAgICAgdG90YWwrKztcbiAgICAgIHRoaXMub25jZSgncG9sbENvbXBsZXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBkZWJ1ZygncHJlLXBhdXNlIHBvbGxpbmcgY29tcGxldGUnKTtcbiAgICAgICAgLS10b3RhbCB8fCBwYXVzZSgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLndyaXRhYmxlKSB7XG4gICAgICBkZWJ1Zygnd2UgYXJlIGN1cnJlbnRseSB3cml0aW5nIC0gd2FpdGluZyB0byBwYXVzZScpO1xuICAgICAgdG90YWwrKztcbiAgICAgIHRoaXMub25jZSgnZHJhaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlYnVnKCdwcmUtcGF1c2Ugd3JpdGluZyBjb21wbGV0ZScpO1xuICAgICAgICAtLXRvdGFsIHx8IHBhdXNlKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcGF1c2UoKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTdGFydHMgcG9sbGluZyBjeWNsZS5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblBvbGxpbmcucHJvdG90eXBlLnBvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCdwb2xsaW5nJyk7XG4gIHRoaXMucG9sbGluZyA9IHRydWU7XG4gIHRoaXMuZG9Qb2xsKCk7XG4gIHRoaXMuZW1pdCgncG9sbCcpO1xufTtcblxuLyoqXG4gKiBPdmVybG9hZHMgb25EYXRhIHRvIGRldGVjdCBwYXlsb2Fkcy5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5vbkRhdGEgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGRlYnVnKCdwb2xsaW5nIGdvdCBkYXRhICVzJywgZGF0YSk7XG4gIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uIChwYWNrZXQsIGluZGV4LCB0b3RhbCkge1xuICAgIC8vIGlmIGl0cyB0aGUgZmlyc3QgbWVzc2FnZSB3ZSBjb25zaWRlciB0aGUgdHJhbnNwb3J0IG9wZW5cbiAgICBpZiAoJ29wZW5pbmcnID09PSBzZWxmLnJlYWR5U3RhdGUpIHtcbiAgICAgIHNlbGYub25PcGVuKCk7XG4gICAgfVxuXG4gICAgLy8gaWYgaXRzIGEgY2xvc2UgcGFja2V0LCB3ZSBjbG9zZSB0aGUgb25nb2luZyByZXF1ZXN0c1xuICAgIGlmICgnY2xvc2UnID09PSBwYWNrZXQudHlwZSkge1xuICAgICAgc2VsZi5vbkNsb3NlKCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gb3RoZXJ3aXNlIGJ5cGFzcyBvbkRhdGEgYW5kIGhhbmRsZSB0aGUgbWVzc2FnZVxuICAgIHNlbGYub25QYWNrZXQocGFja2V0KTtcbiAgfTtcblxuICAvLyBkZWNvZGUgcGF5bG9hZFxuICBwYXJzZXIuZGVjb2RlUGF5bG9hZChkYXRhLCB0aGlzLnNvY2tldC5iaW5hcnlUeXBlLCBjYWxsYmFjayk7XG5cbiAgLy8gaWYgYW4gZXZlbnQgZGlkIG5vdCB0cmlnZ2VyIGNsb3NpbmdcbiAgaWYgKCdjbG9zZWQnICE9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAvLyBpZiB3ZSBnb3QgZGF0YSB3ZSdyZSBub3QgcG9sbGluZ1xuICAgIHRoaXMucG9sbGluZyA9IGZhbHNlO1xuICAgIHRoaXMuZW1pdCgncG9sbENvbXBsZXRlJyk7XG5cbiAgICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAgIHRoaXMucG9sbCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1ZygnaWdub3JpbmcgcG9sbCAtIHRyYW5zcG9ydCBzdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBGb3IgcG9sbGluZywgc2VuZCBhIGNsb3NlIHBhY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gY2xvc2UgKCkge1xuICAgIGRlYnVnKCd3cml0aW5nIGNsb3NlIHBhY2tldCcpO1xuICAgIHNlbGYud3JpdGUoW3sgdHlwZTogJ2Nsb3NlJyB9XSk7XG4gIH1cblxuICBpZiAoJ29wZW4nID09PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICBkZWJ1ZygndHJhbnNwb3J0IG9wZW4gLSBjbG9zaW5nJyk7XG4gICAgY2xvc2UoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbiBjYXNlIHdlJ3JlIHRyeWluZyB0byBjbG9zZSB3aGlsZVxuICAgIC8vIGhhbmRzaGFraW5nIGlzIGluIHByb2dyZXNzIChHSC0xNjQpXG4gICAgZGVidWcoJ3RyYW5zcG9ydCBub3Qgb3BlbiAtIGRlZmVycmluZyBjbG9zZScpO1xuICAgIHRoaXMub25jZSgnb3BlbicsIGNsb3NlKTtcbiAgfVxufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBwYWNrZXRzIHBheWxvYWQuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gZGF0YSBwYWNrZXRzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBkcmFpbiBjYWxsYmFja1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAocGFja2V0cykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcbiAgdmFyIGNhbGxiYWNrZm4gPSBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi53cml0YWJsZSA9IHRydWU7XG4gICAgc2VsZi5lbWl0KCdkcmFpbicpO1xuICB9O1xuXG4gIHBhcnNlci5lbmNvZGVQYXlsb2FkKHBhY2tldHMsIHRoaXMuc3VwcG9ydHNCaW5hcnksIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgc2VsZi5kb1dyaXRlKGRhdGEsIGNhbGxiYWNrZm4pO1xuICB9KTtcbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIHVyaSBmb3IgY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS51cmkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBxdWVyeSA9IHRoaXMucXVlcnkgfHwge307XG4gIHZhciBzY2hlbWEgPSB0aGlzLnNlY3VyZSA/ICdodHRwcycgOiAnaHR0cCc7XG4gIHZhciBwb3J0ID0gJyc7XG5cbiAgLy8gY2FjaGUgYnVzdGluZyBpcyBmb3JjZWRcbiAgaWYgKGZhbHNlICE9PSB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzKSB7XG4gICAgcXVlcnlbdGhpcy50aW1lc3RhbXBQYXJhbV0gPSB5ZWFzdCgpO1xuICB9XG5cbiAgaWYgKCF0aGlzLnN1cHBvcnRzQmluYXJ5ICYmICFxdWVyeS5zaWQpIHtcbiAgICBxdWVyeS5iNjQgPSAxO1xuICB9XG5cbiAgcXVlcnkgPSBwYXJzZXFzLmVuY29kZShxdWVyeSk7XG5cbiAgLy8gYXZvaWQgcG9ydCBpZiBkZWZhdWx0IGZvciBzY2hlbWFcbiAgaWYgKHRoaXMucG9ydCAmJiAoKCdodHRwcycgPT09IHNjaGVtYSAmJiBOdW1iZXIodGhpcy5wb3J0KSAhPT0gNDQzKSB8fFxuICAgICAoJ2h0dHAnID09PSBzY2hlbWEgJiYgTnVtYmVyKHRoaXMucG9ydCkgIT09IDgwKSkpIHtcbiAgICBwb3J0ID0gJzonICsgdGhpcy5wb3J0O1xuICB9XG5cbiAgLy8gcHJlcGVuZCA/IHRvIHF1ZXJ5XG4gIGlmIChxdWVyeS5sZW5ndGgpIHtcbiAgICBxdWVyeSA9ICc/JyArIHF1ZXJ5O1xuICB9XG5cbiAgdmFyIGlwdjYgPSB0aGlzLmhvc3RuYW1lLmluZGV4T2YoJzonKSAhPT0gLTE7XG4gIHJldHVybiBzY2hlbWEgKyAnOi8vJyArIChpcHY2ID8gJ1snICsgdGhpcy5ob3N0bmFtZSArICddJyA6IHRoaXMuaG9zdG5hbWUpICsgcG9ydCArIHRoaXMucGF0aCArIHF1ZXJ5O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///181d\n")},"1e1f":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar eio = __webpack_require__(/*! engine.io-client */ \"c59b\");\nvar Socket = __webpack_require__(/*! ./socket */ \"4c13\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar on = __webpack_require__(/*! ./on */ \"faaa\");\nvar bind = __webpack_require__(/*! component-bind */ \"b6f6\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:manager');\nvar indexOf = __webpack_require__(/*! indexof */ \"3294\");\nvar Backoff = __webpack_require__(/*! backo2 */ \"f942\");\n\n/**\n * IE6+ hasOwnProperty\n */\n\nvar has = Object.prototype.hasOwnProperty;\n\n/**\n * Module exports\n */\n\nmodule.exports = Manager;\n\n/**\n * `Manager` constructor.\n *\n * @param {String} engine instance or engine uri/opts\n * @param {Object} options\n * @api public\n */\n\nfunction Manager (uri, opts) {\n  if (!(this instanceof Manager)) return new Manager(uri, opts);\n  if (uri && ('object' === typeof uri)) {\n    opts = uri;\n    uri = undefined;\n  }\n  opts = opts || {};\n\n  opts.path = opts.path || '/socket.io';\n  this.nsps = {};\n  this.subs = [];\n  this.opts = opts;\n  this.reconnection(opts.reconnection !== false);\n  this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);\n  this.reconnectionDelay(opts.reconnectionDelay || 1000);\n  this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);\n  this.randomizationFactor(opts.randomizationFactor || 0.5);\n  this.backoff = new Backoff({\n    min: this.reconnectionDelay(),\n    max: this.reconnectionDelayMax(),\n    jitter: this.randomizationFactor()\n  });\n  this.timeout(null == opts.timeout ? 20000 : opts.timeout);\n  this.readyState = 'closed';\n  this.uri = uri;\n  this.connecting = [];\n  this.lastPing = null;\n  this.encoding = false;\n  this.packetBuffer = [];\n  this.encoder = new parser.Encoder();\n  this.decoder = new parser.Decoder();\n  this.autoConnect = opts.autoConnect !== false;\n  if (this.autoConnect) this.open();\n}\n\n/**\n * Propagate given event to sockets and emit on `this`\n *\n * @api private\n */\n\nManager.prototype.emitAll = function () {\n  this.emit.apply(this, arguments);\n  for (var nsp in this.nsps) {\n    if (has.call(this.nsps, nsp)) {\n      this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);\n    }\n  }\n};\n\n/**\n * Update `socket.id` of all sockets\n *\n * @api private\n */\n\nManager.prototype.updateSocketIds = function () {\n  for (var nsp in this.nsps) {\n    if (has.call(this.nsps, nsp)) {\n      this.nsps[nsp].id = this.engine.id;\n    }\n  }\n};\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Manager.prototype);\n\n/**\n * Sets the `reconnection` config.\n *\n * @param {Boolean} true/false if it should automatically reconnect\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnection = function (v) {\n  if (!arguments.length) return this._reconnection;\n  this._reconnection = !!v;\n  return this;\n};\n\n/**\n * Sets the reconnection attempts config.\n *\n * @param {Number} max reconnection attempts before giving up\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionAttempts = function (v) {\n  if (!arguments.length) return this._reconnectionAttempts;\n  this._reconnectionAttempts = v;\n  return this;\n};\n\n/**\n * Sets the delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionDelay = function (v) {\n  if (!arguments.length) return this._reconnectionDelay;\n  this._reconnectionDelay = v;\n  this.backoff && this.backoff.setMin(v);\n  return this;\n};\n\nManager.prototype.randomizationFactor = function (v) {\n  if (!arguments.length) return this._randomizationFactor;\n  this._randomizationFactor = v;\n  this.backoff && this.backoff.setJitter(v);\n  return this;\n};\n\n/**\n * Sets the maximum delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.reconnectionDelayMax = function (v) {\n  if (!arguments.length) return this._reconnectionDelayMax;\n  this._reconnectionDelayMax = v;\n  this.backoff && this.backoff.setMax(v);\n  return this;\n};\n\n/**\n * Sets the connection timeout. `false` to disable\n *\n * @return {Manager} self or value\n * @api public\n */\n\nManager.prototype.timeout = function (v) {\n  if (!arguments.length) return this._timeout;\n  this._timeout = v;\n  return this;\n};\n\n/**\n * Starts trying to reconnect if reconnection is enabled and we have not\n * started reconnecting yet\n *\n * @api private\n */\n\nManager.prototype.maybeReconnectOnOpen = function () {\n  // Only try to reconnect if it's the first time we're connecting\n  if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) {\n    // keeps reconnection from firing twice for the same reconnection loop\n    this.reconnect();\n  }\n};\n\n/**\n * Sets the current transport `socket`.\n *\n * @param {Function} optional, callback\n * @return {Manager} self\n * @api public\n */\n\nManager.prototype.open =\nManager.prototype.connect = function (fn, opts) {\n  debug('readyState %s', this.readyState);\n  if (~this.readyState.indexOf('open')) return this;\n\n  debug('opening %s', this.uri);\n  this.engine = eio(this.uri, this.opts);\n  var socket = this.engine;\n  var self = this;\n  this.readyState = 'opening';\n  this.skipReconnect = false;\n\n  // emit `open`\n  var openSub = on(socket, 'open', function () {\n    self.onopen();\n    fn && fn();\n  });\n\n  // emit `connect_error`\n  var errorSub = on(socket, 'error', function (data) {\n    debug('connect_error');\n    self.cleanup();\n    self.readyState = 'closed';\n    self.emitAll('connect_error', data);\n    if (fn) {\n      var err = new Error('Connection error');\n      err.data = data;\n      fn(err);\n    } else {\n      // Only do this if there is no fn to handle the error\n      self.maybeReconnectOnOpen();\n    }\n  });\n\n  // emit `connect_timeout`\n  if (false !== this._timeout) {\n    var timeout = this._timeout;\n    debug('connect attempt will timeout after %d', timeout);\n\n    // set timer\n    var timer = setTimeout(function () {\n      debug('connect attempt timed out after %d', timeout);\n      openSub.destroy();\n      socket.close();\n      socket.emit('error', 'timeout');\n      self.emitAll('connect_timeout', timeout);\n    }, timeout);\n\n    this.subs.push({\n      destroy: function () {\n        clearTimeout(timer);\n      }\n    });\n  }\n\n  this.subs.push(openSub);\n  this.subs.push(errorSub);\n\n  return this;\n};\n\n/**\n * Called upon transport open.\n *\n * @api private\n */\n\nManager.prototype.onopen = function () {\n  debug('open');\n\n  // clear old subs\n  this.cleanup();\n\n  // mark as open\n  this.readyState = 'open';\n  this.emit('open');\n\n  // add new subs\n  var socket = this.engine;\n  this.subs.push(on(socket, 'data', bind(this, 'ondata')));\n  this.subs.push(on(socket, 'ping', bind(this, 'onping')));\n  this.subs.push(on(socket, 'pong', bind(this, 'onpong')));\n  this.subs.push(on(socket, 'error', bind(this, 'onerror')));\n  this.subs.push(on(socket, 'close', bind(this, 'onclose')));\n  this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));\n};\n\n/**\n * Called upon a ping.\n *\n * @api private\n */\n\nManager.prototype.onping = function () {\n  this.lastPing = new Date();\n  this.emitAll('ping');\n};\n\n/**\n * Called upon a packet.\n *\n * @api private\n */\n\nManager.prototype.onpong = function () {\n  this.emitAll('pong', new Date() - this.lastPing);\n};\n\n/**\n * Called with data.\n *\n * @api private\n */\n\nManager.prototype.ondata = function (data) {\n  this.decoder.add(data);\n};\n\n/**\n * Called when parser fully decodes a packet.\n *\n * @api private\n */\n\nManager.prototype.ondecoded = function (packet) {\n  this.emit('packet', packet);\n};\n\n/**\n * Called upon socket error.\n *\n * @api private\n */\n\nManager.prototype.onerror = function (err) {\n  debug('error', err);\n  this.emitAll('error', err);\n};\n\n/**\n * Creates a new socket for the given `nsp`.\n *\n * @return {Socket}\n * @api public\n */\n\nManager.prototype.socket = function (nsp, opts) {\n  var socket = this.nsps[nsp];\n  if (!socket) {\n    socket = new Socket(this, nsp, opts);\n    this.nsps[nsp] = socket;\n    var self = this;\n    socket.on('connecting', onConnecting);\n    socket.on('connect', function () {\n      socket.id = self.engine.id;\n    });\n\n    if (this.autoConnect) {\n      // manually call here since connecting evnet is fired before listening\n      onConnecting();\n    }\n  }\n\n  function onConnecting () {\n    if (!~indexOf(self.connecting, socket)) {\n      self.connecting.push(socket);\n    }\n  }\n\n  return socket;\n};\n\n/**\n * Called upon a socket close.\n *\n * @param {Socket} socket\n */\n\nManager.prototype.destroy = function (socket) {\n  var index = indexOf(this.connecting, socket);\n  if (~index) this.connecting.splice(index, 1);\n  if (this.connecting.length) return;\n\n  this.close();\n};\n\n/**\n * Writes a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nManager.prototype.packet = function (packet) {\n  debug('writing packet %j', packet);\n  var self = this;\n  if (packet.query && packet.type === 0) packet.nsp += '?' + packet.query;\n\n  if (!self.encoding) {\n    // encode, then write to engine with result\n    self.encoding = true;\n    this.encoder.encode(packet, function (encodedPackets) {\n      for (var i = 0; i < encodedPackets.length; i++) {\n        self.engine.write(encodedPackets[i], packet.options);\n      }\n      self.encoding = false;\n      self.processPacketQueue();\n    });\n  } else { // add packet to the queue\n    self.packetBuffer.push(packet);\n  }\n};\n\n/**\n * If packet buffer is non-empty, begins encoding the\n * next packet in line.\n *\n * @api private\n */\n\nManager.prototype.processPacketQueue = function () {\n  if (this.packetBuffer.length > 0 && !this.encoding) {\n    var pack = this.packetBuffer.shift();\n    this.packet(pack);\n  }\n};\n\n/**\n * Clean up transport subscriptions and packet buffer.\n *\n * @api private\n */\n\nManager.prototype.cleanup = function () {\n  debug('cleanup');\n\n  var subsLength = this.subs.length;\n  for (var i = 0; i < subsLength; i++) {\n    var sub = this.subs.shift();\n    sub.destroy();\n  }\n\n  this.packetBuffer = [];\n  this.encoding = false;\n  this.lastPing = null;\n\n  this.decoder.destroy();\n};\n\n/**\n * Close the current socket.\n *\n * @api private\n */\n\nManager.prototype.close =\nManager.prototype.disconnect = function () {\n  debug('disconnect');\n  this.skipReconnect = true;\n  this.reconnecting = false;\n  if ('opening' === this.readyState) {\n    // `onclose` will not fire because\n    // an open event never happened\n    this.cleanup();\n  }\n  this.backoff.reset();\n  this.readyState = 'closed';\n  if (this.engine) this.engine.close();\n};\n\n/**\n * Called upon engine close.\n *\n * @api private\n */\n\nManager.prototype.onclose = function (reason) {\n  debug('onclose');\n\n  this.cleanup();\n  this.backoff.reset();\n  this.readyState = 'closed';\n  this.emit('close', reason);\n\n  if (this._reconnection && !this.skipReconnect) {\n    this.reconnect();\n  }\n};\n\n/**\n * Attempt a reconnection.\n *\n * @api private\n */\n\nManager.prototype.reconnect = function () {\n  if (this.reconnecting || this.skipReconnect) return this;\n\n  var self = this;\n\n  if (this.backoff.attempts >= this._reconnectionAttempts) {\n    debug('reconnect failed');\n    this.backoff.reset();\n    this.emitAll('reconnect_failed');\n    this.reconnecting = false;\n  } else {\n    var delay = this.backoff.duration();\n    debug('will wait %dms before reconnect attempt', delay);\n\n    this.reconnecting = true;\n    var timer = setTimeout(function () {\n      if (self.skipReconnect) return;\n\n      debug('attempting reconnect');\n      self.emitAll('reconnect_attempt', self.backoff.attempts);\n      self.emitAll('reconnecting', self.backoff.attempts);\n\n      // check again for the case socket closed in above events\n      if (self.skipReconnect) return;\n\n      self.open(function (err) {\n        if (err) {\n          debug('reconnect attempt error');\n          self.reconnecting = false;\n          self.reconnect();\n          self.emitAll('reconnect_error', err.data);\n        } else {\n          debug('reconnect success');\n          self.onreconnect();\n        }\n      });\n    }, delay);\n\n    this.subs.push({\n      destroy: function () {\n        clearTimeout(timer);\n      }\n    });\n  }\n};\n\n/**\n * Called upon successful reconnect.\n *\n * @api private\n */\n\nManager.prototype.onreconnect = function () {\n  var attempt = this.backoff.attempts;\n  this.reconnecting = false;\n  this.backoff.reset();\n  this.updateSocketIds();\n  this.emitAll('reconnect', attempt);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMWUxZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvbWFuYWdlci5qcz9mMDk3Il0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBlaW8gPSByZXF1aXJlKCdlbmdpbmUuaW8tY2xpZW50Jyk7XG52YXIgU29ja2V0ID0gcmVxdWlyZSgnLi9zb2NrZXQnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgb24gPSByZXF1aXJlKCcuL29uJyk7XG52YXIgYmluZCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1iaW5kJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdzb2NrZXQuaW8tY2xpZW50Om1hbmFnZXInKTtcbnZhciBpbmRleE9mID0gcmVxdWlyZSgnaW5kZXhvZicpO1xudmFyIEJhY2tvZmYgPSByZXF1aXJlKCdiYWNrbzInKTtcblxuLyoqXG4gKiBJRTYrIGhhc093blByb3BlcnR5XG4gKi9cblxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hbmFnZXI7XG5cbi8qKlxuICogYE1hbmFnZXJgIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBlbmdpbmUgaW5zdGFuY2Ugb3IgZW5naW5lIHVyaS9vcHRzXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBNYW5hZ2VyICh1cmksIG9wdHMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE1hbmFnZXIpKSByZXR1cm4gbmV3IE1hbmFnZXIodXJpLCBvcHRzKTtcbiAgaWYgKHVyaSAmJiAoJ29iamVjdCcgPT09IHR5cGVvZiB1cmkpKSB7XG4gICAgb3B0cyA9IHVyaTtcbiAgICB1cmkgPSB1bmRlZmluZWQ7XG4gIH1cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgb3B0cy5wYXRoID0gb3B0cy5wYXRoIHx8ICcvc29ja2V0LmlvJztcbiAgdGhpcy5uc3BzID0ge307XG4gIHRoaXMuc3VicyA9IFtdO1xuICB0aGlzLm9wdHMgPSBvcHRzO1xuICB0aGlzLnJlY29ubmVjdGlvbihvcHRzLnJlY29ubmVjdGlvbiAhPT0gZmFsc2UpO1xuICB0aGlzLnJlY29ubmVjdGlvbkF0dGVtcHRzKG9wdHMucmVjb25uZWN0aW9uQXR0ZW1wdHMgfHwgSW5maW5pdHkpO1xuICB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KG9wdHMucmVjb25uZWN0aW9uRGVsYXkgfHwgMTAwMCk7XG4gIHRoaXMucmVjb25uZWN0aW9uRGVsYXlNYXgob3B0cy5yZWNvbm5lY3Rpb25EZWxheU1heCB8fCA1MDAwKTtcbiAgdGhpcy5yYW5kb21pemF0aW9uRmFjdG9yKG9wdHMucmFuZG9taXphdGlvbkZhY3RvciB8fCAwLjUpO1xuICB0aGlzLmJhY2tvZmYgPSBuZXcgQmFja29mZih7XG4gICAgbWluOiB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KCksXG4gICAgbWF4OiB0aGlzLnJlY29ubmVjdGlvbkRlbGF5TWF4KCksXG4gICAgaml0dGVyOiB0aGlzLnJhbmRvbWl6YXRpb25GYWN0b3IoKVxuICB9KTtcbiAgdGhpcy50aW1lb3V0KG51bGwgPT0gb3B0cy50aW1lb3V0ID8gMjAwMDAgOiBvcHRzLnRpbWVvdXQpO1xuICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgdGhpcy51cmkgPSB1cmk7XG4gIHRoaXMuY29ubmVjdGluZyA9IFtdO1xuICB0aGlzLmxhc3RQaW5nID0gbnVsbDtcbiAgdGhpcy5lbmNvZGluZyA9IGZhbHNlO1xuICB0aGlzLnBhY2tldEJ1ZmZlciA9IFtdO1xuICB0aGlzLmVuY29kZXIgPSBuZXcgcGFyc2VyLkVuY29kZXIoKTtcbiAgdGhpcy5kZWNvZGVyID0gbmV3IHBhcnNlci5EZWNvZGVyKCk7XG4gIHRoaXMuYXV0b0Nvbm5lY3QgPSBvcHRzLmF1dG9Db25uZWN0ICE9PSBmYWxzZTtcbiAgaWYgKHRoaXMuYXV0b0Nvbm5lY3QpIHRoaXMub3BlbigpO1xufVxuXG4vKipcbiAqIFByb3BhZ2F0ZSBnaXZlbiBldmVudCB0byBzb2NrZXRzIGFuZCBlbWl0IG9uIGB0aGlzYFxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLmVtaXRBbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICBmb3IgKHZhciBuc3AgaW4gdGhpcy5uc3BzKSB7XG4gICAgaWYgKGhhcy5jYWxsKHRoaXMubnNwcywgbnNwKSkge1xuICAgICAgdGhpcy5uc3BzW25zcF0uZW1pdC5hcHBseSh0aGlzLm5zcHNbbnNwXSwgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogVXBkYXRlIGBzb2NrZXQuaWRgIG9mIGFsbCBzb2NrZXRzXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUudXBkYXRlU29ja2V0SWRzID0gZnVuY3Rpb24gKCkge1xuICBmb3IgKHZhciBuc3AgaW4gdGhpcy5uc3BzKSB7XG4gICAgaWYgKGhhcy5jYWxsKHRoaXMubnNwcywgbnNwKSkge1xuICAgICAgdGhpcy5uc3BzW25zcF0uaWQgPSB0aGlzLmVuZ2luZS5pZDtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKE1hbmFnZXIucHJvdG90eXBlKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBgcmVjb25uZWN0aW9uYCBjb25maWcuXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSB0cnVlL2ZhbHNlIGlmIGl0IHNob3VsZCBhdXRvbWF0aWNhbGx5IHJlY29ubmVjdFxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb24gPSBmdW5jdGlvbiAodikge1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb247XG4gIHRoaXMuX3JlY29ubmVjdGlvbiA9ICEhdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIHJlY29ubmVjdGlvbiBhdHRlbXB0cyBjb25maWcuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1heCByZWNvbm5lY3Rpb24gYXR0ZW1wdHMgYmVmb3JlIGdpdmluZyB1cFxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25BdHRlbXB0cyA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JlY29ubmVjdGlvbkF0dGVtcHRzO1xuICB0aGlzLl9yZWNvbm5lY3Rpb25BdHRlbXB0cyA9IHY7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBkZWxheSBiZXR3ZWVuIHJlY29ubmVjdGlvbnMuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGRlbGF5XG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnJlY29ubmVjdGlvbkRlbGF5ID0gZnVuY3Rpb24gKHYpIHtcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fcmVjb25uZWN0aW9uRGVsYXk7XG4gIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5ID0gdjtcbiAgdGhpcy5iYWNrb2ZmICYmIHRoaXMuYmFja29mZi5zZXRNaW4odik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuTWFuYWdlci5wcm90b3R5cGUucmFuZG9taXphdGlvbkZhY3RvciA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JhbmRvbWl6YXRpb25GYWN0b3I7XG4gIHRoaXMuX3JhbmRvbWl6YXRpb25GYWN0b3IgPSB2O1xuICB0aGlzLmJhY2tvZmYgJiYgdGhpcy5iYWNrb2ZmLnNldEppdHRlcih2KTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIG1heGltdW0gZGVsYXkgYmV0d2VlbiByZWNvbm5lY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBkZWxheVxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25EZWxheU1heCA9IGZ1bmN0aW9uICh2KSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5TWF4O1xuICB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheU1heCA9IHY7XG4gIHRoaXMuYmFja29mZiAmJiB0aGlzLmJhY2tvZmYuc2V0TWF4KHYpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgY29ubmVjdGlvbiB0aW1lb3V0LiBgZmFsc2VgIHRvIGRpc2FibGVcbiAqXG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnRpbWVvdXQgPSBmdW5jdGlvbiAodikge1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl90aW1lb3V0O1xuICB0aGlzLl90aW1lb3V0ID0gdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyB0cnlpbmcgdG8gcmVjb25uZWN0IGlmIHJlY29ubmVjdGlvbiBpcyBlbmFibGVkIGFuZCB3ZSBoYXZlIG5vdFxuICogc3RhcnRlZCByZWNvbm5lY3RpbmcgeWV0XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUubWF5YmVSZWNvbm5lY3RPbk9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIC8vIE9ubHkgdHJ5IHRvIHJlY29ubmVjdCBpZiBpdCdzIHRoZSBmaXJzdCB0aW1lIHdlJ3JlIGNvbm5lY3RpbmdcbiAgaWYgKCF0aGlzLnJlY29ubmVjdGluZyAmJiB0aGlzLl9yZWNvbm5lY3Rpb24gJiYgdGhpcy5iYWNrb2ZmLmF0dGVtcHRzID09PSAwKSB7XG4gICAgLy8ga2VlcHMgcmVjb25uZWN0aW9uIGZyb20gZmlyaW5nIHR3aWNlIGZvciB0aGUgc2FtZSByZWNvbm5lY3Rpb24gbG9vcFxuICAgIHRoaXMucmVjb25uZWN0KCk7XG4gIH1cbn07XG5cbi8qKlxuICogU2V0cyB0aGUgY3VycmVudCB0cmFuc3BvcnQgYHNvY2tldGAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gb3B0aW9uYWwsIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9wZW4gPVxuTWFuYWdlci5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uIChmbiwgb3B0cykge1xuICBkZWJ1ZygncmVhZHlTdGF0ZSAlcycsIHRoaXMucmVhZHlTdGF0ZSk7XG4gIGlmICh+dGhpcy5yZWFkeVN0YXRlLmluZGV4T2YoJ29wZW4nKSkgcmV0dXJuIHRoaXM7XG5cbiAgZGVidWcoJ29wZW5pbmcgJXMnLCB0aGlzLnVyaSk7XG4gIHRoaXMuZW5naW5lID0gZWlvKHRoaXMudXJpLCB0aGlzLm9wdHMpO1xuICB2YXIgc29ja2V0ID0gdGhpcy5lbmdpbmU7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW5pbmcnO1xuICB0aGlzLnNraXBSZWNvbm5lY3QgPSBmYWxzZTtcblxuICAvLyBlbWl0IGBvcGVuYFxuICB2YXIgb3BlblN1YiA9IG9uKHNvY2tldCwgJ29wZW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5vbm9wZW4oKTtcbiAgICBmbiAmJiBmbigpO1xuICB9KTtcblxuICAvLyBlbWl0IGBjb25uZWN0X2Vycm9yYFxuICB2YXIgZXJyb3JTdWIgPSBvbihzb2NrZXQsICdlcnJvcicsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgZGVidWcoJ2Nvbm5lY3RfZXJyb3InKTtcbiAgICBzZWxmLmNsZWFudXAoKTtcbiAgICBzZWxmLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgICBzZWxmLmVtaXRBbGwoJ2Nvbm5lY3RfZXJyb3InLCBkYXRhKTtcbiAgICBpZiAoZm4pIHtcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gZXJyb3InKTtcbiAgICAgIGVyci5kYXRhID0gZGF0YTtcbiAgICAgIGZuKGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE9ubHkgZG8gdGhpcyBpZiB0aGVyZSBpcyBubyBmbiB0byBoYW5kbGUgdGhlIGVycm9yXG4gICAgICBzZWxmLm1heWJlUmVjb25uZWN0T25PcGVuKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBlbWl0IGBjb25uZWN0X3RpbWVvdXRgXG4gIGlmIChmYWxzZSAhPT0gdGhpcy5fdGltZW91dCkge1xuICAgIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgICBkZWJ1ZygnY29ubmVjdCBhdHRlbXB0IHdpbGwgdGltZW91dCBhZnRlciAlZCcsIHRpbWVvdXQpO1xuXG4gICAgLy8gc2V0IHRpbWVyXG4gICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBkZWJ1ZygnY29ubmVjdCBhdHRlbXB0IHRpbWVkIG91dCBhZnRlciAlZCcsIHRpbWVvdXQpO1xuICAgICAgb3BlblN1Yi5kZXN0cm95KCk7XG4gICAgICBzb2NrZXQuY2xvc2UoKTtcbiAgICAgIHNvY2tldC5lbWl0KCdlcnJvcicsICd0aW1lb3V0Jyk7XG4gICAgICBzZWxmLmVtaXRBbGwoJ2Nvbm5lY3RfdGltZW91dCcsIHRpbWVvdXQpO1xuICAgIH0sIHRpbWVvdXQpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdGhpcy5zdWJzLnB1c2gob3BlblN1Yik7XG4gIHRoaXMuc3Vicy5wdXNoKGVycm9yU3ViKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IG9wZW4uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25vcGVuID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1Zygnb3BlbicpO1xuXG4gIC8vIGNsZWFyIG9sZCBzdWJzXG4gIHRoaXMuY2xlYW51cCgpO1xuXG4gIC8vIG1hcmsgYXMgb3BlblxuICB0aGlzLnJlYWR5U3RhdGUgPSAnb3Blbic7XG4gIHRoaXMuZW1pdCgnb3BlbicpO1xuXG4gIC8vIGFkZCBuZXcgc3Vic1xuICB2YXIgc29ja2V0ID0gdGhpcy5lbmdpbmU7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2RhdGEnLCBiaW5kKHRoaXMsICdvbmRhdGEnKSkpO1xuICB0aGlzLnN1YnMucHVzaChvbihzb2NrZXQsICdwaW5nJywgYmluZCh0aGlzLCAnb25waW5nJykpKTtcbiAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAncG9uZycsIGJpbmQodGhpcywgJ29ucG9uZycpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2Vycm9yJywgYmluZCh0aGlzLCAnb25lcnJvcicpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2Nsb3NlJywgYmluZCh0aGlzLCAnb25jbG9zZScpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHRoaXMuZGVjb2RlciwgJ2RlY29kZWQnLCBiaW5kKHRoaXMsICdvbmRlY29kZWQnKSkpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBhIHBpbmcuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25waW5nID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmxhc3RQaW5nID0gbmV3IERhdGUoKTtcbiAgdGhpcy5lbWl0QWxsKCdwaW5nJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgcGFja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9ucG9uZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0QWxsKCdwb25nJywgbmV3IERhdGUoKSAtIHRoaXMubGFzdFBpbmcpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgd2l0aCBkYXRhLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uZGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuZGVjb2Rlci5hZGQoZGF0YSk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aGVuIHBhcnNlciBmdWxseSBkZWNvZGVzIGEgcGFja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uZGVjb2RlZCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzb2NrZXQgZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25lcnJvciA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgZGVidWcoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5lbWl0QWxsKCdlcnJvcicsIGVycik7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc29ja2V0IGZvciB0aGUgZ2l2ZW4gYG5zcGAuXG4gKlxuICogQHJldHVybiB7U29ja2V0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5zb2NrZXQgPSBmdW5jdGlvbiAobnNwLCBvcHRzKSB7XG4gIHZhciBzb2NrZXQgPSB0aGlzLm5zcHNbbnNwXTtcbiAgaWYgKCFzb2NrZXQpIHtcbiAgICBzb2NrZXQgPSBuZXcgU29ja2V0KHRoaXMsIG5zcCwgb3B0cyk7XG4gICAgdGhpcy5uc3BzW25zcF0gPSBzb2NrZXQ7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHNvY2tldC5vbignY29ubmVjdGluZycsIG9uQ29ubmVjdGluZyk7XG4gICAgc29ja2V0Lm9uKCdjb25uZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgc29ja2V0LmlkID0gc2VsZi5lbmdpbmUuaWQ7XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5hdXRvQ29ubmVjdCkge1xuICAgICAgLy8gbWFudWFsbHkgY2FsbCBoZXJlIHNpbmNlIGNvbm5lY3RpbmcgZXZuZXQgaXMgZmlyZWQgYmVmb3JlIGxpc3RlbmluZ1xuICAgICAgb25Db25uZWN0aW5nKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25Db25uZWN0aW5nICgpIHtcbiAgICBpZiAoIX5pbmRleE9mKHNlbGYuY29ubmVjdGluZywgc29ja2V0KSkge1xuICAgICAgc2VsZi5jb25uZWN0aW5nLnB1c2goc29ja2V0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc29ja2V0O1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBhIHNvY2tldCBjbG9zZS5cbiAqXG4gKiBAcGFyYW0ge1NvY2tldH0gc29ja2V0XG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uIChzb2NrZXQpIHtcbiAgdmFyIGluZGV4ID0gaW5kZXhPZih0aGlzLmNvbm5lY3RpbmcsIHNvY2tldCk7XG4gIGlmICh+aW5kZXgpIHRoaXMuY29ubmVjdGluZy5zcGxpY2UoaW5kZXgsIDEpO1xuICBpZiAodGhpcy5jb25uZWN0aW5nLmxlbmd0aCkgcmV0dXJuO1xuXG4gIHRoaXMuY2xvc2UoKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgcGFja2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgZGVidWcoJ3dyaXRpbmcgcGFja2V0ICVqJywgcGFja2V0KTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAocGFja2V0LnF1ZXJ5ICYmIHBhY2tldC50eXBlID09PSAwKSBwYWNrZXQubnNwICs9ICc/JyArIHBhY2tldC5xdWVyeTtcblxuICBpZiAoIXNlbGYuZW5jb2RpbmcpIHtcbiAgICAvLyBlbmNvZGUsIHRoZW4gd3JpdGUgdG8gZW5naW5lIHdpdGggcmVzdWx0XG4gICAgc2VsZi5lbmNvZGluZyA9IHRydWU7XG4gICAgdGhpcy5lbmNvZGVyLmVuY29kZShwYWNrZXQsIGZ1bmN0aW9uIChlbmNvZGVkUGFja2V0cykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbmNvZGVkUGFja2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBzZWxmLmVuZ2luZS53cml0ZShlbmNvZGVkUGFja2V0c1tpXSwgcGFja2V0Lm9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgc2VsZi5lbmNvZGluZyA9IGZhbHNlO1xuICAgICAgc2VsZi5wcm9jZXNzUGFja2V0UXVldWUoKTtcbiAgICB9KTtcbiAgfSBlbHNlIHsgLy8gYWRkIHBhY2tldCB0byB0aGUgcXVldWVcbiAgICBzZWxmLnBhY2tldEJ1ZmZlci5wdXNoKHBhY2tldCk7XG4gIH1cbn07XG5cbi8qKlxuICogSWYgcGFja2V0IGJ1ZmZlciBpcyBub24tZW1wdHksIGJlZ2lucyBlbmNvZGluZyB0aGVcbiAqIG5leHQgcGFja2V0IGluIGxpbmUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUucHJvY2Vzc1BhY2tldFF1ZXVlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5wYWNrZXRCdWZmZXIubGVuZ3RoID4gMCAmJiAhdGhpcy5lbmNvZGluZykge1xuICAgIHZhciBwYWNrID0gdGhpcy5wYWNrZXRCdWZmZXIuc2hpZnQoKTtcbiAgICB0aGlzLnBhY2tldChwYWNrKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDbGVhbiB1cCB0cmFuc3BvcnQgc3Vic2NyaXB0aW9ucyBhbmQgcGFja2V0IGJ1ZmZlci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5jbGVhbnVwID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2xlYW51cCcpO1xuXG4gIHZhciBzdWJzTGVuZ3RoID0gdGhpcy5zdWJzLmxlbmd0aDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdWJzTGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc3ViID0gdGhpcy5zdWJzLnNoaWZ0KCk7XG4gICAgc3ViLmRlc3Ryb3koKTtcbiAgfVxuXG4gIHRoaXMucGFja2V0QnVmZmVyID0gW107XG4gIHRoaXMuZW5jb2RpbmcgPSBmYWxzZTtcbiAgdGhpcy5sYXN0UGluZyA9IG51bGw7XG5cbiAgdGhpcy5kZWNvZGVyLmRlc3Ryb3koKTtcbn07XG5cbi8qKlxuICogQ2xvc2UgdGhlIGN1cnJlbnQgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLmNsb3NlID1cbk1hbmFnZXIucHJvdG90eXBlLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCdkaXNjb25uZWN0Jyk7XG4gIHRoaXMuc2tpcFJlY29ubmVjdCA9IHRydWU7XG4gIHRoaXMucmVjb25uZWN0aW5nID0gZmFsc2U7XG4gIGlmICgnb3BlbmluZycgPT09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIC8vIGBvbmNsb3NlYCB3aWxsIG5vdCBmaXJlIGJlY2F1c2VcbiAgICAvLyBhbiBvcGVuIGV2ZW50IG5ldmVyIGhhcHBlbmVkXG4gICAgdGhpcy5jbGVhbnVwKCk7XG4gIH1cbiAgdGhpcy5iYWNrb2ZmLnJlc2V0KCk7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuICBpZiAodGhpcy5lbmdpbmUpIHRoaXMuZW5naW5lLmNsb3NlKCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGVuZ2luZSBjbG9zZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vbmNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICBkZWJ1Zygnb25jbG9zZScpO1xuXG4gIHRoaXMuY2xlYW51cCgpO1xuICB0aGlzLmJhY2tvZmYucmVzZXQoKTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnLCByZWFzb24pO1xuXG4gIGlmICh0aGlzLl9yZWNvbm5lY3Rpb24gJiYgIXRoaXMuc2tpcFJlY29ubmVjdCkge1xuICAgIHRoaXMucmVjb25uZWN0KCk7XG4gIH1cbn07XG5cbi8qKlxuICogQXR0ZW1wdCBhIHJlY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnJlY29ubmVjdGluZyB8fCB0aGlzLnNraXBSZWNvbm5lY3QpIHJldHVybiB0aGlzO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAodGhpcy5iYWNrb2ZmLmF0dGVtcHRzID49IHRoaXMuX3JlY29ubmVjdGlvbkF0dGVtcHRzKSB7XG4gICAgZGVidWcoJ3JlY29ubmVjdCBmYWlsZWQnKTtcbiAgICB0aGlzLmJhY2tvZmYucmVzZXQoKTtcbiAgICB0aGlzLmVtaXRBbGwoJ3JlY29ubmVjdF9mYWlsZWQnKTtcbiAgICB0aGlzLnJlY29ubmVjdGluZyA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHZhciBkZWxheSA9IHRoaXMuYmFja29mZi5kdXJhdGlvbigpO1xuICAgIGRlYnVnKCd3aWxsIHdhaXQgJWRtcyBiZWZvcmUgcmVjb25uZWN0IGF0dGVtcHQnLCBkZWxheSk7XG5cbiAgICB0aGlzLnJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoc2VsZi5za2lwUmVjb25uZWN0KSByZXR1cm47XG5cbiAgICAgIGRlYnVnKCdhdHRlbXB0aW5nIHJlY29ubmVjdCcpO1xuICAgICAgc2VsZi5lbWl0QWxsKCdyZWNvbm5lY3RfYXR0ZW1wdCcsIHNlbGYuYmFja29mZi5hdHRlbXB0cyk7XG4gICAgICBzZWxmLmVtaXRBbGwoJ3JlY29ubmVjdGluZycsIHNlbGYuYmFja29mZi5hdHRlbXB0cyk7XG5cbiAgICAgIC8vIGNoZWNrIGFnYWluIGZvciB0aGUgY2FzZSBzb2NrZXQgY2xvc2VkIGluIGFib3ZlIGV2ZW50c1xuICAgICAgaWYgKHNlbGYuc2tpcFJlY29ubmVjdCkgcmV0dXJuO1xuXG4gICAgICBzZWxmLm9wZW4oZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgZGVidWcoJ3JlY29ubmVjdCBhdHRlbXB0IGVycm9yJyk7XG4gICAgICAgICAgc2VsZi5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLnJlY29ubmVjdCgpO1xuICAgICAgICAgIHNlbGYuZW1pdEFsbCgncmVjb25uZWN0X2Vycm9yJywgZXJyLmRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlYnVnKCdyZWNvbm5lY3Qgc3VjY2VzcycpO1xuICAgICAgICAgIHNlbGYub25yZWNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSwgZGVsYXkpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHN1Y2Nlc3NmdWwgcmVjb25uZWN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9ucmVjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXR0ZW1wdCA9IHRoaXMuYmFja29mZi5hdHRlbXB0cztcbiAgdGhpcy5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgdGhpcy5iYWNrb2ZmLnJlc2V0KCk7XG4gIHRoaXMudXBkYXRlU29ja2V0SWRzKCk7XG4gIHRoaXMuZW1pdEFsbCgncmVjb25uZWN0JywgYXR0ZW1wdCk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1e1f\n")},"1ed2":function(module,exports){eval("/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function(val, options){\n  options = options || {};\n  if ('string' == typeof val) return parse(val);\n  return options.long\n    ? long(val)\n    : short(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n  str = '' + str;\n  if (str.length > 10000) return;\n  var match = /^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);\n  if (!match) return;\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'yrs':\n    case 'yr':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'hrs':\n    case 'hr':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'mins':\n    case 'min':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 'secs':\n    case 'sec':\n    case 's':\n      return n * s;\n    case 'milliseconds':\n    case 'millisecond':\n    case 'msecs':\n    case 'msec':\n    case 'ms':\n      return n;\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction short(ms) {\n  if (ms >= d) return Math.round(ms / d) + 'd';\n  if (ms >= h) return Math.round(ms / h) + 'h';\n  if (ms >= m) return Math.round(ms / m) + 'm';\n  if (ms >= s) return Math.round(ms / s) + 's';\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction long(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, n, name) {\n  if (ms < n) return;\n  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMWVkMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvbXMvaW5kZXguanM/NDg1MiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhlbHBlcnMuXG4gKi9cblxudmFyIHMgPSAxMDAwO1xudmFyIG0gPSBzICogNjA7XG52YXIgaCA9IG0gKiA2MDtcbnZhciBkID0gaCAqIDI0O1xudmFyIHkgPSBkICogMzY1LjI1O1xuXG4vKipcbiAqIFBhcnNlIG9yIGZvcm1hdCB0aGUgZ2l2ZW4gYHZhbGAuXG4gKlxuICogT3B0aW9uczpcbiAqXG4gKiAgLSBgbG9uZ2AgdmVyYm9zZSBmb3JtYXR0aW5nIFtmYWxzZV1cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xOdW1iZXJ9IHZhbFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ3xOdW1iZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24odmFsLCBvcHRpb25zKXtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGlmICgnc3RyaW5nJyA9PSB0eXBlb2YgdmFsKSByZXR1cm4gcGFyc2UodmFsKTtcbiAgcmV0dXJuIG9wdGlvbnMubG9uZ1xuICAgID8gbG9uZyh2YWwpXG4gICAgOiBzaG9ydCh2YWwpO1xufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gYHN0cmAgYW5kIHJldHVybiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7TnVtYmVyfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcGFyc2Uoc3RyKSB7XG4gIHN0ciA9ICcnICsgc3RyO1xuICBpZiAoc3RyLmxlbmd0aCA+IDEwMDAwKSByZXR1cm47XG4gIHZhciBtYXRjaCA9IC9eKCg/OlxcZCspP1xcLj9cXGQrKSAqKG1pbGxpc2Vjb25kcz98bXNlY3M/fG1zfHNlY29uZHM/fHNlY3M/fHN8bWludXRlcz98bWlucz98bXxob3Vycz98aHJzP3xofGRheXM/fGR8eWVhcnM/fHlycz98eSk/JC9pLmV4ZWMoc3RyKTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuO1xuICB2YXIgbiA9IHBhcnNlRmxvYXQobWF0Y2hbMV0pO1xuICB2YXIgdHlwZSA9IChtYXRjaFsyXSB8fCAnbXMnKS50b0xvd2VyQ2FzZSgpO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICd5ZWFycyc6XG4gICAgY2FzZSAneWVhcic6XG4gICAgY2FzZSAneXJzJzpcbiAgICBjYXNlICd5cic6XG4gICAgY2FzZSAneSc6XG4gICAgICByZXR1cm4gbiAqIHk7XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZDtcbiAgICBjYXNlICdob3Vycyc6XG4gICAgY2FzZSAnaG91cic6XG4gICAgY2FzZSAnaHJzJzpcbiAgICBjYXNlICdocic6XG4gICAgY2FzZSAnaCc6XG4gICAgICByZXR1cm4gbiAqIGg7XG4gICAgY2FzZSAnbWludXRlcyc6XG4gICAgY2FzZSAnbWludXRlJzpcbiAgICBjYXNlICdtaW5zJzpcbiAgICBjYXNlICdtaW4nOlxuICAgIGNhc2UgJ20nOlxuICAgICAgcmV0dXJuIG4gKiBtO1xuICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgY2FzZSAnc2Vjcyc6XG4gICAgY2FzZSAnc2VjJzpcbiAgICBjYXNlICdzJzpcbiAgICAgIHJldHVybiBuICogcztcbiAgICBjYXNlICdtaWxsaXNlY29uZHMnOlxuICAgIGNhc2UgJ21pbGxpc2Vjb25kJzpcbiAgICBjYXNlICdtc2Vjcyc6XG4gICAgY2FzZSAnbXNlYyc6XG4gICAgY2FzZSAnbXMnOlxuICAgICAgcmV0dXJuIG47XG4gIH1cbn1cblxuLyoqXG4gKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzaG9ydChtcykge1xuICBpZiAobXMgPj0gZCkgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArICdkJztcbiAgaWYgKG1zID49IGgpIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gaCkgKyAnaCc7XG4gIGlmIChtcyA+PSBtKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIG0pICsgJ20nO1xuICBpZiAobXMgPj0gcykgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArICdzJztcbiAgcmV0dXJuIG1zICsgJ21zJztcbn1cblxuLyoqXG4gKiBMb25nIGZvcm1hdCBmb3IgYG1zYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbXNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvbmcobXMpIHtcbiAgcmV0dXJuIHBsdXJhbChtcywgZCwgJ2RheScpXG4gICAgfHwgcGx1cmFsKG1zLCBoLCAnaG91cicpXG4gICAgfHwgcGx1cmFsKG1zLCBtLCAnbWludXRlJylcbiAgICB8fCBwbHVyYWwobXMsIHMsICdzZWNvbmQnKVxuICAgIHx8IG1zICsgJyBtcyc7XG59XG5cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi9cblxuZnVuY3Rpb24gcGx1cmFsKG1zLCBuLCBuYW1lKSB7XG4gIGlmIChtcyA8IG4pIHJldHVybjtcbiAgaWYgKG1zIDwgbiAqIDEuNSkgcmV0dXJuIE1hdGguZmxvb3IobXMgLyBuKSArICcgJyArIG5hbWU7XG4gIHJldHVybiBNYXRoLmNlaWwobXMgLyBuKSArICcgJyArIG5hbWUgKyAncyc7XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1ed2\n")},"23b1":function(module,exports,__webpack_require__){eval("\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = debug.debug = debug;\nexports.coerce = coerce;\nexports.disable = disable;\nexports.enable = enable;\nexports.enabled = enabled;\nexports.humanize = __webpack_require__(/*! ms */ \"0b10\");\n\n/**\n * The currently active debug mode names, and names to skip.\n */\n\nexports.names = [];\nexports.skips = [];\n\n/**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lowercased letter, i.e. \"n\".\n */\n\nexports.formatters = {};\n\n/**\n * Previously assigned color.\n */\n\nvar prevColor = 0;\n\n/**\n * Previous log timestamp.\n */\n\nvar prevTime;\n\n/**\n * Select a color.\n *\n * @return {Number}\n * @api private\n */\n\nfunction selectColor() {\n  return exports.colors[prevColor++ % exports.colors.length];\n}\n\n/**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\nfunction debug(namespace) {\n\n  // define the `disabled` version\n  function disabled() {\n  }\n  disabled.enabled = false;\n\n  // define the `enabled` version\n  function enabled() {\n\n    var self = enabled;\n\n    // set `diff` timestamp\n    var curr = +new Date();\n    var ms = curr - (prevTime || curr);\n    self.diff = ms;\n    self.prev = prevTime;\n    self.curr = curr;\n    prevTime = curr;\n\n    // add the `color` if not set\n    if (null == self.useColors) self.useColors = exports.useColors();\n    if (null == self.color && self.useColors) self.color = selectColor();\n\n    var args = new Array(arguments.length);\n    for (var i = 0; i < args.length; i++) {\n      args[i] = arguments[i];\n    }\n\n    args[0] = exports.coerce(args[0]);\n\n    if ('string' !== typeof args[0]) {\n      // anything else let's inspect with %o\n      args = ['%o'].concat(args);\n    }\n\n    // apply any `formatters` transformations\n    var index = 0;\n    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {\n      // if we encounter an escaped % then don't increase the array index\n      if (match === '%%') return match;\n      index++;\n      var formatter = exports.formatters[format];\n      if ('function' === typeof formatter) {\n        var val = args[index];\n        match = formatter.call(self, val);\n\n        // now we need to remove `args[index]` since it's inlined in the `format`\n        args.splice(index, 1);\n        index--;\n      }\n      return match;\n    });\n\n    // apply env-specific formatting\n    args = exports.formatArgs.apply(self, args);\n\n    var logFn = enabled.log || exports.log || console.log.bind(console);\n    logFn.apply(self, args);\n  }\n  enabled.enabled = true;\n\n  var fn = exports.enabled(namespace) ? enabled : disabled;\n\n  fn.namespace = namespace;\n\n  return fn;\n}\n\n/**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\nfunction enable(namespaces) {\n  exports.save(namespaces);\n\n  var split = (namespaces || '').split(/[\\s,]+/);\n  var len = split.length;\n\n  for (var i = 0; i < len; i++) {\n    if (!split[i]) continue; // ignore empty strings\n    namespaces = split[i].replace(/[\\\\^$+?.()|[\\]{}]/g, '\\\\$&').replace(/\\*/g, '.*?');\n    if (namespaces[0] === '-') {\n      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n    } else {\n      exports.names.push(new RegExp('^' + namespaces + '$'));\n    }\n  }\n}\n\n/**\n * Disable debug output.\n *\n * @api public\n */\n\nfunction disable() {\n  exports.enable('');\n}\n\n/**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\nfunction enabled(name) {\n  var i, len;\n  for (i = 0, len = exports.skips.length; i < len; i++) {\n    if (exports.skips[i].test(name)) {\n      return false;\n    }\n  }\n  for (i = 0, len = exports.names.length; i < len; i++) {\n    if (exports.names[i].test(name)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\nfunction coerce(val) {\n  if (val instanceof Error) return val.stack || val.message;\n  return val;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjNiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZGVidWcvZGVidWcuanM/NjMxMiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogVGhpcyBpcyB0aGUgY29tbW9uIGxvZ2ljIGZvciBib3RoIHRoZSBOb2RlLmpzIGFuZCB3ZWIgYnJvd3NlclxuICogaW1wbGVtZW50YXRpb25zIG9mIGBkZWJ1ZygpYC5cbiAqXG4gKiBFeHBvc2UgYGRlYnVnKClgIGFzIHRoZSBtb2R1bGUuXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZGVidWcuZGVidWcgPSBkZWJ1ZztcbmV4cG9ydHMuY29lcmNlID0gY29lcmNlO1xuZXhwb3J0cy5kaXNhYmxlID0gZGlzYWJsZTtcbmV4cG9ydHMuZW5hYmxlID0gZW5hYmxlO1xuZXhwb3J0cy5lbmFibGVkID0gZW5hYmxlZDtcbmV4cG9ydHMuaHVtYW5pemUgPSByZXF1aXJlKCdtcycpO1xuXG4vKipcbiAqIFRoZSBjdXJyZW50bHkgYWN0aXZlIGRlYnVnIG1vZGUgbmFtZXMsIGFuZCBuYW1lcyB0byBza2lwLlxuICovXG5cbmV4cG9ydHMubmFtZXMgPSBbXTtcbmV4cG9ydHMuc2tpcHMgPSBbXTtcblxuLyoqXG4gKiBNYXAgb2Ygc3BlY2lhbCBcIiVuXCIgaGFuZGxpbmcgZnVuY3Rpb25zLCBmb3IgdGhlIGRlYnVnIFwiZm9ybWF0XCIgYXJndW1lbnQuXG4gKlxuICogVmFsaWQga2V5IG5hbWVzIGFyZSBhIHNpbmdsZSwgbG93ZXJjYXNlZCBsZXR0ZXIsIGkuZS4gXCJuXCIuXG4gKi9cblxuZXhwb3J0cy5mb3JtYXR0ZXJzID0ge307XG5cbi8qKlxuICogUHJldmlvdXNseSBhc3NpZ25lZCBjb2xvci5cbiAqL1xuXG52YXIgcHJldkNvbG9yID0gMDtcblxuLyoqXG4gKiBQcmV2aW91cyBsb2cgdGltZXN0YW1wLlxuICovXG5cbnZhciBwcmV2VGltZTtcblxuLyoqXG4gKiBTZWxlY3QgYSBjb2xvci5cbiAqXG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzZWxlY3RDb2xvcigpIHtcbiAgcmV0dXJuIGV4cG9ydHMuY29sb3JzW3ByZXZDb2xvcisrICUgZXhwb3J0cy5jb2xvcnMubGVuZ3RoXTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBkZWJ1Z2dlciB3aXRoIHRoZSBnaXZlbiBgbmFtZXNwYWNlYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZGVidWcobmFtZXNwYWNlKSB7XG5cbiAgLy8gZGVmaW5lIHRoZSBgZGlzYWJsZWRgIHZlcnNpb25cbiAgZnVuY3Rpb24gZGlzYWJsZWQoKSB7XG4gIH1cbiAgZGlzYWJsZWQuZW5hYmxlZCA9IGZhbHNlO1xuXG4gIC8vIGRlZmluZSB0aGUgYGVuYWJsZWRgIHZlcnNpb25cbiAgZnVuY3Rpb24gZW5hYmxlZCgpIHtcblxuICAgIHZhciBzZWxmID0gZW5hYmxlZDtcblxuICAgIC8vIHNldCBgZGlmZmAgdGltZXN0YW1wXG4gICAgdmFyIGN1cnIgPSArbmV3IERhdGUoKTtcbiAgICB2YXIgbXMgPSBjdXJyIC0gKHByZXZUaW1lIHx8IGN1cnIpO1xuICAgIHNlbGYuZGlmZiA9IG1zO1xuICAgIHNlbGYucHJldiA9IHByZXZUaW1lO1xuICAgIHNlbGYuY3VyciA9IGN1cnI7XG4gICAgcHJldlRpbWUgPSBjdXJyO1xuXG4gICAgLy8gYWRkIHRoZSBgY29sb3JgIGlmIG5vdCBzZXRcbiAgICBpZiAobnVsbCA9PSBzZWxmLnVzZUNvbG9ycykgc2VsZi51c2VDb2xvcnMgPSBleHBvcnRzLnVzZUNvbG9ycygpO1xuICAgIGlmIChudWxsID09IHNlbGYuY29sb3IgJiYgc2VsZi51c2VDb2xvcnMpIHNlbGYuY29sb3IgPSBzZWxlY3RDb2xvcigpO1xuXG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgIH1cblxuICAgIGFyZ3NbMF0gPSBleHBvcnRzLmNvZXJjZShhcmdzWzBdKTtcblxuICAgIGlmICgnc3RyaW5nJyAhPT0gdHlwZW9mIGFyZ3NbMF0pIHtcbiAgICAgIC8vIGFueXRoaW5nIGVsc2UgbGV0J3MgaW5zcGVjdCB3aXRoICVvXG4gICAgICBhcmdzID0gWyclbyddLmNvbmNhdChhcmdzKTtcbiAgICB9XG5cbiAgICAvLyBhcHBseSBhbnkgYGZvcm1hdHRlcnNgIHRyYW5zZm9ybWF0aW9uc1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgYXJnc1swXSA9IGFyZ3NbMF0ucmVwbGFjZSgvJShbYS16JV0pL2csIGZ1bmN0aW9uKG1hdGNoLCBmb3JtYXQpIHtcbiAgICAgIC8vIGlmIHdlIGVuY291bnRlciBhbiBlc2NhcGVkICUgdGhlbiBkb24ndCBpbmNyZWFzZSB0aGUgYXJyYXkgaW5kZXhcbiAgICAgIGlmIChtYXRjaCA9PT0gJyUlJykgcmV0dXJuIG1hdGNoO1xuICAgICAgaW5kZXgrKztcbiAgICAgIHZhciBmb3JtYXR0ZXIgPSBleHBvcnRzLmZvcm1hdHRlcnNbZm9ybWF0XTtcbiAgICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgZm9ybWF0dGVyKSB7XG4gICAgICAgIHZhciB2YWwgPSBhcmdzW2luZGV4XTtcbiAgICAgICAgbWF0Y2ggPSBmb3JtYXR0ZXIuY2FsbChzZWxmLCB2YWwpO1xuXG4gICAgICAgIC8vIG5vdyB3ZSBuZWVkIHRvIHJlbW92ZSBgYXJnc1tpbmRleF1gIHNpbmNlIGl0J3MgaW5saW5lZCBpbiB0aGUgYGZvcm1hdGBcbiAgICAgICAgYXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBpbmRleC0tO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH0pO1xuXG4gICAgLy8gYXBwbHkgZW52LXNwZWNpZmljIGZvcm1hdHRpbmdcbiAgICBhcmdzID0gZXhwb3J0cy5mb3JtYXRBcmdzLmFwcGx5KHNlbGYsIGFyZ3MpO1xuXG4gICAgdmFyIGxvZ0ZuID0gZW5hYmxlZC5sb2cgfHwgZXhwb3J0cy5sb2cgfHwgY29uc29sZS5sb2cuYmluZChjb25zb2xlKTtcbiAgICBsb2dGbi5hcHBseShzZWxmLCBhcmdzKTtcbiAgfVxuICBlbmFibGVkLmVuYWJsZWQgPSB0cnVlO1xuXG4gIHZhciBmbiA9IGV4cG9ydHMuZW5hYmxlZChuYW1lc3BhY2UpID8gZW5hYmxlZCA6IGRpc2FibGVkO1xuXG4gIGZuLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTtcblxuICByZXR1cm4gZm47XG59XG5cbi8qKlxuICogRW5hYmxlcyBhIGRlYnVnIG1vZGUgYnkgbmFtZXNwYWNlcy4gVGhpcyBjYW4gaW5jbHVkZSBtb2Rlc1xuICogc2VwYXJhdGVkIGJ5IGEgY29sb24gYW5kIHdpbGRjYXJkcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGUobmFtZXNwYWNlcykge1xuICBleHBvcnRzLnNhdmUobmFtZXNwYWNlcyk7XG5cbiAgdmFyIHNwbGl0ID0gKG5hbWVzcGFjZXMgfHwgJycpLnNwbGl0KC9bXFxzLF0rLyk7XG4gIHZhciBsZW4gPSBzcGxpdC5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGlmICghc3BsaXRbaV0pIGNvbnRpbnVlOyAvLyBpZ25vcmUgZW1wdHkgc3RyaW5nc1xuICAgIG5hbWVzcGFjZXMgPSBzcGxpdFtpXS5yZXBsYWNlKC9bXFxcXF4kKz8uKCl8W1xcXXt9XS9nLCAnXFxcXCQmJykucmVwbGFjZSgvXFwqL2csICcuKj8nKTtcbiAgICBpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG4gICAgICBleHBvcnRzLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzLnN1YnN0cigxKSArICckJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzICsgJyQnKSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGlzYWJsZSBkZWJ1ZyBvdXRwdXQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkaXNhYmxlKCkge1xuICBleHBvcnRzLmVuYWJsZSgnJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RlIG5hbWUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGVkKG5hbWUpIHtcbiAgdmFyIGksIGxlbjtcbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLnNraXBzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5uYW1lcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLm5hbWVzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29lcmNlIGB2YWxgLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjb2VyY2UodmFsKSB7XG4gIGlmICh2YWwgaW5zdGFuY2VvZiBFcnJvcikgcmV0dXJuIHZhbC5zdGFjayB8fCB2YWwubWVzc2FnZTtcbiAgcmV0dXJuIHZhbDtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///23b1\n")},"2dce":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {\n/**\n * Module requirements.\n */\n\nvar Polling = __webpack_require__(/*! ./polling */ \"181d\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = JSONPPolling;\n\n/**\n * Cached regular expressions.\n */\n\nvar rNewline = /\\n/g;\nvar rEscapedNewline = /\\\\n/g;\n\n/**\n * Global JSONP callbacks.\n */\n\nvar callbacks;\n\n/**\n * Noop.\n */\n\nfunction empty () { }\n\n/**\n * JSONP Polling constructor.\n *\n * @param {Object} opts.\n * @api public\n */\n\nfunction JSONPPolling (opts) {\n  Polling.call(this, opts);\n\n  this.query = this.query || {};\n\n  // define global callbacks array if not present\n  // we do this here (lazily) to avoid unneeded global pollution\n  if (!callbacks) {\n    // we need to consider multiple engines in the same page\n    if (!global.___eio) global.___eio = [];\n    callbacks = global.___eio;\n  }\n\n  // callback identifier\n  this.index = callbacks.length;\n\n  // add callback to jsonp global\n  var self = this;\n  callbacks.push(function (msg) {\n    self.onData(msg);\n  });\n\n  // append to query string\n  this.query.j = this.index;\n\n  // prevent spurious errors from being emitted when the window is unloaded\n  if (global.document && global.addEventListener) {\n    global.addEventListener('beforeunload', function () {\n      if (self.script) self.script.onerror = empty;\n    }, false);\n  }\n}\n\n/**\n * Inherits from Polling.\n */\n\ninherit(JSONPPolling, Polling);\n\n/*\n * JSONP only supports binary as base64 encoded strings\n */\n\nJSONPPolling.prototype.supportsBinary = false;\n\n/**\n * Closes the socket.\n *\n * @api private\n */\n\nJSONPPolling.prototype.doClose = function () {\n  if (this.script) {\n    this.script.parentNode.removeChild(this.script);\n    this.script = null;\n  }\n\n  if (this.form) {\n    this.form.parentNode.removeChild(this.form);\n    this.form = null;\n    this.iframe = null;\n  }\n\n  Polling.prototype.doClose.call(this);\n};\n\n/**\n * Starts a poll cycle.\n *\n * @api private\n */\n\nJSONPPolling.prototype.doPoll = function () {\n  var self = this;\n  var script = document.createElement('script');\n\n  if (this.script) {\n    this.script.parentNode.removeChild(this.script);\n    this.script = null;\n  }\n\n  script.async = true;\n  script.src = this.uri();\n  script.onerror = function (e) {\n    self.onError('jsonp poll error', e);\n  };\n\n  var insertAt = document.getElementsByTagName('script')[0];\n  if (insertAt) {\n    insertAt.parentNode.insertBefore(script, insertAt);\n  } else {\n    (document.head || document.body).appendChild(script);\n  }\n  this.script = script;\n\n  var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent);\n\n  if (isUAgecko) {\n    setTimeout(function () {\n      var iframe = document.createElement('iframe');\n      document.body.appendChild(iframe);\n      document.body.removeChild(iframe);\n    }, 100);\n  }\n};\n\n/**\n * Writes with a hidden iframe.\n *\n * @param {String} data to send\n * @param {Function} called upon flush.\n * @api private\n */\n\nJSONPPolling.prototype.doWrite = function (data, fn) {\n  var self = this;\n\n  if (!this.form) {\n    var form = document.createElement('form');\n    var area = document.createElement('textarea');\n    var id = this.iframeId = 'eio_iframe_' + this.index;\n    var iframe;\n\n    form.className = 'socketio';\n    form.style.position = 'absolute';\n    form.style.top = '-1000px';\n    form.style.left = '-1000px';\n    form.target = id;\n    form.method = 'POST';\n    form.setAttribute('accept-charset', 'utf-8');\n    area.name = 'd';\n    form.appendChild(area);\n    document.body.appendChild(form);\n\n    this.form = form;\n    this.area = area;\n  }\n\n  this.form.action = this.uri();\n\n  function complete () {\n    initIframe();\n    fn();\n  }\n\n  function initIframe () {\n    if (self.iframe) {\n      try {\n        self.form.removeChild(self.iframe);\n      } catch (e) {\n        self.onError('jsonp polling iframe removal error', e);\n      }\n    }\n\n    try {\n      // ie6 dynamic iframes with target=\"\" support (thanks Chris Lambacher)\n      var html = '<iframe src=\"javascript:0\" name=\"' + self.iframeId + '\">';\n      iframe = document.createElement(html);\n    } catch (e) {\n      iframe = document.createElement('iframe');\n      iframe.name = self.iframeId;\n      iframe.src = 'javascript:0';\n    }\n\n    iframe.id = self.iframeId;\n\n    self.form.appendChild(iframe);\n    self.iframe = iframe;\n  }\n\n  initIframe();\n\n  // escape \\n to prevent it from being converted into \\r\\n by some UAs\n  // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side\n  data = data.replace(rEscapedNewline, '\\\\\\n');\n  this.area.value = data.replace(rNewline, '\\\\n');\n\n  try {\n    this.form.submit();\n  } catch (e) {}\n\n  if (this.iframe.attachEvent) {\n    this.iframe.onreadystatechange = function () {\n      if (self.iframe.readyState === 'complete') {\n        complete();\n      }\n    };\n  } else {\n    this.iframe.onload = complete;\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMmRjZS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLWpzb25wLmpzP2RmZDYiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSByZXF1aXJlbWVudHMuXG4gKi9cblxudmFyIFBvbGxpbmcgPSByZXF1aXJlKCcuL3BvbGxpbmcnKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEpTT05QUG9sbGluZztcblxuLyoqXG4gKiBDYWNoZWQgcmVndWxhciBleHByZXNzaW9ucy5cbiAqL1xuXG52YXIgck5ld2xpbmUgPSAvXFxuL2c7XG52YXIgckVzY2FwZWROZXdsaW5lID0gL1xcXFxuL2c7XG5cbi8qKlxuICogR2xvYmFsIEpTT05QIGNhbGxiYWNrcy5cbiAqL1xuXG52YXIgY2FsbGJhY2tzO1xuXG4vKipcbiAqIE5vb3AuXG4gKi9cblxuZnVuY3Rpb24gZW1wdHkgKCkgeyB9XG5cbi8qKlxuICogSlNPTlAgUG9sbGluZyBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cy5cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gSlNPTlBQb2xsaW5nIChvcHRzKSB7XG4gIFBvbGxpbmcuY2FsbCh0aGlzLCBvcHRzKTtcblxuICB0aGlzLnF1ZXJ5ID0gdGhpcy5xdWVyeSB8fCB7fTtcblxuICAvLyBkZWZpbmUgZ2xvYmFsIGNhbGxiYWNrcyBhcnJheSBpZiBub3QgcHJlc2VudFxuICAvLyB3ZSBkbyB0aGlzIGhlcmUgKGxhemlseSkgdG8gYXZvaWQgdW5uZWVkZWQgZ2xvYmFsIHBvbGx1dGlvblxuICBpZiAoIWNhbGxiYWNrcykge1xuICAgIC8vIHdlIG5lZWQgdG8gY29uc2lkZXIgbXVsdGlwbGUgZW5naW5lcyBpbiB0aGUgc2FtZSBwYWdlXG4gICAgaWYgKCFnbG9iYWwuX19fZWlvKSBnbG9iYWwuX19fZWlvID0gW107XG4gICAgY2FsbGJhY2tzID0gZ2xvYmFsLl9fX2VpbztcbiAgfVxuXG4gIC8vIGNhbGxiYWNrIGlkZW50aWZpZXJcbiAgdGhpcy5pbmRleCA9IGNhbGxiYWNrcy5sZW5ndGg7XG5cbiAgLy8gYWRkIGNhbGxiYWNrIHRvIGpzb25wIGdsb2JhbFxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGNhbGxiYWNrcy5wdXNoKGZ1bmN0aW9uIChtc2cpIHtcbiAgICBzZWxmLm9uRGF0YShtc2cpO1xuICB9KTtcblxuICAvLyBhcHBlbmQgdG8gcXVlcnkgc3RyaW5nXG4gIHRoaXMucXVlcnkuaiA9IHRoaXMuaW5kZXg7XG5cbiAgLy8gcHJldmVudCBzcHVyaW91cyBlcnJvcnMgZnJvbSBiZWluZyBlbWl0dGVkIHdoZW4gdGhlIHdpbmRvdyBpcyB1bmxvYWRlZFxuICBpZiAoZ2xvYmFsLmRvY3VtZW50ICYmIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2JlZm9yZXVubG9hZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLnNjcmlwdCkgc2VsZi5zY3JpcHQub25lcnJvciA9IGVtcHR5O1xuICAgIH0sIGZhbHNlKTtcbiAgfVxufVxuXG4vKipcbiAqIEluaGVyaXRzIGZyb20gUG9sbGluZy5cbiAqL1xuXG5pbmhlcml0KEpTT05QUG9sbGluZywgUG9sbGluZyk7XG5cbi8qXG4gKiBKU09OUCBvbmx5IHN1cHBvcnRzIGJpbmFyeSBhcyBiYXNlNjQgZW5jb2RlZCBzdHJpbmdzXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuXG4vKipcbiAqIENsb3NlcyB0aGUgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkpTT05QUG9sbGluZy5wcm90b3R5cGUuZG9DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuc2NyaXB0KSB7XG4gICAgdGhpcy5zY3JpcHQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnNjcmlwdCk7XG4gICAgdGhpcy5zY3JpcHQgPSBudWxsO1xuICB9XG5cbiAgaWYgKHRoaXMuZm9ybSkge1xuICAgIHRoaXMuZm9ybS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuZm9ybSk7XG4gICAgdGhpcy5mb3JtID0gbnVsbDtcbiAgICB0aGlzLmlmcmFtZSA9IG51bGw7XG4gIH1cblxuICBQb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlLmNhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5kb1BvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gIGlmICh0aGlzLnNjcmlwdCkge1xuICAgIHRoaXMuc2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5zY3JpcHQpO1xuICAgIHRoaXMuc2NyaXB0ID0gbnVsbDtcbiAgfVxuXG4gIHNjcmlwdC5hc3luYyA9IHRydWU7XG4gIHNjcmlwdC5zcmMgPSB0aGlzLnVyaSgpO1xuICBzY3JpcHQub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsIGVycm9yJywgZSk7XG4gIH07XG5cbiAgdmFyIGluc2VydEF0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NjcmlwdCcpWzBdO1xuICBpZiAoaW5zZXJ0QXQpIHtcbiAgICBpbnNlcnRBdC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHQsIGluc2VydEF0KTtcbiAgfSBlbHNlIHtcbiAgICAoZG9jdW1lbnQuaGVhZCB8fCBkb2N1bWVudC5ib2R5KS5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICB9XG4gIHRoaXMuc2NyaXB0ID0gc2NyaXB0O1xuXG4gIHZhciBpc1VBZ2Vja28gPSAndW5kZWZpbmVkJyAhPT0gdHlwZW9mIG5hdmlnYXRvciAmJiAvZ2Vja28vaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG4gIGlmIChpc1VBZ2Vja28pIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgICB9LCAxMDApO1xuICB9XG59O1xuXG4vKipcbiAqIFdyaXRlcyB3aXRoIGEgaGlkZGVuIGlmcmFtZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSB0byBzZW5kXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkpTT05QUG9sbGluZy5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uIChkYXRhLCBmbikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKCF0aGlzLmZvcm0pIHtcbiAgICB2YXIgZm9ybSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2Zvcm0nKTtcbiAgICB2YXIgYXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgdmFyIGlkID0gdGhpcy5pZnJhbWVJZCA9ICdlaW9faWZyYW1lXycgKyB0aGlzLmluZGV4O1xuICAgIHZhciBpZnJhbWU7XG5cbiAgICBmb3JtLmNsYXNzTmFtZSA9ICdzb2NrZXRpbyc7XG4gICAgZm9ybS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgZm9ybS5zdHlsZS50b3AgPSAnLTEwMDBweCc7XG4gICAgZm9ybS5zdHlsZS5sZWZ0ID0gJy0xMDAwcHgnO1xuICAgIGZvcm0udGFyZ2V0ID0gaWQ7XG4gICAgZm9ybS5tZXRob2QgPSAnUE9TVCc7XG4gICAgZm9ybS5zZXRBdHRyaWJ1dGUoJ2FjY2VwdC1jaGFyc2V0JywgJ3V0Zi04Jyk7XG4gICAgYXJlYS5uYW1lID0gJ2QnO1xuICAgIGZvcm0uYXBwZW5kQ2hpbGQoYXJlYSk7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmb3JtKTtcblxuICAgIHRoaXMuZm9ybSA9IGZvcm07XG4gICAgdGhpcy5hcmVhID0gYXJlYTtcbiAgfVxuXG4gIHRoaXMuZm9ybS5hY3Rpb24gPSB0aGlzLnVyaSgpO1xuXG4gIGZ1bmN0aW9uIGNvbXBsZXRlICgpIHtcbiAgICBpbml0SWZyYW1lKCk7XG4gICAgZm4oKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRJZnJhbWUgKCkge1xuICAgIGlmIChzZWxmLmlmcmFtZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2VsZi5mb3JtLnJlbW92ZUNoaWxkKHNlbGYuaWZyYW1lKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsaW5nIGlmcmFtZSByZW1vdmFsIGVycm9yJywgZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIGllNiBkeW5hbWljIGlmcmFtZXMgd2l0aCB0YXJnZXQ9XCJcIiBzdXBwb3J0ICh0aGFua3MgQ2hyaXMgTGFtYmFjaGVyKVxuICAgICAgdmFyIGh0bWwgPSAnPGlmcmFtZSBzcmM9XCJqYXZhc2NyaXB0OjBcIiBuYW1lPVwiJyArIHNlbGYuaWZyYW1lSWQgKyAnXCI+JztcbiAgICAgIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaHRtbCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgICBpZnJhbWUubmFtZSA9IHNlbGYuaWZyYW1lSWQ7XG4gICAgICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6MCc7XG4gICAgfVxuXG4gICAgaWZyYW1lLmlkID0gc2VsZi5pZnJhbWVJZDtcblxuICAgIHNlbGYuZm9ybS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICAgIHNlbGYuaWZyYW1lID0gaWZyYW1lO1xuICB9XG5cbiAgaW5pdElmcmFtZSgpO1xuXG4gIC8vIGVzY2FwZSBcXG4gdG8gcHJldmVudCBpdCBmcm9tIGJlaW5nIGNvbnZlcnRlZCBpbnRvIFxcclxcbiBieSBzb21lIFVBc1xuICAvLyBkb3VibGUgZXNjYXBpbmcgaXMgcmVxdWlyZWQgZm9yIGVzY2FwZWQgbmV3IGxpbmVzIGJlY2F1c2UgdW5lc2NhcGluZyBvZiBuZXcgbGluZXMgY2FuIGJlIGRvbmUgc2FmZWx5IG9uIHNlcnZlci1zaWRlXG4gIGRhdGEgPSBkYXRhLnJlcGxhY2UockVzY2FwZWROZXdsaW5lLCAnXFxcXFxcbicpO1xuICB0aGlzLmFyZWEudmFsdWUgPSBkYXRhLnJlcGxhY2Uock5ld2xpbmUsICdcXFxcbicpO1xuXG4gIHRyeSB7XG4gICAgdGhpcy5mb3JtLnN1Ym1pdCgpO1xuICB9IGNhdGNoIChlKSB7fVxuXG4gIGlmICh0aGlzLmlmcmFtZS5hdHRhY2hFdmVudCkge1xuICAgIHRoaXMuaWZyYW1lLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLmlmcmFtZS5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnKSB7XG4gICAgICAgIGNvbXBsZXRlKCk7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmlmcmFtZS5vbmxvYWQgPSBjb21wbGV0ZTtcbiAgfVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2dce\n")},3902:function(module,exports,__webpack_require__){eval("/**\n * Base class\n *\n * Implements unique ID per instance. It is set once, and can not be updated.\n * An ID is generated during initialization; however it is included in the (de-)serializing of the object.\n * @class Base\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\n// see discussion here: https://gist.github.com/gordonbrander/2230317\nfunction uniqueID () {\n  function chr4 () {\n    return Math.random().toString(16).slice(-4);\n  }\n  return chr4() + chr4() +\n    '-' + chr4() +\n    '-' + chr4() +\n    '-' + chr4() +\n    '-' + chr4() + chr4() + chr4();\n}\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Unique ID for this class\n     * @memberof! Base\n     * @readonly\n     * @type {ID}\n     */\n    id: {\n      type: 'string',\n      default: function () {\n        return uniqueID();\n      },\n      setonce: true\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzkwMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9iYXNlLmpzP2NlYTgiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCYXNlIGNsYXNzXG4gKlxuICogSW1wbGVtZW50cyB1bmlxdWUgSUQgcGVyIGluc3RhbmNlLiBJdCBpcyBzZXQgb25jZSwgYW5kIGNhbiBub3QgYmUgdXBkYXRlZC5cbiAqIEFuIElEIGlzIGdlbmVyYXRlZCBkdXJpbmcgaW5pdGlhbGl6YXRpb247IGhvd2V2ZXIgaXQgaXMgaW5jbHVkZWQgaW4gdGhlIChkZS0pc2VyaWFsaXppbmcgb2YgdGhlIG9iamVjdC5cbiAqIEBjbGFzcyBCYXNlXG4gKi9cbnZhciBBbXBlcnNhbmRNb2RlbCA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1tb2RlbCcpO1xuXG4vLyBzZWUgZGlzY3Vzc2lvbiBoZXJlOiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9nb3Jkb25icmFuZGVyLzIyMzAzMTdcbmZ1bmN0aW9uIHVuaXF1ZUlEICgpIHtcbiAgZnVuY3Rpb24gY2hyNCAoKSB7XG4gICAgcmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMTYpLnNsaWNlKC00KTtcbiAgfVxuICByZXR1cm4gY2hyNCgpICsgY2hyNCgpICtcbiAgICAnLScgKyBjaHI0KCkgK1xuICAgICctJyArIGNocjQoKSArXG4gICAgJy0nICsgY2hyNCgpICtcbiAgICAnLScgKyBjaHI0KCkgKyBjaHI0KCkgKyBjaHI0KCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBVbmlxdWUgSUQgZm9yIHRoaXMgY2xhc3NcbiAgICAgKiBAbWVtYmVyb2YhIEJhc2VcbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKiBAdHlwZSB7SUR9XG4gICAgICovXG4gICAgaWQ6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdW5pcXVlSUQoKTtcbiAgICAgIH0sXG4gICAgICBzZXRvbmNlOiB0cnVlXG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3902\n")},"3b07":function(module,exports,__webpack_require__){eval("/**\n * Main spot object.\n *\n * @class Spot\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\nvar Datasets = __webpack_require__(/*! ./dataset/collection */ \"544d\");\nvar driverClient = __webpack_require__(/*! ./driver/client */ \"720c\");\nvar driverServer = __webpack_require__(/*! ./driver/server */ \"072d\");\nvar utildx = __webpack_require__(/*! ./util/crossfilter */ \"adfa\");\nvar timeUtil = __webpack_require__(/*! ./util/time */ \"d45b\");\nvar io = __webpack_require__(/*! socket.io-client */ \"b452\");\n\n/**\n * Connect to the spot-server using a websocket and setup callbacks\n *\n * @function\n * @param {address} Optional. IP address and port number to connect to. fi.  'http://localhost:3000'\n *\n * @memberof! Spot\n */\nfunction connectToServer (address) {\n  var me = this;\n  var socket;\n\n  if (address) {\n    // connect to specified address\n    // necessary for when window.location is not availble (node.js)\n    socket = io.connect(address);\n  } else {\n    // Use socket.io fallback to autodetect address\n    // ie. when a website wants to connect, use the window.location\n    socket = io.connect();\n  }\n\n  socket.on('connect', function () {\n    me.isConnected = true;\n    console.log('Connected to server');\n  });\n\n  socket.on('disconnect', function () {\n    me.isConnected = false;\n  });\n\n  socket.on('syncDatasets', function (req) {\n    // do an incremental update, as we typically start without datasets\n    me.datasets.add(req.data, { merge: true });\n  });\n\n  socket.on('syncDataview', function (req) {\n    me.dataview.reset(req.data);\n  });\n\n  socket.on('syncFacets', function (req) {\n    // do an incremental update, as we typically update only a few properties of a facet\n    // Also, a full reset will orphan the view.model objects in spot-app (ie. crashes)\n    var dataset = me.datasets.get(req.datasetId);\n    dataset.facets.add(req.data, { merge: true });\n\n    me.resetDataview(); // NOTE: the cached (serialized) datasets need to be updated, too\n\n    dataset.trigger('syncFacets');\n  });\n\n  socket.on('newData', function (req) {\n    var filter = me.dataview.filters.get(req.filterId);\n    if (req.data) {\n      filter.data = req.data;\n\n      // for text filters, rebuild partition and count\n      filter.partitions.forEach(function (partition, p) {\n        var columnToName = {1: 'a', 2: 'b', 3: 'c', 4: 'd'};\n\n        if (partition.isText) {\n          partition.groups.reset(null, {silent: true});\n          filter.data.forEach(function (d) {\n            var count = (parseFloat(d.aa) || parseInt(d.count)) || 0;\n\n            if (count) {\n              partition.groups.add({\n                min: 0,\n                max: 100,\n                count: count,\n                label: d[columnToName[(p + 1)]],\n                value: d[columnToName[(p + 1)]]\n              }, {silent: true});\n            }\n          });\n          partition.groups.sort();\n        }\n      });\n      filter.trigger('newData');\n    }\n  });\n\n  socket.on('newMetaData', function (req) {\n    me.dataview.dataTotal = parseInt(req.dataTotal);\n    me.dataview.dataSelected = parseInt(req.dataSelected);\n    console.timeEnd('Get data');\n    me.dataview.trigger('newMetaData');\n  });\n\n  socket.connect();\n  me.socket = socket;\n}\n\n/**\n * Disconnect from the spot-server\n *\n * @function\n * @memberof! Spot\n */\nfunction disconnectFromServer () {\n  this.socket.disconnect();\n}\n\n/**\n * Request a list of available datasets from the server\n *\n * Depending on the driver, this can be an asyncrhonous function.\n * It returns a Promise that resolves to the dataset collection\n *\n * @function\n * @returns {Promise}\n *\n * @memberof! Spot\n */\nfunction getDatasets () {\n  var me = this;\n\n  return new Promise(function (resolve, reject) {\n    me.socket.emit('getDatasets');\n\n    me.datasets.once('reset', function () {\n      resolve(me.datasets);\n    });\n  });\n}\n\n/**\n * Reset min, max, and categories for all facets in the dataview\n *\n * @param {Spot} me Main spot instance\n *\n * @memberof! Spot\n */\nfunction resetDataview () {\n  var toSerialize = [];\n\n  // Update list of active datasets, and serialize the datasets parts we need to send on getData requests\n  this.dataview.datasetIds = [];\n  this.datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      // BUGFIX: the list of datasetIds can get out of sync when using spot-server. Just recreate it always.\n      this.dataview.datasetIds.push(dataset.getId());\n      toSerialize.push(dataset.toJSON()); // TODO: only serialize used facets?\n    }\n  }, this);\n  this.cachedDatasets = JSON.stringify(toSerialize);\n\n  // rescan min/max values and categories for the newly added facets\n  this.dataview.facets.forEach(function (facet) {\n    var newFacet = this.dataview.facets.get(facet.name, 'name');\n\n    if (newFacet.isContinuous || newFacet.isDatetime || newFacet.isDuration) {\n      this.setFacetMinMax(facet);\n    } else if (newFacet.isCategorial) {\n      this.setFacetCategories(facet);\n    }\n  }, this);\n}\n\n/*\n * Add or remove facets from a dataset to the global (merged) dataset\n *\n * @memberof! Spot\n * @param {Spot} me Main spot instance\n * @param {Dataset} dataset Dataset set add or remove\n */\nfunction toggleDatasetFacets (me, dataset) {\n  if (dataset.isActive) {\n    // remove active facets in dataset from the global dataset...\n    dataset.facets.forEach(function (facet) {\n      if (!facet.isActive) {\n        return;\n      }\n\n      // ...but only when no other active dataset contains it\n      var facetIsUnique = true;\n      me.datasets.forEach(function (otherDataset) {\n        if (!otherDataset.isActive || otherDataset === dataset) {\n          return;\n        }\n        if (otherDataset.facets.get(facet.name, 'name')) {\n          facetIsUnique = false;\n        }\n      });\n      if (facetIsUnique) {\n        var toRemove = me.dataview.facets.get(facet.name, 'name');\n        me.dataview.facets.remove(toRemove);\n      }\n    });\n  } else if (!dataset.isActive) {\n    // copy facets\n    dataset.facets.forEach(function (facet) {\n      // do nothing if facet is not active\n      if (!facet.isActive) {\n        return;\n      }\n\n      // default options for all facet types\n      var options = {\n        name: facet.name,\n        accessor: facet.name,\n        description: facet.description,\n        type: facet.transform.transformedType,\n        units: facet.units, // TODO: transformed units?\n        isActive: true\n      };\n\n      // do not add if a similar facet already exists\n      if (!me.dataview.facets.get(facet.name, 'name')) {\n        me.dataview.facets.add(options);\n      }\n    });\n  }\n}\n\n/*\n * Add or remove data from a dataset to the global (merged) dataset\n *\n * @memberof! Spot\n * @param {Spot} me Main spot instance\n * @param {Dataset} dataset Dataset set add or remove\n */\nfunction toggleDatasetData (me, dataset) {\n  if (dataset.isActive) {\n    // if dataset is active, remove it:\n    // ...clear all crossfilter filters\n    me.dataview.filters.forEach(function (filter) {\n      // BUGFIX: when loading sessions, the dataset is not initialized properly\n      // so check for it to be sure\n      if (filter.dimension) {\n        filter.dimension.filterAll();\n      }\n    });\n\n    // ...filter all data, originating from the dataset from the dataset\n    var dimension = me.dataview.crossfilter.dimension(function (d) {\n      return d._OriginalDatasetId;\n    });\n    dimension.filter(dataset.getId());\n\n    // ...remove matching data\n    me.dataview.crossfilter.remove();\n\n    // ...restore original filters\n    dimension.filterAll();\n    dimension.dispose();\n    me.dataview.filters.forEach(function (filter) {\n      filter.updateDataFilter();\n    });\n  } else if (!dataset.isActive) {\n    // if dataset is not active, add it\n    // ...find facets to copy\n    var dataTransforms = [];\n    dataset.facets.forEach(function (facet) {\n      // do nothing if facet is not active\n      if (!facet.isActive) {\n        return;\n      }\n      dataTransforms.push({\n        key: facet.name,\n        fn: utildx.valueFn(facet)\n      });\n    });\n\n    // ...transform data\n    var data = dataset.data;\n    var transformedData = [];\n\n    data.forEach(function (datum) {\n      var transformedDatum = {};\n      dataTransforms.forEach(function (transform) {\n        transformedDatum[transform.key] = transform.fn(datum);\n      });\n      transformedDatum._OriginalDatasetId = dataset.getId();\n      transformedData.push(transformedDatum);\n    });\n\n    // ...add to merged dataset\n    me.dataview.crossfilter.add(transformedData);\n  }\n\n  // update counts\n  me.dataview.dataTotal = me.dataview.crossfilter.size();\n  me.dataview.dataSelected = me.dataview.countGroup.value();\n}\n\n/**\n * Add or remove a dataset from the dataview\n * @param {Dataset} dataset Dataset set add or remove\n *\n * @function\n * @memberof! Spot\n */\nfunction toggleDataset (dataset) {\n  if (this.sessionType === 'server') {\n    toggleDatasetFacets(this, dataset);\n  } else if (this.sessionType === 'client') {\n    // release all filters\n    this.dataview.filters.forEach(function (filter) {\n      filter.releaseDataFilter();\n    });\n\n    // manually merge the datasets\n    toggleDatasetFacets(this, dataset);\n    toggleDatasetData(this, dataset);\n  }\n\n  dataset.isActive = !dataset.isActive;\n\n  this.resetDataview();\n}\n\nfunction setFacetMinMax (facet) {\n  // This should work for all kinds of facets:\n  // numbers, durations, and datatimes all implement the relevant operations\n  var datasets = this.datasets;\n\n  var first = true;\n  datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      var subFacet = dataset.facets.get(facet.name, 'name');\n      if (first) {\n        facet.minvalAsText = subFacet.transform.transformedMinAsText;\n        facet.maxvalAsText = subFacet.transform.transformedMaxAsText;\n        first = false;\n      } else {\n        if (subFacet.minval < facet.minval) {\n          facet.minvalAsText = subFacet.transform.transformedMinAsText;\n        }\n        if (subFacet.maxval > facet.maxval) {\n          facet.maxvalAsText = subFacet.transform.transformedMaxAsText;\n        }\n      }\n    }\n  });\n}\n\nfunction setFacetCategories (facet) {\n  var datasets = this.datasets;\n\n  facet.categorialTransform.reset();\n\n  // get categories by combining the sets for the separate datasets\n  datasets.forEach(function (dataset) {\n    if (dataset.isActive) {\n      var subFacet = dataset.facets.get(facet.name, 'name');\n\n      if (subFacet.isCategorial) {\n        // merge rules from subFacet into those of Facet\n        subFacet.categorialTransform.rules.forEach(function (rule) {\n          var newRule = facet.categorialTransform.rules.get(rule.expression, 'expression');\n          if (newRule) {\n            newRule.count += rule.count;\n          } else {\n            facet.categorialTransform.rules.add(rule.toJSON());\n          }\n        });\n      } else if (subFacet.isDatetime) {\n        var expressions = timeUtil.timeParts.get(subFacet.datetimeTransform.transformedFormat, 'description').groups;\n        expressions.forEach(function (expression) {\n          var newRule = facet.categorialTransform.rules.get(expression, 'expression');\n          if (newRule) {\n            // no-op: category exist and we don't have a proper count\n          } else {\n            facet.categorialTransform.rules.add({\n              expression: expression,\n              count: 0,\n              group: expression\n            });\n          }\n        });\n      }\n    }\n  });\n}\n\nmodule.exports = BaseModel.extend({\n  type: 'user',\n  props: {\n    /**\n     * Is there a connection with a spot sever?\n     * @memberof! Spot\n     * @type {boolean}\n     */\n    isConnected: ['boolean', true, false],\n    /**\n     * When the app in locked down, facets and datasets cannot be edited\n     * @memberof! Spot\n     * @type {boolean}\n     */\n    isLockedDown: ['boolean', true, false],\n    /**\n     * Type of spot session. Must be 'client' or 'server'\n     * @memberof! Spot\n     * @type {string}\n     */\n    sessionType: {\n      type: 'string',\n      required: true,\n      default: 'client',\n      values: ['client', 'server'],\n      setOnce: true\n    }\n  },\n  children: {\n    /**\n     * A union of all active datasets\n     * @memberof! Spot\n     * @type {Dataview}\n     */\n    dataview: Dataview\n  },\n  collections: {\n    /**\n     * Collection of all datasets\n     * @memberof! Spot\n     * @type {Dataset[]}\n     */\n    datasets: Datasets\n  },\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    // default to client side (crossfilter) sessions\n    this.driver = driverClient;\n\n    // assign backend driver\n    if (arguments && arguments[0] && arguments[0].sessionType) {\n      if (arguments[0].sessionType === 'client') {\n        this.driver = driverClient;\n      } else if (arguments[0].sessionType === 'server') {\n        this.driver = driverServer;\n      } else {\n        console.error('No driver for type', arguments[0].sessionType);\n      }\n    }\n  },\n  resetDataview: resetDataview,\n  connectToServer: connectToServer,\n  disconnectFromServer: disconnectFromServer,\n  getDatasets: getDatasets,\n  setFacetMinMax: setFacetMinMax,\n  setFacetCategories: setFacetCategories,\n  toggleDataset: toggleDataset\n});\n\nmodule.exports.util = {\n  dx: utildx,\n  misval: __webpack_require__(/*! ./util/misval */ \"bff6\"),\n  time: timeUtil\n};\n\nmodule.exports.transforms = {\n  categorial: __webpack_require__(/*! ./facet/categorial-transform */ \"9b75\"),\n  continuous: __webpack_require__(/*! ./facet/continuous-transform */ \"5a80\"),\n  datetime: __webpack_require__(/*! ./facet/datetime-transform */ \"a0ca\"),\n  duration: __webpack_require__(/*! ./facet/duration-transform */ \"b123\")\n};\n\nmodule.exports.constructors = {\n  Dataview: Dataview,\n  Dataset: __webpack_require__(/*! ./dataset */ \"545a\"),\n  Datasets: Datasets\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiM2IwNy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvbWUuanM/Y2NmYSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1haW4gc3BvdCBvYmplY3QuXG4gKlxuICogQGNsYXNzIFNwb3RcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG52YXIgRGF0YXZpZXcgPSByZXF1aXJlKCcuL2RhdGF2aWV3Jyk7XG52YXIgRGF0YXNldHMgPSByZXF1aXJlKCcuL2RhdGFzZXQvY29sbGVjdGlvbicpO1xudmFyIGRyaXZlckNsaWVudCA9IHJlcXVpcmUoJy4vZHJpdmVyL2NsaWVudCcpO1xudmFyIGRyaXZlclNlcnZlciA9IHJlcXVpcmUoJy4vZHJpdmVyL3NlcnZlcicpO1xudmFyIHV0aWxkeCA9IHJlcXVpcmUoJy4vdXRpbC9jcm9zc2ZpbHRlcicpO1xudmFyIHRpbWVVdGlsID0gcmVxdWlyZSgnLi91dGlsL3RpbWUnKTtcbnZhciBpbyA9IHJlcXVpcmUoJ3NvY2tldC5pby1jbGllbnQnKTtcblxuLyoqXG4gKiBDb25uZWN0IHRvIHRoZSBzcG90LXNlcnZlciB1c2luZyBhIHdlYnNvY2tldCBhbmQgc2V0dXAgY2FsbGJhY2tzXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge2FkZHJlc3N9IE9wdGlvbmFsLiBJUCBhZGRyZXNzIGFuZCBwb3J0IG51bWJlciB0byBjb25uZWN0IHRvLiBmaS4gICdodHRwOi8vbG9jYWxob3N0OjMwMDAnXG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIGNvbm5lY3RUb1NlcnZlciAoYWRkcmVzcykge1xuICB2YXIgbWUgPSB0aGlzO1xuICB2YXIgc29ja2V0O1xuXG4gIGlmIChhZGRyZXNzKSB7XG4gICAgLy8gY29ubmVjdCB0byBzcGVjaWZpZWQgYWRkcmVzc1xuICAgIC8vIG5lY2Vzc2FyeSBmb3Igd2hlbiB3aW5kb3cubG9jYXRpb24gaXMgbm90IGF2YWlsYmxlIChub2RlLmpzKVxuICAgIHNvY2tldCA9IGlvLmNvbm5lY3QoYWRkcmVzcyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gVXNlIHNvY2tldC5pbyBmYWxsYmFjayB0byBhdXRvZGV0ZWN0IGFkZHJlc3NcbiAgICAvLyBpZS4gd2hlbiBhIHdlYnNpdGUgd2FudHMgdG8gY29ubmVjdCwgdXNlIHRoZSB3aW5kb3cubG9jYXRpb25cbiAgICBzb2NrZXQgPSBpby5jb25uZWN0KCk7XG4gIH1cblxuICBzb2NrZXQub24oJ2Nvbm5lY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgbWUuaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgIGNvbnNvbGUubG9nKCdDb25uZWN0ZWQgdG8gc2VydmVyJyk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignZGlzY29ubmVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBtZS5pc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICB9KTtcblxuICBzb2NrZXQub24oJ3N5bmNEYXRhc2V0cycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAvLyBkbyBhbiBpbmNyZW1lbnRhbCB1cGRhdGUsIGFzIHdlIHR5cGljYWxseSBzdGFydCB3aXRob3V0IGRhdGFzZXRzXG4gICAgbWUuZGF0YXNldHMuYWRkKHJlcS5kYXRhLCB7IG1lcmdlOiB0cnVlIH0pO1xuICB9KTtcblxuICBzb2NrZXQub24oJ3N5bmNEYXRhdmlldycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICBtZS5kYXRhdmlldy5yZXNldChyZXEuZGF0YSk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignc3luY0ZhY2V0cycsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAvLyBkbyBhbiBpbmNyZW1lbnRhbCB1cGRhdGUsIGFzIHdlIHR5cGljYWxseSB1cGRhdGUgb25seSBhIGZldyBwcm9wZXJ0aWVzIG9mIGEgZmFjZXRcbiAgICAvLyBBbHNvLCBhIGZ1bGwgcmVzZXQgd2lsbCBvcnBoYW4gdGhlIHZpZXcubW9kZWwgb2JqZWN0cyBpbiBzcG90LWFwcCAoaWUuIGNyYXNoZXMpXG4gICAgdmFyIGRhdGFzZXQgPSBtZS5kYXRhc2V0cy5nZXQocmVxLmRhdGFzZXRJZCk7XG4gICAgZGF0YXNldC5mYWNldHMuYWRkKHJlcS5kYXRhLCB7IG1lcmdlOiB0cnVlIH0pO1xuXG4gICAgbWUucmVzZXREYXRhdmlldygpOyAvLyBOT1RFOiB0aGUgY2FjaGVkIChzZXJpYWxpemVkKSBkYXRhc2V0cyBuZWVkIHRvIGJlIHVwZGF0ZWQsIHRvb1xuXG4gICAgZGF0YXNldC50cmlnZ2VyKCdzeW5jRmFjZXRzJyk7XG4gIH0pO1xuXG4gIHNvY2tldC5vbignbmV3RGF0YScsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICB2YXIgZmlsdGVyID0gbWUuZGF0YXZpZXcuZmlsdGVycy5nZXQocmVxLmZpbHRlcklkKTtcbiAgICBpZiAocmVxLmRhdGEpIHtcbiAgICAgIGZpbHRlci5kYXRhID0gcmVxLmRhdGE7XG5cbiAgICAgIC8vIGZvciB0ZXh0IGZpbHRlcnMsIHJlYnVpbGQgcGFydGl0aW9uIGFuZCBjb3VudFxuICAgICAgZmlsdGVyLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uLCBwKSB7XG4gICAgICAgIHZhciBjb2x1bW5Ub05hbWUgPSB7MTogJ2EnLCAyOiAnYicsIDM6ICdjJywgNDogJ2QnfTtcblxuICAgICAgICBpZiAocGFydGl0aW9uLmlzVGV4dCkge1xuICAgICAgICAgIHBhcnRpdGlvbi5ncm91cHMucmVzZXQobnVsbCwge3NpbGVudDogdHJ1ZX0pO1xuICAgICAgICAgIGZpbHRlci5kYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHZhciBjb3VudCA9IChwYXJzZUZsb2F0KGQuYWEpIHx8IHBhcnNlSW50KGQuY291bnQpKSB8fCAwO1xuXG4gICAgICAgICAgICBpZiAoY291bnQpIHtcbiAgICAgICAgICAgICAgcGFydGl0aW9uLmdyb3Vwcy5hZGQoe1xuICAgICAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgICAgICBtYXg6IDEwMCxcbiAgICAgICAgICAgICAgICBjb3VudDogY291bnQsXG4gICAgICAgICAgICAgICAgbGFiZWw6IGRbY29sdW1uVG9OYW1lWyhwICsgMSldXSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogZFtjb2x1bW5Ub05hbWVbKHAgKyAxKV1dXG4gICAgICAgICAgICAgIH0sIHtzaWxlbnQ6IHRydWV9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwYXJ0aXRpb24uZ3JvdXBzLnNvcnQoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBmaWx0ZXIudHJpZ2dlcignbmV3RGF0YScpO1xuICAgIH1cbiAgfSk7XG5cbiAgc29ja2V0Lm9uKCduZXdNZXRhRGF0YScsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICBtZS5kYXRhdmlldy5kYXRhVG90YWwgPSBwYXJzZUludChyZXEuZGF0YVRvdGFsKTtcbiAgICBtZS5kYXRhdmlldy5kYXRhU2VsZWN0ZWQgPSBwYXJzZUludChyZXEuZGF0YVNlbGVjdGVkKTtcbiAgICBjb25zb2xlLnRpbWVFbmQoJ0dldCBkYXRhJyk7XG4gICAgbWUuZGF0YXZpZXcudHJpZ2dlcignbmV3TWV0YURhdGEnKTtcbiAgfSk7XG5cbiAgc29ja2V0LmNvbm5lY3QoKTtcbiAgbWUuc29ja2V0ID0gc29ja2V0O1xufVxuXG4vKipcbiAqIERpc2Nvbm5lY3QgZnJvbSB0aGUgc3BvdC1zZXJ2ZXJcbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiEgU3BvdFxuICovXG5mdW5jdGlvbiBkaXNjb25uZWN0RnJvbVNlcnZlciAoKSB7XG4gIHRoaXMuc29ja2V0LmRpc2Nvbm5lY3QoKTtcbn1cblxuLyoqXG4gKiBSZXF1ZXN0IGEgbGlzdCBvZiBhdmFpbGFibGUgZGF0YXNldHMgZnJvbSB0aGUgc2VydmVyXG4gKlxuICogRGVwZW5kaW5nIG9uIHRoZSBkcml2ZXIsIHRoaXMgY2FuIGJlIGFuIGFzeW5jcmhvbm91cyBmdW5jdGlvbi5cbiAqIEl0IHJldHVybnMgYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGRhdGFzZXQgY29sbGVjdGlvblxuICpcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge1Byb21pc2V9XG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIGdldERhdGFzZXRzICgpIHtcbiAgdmFyIG1lID0gdGhpcztcblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIG1lLnNvY2tldC5lbWl0KCdnZXREYXRhc2V0cycpO1xuXG4gICAgbWUuZGF0YXNldHMub25jZSgncmVzZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXNvbHZlKG1lLmRhdGFzZXRzKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmVzZXQgbWluLCBtYXgsIGFuZCBjYXRlZ29yaWVzIGZvciBhbGwgZmFjZXRzIGluIHRoZSBkYXRhdmlld1xuICpcbiAqIEBwYXJhbSB7U3BvdH0gbWUgTWFpbiBzcG90IGluc3RhbmNlXG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKi9cbmZ1bmN0aW9uIHJlc2V0RGF0YXZpZXcgKCkge1xuICB2YXIgdG9TZXJpYWxpemUgPSBbXTtcblxuICAvLyBVcGRhdGUgbGlzdCBvZiBhY3RpdmUgZGF0YXNldHMsIGFuZCBzZXJpYWxpemUgdGhlIGRhdGFzZXRzIHBhcnRzIHdlIG5lZWQgdG8gc2VuZCBvbiBnZXREYXRhIHJlcXVlc3RzXG4gIHRoaXMuZGF0YXZpZXcuZGF0YXNldElkcyA9IFtdO1xuICB0aGlzLmRhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24gKGRhdGFzZXQpIHtcbiAgICBpZiAoZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgICAgLy8gQlVHRklYOiB0aGUgbGlzdCBvZiBkYXRhc2V0SWRzIGNhbiBnZXQgb3V0IG9mIHN5bmMgd2hlbiB1c2luZyBzcG90LXNlcnZlci4gSnVzdCByZWNyZWF0ZSBpdCBhbHdheXMuXG4gICAgICB0aGlzLmRhdGF2aWV3LmRhdGFzZXRJZHMucHVzaChkYXRhc2V0LmdldElkKCkpO1xuICAgICAgdG9TZXJpYWxpemUucHVzaChkYXRhc2V0LnRvSlNPTigpKTsgLy8gVE9ETzogb25seSBzZXJpYWxpemUgdXNlZCBmYWNldHM/XG4gICAgfVxuICB9LCB0aGlzKTtcbiAgdGhpcy5jYWNoZWREYXRhc2V0cyA9IEpTT04uc3RyaW5naWZ5KHRvU2VyaWFsaXplKTtcblxuICAvLyByZXNjYW4gbWluL21heCB2YWx1ZXMgYW5kIGNhdGVnb3JpZXMgZm9yIHRoZSBuZXdseSBhZGRlZCBmYWNldHNcbiAgdGhpcy5kYXRhdmlldy5mYWNldHMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICB2YXIgbmV3RmFjZXQgPSB0aGlzLmRhdGF2aWV3LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcblxuICAgIGlmIChuZXdGYWNldC5pc0NvbnRpbnVvdXMgfHwgbmV3RmFjZXQuaXNEYXRldGltZSB8fCBuZXdGYWNldC5pc0R1cmF0aW9uKSB7XG4gICAgICB0aGlzLnNldEZhY2V0TWluTWF4KGZhY2V0KTtcbiAgICB9IGVsc2UgaWYgKG5ld0ZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgdGhpcy5zZXRGYWNldENhdGVnb3JpZXMoZmFjZXQpO1xuICAgIH1cbiAgfSwgdGhpcyk7XG59XG5cbi8qXG4gKiBBZGQgb3IgcmVtb3ZlIGZhY2V0cyBmcm9tIGEgZGF0YXNldCB0byB0aGUgZ2xvYmFsIChtZXJnZWQpIGRhdGFzZXRcbiAqXG4gKiBAbWVtYmVyb2YhIFNwb3RcbiAqIEBwYXJhbSB7U3BvdH0gbWUgTWFpbiBzcG90IGluc3RhbmNlXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXQgRGF0YXNldCBzZXQgYWRkIG9yIHJlbW92ZVxuICovXG5mdW5jdGlvbiB0b2dnbGVEYXRhc2V0RmFjZXRzIChtZSwgZGF0YXNldCkge1xuICBpZiAoZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIHJlbW92ZSBhY3RpdmUgZmFjZXRzIGluIGRhdGFzZXQgZnJvbSB0aGUgZ2xvYmFsIGRhdGFzZXQuLi5cbiAgICBkYXRhc2V0LmZhY2V0cy5mb3JFYWNoKGZ1bmN0aW9uIChmYWNldCkge1xuICAgICAgaWYgKCFmYWNldC5pc0FjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIC4uLmJ1dCBvbmx5IHdoZW4gbm8gb3RoZXIgYWN0aXZlIGRhdGFzZXQgY29udGFpbnMgaXRcbiAgICAgIHZhciBmYWNldElzVW5pcXVlID0gdHJ1ZTtcbiAgICAgIG1lLmRhdGFzZXRzLmZvckVhY2goZnVuY3Rpb24gKG90aGVyRGF0YXNldCkge1xuICAgICAgICBpZiAoIW90aGVyRGF0YXNldC5pc0FjdGl2ZSB8fCBvdGhlckRhdGFzZXQgPT09IGRhdGFzZXQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG90aGVyRGF0YXNldC5mYWNldHMuZ2V0KGZhY2V0Lm5hbWUsICduYW1lJykpIHtcbiAgICAgICAgICBmYWNldElzVW5pcXVlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKGZhY2V0SXNVbmlxdWUpIHtcbiAgICAgICAgdmFyIHRvUmVtb3ZlID0gbWUuZGF0YXZpZXcuZmFjZXRzLmdldChmYWNldC5uYW1lLCAnbmFtZScpO1xuICAgICAgICBtZS5kYXRhdmlldy5mYWNldHMucmVtb3ZlKHRvUmVtb3ZlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIGlmICghZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIGNvcHkgZmFjZXRzXG4gICAgZGF0YXNldC5mYWNldHMuZm9yRWFjaChmdW5jdGlvbiAoZmFjZXQpIHtcbiAgICAgIC8vIGRvIG5vdGhpbmcgaWYgZmFjZXQgaXMgbm90IGFjdGl2ZVxuICAgICAgaWYgKCFmYWNldC5pc0FjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGRlZmF1bHQgb3B0aW9ucyBmb3IgYWxsIGZhY2V0IHR5cGVzXG4gICAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgbmFtZTogZmFjZXQubmFtZSxcbiAgICAgICAgYWNjZXNzb3I6IGZhY2V0Lm5hbWUsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBmYWNldC5kZXNjcmlwdGlvbixcbiAgICAgICAgdHlwZTogZmFjZXQudHJhbnNmb3JtLnRyYW5zZm9ybWVkVHlwZSxcbiAgICAgICAgdW5pdHM6IGZhY2V0LnVuaXRzLCAvLyBUT0RPOiB0cmFuc2Zvcm1lZCB1bml0cz9cbiAgICAgICAgaXNBY3RpdmU6IHRydWVcbiAgICAgIH07XG5cbiAgICAgIC8vIGRvIG5vdCBhZGQgaWYgYSBzaW1pbGFyIGZhY2V0IGFscmVhZHkgZXhpc3RzXG4gICAgICBpZiAoIW1lLmRhdGF2aWV3LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKSkge1xuICAgICAgICBtZS5kYXRhdmlldy5mYWNldHMuYWRkKG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbi8qXG4gKiBBZGQgb3IgcmVtb3ZlIGRhdGEgZnJvbSBhIGRhdGFzZXQgdG8gdGhlIGdsb2JhbCAobWVyZ2VkKSBkYXRhc2V0XG4gKlxuICogQG1lbWJlcm9mISBTcG90XG4gKiBAcGFyYW0ge1Nwb3R9IG1lIE1haW4gc3BvdCBpbnN0YW5jZVxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0IERhdGFzZXQgc2V0IGFkZCBvciByZW1vdmVcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlRGF0YXNldERhdGEgKG1lLCBkYXRhc2V0KSB7XG4gIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgLy8gaWYgZGF0YXNldCBpcyBhY3RpdmUsIHJlbW92ZSBpdDpcbiAgICAvLyAuLi5jbGVhciBhbGwgY3Jvc3NmaWx0ZXIgZmlsdGVyc1xuICAgIG1lLmRhdGF2aWV3LmZpbHRlcnMuZm9yRWFjaChmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgICAvLyBCVUdGSVg6IHdoZW4gbG9hZGluZyBzZXNzaW9ucywgdGhlIGRhdGFzZXQgaXMgbm90IGluaXRpYWxpemVkIHByb3Blcmx5XG4gICAgICAvLyBzbyBjaGVjayBmb3IgaXQgdG8gYmUgc3VyZVxuICAgICAgaWYgKGZpbHRlci5kaW1lbnNpb24pIHtcbiAgICAgICAgZmlsdGVyLmRpbWVuc2lvbi5maWx0ZXJBbGwoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIC4uLmZpbHRlciBhbGwgZGF0YSwgb3JpZ2luYXRpbmcgZnJvbSB0aGUgZGF0YXNldCBmcm9tIHRoZSBkYXRhc2V0XG4gICAgdmFyIGRpbWVuc2lvbiA9IG1lLmRhdGF2aWV3LmNyb3NzZmlsdGVyLmRpbWVuc2lvbihmdW5jdGlvbiAoZCkge1xuICAgICAgcmV0dXJuIGQuX09yaWdpbmFsRGF0YXNldElkO1xuICAgIH0pO1xuICAgIGRpbWVuc2lvbi5maWx0ZXIoZGF0YXNldC5nZXRJZCgpKTtcblxuICAgIC8vIC4uLnJlbW92ZSBtYXRjaGluZyBkYXRhXG4gICAgbWUuZGF0YXZpZXcuY3Jvc3NmaWx0ZXIucmVtb3ZlKCk7XG5cbiAgICAvLyAuLi5yZXN0b3JlIG9yaWdpbmFsIGZpbHRlcnNcbiAgICBkaW1lbnNpb24uZmlsdGVyQWxsKCk7XG4gICAgZGltZW5zaW9uLmRpc3Bvc2UoKTtcbiAgICBtZS5kYXRhdmlldy5maWx0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpbHRlcikge1xuICAgICAgZmlsdGVyLnVwZGF0ZURhdGFGaWx0ZXIoKTtcbiAgICB9KTtcbiAgfSBlbHNlIGlmICghZGF0YXNldC5pc0FjdGl2ZSkge1xuICAgIC8vIGlmIGRhdGFzZXQgaXMgbm90IGFjdGl2ZSwgYWRkIGl0XG4gICAgLy8gLi4uZmluZCBmYWNldHMgdG8gY29weVxuICAgIHZhciBkYXRhVHJhbnNmb3JtcyA9IFtdO1xuICAgIGRhdGFzZXQuZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgICAvLyBkbyBub3RoaW5nIGlmIGZhY2V0IGlzIG5vdCBhY3RpdmVcbiAgICAgIGlmICghZmFjZXQuaXNBY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZGF0YVRyYW5zZm9ybXMucHVzaCh7XG4gICAgICAgIGtleTogZmFjZXQubmFtZSxcbiAgICAgICAgZm46IHV0aWxkeC52YWx1ZUZuKGZhY2V0KVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyAuLi50cmFuc2Zvcm0gZGF0YVxuICAgIHZhciBkYXRhID0gZGF0YXNldC5kYXRhO1xuICAgIHZhciB0cmFuc2Zvcm1lZERhdGEgPSBbXTtcblxuICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZGF0dW0pIHtcbiAgICAgIHZhciB0cmFuc2Zvcm1lZERhdHVtID0ge307XG4gICAgICBkYXRhVHJhbnNmb3Jtcy5mb3JFYWNoKGZ1bmN0aW9uICh0cmFuc2Zvcm0pIHtcbiAgICAgICAgdHJhbnNmb3JtZWREYXR1bVt0cmFuc2Zvcm0ua2V5XSA9IHRyYW5zZm9ybS5mbihkYXR1bSk7XG4gICAgICB9KTtcbiAgICAgIHRyYW5zZm9ybWVkRGF0dW0uX09yaWdpbmFsRGF0YXNldElkID0gZGF0YXNldC5nZXRJZCgpO1xuICAgICAgdHJhbnNmb3JtZWREYXRhLnB1c2godHJhbnNmb3JtZWREYXR1bSk7XG4gICAgfSk7XG5cbiAgICAvLyAuLi5hZGQgdG8gbWVyZ2VkIGRhdGFzZXRcbiAgICBtZS5kYXRhdmlldy5jcm9zc2ZpbHRlci5hZGQodHJhbnNmb3JtZWREYXRhKTtcbiAgfVxuXG4gIC8vIHVwZGF0ZSBjb3VudHNcbiAgbWUuZGF0YXZpZXcuZGF0YVRvdGFsID0gbWUuZGF0YXZpZXcuY3Jvc3NmaWx0ZXIuc2l6ZSgpO1xuICBtZS5kYXRhdmlldy5kYXRhU2VsZWN0ZWQgPSBtZS5kYXRhdmlldy5jb3VudEdyb3VwLnZhbHVlKCk7XG59XG5cbi8qKlxuICogQWRkIG9yIHJlbW92ZSBhIGRhdGFzZXQgZnJvbSB0aGUgZGF0YXZpZXdcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldCBEYXRhc2V0IHNldCBhZGQgb3IgcmVtb3ZlXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAbWVtYmVyb2YhIFNwb3RcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlRGF0YXNldCAoZGF0YXNldCkge1xuICBpZiAodGhpcy5zZXNzaW9uVHlwZSA9PT0gJ3NlcnZlcicpIHtcbiAgICB0b2dnbGVEYXRhc2V0RmFjZXRzKHRoaXMsIGRhdGFzZXQpO1xuICB9IGVsc2UgaWYgKHRoaXMuc2Vzc2lvblR5cGUgPT09ICdjbGllbnQnKSB7XG4gICAgLy8gcmVsZWFzZSBhbGwgZmlsdGVyc1xuICAgIHRoaXMuZGF0YXZpZXcuZmlsdGVycy5mb3JFYWNoKGZ1bmN0aW9uIChmaWx0ZXIpIHtcbiAgICAgIGZpbHRlci5yZWxlYXNlRGF0YUZpbHRlcigpO1xuICAgIH0pO1xuXG4gICAgLy8gbWFudWFsbHkgbWVyZ2UgdGhlIGRhdGFzZXRzXG4gICAgdG9nZ2xlRGF0YXNldEZhY2V0cyh0aGlzLCBkYXRhc2V0KTtcbiAgICB0b2dnbGVEYXRhc2V0RGF0YSh0aGlzLCBkYXRhc2V0KTtcbiAgfVxuXG4gIGRhdGFzZXQuaXNBY3RpdmUgPSAhZGF0YXNldC5pc0FjdGl2ZTtcblxuICB0aGlzLnJlc2V0RGF0YXZpZXcoKTtcbn1cblxuZnVuY3Rpb24gc2V0RmFjZXRNaW5NYXggKGZhY2V0KSB7XG4gIC8vIFRoaXMgc2hvdWxkIHdvcmsgZm9yIGFsbCBraW5kcyBvZiBmYWNldHM6XG4gIC8vIG51bWJlcnMsIGR1cmF0aW9ucywgYW5kIGRhdGF0aW1lcyBhbGwgaW1wbGVtZW50IHRoZSByZWxldmFudCBvcGVyYXRpb25zXG4gIHZhciBkYXRhc2V0cyA9IHRoaXMuZGF0YXNldHM7XG5cbiAgdmFyIGZpcnN0ID0gdHJ1ZTtcbiAgZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZGF0YXNldCkge1xuICAgIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgICB2YXIgc3ViRmFjZXQgPSBkYXRhc2V0LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcbiAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICBmYWNldC5taW52YWxBc1RleHQgPSBzdWJGYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW5Bc1RleHQ7XG4gICAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IHN1YkZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZE1heEFzVGV4dDtcbiAgICAgICAgZmlyc3QgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChzdWJGYWNldC5taW52YWwgPCBmYWNldC5taW52YWwpIHtcbiAgICAgICAgICBmYWNldC5taW52YWxBc1RleHQgPSBzdWJGYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW5Bc1RleHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN1YkZhY2V0Lm1heHZhbCA+IGZhY2V0Lm1heHZhbCkge1xuICAgICAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IHN1YkZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZE1heEFzVGV4dDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHNldEZhY2V0Q2F0ZWdvcmllcyAoZmFjZXQpIHtcbiAgdmFyIGRhdGFzZXRzID0gdGhpcy5kYXRhc2V0cztcblxuICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJlc2V0KCk7XG5cbiAgLy8gZ2V0IGNhdGVnb3JpZXMgYnkgY29tYmluaW5nIHRoZSBzZXRzIGZvciB0aGUgc2VwYXJhdGUgZGF0YXNldHNcbiAgZGF0YXNldHMuZm9yRWFjaChmdW5jdGlvbiAoZGF0YXNldCkge1xuICAgIGlmIChkYXRhc2V0LmlzQWN0aXZlKSB7XG4gICAgICB2YXIgc3ViRmFjZXQgPSBkYXRhc2V0LmZhY2V0cy5nZXQoZmFjZXQubmFtZSwgJ25hbWUnKTtcblxuICAgICAgaWYgKHN1YkZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgICAvLyBtZXJnZSBydWxlcyBmcm9tIHN1YkZhY2V0IGludG8gdGhvc2Ugb2YgRmFjZXRcbiAgICAgICAgc3ViRmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChydWxlKSB7XG4gICAgICAgICAgdmFyIG5ld1J1bGUgPSBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLmdldChydWxlLmV4cHJlc3Npb24sICdleHByZXNzaW9uJyk7XG4gICAgICAgICAgaWYgKG5ld1J1bGUpIHtcbiAgICAgICAgICAgIG5ld1J1bGUuY291bnQgKz0gcnVsZS5jb3VudDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5hZGQocnVsZS50b0pTT04oKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoc3ViRmFjZXQuaXNEYXRldGltZSkge1xuICAgICAgICB2YXIgZXhwcmVzc2lvbnMgPSB0aW1lVXRpbC50aW1lUGFydHMuZ2V0KHN1YkZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKS5ncm91cHM7XG4gICAgICAgIGV4cHJlc3Npb25zLmZvckVhY2goZnVuY3Rpb24gKGV4cHJlc3Npb24pIHtcbiAgICAgICAgICB2YXIgbmV3UnVsZSA9IGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuZ2V0KGV4cHJlc3Npb24sICdleHByZXNzaW9uJyk7XG4gICAgICAgICAgaWYgKG5ld1J1bGUpIHtcbiAgICAgICAgICAgIC8vIG5vLW9wOiBjYXRlZ29yeSBleGlzdCBhbmQgd2UgZG9uJ3QgaGF2ZSBhIHByb3BlciBjb3VudFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmYWNldC5jYXRlZ29yaWFsVHJhbnNmb3JtLnJ1bGVzLmFkZCh7XG4gICAgICAgICAgICAgIGV4cHJlc3Npb246IGV4cHJlc3Npb24sXG4gICAgICAgICAgICAgIGNvdW50OiAwLFxuICAgICAgICAgICAgICBncm91cDogZXhwcmVzc2lvblxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VNb2RlbC5leHRlbmQoe1xuICB0eXBlOiAndXNlcicsXG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogSXMgdGhlcmUgYSBjb25uZWN0aW9uIHdpdGggYSBzcG90IHNldmVyP1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIGlzQ29ubmVjdGVkOiBbJ2Jvb2xlYW4nLCB0cnVlLCBmYWxzZV0sXG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgYXBwIGluIGxvY2tlZCBkb3duLCBmYWNldHMgYW5kIGRhdGFzZXRzIGNhbm5vdCBiZSBlZGl0ZWRcbiAgICAgKiBAbWVtYmVyb2YhIFNwb3RcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0xvY2tlZERvd246IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXSxcbiAgICAvKipcbiAgICAgKiBUeXBlIG9mIHNwb3Qgc2Vzc2lvbi4gTXVzdCBiZSAnY2xpZW50JyBvciAnc2VydmVyJ1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgc2Vzc2lvblR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnY2xpZW50JyxcbiAgICAgIHZhbHVlczogWydjbGllbnQnLCAnc2VydmVyJ10sXG4gICAgICBzZXRPbmNlOiB0cnVlXG4gICAgfVxuICB9LFxuICBjaGlsZHJlbjoge1xuICAgIC8qKlxuICAgICAqIEEgdW5pb24gb2YgYWxsIGFjdGl2ZSBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtEYXRhdmlld31cbiAgICAgKi9cbiAgICBkYXRhdmlldzogRGF0YXZpZXdcbiAgfSxcbiAgY29sbGVjdGlvbnM6IHtcbiAgICAvKipcbiAgICAgKiBDb2xsZWN0aW9uIG9mIGFsbCBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgU3BvdFxuICAgICAqIEB0eXBlIHtEYXRhc2V0W119XG4gICAgICovXG4gICAgZGF0YXNldHM6IERhdGFzZXRzXG4gIH0sXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBmaXJzdCBkbyBwYXJlbnQgY2xhc3MgaW5pdGlhbGl6YXRpb25cbiAgICBCYXNlTW9kZWwucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIC8vIGRlZmF1bHQgdG8gY2xpZW50IHNpZGUgKGNyb3NzZmlsdGVyKSBzZXNzaW9uc1xuICAgIHRoaXMuZHJpdmVyID0gZHJpdmVyQ2xpZW50O1xuXG4gICAgLy8gYXNzaWduIGJhY2tlbmQgZHJpdmVyXG4gICAgaWYgKGFyZ3VtZW50cyAmJiBhcmd1bWVudHNbMF0gJiYgYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlKSB7XG4gICAgICBpZiAoYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlID09PSAnY2xpZW50Jykge1xuICAgICAgICB0aGlzLmRyaXZlciA9IGRyaXZlckNsaWVudDtcbiAgICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzWzBdLnNlc3Npb25UeXBlID09PSAnc2VydmVyJykge1xuICAgICAgICB0aGlzLmRyaXZlciA9IGRyaXZlclNlcnZlcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ05vIGRyaXZlciBmb3IgdHlwZScsIGFyZ3VtZW50c1swXS5zZXNzaW9uVHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICByZXNldERhdGF2aWV3OiByZXNldERhdGF2aWV3LFxuICBjb25uZWN0VG9TZXJ2ZXI6IGNvbm5lY3RUb1NlcnZlcixcbiAgZGlzY29ubmVjdEZyb21TZXJ2ZXI6IGRpc2Nvbm5lY3RGcm9tU2VydmVyLFxuICBnZXREYXRhc2V0czogZ2V0RGF0YXNldHMsXG4gIHNldEZhY2V0TWluTWF4OiBzZXRGYWNldE1pbk1heCxcbiAgc2V0RmFjZXRDYXRlZ29yaWVzOiBzZXRGYWNldENhdGVnb3JpZXMsXG4gIHRvZ2dsZURhdGFzZXQ6IHRvZ2dsZURhdGFzZXRcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cy51dGlsID0ge1xuICBkeDogdXRpbGR4LFxuICBtaXN2YWw6IHJlcXVpcmUoJy4vdXRpbC9taXN2YWwnKSxcbiAgdGltZTogdGltZVV0aWxcbn07XG5cbm1vZHVsZS5leHBvcnRzLnRyYW5zZm9ybXMgPSB7XG4gIGNhdGVnb3JpYWw6IHJlcXVpcmUoJy4vZmFjZXQvY2F0ZWdvcmlhbC10cmFuc2Zvcm0nKSxcbiAgY29udGludW91czogcmVxdWlyZSgnLi9mYWNldC9jb250aW51b3VzLXRyYW5zZm9ybScpLFxuICBkYXRldGltZTogcmVxdWlyZSgnLi9mYWNldC9kYXRldGltZS10cmFuc2Zvcm0nKSxcbiAgZHVyYXRpb246IHJlcXVpcmUoJy4vZmFjZXQvZHVyYXRpb24tdHJhbnNmb3JtJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNvbnN0cnVjdG9ycyA9IHtcbiAgRGF0YXZpZXc6IERhdGF2aWV3LFxuICBEYXRhc2V0OiByZXF1aXJlKCcuL2RhdGFzZXQnKSxcbiAgRGF0YXNldHM6IERhdGFzZXRzXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3b07\n")},"419b":function(module,exports,__webpack_require__){eval('/* WEBPACK VAR INJECTION */(function(global) {\nmodule.exports = isBuf;\n\n/**\n * Returns true if obj is a buffer or an arraybuffer.\n *\n * @api private\n */\n\nfunction isBuf(obj) {\n  return (global.Buffer && global.Buffer.isBuffer(obj)) ||\n         (global.ArrayBuffer && obj instanceof ArrayBuffer);\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ "698d")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDE5Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9pcy1idWZmZXIuanM/MGJlNiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbm1vZHVsZS5leHBvcnRzID0gaXNCdWY7XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIG9iaiBpcyBhIGJ1ZmZlciBvciBhbiBhcnJheWJ1ZmZlci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc0J1ZihvYmopIHtcbiAgcmV0dXJuIChnbG9iYWwuQnVmZmVyICYmIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIob2JqKSkgfHxcbiAgICAgICAgIChnbG9iYWwuQXJyYXlCdWZmZXIgJiYgb2JqIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpO1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///419b\n')},"433b":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(process) {\n/**\n * This is the web browser implementation of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = __webpack_require__(/*! ./debug */ \"23b1\");\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = 'undefined' != typeof chrome\n               && 'undefined' != typeof chrome.storage\n                  ? chrome.storage.local\n                  : localstorage();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n  'lightseagreen',\n  'forestgreen',\n  'goldenrod',\n  'dodgerblue',\n  'darkorchid',\n  'crimson'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\nfunction useColors() {\n  // is webkit? http://stackoverflow.com/a/16459606/376773\n  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n  return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) ||\n    // is firebug? http://stackoverflow.com/a/398120/376773\n    (window.console && (console.firebug || (console.exception && console.table))) ||\n    // is firefox >= v31?\n    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n    (navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31);\n}\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nexports.formatters.j = function(v) {\n  try {\n    return JSON.stringify(v);\n  } catch (err) {\n    return '[UnexpectedJSONParseError]: ' + err.message;\n  }\n};\n\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs() {\n  var args = arguments;\n  var useColors = this.useColors;\n\n  args[0] = (useColors ? '%c' : '')\n    + this.namespace\n    + (useColors ? ' %c' : ' ')\n    + args[0]\n    + (useColors ? '%c ' : ' ')\n    + '+' + exports.humanize(this.diff);\n\n  if (!useColors) return args;\n\n  var c = 'color: ' + this.color;\n  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));\n\n  // the final \"%c\" is somewhat tricky, because there could be other\n  // arguments passed either before or after the %c, so we need to\n  // figure out the correct index to insert the CSS into\n  var index = 0;\n  var lastC = 0;\n  args[0].replace(/%[a-z%]/g, function(match) {\n    if ('%%' === match) return;\n    index++;\n    if ('%c' === match) {\n      // we only are interested in the *last* %c\n      // (the user may have provided their own)\n      lastC = index;\n    }\n  });\n\n  args.splice(lastC, 0, c);\n  return args;\n}\n\n/**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\nfunction log() {\n  // this hackery is required for IE8/9, where\n  // the `console.log` function doesn't have 'apply'\n  return 'object' === typeof console\n    && console.log\n    && Function.prototype.apply.call(console.log, console, arguments);\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\nfunction save(namespaces) {\n  try {\n    if (null == namespaces) {\n      exports.storage.removeItem('debug');\n    } else {\n      exports.storage.debug = namespaces;\n    }\n  } catch(e) {}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n  var r;\n  try {\n    return exports.storage.debug;\n  } catch(e) {}\n\n  // If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n  if (typeof process !== 'undefined' && 'env' in process) {\n    return process.env.DEBUG;\n  }\n}\n\n/**\n * Enable namespaces listed in `localStorage.debug` initially.\n */\n\nexports.enable(load());\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage(){\n  try {\n    return window.localStorage;\n  } catch (e) {}\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../process/browser.js */ \"26d5\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDMzYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZGVidWcvYnJvd3Nlci5qcz82NDdhIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSB3ZWIgYnJvd3NlciBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gKlxuICogRXhwb3NlIGBkZWJ1ZygpYCBhcyB0aGUgbW9kdWxlLlxuICovXG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZGVidWcnKTtcbmV4cG9ydHMubG9nID0gbG9nO1xuZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbmV4cG9ydHMuc2F2ZSA9IHNhdmU7XG5leHBvcnRzLmxvYWQgPSBsb2FkO1xuZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG5leHBvcnRzLnN0b3JhZ2UgPSAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lXG4gICAgICAgICAgICAgICAmJiAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lLnN0b3JhZ2VcbiAgICAgICAgICAgICAgICAgID8gY2hyb21lLnN0b3JhZ2UubG9jYWxcbiAgICAgICAgICAgICAgICAgIDogbG9jYWxzdG9yYWdlKCk7XG5cbi8qKlxuICogQ29sb3JzLlxuICovXG5cbmV4cG9ydHMuY29sb3JzID0gW1xuICAnbGlnaHRzZWFncmVlbicsXG4gICdmb3Jlc3RncmVlbicsXG4gICdnb2xkZW5yb2QnLFxuICAnZG9kZ2VyYmx1ZScsXG4gICdkYXJrb3JjaGlkJyxcbiAgJ2NyaW1zb24nXG5dO1xuXG4vKipcbiAqIEN1cnJlbnRseSBvbmx5IFdlYktpdC1iYXNlZCBXZWIgSW5zcGVjdG9ycywgRmlyZWZveCA+PSB2MzEsXG4gKiBhbmQgdGhlIEZpcmVidWcgZXh0ZW5zaW9uIChhbnkgRmlyZWZveCB2ZXJzaW9uKSBhcmUga25vd25cbiAqIHRvIHN1cHBvcnQgXCIlY1wiIENTUyBjdXN0b21pemF0aW9ucy5cbiAqXG4gKiBUT0RPOiBhZGQgYSBgbG9jYWxTdG9yYWdlYCB2YXJpYWJsZSB0byBleHBsaWNpdGx5IGVuYWJsZS9kaXNhYmxlIGNvbG9yc1xuICovXG5cbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcbiAgLy8gaXMgd2Via2l0PyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNjQ1OTYwNi8zNzY3NzNcbiAgLy8gZG9jdW1lbnQgaXMgdW5kZWZpbmVkIGluIHJlYWN0LW5hdGl2ZTogaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0LW5hdGl2ZS9wdWxsLzE2MzJcbiAgcmV0dXJuICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmICdXZWJraXRBcHBlYXJhbmNlJyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUpIHx8XG4gICAgLy8gaXMgZmlyZWJ1Zz8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzk4MTIwLzM3Njc3M1xuICAgICh3aW5kb3cuY29uc29sZSAmJiAoY29uc29sZS5maXJlYnVnIHx8IChjb25zb2xlLmV4Y2VwdGlvbiAmJiBjb25zb2xlLnRhYmxlKSkpIHx8XG4gICAgLy8gaXMgZmlyZWZveCA+PSB2MzE/XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9Ub29scy9XZWJfQ29uc29sZSNTdHlsaW5nX21lc3NhZ2VzXG4gICAgKG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5tYXRjaCgvZmlyZWZveFxcLyhcXGQrKS8pICYmIHBhcnNlSW50KFJlZ0V4cC4kMSwgMTApID49IDMxKTtcbn1cblxuLyoqXG4gKiBNYXAgJWogdG8gYEpTT04uc3RyaW5naWZ5KClgLCBzaW5jZSBubyBXZWIgSW5zcGVjdG9ycyBkbyB0aGF0IGJ5IGRlZmF1bHQuXG4gKi9cblxuZXhwb3J0cy5mb3JtYXR0ZXJzLmogPSBmdW5jdGlvbih2KSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHYpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gJ1tVbmV4cGVjdGVkSlNPTlBhcnNlRXJyb3JdOiAnICsgZXJyLm1lc3NhZ2U7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBDb2xvcml6ZSBsb2cgYXJndW1lbnRzIGlmIGVuYWJsZWQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBmb3JtYXRBcmdzKCkge1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIHVzZUNvbG9ycyA9IHRoaXMudXNlQ29sb3JzO1xuXG4gIGFyZ3NbMF0gPSAodXNlQ29sb3JzID8gJyVjJyA6ICcnKVxuICAgICsgdGhpcy5uYW1lc3BhY2VcbiAgICArICh1c2VDb2xvcnMgPyAnICVjJyA6ICcgJylcbiAgICArIGFyZ3NbMF1cbiAgICArICh1c2VDb2xvcnMgPyAnJWMgJyA6ICcgJylcbiAgICArICcrJyArIGV4cG9ydHMuaHVtYW5pemUodGhpcy5kaWZmKTtcblxuICBpZiAoIXVzZUNvbG9ycykgcmV0dXJuIGFyZ3M7XG5cbiAgdmFyIGMgPSAnY29sb3I6ICcgKyB0aGlzLmNvbG9yO1xuICBhcmdzID0gW2FyZ3NbMF0sIGMsICdjb2xvcjogaW5oZXJpdCddLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmdzLCAxKSk7XG5cbiAgLy8gdGhlIGZpbmFsIFwiJWNcIiBpcyBzb21ld2hhdCB0cmlja3ksIGJlY2F1c2UgdGhlcmUgY291bGQgYmUgb3RoZXJcbiAgLy8gYXJndW1lbnRzIHBhc3NlZCBlaXRoZXIgYmVmb3JlIG9yIGFmdGVyIHRoZSAlYywgc28gd2UgbmVlZCB0b1xuICAvLyBmaWd1cmUgb3V0IHRoZSBjb3JyZWN0IGluZGV4IHRvIGluc2VydCB0aGUgQ1NTIGludG9cbiAgdmFyIGluZGV4ID0gMDtcbiAgdmFyIGxhc3RDID0gMDtcbiAgYXJnc1swXS5yZXBsYWNlKC8lW2EteiVdL2csIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgaWYgKCclJScgPT09IG1hdGNoKSByZXR1cm47XG4gICAgaW5kZXgrKztcbiAgICBpZiAoJyVjJyA9PT0gbWF0Y2gpIHtcbiAgICAgIC8vIHdlIG9ubHkgYXJlIGludGVyZXN0ZWQgaW4gdGhlICpsYXN0KiAlY1xuICAgICAgLy8gKHRoZSB1c2VyIG1heSBoYXZlIHByb3ZpZGVkIHRoZWlyIG93bilcbiAgICAgIGxhc3RDID0gaW5kZXg7XG4gICAgfVxuICB9KTtcblxuICBhcmdzLnNwbGljZShsYXN0QywgMCwgYyk7XG4gIHJldHVybiBhcmdzO1xufVxuXG4vKipcbiAqIEludm9rZXMgYGNvbnNvbGUubG9nKClgIHdoZW4gYXZhaWxhYmxlLlxuICogTm8tb3Agd2hlbiBgY29uc29sZS5sb2dgIGlzIG5vdCBhIFwiZnVuY3Rpb25cIi5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGxvZygpIHtcbiAgLy8gdGhpcyBoYWNrZXJ5IGlzIHJlcXVpcmVkIGZvciBJRTgvOSwgd2hlcmVcbiAgLy8gdGhlIGBjb25zb2xlLmxvZ2AgZnVuY3Rpb24gZG9lc24ndCBoYXZlICdhcHBseSdcbiAgcmV0dXJuICdvYmplY3QnID09PSB0eXBlb2YgY29uc29sZVxuICAgICYmIGNvbnNvbGUubG9nXG4gICAgJiYgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoY29uc29sZS5sb2csIGNvbnNvbGUsIGFyZ3VtZW50cyk7XG59XG5cbi8qKlxuICogU2F2ZSBgbmFtZXNwYWNlc2AuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNhdmUobmFtZXNwYWNlcykge1xuICB0cnkge1xuICAgIGlmIChudWxsID09IG5hbWVzcGFjZXMpIHtcbiAgICAgIGV4cG9ydHMuc3RvcmFnZS5yZW1vdmVJdGVtKCdkZWJ1ZycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLnN0b3JhZ2UuZGVidWcgPSBuYW1lc3BhY2VzO1xuICAgIH1cbiAgfSBjYXRjaChlKSB7fVxufVxuXG4vKipcbiAqIExvYWQgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gcmV0dXJucyB0aGUgcHJldmlvdXNseSBwZXJzaXN0ZWQgZGVidWcgbW9kZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvYWQoKSB7XG4gIHZhciByO1xuICB0cnkge1xuICAgIHJldHVybiBleHBvcnRzLnN0b3JhZ2UuZGVidWc7XG4gIH0gY2F0Y2goZSkge31cblxuICAvLyBJZiBkZWJ1ZyBpc24ndCBzZXQgaW4gTFMsIGFuZCB3ZSdyZSBpbiBFbGVjdHJvbiwgdHJ5IHRvIGxvYWQgJERFQlVHXG4gIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ2VudicgaW4gcHJvY2Vzcykge1xuICAgIHJldHVybiBwcm9jZXNzLmVudi5ERUJVRztcbiAgfVxufVxuXG4vKipcbiAqIEVuYWJsZSBuYW1lc3BhY2VzIGxpc3RlZCBpbiBgbG9jYWxTdG9yYWdlLmRlYnVnYCBpbml0aWFsbHkuXG4gKi9cblxuZXhwb3J0cy5lbmFibGUobG9hZCgpKTtcblxuLyoqXG4gKiBMb2NhbHN0b3JhZ2UgYXR0ZW1wdHMgdG8gcmV0dXJuIHRoZSBsb2NhbHN0b3JhZ2UuXG4gKlxuICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBzYWZhcmkgdGhyb3dzXG4gKiB3aGVuIGEgdXNlciBkaXNhYmxlcyBjb29raWVzL2xvY2Fsc3RvcmFnZVxuICogYW5kIHlvdSBhdHRlbXB0IHRvIGFjY2VzcyBpdC5cbiAqXG4gKiBAcmV0dXJuIHtMb2NhbFN0b3JhZ2V9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2NhbHN0b3JhZ2UoKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZTtcbiAgfSBjYXRjaCAoZSkge31cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///433b\n")},"4c13":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"ee5b\");\nvar toArray = __webpack_require__(/*! to-array */ \"7de3\");\nvar on = __webpack_require__(/*! ./on */ \"faaa\");\nvar bind = __webpack_require__(/*! component-bind */ \"b6f6\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:socket');\nvar hasBin = __webpack_require__(/*! has-binary */ \"d304\");\n\n/**\n * Module exports.\n */\n\nmodule.exports = exports = Socket;\n\n/**\n * Internal events (blacklisted).\n * These events can't be emitted by the user.\n *\n * @api private\n */\n\nvar events = {\n  connect: 1,\n  connect_error: 1,\n  connect_timeout: 1,\n  connecting: 1,\n  disconnect: 1,\n  error: 1,\n  reconnect: 1,\n  reconnect_attempt: 1,\n  reconnect_failed: 1,\n  reconnect_error: 1,\n  reconnecting: 1,\n  ping: 1,\n  pong: 1\n};\n\n/**\n * Shortcut to `Emitter#emit`.\n */\n\nvar emit = Emitter.prototype.emit;\n\n/**\n * `Socket` constructor.\n *\n * @api public\n */\n\nfunction Socket (io, nsp, opts) {\n  this.io = io;\n  this.nsp = nsp;\n  this.json = this; // compat\n  this.ids = 0;\n  this.acks = {};\n  this.receiveBuffer = [];\n  this.sendBuffer = [];\n  this.connected = false;\n  this.disconnected = true;\n  if (opts && opts.query) {\n    this.query = opts.query;\n  }\n  if (this.io.autoConnect) this.open();\n}\n\n/**\n * Mix in `Emitter`.\n */\n\nEmitter(Socket.prototype);\n\n/**\n * Subscribe to open, close and packet events\n *\n * @api private\n */\n\nSocket.prototype.subEvents = function () {\n  if (this.subs) return;\n\n  var io = this.io;\n  this.subs = [\n    on(io, 'open', bind(this, 'onopen')),\n    on(io, 'packet', bind(this, 'onpacket')),\n    on(io, 'close', bind(this, 'onclose'))\n  ];\n};\n\n/**\n * \"Opens\" the socket.\n *\n * @api public\n */\n\nSocket.prototype.open =\nSocket.prototype.connect = function () {\n  if (this.connected) return this;\n\n  this.subEvents();\n  this.io.open(); // ensure open\n  if ('open' === this.io.readyState) this.onopen();\n  this.emit('connecting');\n  return this;\n};\n\n/**\n * Sends a `message` event.\n *\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.send = function () {\n  var args = toArray(arguments);\n  args.unshift('message');\n  this.emit.apply(this, args);\n  return this;\n};\n\n/**\n * Override `emit`.\n * If the event is in `events`, it's emitted normally.\n *\n * @param {String} event name\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.emit = function (ev) {\n  if (events.hasOwnProperty(ev)) {\n    emit.apply(this, arguments);\n    return this;\n  }\n\n  var args = toArray(arguments);\n  var parserType = parser.EVENT; // default\n  if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary\n  var packet = { type: parserType, data: args };\n\n  packet.options = {};\n  packet.options.compress = !this.flags || false !== this.flags.compress;\n\n  // event ack callback\n  if ('function' === typeof args[args.length - 1]) {\n    debug('emitting packet with ack id %d', this.ids);\n    this.acks[this.ids] = args.pop();\n    packet.id = this.ids++;\n  }\n\n  if (this.connected) {\n    this.packet(packet);\n  } else {\n    this.sendBuffer.push(packet);\n  }\n\n  delete this.flags;\n\n  return this;\n};\n\n/**\n * Sends a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.packet = function (packet) {\n  packet.nsp = this.nsp;\n  this.io.packet(packet);\n};\n\n/**\n * Called upon engine `open`.\n *\n * @api private\n */\n\nSocket.prototype.onopen = function () {\n  debug('transport is open - connecting');\n\n  // write connect packet if necessary\n  if ('/' !== this.nsp) {\n    if (this.query) {\n      this.packet({type: parser.CONNECT, query: this.query});\n    } else {\n      this.packet({type: parser.CONNECT});\n    }\n  }\n};\n\n/**\n * Called upon engine `close`.\n *\n * @param {String} reason\n * @api private\n */\n\nSocket.prototype.onclose = function (reason) {\n  debug('close (%s)', reason);\n  this.connected = false;\n  this.disconnected = true;\n  delete this.id;\n  this.emit('disconnect', reason);\n};\n\n/**\n * Called with socket packet.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onpacket = function (packet) {\n  if (packet.nsp !== this.nsp) return;\n\n  switch (packet.type) {\n    case parser.CONNECT:\n      this.onconnect();\n      break;\n\n    case parser.EVENT:\n      this.onevent(packet);\n      break;\n\n    case parser.BINARY_EVENT:\n      this.onevent(packet);\n      break;\n\n    case parser.ACK:\n      this.onack(packet);\n      break;\n\n    case parser.BINARY_ACK:\n      this.onack(packet);\n      break;\n\n    case parser.DISCONNECT:\n      this.ondisconnect();\n      break;\n\n    case parser.ERROR:\n      this.emit('error', packet.data);\n      break;\n  }\n};\n\n/**\n * Called upon a server event.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onevent = function (packet) {\n  var args = packet.data || [];\n  debug('emitting event %j', args);\n\n  if (null != packet.id) {\n    debug('attaching ack callback to event');\n    args.push(this.ack(packet.id));\n  }\n\n  if (this.connected) {\n    emit.apply(this, args);\n  } else {\n    this.receiveBuffer.push(args);\n  }\n};\n\n/**\n * Produces an ack callback to emit with an event.\n *\n * @api private\n */\n\nSocket.prototype.ack = function (id) {\n  var self = this;\n  var sent = false;\n  return function () {\n    // prevent double callbacks\n    if (sent) return;\n    sent = true;\n    var args = toArray(arguments);\n    debug('sending ack %j', args);\n\n    var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;\n    self.packet({\n      type: type,\n      id: id,\n      data: args\n    });\n  };\n};\n\n/**\n * Called upon a server acknowlegement.\n *\n * @param {Object} packet\n * @api private\n */\n\nSocket.prototype.onack = function (packet) {\n  var ack = this.acks[packet.id];\n  if ('function' === typeof ack) {\n    debug('calling ack %s with %j', packet.id, packet.data);\n    ack.apply(this, packet.data);\n    delete this.acks[packet.id];\n  } else {\n    debug('bad ack %s', packet.id);\n  }\n};\n\n/**\n * Called upon server connect.\n *\n * @api private\n */\n\nSocket.prototype.onconnect = function () {\n  this.connected = true;\n  this.disconnected = false;\n  this.emit('connect');\n  this.emitBuffered();\n};\n\n/**\n * Emit buffered events (received and emitted).\n *\n * @api private\n */\n\nSocket.prototype.emitBuffered = function () {\n  var i;\n  for (i = 0; i < this.receiveBuffer.length; i++) {\n    emit.apply(this, this.receiveBuffer[i]);\n  }\n  this.receiveBuffer = [];\n\n  for (i = 0; i < this.sendBuffer.length; i++) {\n    this.packet(this.sendBuffer[i]);\n  }\n  this.sendBuffer = [];\n};\n\n/**\n * Called upon server disconnect.\n *\n * @api private\n */\n\nSocket.prototype.ondisconnect = function () {\n  debug('server disconnect (%s)', this.nsp);\n  this.destroy();\n  this.onclose('io server disconnect');\n};\n\n/**\n * Called upon forced client/server side disconnections,\n * this method ensures the manager stops tracking us and\n * that reconnections don't get triggered for this.\n *\n * @api private.\n */\n\nSocket.prototype.destroy = function () {\n  if (this.subs) {\n    // clean subscriptions to avoid reconnections\n    for (var i = 0; i < this.subs.length; i++) {\n      this.subs[i].destroy();\n    }\n    this.subs = null;\n  }\n\n  this.io.destroy(this);\n};\n\n/**\n * Disconnects the socket manually.\n *\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.close =\nSocket.prototype.disconnect = function () {\n  if (this.connected) {\n    debug('performing disconnect (%s)', this.nsp);\n    this.packet({ type: parser.DISCONNECT });\n  }\n\n  // remove socket from pool\n  this.destroy();\n\n  if (this.connected) {\n    // fire events\n    this.onclose('io client disconnect');\n  }\n  return this;\n};\n\n/**\n * Sets the compress flag.\n *\n * @param {Boolean} if `true`, compresses the sending data\n * @return {Socket} self\n * @api public\n */\n\nSocket.prototype.compress = function (compress) {\n  this.flags = this.flags || {};\n  this.flags.compress = compress;\n  return this;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNGMxMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvc29ja2V0LmpzPzg3ZDEiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNlciA9IHJlcXVpcmUoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciB0b0FycmF5ID0gcmVxdWlyZSgndG8tYXJyYXknKTtcbnZhciBvbiA9IHJlcXVpcmUoJy4vb24nKTtcbnZhciBiaW5kID0gcmVxdWlyZSgnY29tcG9uZW50LWJpbmQnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6c29ja2V0Jyk7XG52YXIgaGFzQmluID0gcmVxdWlyZSgnaGFzLWJpbmFyeScpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IFNvY2tldDtcblxuLyoqXG4gKiBJbnRlcm5hbCBldmVudHMgKGJsYWNrbGlzdGVkKS5cbiAqIFRoZXNlIGV2ZW50cyBjYW4ndCBiZSBlbWl0dGVkIGJ5IHRoZSB1c2VyLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbnZhciBldmVudHMgPSB7XG4gIGNvbm5lY3Q6IDEsXG4gIGNvbm5lY3RfZXJyb3I6IDEsXG4gIGNvbm5lY3RfdGltZW91dDogMSxcbiAgY29ubmVjdGluZzogMSxcbiAgZGlzY29ubmVjdDogMSxcbiAgZXJyb3I6IDEsXG4gIHJlY29ubmVjdDogMSxcbiAgcmVjb25uZWN0X2F0dGVtcHQ6IDEsXG4gIHJlY29ubmVjdF9mYWlsZWQ6IDEsXG4gIHJlY29ubmVjdF9lcnJvcjogMSxcbiAgcmVjb25uZWN0aW5nOiAxLFxuICBwaW5nOiAxLFxuICBwb25nOiAxXG59O1xuXG4vKipcbiAqIFNob3J0Y3V0IHRvIGBFbWl0dGVyI2VtaXRgLlxuICovXG5cbnZhciBlbWl0ID0gRW1pdHRlci5wcm90b3R5cGUuZW1pdDtcblxuLyoqXG4gKiBgU29ja2V0YCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFNvY2tldCAoaW8sIG5zcCwgb3B0cykge1xuICB0aGlzLmlvID0gaW87XG4gIHRoaXMubnNwID0gbnNwO1xuICB0aGlzLmpzb24gPSB0aGlzOyAvLyBjb21wYXRcbiAgdGhpcy5pZHMgPSAwO1xuICB0aGlzLmFja3MgPSB7fTtcbiAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG4gIHRoaXMuc2VuZEJ1ZmZlciA9IFtdO1xuICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICB0aGlzLmRpc2Nvbm5lY3RlZCA9IHRydWU7XG4gIGlmIChvcHRzICYmIG9wdHMucXVlcnkpIHtcbiAgICB0aGlzLnF1ZXJ5ID0gb3B0cy5xdWVyeTtcbiAgfVxuICBpZiAodGhpcy5pby5hdXRvQ29ubmVjdCkgdGhpcy5vcGVuKCk7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFNvY2tldC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIFN1YnNjcmliZSB0byBvcGVuLCBjbG9zZSBhbmQgcGFja2V0IGV2ZW50c1xuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc3ViRXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zdWJzKSByZXR1cm47XG5cbiAgdmFyIGlvID0gdGhpcy5pbztcbiAgdGhpcy5zdWJzID0gW1xuICAgIG9uKGlvLCAnb3BlbicsIGJpbmQodGhpcywgJ29ub3BlbicpKSxcbiAgICBvbihpbywgJ3BhY2tldCcsIGJpbmQodGhpcywgJ29ucGFja2V0JykpLFxuICAgIG9uKGlvLCAnY2xvc2UnLCBiaW5kKHRoaXMsICdvbmNsb3NlJykpXG4gIF07XG59O1xuXG4vKipcbiAqIFwiT3BlbnNcIiB0aGUgc29ja2V0LlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vcGVuID1cblNvY2tldC5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY29ubmVjdGVkKSByZXR1cm4gdGhpcztcblxuICB0aGlzLnN1YkV2ZW50cygpO1xuICB0aGlzLmlvLm9wZW4oKTsgLy8gZW5zdXJlIG9wZW5cbiAgaWYgKCdvcGVuJyA9PT0gdGhpcy5pby5yZWFkeVN0YXRlKSB0aGlzLm9ub3BlbigpO1xuICB0aGlzLmVtaXQoJ2Nvbm5lY3RpbmcnKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIGEgYG1lc3NhZ2VgIGV2ZW50LlxuICpcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMpO1xuICBhcmdzLnVuc2hpZnQoJ21lc3NhZ2UnKTtcbiAgdGhpcy5lbWl0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgYGVtaXRgLlxuICogSWYgdGhlIGV2ZW50IGlzIGluIGBldmVudHNgLCBpdCdzIGVtaXR0ZWQgbm9ybWFsbHkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IG5hbWVcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShldikpIHtcbiAgICBlbWl0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgdmFyIHBhcnNlclR5cGUgPSBwYXJzZXIuRVZFTlQ7IC8vIGRlZmF1bHRcbiAgaWYgKGhhc0JpbihhcmdzKSkgeyBwYXJzZXJUeXBlID0gcGFyc2VyLkJJTkFSWV9FVkVOVDsgfSAvLyBiaW5hcnlcbiAgdmFyIHBhY2tldCA9IHsgdHlwZTogcGFyc2VyVHlwZSwgZGF0YTogYXJncyB9O1xuXG4gIHBhY2tldC5vcHRpb25zID0ge307XG4gIHBhY2tldC5vcHRpb25zLmNvbXByZXNzID0gIXRoaXMuZmxhZ3MgfHwgZmFsc2UgIT09IHRoaXMuZmxhZ3MuY29tcHJlc3M7XG5cbiAgLy8gZXZlbnQgYWNrIGNhbGxiYWNrXG4gIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgYXJnc1thcmdzLmxlbmd0aCAtIDFdKSB7XG4gICAgZGVidWcoJ2VtaXR0aW5nIHBhY2tldCB3aXRoIGFjayBpZCAlZCcsIHRoaXMuaWRzKTtcbiAgICB0aGlzLmFja3NbdGhpcy5pZHNdID0gYXJncy5wb3AoKTtcbiAgICBwYWNrZXQuaWQgPSB0aGlzLmlkcysrO1xuICB9XG5cbiAgaWYgKHRoaXMuY29ubmVjdGVkKSB7XG4gICAgdGhpcy5wYWNrZXQocGFja2V0KTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnNlbmRCdWZmZXIucHVzaChwYWNrZXQpO1xuICB9XG5cbiAgZGVsZXRlIHRoaXMuZmxhZ3M7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIGEgcGFja2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUucGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICBwYWNrZXQubnNwID0gdGhpcy5uc3A7XG4gIHRoaXMuaW8ucGFja2V0KHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGVuZ2luZSBgb3BlbmAuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCd0cmFuc3BvcnQgaXMgb3BlbiAtIGNvbm5lY3RpbmcnKTtcblxuICAvLyB3cml0ZSBjb25uZWN0IHBhY2tldCBpZiBuZWNlc3NhcnlcbiAgaWYgKCcvJyAhPT0gdGhpcy5uc3ApIHtcbiAgICBpZiAodGhpcy5xdWVyeSkge1xuICAgICAgdGhpcy5wYWNrZXQoe3R5cGU6IHBhcnNlci5DT05ORUNULCBxdWVyeTogdGhpcy5xdWVyeX0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBhY2tldCh7dHlwZTogcGFyc2VyLkNPTk5FQ1R9KTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZW5naW5lIGBjbG9zZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJlYXNvblxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICBkZWJ1ZygnY2xvc2UgKCVzKScsIHJlYXNvbik7XG4gIHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG4gIHRoaXMuZGlzY29ubmVjdGVkID0gdHJ1ZTtcbiAgZGVsZXRlIHRoaXMuaWQ7XG4gIHRoaXMuZW1pdCgnZGlzY29ubmVjdCcsIHJlYXNvbik7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIHNvY2tldCBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbnBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgaWYgKHBhY2tldC5uc3AgIT09IHRoaXMubnNwKSByZXR1cm47XG5cbiAgc3dpdGNoIChwYWNrZXQudHlwZSkge1xuICAgIGNhc2UgcGFyc2VyLkNPTk5FQ1Q6XG4gICAgICB0aGlzLm9uY29ubmVjdCgpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5FVkVOVDpcbiAgICAgIHRoaXMub25ldmVudChwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfRVZFTlQ6XG4gICAgICB0aGlzLm9uZXZlbnQocGFja2V0KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5ESVNDT05ORUNUOlxuICAgICAgdGhpcy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuRVJST1I6XG4gICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgcGFja2V0LmRhdGEpO1xuICAgICAgYnJlYWs7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gYSBzZXJ2ZXIgZXZlbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmV2ZW50ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICB2YXIgYXJncyA9IHBhY2tldC5kYXRhIHx8IFtdO1xuICBkZWJ1ZygnZW1pdHRpbmcgZXZlbnQgJWonLCBhcmdzKTtcblxuICBpZiAobnVsbCAhPSBwYWNrZXQuaWQpIHtcbiAgICBkZWJ1ZygnYXR0YWNoaW5nIGFjayBjYWxsYmFjayB0byBldmVudCcpO1xuICAgIGFyZ3MucHVzaCh0aGlzLmFjayhwYWNrZXQuaWQpKTtcbiAgfVxuXG4gIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgIGVtaXQuYXBwbHkodGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yZWNlaXZlQnVmZmVyLnB1c2goYXJncyk7XG4gIH1cbn07XG5cbi8qKlxuICogUHJvZHVjZXMgYW4gYWNrIGNhbGxiYWNrIHRvIGVtaXQgd2l0aCBhbiBldmVudC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmFjayA9IGZ1bmN0aW9uIChpZCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBzZW50ID0gZmFsc2U7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gcHJldmVudCBkb3VibGUgY2FsbGJhY2tzXG4gICAgaWYgKHNlbnQpIHJldHVybjtcbiAgICBzZW50ID0gdHJ1ZTtcbiAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICBkZWJ1Zygnc2VuZGluZyBhY2sgJWonLCBhcmdzKTtcblxuICAgIHZhciB0eXBlID0gaGFzQmluKGFyZ3MpID8gcGFyc2VyLkJJTkFSWV9BQ0sgOiBwYXJzZXIuQUNLO1xuICAgIHNlbGYucGFja2V0KHtcbiAgICAgIHR5cGU6IHR5cGUsXG4gICAgICBpZDogaWQsXG4gICAgICBkYXRhOiBhcmdzXG4gICAgfSk7XG4gIH07XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgc2VydmVyIGFja25vd2xlZ2VtZW50LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25hY2sgPSBmdW5jdGlvbiAocGFja2V0KSB7XG4gIHZhciBhY2sgPSB0aGlzLmFja3NbcGFja2V0LmlkXTtcbiAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBhY2spIHtcbiAgICBkZWJ1ZygnY2FsbGluZyBhY2sgJXMgd2l0aCAlaicsIHBhY2tldC5pZCwgcGFja2V0LmRhdGEpO1xuICAgIGFjay5hcHBseSh0aGlzLCBwYWNrZXQuZGF0YSk7XG4gICAgZGVsZXRlIHRoaXMuYWNrc1twYWNrZXQuaWRdO1xuICB9IGVsc2Uge1xuICAgIGRlYnVnKCdiYWQgYWNrICVzJywgcGFja2V0LmlkKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzZXJ2ZXIgY29ubmVjdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuICB0aGlzLmRpc2Nvbm5lY3RlZCA9IGZhbHNlO1xuICB0aGlzLmVtaXQoJ2Nvbm5lY3QnKTtcbiAgdGhpcy5lbWl0QnVmZmVyZWQoKTtcbn07XG5cbi8qKlxuICogRW1pdCBidWZmZXJlZCBldmVudHMgKHJlY2VpdmVkIGFuZCBlbWl0dGVkKS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmVtaXRCdWZmZXJlZCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnJlY2VpdmVCdWZmZXIubGVuZ3RoOyBpKyspIHtcbiAgICBlbWl0LmFwcGx5KHRoaXMsIHRoaXMucmVjZWl2ZUJ1ZmZlcltpXSk7XG4gIH1cbiAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMuc2VuZEJ1ZmZlci5sZW5ndGg7IGkrKykge1xuICAgIHRoaXMucGFja2V0KHRoaXMuc2VuZEJ1ZmZlcltpXSk7XG4gIH1cbiAgdGhpcy5zZW5kQnVmZmVyID0gW107XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHNlcnZlciBkaXNjb25uZWN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25kaXNjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1Zygnc2VydmVyIGRpc2Nvbm5lY3QgKCVzKScsIHRoaXMubnNwKTtcbiAgdGhpcy5kZXN0cm95KCk7XG4gIHRoaXMub25jbG9zZSgnaW8gc2VydmVyIGRpc2Nvbm5lY3QnKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZm9yY2VkIGNsaWVudC9zZXJ2ZXIgc2lkZSBkaXNjb25uZWN0aW9ucyxcbiAqIHRoaXMgbWV0aG9kIGVuc3VyZXMgdGhlIG1hbmFnZXIgc3RvcHMgdHJhY2tpbmcgdXMgYW5kXG4gKiB0aGF0IHJlY29ubmVjdGlvbnMgZG9uJ3QgZ2V0IHRyaWdnZXJlZCBmb3IgdGhpcy5cbiAqXG4gKiBAYXBpIHByaXZhdGUuXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zdWJzKSB7XG4gICAgLy8gY2xlYW4gc3Vic2NyaXB0aW9ucyB0byBhdm9pZCByZWNvbm5lY3Rpb25zXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuc3Vic1tpXS5kZXN0cm95KCk7XG4gICAgfVxuICAgIHRoaXMuc3VicyA9IG51bGw7XG4gIH1cblxuICB0aGlzLmlvLmRlc3Ryb3kodGhpcyk7XG59O1xuXG4vKipcbiAqIERpc2Nvbm5lY3RzIHRoZSBzb2NrZXQgbWFudWFsbHkuXG4gKlxuICogQHJldHVybiB7U29ja2V0fSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPVxuU29ja2V0LnByb3RvdHlwZS5kaXNjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jb25uZWN0ZWQpIHtcbiAgICBkZWJ1ZygncGVyZm9ybWluZyBkaXNjb25uZWN0ICglcyknLCB0aGlzLm5zcCk7XG4gICAgdGhpcy5wYWNrZXQoeyB0eXBlOiBwYXJzZXIuRElTQ09OTkVDVCB9KTtcbiAgfVxuXG4gIC8vIHJlbW92ZSBzb2NrZXQgZnJvbSBwb29sXG4gIHRoaXMuZGVzdHJveSgpO1xuXG4gIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgIC8vIGZpcmUgZXZlbnRzXG4gICAgdGhpcy5vbmNsb3NlKCdpbyBjbGllbnQgZGlzY29ubmVjdCcpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBjb21wcmVzcyBmbGFnLlxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaWYgYHRydWVgLCBjb21wcmVzc2VzIHRoZSBzZW5kaW5nIGRhdGFcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNvbXByZXNzID0gZnVuY3Rpb24gKGNvbXByZXNzKSB7XG4gIHRoaXMuZmxhZ3MgPSB0aGlzLmZsYWdzIHx8IHt9O1xuICB0aGlzLmZsYWdzLmNvbXByZXNzID0gY29tcHJlc3M7XG4gIHJldHVybiB0aGlzO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4c13\n")},"4d50":function(module,exports,__webpack_require__){eval("/**\n * Facets are the main abstraction over the data.\n *\n * A `Dataset` is a collection of (similar) items, with each item having a certain set of properties, ie. `Facet`s.\n * The `Facet` class defines the property: It can be a continuous value, a set of labels or tags,\n * or it can be result of some transformation or equation.\n *\n * @class Facet\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar CategorialTransform = __webpack_require__(/*! ./facet/categorial-transform */ \"9b75\");\nvar ContinuousTransform = __webpack_require__(/*! ./facet/continuous-transform */ \"5a80\");\nvar datetimeTransform = __webpack_require__(/*! ./facet/datetime-transform */ \"a0ca\");\nvar durationTransform = __webpack_require__(/*! ./facet/duration-transform */ \"b123\");\nvar textTransform = __webpack_require__(/*! ./facet/text-transform */ \"e810\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    this.on('change:type', function (facet, newval) {\n      // reset transformations on type change\n      this.continuousTransform.reset();\n      this.categorialTransform.reset();\n      this.datetimeTransform.reset();\n      this.durationTransform.reset();\n    });\n  },\n  props: {\n    /**\n     * Show in facet lists (used for interactive searching on Facets page)\n     * @memberof! Facet\n     * @type {boolean}\n     */\n    show: ['boolean', false, true],\n\n    /**\n     * Show facet bar (on Analyze page)\n     * @memberof! Facet\n     * @type {boolean}\n     */\n    isActive: ['boolean', false, false],\n\n    // general facet properties\n    /**\n     * Description of this facet, for displaying purposes\n     * @memberof! Facet\n     * @type {string}\n     */\n    description: ['string', true, ''],\n\n    /**\n     * For continuous facets, its units for displaying purposes\n     * @memberof! Facet\n     * @type {string}\n     */\n    units: ['string', true, ''],\n\n    /**\n     * Short name (human readable) for this facet, must be unique.\n     * @memberof! Facet\n     * @type {string}\n     */\n    name: ['string', true, ''],\n\n    /**\n     * Type of this facet:\n     *  * `constant`        A constant value of \"1\" for all data items\n     *  * `continuous`      The facet takes on real numbers\n     *  * `categorial`      The facet is a string, or an array of strings (for a well defined set of labels and tags)\n     *  * `datetime`        The facet is a datetime (using momentjs.tz)\n     *  * `duration`        The facet is a duration (using momentjs.duration)\n     *  * `text`            Freeform text.\n     * Check for facet type using isConstant, isContinuous, isCategorial, isDatetime, isDuration, or isText  properties.\n     * @memberof! Facet\n     * @type {string}\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['constant', 'continuous', 'categorial', 'datetime', 'duration', 'text']\n    },\n\n    /**\n     * The accessor for this facet.\n     * For nested properties use dot notation: For a dataset `[ {name: {first: \"Santa\", last: \"Claus\"}}, ...]`\n     * you can use `name.first` and `name.last` to get Santa and Claus, respectively.\n     *\n     * @memberof! Facet\n     * @type {string}\n     */\n    accessor: ['string', false, null],\n\n    /**\n     * Missing or invalid data indicator; for multiple values, use a comma separated, quoted list\n     * Numbers, strings, booleans, and the special value null are allowed.\n     * Use single or double quotes for strings \"missing\".\n     * The parsed values are available in the misval property.\n     *\n     * @memberof! Facet\n     * @type {string}\n     */\n    misvalAsText: 'string',\n\n    /**\n     * For continuous or datetime Facets, the minimum value as text.\n     * Parsed value available in the `minval` property\n     * @memberof! Facet\n     * @type {string}\n     */\n    minvalAsText: 'string',\n\n    /**\n     * For continuous or datetime Facets, the maximum value as text.\n     * Parsed value available in the `maxval` property\n     * @memberof! Facet\n     * @type {string}\n     */\n    maxvalAsText: 'string'\n  },\n  children: {\n    /**\n     * A categorial transformation to apply to the data\n     * @memberof! Facet\n     * @type {CategorialTransform}\n     */\n    categorialTransform: CategorialTransform,\n    /**\n     * A datetime transformation to apply to the data\n     * @memberof! Facet\n     * @type {dateimeTransform}\n     */\n    datetimeTransform: datetimeTransform,\n    /**\n     * A duration transformation to apply to the data\n     * @memberof! Facet\n     * @type {dateimeTransform}\n     */\n    durationTransform: durationTransform,\n    /**\n     * A continuous transformation to apply to the data\n     * @memberof! Facet\n     * @type {ContinuousTransform}\n     */\n    continuousTransform: ContinuousTransform,\n    /**\n     * A text transform\n     * @memberof! Facet\n     * @type {TextTransform}\n     */\n    textTransform: textTransform\n  },\n\n  derived: {\n    // properties for: type\n    isConstant: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'constant';\n      }\n    },\n    isContinuous: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'continuous';\n      }\n    },\n    isCategorial: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'categorial';\n      }\n    },\n    isDatetime: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'datetime';\n      }\n    },\n    isDuration: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'duration';\n      }\n    },\n    isText: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'text';\n      }\n    },\n\n    /**\n     * Array of missing data indicators\n     * @memberof! Facet\n     * @type {Object[]}\n     * @readonly\n     */\n    misval: {\n      deps: ['misvalAsText'],\n      fn: function () {\n        // Parse the text content as a JSON array:\n        //  - strings should be quoted\n        //  - numbers unquoated\n        //  - special numbers not allowed: NaN, Infinity\n        try {\n          if (this.misvalAsText !== null) {\n            return JSON.parse('[' + this.misvalAsText + ']');\n          } else {\n            return [];\n          }\n        } catch (e) {\n          return [];\n        }\n      },\n      cache: false\n    },\n\n    /**\n     * For continuous or datetime Facets, the minimum value.\n     * @memberof! Facet\n     * @type {number|datetime}\n     * @readonly\n     */\n    minval: {\n      deps: ['minvalAsText', 'type'],\n      fn: function () {\n        var min;\n        if (this.isContinuous) {\n          min = parseFloat(this.minvalAsText);\n          if (isNaN(min)) {\n            min = 0;\n          }\n        } else if (this.isDatetime) {\n          min = moment(this.minvalAsText, moment.ISO_8601);\n          if (!min.isValid()) {\n            min = moment('2010-01-01 00:00', moment.ISO_8601);\n          }\n        } else if (this.isDuration) {\n          min = moment.duration(this.minvalAsText);\n          if (!moment.isDuration(min)) {\n            min = moment.duration(1, 'seconds');\n          }\n        }\n        return min;\n      },\n      cache: false\n    },\n    /**\n     * For continuous or datetime Facets, the maximum value.\n     * @memberof! Facet\n     * @type {number|datetime}\n     * @readonly\n     */\n    maxval: {\n      deps: ['maxvalAsText', 'type'],\n      fn: function () {\n        var max;\n        if (this.isContinuous) {\n          max = parseFloat(this.maxvalAsText);\n          if (isNaN(max)) {\n            max = 100;\n          }\n        } else if (this.isDatetime) {\n          max = moment(this.maxvalAsText, moment.ISO_8601);\n          if (!max.isValid()) {\n            max = moment('2020-01-01 00:00', moment.ISO_8601);\n          }\n        } else if (this.isDuration) {\n          max = moment.duration(this.maxvalAsText);\n          if (!moment.isDuration(max)) {\n            max = moment.duration(100, 'seconds');\n          }\n        }\n        return max;\n      },\n      cache: false\n    },\n    transform: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isContinuous) {\n          return this.continuousTransform;\n        } else if (this.isCategorial) {\n          return this.categorialTransform;\n        } else if (this.isDatetime) {\n          return this.datetimeTransform;\n        } else if (this.isDuration) {\n          return this.durationTransform;\n        } else if (this.isText) {\n          return this.textTransform;\n        }\n        console.error('Invalid facet');\n      },\n      cache: false\n    }\n  },\n  /**\n   * setMinMax sets the range of a continuous or time facet\n   * For facets in a dataview, the minimum is just the minimum of the facet over all active datasets,\n   * and the same for the maximum.\n   * For facets in a datset, the actual implementation is in the dataset driver.\n   *\n   * @memberof! Facet\n   */\n  setMinMax: function () {\n    var Dataset = __webpack_require__(/*! ./dataset */ \"545a\");\n    var Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\n\n    var ancestor = this.collection.parent;\n    var spot;\n\n    if (ancestor instanceof Dataview) {\n      // Facet -> Facets -> Dataview -> Spot\n      spot = this.collection.parent.parent;\n      spot.setFacetMinMax(this);\n    } else if (ancestor instanceof Dataset) {\n      // Dataset -> Datasets -> Spot\n      spot = ancestor.collection.parent;\n      spot.driver.setMinMax(ancestor, this);\n    }\n  },\n  /**\n   * setCategories finds finds all values on an ordinal (categorial) axis\n   * Updates the categorialTransform of the facet\n   * For facets in a dataview, this is the union of the categories of facet over all active datasets.\n   * For facets in a dataset, the actual implementation is in the dataset driver.\n   *\n   * @memberof! Facet\n   */\n  setCategories: function () {\n    var Dataset = __webpack_require__(/*! ./dataset */ \"545a\");\n    var Dataview = __webpack_require__(/*! ./dataview */ \"5066\");\n\n    var ancestor = this.collection.parent;\n    var spot;\n\n    if (ancestor instanceof Dataview) {\n      // Facet -> Facets -> Dataview -> Spot\n      spot = this.collection.parent.parent;\n      spot.setFacetCategories(this);\n    } else if (ancestor instanceof Dataset) {\n      // Facet -> Facets -> Dataset -> Datasets -> Spot\n      spot = ancestor.collection.parent;\n      spot.driver.setCategories(ancestor, this);\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNGQ1MC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQuanM/ZDdlYiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEZhY2V0cyBhcmUgdGhlIG1haW4gYWJzdHJhY3Rpb24gb3ZlciB0aGUgZGF0YS5cbiAqXG4gKiBBIGBEYXRhc2V0YCBpcyBhIGNvbGxlY3Rpb24gb2YgKHNpbWlsYXIpIGl0ZW1zLCB3aXRoIGVhY2ggaXRlbSBoYXZpbmcgYSBjZXJ0YWluIHNldCBvZiBwcm9wZXJ0aWVzLCBpZS4gYEZhY2V0YHMuXG4gKiBUaGUgYEZhY2V0YCBjbGFzcyBkZWZpbmVzIHRoZSBwcm9wZXJ0eTogSXQgY2FuIGJlIGEgY29udGludW91cyB2YWx1ZSwgYSBzZXQgb2YgbGFiZWxzIG9yIHRhZ3MsXG4gKiBvciBpdCBjYW4gYmUgcmVzdWx0IG9mIHNvbWUgdHJhbnNmb3JtYXRpb24gb3IgZXF1YXRpb24uXG4gKlxuICogQGNsYXNzIEZhY2V0XG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBCYXNlTW9kZWwgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIENhdGVnb3JpYWxUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L2NhdGVnb3JpYWwtdHJhbnNmb3JtJyk7XG52YXIgQ29udGludW91c1RyYW5zZm9ybSA9IHJlcXVpcmUoJy4vZmFjZXQvY29udGludW91cy10cmFuc2Zvcm0nKTtcbnZhciBkYXRldGltZVRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vZmFjZXQvZGF0ZXRpbWUtdHJhbnNmb3JtJyk7XG52YXIgZHVyYXRpb25UcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L2R1cmF0aW9uLXRyYW5zZm9ybScpO1xudmFyIHRleHRUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL2ZhY2V0L3RleHQtdHJhbnNmb3JtJyk7XG52YXIgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50LXRpbWV6b25lJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLm9uKCdjaGFuZ2U6dHlwZScsIGZ1bmN0aW9uIChmYWNldCwgbmV3dmFsKSB7XG4gICAgICAvLyByZXNldCB0cmFuc2Zvcm1hdGlvbnMgb24gdHlwZSBjaGFuZ2VcbiAgICAgIHRoaXMuY29udGludW91c1RyYW5zZm9ybS5yZXNldCgpO1xuICAgICAgdGhpcy5jYXRlZ29yaWFsVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgICB0aGlzLmRhdGV0aW1lVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgICB0aGlzLmR1cmF0aW9uVHJhbnNmb3JtLnJlc2V0KCk7XG4gICAgfSk7XG4gIH0sXG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogU2hvdyBpbiBmYWNldCBsaXN0cyAodXNlZCBmb3IgaW50ZXJhY3RpdmUgc2VhcmNoaW5nIG9uIEZhY2V0cyBwYWdlKVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBzaG93OiBbJ2Jvb2xlYW4nLCBmYWxzZSwgdHJ1ZV0sXG5cbiAgICAvKipcbiAgICAgKiBTaG93IGZhY2V0IGJhciAob24gQW5hbHl6ZSBwYWdlKVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0FjdGl2ZTogWydib29sZWFuJywgZmFsc2UsIGZhbHNlXSxcblxuICAgIC8vIGdlbmVyYWwgZmFjZXQgcHJvcGVydGllc1xuICAgIC8qKlxuICAgICAqIERlc2NyaXB0aW9uIG9mIHRoaXMgZmFjZXQsIGZvciBkaXNwbGF5aW5nIHB1cnBvc2VzXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgZGVzY3JpcHRpb246IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgZmFjZXRzLCBpdHMgdW5pdHMgZm9yIGRpc3BsYXlpbmcgcHVycG9zZXNcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB1bml0czogWydzdHJpbmcnLCB0cnVlLCAnJ10sXG5cbiAgICAvKipcbiAgICAgKiBTaG9ydCBuYW1lIChodW1hbiByZWFkYWJsZSkgZm9yIHRoaXMgZmFjZXQsIG11c3QgYmUgdW5pcXVlLlxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG5hbWU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiB0aGlzIGZhY2V0OlxuICAgICAqICAqIGBjb25zdGFudGAgICAgICAgIEEgY29uc3RhbnQgdmFsdWUgb2YgXCIxXCIgZm9yIGFsbCBkYXRhIGl0ZW1zXG4gICAgICogICogYGNvbnRpbnVvdXNgICAgICAgVGhlIGZhY2V0IHRha2VzIG9uIHJlYWwgbnVtYmVyc1xuICAgICAqICAqIGBjYXRlZ29yaWFsYCAgICAgIFRoZSBmYWNldCBpcyBhIHN0cmluZywgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncyAoZm9yIGEgd2VsbCBkZWZpbmVkIHNldCBvZiBsYWJlbHMgYW5kIHRhZ3MpXG4gICAgICogICogYGRhdGV0aW1lYCAgICAgICAgVGhlIGZhY2V0IGlzIGEgZGF0ZXRpbWUgKHVzaW5nIG1vbWVudGpzLnR6KVxuICAgICAqICAqIGBkdXJhdGlvbmAgICAgICAgIFRoZSBmYWNldCBpcyBhIGR1cmF0aW9uICh1c2luZyBtb21lbnRqcy5kdXJhdGlvbilcbiAgICAgKiAgKiBgdGV4dGAgICAgICAgICAgICBGcmVlZm9ybSB0ZXh0LlxuICAgICAqIENoZWNrIGZvciBmYWNldCB0eXBlIHVzaW5nIGlzQ29uc3RhbnQsIGlzQ29udGludW91cywgaXNDYXRlZ29yaWFsLCBpc0RhdGV0aW1lLCBpc0R1cmF0aW9uLCBvciBpc1RleHQgIHByb3BlcnRpZXMuXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHlwZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICdjYXRlZ29yaWFsJyxcbiAgICAgIHZhbHVlczogWydjb25zdGFudCcsICdjb250aW51b3VzJywgJ2NhdGVnb3JpYWwnLCAnZGF0ZXRpbWUnLCAnZHVyYXRpb24nLCAndGV4dCddXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBhY2Nlc3NvciBmb3IgdGhpcyBmYWNldC5cbiAgICAgKiBGb3IgbmVzdGVkIHByb3BlcnRpZXMgdXNlIGRvdCBub3RhdGlvbjogRm9yIGEgZGF0YXNldCBgWyB7bmFtZToge2ZpcnN0OiBcIlNhbnRhXCIsIGxhc3Q6IFwiQ2xhdXNcIn19LCAuLi5dYFxuICAgICAqIHlvdSBjYW4gdXNlIGBuYW1lLmZpcnN0YCBhbmQgYG5hbWUubGFzdGAgdG8gZ2V0IFNhbnRhIGFuZCBDbGF1cywgcmVzcGVjdGl2ZWx5LlxuICAgICAqXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgYWNjZXNzb3I6IFsnc3RyaW5nJywgZmFsc2UsIG51bGxdLFxuXG4gICAgLyoqXG4gICAgICogTWlzc2luZyBvciBpbnZhbGlkIGRhdGEgaW5kaWNhdG9yOyBmb3IgbXVsdGlwbGUgdmFsdWVzLCB1c2UgYSBjb21tYSBzZXBhcmF0ZWQsIHF1b3RlZCBsaXN0XG4gICAgICogTnVtYmVycywgc3RyaW5ncywgYm9vbGVhbnMsIGFuZCB0aGUgc3BlY2lhbCB2YWx1ZSBudWxsIGFyZSBhbGxvd2VkLlxuICAgICAqIFVzZSBzaW5nbGUgb3IgZG91YmxlIHF1b3RlcyBmb3Igc3RyaW5ncyBcIm1pc3NpbmdcIi5cbiAgICAgKiBUaGUgcGFyc2VkIHZhbHVlcyBhcmUgYXZhaWxhYmxlIGluIHRoZSBtaXN2YWwgcHJvcGVydHkuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBtaXN2YWxBc1RleHQ6ICdzdHJpbmcnLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgb3IgZGF0ZXRpbWUgRmFjZXRzLCB0aGUgbWluaW11bSB2YWx1ZSBhcyB0ZXh0LlxuICAgICAqIFBhcnNlZCB2YWx1ZSBhdmFpbGFibGUgaW4gdGhlIGBtaW52YWxgIHByb3BlcnR5XG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgbWludmFsQXNUZXh0OiAnc3RyaW5nJyxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1heGltdW0gdmFsdWUgYXMgdGV4dC5cbiAgICAgKiBQYXJzZWQgdmFsdWUgYXZhaWxhYmxlIGluIHRoZSBgbWF4dmFsYCBwcm9wZXJ0eVxuICAgICAqIEBtZW1iZXJvZiEgRmFjZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG1heHZhbEFzVGV4dDogJ3N0cmluZydcbiAgfSxcbiAgY2hpbGRyZW46IHtcbiAgICAvKipcbiAgICAgKiBBIGNhdGVnb3JpYWwgdHJhbnNmb3JtYXRpb24gdG8gYXBwbHkgdG8gdGhlIGRhdGFcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge0NhdGVnb3JpYWxUcmFuc2Zvcm19XG4gICAgICovXG4gICAgY2F0ZWdvcmlhbFRyYW5zZm9ybTogQ2F0ZWdvcmlhbFRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGRhdGV0aW1lIHRyYW5zZm9ybWF0aW9uIHRvIGFwcGx5IHRvIHRoZSBkYXRhXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtkYXRlaW1lVHJhbnNmb3JtfVxuICAgICAqL1xuICAgIGRhdGV0aW1lVHJhbnNmb3JtOiBkYXRldGltZVRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGR1cmF0aW9uIHRyYW5zZm9ybWF0aW9uIHRvIGFwcGx5IHRvIHRoZSBkYXRhXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtkYXRlaW1lVHJhbnNmb3JtfVxuICAgICAqL1xuICAgIGR1cmF0aW9uVHJhbnNmb3JtOiBkdXJhdGlvblRyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIGNvbnRpbnVvdXMgdHJhbnNmb3JtYXRpb24gdG8gYXBwbHkgdG8gdGhlIGRhdGFcbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge0NvbnRpbnVvdXNUcmFuc2Zvcm19XG4gICAgICovXG4gICAgY29udGludW91c1RyYW5zZm9ybTogQ29udGludW91c1RyYW5zZm9ybSxcbiAgICAvKipcbiAgICAgKiBBIHRleHQgdHJhbnNmb3JtXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtUZXh0VHJhbnNmb3JtfVxuICAgICAqL1xuICAgIHRleHRUcmFuc2Zvcm06IHRleHRUcmFuc2Zvcm1cbiAgfSxcblxuICBkZXJpdmVkOiB7XG4gICAgLy8gcHJvcGVydGllcyBmb3I6IHR5cGVcbiAgICBpc0NvbnN0YW50OiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjb25zdGFudCc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0NvbnRpbnVvdXM6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2NvbnRpbnVvdXMnO1xuICAgICAgfVxuICAgIH0sXG4gICAgaXNDYXRlZ29yaWFsOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjYXRlZ29yaWFsJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzRGF0ZXRpbWU6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2RhdGV0aW1lJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzRHVyYXRpb246IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ2R1cmF0aW9uJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzVGV4dDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAndGV4dCc7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEFycmF5IG9mIG1pc3NpbmcgZGF0YSBpbmRpY2F0b3JzXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtPYmplY3RbXX1cbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKi9cbiAgICBtaXN2YWw6IHtcbiAgICAgIGRlcHM6IFsnbWlzdmFsQXNUZXh0J10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBQYXJzZSB0aGUgdGV4dCBjb250ZW50IGFzIGEgSlNPTiBhcnJheTpcbiAgICAgICAgLy8gIC0gc3RyaW5ncyBzaG91bGQgYmUgcXVvdGVkXG4gICAgICAgIC8vICAtIG51bWJlcnMgdW5xdW9hdGVkXG4gICAgICAgIC8vICAtIHNwZWNpYWwgbnVtYmVycyBub3QgYWxsb3dlZDogTmFOLCBJbmZpbml0eVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICh0aGlzLm1pc3ZhbEFzVGV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoJ1snICsgdGhpcy5taXN2YWxBc1RleHQgKyAnXScpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1pbmltdW0gdmFsdWUuXG4gICAgICogQG1lbWJlcm9mISBGYWNldFxuICAgICAqIEB0eXBlIHtudW1iZXJ8ZGF0ZXRpbWV9XG4gICAgICogQHJlYWRvbmx5XG4gICAgICovXG4gICAgbWludmFsOiB7XG4gICAgICBkZXBzOiBbJ21pbnZhbEFzVGV4dCcsICd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWluO1xuICAgICAgICBpZiAodGhpcy5pc0NvbnRpbnVvdXMpIHtcbiAgICAgICAgICBtaW4gPSBwYXJzZUZsb2F0KHRoaXMubWludmFsQXNUZXh0KTtcbiAgICAgICAgICBpZiAoaXNOYU4obWluKSkge1xuICAgICAgICAgICAgbWluID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0RhdGV0aW1lKSB7XG4gICAgICAgICAgbWluID0gbW9tZW50KHRoaXMubWludmFsQXNUZXh0LCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICAgIGlmICghbWluLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgbWluID0gbW9tZW50KCcyMDEwLTAxLTAxIDAwOjAwJywgbW9tZW50LklTT184NjAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0R1cmF0aW9uKSB7XG4gICAgICAgICAgbWluID0gbW9tZW50LmR1cmF0aW9uKHRoaXMubWludmFsQXNUZXh0KTtcbiAgICAgICAgICBpZiAoIW1vbWVudC5pc0R1cmF0aW9uKG1pbikpIHtcbiAgICAgICAgICAgIG1pbiA9IG1vbWVudC5kdXJhdGlvbigxLCAnc2Vjb25kcycpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWluO1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMgb3IgZGF0ZXRpbWUgRmFjZXRzLCB0aGUgbWF4aW11bSB2YWx1ZS5cbiAgICAgKiBAbWVtYmVyb2YhIEZhY2V0XG4gICAgICogQHR5cGUge251bWJlcnxkYXRldGltZX1cbiAgICAgKiBAcmVhZG9ubHlcbiAgICAgKi9cbiAgICBtYXh2YWw6IHtcbiAgICAgIGRlcHM6IFsnbWF4dmFsQXNUZXh0JywgJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXg7XG4gICAgICAgIGlmICh0aGlzLmlzQ29udGludW91cykge1xuICAgICAgICAgIG1heCA9IHBhcnNlRmxvYXQodGhpcy5tYXh2YWxBc1RleHQpO1xuICAgICAgICAgIGlmIChpc05hTihtYXgpKSB7XG4gICAgICAgICAgICBtYXggPSAxMDA7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEYXRldGltZSkge1xuICAgICAgICAgIG1heCA9IG1vbWVudCh0aGlzLm1heHZhbEFzVGV4dCwgbW9tZW50LklTT184NjAxKTtcbiAgICAgICAgICBpZiAoIW1heC5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIG1heCA9IG1vbWVudCgnMjAyMC0wMS0wMSAwMDowMCcsIG1vbWVudC5JU09fODYwMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEdXJhdGlvbikge1xuICAgICAgICAgIG1heCA9IG1vbWVudC5kdXJhdGlvbih0aGlzLm1heHZhbEFzVGV4dCk7XG4gICAgICAgICAgaWYgKCFtb21lbnQuaXNEdXJhdGlvbihtYXgpKSB7XG4gICAgICAgICAgICBtYXggPSBtb21lbnQuZHVyYXRpb24oMTAwLCAnc2Vjb25kcycpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWF4O1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgdHJhbnNmb3JtOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzQ29udGludW91cykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRpbnVvdXNUcmFuc2Zvcm07XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0NhdGVnb3JpYWwpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jYXRlZ29yaWFsVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEYXRldGltZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmRhdGV0aW1lVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNEdXJhdGlvbikge1xuICAgICAgICAgIHJldHVybiB0aGlzLmR1cmF0aW9uVHJhbnNmb3JtO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNUZXh0KSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudGV4dFRyYW5zZm9ybTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmVycm9yKCdJbnZhbGlkIGZhY2V0Jyk7XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfVxuICB9LFxuICAvKipcbiAgICogc2V0TWluTWF4IHNldHMgdGhlIHJhbmdlIG9mIGEgY29udGludW91cyBvciB0aW1lIGZhY2V0XG4gICAqIEZvciBmYWNldHMgaW4gYSBkYXRhdmlldywgdGhlIG1pbmltdW0gaXMganVzdCB0aGUgbWluaW11bSBvZiB0aGUgZmFjZXQgb3ZlciBhbGwgYWN0aXZlIGRhdGFzZXRzLFxuICAgKiBhbmQgdGhlIHNhbWUgZm9yIHRoZSBtYXhpbXVtLlxuICAgKiBGb3IgZmFjZXRzIGluIGEgZGF0c2V0LCB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIGlzIGluIHRoZSBkYXRhc2V0IGRyaXZlci5cbiAgICpcbiAgICogQG1lbWJlcm9mISBGYWNldFxuICAgKi9cbiAgc2V0TWluTWF4OiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIERhdGFzZXQgPSByZXF1aXJlKCcuL2RhdGFzZXQnKTtcbiAgICB2YXIgRGF0YXZpZXcgPSByZXF1aXJlKCcuL2RhdGF2aWV3Jyk7XG5cbiAgICB2YXIgYW5jZXN0b3IgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90O1xuXG4gICAgaWYgKGFuY2VzdG9yIGluc3RhbmNlb2YgRGF0YXZpZXcpIHtcbiAgICAgIC8vIEZhY2V0IC0+IEZhY2V0cyAtPiBEYXRhdmlldyAtPiBTcG90XG4gICAgICBzcG90ID0gdGhpcy5jb2xsZWN0aW9uLnBhcmVudC5wYXJlbnQ7XG4gICAgICBzcG90LnNldEZhY2V0TWluTWF4KHRoaXMpO1xuICAgIH0gZWxzZSBpZiAoYW5jZXN0b3IgaW5zdGFuY2VvZiBEYXRhc2V0KSB7XG4gICAgICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgICAgIHNwb3QgPSBhbmNlc3Rvci5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICAgIHNwb3QuZHJpdmVyLnNldE1pbk1heChhbmNlc3RvciwgdGhpcyk7XG4gICAgfVxuICB9LFxuICAvKipcbiAgICogc2V0Q2F0ZWdvcmllcyBmaW5kcyBmaW5kcyBhbGwgdmFsdWVzIG9uIGFuIG9yZGluYWwgKGNhdGVnb3JpYWwpIGF4aXNcbiAgICogVXBkYXRlcyB0aGUgY2F0ZWdvcmlhbFRyYW5zZm9ybSBvZiB0aGUgZmFjZXRcbiAgICogRm9yIGZhY2V0cyBpbiBhIGRhdGF2aWV3LCB0aGlzIGlzIHRoZSB1bmlvbiBvZiB0aGUgY2F0ZWdvcmllcyBvZiBmYWNldCBvdmVyIGFsbCBhY3RpdmUgZGF0YXNldHMuXG4gICAqIEZvciBmYWNldHMgaW4gYSBkYXRhc2V0LCB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIGlzIGluIHRoZSBkYXRhc2V0IGRyaXZlci5cbiAgICpcbiAgICogQG1lbWJlcm9mISBGYWNldFxuICAgKi9cbiAgc2V0Q2F0ZWdvcmllczogZnVuY3Rpb24gKCkge1xuICAgIHZhciBEYXRhc2V0ID0gcmVxdWlyZSgnLi9kYXRhc2V0Jyk7XG4gICAgdmFyIERhdGF2aWV3ID0gcmVxdWlyZSgnLi9kYXRhdmlldycpO1xuXG4gICAgdmFyIGFuY2VzdG9yID0gdGhpcy5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICB2YXIgc3BvdDtcblxuICAgIGlmIChhbmNlc3RvciBpbnN0YW5jZW9mIERhdGF2aWV3KSB7XG4gICAgICAvLyBGYWNldCAtPiBGYWNldHMgLT4gRGF0YXZpZXcgLT4gU3BvdFxuICAgICAgc3BvdCA9IHRoaXMuY29sbGVjdGlvbi5wYXJlbnQucGFyZW50O1xuICAgICAgc3BvdC5zZXRGYWNldENhdGVnb3JpZXModGhpcyk7XG4gICAgfSBlbHNlIGlmIChhbmNlc3RvciBpbnN0YW5jZW9mIERhdGFzZXQpIHtcbiAgICAgIC8vIEZhY2V0IC0+IEZhY2V0cyAtPiBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IFNwb3RcbiAgICAgIHNwb3QgPSBhbmNlc3Rvci5jb2xsZWN0aW9uLnBhcmVudDtcbiAgICAgIHNwb3QuZHJpdmVyLnNldENhdGVnb3JpZXMoYW5jZXN0b3IsIHRoaXMpO1xuICAgIH1cbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4d50\n")},5066:function(module,exports,__webpack_require__){eval("/**\n * A Dataview is a join of Datasets\n *\n * @class Dataview\n * @extends Base\n */\nvar Crossfilter = __webpack_require__(/*! crossfilter2 */ \"0352\"); // TODO: only for client side datasets\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Filters = __webpack_require__(/*! ./filter/collection */ \"7fa4\");\nvar Facets = __webpack_require__(/*! ./facet/collection */ \"51fb\");\n\nfunction getData () {\n  if (this.isPaused) {\n    return;\n  }\n  console.time('Get data');\n\n  var spot = this.parent;\n\n  return spot.driver.getData(this);\n}\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    /**\n     * Crossfilter instance, see [here](http://square.github.io/crossfilter/)\n     * used for client side data handling.\n     *\n     * @memberof! Dataset\n     */\n    this.crossfilter = new Crossfilter([]);\n    this.countGroup = this.crossfilter.groupAll().reduceCount();\n  },\n  props: {\n    /**\n     * Total number of datapoints in the current dataview\n     *\n     * @memberof! Dataview\n     * @readonly\n     * @type {number}\n     */\n    dataTotal: ['number', true, 0],\n    /**\n     * Number of datapoints that are currently selected\n     *\n     * @memberof! Dataview\n     * @readonly\n     * @type {number}\n     */\n    dataSelected: ['number', true, 0],\n    /**\n     * DatasetId's of active datasets\n     *\n     * @memberof! Dataview\n     * @type {String[]}\n     */\n    datasetIds: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    }\n  },\n  session: {\n    /**\n     * isPaused when true, calls to getAllData are ignored.\n     * This is useful to suppres calls to getData\n     * when adding and removing a number of filters at once.\n     * @memberof! Dataview\n     * @type {boolean}\n     */\n    isPaused: ['boolean', true, false]\n  },\n  collections: {\n    /**\n     * A Facet collection holding pre defined facets\n     *\n     * @memberof! Dataview\n     * @type {Facet[]}\n     */\n    facets: Facets,\n    /**\n     * A Filter collection holding all active filters on the dataview\n     *\n     * @memberof! Dataview\n     * @type {Filter[]}\n     */\n    filters: Filters\n  },\n  /**\n   * Pause the dataview. This means calls to getData are blocked.\n   * Useful when updating a lot of filters and you are not interested in the intermediate state.\n   *\n   * @memberof! Dataview\n   */\n  pause: function () {\n    this.isPaused = true;\n  },\n  /**\n   * Unpause the dataview.\n   *\n   * @memberof! Dataview\n   */\n  play: function () {\n    this.isPaused = false;\n  },\n\n  /**\n   * Get data for all filters linked to this dataview.\n   * When data has become available for a filter, a `newData` event is triggered on that filter.\n   *\n   * @memberof! Dataview\n   * @function\n   */\n  getData: getData\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTA2Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXZpZXcuanM/NGQ0YSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEEgRGF0YXZpZXcgaXMgYSBqb2luIG9mIERhdGFzZXRzXG4gKlxuICogQGNsYXNzIERhdGF2aWV3XG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBDcm9zc2ZpbHRlciA9IHJlcXVpcmUoJ2Nyb3NzZmlsdGVyMicpOyAvLyBUT0RPOiBvbmx5IGZvciBjbGllbnQgc2lkZSBkYXRhc2V0c1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG52YXIgRmlsdGVycyA9IHJlcXVpcmUoJy4vZmlsdGVyL2NvbGxlY3Rpb24nKTtcbnZhciBGYWNldHMgPSByZXF1aXJlKCcuL2ZhY2V0L2NvbGxlY3Rpb24nKTtcblxuZnVuY3Rpb24gZ2V0RGF0YSAoKSB7XG4gIGlmICh0aGlzLmlzUGF1c2VkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnNvbGUudGltZSgnR2V0IGRhdGEnKTtcblxuICB2YXIgc3BvdCA9IHRoaXMucGFyZW50O1xuXG4gIHJldHVybiBzcG90LmRyaXZlci5nZXREYXRhKHRoaXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VNb2RlbC5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gZmlyc3QgZG8gcGFyZW50IGNsYXNzIGluaXRpYWxpemF0aW9uXG4gICAgQmFzZU1vZGVsLnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICAvKipcbiAgICAgKiBDcm9zc2ZpbHRlciBpbnN0YW5jZSwgc2VlIFtoZXJlXShodHRwOi8vc3F1YXJlLmdpdGh1Yi5pby9jcm9zc2ZpbHRlci8pXG4gICAgICogdXNlZCBmb3IgY2xpZW50IHNpZGUgZGF0YSBoYW5kbGluZy5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqL1xuICAgIHRoaXMuY3Jvc3NmaWx0ZXIgPSBuZXcgQ3Jvc3NmaWx0ZXIoW10pO1xuICAgIHRoaXMuY291bnRHcm91cCA9IHRoaXMuY3Jvc3NmaWx0ZXIuZ3JvdXBBbGwoKS5yZWR1Y2VDb3VudCgpO1xuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRvdGFsIG51bWJlciBvZiBkYXRhcG9pbnRzIGluIHRoZSBjdXJyZW50IGRhdGF2aWV3XG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHJlYWRvbmx5XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBkYXRhVG90YWw6IFsnbnVtYmVyJywgdHJ1ZSwgMF0sXG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIGRhdGFwb2ludHMgdGhhdCBhcmUgY3VycmVudGx5IHNlbGVjdGVkXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHJlYWRvbmx5XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBkYXRhU2VsZWN0ZWQ6IFsnbnVtYmVyJywgdHJ1ZSwgMF0sXG4gICAgLyoqXG4gICAgICogRGF0YXNldElkJ3Mgb2YgYWN0aXZlIGRhdGFzZXRzXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge1N0cmluZ1tdfVxuICAgICAqL1xuICAgIGRhdGFzZXRJZHM6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBkZWZhdWx0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHNlc3Npb246IHtcbiAgICAvKipcbiAgICAgKiBpc1BhdXNlZCB3aGVuIHRydWUsIGNhbGxzIHRvIGdldEFsbERhdGEgYXJlIGlnbm9yZWQuXG4gICAgICogVGhpcyBpcyB1c2VmdWwgdG8gc3VwcHJlcyBjYWxscyB0byBnZXREYXRhXG4gICAgICogd2hlbiBhZGRpbmcgYW5kIHJlbW92aW5nIGEgbnVtYmVyIG9mIGZpbHRlcnMgYXQgb25jZS5cbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNQYXVzZWQ6IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXVxuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEEgRmFjZXQgY29sbGVjdGlvbiBob2xkaW5nIHByZSBkZWZpbmVkIGZhY2V0c1xuICAgICAqXG4gICAgICogQG1lbWJlcm9mISBEYXRhdmlld1xuICAgICAqIEB0eXBlIHtGYWNldFtdfVxuICAgICAqL1xuICAgIGZhY2V0czogRmFjZXRzLFxuICAgIC8qKlxuICAgICAqIEEgRmlsdGVyIGNvbGxlY3Rpb24gaG9sZGluZyBhbGwgYWN0aXZlIGZpbHRlcnMgb24gdGhlIGRhdGF2aWV3XG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGF2aWV3XG4gICAgICogQHR5cGUge0ZpbHRlcltdfVxuICAgICAqL1xuICAgIGZpbHRlcnM6IEZpbHRlcnNcbiAgfSxcbiAgLyoqXG4gICAqIFBhdXNlIHRoZSBkYXRhdmlldy4gVGhpcyBtZWFucyBjYWxscyB0byBnZXREYXRhIGFyZSBibG9ja2VkLlxuICAgKiBVc2VmdWwgd2hlbiB1cGRhdGluZyBhIGxvdCBvZiBmaWx0ZXJzIGFuZCB5b3UgYXJlIG5vdCBpbnRlcmVzdGVkIGluIHRoZSBpbnRlcm1lZGlhdGUgc3RhdGUuXG4gICAqXG4gICAqIEBtZW1iZXJvZiEgRGF0YXZpZXdcbiAgICovXG4gIHBhdXNlOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5pc1BhdXNlZCA9IHRydWU7XG4gIH0sXG4gIC8qKlxuICAgKiBVbnBhdXNlIHRoZSBkYXRhdmlldy5cbiAgICpcbiAgICogQG1lbWJlcm9mISBEYXRhdmlld1xuICAgKi9cbiAgcGxheTogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuaXNQYXVzZWQgPSBmYWxzZTtcbiAgfSxcblxuICAvKipcbiAgICogR2V0IGRhdGEgZm9yIGFsbCBmaWx0ZXJzIGxpbmtlZCB0byB0aGlzIGRhdGF2aWV3LlxuICAgKiBXaGVuIGRhdGEgaGFzIGJlY29tZSBhdmFpbGFibGUgZm9yIGEgZmlsdGVyLCBhIGBuZXdEYXRhYCBldmVudCBpcyB0cmlnZ2VyZWQgb24gdGhhdCBmaWx0ZXIuXG4gICAqXG4gICAqIEBtZW1iZXJvZiEgRGF0YXZpZXdcbiAgICogQGZ1bmN0aW9uXG4gICAqL1xuICBnZXREYXRhOiBnZXREYXRhXG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5066\n")},"51fb":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Facet = __webpack_require__(/*! ../facet */ \"4d50\");\n\nmodule.exports = Collection.extend({\n  model: Facet,\n  mainIndex: 'id',\n  indexes: ['name'],\n  session: {\n    needle: ['string', true, ''], // search string used on the Facet page\n    showSearch: ['boolean', true, false] // show/hide the search bar on the Facet page\n  },\n  comparator: function (left, right) {\n    return left.name.localeCompare(right.name);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTFmYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29sbGVjdGlvbi5qcz84ZWU5Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBDb2xsZWN0aW9uID0gcmVxdWlyZSgnYW1wZXJzYW5kLWNvbGxlY3Rpb24nKTtcbnZhciBGYWNldCA9IHJlcXVpcmUoJy4uL2ZhY2V0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogRmFjZXQsXG4gIG1haW5JbmRleDogJ2lkJyxcbiAgaW5kZXhlczogWyduYW1lJ10sXG4gIHNlc3Npb246IHtcbiAgICBuZWVkbGU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLCAvLyBzZWFyY2ggc3RyaW5nIHVzZWQgb24gdGhlIEZhY2V0IHBhZ2VcbiAgICBzaG93U2VhcmNoOiBbJ2Jvb2xlYW4nLCB0cnVlLCBmYWxzZV0gLy8gc2hvdy9oaWRlIHRoZSBzZWFyY2ggYmFyIG9uIHRoZSBGYWNldCBwYWdlXG4gIH0sXG4gIGNvbXBhcmF0b3I6IGZ1bmN0aW9uIChsZWZ0LCByaWdodCkge1xuICAgIHJldHVybiBsZWZ0Lm5hbWUubG9jYWxlQ29tcGFyZShyaWdodC5uYW1lKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///51fb\n")},"544d":function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Dataset = __webpack_require__(/*! ../dataset */ \"545a\");\n\nmodule.exports = Collection.extend({\n  mainIndex: 'id',\n  indexes: ['name'],\n  model: Dataset\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQ0ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXNldC9jb2xsZWN0aW9uLmpzPzkxZDkiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIENvbGxlY3Rpb24gPSByZXF1aXJlKCdhbXBlcnNhbmQtY29sbGVjdGlvbicpO1xudmFyIERhdGFzZXQgPSByZXF1aXJlKCcuLi9kYXRhc2V0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtYWluSW5kZXg6ICdpZCcsXG4gIGluZGV4ZXM6IFsnbmFtZSddLFxuICBtb2RlbDogRGF0YXNldFxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///544d\n")},"545a":function(module,exports,__webpack_require__){eval("/**\n * @class Dataset\n * @extends Base\n */\nvar Crossfilter = __webpack_require__(/*! crossfilter2 */ \"0352\"); // TODO: only for client side datasets\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Facets = __webpack_require__(/*! ./facet/collection */ \"51fb\");\n\nmodule.exports = BaseModel.extend({\n  initialize: function () {\n    // first do parent class initialization\n    BaseModel.prototype.initialize.apply(this, arguments);\n\n    /**\n     * Crossfilter instance, see [here](http://square.github.io/crossfilter/)\n     * used for client side data handling.\n     *\n     * @memberof! Dataset\n     */\n    this.crossfilter = new Crossfilter([]);\n    this.countGroup = this.crossfilter.groupAll().reduceCount();\n  },\n  props: {\n    /**\n     * Name of the dataset\n     * @memberof! Dataset\n     * @type {string}\n     */\n    name: {\n      type: 'string',\n      required: true,\n      default: 'Name'\n    },\n    /**\n     * URL, fi. to paper, dataset owner, etc.\n     * @memberof! Dataset\n     * @type {string}\n     */\n    URL: {\n      type: 'string',\n      required: true,\n      default: 'URL'\n    },\n    /**\n     * Database table name for server datasets\n     * @memberof! Dataset\n     * @type {string}\n     */\n    databaseTable: {\n      type: 'string',\n      default: ''\n    },\n    /**\n     * Short description of the dataset\n     * @memberof! Dataset\n     * @type {string}\n     */\n    description: {\n      type: 'string',\n      required: true,\n      default: 'Description'\n    },\n    /**\n     * If dataset is part of the current session\n     * @memberof! Dataset\n     * @type {boolean}\n     */\n    isActive: {\n      type: 'boolean',\n      required: true,\n      default: false\n    }\n  },\n  session: {\n    /**\n     * For searching through datasets URL and description.\n     * True if this dataset matches the search paramters.\n     */\n    show: {\n      type: 'boolean',\n      required: true,\n      default: true\n    },\n    data: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    }\n  },\n  collections: {\n    /**\n     * A Facet collection holding pre defined facets\n     * @memberof! Dataset\n     * @type {Facet[]}\n     */\n    facets: Facets\n  },\n  scan: function () {\n    // Dataset -> Datasets -> spot\n    var spot = this.collection.parent;\n\n    // clear all existing facets\n    this.facets.reset();\n\n    spot.driver.scan(this);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQ1YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZGF0YXNldC5qcz9lYTcwIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGNsYXNzIERhdGFzZXRcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xudmFyIENyb3NzZmlsdGVyID0gcmVxdWlyZSgnY3Jvc3NmaWx0ZXIyJyk7IC8vIFRPRE86IG9ubHkgZm9yIGNsaWVudCBzaWRlIGRhdGFzZXRzXG52YXIgQmFzZU1vZGVsID0gcmVxdWlyZSgnLi91dGlsL2Jhc2UnKTtcbnZhciBGYWNldHMgPSByZXF1aXJlKCcuL2ZhY2V0L2NvbGxlY3Rpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlTW9kZWwuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICAgIC8vIGZpcnN0IGRvIHBhcmVudCBjbGFzcyBpbml0aWFsaXphdGlvblxuICAgIEJhc2VNb2RlbC5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgLyoqXG4gICAgICogQ3Jvc3NmaWx0ZXIgaW5zdGFuY2UsIHNlZSBbaGVyZV0oaHR0cDovL3NxdWFyZS5naXRodWIuaW8vY3Jvc3NmaWx0ZXIvKVxuICAgICAqIHVzZWQgZm9yIGNsaWVudCBzaWRlIGRhdGEgaGFuZGxpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKi9cbiAgICB0aGlzLmNyb3NzZmlsdGVyID0gbmV3IENyb3NzZmlsdGVyKFtdKTtcbiAgICB0aGlzLmNvdW50R3JvdXAgPSB0aGlzLmNyb3NzZmlsdGVyLmdyb3VwQWxsKCkucmVkdWNlQ291bnQoKTtcbiAgfSxcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBOYW1lIG9mIHRoZSBkYXRhc2V0XG4gICAgICogQG1lbWJlcm9mISBEYXRhc2V0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBuYW1lOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ05hbWUnXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBVUkwsIGZpLiB0byBwYXBlciwgZGF0YXNldCBvd25lciwgZXRjLlxuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgVVJMOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ1VSTCdcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIERhdGFiYXNlIHRhYmxlIG5hbWUgZm9yIHNlcnZlciBkYXRhc2V0c1xuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgZGF0YWJhc2VUYWJsZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICBkZWZhdWx0OiAnJ1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogU2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIGRhdGFzZXRcbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRlc2NyaXB0aW9uOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ0Rlc2NyaXB0aW9uJ1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogSWYgZGF0YXNldCBpcyBwYXJ0IG9mIHRoZSBjdXJyZW50IHNlc3Npb25cbiAgICAgKiBAbWVtYmVyb2YhIERhdGFzZXRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc0FjdGl2ZToge1xuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiBmYWxzZVxuICAgIH1cbiAgfSxcbiAgc2Vzc2lvbjoge1xuICAgIC8qKlxuICAgICAqIEZvciBzZWFyY2hpbmcgdGhyb3VnaCBkYXRhc2V0cyBVUkwgYW5kIGRlc2NyaXB0aW9uLlxuICAgICAqIFRydWUgaWYgdGhpcyBkYXRhc2V0IG1hdGNoZXMgdGhlIHNlYXJjaCBwYXJhbXRlcnMuXG4gICAgICovXG4gICAgc2hvdzoge1xuICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiB0cnVlXG4gICAgfSxcbiAgICBkYXRhOiB7XG4gICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEEgRmFjZXQgY29sbGVjdGlvbiBob2xkaW5nIHByZSBkZWZpbmVkIGZhY2V0c1xuICAgICAqIEBtZW1iZXJvZiEgRGF0YXNldFxuICAgICAqIEB0eXBlIHtGYWNldFtdfVxuICAgICAqL1xuICAgIGZhY2V0czogRmFjZXRzXG4gIH0sXG4gIHNjYW46IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBEYXRhc2V0IC0+IERhdGFzZXRzIC0+IHNwb3RcbiAgICB2YXIgc3BvdCA9IHRoaXMuY29sbGVjdGlvbi5wYXJlbnQ7XG5cbiAgICAvLyBjbGVhciBhbGwgZXhpc3RpbmcgZmFjZXRzXG4gICAgdGhpcy5mYWNldHMucmVzZXQoKTtcblxuICAgIHNwb3QuZHJpdmVyLnNjYW4odGhpcyk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///545a\n")},"58ab":function(module,exports,__webpack_require__){eval('\nmodule.exports = __webpack_require__(/*! ./socket */ "0112");\n\n/**\n * Exports parser\n *\n * @api public\n *\n */\nmodule.exports.parser = __webpack_require__(/*! engine.io-parser */ "aa6c");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNThhYi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvaW5kZXguanM/ZWViYiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9zb2NrZXQnKTtcblxuLyoqXG4gKiBFeHBvcnRzIHBhcnNlclxuICpcbiAqIEBhcGkgcHVibGljXG4gKlxuICovXG5tb2R1bGUuZXhwb3J0cy5wYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///58ab\n')},"5a80":function(module,exports,__webpack_require__){eval("/**\n * ContinuousTransfrom defines a transformation on continuous (nummerical) data.\n * Currently linear interpolation between a set of control points is implemented.\n *\n * @class ContinuousTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nvar ControlPoint = __webpack_require__(/*! ./control-point */ \"09c5\");\nvar ControlPoints = Collection.extend({\n  model: ControlPoint\n});\n\n/**\n * Apply piecewise linear transformation\n * The function is constant outside the range spanned by the control points;\n * there it is set to value of the first, or the last, control points.\n *\n * @function\n * @memberof! ContinuousTransform\n * @param {number} x\n * @returns {number} fx\n */\nfunction transform (cps, x) {\n  if (x === misval) {\n    return misval;\n  }\n\n  var ncps = cps.models.length;\n  if (x <= cps.models[0].x) {\n    // outside range on left side\n    return cps.models[0].fx;\n  } else if (x >= cps.models[ncps - 1].x) {\n    // outside range on right side\n    return cps.models[ncps - 1].fx;\n  } else {\n    // inside range\n    var i = 0;\n    while (x > cps.models[i].x) {\n      i = i + 1;\n    }\n\n    // linear interpolate between fx_i and fx_(i+1)\n    var xm = cps.models[i].x;\n    var xp = cps.models[i + 1].x;\n    var fxm = cps.models[i].fx;\n    var fxp = cps.models[i + 1].fx;\n    if (xp === xm) {\n      return 0.5 * (fxm + fxp);\n    } else {\n      return fxm + (x - xm) * (fxp - fxm) / (xp - xm);\n    }\n  }\n}\n\n/**\n * The inverse of the transform\n *\n * @function\n * @memberof! ContinuousTransform\n * @param {number} fx\n * @returns {number} x\n */\nfunction inverse (cps, fx) {\n  if (fx === misval) {\n    return misval;\n  }\n\n  var ncps = cps.models.length;\n  if (fx <= cps.models[0].fx) {\n    // outside range on left side\n    return cps.models[0].x;\n  } else if (fx >= cps.models[ncps - 1].fx) {\n    // outside range on right side\n    return cps.models[ncps - 1].x;\n  } else {\n    // inside range\n    var i = 0;\n    while (fx > cps.models[i].fx) {\n      i = i + 1;\n    }\n\n    // linear interpolate between fx_i and fx_(i+1)\n    var xm = cps.models[i].x;\n    var xp = cps.models[i + 1].x;\n    var fxm = cps.models[i].fx;\n    var fxp = cps.models[i + 1].fx;\n    if (fxp === fxm) {\n      return 0.5 * (xm + xp);\n    } else {\n      return xm + (fx - fxm) * (xp - xm) / (fxp - fxm);\n    }\n  }\n}\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * The type of continuous transform, can be none, or percentiles\n     * Use isNone, or isPercentiles, check for transform type\n     * @memberof! ContinuousTransform\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'none',\n      values: ['none', 'percentiles']\n    },\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'continuous',\n      values: ['continuous']\n    }\n  },\n  derived: {\n    isNone: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'none';\n      }\n    },\n    isPercentiles: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'percentiles';\n      }\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! ContinuousTransform\n     */\n    transformedMin: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isPercentiles) {\n          return 0;\n        } else if (this.isNone) {\n          return this.parent.minval;\n        } else {\n          console.error('Invalid continuous transform');\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! ContinuousTransform\n     */\n    transformedMax: {\n      deps: ['type'],\n      fn: function () {\n        if (this.isPercentiles) {\n          return 100;\n        } else if (this.isNone) {\n          return this.parent.maxval;\n        } else {\n          console.error('Invalid continuous transform');\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! ContinuousTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! ContinuousTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n  collections: {\n    cps: ControlPoints\n  },\n  transform: function (x) {\n    return transform(this.cps, x);\n  },\n  inverse: function (fx) {\n    return inverse(this.cps, fx);\n  },\n  reset: function () {\n    this.type = 'none';\n    this.cps.reset();\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNWE4MC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY29udGludW91cy10cmFuc2Zvcm0uanM/YzgwOSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbnRpbnVvdXNUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNvbnRpbnVvdXMgKG51bW1lcmljYWwpIGRhdGEuXG4gKiBDdXJyZW50bHkgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiBhIHNldCBvZiBjb250cm9sIHBvaW50cyBpcyBpbXBsZW1lbnRlZC5cbiAqXG4gKiBAY2xhc3MgQ29udGludW91c1RyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBDb2xsZWN0aW9uID0gcmVxdWlyZSgnYW1wZXJzYW5kLWNvbGxlY3Rpb24nKTtcbnZhciBtaXN2YWwgPSByZXF1aXJlKCcuLi91dGlsL21pc3ZhbCcpO1xuXG52YXIgQ29udHJvbFBvaW50ID0gcmVxdWlyZSgnLi9jb250cm9sLXBvaW50Jyk7XG52YXIgQ29udHJvbFBvaW50cyA9IENvbGxlY3Rpb24uZXh0ZW5kKHtcbiAgbW9kZWw6IENvbnRyb2xQb2ludFxufSk7XG5cbi8qKlxuICogQXBwbHkgcGllY2V3aXNlIGxpbmVhciB0cmFuc2Zvcm1hdGlvblxuICogVGhlIGZ1bmN0aW9uIGlzIGNvbnN0YW50IG91dHNpZGUgdGhlIHJhbmdlIHNwYW5uZWQgYnkgdGhlIGNvbnRyb2wgcG9pbnRzO1xuICogdGhlcmUgaXQgaXMgc2V0IHRvIHZhbHVlIG9mIHRoZSBmaXJzdCwgb3IgdGhlIGxhc3QsIGNvbnRyb2wgcG9pbnRzLlxuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mISBDb250aW51b3VzVHJhbnNmb3JtXG4gKiBAcGFyYW0ge251bWJlcn0geFxuICogQHJldHVybnMge251bWJlcn0gZnhcbiAqL1xuZnVuY3Rpb24gdHJhbnNmb3JtIChjcHMsIHgpIHtcbiAgaWYgKHggPT09IG1pc3ZhbCkge1xuICAgIHJldHVybiBtaXN2YWw7XG4gIH1cblxuICB2YXIgbmNwcyA9IGNwcy5tb2RlbHMubGVuZ3RoO1xuICBpZiAoeCA8PSBjcHMubW9kZWxzWzBdLngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIGxlZnQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzWzBdLmZ4O1xuICB9IGVsc2UgaWYgKHggPj0gY3BzLm1vZGVsc1tuY3BzIC0gMV0ueCkge1xuICAgIC8vIG91dHNpZGUgcmFuZ2Ugb24gcmlnaHQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzW25jcHMgLSAxXS5meDtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbnNpZGUgcmFuZ2VcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKHggPiBjcHMubW9kZWxzW2ldLngpIHtcbiAgICAgIGkgPSBpICsgMTtcbiAgICB9XG5cbiAgICAvLyBsaW5lYXIgaW50ZXJwb2xhdGUgYmV0d2VlbiBmeF9pIGFuZCBmeF8oaSsxKVxuICAgIHZhciB4bSA9IGNwcy5tb2RlbHNbaV0ueDtcbiAgICB2YXIgeHAgPSBjcHMubW9kZWxzW2kgKyAxXS54O1xuICAgIHZhciBmeG0gPSBjcHMubW9kZWxzW2ldLmZ4O1xuICAgIHZhciBmeHAgPSBjcHMubW9kZWxzW2kgKyAxXS5meDtcbiAgICBpZiAoeHAgPT09IHhtKSB7XG4gICAgICByZXR1cm4gMC41ICogKGZ4bSArIGZ4cCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmeG0gKyAoeCAtIHhtKSAqIChmeHAgLSBmeG0pIC8gKHhwIC0geG0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoZSBpbnZlcnNlIG9mIHRoZSB0cmFuc2Zvcm1cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICogQHBhcmFtIHtudW1iZXJ9IGZ4XG4gKiBAcmV0dXJucyB7bnVtYmVyfSB4XG4gKi9cbmZ1bmN0aW9uIGludmVyc2UgKGNwcywgZngpIHtcbiAgaWYgKGZ4ID09PSBtaXN2YWwpIHtcbiAgICByZXR1cm4gbWlzdmFsO1xuICB9XG5cbiAgdmFyIG5jcHMgPSBjcHMubW9kZWxzLmxlbmd0aDtcbiAgaWYgKGZ4IDw9IGNwcy5tb2RlbHNbMF0uZngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIGxlZnQgc2lkZVxuICAgIHJldHVybiBjcHMubW9kZWxzWzBdLng7XG4gIH0gZWxzZSBpZiAoZnggPj0gY3BzLm1vZGVsc1tuY3BzIC0gMV0uZngpIHtcbiAgICAvLyBvdXRzaWRlIHJhbmdlIG9uIHJpZ2h0IHNpZGVcbiAgICByZXR1cm4gY3BzLm1vZGVsc1tuY3BzIC0gMV0ueDtcbiAgfSBlbHNlIHtcbiAgICAvLyBpbnNpZGUgcmFuZ2VcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKGZ4ID4gY3BzLm1vZGVsc1tpXS5meCkge1xuICAgICAgaSA9IGkgKyAxO1xuICAgIH1cblxuICAgIC8vIGxpbmVhciBpbnRlcnBvbGF0ZSBiZXR3ZWVuIGZ4X2kgYW5kIGZ4XyhpKzEpXG4gICAgdmFyIHhtID0gY3BzLm1vZGVsc1tpXS54O1xuICAgIHZhciB4cCA9IGNwcy5tb2RlbHNbaSArIDFdLng7XG4gICAgdmFyIGZ4bSA9IGNwcy5tb2RlbHNbaV0uZng7XG4gICAgdmFyIGZ4cCA9IGNwcy5tb2RlbHNbaSArIDFdLmZ4O1xuICAgIGlmIChmeHAgPT09IGZ4bSkge1xuICAgICAgcmV0dXJuIDAuNSAqICh4bSArIHhwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHhtICsgKGZ4IC0gZnhtKSAqICh4cCAtIHhtKSAvIChmeHAgLSBmeG0pO1xuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEFtcGVyc2FuZE1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgY29udGludW91cyB0cmFuc2Zvcm0sIGNhbiBiZSBub25lLCBvciBwZXJjZW50aWxlc1xuICAgICAqIFVzZSBpc05vbmUsIG9yIGlzUGVyY2VudGlsZXMsIGNoZWNrIGZvciB0cmFuc2Zvcm0gdHlwZVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnbm9uZScsXG4gICAgICB2YWx1ZXM6IFsnbm9uZScsICdwZXJjZW50aWxlcyddXG4gICAgfSxcbiAgICB0cmFuc2Zvcm1lZFR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnY29udGludW91cycsXG4gICAgICB2YWx1ZXM6IFsnY29udGludW91cyddXG4gICAgfVxuICB9LFxuICBkZXJpdmVkOiB7XG4gICAgaXNOb25lOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdub25lJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzUGVyY2VudGlsZXM6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ3BlcmNlbnRpbGVzJztcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1pbjoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5pc1BlcmNlbnRpbGVzKSB7XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc05vbmUpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQubWludmFsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgY29udGludW91cyB0cmFuc2Zvcm0nKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWF4OiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUGVyY2VudGlsZXMpIHtcbiAgICAgICAgICByZXR1cm4gMTAwO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaXNOb25lKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50Lm1heHZhbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdJbnZhbGlkIGNvbnRpbnVvdXMgdHJhbnNmb3JtJyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqIEBtZW1iZXJvZiEgQ29udGludW91c1RyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkTWluJywgJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1pbnZhbCA9IHRoaXMudHJhbnNmb3JtZWRNaW47XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiBtaW52YWwuZm9ybWF0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIENvbnRpbnVvdXNUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1heEFzVGV4dDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZE1heCcsICd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXh2YWwgPSB0aGlzLnRyYW5zZm9ybWVkTWF4O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLmZvcm1hdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH1cbiAgfSxcbiAgY29sbGVjdGlvbnM6IHtcbiAgICBjcHM6IENvbnRyb2xQb2ludHNcbiAgfSxcbiAgdHJhbnNmb3JtOiBmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiB0cmFuc2Zvcm0odGhpcy5jcHMsIHgpO1xuICB9LFxuICBpbnZlcnNlOiBmdW5jdGlvbiAoZngpIHtcbiAgICByZXR1cm4gaW52ZXJzZSh0aGlzLmNwcywgZngpO1xuICB9LFxuICByZXNldDogZnVuY3Rpb24gKCkge1xuICAgIHRoaXMudHlwZSA9ICdub25lJztcbiAgICB0aGlzLmNwcy5yZXNldCgpO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5a80\n")},6176:function(module,exports){eval("module.exports = Array.isArray || function (arr) {\n  return Object.prototype.toString.call(arr) == '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjE3Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcz8xYjA4Il0sInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6176\n")},"636d":function(module,exports){eval("\n/**\n * Expose `Emitter`.\n */\n\nmodule.exports = Emitter;\n\n/**\n * Initialize a new `Emitter`.\n *\n * @api public\n */\n\nfunction Emitter(obj) {\n  if (obj) return mixin(obj);\n};\n\n/**\n * Mixin the emitter properties.\n *\n * @param {Object} obj\n * @return {Object}\n * @api private\n */\n\nfunction mixin(obj) {\n  for (var key in Emitter.prototype) {\n    obj[key] = Emitter.prototype[key];\n  }\n  return obj;\n}\n\n/**\n * Listen on the given `event` with `fn`.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.on =\nEmitter.prototype.addEventListener = function(event, fn){\n  this._callbacks = this._callbacks || {};\n  (this._callbacks[event] = this._callbacks[event] || [])\n    .push(fn);\n  return this;\n};\n\n/**\n * Adds an `event` listener that will be invoked a single\n * time then automatically removed.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.once = function(event, fn){\n  var self = this;\n  this._callbacks = this._callbacks || {};\n\n  function on() {\n    self.off(event, on);\n    fn.apply(this, arguments);\n  }\n\n  on.fn = fn;\n  this.on(event, on);\n  return this;\n};\n\n/**\n * Remove the given callback for `event` or all\n * registered callbacks.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\nEmitter.prototype.off =\nEmitter.prototype.removeListener =\nEmitter.prototype.removeAllListeners =\nEmitter.prototype.removeEventListener = function(event, fn){\n  this._callbacks = this._callbacks || {};\n\n  // all\n  if (0 == arguments.length) {\n    this._callbacks = {};\n    return this;\n  }\n\n  // specific event\n  var callbacks = this._callbacks[event];\n  if (!callbacks) return this;\n\n  // remove all handlers\n  if (1 == arguments.length) {\n    delete this._callbacks[event];\n    return this;\n  }\n\n  // remove specific handler\n  var cb;\n  for (var i = 0; i < callbacks.length; i++) {\n    cb = callbacks[i];\n    if (cb === fn || cb.fn === fn) {\n      callbacks.splice(i, 1);\n      break;\n    }\n  }\n  return this;\n};\n\n/**\n * Emit `event` with the given args.\n *\n * @param {String} event\n * @param {Mixed} ...\n * @return {Emitter}\n */\n\nEmitter.prototype.emit = function(event){\n  this._callbacks = this._callbacks || {};\n  var args = [].slice.call(arguments, 1)\n    , callbacks = this._callbacks[event];\n\n  if (callbacks) {\n    callbacks = callbacks.slice(0);\n    for (var i = 0, len = callbacks.length; i < len; ++i) {\n      callbacks[i].apply(this, args);\n    }\n  }\n\n  return this;\n};\n\n/**\n * Return array of callbacks for `event`.\n *\n * @param {String} event\n * @return {Array}\n * @api public\n */\n\nEmitter.prototype.listeners = function(event){\n  this._callbacks = this._callbacks || {};\n  return this._callbacks[event] || [];\n};\n\n/**\n * Check if this emitter has `event` handlers.\n *\n * @param {String} event\n * @return {Boolean}\n * @api public\n */\n\nEmitter.prototype.hasListeners = function(event){\n  return !! this.listeners(event).length;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjM2ZC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanM/ZWVlMiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogRXhwb3NlIGBFbWl0dGVyYC5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVtaXR0ZXI7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgRW1pdHRlcmAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBFbWl0dGVyKG9iaikge1xuICBpZiAob2JqKSByZXR1cm4gbWl4aW4ob2JqKTtcbn07XG5cbi8qKlxuICogTWl4aW4gdGhlIGVtaXR0ZXIgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBtaXhpbihvYmopIHtcbiAgZm9yICh2YXIga2V5IGluIEVtaXR0ZXIucHJvdG90eXBlKSB7XG4gICAgb2JqW2tleV0gPSBFbWl0dGVyLnByb3RvdHlwZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbiA9XG5FbWl0dGVyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICAodGhpcy5fY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuX2NhbGxiYWNrc1tldmVudF0gfHwgW10pXG4gICAgLnB1c2goZm4pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXG4gKiB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICBmdW5jdGlvbiBvbigpIHtcbiAgICBzZWxmLm9mZihldmVudCwgb24pO1xuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBvbi5mbiA9IGZuO1xuICB0aGlzLm9uKGV2ZW50LCBvbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICogcmVnaXN0ZXJlZCBjYWxsYmFja3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub2ZmID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuXG4gIC8vIGFsbFxuICBpZiAoMCA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgdGhpcy5fY2FsbGJhY2tzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzcGVjaWZpYyBldmVudFxuICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcbiAgaWYgKCFjYWxsYmFja3MpIHJldHVybiB0aGlzO1xuXG4gIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcbiAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcbiAgdmFyIGNiO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgIGNiID0gY2FsbGJhY2tzW2ldO1xuICAgIGlmIChjYiA9PT0gZm4gfHwgY2IuZm4gPT09IGZuKSB7XG4gICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7TWl4ZWR9IC4uLlxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oZXZlbnQpe1xuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG4gIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpXG4gICAgLCBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuXG4gIGlmIChjYWxsYmFja3MpIHtcbiAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgY2FsbGJhY2tzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYXJyYXkgb2YgY2FsbGJhY2tzIGZvciBgZXZlbnRgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7QXJyYXl9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XSB8fCBbXTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhpcyBlbWl0dGVyIGhhcyBgZXZlbnRgIGhhbmRsZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuaGFzTGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xuICByZXR1cm4gISEgdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///636d\n")},"6b20":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar Transport = __webpack_require__(/*! ../transport */ \"0d97\");\nvar parser = __webpack_require__(/*! engine.io-parser */ \"aa6c\");\nvar parseqs = __webpack_require__(/*! parseqs */ \"914f\");\nvar inherit = __webpack_require__(/*! component-inherit */ \"42bf\");\nvar yeast = __webpack_require__(/*! yeast */ \"c16d\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('engine.io-client:websocket');\nvar BrowserWebSocket = global.WebSocket || global.MozWebSocket;\nvar NodeWebSocket;\nif (typeof window === 'undefined') {\n  try {\n    NodeWebSocket = __webpack_require__(/*! ws */ 1);\n  } catch (e) { }\n}\n\n/**\n * Get either the `WebSocket` or `MozWebSocket` globals\n * in the browser or try to resolve WebSocket-compatible\n * interface exposed by `ws` for Node-like environment.\n */\n\nvar WebSocket = BrowserWebSocket;\nif (!WebSocket && typeof window === 'undefined') {\n  WebSocket = NodeWebSocket;\n}\n\n/**\n * Module exports.\n */\n\nmodule.exports = WS;\n\n/**\n * WebSocket transport constructor.\n *\n * @api {Object} connection options\n * @api public\n */\n\nfunction WS (opts) {\n  var forceBase64 = (opts && opts.forceBase64);\n  if (forceBase64) {\n    this.supportsBinary = false;\n  }\n  this.perMessageDeflate = opts.perMessageDeflate;\n  this.usingBrowserWebSocket = BrowserWebSocket && !opts.forceNode;\n  if (!this.usingBrowserWebSocket) {\n    WebSocket = NodeWebSocket;\n  }\n  Transport.call(this, opts);\n}\n\n/**\n * Inherits from Transport.\n */\n\ninherit(WS, Transport);\n\n/**\n * Transport name.\n *\n * @api public\n */\n\nWS.prototype.name = 'websocket';\n\n/*\n * WebSockets support binary\n */\n\nWS.prototype.supportsBinary = true;\n\n/**\n * Opens socket.\n *\n * @api private\n */\n\nWS.prototype.doOpen = function () {\n  if (!this.check()) {\n    // let probe timeout\n    return;\n  }\n\n  var uri = this.uri();\n  var protocols = void (0);\n  var opts = {\n    agent: this.agent,\n    perMessageDeflate: this.perMessageDeflate\n  };\n\n  // SSL options for Node.js client\n  opts.pfx = this.pfx;\n  opts.key = this.key;\n  opts.passphrase = this.passphrase;\n  opts.cert = this.cert;\n  opts.ca = this.ca;\n  opts.ciphers = this.ciphers;\n  opts.rejectUnauthorized = this.rejectUnauthorized;\n  if (this.extraHeaders) {\n    opts.headers = this.extraHeaders;\n  }\n  if (this.localAddress) {\n    opts.localAddress = this.localAddress;\n  }\n\n  try {\n    this.ws = this.usingBrowserWebSocket ? new WebSocket(uri) : new WebSocket(uri, protocols, opts);\n  } catch (err) {\n    return this.emit('error', err);\n  }\n\n  if (this.ws.binaryType === undefined) {\n    this.supportsBinary = false;\n  }\n\n  if (this.ws.supports && this.ws.supports.binary) {\n    this.supportsBinary = true;\n    this.ws.binaryType = 'nodebuffer';\n  } else {\n    this.ws.binaryType = 'arraybuffer';\n  }\n\n  this.addEventListeners();\n};\n\n/**\n * Adds event listeners to the socket\n *\n * @api private\n */\n\nWS.prototype.addEventListeners = function () {\n  var self = this;\n\n  this.ws.onopen = function () {\n    self.onOpen();\n  };\n  this.ws.onclose = function () {\n    self.onClose();\n  };\n  this.ws.onmessage = function (ev) {\n    self.onData(ev.data);\n  };\n  this.ws.onerror = function (e) {\n    self.onError('websocket error', e);\n  };\n};\n\n/**\n * Writes data to socket.\n *\n * @param {Array} array of packets.\n * @api private\n */\n\nWS.prototype.write = function (packets) {\n  var self = this;\n  this.writable = false;\n\n  // encodePacket efficient as it uses WS framing\n  // no need for encodePayload\n  var total = packets.length;\n  for (var i = 0, l = total; i < l; i++) {\n    (function (packet) {\n      parser.encodePacket(packet, self.supportsBinary, function (data) {\n        if (!self.usingBrowserWebSocket) {\n          // always create a new object (GH-437)\n          var opts = {};\n          if (packet.options) {\n            opts.compress = packet.options.compress;\n          }\n\n          if (self.perMessageDeflate) {\n            var len = 'string' === typeof data ? global.Buffer.byteLength(data) : data.length;\n            if (len < self.perMessageDeflate.threshold) {\n              opts.compress = false;\n            }\n          }\n        }\n\n        // Sometimes the websocket has already been closed but the browser didn't\n        // have a chance of informing us about it yet, in that case send will\n        // throw an error\n        try {\n          if (self.usingBrowserWebSocket) {\n            // TypeError is thrown when passing the second argument on Safari\n            self.ws.send(data);\n          } else {\n            self.ws.send(data, opts);\n          }\n        } catch (e) {\n          debug('websocket closed before onclose event');\n        }\n\n        --total || done();\n      });\n    })(packets[i]);\n  }\n\n  function done () {\n    self.emit('flush');\n\n    // fake drain\n    // defer to next tick to allow Socket to clear writeBuffer\n    setTimeout(function () {\n      self.writable = true;\n      self.emit('drain');\n    }, 0);\n  }\n};\n\n/**\n * Called upon close\n *\n * @api private\n */\n\nWS.prototype.onClose = function () {\n  Transport.prototype.onClose.call(this);\n};\n\n/**\n * Closes socket.\n *\n * @api private\n */\n\nWS.prototype.doClose = function () {\n  if (typeof this.ws !== 'undefined') {\n    this.ws.close();\n  }\n};\n\n/**\n * Generates uri for connection.\n *\n * @api private\n */\n\nWS.prototype.uri = function () {\n  var query = this.query || {};\n  var schema = this.secure ? 'wss' : 'ws';\n  var port = '';\n\n  // avoid port if default for schema\n  if (this.port && (('wss' === schema && Number(this.port) !== 443) ||\n    ('ws' === schema && Number(this.port) !== 80))) {\n    port = ':' + this.port;\n  }\n\n  // append timestamp to URI\n  if (this.timestampRequests) {\n    query[this.timestampParam] = yeast();\n  }\n\n  // communicate binary support capabilities\n  if (!this.supportsBinary) {\n    query.b64 = 1;\n  }\n\n  query = parseqs.encode(query);\n\n  // prepend ? to query\n  if (query.length) {\n    query = '?' + query;\n  }\n\n  var ipv6 = this.hostname.indexOf(':') !== -1;\n  return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;\n};\n\n/**\n * Feature detection for WebSocket.\n *\n * @return {Boolean} whether this transport is available.\n * @api public\n */\n\nWS.prototype.check = function () {\n  return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNmIyMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy93ZWJzb2NrZXQuanM/ZGI4MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIFRyYW5zcG9ydCA9IHJlcXVpcmUoJy4uL3RyYW5zcG9ydCcpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBwYXJzZXFzID0gcmVxdWlyZSgncGFyc2VxcycpO1xudmFyIGluaGVyaXQgPSByZXF1aXJlKCdjb21wb25lbnQtaW5oZXJpdCcpO1xudmFyIHllYXN0ID0gcmVxdWlyZSgneWVhc3QnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ2VuZ2luZS5pby1jbGllbnQ6d2Vic29ja2V0Jyk7XG52YXIgQnJvd3NlcldlYlNvY2tldCA9IGdsb2JhbC5XZWJTb2NrZXQgfHwgZ2xvYmFsLk1veldlYlNvY2tldDtcbnZhciBOb2RlV2ViU29ja2V0O1xuaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gIHRyeSB7XG4gICAgTm9kZVdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG4gIH0gY2F0Y2ggKGUpIHsgfVxufVxuXG4vKipcbiAqIEdldCBlaXRoZXIgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyIG9yIHRyeSB0byByZXNvbHZlIFdlYlNvY2tldC1jb21wYXRpYmxlXG4gKiBpbnRlcmZhY2UgZXhwb3NlZCBieSBgd3NgIGZvciBOb2RlLWxpa2UgZW52aXJvbm1lbnQuXG4gKi9cblxudmFyIFdlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQ7XG5pZiAoIVdlYlNvY2tldCAmJiB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICBXZWJTb2NrZXQgPSBOb2RlV2ViU29ja2V0O1xufVxuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gV1M7XG5cbi8qKlxuICogV2ViU29ja2V0IHRyYW5zcG9ydCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHtPYmplY3R9IGNvbm5lY3Rpb24gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBXUyAob3B0cykge1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIHRoaXMucGVyTWVzc2FnZURlZmxhdGUgPSBvcHRzLnBlck1lc3NhZ2VEZWZsYXRlO1xuICB0aGlzLnVzaW5nQnJvd3NlcldlYlNvY2tldCA9IEJyb3dzZXJXZWJTb2NrZXQgJiYgIW9wdHMuZm9yY2VOb2RlO1xuICBpZiAoIXRoaXMudXNpbmdCcm93c2VyV2ViU29ja2V0KSB7XG4gICAgV2ViU29ja2V0ID0gTm9kZVdlYlNvY2tldDtcbiAgfVxuICBUcmFuc3BvcnQuY2FsbCh0aGlzLCBvcHRzKTtcbn1cblxuLyoqXG4gKiBJbmhlcml0cyBmcm9tIFRyYW5zcG9ydC5cbiAqL1xuXG5pbmhlcml0KFdTLCBUcmFuc3BvcnQpO1xuXG4vKipcbiAqIFRyYW5zcG9ydCBuYW1lLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuV1MucHJvdG90eXBlLm5hbWUgPSAnd2Vic29ja2V0JztcblxuLypcbiAqIFdlYlNvY2tldHMgc3VwcG9ydCBiaW5hcnlcbiAqL1xuXG5XUy5wcm90b3R5cGUuc3VwcG9ydHNCaW5hcnkgPSB0cnVlO1xuXG4vKipcbiAqIE9wZW5zIHNvY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5XUy5wcm90b3R5cGUuZG9PcGVuID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuY2hlY2soKSkge1xuICAgIC8vIGxldCBwcm9iZSB0aW1lb3V0XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHVyaSA9IHRoaXMudXJpKCk7XG4gIHZhciBwcm90b2NvbHMgPSB2b2lkICgwKTtcbiAgdmFyIG9wdHMgPSB7XG4gICAgYWdlbnQ6IHRoaXMuYWdlbnQsXG4gICAgcGVyTWVzc2FnZURlZmxhdGU6IHRoaXMucGVyTWVzc2FnZURlZmxhdGVcbiAgfTtcblxuICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgb3B0cy5wZnggPSB0aGlzLnBmeDtcbiAgb3B0cy5rZXkgPSB0aGlzLmtleTtcbiAgb3B0cy5wYXNzcGhyYXNlID0gdGhpcy5wYXNzcGhyYXNlO1xuICBvcHRzLmNlcnQgPSB0aGlzLmNlcnQ7XG4gIG9wdHMuY2EgPSB0aGlzLmNhO1xuICBvcHRzLmNpcGhlcnMgPSB0aGlzLmNpcGhlcnM7XG4gIG9wdHMucmVqZWN0VW5hdXRob3JpemVkID0gdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQ7XG4gIGlmICh0aGlzLmV4dHJhSGVhZGVycykge1xuICAgIG9wdHMuaGVhZGVycyA9IHRoaXMuZXh0cmFIZWFkZXJzO1xuICB9XG4gIGlmICh0aGlzLmxvY2FsQWRkcmVzcykge1xuICAgIG9wdHMubG9jYWxBZGRyZXNzID0gdGhpcy5sb2NhbEFkZHJlc3M7XG4gIH1cblxuICB0cnkge1xuICAgIHRoaXMud3MgPSB0aGlzLnVzaW5nQnJvd3NlcldlYlNvY2tldCA/IG5ldyBXZWJTb2NrZXQodXJpKSA6IG5ldyBXZWJTb2NrZXQodXJpLCBwcm90b2NvbHMsIG9wdHMpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gIH1cblxuICBpZiAodGhpcy53cy5iaW5hcnlUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG4gIH1cblxuICBpZiAodGhpcy53cy5zdXBwb3J0cyAmJiB0aGlzLndzLnN1cHBvcnRzLmJpbmFyeSkge1xuICAgIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSB0cnVlO1xuICAgIHRoaXMud3MuYmluYXJ5VHlwZSA9ICdub2RlYnVmZmVyJztcbiAgfSBlbHNlIHtcbiAgICB0aGlzLndzLmJpbmFyeVR5cGUgPSAnYXJyYXlidWZmZXInO1xuICB9XG5cbiAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xufTtcblxuLyoqXG4gKiBBZGRzIGV2ZW50IGxpc3RlbmVycyB0byB0aGUgc29ja2V0XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXJzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy53cy5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5vbk9wZW4oKTtcbiAgfTtcbiAgdGhpcy53cy5vbmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgIHNlbGYub25DbG9zZSgpO1xuICB9O1xuICB0aGlzLndzLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChldikge1xuICAgIHNlbGYub25EYXRhKGV2LmRhdGEpO1xuICB9O1xuICB0aGlzLndzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZSkge1xuICAgIHNlbGYub25FcnJvcignd2Vic29ja2V0IGVycm9yJywgZSk7XG4gIH07XG59O1xuXG4vKipcbiAqIFdyaXRlcyBkYXRhIHRvIHNvY2tldC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBvZiBwYWNrZXRzLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKHBhY2tldHMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG5cbiAgLy8gZW5jb2RlUGFja2V0IGVmZmljaWVudCBhcyBpdCB1c2VzIFdTIGZyYW1pbmdcbiAgLy8gbm8gbmVlZCBmb3IgZW5jb2RlUGF5bG9hZFxuICB2YXIgdG90YWwgPSBwYWNrZXRzLmxlbmd0aDtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB0b3RhbDsgaSA8IGw7IGkrKykge1xuICAgIChmdW5jdGlvbiAocGFja2V0KSB7XG4gICAgICBwYXJzZXIuZW5jb2RlUGFja2V0KHBhY2tldCwgc2VsZi5zdXBwb3J0c0JpbmFyeSwgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgaWYgKCFzZWxmLnVzaW5nQnJvd3NlcldlYlNvY2tldCkge1xuICAgICAgICAgIC8vIGFsd2F5cyBjcmVhdGUgYSBuZXcgb2JqZWN0IChHSC00MzcpXG4gICAgICAgICAgdmFyIG9wdHMgPSB7fTtcbiAgICAgICAgICBpZiAocGFja2V0Lm9wdGlvbnMpIHtcbiAgICAgICAgICAgIG9wdHMuY29tcHJlc3MgPSBwYWNrZXQub3B0aW9ucy5jb21wcmVzcztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc2VsZi5wZXJNZXNzYWdlRGVmbGF0ZSkge1xuICAgICAgICAgICAgdmFyIGxlbiA9ICdzdHJpbmcnID09PSB0eXBlb2YgZGF0YSA/IGdsb2JhbC5CdWZmZXIuYnl0ZUxlbmd0aChkYXRhKSA6IGRhdGEubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKGxlbiA8IHNlbGYucGVyTWVzc2FnZURlZmxhdGUudGhyZXNob2xkKSB7XG4gICAgICAgICAgICAgIG9wdHMuY29tcHJlc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTb21ldGltZXMgdGhlIHdlYnNvY2tldCBoYXMgYWxyZWFkeSBiZWVuIGNsb3NlZCBidXQgdGhlIGJyb3dzZXIgZGlkbid0XG4gICAgICAgIC8vIGhhdmUgYSBjaGFuY2Ugb2YgaW5mb3JtaW5nIHVzIGFib3V0IGl0IHlldCwgaW4gdGhhdCBjYXNlIHNlbmQgd2lsbFxuICAgICAgICAvLyB0aHJvdyBhbiBlcnJvclxuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChzZWxmLnVzaW5nQnJvd3NlcldlYlNvY2tldCkge1xuICAgICAgICAgICAgLy8gVHlwZUVycm9yIGlzIHRocm93biB3aGVuIHBhc3NpbmcgdGhlIHNlY29uZCBhcmd1bWVudCBvbiBTYWZhcmlcbiAgICAgICAgICAgIHNlbGYud3Muc2VuZChkYXRhKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi53cy5zZW5kKGRhdGEsIG9wdHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGRlYnVnKCd3ZWJzb2NrZXQgY2xvc2VkIGJlZm9yZSBvbmNsb3NlIGV2ZW50Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAtLXRvdGFsIHx8IGRvbmUoKTtcbiAgICAgIH0pO1xuICAgIH0pKHBhY2tldHNbaV0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZG9uZSAoKSB7XG4gICAgc2VsZi5lbWl0KCdmbHVzaCcpO1xuXG4gICAgLy8gZmFrZSBkcmFpblxuICAgIC8vIGRlZmVyIHRvIG5leHQgdGljayB0byBhbGxvdyBTb2NrZXQgdG8gY2xlYXIgd3JpdGVCdWZmZXJcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYud3JpdGFibGUgPSB0cnVlO1xuICAgICAgc2VsZi5lbWl0KCdkcmFpbicpO1xuICAgIH0sIDApO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGNsb3NlXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLm9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIFRyYW5zcG9ydC5wcm90b3R5cGUub25DbG9zZS5jYWxsKHRoaXMpO1xufTtcblxuLyoqXG4gKiBDbG9zZXMgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbldTLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIHRoaXMud3MgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhpcy53cy5jbG9zZSgpO1xuICB9XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyB1cmkgZm9yIGNvbm5lY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLnVyaSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHF1ZXJ5ID0gdGhpcy5xdWVyeSB8fCB7fTtcbiAgdmFyIHNjaGVtYSA9IHRoaXMuc2VjdXJlID8gJ3dzcycgOiAnd3MnO1xuICB2YXIgcG9ydCA9ICcnO1xuXG4gIC8vIGF2b2lkIHBvcnQgaWYgZGVmYXVsdCBmb3Igc2NoZW1hXG4gIGlmICh0aGlzLnBvcnQgJiYgKCgnd3NzJyA9PT0gc2NoZW1hICYmIE51bWJlcih0aGlzLnBvcnQpICE9PSA0NDMpIHx8XG4gICAgKCd3cycgPT09IHNjaGVtYSAmJiBOdW1iZXIodGhpcy5wb3J0KSAhPT0gODApKSkge1xuICAgIHBvcnQgPSAnOicgKyB0aGlzLnBvcnQ7XG4gIH1cblxuICAvLyBhcHBlbmQgdGltZXN0YW1wIHRvIFVSSVxuICBpZiAodGhpcy50aW1lc3RhbXBSZXF1ZXN0cykge1xuICAgIHF1ZXJ5W3RoaXMudGltZXN0YW1wUGFyYW1dID0geWVhc3QoKTtcbiAgfVxuXG4gIC8vIGNvbW11bmljYXRlIGJpbmFyeSBzdXBwb3J0IGNhcGFiaWxpdGllc1xuICBpZiAoIXRoaXMuc3VwcG9ydHNCaW5hcnkpIHtcbiAgICBxdWVyeS5iNjQgPSAxO1xuICB9XG5cbiAgcXVlcnkgPSBwYXJzZXFzLmVuY29kZShxdWVyeSk7XG5cbiAgLy8gcHJlcGVuZCA/IHRvIHF1ZXJ5XG4gIGlmIChxdWVyeS5sZW5ndGgpIHtcbiAgICBxdWVyeSA9ICc/JyArIHF1ZXJ5O1xuICB9XG5cbiAgdmFyIGlwdjYgPSB0aGlzLmhvc3RuYW1lLmluZGV4T2YoJzonKSAhPT0gLTE7XG4gIHJldHVybiBzY2hlbWEgKyAnOi8vJyArIChpcHY2ID8gJ1snICsgdGhpcy5ob3N0bmFtZSArICddJyA6IHRoaXMuaG9zdG5hbWUpICsgcG9ydCArIHRoaXMucGF0aCArIHF1ZXJ5O1xufTtcblxuLyoqXG4gKiBGZWF0dXJlIGRldGVjdGlvbiBmb3IgV2ViU29ja2V0LlxuICpcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHdoZXRoZXIgdGhpcyB0cmFuc3BvcnQgaXMgYXZhaWxhYmxlLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5XUy5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhIVdlYlNvY2tldCAmJiAhKCdfX2luaXRpYWxpemUnIGluIFdlYlNvY2tldCAmJiB0aGlzLm5hbWUgPT09IFdTLnByb3RvdHlwZS5uYW1lKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6b20\n")},"6fba":function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar debug = __webpack_require__(/*! debug */ \"8233\")('socket.io-parser');\nvar json = __webpack_require__(/*! json3 */ \"3b17\");\nvar Emitter = __webpack_require__(/*! component-emitter */ \"636d\");\nvar binary = __webpack_require__(/*! ./binary */ \"ea82\");\nvar isBuf = __webpack_require__(/*! ./is-buffer */ \"419b\");\n\n/**\n * Protocol version.\n *\n * @api public\n */\n\nexports.protocol = 4;\n\n/**\n * Packet types.\n *\n * @api public\n */\n\nexports.types = [\n  'CONNECT',\n  'DISCONNECT',\n  'EVENT',\n  'ACK',\n  'ERROR',\n  'BINARY_EVENT',\n  'BINARY_ACK'\n];\n\n/**\n * Packet type `connect`.\n *\n * @api public\n */\n\nexports.CONNECT = 0;\n\n/**\n * Packet type `disconnect`.\n *\n * @api public\n */\n\nexports.DISCONNECT = 1;\n\n/**\n * Packet type `event`.\n *\n * @api public\n */\n\nexports.EVENT = 2;\n\n/**\n * Packet type `ack`.\n *\n * @api public\n */\n\nexports.ACK = 3;\n\n/**\n * Packet type `error`.\n *\n * @api public\n */\n\nexports.ERROR = 4;\n\n/**\n * Packet type 'binary event'\n *\n * @api public\n */\n\nexports.BINARY_EVENT = 5;\n\n/**\n * Packet type `binary ack`. For acks with binary arguments.\n *\n * @api public\n */\n\nexports.BINARY_ACK = 6;\n\n/**\n * Encoder constructor.\n *\n * @api public\n */\n\nexports.Encoder = Encoder;\n\n/**\n * Decoder constructor.\n *\n * @api public\n */\n\nexports.Decoder = Decoder;\n\n/**\n * A socket.io Encoder instance\n *\n * @api public\n */\n\nfunction Encoder() {}\n\n/**\n * Encode a packet as a single string if non-binary, or as a\n * buffer sequence, depending on packet type.\n *\n * @param {Object} obj - packet object\n * @param {Function} callback - function to handle encodings (likely engine.write)\n * @return Calls callback with Array of encodings\n * @api public\n */\n\nEncoder.prototype.encode = function(obj, callback){\n  debug('encoding packet %j', obj);\n\n  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n    encodeAsBinary(obj, callback);\n  }\n  else {\n    var encoding = encodeAsString(obj);\n    callback([encoding]);\n  }\n};\n\n/**\n * Encode packet as string.\n *\n * @param {Object} packet\n * @return {String} encoded\n * @api private\n */\n\nfunction encodeAsString(obj) {\n  var str = '';\n  var nsp = false;\n\n  // first is type\n  str += obj.type;\n\n  // attachments if we have them\n  if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n    str += obj.attachments;\n    str += '-';\n  }\n\n  // if we have a namespace other than `/`\n  // we append it followed by a comma `,`\n  if (obj.nsp && '/' != obj.nsp) {\n    nsp = true;\n    str += obj.nsp;\n  }\n\n  // immediately followed by the id\n  if (null != obj.id) {\n    if (nsp) {\n      str += ',';\n      nsp = false;\n    }\n    str += obj.id;\n  }\n\n  // json data\n  if (null != obj.data) {\n    if (nsp) str += ',';\n    str += json.stringify(obj.data);\n  }\n\n  debug('encoded %j as %s', obj, str);\n  return str;\n}\n\n/**\n * Encode packet as 'buffer sequence' by removing blobs, and\n * deconstructing packet into object with placeholders and\n * a list of buffers.\n *\n * @param {Object} packet\n * @return {Buffer} encoded\n * @api private\n */\n\nfunction encodeAsBinary(obj, callback) {\n\n  function writeEncoding(bloblessData) {\n    var deconstruction = binary.deconstructPacket(bloblessData);\n    var pack = encodeAsString(deconstruction.packet);\n    var buffers = deconstruction.buffers;\n\n    buffers.unshift(pack); // add packet info to beginning of data list\n    callback(buffers); // write all the buffers\n  }\n\n  binary.removeBlobs(obj, writeEncoding);\n}\n\n/**\n * A socket.io Decoder instance\n *\n * @return {Object} decoder\n * @api public\n */\n\nfunction Decoder() {\n  this.reconstructor = null;\n}\n\n/**\n * Mix in `Emitter` with Decoder.\n */\n\nEmitter(Decoder.prototype);\n\n/**\n * Decodes an ecoded packet string into packet JSON.\n *\n * @param {String} obj - encoded packet\n * @return {Object} packet\n * @api public\n */\n\nDecoder.prototype.add = function(obj) {\n  var packet;\n  if ('string' == typeof obj) {\n    packet = decodeString(obj);\n    if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) { // binary packet's json\n      this.reconstructor = new BinaryReconstructor(packet);\n\n      // no attachments, labeled binary but no binary data to follow\n      if (this.reconstructor.reconPack.attachments === 0) {\n        this.emit('decoded', packet);\n      }\n    } else { // non-binary full packet\n      this.emit('decoded', packet);\n    }\n  }\n  else if (isBuf(obj) || obj.base64) { // raw binary data\n    if (!this.reconstructor) {\n      throw new Error('got binary data when not reconstructing a packet');\n    } else {\n      packet = this.reconstructor.takeBinaryData(obj);\n      if (packet) { // received final buffer\n        this.reconstructor = null;\n        this.emit('decoded', packet);\n      }\n    }\n  }\n  else {\n    throw new Error('Unknown type: ' + obj);\n  }\n};\n\n/**\n * Decode a packet String (JSON data)\n *\n * @param {String} str\n * @return {Object} packet\n * @api private\n */\n\nfunction decodeString(str) {\n  var p = {};\n  var i = 0;\n\n  // look up type\n  p.type = Number(str.charAt(0));\n  if (null == exports.types[p.type]) return error();\n\n  // look up attachments if type binary\n  if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) {\n    var buf = '';\n    while (str.charAt(++i) != '-') {\n      buf += str.charAt(i);\n      if (i == str.length) break;\n    }\n    if (buf != Number(buf) || str.charAt(i) != '-') {\n      throw new Error('Illegal attachments');\n    }\n    p.attachments = Number(buf);\n  }\n\n  // look up namespace (if any)\n  if ('/' == str.charAt(i + 1)) {\n    p.nsp = '';\n    while (++i) {\n      var c = str.charAt(i);\n      if (',' == c) break;\n      p.nsp += c;\n      if (i == str.length) break;\n    }\n  } else {\n    p.nsp = '/';\n  }\n\n  // look up id\n  var next = str.charAt(i + 1);\n  if ('' !== next && Number(next) == next) {\n    p.id = '';\n    while (++i) {\n      var c = str.charAt(i);\n      if (null == c || Number(c) != c) {\n        --i;\n        break;\n      }\n      p.id += str.charAt(i);\n      if (i == str.length) break;\n    }\n    p.id = Number(p.id);\n  }\n\n  // look up json data\n  if (str.charAt(++i)) {\n    p = tryParse(p, str.substr(i));\n  }\n\n  debug('decoded %s as %j', str, p);\n  return p;\n}\n\nfunction tryParse(p, str) {\n  try {\n    p.data = json.parse(str);\n  } catch(e){\n    return error();\n  }\n  return p; \n};\n\n/**\n * Deallocates a parser's resources\n *\n * @api public\n */\n\nDecoder.prototype.destroy = function() {\n  if (this.reconstructor) {\n    this.reconstructor.finishedReconstruction();\n  }\n};\n\n/**\n * A manager of a binary event's 'buffer sequence'. Should\n * be constructed whenever a packet of type BINARY_EVENT is\n * decoded.\n *\n * @param {Object} packet\n * @return {BinaryReconstructor} initialized reconstructor\n * @api private\n */\n\nfunction BinaryReconstructor(packet) {\n  this.reconPack = packet;\n  this.buffers = [];\n}\n\n/**\n * Method to be called when binary data received from connection\n * after a BINARY_EVENT packet.\n *\n * @param {Buffer | ArrayBuffer} binData - the raw binary data received\n * @return {null | Object} returns null if more binary data is expected or\n *   a reconstructed packet object if all buffers have been received.\n * @api private\n */\n\nBinaryReconstructor.prototype.takeBinaryData = function(binData) {\n  this.buffers.push(binData);\n  if (this.buffers.length == this.reconPack.attachments) { // done with buffer list\n    var packet = binary.reconstructPacket(this.reconPack, this.buffers);\n    this.finishedReconstruction();\n    return packet;\n  }\n  return null;\n};\n\n/**\n * Cleans up binary packet reconstruction variables.\n *\n * @api private\n */\n\nBinaryReconstructor.prototype.finishedReconstruction = function() {\n  this.reconPack = null;\n  this.buffers = [];\n};\n\nfunction error(data){\n  return {\n    type: exports.ERROR,\n    data: 'parser error'\n  };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNmZiYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9pbmRleC5qcz84ZjQzIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBqc29uID0gcmVxdWlyZSgnanNvbjMnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciBiaW5hcnkgPSByZXF1aXJlKCcuL2JpbmFyeScpO1xudmFyIGlzQnVmID0gcmVxdWlyZSgnLi9pcy1idWZmZXInKTtcblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5wcm90b2NvbCA9IDQ7XG5cbi8qKlxuICogUGFja2V0IHR5cGVzLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy50eXBlcyA9IFtcbiAgJ0NPTk5FQ1QnLFxuICAnRElTQ09OTkVDVCcsXG4gICdFVkVOVCcsXG4gICdBQ0snLFxuICAnRVJST1InLFxuICAnQklOQVJZX0VWRU5UJyxcbiAgJ0JJTkFSWV9BQ0snXG5dO1xuXG4vKipcbiAqIFBhY2tldCB0eXBlIGBjb25uZWN0YC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuQ09OTkVDVCA9IDA7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGRpc2Nvbm5lY3RgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5ESVNDT05ORUNUID0gMTtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgZXZlbnRgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5FVkVOVCA9IDI7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGFja2AuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkFDSyA9IDM7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGVycm9yYC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuRVJST1IgPSA0O1xuXG4vKipcbiAqIFBhY2tldCB0eXBlICdiaW5hcnkgZXZlbnQnXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkJJTkFSWV9FVkVOVCA9IDU7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGJpbmFyeSBhY2tgLiBGb3IgYWNrcyB3aXRoIGJpbmFyeSBhcmd1bWVudHMuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkJJTkFSWV9BQ0sgPSA2O1xuXG4vKipcbiAqIEVuY29kZXIgY29uc3RydWN0b3IuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkVuY29kZXIgPSBFbmNvZGVyO1xuXG4vKipcbiAqIERlY29kZXIgY29uc3RydWN0b3IuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkRlY29kZXIgPSBEZWNvZGVyO1xuXG4vKipcbiAqIEEgc29ja2V0LmlvIEVuY29kZXIgaW5zdGFuY2VcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIEVuY29kZXIoKSB7fVxuXG4vKipcbiAqIEVuY29kZSBhIHBhY2tldCBhcyBhIHNpbmdsZSBzdHJpbmcgaWYgbm9uLWJpbmFyeSwgb3IgYXMgYVxuICogYnVmZmVyIHNlcXVlbmNlLCBkZXBlbmRpbmcgb24gcGFja2V0IHR5cGUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiAtIHBhY2tldCBvYmplY3RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIC0gZnVuY3Rpb24gdG8gaGFuZGxlIGVuY29kaW5ncyAobGlrZWx5IGVuZ2luZS53cml0ZSlcbiAqIEByZXR1cm4gQ2FsbHMgY2FsbGJhY2sgd2l0aCBBcnJheSBvZiBlbmNvZGluZ3NcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW5jb2Rlci5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24ob2JqLCBjYWxsYmFjayl7XG4gIGRlYnVnKCdlbmNvZGluZyBwYWNrZXQgJWonLCBvYmopO1xuXG4gIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBvYmoudHlwZSB8fCBleHBvcnRzLkJJTkFSWV9BQ0sgPT0gb2JqLnR5cGUpIHtcbiAgICBlbmNvZGVBc0JpbmFyeShvYmosIGNhbGxiYWNrKTtcbiAgfVxuICBlbHNlIHtcbiAgICB2YXIgZW5jb2RpbmcgPSBlbmNvZGVBc1N0cmluZyhvYmopO1xuICAgIGNhbGxiYWNrKFtlbmNvZGluZ10pO1xuICB9XG59O1xuXG4vKipcbiAqIEVuY29kZSBwYWNrZXQgYXMgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEByZXR1cm4ge1N0cmluZ30gZW5jb2RlZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gZW5jb2RlQXNTdHJpbmcob2JqKSB7XG4gIHZhciBzdHIgPSAnJztcbiAgdmFyIG5zcCA9IGZhbHNlO1xuXG4gIC8vIGZpcnN0IGlzIHR5cGVcbiAgc3RyICs9IG9iai50eXBlO1xuXG4gIC8vIGF0dGFjaG1lbnRzIGlmIHdlIGhhdmUgdGhlbVxuICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gb2JqLnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IG9iai50eXBlKSB7XG4gICAgc3RyICs9IG9iai5hdHRhY2htZW50cztcbiAgICBzdHIgKz0gJy0nO1xuICB9XG5cbiAgLy8gaWYgd2UgaGF2ZSBhIG5hbWVzcGFjZSBvdGhlciB0aGFuIGAvYFxuICAvLyB3ZSBhcHBlbmQgaXQgZm9sbG93ZWQgYnkgYSBjb21tYSBgLGBcbiAgaWYgKG9iai5uc3AgJiYgJy8nICE9IG9iai5uc3ApIHtcbiAgICBuc3AgPSB0cnVlO1xuICAgIHN0ciArPSBvYmoubnNwO1xuICB9XG5cbiAgLy8gaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgdGhlIGlkXG4gIGlmIChudWxsICE9IG9iai5pZCkge1xuICAgIGlmIChuc3ApIHtcbiAgICAgIHN0ciArPSAnLCc7XG4gICAgICBuc3AgPSBmYWxzZTtcbiAgICB9XG4gICAgc3RyICs9IG9iai5pZDtcbiAgfVxuXG4gIC8vIGpzb24gZGF0YVxuICBpZiAobnVsbCAhPSBvYmouZGF0YSkge1xuICAgIGlmIChuc3ApIHN0ciArPSAnLCc7XG4gICAgc3RyICs9IGpzb24uc3RyaW5naWZ5KG9iai5kYXRhKTtcbiAgfVxuXG4gIGRlYnVnKCdlbmNvZGVkICVqIGFzICVzJywgb2JqLCBzdHIpO1xuICByZXR1cm4gc3RyO1xufVxuXG4vKipcbiAqIEVuY29kZSBwYWNrZXQgYXMgJ2J1ZmZlciBzZXF1ZW5jZScgYnkgcmVtb3ZpbmcgYmxvYnMsIGFuZFxuICogZGVjb25zdHJ1Y3RpbmcgcGFja2V0IGludG8gb2JqZWN0IHdpdGggcGxhY2Vob2xkZXJzIGFuZFxuICogYSBsaXN0IG9mIGJ1ZmZlcnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQHJldHVybiB7QnVmZmVyfSBlbmNvZGVkXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBlbmNvZGVBc0JpbmFyeShvYmosIGNhbGxiYWNrKSB7XG5cbiAgZnVuY3Rpb24gd3JpdGVFbmNvZGluZyhibG9ibGVzc0RhdGEpIHtcbiAgICB2YXIgZGVjb25zdHJ1Y3Rpb24gPSBiaW5hcnkuZGVjb25zdHJ1Y3RQYWNrZXQoYmxvYmxlc3NEYXRhKTtcbiAgICB2YXIgcGFjayA9IGVuY29kZUFzU3RyaW5nKGRlY29uc3RydWN0aW9uLnBhY2tldCk7XG4gICAgdmFyIGJ1ZmZlcnMgPSBkZWNvbnN0cnVjdGlvbi5idWZmZXJzO1xuXG4gICAgYnVmZmVycy51bnNoaWZ0KHBhY2spOyAvLyBhZGQgcGFja2V0IGluZm8gdG8gYmVnaW5uaW5nIG9mIGRhdGEgbGlzdFxuICAgIGNhbGxiYWNrKGJ1ZmZlcnMpOyAvLyB3cml0ZSBhbGwgdGhlIGJ1ZmZlcnNcbiAgfVxuXG4gIGJpbmFyeS5yZW1vdmVCbG9icyhvYmosIHdyaXRlRW5jb2RpbmcpO1xufVxuXG4vKipcbiAqIEEgc29ja2V0LmlvIERlY29kZXIgaW5zdGFuY2VcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGRlY29kZXJcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRGVjb2RlcigpIHtcbiAgdGhpcy5yZWNvbnN0cnVjdG9yID0gbnVsbDtcbn1cblxuLyoqXG4gKiBNaXggaW4gYEVtaXR0ZXJgIHdpdGggRGVjb2Rlci5cbiAqL1xuXG5FbWl0dGVyKERlY29kZXIucHJvdG90eXBlKTtcblxuLyoqXG4gKiBEZWNvZGVzIGFuIGVjb2RlZCBwYWNrZXQgc3RyaW5nIGludG8gcGFja2V0IEpTT04uXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG9iaiAtIGVuY29kZWQgcGFja2V0XG4gKiBAcmV0dXJuIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5EZWNvZGVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbihvYmopIHtcbiAgdmFyIHBhY2tldDtcbiAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBvYmopIHtcbiAgICBwYWNrZXQgPSBkZWNvZGVTdHJpbmcob2JqKTtcbiAgICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gcGFja2V0LnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IHBhY2tldC50eXBlKSB7IC8vIGJpbmFyeSBwYWNrZXQncyBqc29uXG4gICAgICB0aGlzLnJlY29uc3RydWN0b3IgPSBuZXcgQmluYXJ5UmVjb25zdHJ1Y3RvcihwYWNrZXQpO1xuXG4gICAgICAvLyBubyBhdHRhY2htZW50cywgbGFiZWxlZCBiaW5hcnkgYnV0IG5vIGJpbmFyeSBkYXRhIHRvIGZvbGxvd1xuICAgICAgaWYgKHRoaXMucmVjb25zdHJ1Y3Rvci5yZWNvblBhY2suYXR0YWNobWVudHMgPT09IDApIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkZWNvZGVkJywgcGFja2V0KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgeyAvLyBub24tYmluYXJ5IGZ1bGwgcGFja2V0XG4gICAgICB0aGlzLmVtaXQoJ2RlY29kZWQnLCBwYWNrZXQpO1xuICAgIH1cbiAgfVxuICBlbHNlIGlmIChpc0J1ZihvYmopIHx8IG9iai5iYXNlNjQpIHsgLy8gcmF3IGJpbmFyeSBkYXRhXG4gICAgaWYgKCF0aGlzLnJlY29uc3RydWN0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ290IGJpbmFyeSBkYXRhIHdoZW4gbm90IHJlY29uc3RydWN0aW5nIGEgcGFja2V0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhY2tldCA9IHRoaXMucmVjb25zdHJ1Y3Rvci50YWtlQmluYXJ5RGF0YShvYmopO1xuICAgICAgaWYgKHBhY2tldCkgeyAvLyByZWNlaXZlZCBmaW5hbCBidWZmZXJcbiAgICAgICAgdGhpcy5yZWNvbnN0cnVjdG9yID0gbnVsbDtcbiAgICAgICAgdGhpcy5lbWl0KCdkZWNvZGVkJywgcGFja2V0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHR5cGU6ICcgKyBvYmopO1xuICB9XG59O1xuXG4vKipcbiAqIERlY29kZSBhIHBhY2tldCBTdHJpbmcgKEpTT04gZGF0YSlcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gZGVjb2RlU3RyaW5nKHN0cikge1xuICB2YXIgcCA9IHt9O1xuICB2YXIgaSA9IDA7XG5cbiAgLy8gbG9vayB1cCB0eXBlXG4gIHAudHlwZSA9IE51bWJlcihzdHIuY2hhckF0KDApKTtcbiAgaWYgKG51bGwgPT0gZXhwb3J0cy50eXBlc1twLnR5cGVdKSByZXR1cm4gZXJyb3IoKTtcblxuICAvLyBsb29rIHVwIGF0dGFjaG1lbnRzIGlmIHR5cGUgYmluYXJ5XG4gIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBwLnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IHAudHlwZSkge1xuICAgIHZhciBidWYgPSAnJztcbiAgICB3aGlsZSAoc3RyLmNoYXJBdCgrK2kpICE9ICctJykge1xuICAgICAgYnVmICs9IHN0ci5jaGFyQXQoaSk7XG4gICAgICBpZiAoaSA9PSBzdHIubGVuZ3RoKSBicmVhaztcbiAgICB9XG4gICAgaWYgKGJ1ZiAhPSBOdW1iZXIoYnVmKSB8fCBzdHIuY2hhckF0KGkpICE9ICctJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbGxlZ2FsIGF0dGFjaG1lbnRzJyk7XG4gICAgfVxuICAgIHAuYXR0YWNobWVudHMgPSBOdW1iZXIoYnVmKTtcbiAgfVxuXG4gIC8vIGxvb2sgdXAgbmFtZXNwYWNlIChpZiBhbnkpXG4gIGlmICgnLycgPT0gc3RyLmNoYXJBdChpICsgMSkpIHtcbiAgICBwLm5zcCA9ICcnO1xuICAgIHdoaWxlICgrK2kpIHtcbiAgICAgIHZhciBjID0gc3RyLmNoYXJBdChpKTtcbiAgICAgIGlmICgnLCcgPT0gYykgYnJlYWs7XG4gICAgICBwLm5zcCArPSBjO1xuICAgICAgaWYgKGkgPT0gc3RyLmxlbmd0aCkgYnJlYWs7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHAubnNwID0gJy8nO1xuICB9XG5cbiAgLy8gbG9vayB1cCBpZFxuICB2YXIgbmV4dCA9IHN0ci5jaGFyQXQoaSArIDEpO1xuICBpZiAoJycgIT09IG5leHQgJiYgTnVtYmVyKG5leHQpID09IG5leHQpIHtcbiAgICBwLmlkID0gJyc7XG4gICAgd2hpbGUgKCsraSkge1xuICAgICAgdmFyIGMgPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKG51bGwgPT0gYyB8fCBOdW1iZXIoYykgIT0gYykge1xuICAgICAgICAtLWk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgcC5pZCArPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKGkgPT0gc3RyLmxlbmd0aCkgYnJlYWs7XG4gICAgfVxuICAgIHAuaWQgPSBOdW1iZXIocC5pZCk7XG4gIH1cblxuICAvLyBsb29rIHVwIGpzb24gZGF0YVxuICBpZiAoc3RyLmNoYXJBdCgrK2kpKSB7XG4gICAgcCA9IHRyeVBhcnNlKHAsIHN0ci5zdWJzdHIoaSkpO1xuICB9XG5cbiAgZGVidWcoJ2RlY29kZWQgJXMgYXMgJWonLCBzdHIsIHApO1xuICByZXR1cm4gcDtcbn1cblxuZnVuY3Rpb24gdHJ5UGFyc2UocCwgc3RyKSB7XG4gIHRyeSB7XG4gICAgcC5kYXRhID0ganNvbi5wYXJzZShzdHIpO1xuICB9IGNhdGNoKGUpe1xuICAgIHJldHVybiBlcnJvcigpO1xuICB9XG4gIHJldHVybiBwOyBcbn07XG5cbi8qKlxuICogRGVhbGxvY2F0ZXMgYSBwYXJzZXIncyByZXNvdXJjZXNcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkRlY29kZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMucmVjb25zdHJ1Y3Rvcikge1xuICAgIHRoaXMucmVjb25zdHJ1Y3Rvci5maW5pc2hlZFJlY29uc3RydWN0aW9uKCk7XG4gIH1cbn07XG5cbi8qKlxuICogQSBtYW5hZ2VyIG9mIGEgYmluYXJ5IGV2ZW50J3MgJ2J1ZmZlciBzZXF1ZW5jZScuIFNob3VsZFxuICogYmUgY29uc3RydWN0ZWQgd2hlbmV2ZXIgYSBwYWNrZXQgb2YgdHlwZSBCSU5BUllfRVZFTlQgaXNcbiAqIGRlY29kZWQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQHJldHVybiB7QmluYXJ5UmVjb25zdHJ1Y3Rvcn0gaW5pdGlhbGl6ZWQgcmVjb25zdHJ1Y3RvclxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gQmluYXJ5UmVjb25zdHJ1Y3RvcihwYWNrZXQpIHtcbiAgdGhpcy5yZWNvblBhY2sgPSBwYWNrZXQ7XG4gIHRoaXMuYnVmZmVycyA9IFtdO1xufVxuXG4vKipcbiAqIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiBiaW5hcnkgZGF0YSByZWNlaXZlZCBmcm9tIGNvbm5lY3Rpb25cbiAqIGFmdGVyIGEgQklOQVJZX0VWRU5UIHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge0J1ZmZlciB8IEFycmF5QnVmZmVyfSBiaW5EYXRhIC0gdGhlIHJhdyBiaW5hcnkgZGF0YSByZWNlaXZlZFxuICogQHJldHVybiB7bnVsbCB8IE9iamVjdH0gcmV0dXJucyBudWxsIGlmIG1vcmUgYmluYXJ5IGRhdGEgaXMgZXhwZWN0ZWQgb3JcbiAqICAgYSByZWNvbnN0cnVjdGVkIHBhY2tldCBvYmplY3QgaWYgYWxsIGJ1ZmZlcnMgaGF2ZSBiZWVuIHJlY2VpdmVkLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuQmluYXJ5UmVjb25zdHJ1Y3Rvci5wcm90b3R5cGUudGFrZUJpbmFyeURhdGEgPSBmdW5jdGlvbihiaW5EYXRhKSB7XG4gIHRoaXMuYnVmZmVycy5wdXNoKGJpbkRhdGEpO1xuICBpZiAodGhpcy5idWZmZXJzLmxlbmd0aCA9PSB0aGlzLnJlY29uUGFjay5hdHRhY2htZW50cykgeyAvLyBkb25lIHdpdGggYnVmZmVyIGxpc3RcbiAgICB2YXIgcGFja2V0ID0gYmluYXJ5LnJlY29uc3RydWN0UGFja2V0KHRoaXMucmVjb25QYWNrLCB0aGlzLmJ1ZmZlcnMpO1xuICAgIHRoaXMuZmluaXNoZWRSZWNvbnN0cnVjdGlvbigpO1xuICAgIHJldHVybiBwYWNrZXQ7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIENsZWFucyB1cCBiaW5hcnkgcGFja2V0IHJlY29uc3RydWN0aW9uIHZhcmlhYmxlcy5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5CaW5hcnlSZWNvbnN0cnVjdG9yLnByb3RvdHlwZS5maW5pc2hlZFJlY29uc3RydWN0aW9uID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMucmVjb25QYWNrID0gbnVsbDtcbiAgdGhpcy5idWZmZXJzID0gW107XG59O1xuXG5mdW5jdGlvbiBlcnJvcihkYXRhKXtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBleHBvcnRzLkVSUk9SLFxuICAgIGRhdGE6ICdwYXJzZXIgZXJyb3InXG4gIH07XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6fba\n")},"720c":function(module,exports,__webpack_require__){eval("/**\n * Client side filtering using crossfilter\n * Due to limitation of crossfilter with array (or data that has no natrual ordering), this will not work as expected:\n * * dimension: `function (d) {return [d.x, d.y, d.z]}`\n * * group: `function (d) {return [d.x / 10 , d.y / 10, d.z / 10]}`\n *\n * Therefore, we preform grouping already in the dimension itself, and join the array to a string.\n * Strings have a natural ordering and thus can be used as dimension value.\n * * dimension: `function (d) -> \"d.x/10|d.y/10|d.z/10\"`\n * * group: `function (d) {return d;}`\n *\n * @module driver/client\n */\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\nvar utildx = __webpack_require__(/*! ../util/crossfilter */ \"adfa\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nvar grpIdxToName = {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'};\nvar aggRankToName = {1: 'aa', 2: 'bb', 3: 'cc', 4: 'dd', 5: 'ee'};\n\n/**\n * setMinMax sets the range of a continuous or time facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setMinMax (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var valFn = utildx.baseValueFn(facet);\n\n  // to be able to mark the value as missing we need it unprocessed, so rawValueFn\n  var rawValFn = utildx.rawValueFn(facet);\n\n  var lessFn;\n  var moreFn;\n  if (facet.isDatetime) {\n    lessFn = function (a, b) { return (b === misval || a.isBefore(b)); };\n    moreFn = function (a, b) { return (b === misval || b.isBefore(a)); };\n  } else {\n    lessFn = function (a, b) { return (b === misval || a < b); };\n    moreFn = function (a, b) { return (b === misval || a > b); };\n  }\n\n  var minval = misval;\n  var rawMin = misval;\n\n  var maxval = misval;\n  var rawMax = misval;\n\n  dataset.data.forEach(function (d) {\n    var rawV = rawValFn(d);\n    var v = valFn(d);\n\n    if (v !== misval) {\n      if (lessFn(v, minval)) {\n        minval = v;\n        rawMin = rawV;\n      }\n      if (moreFn(v, maxval)) {\n        maxval = v;\n        rawMax = rawV;\n      }\n    }\n  });\n\n  if (minval !== misval) {\n    if (facet.isContinuous) {\n      facet.minvalAsText = minval.toString();\n    } else if (facet.isDatetime) {\n      facet.minvalAsText = minval.toISOString();\n    } else if (facet.isDuration) {\n      facet.minvalAsText = minval.toISOString();\n    }\n    facet.rawMinval = rawMin;\n  } else {\n    facet.minvalAsText = '';\n    facet.rawMinval = misval;\n  }\n\n  if (maxval !== misval) {\n    if (facet.isContinuous) {\n      facet.maxvalAsText = maxval.toString();\n    } else if (facet.isDatetime) {\n      facet.maxvalAsText = maxval.toISOString();\n    } else if (facet.isDuration) {\n      facet.maxvalAsText = maxval.toISOString();\n    }\n    facet.rawMaxval = rawMax;\n  } else {\n    facet.maxvalAsText = '';\n    facet.rawMaxval = misval;\n  }\n}\n\n/**\n * setCategories finds finds all values on an ordinal (categorial) axis\n * Updates the categorialTransform of the facet\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setCategories (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var valFn = utildx.baseValueFn(facet);\n\n  var p = {};\n  var Plength = 0;\n  dataset.data.forEach(function (d, i) {\n    var vals = valFn(d);\n    if (vals instanceof Array) {\n      vals.forEach(function (val) {\n        if (p.hasOwnProperty(val)) {\n          p[val]++;\n        } else {\n          if (Plength < 75) { // NOTE: limit to maximally 75 categories\n            p[val] = 1;\n            Plength++;\n          }\n        }\n      });\n    } else {\n      if (p.hasOwnProperty(vals)) {\n        p[vals]++;\n      } else {\n        if (Plength < 75) { // NOTE: limit to maximally 75 categories\n          p[vals] = 1;\n          Plength++;\n        }\n      }\n    }\n  });\n\n  facet.categorialTransform.reset();\n\n  Object.keys(p).forEach(function (key) {\n    // TODO: missing data should be mapped to a misval from misvalAsText\n    var keyAsString = key.toString();\n    var groupAsString = keyAsString;\n\n    facet.categorialTransform.rules.add({expression: keyAsString, count: p[key], group: groupAsString});\n  });\n}\n\n/**\n * Calculate 100 percentiles (ie. 1,2,3,4 etc.), and initialize the `facet.continuousTransform`\n * to an approximate percentile mapping.\n * Use the recommended method from [NIST](http://www.itl.nist.gov/div898/handbook/prc/section2/prc262.htm)\n * See also the discussion on [Wikipedia](https://en.wikipedia.org/wiki/Percentile)\n *\n * @param {Dataset} dataset\n * @param {Facet} facet\n */\nfunction setPercentiles (dataset, facet) {\n  // we need the value just before a transformation, so baseValueFn\n  var basevalueFn = utildx.baseValueFn(facet);\n  var data = dataset.data;\n\n  data.sort(function (a, b) {\n    var valA = basevalueFn(a);\n    var valB = basevalueFn(b);\n\n    if (valA === valB) {\n      return 0;\n    }\n    if (valA === misval) {\n      return -1;\n    }\n    if (valB === misval) {\n      return 1;\n    }\n\n    if (valA < valB) {\n      return -1;\n    } else {\n      return 1;\n    }\n  });\n\n  var tf = facet.continuousTransform;\n  var x, i;\n\n  // drop missing values, which should be sorted at the start of the array\n  i = 0;\n  while (basevalueFn(data[i]) === misval && i < data.length) {\n    i++;\n  }\n  data.splice(0, i);\n\n  // start clean\n  tf.reset();\n\n  // add minimum value as control points p0 and p1\n  tf.cps.add({x: basevalueFn(data[0]), fx: 0});\n  tf.cps.add({x: basevalueFn(data[0]), fx: 0});\n\n  var p, value;\n  for (p = 1; p < 100; p++) {\n    x = (p * 0.01) * (data.length + 1) - 1; // indexing starts at zero, not at one\n    i = Math.trunc(x);\n    value = (1 - x + i) * basevalueFn(data[i]) + (x - i) * basevalueFn(data[i + 1]);\n    tf.cps.add({x: value, fx: p});\n  }\n\n  // add maximum value as p101 and p102\n  tf.cps.add({x: basevalueFn(data[data.length - 1]), fx: 100});\n  tf.cps.add({x: basevalueFn(data[data.length - 1]), fx: 100});\n\n  tf.type = 'percentiles';\n}\n\n/**\n * Autoconfigure a dataset:\n * 1. pick 10 random elements\n * 2. create facets for their properties\n * 3. add facets' values over the sample to the facet.description\n * 4. set range or categories\n *\n * @param {Dataset} dataset\n */\nfunction scan (dataset) {\n  function facetExists (facets, path) {\n    var exists = false;\n    facets.forEach(function (f) {\n      if (f.accessor === path || f.accessor === path + '[]') {\n        exists = true;\n      }\n    });\n    return exists;\n  }\n\n  function addValue (values, v, missing) {\n    if (v === misval) {\n      v = missing;\n    }\n    if (values.indexOf(v) === -1) {\n      values.push(v);\n    }\n  }\n\n  function guessType (values) {\n    var mytype = {\n      continuous: 0,\n      text: 0,\n      datetime: 0,\n      duration: 0,\n      categorial: 0\n    };\n    values.forEach(function (value) {\n      if (moment(value, moment.ISO_8601).isValid()) {\n        // \"2016-08-17 17:25:00+01\"\n        mytype.datetime++;\n      } else if (\n          (moment.duration(value).asMilliseconds() !== 0) &&\n          (typeof value === 'string') &&\n          (value[0].toLowerCase() === 'p')) {\n        // \"P10Y\"\n        mytype.duration++;\n      } else if (value == +value) {  // eslint-disable-line eqeqeq\n        // \"10\" or 10\n        mytype.continuous++;\n      } else {\n        // \"hello world\"\n        mytype.categorial++;\n      }\n    });\n\n    // get facetType with highest count\n    var max = -1;\n    var facetType;\n    Object.keys(mytype).forEach(function (key) {\n      if (mytype[key] > max) {\n        facetType = key;\n        max = mytype[key];\n      }\n    });\n\n    return facetType;\n  }\n\n  function tryFacet (facets, data, path, value) {\n    // Check for existence\n    if (facetExists(facets, path)) {\n      return;\n    }\n\n    // Create a new facet\n    var facet = facets.add({\n      name: path,\n      accessor: path,\n      type: 'text'\n    });\n\n    // Sample values\n    var baseValueFn = utildx.baseValueFn(facet);\n    var values = [];\n    var isArray = false;\n\n    data.forEach(function (d) {\n      var value = baseValueFn(d);\n      if (value instanceof Array) {\n        isArray = true;\n        value.forEach(function (v) {\n          addValue(values, v, facet.misval[0]);\n        });\n      } else {\n        addValue(values, value, facet.misval[0]);\n      }\n    });\n\n    // Reconfigure facet\n    facet.accessor = isArray ? facet.accessor + '[]' : facet.accessor;\n    facet.type = guessType(values);\n    facet.description = values.join(', ').match('^.{0,40}') + '...';\n    facet.isActive = true;\n  }\n\n  function recurse (facets, data, path, tree) {\n    var props = Object.getOwnPropertyNames(tree);\n    props.forEach(function (name) {\n      var subpath;\n      if (path) {\n        subpath = path + '##' + name;\n      } else {\n        subpath = name;\n      }\n\n      if (tree[name] instanceof Array) {\n        // add an array as a itself as a facet, ie. labelset, to prevent adding each element as separate facet\n        // also add the array length as facet\n        tryFacet(facets, data, subpath, tree[name]);\n        tryFacet(facets, data, subpath + '.length', tree[name].length);\n      } else if (tree[name] instanceof Object) {\n        // recurse into objects\n        recurse(facets, data, subpath, tree[name]);\n      } else {\n        // add strings and numbers as facets\n        tryFacet(facets, data, subpath, tree[name]);\n      }\n    });\n  }\n\n  // Add facets\n  var data = dataset.data.slice(0, 10);\n  data.forEach(function (d) {\n    recurse(dataset.facets, data, '', d);\n  });\n\n  dataset.facets.forEach(function (facet) {\n    if (facet.isCategorial) {\n      setCategories(dataset, facet);\n    } else if (facet.isContinuous || facet.isDatetime) {\n      setMinMax(dataset, facet);\n    }\n  });\n  dataset.trigger('syncFacets');\n}\n\n/**\n * Initialize the data filter, and construct the getData callback function on the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction initDataFilter (dataview, filter) {\n  var facet;\n\n  // use the partitions as groups:\n  var groupFns = [];\n  filter.partitions.forEach(function (partition) {\n    facet = dataview.facets.get(partition.facetName, 'name');\n    var valueFn = utildx.valueFn(facet);\n    var groupFn = utildx.groupFn(partition);\n\n    var rank = partition.rank;\n    groupFns[rank - 1] = function (d) {\n      return groupFn(valueFn(d));\n    };\n  });\n\n  // and then create keys from the group values\n  var groupsKeys = function (d) {\n    var keys = [];\n\n    groupFns.forEach(function (groupFn) {\n      var result = groupFn(d);\n      var newKeys = [];\n      if (keys.length === 0) {\n        if (result instanceof Array) {\n          newKeys = result;\n        } else {\n          newKeys = [result];\n        }\n      } else {\n        if (result instanceof Array) {\n          keys.forEach(function (oldKey) {\n            result.forEach(function (key) {\n              newKeys.push(oldKey + '|' + key);\n            });\n          });\n        } else {\n          keys.forEach(function (oldKey) {\n            newKeys.push(oldKey + '|' + result);\n          });\n        }\n      }\n      keys = newKeys;\n    });\n    return keys;\n  };\n\n  // set up the facet valueFns to aggregate over\n  // and the reduction functions for them\n  var aggregateFns = [];\n  var aggregateRanks = [];\n  var reduceFns = [];\n  filter.aggregates.forEach(function (aggregate) {\n    facet = dataview.facets.get(aggregate.facetName, 'name');\n    aggregateRanks.push(aggregate.rank);\n    aggregateFns.push(utildx.valueFn(facet));\n    reduceFns.push(utildx.reduceFn(aggregate));\n  });\n\n  // setup the crossfilter dimensions and groups\n  filter.dimension = dataview.crossfilter.dimension(function (d) {\n    return groupsKeys(d);\n  }, true);\n  var crossfilterGroup = filter.dimension.group(function (d) { return d; });\n\n  crossfilterGroup.reduce(\n    // add\n    function (p, d) {\n      if (aggregateFns.length === 0) {\n        p[0] = p[0] ? p[0] : {count: 0};\n        p[0].count += 1;\n      }\n\n      aggregateFns.forEach(function (aggregateFn, i) {\n        var val = aggregateFn(d);\n        if (val !== misval) {\n          val = parseFloat(val);\n          p[i] = p[i] || {count: 0, sum: 0, sumsquares: 0};\n          p[i].count += 1;\n          p[i].sum += val;\n          p[i].sumsquares += val * val;\n        }\n      });\n      return p;\n    },\n    // subtract\n    function (p, d) {\n      if (aggregateFns.length === 0) {\n        p[0] = p[0] ? p[0] : {count: 0};\n        p[0].count -= 1;\n      }\n\n      aggregateFns.forEach(function (aggregateFn, i) {\n        var val = aggregateFn(d);\n        if (val !== misval) {\n          val = parseFloat(val);\n          p[i] = p[i] || {count: 0, sum: 0, sumsquares: 0};\n          p[i].count -= 1;\n          p[i].sum -= val;\n          p[i].sumsquares -= val * val;\n        }\n      });\n      return p;\n    },\n    // initialize\n    function () {\n      return [];\n    }\n  );\n\n  filter.getData = function () {\n    filter.data = [];\n\n    // Get data from crossfilter\n    var groups = crossfilterGroup.all();\n\n    // { key: \"group1|group2|...\",\n    //   value: [ {count: agg1, sum: agg1}\n    //            {count: agg2, sum: agg2}\n    //            {count: agg3, sum: agg3}\n    //                    ...             ]}\n    groups.forEach(function (group) {\n      var item = {};\n\n      // turn the string back into individual group values\n      var groupsKeys;\n      if (typeof group.key === 'string') {\n        groupsKeys = group.key.split('|');\n      } else {\n        // shortcut for numeric non-partitioned case\n        groupsKeys = [group.key];\n      }\n\n      // add paritioning data to the item\n      groupsKeys.forEach(function (subkey, i) {\n        item[grpIdxToName[i]] = subkey;\n      });\n\n      // add aggregated data to the item\n      reduceFns.forEach(function (reduceFn, i) {\n        var name = aggRankToName[aggregateRanks[i]];\n        item[name] = reduceFn(group.value[i]);\n      });\n\n      // add an overall count\n      // becuase the filtering removes missing data points, this is the same as\n      // the count for any one of the aggregates\n      item.count = group.value[0] ? group.value[0].count : 0;\n\n      filter.data.push(item);\n    });\n  };\n}\n\n/**\n * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n * related to the filter.\n * @param {Dataview} dataview\n * @param {Filter} filter\n */\nfunction releaseDataFilter (dataview, filter) {\n  if (filter.dimension) {\n    filter.dimension.filterAll();\n    filter.dimension.dispose();\n    delete filter.dimension;\n    delete filter.getData;\n  }\n}\n\n/**\n * Change the filter parameters for an initialized filter\n * @param {Filter} filter\n */\nfunction updateDataFilter (filter) {\n  if (filter.dimension) {\n    filter.dimension.filterFunction(filter.filterFunction());\n  }\n}\n\n/**\n * Get data for every filter, and trigger a 'newData' event\n *\n * Returns a Promise that resolves to the dataview when all data and metadata has been updated\n *\n * @param {Dataview} dataview\n * @returns {Promise}\n */\nfunction getData (dataview) {\n  dataview.filters.forEach(function (filter) {\n    if (filter.isInitialized) {\n      filter.getData();\n      filter.trigger('newData');\n    }\n  });\n\n  // update counts\n  dataview.dataTotal = dataview.crossfilter.size();\n  dataview.dataSelected = dataview.countGroup.value();\n  dataview.trigger('newMetaData');\n\n  return Promise.resolve(dataview);\n}\n\nmodule.exports = {\n  driverType: 'client',\n  scan: scan,\n  setMinMax: setMinMax,\n  setCategories: setCategories,\n  setPercentiles: setPercentiles,\n  initDataFilter: initDataFilter,\n  releaseDataFilter: releaseDataFilter,\n  updateDataFilter: updateDataFilter,\n  getData: getData\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzIwYy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZHJpdmVyL2NsaWVudC5qcz9kZjc3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2xpZW50IHNpZGUgZmlsdGVyaW5nIHVzaW5nIGNyb3NzZmlsdGVyXG4gKiBEdWUgdG8gbGltaXRhdGlvbiBvZiBjcm9zc2ZpbHRlciB3aXRoIGFycmF5IChvciBkYXRhIHRoYXQgaGFzIG5vIG5hdHJ1YWwgb3JkZXJpbmcpLCB0aGlzIHdpbGwgbm90IHdvcmsgYXMgZXhwZWN0ZWQ6XG4gKiAqIGRpbWVuc2lvbjogYGZ1bmN0aW9uIChkKSB7cmV0dXJuIFtkLngsIGQueSwgZC56XX1gXG4gKiAqIGdyb3VwOiBgZnVuY3Rpb24gKGQpIHtyZXR1cm4gW2QueCAvIDEwICwgZC55IC8gMTAsIGQueiAvIDEwXX1gXG4gKlxuICogVGhlcmVmb3JlLCB3ZSBwcmVmb3JtIGdyb3VwaW5nIGFscmVhZHkgaW4gdGhlIGRpbWVuc2lvbiBpdHNlbGYsIGFuZCBqb2luIHRoZSBhcnJheSB0byBhIHN0cmluZy5cbiAqIFN0cmluZ3MgaGF2ZSBhIG5hdHVyYWwgb3JkZXJpbmcgYW5kIHRodXMgY2FuIGJlIHVzZWQgYXMgZGltZW5zaW9uIHZhbHVlLlxuICogKiBkaW1lbnNpb246IGBmdW5jdGlvbiAoZCkgLT4gXCJkLngvMTB8ZC55LzEwfGQuei8xMFwiYFxuICogKiBncm91cDogYGZ1bmN0aW9uIChkKSB7cmV0dXJuIGQ7fWBcbiAqXG4gKiBAbW9kdWxlIGRyaXZlci9jbGllbnRcbiAqL1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xuXG52YXIgdXRpbGR4ID0gcmVxdWlyZSgnLi4vdXRpbC9jcm9zc2ZpbHRlcicpO1xudmFyIG1pc3ZhbCA9IHJlcXVpcmUoJy4uL3V0aWwvbWlzdmFsJyk7XG5cbnZhciBncnBJZHhUb05hbWUgPSB7MDogJ2EnLCAxOiAnYicsIDI6ICdjJywgMzogJ2QnLCA0OiAnZSd9O1xudmFyIGFnZ1JhbmtUb05hbWUgPSB7MTogJ2FhJywgMjogJ2JiJywgMzogJ2NjJywgNDogJ2RkJywgNTogJ2VlJ307XG5cbi8qKlxuICogc2V0TWluTWF4IHNldHMgdGhlIHJhbmdlIG9mIGEgY29udGludW91cyBvciB0aW1lIGZhY2V0XG4gKlxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0XG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICovXG5mdW5jdGlvbiBzZXRNaW5NYXggKGRhdGFzZXQsIGZhY2V0KSB7XG4gIC8vIHdlIG5lZWQgdGhlIHZhbHVlIGp1c3QgYmVmb3JlIGEgdHJhbnNmb3JtYXRpb24sIHNvIGJhc2VWYWx1ZUZuXG4gIHZhciB2YWxGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG5cbiAgLy8gdG8gYmUgYWJsZSB0byBtYXJrIHRoZSB2YWx1ZSBhcyBtaXNzaW5nIHdlIG5lZWQgaXQgdW5wcm9jZXNzZWQsIHNvIHJhd1ZhbHVlRm5cbiAgdmFyIHJhd1ZhbEZuID0gdXRpbGR4LnJhd1ZhbHVlRm4oZmFjZXQpO1xuXG4gIHZhciBsZXNzRm47XG4gIHZhciBtb3JlRm47XG4gIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgbGVzc0ZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYS5pc0JlZm9yZShiKSk7IH07XG4gICAgbW9yZUZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYi5pc0JlZm9yZShhKSk7IH07XG4gIH0gZWxzZSB7XG4gICAgbGVzc0ZuID0gZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIChiID09PSBtaXN2YWwgfHwgYSA8IGIpOyB9O1xuICAgIG1vcmVGbiA9IGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiAoYiA9PT0gbWlzdmFsIHx8IGEgPiBiKTsgfTtcbiAgfVxuXG4gIHZhciBtaW52YWwgPSBtaXN2YWw7XG4gIHZhciByYXdNaW4gPSBtaXN2YWw7XG5cbiAgdmFyIG1heHZhbCA9IG1pc3ZhbDtcbiAgdmFyIHJhd01heCA9IG1pc3ZhbDtcblxuICBkYXRhc2V0LmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgIHZhciByYXdWID0gcmF3VmFsRm4oZCk7XG4gICAgdmFyIHYgPSB2YWxGbihkKTtcblxuICAgIGlmICh2ICE9PSBtaXN2YWwpIHtcbiAgICAgIGlmIChsZXNzRm4odiwgbWludmFsKSkge1xuICAgICAgICBtaW52YWwgPSB2O1xuICAgICAgICByYXdNaW4gPSByYXdWO1xuICAgICAgfVxuICAgICAgaWYgKG1vcmVGbih2LCBtYXh2YWwpKSB7XG4gICAgICAgIG1heHZhbCA9IHY7XG4gICAgICAgIHJhd01heCA9IHJhd1Y7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBpZiAobWludmFsICE9PSBtaXN2YWwpIHtcbiAgICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgICBmYWNldC5taW52YWxBc1RleHQgPSBtaW52YWwudG9TdHJpbmcoKTtcbiAgICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICAgIGZhY2V0Lm1pbnZhbEFzVGV4dCA9IG1pbnZhbC50b0lTT1N0cmluZygpO1xuICAgIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgICAgZmFjZXQubWludmFsQXNUZXh0ID0gbWludmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGZhY2V0LnJhd01pbnZhbCA9IHJhd01pbjtcbiAgfSBlbHNlIHtcbiAgICBmYWNldC5taW52YWxBc1RleHQgPSAnJztcbiAgICBmYWNldC5yYXdNaW52YWwgPSBtaXN2YWw7XG4gIH1cblxuICBpZiAobWF4dmFsICE9PSBtaXN2YWwpIHtcbiAgICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgICBmYWNldC5tYXh2YWxBc1RleHQgPSBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICAgIGZhY2V0Lm1heHZhbEFzVGV4dCA9IG1heHZhbC50b0lTT1N0cmluZygpO1xuICAgIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgICAgZmFjZXQubWF4dmFsQXNUZXh0ID0gbWF4dmFsLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGZhY2V0LnJhd01heHZhbCA9IHJhd01heDtcbiAgfSBlbHNlIHtcbiAgICBmYWNldC5tYXh2YWxBc1RleHQgPSAnJztcbiAgICBmYWNldC5yYXdNYXh2YWwgPSBtaXN2YWw7XG4gIH1cbn1cblxuLyoqXG4gKiBzZXRDYXRlZ29yaWVzIGZpbmRzIGZpbmRzIGFsbCB2YWx1ZXMgb24gYW4gb3JkaW5hbCAoY2F0ZWdvcmlhbCkgYXhpc1xuICogVXBkYXRlcyB0aGUgY2F0ZWdvcmlhbFRyYW5zZm9ybSBvZiB0aGUgZmFjZXRcbiAqXG4gKiBAcGFyYW0ge0RhdGFzZXR9IGRhdGFzZXRcbiAqIEBwYXJhbSB7RmFjZXR9IGZhY2V0XG4gKi9cbmZ1bmN0aW9uIHNldENhdGVnb3JpZXMgKGRhdGFzZXQsIGZhY2V0KSB7XG4gIC8vIHdlIG5lZWQgdGhlIHZhbHVlIGp1c3QgYmVmb3JlIGEgdHJhbnNmb3JtYXRpb24sIHNvIGJhc2VWYWx1ZUZuXG4gIHZhciB2YWxGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG5cbiAgdmFyIHAgPSB7fTtcbiAgdmFyIFBsZW5ndGggPSAwO1xuICBkYXRhc2V0LmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZCwgaSkge1xuICAgIHZhciB2YWxzID0gdmFsRm4oZCk7XG4gICAgaWYgKHZhbHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgdmFscy5mb3JFYWNoKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgaWYgKHAuaGFzT3duUHJvcGVydHkodmFsKSkge1xuICAgICAgICAgIHBbdmFsXSsrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChQbGVuZ3RoIDwgNzUpIHsgLy8gTk9URTogbGltaXQgdG8gbWF4aW1hbGx5IDc1IGNhdGVnb3JpZXNcbiAgICAgICAgICAgIHBbdmFsXSA9IDE7XG4gICAgICAgICAgICBQbGVuZ3RoKys7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHAuaGFzT3duUHJvcGVydHkodmFscykpIHtcbiAgICAgICAgcFt2YWxzXSsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKFBsZW5ndGggPCA3NSkgeyAvLyBOT1RFOiBsaW1pdCB0byBtYXhpbWFsbHkgNzUgY2F0ZWdvcmllc1xuICAgICAgICAgIHBbdmFsc10gPSAxO1xuICAgICAgICAgIFBsZW5ndGgrKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5yZXNldCgpO1xuXG4gIE9iamVjdC5rZXlzKHApLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIC8vIFRPRE86IG1pc3NpbmcgZGF0YSBzaG91bGQgYmUgbWFwcGVkIHRvIGEgbWlzdmFsIGZyb20gbWlzdmFsQXNUZXh0XG4gICAgdmFyIGtleUFzU3RyaW5nID0ga2V5LnRvU3RyaW5nKCk7XG4gICAgdmFyIGdyb3VwQXNTdHJpbmcgPSBrZXlBc1N0cmluZztcblxuICAgIGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuYWRkKHtleHByZXNzaW9uOiBrZXlBc1N0cmluZywgY291bnQ6IHBba2V5XSwgZ3JvdXA6IGdyb3VwQXNTdHJpbmd9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIDEwMCBwZXJjZW50aWxlcyAoaWUuIDEsMiwzLDQgZXRjLiksIGFuZCBpbml0aWFsaXplIHRoZSBgZmFjZXQuY29udGludW91c1RyYW5zZm9ybWBcbiAqIHRvIGFuIGFwcHJveGltYXRlIHBlcmNlbnRpbGUgbWFwcGluZy5cbiAqIFVzZSB0aGUgcmVjb21tZW5kZWQgbWV0aG9kIGZyb20gW05JU1RdKGh0dHA6Ly93d3cuaXRsLm5pc3QuZ292L2Rpdjg5OC9oYW5kYm9vay9wcmMvc2VjdGlvbjIvcHJjMjYyLmh0bSlcbiAqIFNlZSBhbHNvIHRoZSBkaXNjdXNzaW9uIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1BlcmNlbnRpbGUpXG4gKlxuICogQHBhcmFtIHtEYXRhc2V0fSBkYXRhc2V0XG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICovXG5mdW5jdGlvbiBzZXRQZXJjZW50aWxlcyAoZGF0YXNldCwgZmFjZXQpIHtcbiAgLy8gd2UgbmVlZCB0aGUgdmFsdWUganVzdCBiZWZvcmUgYSB0cmFuc2Zvcm1hdGlvbiwgc28gYmFzZVZhbHVlRm5cbiAgdmFyIGJhc2V2YWx1ZUZuID0gdXRpbGR4LmJhc2VWYWx1ZUZuKGZhY2V0KTtcbiAgdmFyIGRhdGEgPSBkYXRhc2V0LmRhdGE7XG5cbiAgZGF0YS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgdmFyIHZhbEEgPSBiYXNldmFsdWVGbihhKTtcbiAgICB2YXIgdmFsQiA9IGJhc2V2YWx1ZUZuKGIpO1xuXG4gICAgaWYgKHZhbEEgPT09IHZhbEIpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpZiAodmFsQSA9PT0gbWlzdmFsKSB7XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIGlmICh2YWxCID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIGlmICh2YWxBIDwgdmFsQikge1xuICAgICAgcmV0dXJuIC0xO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH0pO1xuXG4gIHZhciB0ZiA9IGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm07XG4gIHZhciB4LCBpO1xuXG4gIC8vIGRyb3AgbWlzc2luZyB2YWx1ZXMsIHdoaWNoIHNob3VsZCBiZSBzb3J0ZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZSBhcnJheVxuICBpID0gMDtcbiAgd2hpbGUgKGJhc2V2YWx1ZUZuKGRhdGFbaV0pID09PSBtaXN2YWwgJiYgaSA8IGRhdGEubGVuZ3RoKSB7XG4gICAgaSsrO1xuICB9XG4gIGRhdGEuc3BsaWNlKDAsIGkpO1xuXG4gIC8vIHN0YXJ0IGNsZWFuXG4gIHRmLnJlc2V0KCk7XG5cbiAgLy8gYWRkIG1pbmltdW0gdmFsdWUgYXMgY29udHJvbCBwb2ludHMgcDAgYW5kIHAxXG4gIHRmLmNwcy5hZGQoe3g6IGJhc2V2YWx1ZUZuKGRhdGFbMF0pLCBmeDogMH0pO1xuICB0Zi5jcHMuYWRkKHt4OiBiYXNldmFsdWVGbihkYXRhWzBdKSwgZng6IDB9KTtcblxuICB2YXIgcCwgdmFsdWU7XG4gIGZvciAocCA9IDE7IHAgPCAxMDA7IHArKykge1xuICAgIHggPSAocCAqIDAuMDEpICogKGRhdGEubGVuZ3RoICsgMSkgLSAxOyAvLyBpbmRleGluZyBzdGFydHMgYXQgemVybywgbm90IGF0IG9uZVxuICAgIGkgPSBNYXRoLnRydW5jKHgpO1xuICAgIHZhbHVlID0gKDEgLSB4ICsgaSkgKiBiYXNldmFsdWVGbihkYXRhW2ldKSArICh4IC0gaSkgKiBiYXNldmFsdWVGbihkYXRhW2kgKyAxXSk7XG4gICAgdGYuY3BzLmFkZCh7eDogdmFsdWUsIGZ4OiBwfSk7XG4gIH1cblxuICAvLyBhZGQgbWF4aW11bSB2YWx1ZSBhcyBwMTAxIGFuZCBwMTAyXG4gIHRmLmNwcy5hZGQoe3g6IGJhc2V2YWx1ZUZuKGRhdGFbZGF0YS5sZW5ndGggLSAxXSksIGZ4OiAxMDB9KTtcbiAgdGYuY3BzLmFkZCh7eDogYmFzZXZhbHVlRm4oZGF0YVtkYXRhLmxlbmd0aCAtIDFdKSwgZng6IDEwMH0pO1xuXG4gIHRmLnR5cGUgPSAncGVyY2VudGlsZXMnO1xufVxuXG4vKipcbiAqIEF1dG9jb25maWd1cmUgYSBkYXRhc2V0OlxuICogMS4gcGljayAxMCByYW5kb20gZWxlbWVudHNcbiAqIDIuIGNyZWF0ZSBmYWNldHMgZm9yIHRoZWlyIHByb3BlcnRpZXNcbiAqIDMuIGFkZCBmYWNldHMnIHZhbHVlcyBvdmVyIHRoZSBzYW1wbGUgdG8gdGhlIGZhY2V0LmRlc2NyaXB0aW9uXG4gKiA0LiBzZXQgcmFuZ2Ugb3IgY2F0ZWdvcmllc1xuICpcbiAqIEBwYXJhbSB7RGF0YXNldH0gZGF0YXNldFxuICovXG5mdW5jdGlvbiBzY2FuIChkYXRhc2V0KSB7XG4gIGZ1bmN0aW9uIGZhY2V0RXhpc3RzIChmYWNldHMsIHBhdGgpIHtcbiAgICB2YXIgZXhpc3RzID0gZmFsc2U7XG4gICAgZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgIGlmIChmLmFjY2Vzc29yID09PSBwYXRoIHx8IGYuYWNjZXNzb3IgPT09IHBhdGggKyAnW10nKSB7XG4gICAgICAgIGV4aXN0cyA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGV4aXN0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFZhbHVlICh2YWx1ZXMsIHYsIG1pc3NpbmcpIHtcbiAgICBpZiAodiA9PT0gbWlzdmFsKSB7XG4gICAgICB2ID0gbWlzc2luZztcbiAgICB9XG4gICAgaWYgKHZhbHVlcy5pbmRleE9mKHYpID09PSAtMSkge1xuICAgICAgdmFsdWVzLnB1c2godik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZ3Vlc3NUeXBlICh2YWx1ZXMpIHtcbiAgICB2YXIgbXl0eXBlID0ge1xuICAgICAgY29udGludW91czogMCxcbiAgICAgIHRleHQ6IDAsXG4gICAgICBkYXRldGltZTogMCxcbiAgICAgIGR1cmF0aW9uOiAwLFxuICAgICAgY2F0ZWdvcmlhbDogMFxuICAgIH07XG4gICAgdmFsdWVzLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBpZiAobW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpLmlzVmFsaWQoKSkge1xuICAgICAgICAvLyBcIjIwMTYtMDgtMTcgMTc6MjU6MDArMDFcIlxuICAgICAgICBteXR5cGUuZGF0ZXRpbWUrKztcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgKG1vbWVudC5kdXJhdGlvbih2YWx1ZSkuYXNNaWxsaXNlY29uZHMoKSAhPT0gMCkgJiZcbiAgICAgICAgICAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgJiZcbiAgICAgICAgICAodmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSkge1xuICAgICAgICAvLyBcIlAxMFlcIlxuICAgICAgICBteXR5cGUuZHVyYXRpb24rKztcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gK3ZhbHVlKSB7ICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgICAgICAvLyBcIjEwXCIgb3IgMTBcbiAgICAgICAgbXl0eXBlLmNvbnRpbnVvdXMrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFwiaGVsbG8gd29ybGRcIlxuICAgICAgICBteXR5cGUuY2F0ZWdvcmlhbCsrO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gZ2V0IGZhY2V0VHlwZSB3aXRoIGhpZ2hlc3QgY291bnRcbiAgICB2YXIgbWF4ID0gLTE7XG4gICAgdmFyIGZhY2V0VHlwZTtcbiAgICBPYmplY3Qua2V5cyhteXR5cGUpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgaWYgKG15dHlwZVtrZXldID4gbWF4KSB7XG4gICAgICAgIGZhY2V0VHlwZSA9IGtleTtcbiAgICAgICAgbWF4ID0gbXl0eXBlW2tleV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZmFjZXRUeXBlO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJ5RmFjZXQgKGZhY2V0cywgZGF0YSwgcGF0aCwgdmFsdWUpIHtcbiAgICAvLyBDaGVjayBmb3IgZXhpc3RlbmNlXG4gICAgaWYgKGZhY2V0RXhpc3RzKGZhY2V0cywgcGF0aCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYSBuZXcgZmFjZXRcbiAgICB2YXIgZmFjZXQgPSBmYWNldHMuYWRkKHtcbiAgICAgIG5hbWU6IHBhdGgsXG4gICAgICBhY2Nlc3NvcjogcGF0aCxcbiAgICAgIHR5cGU6ICd0ZXh0J1xuICAgIH0pO1xuXG4gICAgLy8gU2FtcGxlIHZhbHVlc1xuICAgIHZhciBiYXNlVmFsdWVGbiA9IHV0aWxkeC5iYXNlVmFsdWVGbihmYWNldCk7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIHZhciBpc0FycmF5ID0gZmFsc2U7XG5cbiAgICBkYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGJhc2VWYWx1ZUZuKGQpO1xuICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgaXNBcnJheSA9IHRydWU7XG4gICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICBhZGRWYWx1ZSh2YWx1ZXMsIHYsIGZhY2V0Lm1pc3ZhbFswXSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWRkVmFsdWUodmFsdWVzLCB2YWx1ZSwgZmFjZXQubWlzdmFsWzBdKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFJlY29uZmlndXJlIGZhY2V0XG4gICAgZmFjZXQuYWNjZXNzb3IgPSBpc0FycmF5ID8gZmFjZXQuYWNjZXNzb3IgKyAnW10nIDogZmFjZXQuYWNjZXNzb3I7XG4gICAgZmFjZXQudHlwZSA9IGd1ZXNzVHlwZSh2YWx1ZXMpO1xuICAgIGZhY2V0LmRlc2NyaXB0aW9uID0gdmFsdWVzLmpvaW4oJywgJykubWF0Y2goJ14uezAsNDB9JykgKyAnLi4uJztcbiAgICBmYWNldC5pc0FjdGl2ZSA9IHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiByZWN1cnNlIChmYWNldHMsIGRhdGEsIHBhdGgsIHRyZWUpIHtcbiAgICB2YXIgcHJvcHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0cmVlKTtcbiAgICBwcm9wcy5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICB2YXIgc3VicGF0aDtcbiAgICAgIGlmIChwYXRoKSB7XG4gICAgICAgIHN1YnBhdGggPSBwYXRoICsgJyMjJyArIG5hbWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdWJwYXRoID0gbmFtZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRyZWVbbmFtZV0gaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAvLyBhZGQgYW4gYXJyYXkgYXMgYSBpdHNlbGYgYXMgYSBmYWNldCwgaWUuIGxhYmVsc2V0LCB0byBwcmV2ZW50IGFkZGluZyBlYWNoIGVsZW1lbnQgYXMgc2VwYXJhdGUgZmFjZXRcbiAgICAgICAgLy8gYWxzbyBhZGQgdGhlIGFycmF5IGxlbmd0aCBhcyBmYWNldFxuICAgICAgICB0cnlGYWNldChmYWNldHMsIGRhdGEsIHN1YnBhdGgsIHRyZWVbbmFtZV0pO1xuICAgICAgICB0cnlGYWNldChmYWNldHMsIGRhdGEsIHN1YnBhdGggKyAnLmxlbmd0aCcsIHRyZWVbbmFtZV0ubGVuZ3RoKTtcbiAgICAgIH0gZWxzZSBpZiAodHJlZVtuYW1lXSBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgICAgICAvLyByZWN1cnNlIGludG8gb2JqZWN0c1xuICAgICAgICByZWN1cnNlKGZhY2V0cywgZGF0YSwgc3VicGF0aCwgdHJlZVtuYW1lXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBhZGQgc3RyaW5ncyBhbmQgbnVtYmVycyBhcyBmYWNldHNcbiAgICAgICAgdHJ5RmFjZXQoZmFjZXRzLCBkYXRhLCBzdWJwYXRoLCB0cmVlW25hbWVdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIEFkZCBmYWNldHNcbiAgdmFyIGRhdGEgPSBkYXRhc2V0LmRhdGEuc2xpY2UoMCwgMTApO1xuICBkYXRhLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICByZWN1cnNlKGRhdGFzZXQuZmFjZXRzLCBkYXRhLCAnJywgZCk7XG4gIH0pO1xuXG4gIGRhdGFzZXQuZmFjZXRzLmZvckVhY2goZnVuY3Rpb24gKGZhY2V0KSB7XG4gICAgaWYgKGZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgICAgc2V0Q2F0ZWdvcmllcyhkYXRhc2V0LCBmYWNldCk7XG4gICAgfSBlbHNlIGlmIChmYWNldC5pc0NvbnRpbnVvdXMgfHwgZmFjZXQuaXNEYXRldGltZSkge1xuICAgICAgc2V0TWluTWF4KGRhdGFzZXQsIGZhY2V0KTtcbiAgICB9XG4gIH0pO1xuICBkYXRhc2V0LnRyaWdnZXIoJ3N5bmNGYWNldHMnKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEBwYXJhbSB7RmlsdGVyfSBmaWx0ZXJcbiAqL1xuZnVuY3Rpb24gaW5pdERhdGFGaWx0ZXIgKGRhdGF2aWV3LCBmaWx0ZXIpIHtcbiAgdmFyIGZhY2V0O1xuXG4gIC8vIHVzZSB0aGUgcGFydGl0aW9ucyBhcyBncm91cHM6XG4gIHZhciBncm91cEZucyA9IFtdO1xuICBmaWx0ZXIucGFydGl0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgICBmYWNldCA9IGRhdGF2aWV3LmZhY2V0cy5nZXQocGFydGl0aW9uLmZhY2V0TmFtZSwgJ25hbWUnKTtcbiAgICB2YXIgdmFsdWVGbiA9IHV0aWxkeC52YWx1ZUZuKGZhY2V0KTtcbiAgICB2YXIgZ3JvdXBGbiA9IHV0aWxkeC5ncm91cEZuKHBhcnRpdGlvbik7XG5cbiAgICB2YXIgcmFuayA9IHBhcnRpdGlvbi5yYW5rO1xuICAgIGdyb3VwRm5zW3JhbmsgLSAxXSA9IGZ1bmN0aW9uIChkKSB7XG4gICAgICByZXR1cm4gZ3JvdXBGbih2YWx1ZUZuKGQpKTtcbiAgICB9O1xuICB9KTtcblxuICAvLyBhbmQgdGhlbiBjcmVhdGUga2V5cyBmcm9tIHRoZSBncm91cCB2YWx1ZXNcbiAgdmFyIGdyb3Vwc0tleXMgPSBmdW5jdGlvbiAoZCkge1xuICAgIHZhciBrZXlzID0gW107XG5cbiAgICBncm91cEZucy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cEZuKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gZ3JvdXBGbihkKTtcbiAgICAgIHZhciBuZXdLZXlzID0gW107XG4gICAgICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgbmV3S2V5cyA9IHJlc3VsdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdLZXlzID0gW3Jlc3VsdF07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbiAob2xkS2V5KSB7XG4gICAgICAgICAgICByZXN1bHQuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgIG5ld0tleXMucHVzaChvbGRLZXkgKyAnfCcgKyBrZXkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChvbGRLZXkpIHtcbiAgICAgICAgICAgIG5ld0tleXMucHVzaChvbGRLZXkgKyAnfCcgKyByZXN1bHQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBrZXlzID0gbmV3S2V5cztcbiAgICB9KTtcbiAgICByZXR1cm4ga2V5cztcbiAgfTtcblxuICAvLyBzZXQgdXAgdGhlIGZhY2V0IHZhbHVlRm5zIHRvIGFnZ3JlZ2F0ZSBvdmVyXG4gIC8vIGFuZCB0aGUgcmVkdWN0aW9uIGZ1bmN0aW9ucyBmb3IgdGhlbVxuICB2YXIgYWdncmVnYXRlRm5zID0gW107XG4gIHZhciBhZ2dyZWdhdGVSYW5rcyA9IFtdO1xuICB2YXIgcmVkdWNlRm5zID0gW107XG4gIGZpbHRlci5hZ2dyZWdhdGVzLmZvckVhY2goZnVuY3Rpb24gKGFnZ3JlZ2F0ZSkge1xuICAgIGZhY2V0ID0gZGF0YXZpZXcuZmFjZXRzLmdldChhZ2dyZWdhdGUuZmFjZXROYW1lLCAnbmFtZScpO1xuICAgIGFnZ3JlZ2F0ZVJhbmtzLnB1c2goYWdncmVnYXRlLnJhbmspO1xuICAgIGFnZ3JlZ2F0ZUZucy5wdXNoKHV0aWxkeC52YWx1ZUZuKGZhY2V0KSk7XG4gICAgcmVkdWNlRm5zLnB1c2godXRpbGR4LnJlZHVjZUZuKGFnZ3JlZ2F0ZSkpO1xuICB9KTtcblxuICAvLyBzZXR1cCB0aGUgY3Jvc3NmaWx0ZXIgZGltZW5zaW9ucyBhbmQgZ3JvdXBzXG4gIGZpbHRlci5kaW1lbnNpb24gPSBkYXRhdmlldy5jcm9zc2ZpbHRlci5kaW1lbnNpb24oZnVuY3Rpb24gKGQpIHtcbiAgICByZXR1cm4gZ3JvdXBzS2V5cyhkKTtcbiAgfSwgdHJ1ZSk7XG4gIHZhciBjcm9zc2ZpbHRlckdyb3VwID0gZmlsdGVyLmRpbWVuc2lvbi5ncm91cChmdW5jdGlvbiAoZCkgeyByZXR1cm4gZDsgfSk7XG5cbiAgY3Jvc3NmaWx0ZXJHcm91cC5yZWR1Y2UoXG4gICAgLy8gYWRkXG4gICAgZnVuY3Rpb24gKHAsIGQpIHtcbiAgICAgIGlmIChhZ2dyZWdhdGVGbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHBbMF0gPSBwWzBdID8gcFswXSA6IHtjb3VudDogMH07XG4gICAgICAgIHBbMF0uY291bnQgKz0gMTtcbiAgICAgIH1cblxuICAgICAgYWdncmVnYXRlRm5zLmZvckVhY2goZnVuY3Rpb24gKGFnZ3JlZ2F0ZUZuLCBpKSB7XG4gICAgICAgIHZhciB2YWwgPSBhZ2dyZWdhdGVGbihkKTtcbiAgICAgICAgaWYgKHZhbCAhPT0gbWlzdmFsKSB7XG4gICAgICAgICAgdmFsID0gcGFyc2VGbG9hdCh2YWwpO1xuICAgICAgICAgIHBbaV0gPSBwW2ldIHx8IHtjb3VudDogMCwgc3VtOiAwLCBzdW1zcXVhcmVzOiAwfTtcbiAgICAgICAgICBwW2ldLmNvdW50ICs9IDE7XG4gICAgICAgICAgcFtpXS5zdW0gKz0gdmFsO1xuICAgICAgICAgIHBbaV0uc3Vtc3F1YXJlcyArPSB2YWwgKiB2YWw7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHA7XG4gICAgfSxcbiAgICAvLyBzdWJ0cmFjdFxuICAgIGZ1bmN0aW9uIChwLCBkKSB7XG4gICAgICBpZiAoYWdncmVnYXRlRm5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBwWzBdID0gcFswXSA/IHBbMF0gOiB7Y291bnQ6IDB9O1xuICAgICAgICBwWzBdLmNvdW50IC09IDE7XG4gICAgICB9XG5cbiAgICAgIGFnZ3JlZ2F0ZUZucy5mb3JFYWNoKGZ1bmN0aW9uIChhZ2dyZWdhdGVGbiwgaSkge1xuICAgICAgICB2YXIgdmFsID0gYWdncmVnYXRlRm4oZCk7XG4gICAgICAgIGlmICh2YWwgIT09IG1pc3ZhbCkge1xuICAgICAgICAgIHZhbCA9IHBhcnNlRmxvYXQodmFsKTtcbiAgICAgICAgICBwW2ldID0gcFtpXSB8fCB7Y291bnQ6IDAsIHN1bTogMCwgc3Vtc3F1YXJlczogMH07XG4gICAgICAgICAgcFtpXS5jb3VudCAtPSAxO1xuICAgICAgICAgIHBbaV0uc3VtIC09IHZhbDtcbiAgICAgICAgICBwW2ldLnN1bXNxdWFyZXMgLT0gdmFsICogdmFsO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBwO1xuICAgIH0sXG4gICAgLy8gaW5pdGlhbGl6ZVxuICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICk7XG5cbiAgZmlsdGVyLmdldERhdGEgPSBmdW5jdGlvbiAoKSB7XG4gICAgZmlsdGVyLmRhdGEgPSBbXTtcblxuICAgIC8vIEdldCBkYXRhIGZyb20gY3Jvc3NmaWx0ZXJcbiAgICB2YXIgZ3JvdXBzID0gY3Jvc3NmaWx0ZXJHcm91cC5hbGwoKTtcblxuICAgIC8vIHsga2V5OiBcImdyb3VwMXxncm91cDJ8Li4uXCIsXG4gICAgLy8gICB2YWx1ZTogWyB7Y291bnQ6IGFnZzEsIHN1bTogYWdnMX1cbiAgICAvLyAgICAgICAgICAgIHtjb3VudDogYWdnMiwgc3VtOiBhZ2cyfVxuICAgIC8vICAgICAgICAgICAge2NvdW50OiBhZ2czLCBzdW06IGFnZzN9XG4gICAgLy8gICAgICAgICAgICAgICAgICAgIC4uLiAgICAgICAgICAgICBdfVxuICAgIGdyb3Vwcy5mb3JFYWNoKGZ1bmN0aW9uIChncm91cCkge1xuICAgICAgdmFyIGl0ZW0gPSB7fTtcblxuICAgICAgLy8gdHVybiB0aGUgc3RyaW5nIGJhY2sgaW50byBpbmRpdmlkdWFsIGdyb3VwIHZhbHVlc1xuICAgICAgdmFyIGdyb3Vwc0tleXM7XG4gICAgICBpZiAodHlwZW9mIGdyb3VwLmtleSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZ3JvdXBzS2V5cyA9IGdyb3VwLmtleS5zcGxpdCgnfCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gc2hvcnRjdXQgZm9yIG51bWVyaWMgbm9uLXBhcnRpdGlvbmVkIGNhc2VcbiAgICAgICAgZ3JvdXBzS2V5cyA9IFtncm91cC5rZXldO1xuICAgICAgfVxuXG4gICAgICAvLyBhZGQgcGFyaXRpb25pbmcgZGF0YSB0byB0aGUgaXRlbVxuICAgICAgZ3JvdXBzS2V5cy5mb3JFYWNoKGZ1bmN0aW9uIChzdWJrZXksIGkpIHtcbiAgICAgICAgaXRlbVtncnBJZHhUb05hbWVbaV1dID0gc3Via2V5O1xuICAgICAgfSk7XG5cbiAgICAgIC8vIGFkZCBhZ2dyZWdhdGVkIGRhdGEgdG8gdGhlIGl0ZW1cbiAgICAgIHJlZHVjZUZucy5mb3JFYWNoKGZ1bmN0aW9uIChyZWR1Y2VGbiwgaSkge1xuICAgICAgICB2YXIgbmFtZSA9IGFnZ1JhbmtUb05hbWVbYWdncmVnYXRlUmFua3NbaV1dO1xuICAgICAgICBpdGVtW25hbWVdID0gcmVkdWNlRm4oZ3JvdXAudmFsdWVbaV0pO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIGFkZCBhbiBvdmVyYWxsIGNvdW50XG4gICAgICAvLyBiZWN1YXNlIHRoZSBmaWx0ZXJpbmcgcmVtb3ZlcyBtaXNzaW5nIGRhdGEgcG9pbnRzLCB0aGlzIGlzIHRoZSBzYW1lIGFzXG4gICAgICAvLyB0aGUgY291bnQgZm9yIGFueSBvbmUgb2YgdGhlIGFnZ3JlZ2F0ZXNcbiAgICAgIGl0ZW0uY291bnQgPSBncm91cC52YWx1ZVswXSA/IGdyb3VwLnZhbHVlWzBdLmNvdW50IDogMDtcblxuICAgICAgZmlsdGVyLmRhdGEucHVzaChpdGVtKTtcbiAgICB9KTtcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGUgb3Bwb3NpdGUgb3IgaW5pdERhdGFGaWx0ZXIsIGl0IHNob3VsZCByZW1vdmUgdGhlIGZpbHRlciBhbmQgZGVhbGxvY2F0ZSBvdGhlciBjb25maWd1cmF0aW9uXG4gKiByZWxhdGVkIHRvIHRoZSBmaWx0ZXIuXG4gKiBAcGFyYW0ge0RhdGF2aWV3fSBkYXRhdmlld1xuICogQHBhcmFtIHtGaWx0ZXJ9IGZpbHRlclxuICovXG5mdW5jdGlvbiByZWxlYXNlRGF0YUZpbHRlciAoZGF0YXZpZXcsIGZpbHRlcikge1xuICBpZiAoZmlsdGVyLmRpbWVuc2lvbikge1xuICAgIGZpbHRlci5kaW1lbnNpb24uZmlsdGVyQWxsKCk7XG4gICAgZmlsdGVyLmRpbWVuc2lvbi5kaXNwb3NlKCk7XG4gICAgZGVsZXRlIGZpbHRlci5kaW1lbnNpb247XG4gICAgZGVsZXRlIGZpbHRlci5nZXREYXRhO1xuICB9XG59XG5cbi8qKlxuICogQ2hhbmdlIHRoZSBmaWx0ZXIgcGFyYW1ldGVycyBmb3IgYW4gaW5pdGlhbGl6ZWQgZmlsdGVyXG4gKiBAcGFyYW0ge0ZpbHRlcn0gZmlsdGVyXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZURhdGFGaWx0ZXIgKGZpbHRlcikge1xuICBpZiAoZmlsdGVyLmRpbWVuc2lvbikge1xuICAgIGZpbHRlci5kaW1lbnNpb24uZmlsdGVyRnVuY3Rpb24oZmlsdGVyLmZpbHRlckZ1bmN0aW9uKCkpO1xuICB9XG59XG5cbi8qKlxuICogR2V0IGRhdGEgZm9yIGV2ZXJ5IGZpbHRlciwgYW5kIHRyaWdnZXIgYSAnbmV3RGF0YScgZXZlbnRcbiAqXG4gKiBSZXR1cm5zIGEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkYXRhdmlldyB3aGVuIGFsbCBkYXRhIGFuZCBtZXRhZGF0YSBoYXMgYmVlbiB1cGRhdGVkXG4gKlxuICogQHBhcmFtIHtEYXRhdmlld30gZGF0YXZpZXdcbiAqIEByZXR1cm5zIHtQcm9taXNlfVxuICovXG5mdW5jdGlvbiBnZXREYXRhIChkYXRhdmlldykge1xuICBkYXRhdmlldy5maWx0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpbHRlcikge1xuICAgIGlmIChmaWx0ZXIuaXNJbml0aWFsaXplZCkge1xuICAgICAgZmlsdGVyLmdldERhdGEoKTtcbiAgICAgIGZpbHRlci50cmlnZ2VyKCduZXdEYXRhJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyB1cGRhdGUgY291bnRzXG4gIGRhdGF2aWV3LmRhdGFUb3RhbCA9IGRhdGF2aWV3LmNyb3NzZmlsdGVyLnNpemUoKTtcbiAgZGF0YXZpZXcuZGF0YVNlbGVjdGVkID0gZGF0YXZpZXcuY291bnRHcm91cC52YWx1ZSgpO1xuICBkYXRhdmlldy50cmlnZ2VyKCduZXdNZXRhRGF0YScpO1xuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoZGF0YXZpZXcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZHJpdmVyVHlwZTogJ2NsaWVudCcsXG4gIHNjYW46IHNjYW4sXG4gIHNldE1pbk1heDogc2V0TWluTWF4LFxuICBzZXRDYXRlZ29yaWVzOiBzZXRDYXRlZ29yaWVzLFxuICBzZXRQZXJjZW50aWxlczogc2V0UGVyY2VudGlsZXMsXG4gIGluaXREYXRhRmlsdGVyOiBpbml0RGF0YUZpbHRlcixcbiAgcmVsZWFzZURhdGFGaWx0ZXI6IHJlbGVhc2VEYXRhRmlsdGVyLFxuICB1cGRhdGVEYXRhRmlsdGVyOiB1cGRhdGVEYXRhRmlsdGVyLFxuICBnZXREYXRhOiBnZXREYXRhXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///720c\n")},"780f":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {\n/**\n * Module dependencies.\n */\n\nvar parseuri = __webpack_require__(/*! parseuri */ \"64a0\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client:url');\n\n/**\n * Module exports.\n */\n\nmodule.exports = url;\n\n/**\n * URL parser.\n *\n * @param {String} url\n * @param {Object} An object meant to mimic window.location.\n *                 Defaults to window.location.\n * @api public\n */\n\nfunction url (uri, loc) {\n  var obj = uri;\n\n  // default to window.location\n  loc = loc || global.location;\n  if (null == uri) uri = loc.protocol + '//' + loc.host;\n\n  // relative path support\n  if ('string' === typeof uri) {\n    if ('/' === uri.charAt(0)) {\n      if ('/' === uri.charAt(1)) {\n        uri = loc.protocol + uri;\n      } else {\n        uri = loc.host + uri;\n      }\n    }\n\n    if (!/^(https?|wss?):\\/\\//.test(uri)) {\n      debug('protocol-less url %s', uri);\n      if ('undefined' !== typeof loc) {\n        uri = loc.protocol + '//' + uri;\n      } else {\n        uri = 'https://' + uri;\n      }\n    }\n\n    // parse\n    debug('parse %s', uri);\n    obj = parseuri(uri);\n  }\n\n  // make sure we treat `localhost:80` and `localhost` equally\n  if (!obj.port) {\n    if (/^(http|ws)$/.test(obj.protocol)) {\n      obj.port = '80';\n    } else if (/^(http|ws)s$/.test(obj.protocol)) {\n      obj.port = '443';\n    }\n  }\n\n  obj.path = obj.path || '/';\n\n  var ipv6 = obj.host.indexOf(':') !== -1;\n  var host = ipv6 ? '[' + obj.host + ']' : obj.host;\n\n  // define unique id\n  obj.id = obj.protocol + '://' + host + ':' + obj.port;\n  // define href\n  obj.href = obj.protocol + '://' + host + (loc && loc.port === obj.port ? '' : (':' + obj.port));\n\n  return obj;\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzgwZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvdXJsLmpzPzAwMGMiXSwic291cmNlc0NvbnRlbnQiOlsiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNldXJpID0gcmVxdWlyZSgncGFyc2V1cmknKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6dXJsJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSB1cmw7XG5cbi8qKlxuICogVVJMIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge09iamVjdH0gQW4gb2JqZWN0IG1lYW50IHRvIG1pbWljIHdpbmRvdy5sb2NhdGlvbi5cbiAqICAgICAgICAgICAgICAgICBEZWZhdWx0cyB0byB3aW5kb3cubG9jYXRpb24uXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIHVybCAodXJpLCBsb2MpIHtcbiAgdmFyIG9iaiA9IHVyaTtcblxuICAvLyBkZWZhdWx0IHRvIHdpbmRvdy5sb2NhdGlvblxuICBsb2MgPSBsb2MgfHwgZ2xvYmFsLmxvY2F0aW9uO1xuICBpZiAobnVsbCA9PSB1cmkpIHVyaSA9IGxvYy5wcm90b2NvbCArICcvLycgKyBsb2MuaG9zdDtcblxuICAvLyByZWxhdGl2ZSBwYXRoIHN1cHBvcnRcbiAgaWYgKCdzdHJpbmcnID09PSB0eXBlb2YgdXJpKSB7XG4gICAgaWYgKCcvJyA9PT0gdXJpLmNoYXJBdCgwKSkge1xuICAgICAgaWYgKCcvJyA9PT0gdXJpLmNoYXJBdCgxKSkge1xuICAgICAgICB1cmkgPSBsb2MucHJvdG9jb2wgKyB1cmk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cmkgPSBsb2MuaG9zdCArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIS9eKGh0dHBzP3x3c3M/KTpcXC9cXC8vLnRlc3QodXJpKSkge1xuICAgICAgZGVidWcoJ3Byb3RvY29sLWxlc3MgdXJsICVzJywgdXJpKTtcbiAgICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGxvYykge1xuICAgICAgICB1cmkgPSBsb2MucHJvdG9jb2wgKyAnLy8nICsgdXJpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdXJpID0gJ2h0dHBzOi8vJyArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBwYXJzZVxuICAgIGRlYnVnKCdwYXJzZSAlcycsIHVyaSk7XG4gICAgb2JqID0gcGFyc2V1cmkodXJpKTtcbiAgfVxuXG4gIC8vIG1ha2Ugc3VyZSB3ZSB0cmVhdCBgbG9jYWxob3N0OjgwYCBhbmQgYGxvY2FsaG9zdGAgZXF1YWxseVxuICBpZiAoIW9iai5wb3J0KSB7XG4gICAgaWYgKC9eKGh0dHB8d3MpJC8udGVzdChvYmoucHJvdG9jb2wpKSB7XG4gICAgICBvYmoucG9ydCA9ICc4MCc7XG4gICAgfSBlbHNlIGlmICgvXihodHRwfHdzKXMkLy50ZXN0KG9iai5wcm90b2NvbCkpIHtcbiAgICAgIG9iai5wb3J0ID0gJzQ0Myc7XG4gICAgfVxuICB9XG5cbiAgb2JqLnBhdGggPSBvYmoucGF0aCB8fCAnLyc7XG5cbiAgdmFyIGlwdjYgPSBvYmouaG9zdC5pbmRleE9mKCc6JykgIT09IC0xO1xuICB2YXIgaG9zdCA9IGlwdjYgPyAnWycgKyBvYmouaG9zdCArICddJyA6IG9iai5ob3N0O1xuXG4gIC8vIGRlZmluZSB1bmlxdWUgaWRcbiAgb2JqLmlkID0gb2JqLnByb3RvY29sICsgJzovLycgKyBob3N0ICsgJzonICsgb2JqLnBvcnQ7XG4gIC8vIGRlZmluZSBocmVmXG4gIG9iai5ocmVmID0gb2JqLnByb3RvY29sICsgJzovLycgKyBob3N0ICsgKGxvYyAmJiBsb2MucG9ydCA9PT0gb2JqLnBvcnQgPyAnJyA6ICgnOicgKyBvYmoucG9ydCkpO1xuXG4gIHJldHVybiBvYmo7XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///780f\n")},"7d91":function(module,exports){eval("\n/**\n * Gets the keys for an object.\n *\n * @return {Array} keys\n * @api private\n */\n\nmodule.exports = Object.keys || function keys (obj){\n  var arr = [];\n  var has = Object.prototype.hasOwnProperty;\n\n  for (var i in obj) {\n    if (has.call(obj, i)) {\n      arr.push(i);\n    }\n  }\n  return arr;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2Q5MS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIva2V5cy5qcz83NTljIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBHZXRzIHRoZSBrZXlzIGZvciBhbiBvYmplY3QuXG4gKlxuICogQHJldHVybiB7QXJyYXl9IGtleXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ga2V5cyAob2JqKXtcbiAgdmFyIGFyciA9IFtdO1xuICB2YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGkpKSB7XG4gICAgICBhcnIucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycjtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7d91\n")},"7fa4":function(module,exports,__webpack_require__){eval('var Collection = __webpack_require__(/*! ampersand-collection */ "7bd3");\nvar Filter = __webpack_require__(/*! ../filter */ "9476");\n\nmodule.exports = Collection.extend({\n  mainIndex: \'id\',\n  model: Filter,\n  comparator: function (a, b) {\n    if (a.row > b.row || a.row === b.row && a.col > b.col) {\n      return 1;\n    }\n    if (a.col === b.col) {\n      return 0;\n    }\n    return -1;\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiN2ZhNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmlsdGVyL2NvbGxlY3Rpb24uanM/ODgyYyJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgRmlsdGVyID0gcmVxdWlyZSgnLi4vZmlsdGVyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtYWluSW5kZXg6ICdpZCcsXG4gIG1vZGVsOiBGaWx0ZXIsXG4gIGNvbXBhcmF0b3I6IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgaWYgKGEucm93ID4gYi5yb3cgfHwgYS5yb3cgPT09IGIucm93ICYmIGEuY29sID4gYi5jb2wpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICBpZiAoYS5jb2wgPT09IGIuY29sKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///7fa4\n')},8191:function(module,exports,__webpack_require__){eval("/**\n * Partition\n *\n * Describes a partitioning of the data, based on the values a Facet can take.\n *\n * @class Partition\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Groups = __webpack_require__(/*! ./partition/group-collection */ \"0056\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar selection = __webpack_require__(/*! ./util/selection */ \"1278\");\nvar util = __webpack_require__(/*! ./util/time */ \"d45b\");\n\n/*\n * @param {Partition} partition\n * @param {Group[]} groups\n * @memberof! Partition\n */\nfunction setDatetimeGroups (partition, groups) {\n  var timeStart = partition.minval;\n  var timeEnd = partition.maxval;\n  var timeRes = util.getDatetimeResolution(timeStart, timeEnd);\n  var timeZone = partition.zone;\n\n  var current = moment(timeStart);\n  while ((!current.isAfter(timeEnd)) && groups.length < 500) {\n    groups.add({\n      min: moment(current).tz(timeZone).startOf(timeRes),\n      max: moment(current).tz(timeZone).endOf(timeRes),\n      value: moment(current).tz(timeZone).startOf(timeRes).format(),\n      label: moment(current).tz(timeZone).startOf(timeRes).format()\n    });\n    current.add(1, timeRes);\n  }\n}\n\n/*\n * @param {Partition} partition\n * @param {Group[]} groups\n * @memberof! Partition\n */\nfunction setDurationGroups (partition, groups) {\n  var dStart = partition.minval;\n  var dEnd = partition.maxval;\n  var dRes = util.getDurationResolution(dStart, dEnd);\n\n  var current = Math.floor(parseFloat(dStart.as(dRes)));\n  var last = Math.floor(parseFloat(dEnd.as(dRes)));\n\n  while (current < last) {\n    groups.add({\n      min: moment.duration(current, dRes),\n      max: moment.duration(current + 1, dRes),\n      value: moment.duration(current, dRes).toISOString(),\n      label: moment.duration(current, dRes).toISOString()\n    });\n\n    current = current + 1;\n  }\n}\n\n/*\n * Setup a grouping based on the `partition.groupingContinuous`, `partition.minval`,\n * `partition.maxval`, and the `partition.groupingParam`.\n * @memberof! Partition\n * @param {Partition} partition\n * @param {Group[]} groups\n */\nfunction setContinuousGroups (partition, groups) {\n  var param = partition.groupingParam;\n  var x0, x1, size, nbins;\n\n  if (partition.groupFixedN) {\n    // A fixed number of equally sized bins\n    nbins = param;\n    x0 = partition.minval;\n    x1 = partition.maxval;\n    size = (x1 - x0) / nbins;\n  } else if (partition.groupFixedS) {\n    // A fixed bin size\n    size = param;\n    x0 = Math.floor(partition.minval / size) * size;\n    x1 = Math.ceil(partition.maxval / size) * size;\n    nbins = (x1 - x0) / size;\n  } else if (partition.groupFixedSC) {\n    // A fixed bin size, centered on 0\n    size = param;\n    x0 = (Math.floor(partition.minval / size) - 0.5) * size;\n    x1 = (Math.ceil(partition.maxval / size) + 0.5) * size;\n    nbins = (x1 - x0) / size;\n  } else if (partition.groupLog) {\n    // Fixed number of logarithmically (base 10) sized bins\n    nbins = param;\n    x0 = Math.log(partition.minval) / Math.log(10.0);\n    x1 = Math.log(partition.maxval) / Math.log(10.0);\n    size = (x1 - x0) / nbins;\n  }\n\n  function unlog (x) {\n    return Math.exp(x * Math.log(10));\n  }\n\n  var i;\n  for (i = 0; i < nbins; i++) {\n    var start = x0 + i * size;\n    var end = x0 + (i + 1) * size;\n    var mid = 0.5 * (start + end);\n\n    if (partition.groupLog) {\n      groups.add({\n        min: unlog(start),\n        max: unlog(end),\n        value: unlog(start),\n        label: unlog(end).toPrecision(5)\n      });\n    } else {\n      groups.add({\n        min: start,\n        max: end,\n        value: mid,\n        label: mid.toPrecision(5)\n      });\n    }\n  }\n}\n\n/*\n * Setup a grouping based on the `partition.categorialTransform`\n * @memberof! Partition\n * @param {Partition} partition\n * @param {Group[]} groups\n */\nfunction setCategorialGroups (partition, groups) {\n  // dataview -> filters -> filter -> partitions -> partition\n  //          -> facets\n\n  var dataview;\n  var facet;\n  try {\n    dataview = partition.collection.parent.collection.parent;\n    facet = dataview.facets.get(partition.facetName, 'name');\n  } catch (e) {\n    console.error('setCategorialGroups: cannot locate facet for this partition');\n    return;\n  }\n\n  if (facet.isCategorial) {\n    // default: a categorial facet, with a categorial parittion\n    facet.categorialTransform.rules.forEach(function (rule, i) {\n      groups.add({\n        value: rule.group,\n        label: rule.group,\n        count: rule.count\n      });\n    });\n  } else if (facet.isDatetime) {\n    var format = facet.datetimeTransform.transformedFormat;\n    var timePart = util.timeParts.get(format, 'description');\n\n    timePart.groups.forEach(function (g, i) {\n      groups.add({\n        value: g,\n        label: g,\n        count: 0\n      });\n    });\n  } else {\n    console.warn('Not implemented');\n  }\n}\n\n/**\n * Reset type, minimum and maximum values\n * @params {Partition} partition\n * @params {Object} Options - silent do not trigger change events\n * @memberof! Partition\n */\nfunction reset (options) {\n  var partition = this;\n  // partition -> partitions -> filter -> filters -> dataview\n  var filter = partition.collection.parent;\n  var dataview = filter.collection.parent;\n  var facet = dataview.facets.get(partition.facetName, 'name');\n  options = options || {};\n\n  partition.set({\n    type: facet.transform.transformedType,\n    minval: facet.transform.transformedMin,\n    maxval: facet.transform.transformedMax\n  }, options);\n}\n\nmodule.exports = BaseModel.extend({\n  dataTypes: {\n    'numberDatetimeOrDuration': {\n      set: function (value) {\n        var newValue;\n\n        // check for momentjs objects\n        if (moment.isDuration(value)) {\n          return {\n            val: moment.duration(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (moment.isMoment(value)) {\n          return {\n            val: value.clone(),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to create momentjs objects\n        newValue = moment(value, moment.ISO_8601);\n        if (newValue.isValid()) {\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          newValue = moment.duration(value);\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to set a number\n        if (value === +value) {\n          return {\n            val: +value,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // failed..\n        return {\n          val: value,\n          type: typeof value\n        };\n      },\n      compare: function (currentVal, newVal) {\n        if (currentVal instanceof moment) {\n          return currentVal.isSame(newVal);\n        } else {\n          return +currentVal === +newVal;\n        }\n      }\n    }\n  },\n  props: {\n    /**\n     * Label for displaying on plots\n     * @memberof! Partition\n     * @type {string}\n     */\n    label: {\n      type: 'string',\n      required: true,\n      default: ''\n    },\n    /**\n     * Show a legend for this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    showLegend: {\n      type: 'boolean',\n      required: false,\n      default: true\n    },\n    /**\n     * Show an axis label for this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    showLabel: {\n      type: 'boolean',\n      required: false,\n      default: true\n    },\n\n    /**\n     * Timezone for partitioning\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    zone: {\n      type: 'string',\n      required: 'true',\n      default: function () {\n        return moment.tz.guess();\n      }\n    },\n\n    /**\n     * Type of this partition\n     * @memberof! Partition\n     * @type {string}\n     */\n    type: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['constant', 'continuous', 'categorial', 'datetime', 'duration', 'text']\n    },\n\n    /**\n     * The name of the facet to partition over\n     * @memberof! Partition\n     * @type {string}\n     */\n    facetName: 'string',\n\n    /**\n     * When part of a partitioning, this deterimines the ordering\n     * @memberof! Partition\n     * @type {number}\n     */\n    rank: {\n      type: 'number',\n      required: true\n    },\n\n    /**\n     * For categorial and text Facets, the ordering can be alfabetical or by count\n     * @memberof! Partition\n     */\n    ordering: {\n      type: 'string',\n      values: ['count', 'value'],\n      required: true,\n      default: 'value'\n    },\n\n    /**\n     * For continuous or datetime Facets, the minimum value. Values lower than this are grouped to 'missing'\n     * @memberof! Partition\n     * @type {number|moment}\n     */\n    minval: 'numberDatetimeOrDuration',\n\n    /**\n     * For continuous or datetime Facets, the maximum value. Values higher than this are grouped to 'missing'\n     * @memberof! Partition\n     * @type {number|moment}\n     */\n    maxval: 'numberDatetimeOrDuration',\n\n    /**\n     * Extra parameter used in the grouping strategy: either the number of bins, or the bin size.\n     * @memberof! Partition\n     * @type {number}\n     */\n    groupingParam: ['number', true, 20],\n\n    /**\n     * Grouping strategy:\n     *  * `fixedn`  fixed number of bins in the interval [minval, maxval]\n     *  * `fixedsc` a fixed binsize, centered on zero\n     *  * `fixeds`  a fixed binsize, starting at zero\n     *  * `log`     fixed number of bins but on a logarithmic scale\n     * Don't use directly but check grouping via the groupFixedN, groupFixedSC,\n     * groupFixedS, and groupLog properties\n     * @memberof! Partition\n     * @type {number}\n     */\n    groupingContinuous: {\n      type: 'string',\n      required: true,\n      default: 'fixedn',\n      values: ['fixedn', 'fixedsc', 'fixeds', 'log']\n    },\n\n    /**\n     * Depending on the type of partition, this can be an array of the selected groups,\n     * or a numberic interval [start, end]\n     * @memberof! Partition\n     * @type {array}\n     */\n    // NOTE: for categorial facets, contains rule.group\n    selected: {\n      type: 'array',\n      required: true,\n      default: function () {\n        return [];\n      }\n    }\n  },\n  derived: {\n    // properties for: type\n    isConstant: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'constant';\n      }\n    },\n    isContinuous: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'continuous';\n      }\n    },\n    isCategorial: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'categorial';\n      }\n    },\n    isDatetime: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'datetime';\n      }\n    },\n    isDuration: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'duration';\n      }\n    },\n    isText: {\n      deps: ['type'],\n      fn: function () {\n        return this.type === 'text';\n      }\n    },\n    // properties for grouping-continuous\n    groupFixedN: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixedn';\n      }\n    },\n    groupFixedSC: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixedsc';\n      }\n    },\n    groupFixedS: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'fixeds';\n      }\n    },\n    groupLog: {\n      deps: ['groupingContinuous'],\n      fn: function () {\n        return this.groupingContinuous === 'log';\n      }\n    },\n    /**\n     * The (ordered) set of groups this Partition can take, making up this partition.\n     * The list is recalculated when any of the partition's properties change:\n     * 'groupingContinuous', 'groupingParam', 'minval', 'maxval', 'type', 'zone' change\n     * The list keeps itself sorted according to the partition.ordering\n     *\n     * Can be used for plotting etc.\n     * @memberof! Partition\n     * @type {Group[]}\n     */\n    groups: {\n      deps: ['groupingContinuous', 'groupingParam', 'minval', 'maxval', 'type', 'zone'],\n      fn: function () {\n        var partition = this;\n        var groups = new Groups([], {\n          parent: partition\n        });\n\n        if (partition.isCategorial) {\n          setCategorialGroups(partition, groups);\n        } else if (partition.isContinuous) {\n          setContinuousGroups(partition, groups);\n        } else if (partition.isDatetime) {\n          setDatetimeGroups(partition, groups);\n        } else if (partition.isDuration) {\n          setDurationGroups(partition, groups);\n        } else if (partition.isText) {\n          // no-op\n        } else {\n          console.error('Cannot set groups for partition', partition.getId());\n        }\n\n        return groups;\n      }\n    }\n  },\n  updateSelection: function (group) {\n    selection.updateSelection(this, group);\n  },\n  filterFunction: function () {\n    return selection.filterFunction(this);\n  },\n  reset: reset\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODE5MS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uLmpzPzUzODciXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQYXJ0aXRpb25cbiAqXG4gKiBEZXNjcmliZXMgYSBwYXJ0aXRpb25pbmcgb2YgdGhlIGRhdGEsIGJhc2VkIG9uIHRoZSB2YWx1ZXMgYSBGYWNldCBjYW4gdGFrZS5cbiAqXG4gKiBAY2xhc3MgUGFydGl0aW9uXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbnZhciBCYXNlTW9kZWwgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIEdyb3VwcyA9IHJlcXVpcmUoJy4vcGFydGl0aW9uL2dyb3VwLWNvbGxlY3Rpb24nKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciBzZWxlY3Rpb24gPSByZXF1aXJlKCcuL3V0aWwvc2VsZWN0aW9uJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbC90aW1lJyk7XG5cbi8qXG4gKiBAcGFyYW0ge1BhcnRpdGlvbn0gcGFydGl0aW9uXG4gKiBAcGFyYW0ge0dyb3VwW119IGdyb3Vwc1xuICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAqL1xuZnVuY3Rpb24gc2V0RGF0ZXRpbWVHcm91cHMgKHBhcnRpdGlvbiwgZ3JvdXBzKSB7XG4gIHZhciB0aW1lU3RhcnQgPSBwYXJ0aXRpb24ubWludmFsO1xuICB2YXIgdGltZUVuZCA9IHBhcnRpdGlvbi5tYXh2YWw7XG4gIHZhciB0aW1lUmVzID0gdXRpbC5nZXREYXRldGltZVJlc29sdXRpb24odGltZVN0YXJ0LCB0aW1lRW5kKTtcbiAgdmFyIHRpbWVab25lID0gcGFydGl0aW9uLnpvbmU7XG5cbiAgdmFyIGN1cnJlbnQgPSBtb21lbnQodGltZVN0YXJ0KTtcbiAgd2hpbGUgKCghY3VycmVudC5pc0FmdGVyKHRpbWVFbmQpKSAmJiBncm91cHMubGVuZ3RoIDwgNTAwKSB7XG4gICAgZ3JvdXBzLmFkZCh7XG4gICAgICBtaW46IG1vbWVudChjdXJyZW50KS50eih0aW1lWm9uZSkuc3RhcnRPZih0aW1lUmVzKSxcbiAgICAgIG1heDogbW9tZW50KGN1cnJlbnQpLnR6KHRpbWVab25lKS5lbmRPZih0aW1lUmVzKSxcbiAgICAgIHZhbHVlOiBtb21lbnQoY3VycmVudCkudHoodGltZVpvbmUpLnN0YXJ0T2YodGltZVJlcykuZm9ybWF0KCksXG4gICAgICBsYWJlbDogbW9tZW50KGN1cnJlbnQpLnR6KHRpbWVab25lKS5zdGFydE9mKHRpbWVSZXMpLmZvcm1hdCgpXG4gICAgfSk7XG4gICAgY3VycmVudC5hZGQoMSwgdGltZVJlcyk7XG4gIH1cbn1cblxuLypcbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7R3JvdXBbXX0gZ3JvdXBzXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICovXG5mdW5jdGlvbiBzZXREdXJhdGlvbkdyb3VwcyAocGFydGl0aW9uLCBncm91cHMpIHtcbiAgdmFyIGRTdGFydCA9IHBhcnRpdGlvbi5taW52YWw7XG4gIHZhciBkRW5kID0gcGFydGl0aW9uLm1heHZhbDtcbiAgdmFyIGRSZXMgPSB1dGlsLmdldER1cmF0aW9uUmVzb2x1dGlvbihkU3RhcnQsIGRFbmQpO1xuXG4gIHZhciBjdXJyZW50ID0gTWF0aC5mbG9vcihwYXJzZUZsb2F0KGRTdGFydC5hcyhkUmVzKSkpO1xuICB2YXIgbGFzdCA9IE1hdGguZmxvb3IocGFyc2VGbG9hdChkRW5kLmFzKGRSZXMpKSk7XG5cbiAgd2hpbGUgKGN1cnJlbnQgPCBsYXN0KSB7XG4gICAgZ3JvdXBzLmFkZCh7XG4gICAgICBtaW46IG1vbWVudC5kdXJhdGlvbihjdXJyZW50LCBkUmVzKSxcbiAgICAgIG1heDogbW9tZW50LmR1cmF0aW9uKGN1cnJlbnQgKyAxLCBkUmVzKSxcbiAgICAgIHZhbHVlOiBtb21lbnQuZHVyYXRpb24oY3VycmVudCwgZFJlcykudG9JU09TdHJpbmcoKSxcbiAgICAgIGxhYmVsOiBtb21lbnQuZHVyYXRpb24oY3VycmVudCwgZFJlcykudG9JU09TdHJpbmcoKVxuICAgIH0pO1xuXG4gICAgY3VycmVudCA9IGN1cnJlbnQgKyAxO1xuICB9XG59XG5cbi8qXG4gKiBTZXR1cCBhIGdyb3VwaW5nIGJhc2VkIG9uIHRoZSBgcGFydGl0aW9uLmdyb3VwaW5nQ29udGludW91c2AsIGBwYXJ0aXRpb24ubWludmFsYCxcbiAqIGBwYXJ0aXRpb24ubWF4dmFsYCwgYW5kIHRoZSBgcGFydGl0aW9uLmdyb3VwaW5nUGFyYW1gLlxuICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7R3JvdXBbXX0gZ3JvdXBzXG4gKi9cbmZ1bmN0aW9uIHNldENvbnRpbnVvdXNHcm91cHMgKHBhcnRpdGlvbiwgZ3JvdXBzKSB7XG4gIHZhciBwYXJhbSA9IHBhcnRpdGlvbi5ncm91cGluZ1BhcmFtO1xuICB2YXIgeDAsIHgxLCBzaXplLCBuYmlucztcblxuICBpZiAocGFydGl0aW9uLmdyb3VwRml4ZWROKSB7XG4gICAgLy8gQSBmaXhlZCBudW1iZXIgb2YgZXF1YWxseSBzaXplZCBiaW5zXG4gICAgbmJpbnMgPSBwYXJhbTtcbiAgICB4MCA9IHBhcnRpdGlvbi5taW52YWw7XG4gICAgeDEgPSBwYXJ0aXRpb24ubWF4dmFsO1xuICAgIHNpemUgPSAoeDEgLSB4MCkgLyBuYmlucztcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uZ3JvdXBGaXhlZFMpIHtcbiAgICAvLyBBIGZpeGVkIGJpbiBzaXplXG4gICAgc2l6ZSA9IHBhcmFtO1xuICAgIHgwID0gTWF0aC5mbG9vcihwYXJ0aXRpb24ubWludmFsIC8gc2l6ZSkgKiBzaXplO1xuICAgIHgxID0gTWF0aC5jZWlsKHBhcnRpdGlvbi5tYXh2YWwgLyBzaXplKSAqIHNpemU7XG4gICAgbmJpbnMgPSAoeDEgLSB4MCkgLyBzaXplO1xuICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5ncm91cEZpeGVkU0MpIHtcbiAgICAvLyBBIGZpeGVkIGJpbiBzaXplLCBjZW50ZXJlZCBvbiAwXG4gICAgc2l6ZSA9IHBhcmFtO1xuICAgIHgwID0gKE1hdGguZmxvb3IocGFydGl0aW9uLm1pbnZhbCAvIHNpemUpIC0gMC41KSAqIHNpemU7XG4gICAgeDEgPSAoTWF0aC5jZWlsKHBhcnRpdGlvbi5tYXh2YWwgLyBzaXplKSArIDAuNSkgKiBzaXplO1xuICAgIG5iaW5zID0gKHgxIC0geDApIC8gc2l6ZTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAvLyBGaXhlZCBudW1iZXIgb2YgbG9nYXJpdGhtaWNhbGx5IChiYXNlIDEwKSBzaXplZCBiaW5zXG4gICAgbmJpbnMgPSBwYXJhbTtcbiAgICB4MCA9IE1hdGgubG9nKHBhcnRpdGlvbi5taW52YWwpIC8gTWF0aC5sb2coMTAuMCk7XG4gICAgeDEgPSBNYXRoLmxvZyhwYXJ0aXRpb24ubWF4dmFsKSAvIE1hdGgubG9nKDEwLjApO1xuICAgIHNpemUgPSAoeDEgLSB4MCkgLyBuYmlucztcbiAgfVxuXG4gIGZ1bmN0aW9uIHVubG9nICh4KSB7XG4gICAgcmV0dXJuIE1hdGguZXhwKHggKiBNYXRoLmxvZygxMCkpO1xuICB9XG5cbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBuYmluczsgaSsrKSB7XG4gICAgdmFyIHN0YXJ0ID0geDAgKyBpICogc2l6ZTtcbiAgICB2YXIgZW5kID0geDAgKyAoaSArIDEpICogc2l6ZTtcbiAgICB2YXIgbWlkID0gMC41ICogKHN0YXJ0ICsgZW5kKTtcblxuICAgIGlmIChwYXJ0aXRpb24uZ3JvdXBMb2cpIHtcbiAgICAgIGdyb3Vwcy5hZGQoe1xuICAgICAgICBtaW46IHVubG9nKHN0YXJ0KSxcbiAgICAgICAgbWF4OiB1bmxvZyhlbmQpLFxuICAgICAgICB2YWx1ZTogdW5sb2coc3RhcnQpLFxuICAgICAgICBsYWJlbDogdW5sb2coZW5kKS50b1ByZWNpc2lvbig1KVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdyb3Vwcy5hZGQoe1xuICAgICAgICBtaW46IHN0YXJ0LFxuICAgICAgICBtYXg6IGVuZCxcbiAgICAgICAgdmFsdWU6IG1pZCxcbiAgICAgICAgbGFiZWw6IG1pZC50b1ByZWNpc2lvbig1KVxuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qXG4gKiBTZXR1cCBhIGdyb3VwaW5nIGJhc2VkIG9uIHRoZSBgcGFydGl0aW9uLmNhdGVnb3JpYWxUcmFuc2Zvcm1gXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICogQHBhcmFtIHtQYXJ0aXRpb259IHBhcnRpdGlvblxuICogQHBhcmFtIHtHcm91cFtdfSBncm91cHNcbiAqL1xuZnVuY3Rpb24gc2V0Q2F0ZWdvcmlhbEdyb3VwcyAocGFydGl0aW9uLCBncm91cHMpIHtcbiAgLy8gZGF0YXZpZXcgLT4gZmlsdGVycyAtPiBmaWx0ZXIgLT4gcGFydGl0aW9ucyAtPiBwYXJ0aXRpb25cbiAgLy8gICAgICAgICAgLT4gZmFjZXRzXG5cbiAgdmFyIGRhdGF2aWV3O1xuICB2YXIgZmFjZXQ7XG4gIHRyeSB7XG4gICAgZGF0YXZpZXcgPSBwYXJ0aXRpb24uY29sbGVjdGlvbi5wYXJlbnQuY29sbGVjdGlvbi5wYXJlbnQ7XG4gICAgZmFjZXQgPSBkYXRhdmlldy5mYWNldHMuZ2V0KHBhcnRpdGlvbi5mYWNldE5hbWUsICduYW1lJyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKCdzZXRDYXRlZ29yaWFsR3JvdXBzOiBjYW5ub3QgbG9jYXRlIGZhY2V0IGZvciB0aGlzIHBhcnRpdGlvbicpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmYWNldC5pc0NhdGVnb3JpYWwpIHtcbiAgICAvLyBkZWZhdWx0OiBhIGNhdGVnb3JpYWwgZmFjZXQsIHdpdGggYSBjYXRlZ29yaWFsIHBhcml0dGlvblxuICAgIGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0ucnVsZXMuZm9yRWFjaChmdW5jdGlvbiAocnVsZSwgaSkge1xuICAgICAgZ3JvdXBzLmFkZCh7XG4gICAgICAgIHZhbHVlOiBydWxlLmdyb3VwLFxuICAgICAgICBsYWJlbDogcnVsZS5ncm91cCxcbiAgICAgICAgY291bnQ6IHJ1bGUuY291bnRcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKGZhY2V0LmlzRGF0ZXRpbWUpIHtcbiAgICB2YXIgZm9ybWF0ID0gZmFjZXQuZGF0ZXRpbWVUcmFuc2Zvcm0udHJhbnNmb3JtZWRGb3JtYXQ7XG4gICAgdmFyIHRpbWVQYXJ0ID0gdXRpbC50aW1lUGFydHMuZ2V0KGZvcm1hdCwgJ2Rlc2NyaXB0aW9uJyk7XG5cbiAgICB0aW1lUGFydC5ncm91cHMuZm9yRWFjaChmdW5jdGlvbiAoZywgaSkge1xuICAgICAgZ3JvdXBzLmFkZCh7XG4gICAgICAgIHZhbHVlOiBnLFxuICAgICAgICBsYWJlbDogZyxcbiAgICAgICAgY291bnQ6IDBcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUud2FybignTm90IGltcGxlbWVudGVkJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNldCB0eXBlLCBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlc1xuICogQHBhcmFtcyB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEBwYXJhbXMge09iamVjdH0gT3B0aW9ucyAtIHNpbGVudCBkbyBub3QgdHJpZ2dlciBjaGFuZ2UgZXZlbnRzXG4gKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICovXG5mdW5jdGlvbiByZXNldCAob3B0aW9ucykge1xuICB2YXIgcGFydGl0aW9uID0gdGhpcztcbiAgLy8gcGFydGl0aW9uIC0+IHBhcnRpdGlvbnMgLT4gZmlsdGVyIC0+IGZpbHRlcnMgLT4gZGF0YXZpZXdcbiAgdmFyIGZpbHRlciA9IHBhcnRpdGlvbi5jb2xsZWN0aW9uLnBhcmVudDtcbiAgdmFyIGRhdGF2aWV3ID0gZmlsdGVyLmNvbGxlY3Rpb24ucGFyZW50O1xuICB2YXIgZmFjZXQgPSBkYXRhdmlldy5mYWNldHMuZ2V0KHBhcnRpdGlvbi5mYWNldE5hbWUsICduYW1lJyk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHBhcnRpdGlvbi5zZXQoe1xuICAgIHR5cGU6IGZhY2V0LnRyYW5zZm9ybS50cmFuc2Zvcm1lZFR5cGUsXG4gICAgbWludmFsOiBmYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNaW4sXG4gICAgbWF4dmFsOiBmYWNldC50cmFuc2Zvcm0udHJhbnNmb3JtZWRNYXhcbiAgfSwgb3B0aW9ucyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIGRhdGFUeXBlczoge1xuICAgICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nOiB7XG4gICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIG1vbWVudGpzIG9iamVjdHNcbiAgICAgICAgaWYgKG1vbWVudC5pc0R1cmF0aW9uKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG1vbWVudC5kdXJhdGlvbih2YWx1ZSksXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vbWVudC5pc01vbWVudCh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsOiB2YWx1ZS5jbG9uZSgpLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIGNyZWF0ZSBtb21lbnRqcyBvYmplY3RzXG4gICAgICAgIG5ld1ZhbHVlID0gbW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICBpZiAobmV3VmFsdWUuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbDogbmV3VmFsdWUsXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSB7XG4gICAgICAgICAgbmV3VmFsdWUgPSBtb21lbnQuZHVyYXRpb24odmFsdWUpO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG5ld1ZhbHVlLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIHNldCBhIG51bWJlclxuICAgICAgICBpZiAodmFsdWUgPT09ICt2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6ICt2YWx1ZSxcbiAgICAgICAgICAgIHR5cGU6ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZhaWxlZC4uXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsOiB2YWx1ZSxcbiAgICAgICAgICB0eXBlOiB0eXBlb2YgdmFsdWVcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBjb21wYXJlOiBmdW5jdGlvbiAoY3VycmVudFZhbCwgbmV3VmFsKSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsIGluc3RhbmNlb2YgbW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuIGN1cnJlbnRWYWwuaXNTYW1lKG5ld1ZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICtjdXJyZW50VmFsID09PSArbmV3VmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIExhYmVsIGZvciBkaXNwbGF5aW5nIG9uIHBsb3RzXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGxhYmVsOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJydcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFNob3cgYSBsZWdlbmQgZm9yIHRoaXMgcGFydGl0aW9uXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHNob3dMZWdlbmQ6IHtcbiAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgIGRlZmF1bHQ6IHRydWVcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFNob3cgYW4gYXhpcyBsYWJlbCBmb3IgdGhpcyBwYXJ0aXRpb25cbiAgICAgKiBAbWVtYmVyb2YhIFBhcnRpdGlvblxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgc2hvd0xhYmVsOiB7XG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICBkZWZhdWx0OiB0cnVlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRpbWV6b25lIGZvciBwYXJ0aXRpb25pbmdcbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB6b25lOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiAndHJ1ZScsXG4gICAgICBkZWZhdWx0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiB0aGlzIHBhcnRpdGlvblxuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0eXBlOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ2NhdGVnb3JpYWwnLFxuICAgICAgdmFsdWVzOiBbJ2NvbnN0YW50JywgJ2NvbnRpbnVvdXMnLCAnY2F0ZWdvcmlhbCcsICdkYXRldGltZScsICdkdXJhdGlvbicsICd0ZXh0J11cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGZhY2V0IHRvIHBhcnRpdGlvbiBvdmVyXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZhY2V0TmFtZTogJ3N0cmluZycsXG5cbiAgICAvKipcbiAgICAgKiBXaGVuIHBhcnQgb2YgYSBwYXJ0aXRpb25pbmcsIHRoaXMgZGV0ZXJpbWluZXMgdGhlIG9yZGVyaW5nXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHJhbms6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNhdGVnb3JpYWwgYW5kIHRleHQgRmFjZXRzLCB0aGUgb3JkZXJpbmcgY2FuIGJlIGFsZmFiZXRpY2FsIG9yIGJ5IGNvdW50XG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKi9cbiAgICBvcmRlcmluZzoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICB2YWx1ZXM6IFsnY291bnQnLCAndmFsdWUnXSxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ3ZhbHVlJ1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBGb3IgY29udGludW91cyBvciBkYXRldGltZSBGYWNldHMsIHRoZSBtaW5pbXVtIHZhbHVlLiBWYWx1ZXMgbG93ZXIgdGhhbiB0aGlzIGFyZSBncm91cGVkIHRvICdtaXNzaW5nJ1xuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICovXG4gICAgbWludmFsOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJyxcblxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIG9yIGRhdGV0aW1lIEZhY2V0cywgdGhlIG1heGltdW0gdmFsdWUuIFZhbHVlcyBoaWdoZXIgdGhhbiB0aGlzIGFyZSBncm91cGVkIHRvICdtaXNzaW5nJ1xuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICovXG4gICAgbWF4dmFsOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJyxcblxuICAgIC8qKlxuICAgICAqIEV4dHJhIHBhcmFtZXRlciB1c2VkIGluIHRoZSBncm91cGluZyBzdHJhdGVneTogZWl0aGVyIHRoZSBudW1iZXIgb2YgYmlucywgb3IgdGhlIGJpbiBzaXplLlxuICAgICAqIEBtZW1iZXJvZiEgUGFydGl0aW9uXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBncm91cGluZ1BhcmFtOiBbJ251bWJlcicsIHRydWUsIDIwXSxcblxuICAgIC8qKlxuICAgICAqIEdyb3VwaW5nIHN0cmF0ZWd5OlxuICAgICAqICAqIGBmaXhlZG5gICBmaXhlZCBudW1iZXIgb2YgYmlucyBpbiB0aGUgaW50ZXJ2YWwgW21pbnZhbCwgbWF4dmFsXVxuICAgICAqICAqIGBmaXhlZHNjYCBhIGZpeGVkIGJpbnNpemUsIGNlbnRlcmVkIG9uIHplcm9cbiAgICAgKiAgKiBgZml4ZWRzYCAgYSBmaXhlZCBiaW5zaXplLCBzdGFydGluZyBhdCB6ZXJvXG4gICAgICogICogYGxvZ2AgICAgIGZpeGVkIG51bWJlciBvZiBiaW5zIGJ1dCBvbiBhIGxvZ2FyaXRobWljIHNjYWxlXG4gICAgICogRG9uJ3QgdXNlIGRpcmVjdGx5IGJ1dCBjaGVjayBncm91cGluZyB2aWEgdGhlIGdyb3VwRml4ZWROLCBncm91cEZpeGVkU0MsXG4gICAgICogZ3JvdXBGaXhlZFMsIGFuZCBncm91cExvZyBwcm9wZXJ0aWVzXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdyb3VwaW5nQ29udGludW91czoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICdmaXhlZG4nLFxuICAgICAgdmFsdWVzOiBbJ2ZpeGVkbicsICdmaXhlZHNjJywgJ2ZpeGVkcycsICdsb2cnXVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBEZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgcGFydGl0aW9uLCB0aGlzIGNhbiBiZSBhbiBhcnJheSBvZiB0aGUgc2VsZWN0ZWQgZ3JvdXBzLFxuICAgICAqIG9yIGEgbnVtYmVyaWMgaW50ZXJ2YWwgW3N0YXJ0LCBlbmRdXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7YXJyYXl9XG4gICAgICovXG4gICAgLy8gTk9URTogZm9yIGNhdGVnb3JpYWwgZmFjZXRzLCBjb250YWlucyBydWxlLmdyb3VwXG4gICAgc2VsZWN0ZWQ6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgZGVyaXZlZDoge1xuICAgIC8vIHByb3BlcnRpZXMgZm9yOiB0eXBlXG4gICAgaXNDb25zdGFudDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAnY29uc3RhbnQnO1xuICAgICAgfVxuICAgIH0sXG4gICAgaXNDb250aW51b3VzOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdjb250aW51b3VzJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGlzQ2F0ZWdvcmlhbDoge1xuICAgICAgZGVwczogWyd0eXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAnY2F0ZWdvcmlhbCc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0RhdGV0aW1lOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdkYXRldGltZSc7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc0R1cmF0aW9uOiB7XG4gICAgICBkZXBzOiBbJ3R5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdkdXJhdGlvbic7XG4gICAgICB9XG4gICAgfSxcbiAgICBpc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gJ3RleHQnO1xuICAgICAgfVxuICAgIH0sXG4gICAgLy8gcHJvcGVydGllcyBmb3IgZ3JvdXBpbmctY29udGludW91c1xuICAgIGdyb3VwRml4ZWROOiB7XG4gICAgICBkZXBzOiBbJ2dyb3VwaW5nQ29udGludW91cyddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JvdXBpbmdDb250aW51b3VzID09PSAnZml4ZWRuJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGdyb3VwRml4ZWRTQzoge1xuICAgICAgZGVwczogWydncm91cGluZ0NvbnRpbnVvdXMnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyb3VwaW5nQ29udGludW91cyA9PT0gJ2ZpeGVkc2MnO1xuICAgICAgfVxuICAgIH0sXG4gICAgZ3JvdXBGaXhlZFM6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cGluZ0NvbnRpbnVvdXMgPT09ICdmaXhlZHMnO1xuICAgICAgfVxuICAgIH0sXG4gICAgZ3JvdXBMb2c6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cGluZ0NvbnRpbnVvdXMgPT09ICdsb2cnO1xuICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIChvcmRlcmVkKSBzZXQgb2YgZ3JvdXBzIHRoaXMgUGFydGl0aW9uIGNhbiB0YWtlLCBtYWtpbmcgdXAgdGhpcyBwYXJ0aXRpb24uXG4gICAgICogVGhlIGxpc3QgaXMgcmVjYWxjdWxhdGVkIHdoZW4gYW55IG9mIHRoZSBwYXJ0aXRpb24ncyBwcm9wZXJ0aWVzIGNoYW5nZTpcbiAgICAgKiAnZ3JvdXBpbmdDb250aW51b3VzJywgJ2dyb3VwaW5nUGFyYW0nLCAnbWludmFsJywgJ21heHZhbCcsICd0eXBlJywgJ3pvbmUnIGNoYW5nZVxuICAgICAqIFRoZSBsaXN0IGtlZXBzIGl0c2VsZiBzb3J0ZWQgYWNjb3JkaW5nIHRvIHRoZSBwYXJ0aXRpb24ub3JkZXJpbmdcbiAgICAgKlxuICAgICAqIENhbiBiZSB1c2VkIGZvciBwbG90dGluZyBldGMuXG4gICAgICogQG1lbWJlcm9mISBQYXJ0aXRpb25cbiAgICAgKiBAdHlwZSB7R3JvdXBbXX1cbiAgICAgKi9cbiAgICBncm91cHM6IHtcbiAgICAgIGRlcHM6IFsnZ3JvdXBpbmdDb250aW51b3VzJywgJ2dyb3VwaW5nUGFyYW0nLCAnbWludmFsJywgJ21heHZhbCcsICd0eXBlJywgJ3pvbmUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwYXJ0aXRpb24gPSB0aGlzO1xuICAgICAgICB2YXIgZ3JvdXBzID0gbmV3IEdyb3VwcyhbXSwge1xuICAgICAgICAgIHBhcmVudDogcGFydGl0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChwYXJ0aXRpb24uaXNDYXRlZ29yaWFsKSB7XG4gICAgICAgICAgc2V0Q2F0ZWdvcmlhbEdyb3VwcyhwYXJ0aXRpb24sIGdyb3Vwcyk7XG4gICAgICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzQ29udGludW91cykge1xuICAgICAgICAgIHNldENvbnRpbnVvdXNHcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0RhdGV0aW1lKSB7XG4gICAgICAgICAgc2V0RGF0ZXRpbWVHcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0R1cmF0aW9uKSB7XG4gICAgICAgICAgc2V0RHVyYXRpb25Hcm91cHMocGFydGl0aW9uLCBncm91cHMpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc1RleHQpIHtcbiAgICAgICAgICAvLyBuby1vcFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Nhbm5vdCBzZXQgZ3JvdXBzIGZvciBwYXJ0aXRpb24nLCBwYXJ0aXRpb24uZ2V0SWQoKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ3JvdXBzO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgdXBkYXRlU2VsZWN0aW9uOiBmdW5jdGlvbiAoZ3JvdXApIHtcbiAgICBzZWxlY3Rpb24udXBkYXRlU2VsZWN0aW9uKHRoaXMsIGdyb3VwKTtcbiAgfSxcbiAgZmlsdGVyRnVuY3Rpb246IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gc2VsZWN0aW9uLmZpbHRlckZ1bmN0aW9uKHRoaXMpO1xuICB9LFxuICByZXNldDogcmVzZXRcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8191\n")},8233:function(module,exports,__webpack_require__){eval("\n/**\n * This is the web browser implementation of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = __webpack_require__(/*! ./debug */ \"bb16\");\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = 'undefined' != typeof chrome\n               && 'undefined' != typeof chrome.storage\n                  ? chrome.storage.local\n                  : localstorage();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n  'lightseagreen',\n  'forestgreen',\n  'goldenrod',\n  'dodgerblue',\n  'darkorchid',\n  'crimson'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\nfunction useColors() {\n  // is webkit? http://stackoverflow.com/a/16459606/376773\n  return ('WebkitAppearance' in document.documentElement.style) ||\n    // is firebug? http://stackoverflow.com/a/398120/376773\n    (window.console && (console.firebug || (console.exception && console.table))) ||\n    // is firefox >= v31?\n    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n    (navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31);\n}\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nexports.formatters.j = function(v) {\n  return JSON.stringify(v);\n};\n\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs() {\n  var args = arguments;\n  var useColors = this.useColors;\n\n  args[0] = (useColors ? '%c' : '')\n    + this.namespace\n    + (useColors ? ' %c' : ' ')\n    + args[0]\n    + (useColors ? '%c ' : ' ')\n    + '+' + exports.humanize(this.diff);\n\n  if (!useColors) return args;\n\n  var c = 'color: ' + this.color;\n  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));\n\n  // the final \"%c\" is somewhat tricky, because there could be other\n  // arguments passed either before or after the %c, so we need to\n  // figure out the correct index to insert the CSS into\n  var index = 0;\n  var lastC = 0;\n  args[0].replace(/%[a-z%]/g, function(match) {\n    if ('%%' === match) return;\n    index++;\n    if ('%c' === match) {\n      // we only are interested in the *last* %c\n      // (the user may have provided their own)\n      lastC = index;\n    }\n  });\n\n  args.splice(lastC, 0, c);\n  return args;\n}\n\n/**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\nfunction log() {\n  // this hackery is required for IE8/9, where\n  // the `console.log` function doesn't have 'apply'\n  return 'object' === typeof console\n    && console.log\n    && Function.prototype.apply.call(console.log, console, arguments);\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\nfunction save(namespaces) {\n  try {\n    if (null == namespaces) {\n      exports.storage.removeItem('debug');\n    } else {\n      exports.storage.debug = namespaces;\n    }\n  } catch(e) {}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n  var r;\n  try {\n    r = exports.storage.debug;\n  } catch(e) {}\n  return r;\n}\n\n/**\n * Enable namespaces listed in `localStorage.debug` initially.\n */\n\nexports.enable(load());\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage(){\n  try {\n    return window.localStorage;\n  } catch (e) {}\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODIzMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvZGVidWcvYnJvd3Nlci5qcz80ZDVhIl0sInNvdXJjZXNDb250ZW50IjpbIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSB3ZWIgYnJvd3NlciBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gKlxuICogRXhwb3NlIGBkZWJ1ZygpYCBhcyB0aGUgbW9kdWxlLlxuICovXG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZGVidWcnKTtcbmV4cG9ydHMubG9nID0gbG9nO1xuZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbmV4cG9ydHMuc2F2ZSA9IHNhdmU7XG5leHBvcnRzLmxvYWQgPSBsb2FkO1xuZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG5leHBvcnRzLnN0b3JhZ2UgPSAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lXG4gICAgICAgICAgICAgICAmJiAndW5kZWZpbmVkJyAhPSB0eXBlb2YgY2hyb21lLnN0b3JhZ2VcbiAgICAgICAgICAgICAgICAgID8gY2hyb21lLnN0b3JhZ2UubG9jYWxcbiAgICAgICAgICAgICAgICAgIDogbG9jYWxzdG9yYWdlKCk7XG5cbi8qKlxuICogQ29sb3JzLlxuICovXG5cbmV4cG9ydHMuY29sb3JzID0gW1xuICAnbGlnaHRzZWFncmVlbicsXG4gICdmb3Jlc3RncmVlbicsXG4gICdnb2xkZW5yb2QnLFxuICAnZG9kZ2VyYmx1ZScsXG4gICdkYXJrb3JjaGlkJyxcbiAgJ2NyaW1zb24nXG5dO1xuXG4vKipcbiAqIEN1cnJlbnRseSBvbmx5IFdlYktpdC1iYXNlZCBXZWIgSW5zcGVjdG9ycywgRmlyZWZveCA+PSB2MzEsXG4gKiBhbmQgdGhlIEZpcmVidWcgZXh0ZW5zaW9uIChhbnkgRmlyZWZveCB2ZXJzaW9uKSBhcmUga25vd25cbiAqIHRvIHN1cHBvcnQgXCIlY1wiIENTUyBjdXN0b21pemF0aW9ucy5cbiAqXG4gKiBUT0RPOiBhZGQgYSBgbG9jYWxTdG9yYWdlYCB2YXJpYWJsZSB0byBleHBsaWNpdGx5IGVuYWJsZS9kaXNhYmxlIGNvbG9yc1xuICovXG5cbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcbiAgLy8gaXMgd2Via2l0PyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNjQ1OTYwNi8zNzY3NzNcbiAgcmV0dXJuICgnV2Via2l0QXBwZWFyYW5jZScgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlKSB8fFxuICAgIC8vIGlzIGZpcmVidWc/IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM5ODEyMC8zNzY3NzNcbiAgICAod2luZG93LmNvbnNvbGUgJiYgKGNvbnNvbGUuZmlyZWJ1ZyB8fCAoY29uc29sZS5leGNlcHRpb24gJiYgY29uc29sZS50YWJsZSkpKSB8fFxuICAgIC8vIGlzIGZpcmVmb3ggPj0gdjMxP1xuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvVG9vbHMvV2ViX0NvbnNvbGUjU3R5bGluZ19tZXNzYWdlc1xuICAgIChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkubWF0Y2goL2ZpcmVmb3hcXC8oXFxkKykvKSAmJiBwYXJzZUludChSZWdFeHAuJDEsIDEwKSA+PSAzMSk7XG59XG5cbi8qKlxuICogTWFwICVqIHRvIGBKU09OLnN0cmluZ2lmeSgpYCwgc2luY2Ugbm8gV2ViIEluc3BlY3RvcnMgZG8gdGhhdCBieSBkZWZhdWx0LlxuICovXG5cbmV4cG9ydHMuZm9ybWF0dGVycy5qID0gZnVuY3Rpb24odikge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodik7XG59O1xuXG5cbi8qKlxuICogQ29sb3JpemUgbG9nIGFyZ3VtZW50cyBpZiBlbmFibGVkLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZm9ybWF0QXJncygpIHtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciB1c2VDb2xvcnMgPSB0aGlzLnVzZUNvbG9ycztcblxuICBhcmdzWzBdID0gKHVzZUNvbG9ycyA/ICclYycgOiAnJylcbiAgICArIHRoaXMubmFtZXNwYWNlXG4gICAgKyAodXNlQ29sb3JzID8gJyAlYycgOiAnICcpXG4gICAgKyBhcmdzWzBdXG4gICAgKyAodXNlQ29sb3JzID8gJyVjICcgOiAnICcpXG4gICAgKyAnKycgKyBleHBvcnRzLmh1bWFuaXplKHRoaXMuZGlmZik7XG5cbiAgaWYgKCF1c2VDb2xvcnMpIHJldHVybiBhcmdzO1xuXG4gIHZhciBjID0gJ2NvbG9yOiAnICsgdGhpcy5jb2xvcjtcbiAgYXJncyA9IFthcmdzWzBdLCBjLCAnY29sb3I6IGluaGVyaXQnXS5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncywgMSkpO1xuXG4gIC8vIHRoZSBmaW5hbCBcIiVjXCIgaXMgc29tZXdoYXQgdHJpY2t5LCBiZWNhdXNlIHRoZXJlIGNvdWxkIGJlIG90aGVyXG4gIC8vIGFyZ3VtZW50cyBwYXNzZWQgZWl0aGVyIGJlZm9yZSBvciBhZnRlciB0aGUgJWMsIHNvIHdlIG5lZWQgdG9cbiAgLy8gZmlndXJlIG91dCB0aGUgY29ycmVjdCBpbmRleCB0byBpbnNlcnQgdGhlIENTUyBpbnRvXG4gIHZhciBpbmRleCA9IDA7XG4gIHZhciBsYXN0QyA9IDA7XG4gIGFyZ3NbMF0ucmVwbGFjZSgvJVthLXolXS9nLCBmdW5jdGlvbihtYXRjaCkge1xuICAgIGlmICgnJSUnID09PSBtYXRjaCkgcmV0dXJuO1xuICAgIGluZGV4Kys7XG4gICAgaWYgKCclYycgPT09IG1hdGNoKSB7XG4gICAgICAvLyB3ZSBvbmx5IGFyZSBpbnRlcmVzdGVkIGluIHRoZSAqbGFzdCogJWNcbiAgICAgIC8vICh0aGUgdXNlciBtYXkgaGF2ZSBwcm92aWRlZCB0aGVpciBvd24pXG4gICAgICBsYXN0QyA9IGluZGV4O1xuICAgIH1cbiAgfSk7XG5cbiAgYXJncy5zcGxpY2UobGFzdEMsIDAsIGMpO1xuICByZXR1cm4gYXJncztcbn1cblxuLyoqXG4gKiBJbnZva2VzIGBjb25zb2xlLmxvZygpYCB3aGVuIGF2YWlsYWJsZS5cbiAqIE5vLW9wIHdoZW4gYGNvbnNvbGUubG9nYCBpcyBub3QgYSBcImZ1bmN0aW9uXCIuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBsb2coKSB7XG4gIC8vIHRoaXMgaGFja2VyeSBpcyByZXF1aXJlZCBmb3IgSUU4LzksIHdoZXJlXG4gIC8vIHRoZSBgY29uc29sZS5sb2dgIGZ1bmN0aW9uIGRvZXNuJ3QgaGF2ZSAnYXBwbHknXG4gIHJldHVybiAnb2JqZWN0JyA9PT0gdHlwZW9mIGNvbnNvbGVcbiAgICAmJiBjb25zb2xlLmxvZ1xuICAgICYmIEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKGNvbnNvbGUubG9nLCBjb25zb2xlLCBhcmd1bWVudHMpO1xufVxuXG4vKipcbiAqIFNhdmUgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lc3BhY2VzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzYXZlKG5hbWVzcGFjZXMpIHtcbiAgdHJ5IHtcbiAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2VzKSB7XG4gICAgICBleHBvcnRzLnN0b3JhZ2UucmVtb3ZlSXRlbSgnZGVidWcnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhwb3J0cy5zdG9yYWdlLmRlYnVnID0gbmFtZXNwYWNlcztcbiAgICB9XG4gIH0gY2F0Y2goZSkge31cbn1cblxuLyoqXG4gKiBMb2FkIGBuYW1lc3BhY2VzYC5cbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHJldHVybnMgdGhlIHByZXZpb3VzbHkgcGVyc2lzdGVkIGRlYnVnIG1vZGVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2FkKCkge1xuICB2YXIgcjtcbiAgdHJ5IHtcbiAgICByID0gZXhwb3J0cy5zdG9yYWdlLmRlYnVnO1xuICB9IGNhdGNoKGUpIHt9XG4gIHJldHVybiByO1xufVxuXG4vKipcbiAqIEVuYWJsZSBuYW1lc3BhY2VzIGxpc3RlZCBpbiBgbG9jYWxTdG9yYWdlLmRlYnVnYCBpbml0aWFsbHkuXG4gKi9cblxuZXhwb3J0cy5lbmFibGUobG9hZCgpKTtcblxuLyoqXG4gKiBMb2NhbHN0b3JhZ2UgYXR0ZW1wdHMgdG8gcmV0dXJuIHRoZSBsb2NhbHN0b3JhZ2UuXG4gKlxuICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBzYWZhcmkgdGhyb3dzXG4gKiB3aGVuIGEgdXNlciBkaXNhYmxlcyBjb29raWVzL2xvY2Fsc3RvcmFnZVxuICogYW5kIHlvdSBhdHRlbXB0IHRvIGFjY2VzcyBpdC5cbiAqXG4gKiBAcmV0dXJuIHtMb2NhbFN0b3JhZ2V9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2NhbHN0b3JhZ2UoKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZTtcbiAgfSBjYXRjaCAoZSkge31cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8233\n")},"834b":function(module,exports,__webpack_require__){eval('/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies\n */\n\nvar XMLHttpRequest = __webpack_require__(/*! xmlhttprequest-ssl */ "86e3");\nvar XHR = __webpack_require__(/*! ./polling-xhr */ "108d");\nvar JSONP = __webpack_require__(/*! ./polling-jsonp */ "2dce");\nvar websocket = __webpack_require__(/*! ./websocket */ "6b20");\n\n/**\n * Export transports.\n */\n\nexports.polling = polling;\nexports.websocket = websocket;\n\n/**\n * Polling transport polymorphic constructor.\n * Decides on xhr vs jsonp based on feature detection.\n *\n * @api private\n */\n\nfunction polling (opts) {\n  var xhr;\n  var xd = false;\n  var xs = false;\n  var jsonp = false !== opts.jsonp;\n\n  if (global.location) {\n    var isSSL = \'https:\' === location.protocol;\n    var port = location.port;\n\n    // some user agents have empty `location.port`\n    if (!port) {\n      port = isSSL ? 443 : 80;\n    }\n\n    xd = opts.hostname !== location.hostname || port !== opts.port;\n    xs = opts.secure !== isSSL;\n  }\n\n  opts.xdomain = xd;\n  opts.xscheme = xs;\n  xhr = new XMLHttpRequest(opts);\n\n  if (\'open\' in xhr && !opts.forceJSONP) {\n    return new XHR(opts);\n  } else {\n    if (!jsonp) throw new Error(\'JSONP disabled\');\n    return new JSONP(opts);\n  }\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../webpack/buildin/global.js */ "698d")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODM0Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9pbmRleC5qcz84OTk2Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llc1xuICovXG5cbnZhciBYTUxIdHRwUmVxdWVzdCA9IHJlcXVpcmUoJ3htbGh0dHByZXF1ZXN0LXNzbCcpO1xudmFyIFhIUiA9IHJlcXVpcmUoJy4vcG9sbGluZy14aHInKTtcbnZhciBKU09OUCA9IHJlcXVpcmUoJy4vcG9sbGluZy1qc29ucCcpO1xudmFyIHdlYnNvY2tldCA9IHJlcXVpcmUoJy4vd2Vic29ja2V0Jyk7XG5cbi8qKlxuICogRXhwb3J0IHRyYW5zcG9ydHMuXG4gKi9cblxuZXhwb3J0cy5wb2xsaW5nID0gcG9sbGluZztcbmV4cG9ydHMud2Vic29ja2V0ID0gd2Vic29ja2V0O1xuXG4vKipcbiAqIFBvbGxpbmcgdHJhbnNwb3J0IHBvbHltb3JwaGljIGNvbnN0cnVjdG9yLlxuICogRGVjaWRlcyBvbiB4aHIgdnMganNvbnAgYmFzZWQgb24gZmVhdHVyZSBkZXRlY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcG9sbGluZyAob3B0cykge1xuICB2YXIgeGhyO1xuICB2YXIgeGQgPSBmYWxzZTtcbiAgdmFyIHhzID0gZmFsc2U7XG4gIHZhciBqc29ucCA9IGZhbHNlICE9PSBvcHRzLmpzb25wO1xuXG4gIGlmIChnbG9iYWwubG9jYXRpb24pIHtcbiAgICB2YXIgaXNTU0wgPSAnaHR0cHM6JyA9PT0gbG9jYXRpb24ucHJvdG9jb2w7XG4gICAgdmFyIHBvcnQgPSBsb2NhdGlvbi5wb3J0O1xuXG4gICAgLy8gc29tZSB1c2VyIGFnZW50cyBoYXZlIGVtcHR5IGBsb2NhdGlvbi5wb3J0YFxuICAgIGlmICghcG9ydCkge1xuICAgICAgcG9ydCA9IGlzU1NMID8gNDQzIDogODA7XG4gICAgfVxuXG4gICAgeGQgPSBvcHRzLmhvc3RuYW1lICE9PSBsb2NhdGlvbi5ob3N0bmFtZSB8fCBwb3J0ICE9PSBvcHRzLnBvcnQ7XG4gICAgeHMgPSBvcHRzLnNlY3VyZSAhPT0gaXNTU0w7XG4gIH1cblxuICBvcHRzLnhkb21haW4gPSB4ZDtcbiAgb3B0cy54c2NoZW1lID0geHM7XG4gIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdChvcHRzKTtcblxuICBpZiAoJ29wZW4nIGluIHhociAmJiAhb3B0cy5mb3JjZUpTT05QKSB7XG4gICAgcmV0dXJuIG5ldyBYSFIob3B0cyk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFqc29ucCkgdGhyb3cgbmV3IEVycm9yKCdKU09OUCBkaXNhYmxlZCcpO1xuICAgIHJldHVybiBuZXcgSlNPTlAob3B0cyk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///834b\n')},"86e3":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {// browser shim for xmlhttprequest module\n\nvar hasCORS = __webpack_require__(/*! has-cors */ \"0392\");\n\nmodule.exports = function (opts) {\n  var xdomain = opts.xdomain;\n\n  // scheme must be same when usign XDomainRequest\n  // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx\n  var xscheme = opts.xscheme;\n\n  // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.\n  // https://github.com/Automattic/engine.io-client/pull/217\n  var enablesXDR = opts.enablesXDR;\n\n  // XMLHttpRequest can be disabled on IE\n  try {\n    if ('undefined' !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {\n      return new XMLHttpRequest();\n    }\n  } catch (e) { }\n\n  // Use XDomainRequest for IE8 if enablesXDR is true\n  // because loading bar keeps flashing when using jsonp-polling\n  // https://github.com/yujiosaka/socke.io-ie8-loading-example\n  try {\n    if ('undefined' !== typeof XDomainRequest && !xscheme && enablesXDR) {\n      return new XDomainRequest();\n    }\n  } catch (e) { }\n\n  if (!xdomain) {\n    try {\n      return new global[['Active'].concat('Object').join('X')]('Microsoft.XMLHTTP');\n    } catch (e) { }\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODZlMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIveG1saHR0cHJlcXVlc3QuanM/NzY2NSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBicm93c2VyIHNoaW0gZm9yIHhtbGh0dHByZXF1ZXN0IG1vZHVsZVxuXG52YXIgaGFzQ09SUyA9IHJlcXVpcmUoJ2hhcy1jb3JzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgdmFyIHhkb21haW4gPSBvcHRzLnhkb21haW47XG5cbiAgLy8gc2NoZW1lIG11c3QgYmUgc2FtZSB3aGVuIHVzaWduIFhEb21haW5SZXF1ZXN0XG4gIC8vIGh0dHA6Ly9ibG9ncy5tc2RuLmNvbS9iL2llaW50ZXJuYWxzL2FyY2hpdmUvMjAxMC8wNS8xMy94ZG9tYWlucmVxdWVzdC1yZXN0cmljdGlvbnMtbGltaXRhdGlvbnMtYW5kLXdvcmthcm91bmRzLmFzcHhcbiAgdmFyIHhzY2hlbWUgPSBvcHRzLnhzY2hlbWU7XG5cbiAgLy8gWERvbWFpblJlcXVlc3QgaGFzIGEgZmxvdyBvZiBub3Qgc2VuZGluZyBjb29raWUsIHRoZXJlZm9yZSBpdCBzaG91bGQgYmUgZGlzYWJsZWQgYXMgYSBkZWZhdWx0LlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vQXV0b21hdHRpYy9lbmdpbmUuaW8tY2xpZW50L3B1bGwvMjE3XG4gIHZhciBlbmFibGVzWERSID0gb3B0cy5lbmFibGVzWERSO1xuXG4gIC8vIFhNTEh0dHBSZXF1ZXN0IGNhbiBiZSBkaXNhYmxlZCBvbiBJRVxuICB0cnkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIFhNTEh0dHBSZXF1ZXN0ICYmICgheGRvbWFpbiB8fCBoYXNDT1JTKSkge1xuICAgICAgcmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkgeyB9XG5cbiAgLy8gVXNlIFhEb21haW5SZXF1ZXN0IGZvciBJRTggaWYgZW5hYmxlc1hEUiBpcyB0cnVlXG4gIC8vIGJlY2F1c2UgbG9hZGluZyBiYXIga2VlcHMgZmxhc2hpbmcgd2hlbiB1c2luZyBqc29ucC1wb2xsaW5nXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS95dWppb3Nha2Evc29ja2UuaW8taWU4LWxvYWRpbmctZXhhbXBsZVxuICB0cnkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIFhEb21haW5SZXF1ZXN0ICYmICF4c2NoZW1lICYmIGVuYWJsZXNYRFIpIHtcbiAgICAgIHJldHVybiBuZXcgWERvbWFpblJlcXVlc3QoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHsgfVxuXG4gIGlmICgheGRvbWFpbikge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbmV3IGdsb2JhbFtbJ0FjdGl2ZSddLmNvbmNhdCgnT2JqZWN0Jykuam9pbignWCcpXSgnTWljcm9zb2Z0LlhNTEhUVFAnKTtcbiAgICB9IGNhdGNoIChlKSB7IH1cbiAgfVxufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///86e3\n")},9083:function(module,exports,__webpack_require__){eval("/**\n * A `Group` represents a value a `Facet` can take using a partitioning.\n * For continuous or time facets, it represents an interval.\n * For categorial facets, it is a single label.\n *\n * The `Facet.groups` collection is used for plotting, to deterime the postion along the axis.\n * Selections can be updated using a `Group`.\n *\n * @extends Base\n * @class Group\n */\nvar Base = __webpack_require__(/*! ../util/base */ \"3902\");\nvar moment = __webpack_require__(/*! moment */ \"da01\");\n\nmodule.exports = Base.extend({\n  dataTypes: {\n    'numberDatetimeOrDuration': {\n      set: function (value) {\n        var newValue;\n\n        // check for momentjs objects\n        if (moment.isDuration(value)) {\n          return {\n            val: moment.duration(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (moment.isMoment(value)) {\n          return {\n            val: moment(value),\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to create momentjs objects\n        newValue = moment(value, moment.ISO_8601);\n        if (newValue.isValid()) {\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n        if (typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          newValue = moment.duration(value);\n          return {\n            val: newValue,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // try to set a number\n        if (value === +value) {\n          return {\n            val: +value,\n            type: 'numberDatetimeOrDuration'\n          };\n        }\n\n        // failed..\n        return {\n          val: value,\n          type: typeof value\n        };\n      },\n      compare: function (currentVal, newVal) {\n        if (currentVal instanceof moment) {\n          return currentVal.isSame(newVal);\n        } else {\n          return +currentVal === +newVal;\n        }\n      }\n    }\n  },\n  props: {\n    /**\n     * For continuous, datetime, or duration facets. Lower limit of interval\n     * @type {number|moment}\n     * @memberof! Group\n     */\n    min: 'numberDatetimeOrDuration',\n\n    /**\n     * For continuous, datetime, or duration facets. Upper limit of interval\n     * @type {number|moment}\n     * @memberof! Group\n     */\n    max: 'numberDatetimeOrDuration',\n\n    /**\n     * Number of times this transform is used\n     * @type {number}\n     * @memberof! Group\n     */\n    count: ['number', true, 0],\n\n    /**\n     * Label for display\n     * @type {string}\n     * @memberof! Group\n     */\n    label: ['string', true, 'label'],\n\n    /**\n     * A value guaranteed to be in this group, used to check if this group is currently selected.\n     * moments and durations should be stored as moment.format() and duration.toISOString()\n     * @type {string|number}\n     * @memberof! Group\n     */\n    value: 'any',\n\n    /**\n     * Index, cached version of groups.models.indexOf(group)\n     * @type {number}\n     * @memberof! Group\n     */\n    groupIndex: 'number'\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTA4My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2dyb3VwLmpzPzEwNGMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBIGBHcm91cGAgcmVwcmVzZW50cyBhIHZhbHVlIGEgYEZhY2V0YCBjYW4gdGFrZSB1c2luZyBhIHBhcnRpdGlvbmluZy5cbiAqIEZvciBjb250aW51b3VzIG9yIHRpbWUgZmFjZXRzLCBpdCByZXByZXNlbnRzIGFuIGludGVydmFsLlxuICogRm9yIGNhdGVnb3JpYWwgZmFjZXRzLCBpdCBpcyBhIHNpbmdsZSBsYWJlbC5cbiAqXG4gKiBUaGUgYEZhY2V0Lmdyb3Vwc2AgY29sbGVjdGlvbiBpcyB1c2VkIGZvciBwbG90dGluZywgdG8gZGV0ZXJpbWUgdGhlIHBvc3Rpb24gYWxvbmcgdGhlIGF4aXMuXG4gKiBTZWxlY3Rpb25zIGNhbiBiZSB1cGRhdGVkIHVzaW5nIGEgYEdyb3VwYC5cbiAqXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKiBAY2xhc3MgR3JvdXBcbiAqL1xudmFyIEJhc2UgPSByZXF1aXJlKCcuLi91dGlsL2Jhc2UnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlLmV4dGVuZCh7XG4gIGRhdGFUeXBlczoge1xuICAgICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nOiB7XG4gICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIG1vbWVudGpzIG9iamVjdHNcbiAgICAgICAgaWYgKG1vbWVudC5pc0R1cmF0aW9uKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG1vbWVudC5kdXJhdGlvbih2YWx1ZSksXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vbWVudC5pc01vbWVudCh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsOiBtb21lbnQodmFsdWUpLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIGNyZWF0ZSBtb21lbnRqcyBvYmplY3RzXG4gICAgICAgIG5ld1ZhbHVlID0gbW9tZW50KHZhbHVlLCBtb21lbnQuSVNPXzg2MDEpO1xuICAgICAgICBpZiAobmV3VmFsdWUuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbDogbmV3VmFsdWUsXG4gICAgICAgICAgICB0eXBlOiAnbnVtYmVyRGF0ZXRpbWVPckR1cmF0aW9uJ1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWVbMF0udG9Mb3dlckNhc2UoKSA9PT0gJ3AnKSB7XG4gICAgICAgICAgbmV3VmFsdWUgPSBtb21lbnQuZHVyYXRpb24odmFsdWUpO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6IG5ld1ZhbHVlLFxuICAgICAgICAgICAgdHlwZTogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbidcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJ5IHRvIHNldCBhIG51bWJlclxuICAgICAgICBpZiAodmFsdWUgPT09ICt2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWw6ICt2YWx1ZSxcbiAgICAgICAgICAgIHR5cGU6ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZhaWxlZC4uXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsOiB2YWx1ZSxcbiAgICAgICAgICB0eXBlOiB0eXBlb2YgdmFsdWVcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBjb21wYXJlOiBmdW5jdGlvbiAoY3VycmVudFZhbCwgbmV3VmFsKSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsIGluc3RhbmNlb2YgbW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuIGN1cnJlbnRWYWwuaXNTYW1lKG5ld1ZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuICtjdXJyZW50VmFsID09PSArbmV3VmFsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzLCBkYXRldGltZSwgb3IgZHVyYXRpb24gZmFjZXRzLiBMb3dlciBsaW1pdCBvZiBpbnRlcnZhbFxuICAgICAqIEB0eXBlIHtudW1iZXJ8bW9tZW50fVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICBtaW46ICdudW1iZXJEYXRldGltZU9yRHVyYXRpb24nLFxuXG4gICAgLyoqXG4gICAgICogRm9yIGNvbnRpbnVvdXMsIGRhdGV0aW1lLCBvciBkdXJhdGlvbiBmYWNldHMuIFVwcGVyIGxpbWl0IG9mIGludGVydmFsXG4gICAgICogQHR5cGUge251bWJlcnxtb21lbnR9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIG1heDogJ251bWJlckRhdGV0aW1lT3JEdXJhdGlvbicsXG5cbiAgICAvKipcbiAgICAgKiBOdW1iZXIgb2YgdGltZXMgdGhpcyB0cmFuc2Zvcm0gaXMgdXNlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIGNvdW50OiBbJ251bWJlcicsIHRydWUsIDBdLFxuXG4gICAgLyoqXG4gICAgICogTGFiZWwgZm9yIGRpc3BsYXlcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICBsYWJlbDogWydzdHJpbmcnLCB0cnVlLCAnbGFiZWwnXSxcblxuICAgIC8qKlxuICAgICAqIEEgdmFsdWUgZ3VhcmFudGVlZCB0byBiZSBpbiB0aGlzIGdyb3VwLCB1c2VkIHRvIGNoZWNrIGlmIHRoaXMgZ3JvdXAgaXMgY3VycmVudGx5IHNlbGVjdGVkLlxuICAgICAqIG1vbWVudHMgYW5kIGR1cmF0aW9ucyBzaG91bGQgYmUgc3RvcmVkIGFzIG1vbWVudC5mb3JtYXQoKSBhbmQgZHVyYXRpb24udG9JU09TdHJpbmcoKVxuICAgICAqIEB0eXBlIHtzdHJpbmd8bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgR3JvdXBcbiAgICAgKi9cbiAgICB2YWx1ZTogJ2FueScsXG5cbiAgICAvKipcbiAgICAgKiBJbmRleCwgY2FjaGVkIHZlcnNpb24gb2YgZ3JvdXBzLm1vZGVscy5pbmRleE9mKGdyb3VwKVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBHcm91cFxuICAgICAqL1xuICAgIGdyb3VwSW5kZXg6ICdudW1iZXInXG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9083\n")},"939f":function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Create a blob builder even when vendor prefixes exist\n */\n\nvar BlobBuilder = global.BlobBuilder\n  || global.WebKitBlobBuilder\n  || global.MSBlobBuilder\n  || global.MozBlobBuilder;\n\n/**\n * Check if Blob constructor is supported\n */\n\nvar blobSupported = (function() {\n  try {\n    var a = new Blob(['hi']);\n    return a.size === 2;\n  } catch(e) {\n    return false;\n  }\n})();\n\n/**\n * Check if Blob constructor supports ArrayBufferViews\n * Fails in Safari 6, so we need to map to ArrayBuffers there.\n */\n\nvar blobSupportsArrayBufferView = blobSupported && (function() {\n  try {\n    var b = new Blob([new Uint8Array([1,2])]);\n    return b.size === 2;\n  } catch(e) {\n    return false;\n  }\n})();\n\n/**\n * Check if BlobBuilder is supported\n */\n\nvar blobBuilderSupported = BlobBuilder\n  && BlobBuilder.prototype.append\n  && BlobBuilder.prototype.getBlob;\n\n/**\n * Helper function that maps ArrayBufferViews to ArrayBuffers\n * Used by BlobBuilder constructor and old browsers that didn't\n * support it in the Blob constructor.\n */\n\nfunction mapArrayBufferViews(ary) {\n  for (var i = 0; i < ary.length; i++) {\n    var chunk = ary[i];\n    if (chunk.buffer instanceof ArrayBuffer) {\n      var buf = chunk.buffer;\n\n      // if this is a subarray, make a copy so we only\n      // include the subarray region from the underlying buffer\n      if (chunk.byteLength !== buf.byteLength) {\n        var copy = new Uint8Array(chunk.byteLength);\n        copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength));\n        buf = copy.buffer;\n      }\n\n      ary[i] = buf;\n    }\n  }\n}\n\nfunction BlobBuilderConstructor(ary, options) {\n  options = options || {};\n\n  var bb = new BlobBuilder();\n  mapArrayBufferViews(ary);\n\n  for (var i = 0; i < ary.length; i++) {\n    bb.append(ary[i]);\n  }\n\n  return (options.type) ? bb.getBlob(options.type) : bb.getBlob();\n};\n\nfunction BlobConstructor(ary, options) {\n  mapArrayBufferViews(ary);\n  return new Blob(ary, options || {});\n};\n\nmodule.exports = (function() {\n  if (blobSupported) {\n    return blobSupportsArrayBufferView ? global.Blob : BlobConstructor;\n  } else if (blobBuilderSupported) {\n    return BlobBuilderConstructor;\n  } else {\n    return undefined;\n  }\n})();\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM5Zi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvYmxvYi9pbmRleC5qcz8yMTA3Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ3JlYXRlIGEgYmxvYiBidWlsZGVyIGV2ZW4gd2hlbiB2ZW5kb3IgcHJlZml4ZXMgZXhpc3RcbiAqL1xuXG52YXIgQmxvYkJ1aWxkZXIgPSBnbG9iYWwuQmxvYkJ1aWxkZXJcbiAgfHwgZ2xvYmFsLldlYktpdEJsb2JCdWlsZGVyXG4gIHx8IGdsb2JhbC5NU0Jsb2JCdWlsZGVyXG4gIHx8IGdsb2JhbC5Nb3pCbG9iQnVpbGRlcjtcblxuLyoqXG4gKiBDaGVjayBpZiBCbG9iIGNvbnN0cnVjdG9yIGlzIHN1cHBvcnRlZFxuICovXG5cbnZhciBibG9iU3VwcG9ydGVkID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIHZhciBhID0gbmV3IEJsb2IoWydoaSddKTtcbiAgICByZXR1cm4gYS5zaXplID09PSAyO1xuICB9IGNhdGNoKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8qKlxuICogQ2hlY2sgaWYgQmxvYiBjb25zdHJ1Y3RvciBzdXBwb3J0cyBBcnJheUJ1ZmZlclZpZXdzXG4gKiBGYWlscyBpbiBTYWZhcmkgNiwgc28gd2UgbmVlZCB0byBtYXAgdG8gQXJyYXlCdWZmZXJzIHRoZXJlLlxuICovXG5cbnZhciBibG9iU3VwcG9ydHNBcnJheUJ1ZmZlclZpZXcgPSBibG9iU3VwcG9ydGVkICYmIChmdW5jdGlvbigpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYiA9IG5ldyBCbG9iKFtuZXcgVWludDhBcnJheShbMSwyXSldKTtcbiAgICByZXR1cm4gYi5zaXplID09PSAyO1xuICB9IGNhdGNoKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8qKlxuICogQ2hlY2sgaWYgQmxvYkJ1aWxkZXIgaXMgc3VwcG9ydGVkXG4gKi9cblxudmFyIGJsb2JCdWlsZGVyU3VwcG9ydGVkID0gQmxvYkJ1aWxkZXJcbiAgJiYgQmxvYkJ1aWxkZXIucHJvdG90eXBlLmFwcGVuZFxuICAmJiBCbG9iQnVpbGRlci5wcm90b3R5cGUuZ2V0QmxvYjtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBtYXBzIEFycmF5QnVmZmVyVmlld3MgdG8gQXJyYXlCdWZmZXJzXG4gKiBVc2VkIGJ5IEJsb2JCdWlsZGVyIGNvbnN0cnVjdG9yIGFuZCBvbGQgYnJvd3NlcnMgdGhhdCBkaWRuJ3RcbiAqIHN1cHBvcnQgaXQgaW4gdGhlIEJsb2IgY29uc3RydWN0b3IuXG4gKi9cblxuZnVuY3Rpb24gbWFwQXJyYXlCdWZmZXJWaWV3cyhhcnkpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnkubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgY2h1bmsgPSBhcnlbaV07XG4gICAgaWYgKGNodW5rLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICB2YXIgYnVmID0gY2h1bmsuYnVmZmVyO1xuXG4gICAgICAvLyBpZiB0aGlzIGlzIGEgc3ViYXJyYXksIG1ha2UgYSBjb3B5IHNvIHdlIG9ubHlcbiAgICAgIC8vIGluY2x1ZGUgdGhlIHN1YmFycmF5IHJlZ2lvbiBmcm9tIHRoZSB1bmRlcmx5aW5nIGJ1ZmZlclxuICAgICAgaWYgKGNodW5rLmJ5dGVMZW5ndGggIT09IGJ1Zi5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHZhciBjb3B5ID0gbmV3IFVpbnQ4QXJyYXkoY2h1bmsuYnl0ZUxlbmd0aCk7XG4gICAgICAgIGNvcHkuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZiwgY2h1bmsuYnl0ZU9mZnNldCwgY2h1bmsuYnl0ZUxlbmd0aCkpO1xuICAgICAgICBidWYgPSBjb3B5LmJ1ZmZlcjtcbiAgICAgIH1cblxuICAgICAgYXJ5W2ldID0gYnVmO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBCbG9iQnVpbGRlckNvbnN0cnVjdG9yKGFyeSwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgYmIgPSBuZXcgQmxvYkJ1aWxkZXIoKTtcbiAgbWFwQXJyYXlCdWZmZXJWaWV3cyhhcnkpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgYmIuYXBwZW5kKGFyeVtpXSk7XG4gIH1cblxuICByZXR1cm4gKG9wdGlvbnMudHlwZSkgPyBiYi5nZXRCbG9iKG9wdGlvbnMudHlwZSkgOiBiYi5nZXRCbG9iKCk7XG59O1xuXG5mdW5jdGlvbiBCbG9iQ29uc3RydWN0b3IoYXJ5LCBvcHRpb25zKSB7XG4gIG1hcEFycmF5QnVmZmVyVmlld3MoYXJ5KTtcbiAgcmV0dXJuIG5ldyBCbG9iKGFyeSwgb3B0aW9ucyB8fCB7fSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IChmdW5jdGlvbigpIHtcbiAgaWYgKGJsb2JTdXBwb3J0ZWQpIHtcbiAgICByZXR1cm4gYmxvYlN1cHBvcnRzQXJyYXlCdWZmZXJWaWV3ID8gZ2xvYmFsLkJsb2IgOiBCbG9iQ29uc3RydWN0b3I7XG4gIH0gZWxzZSBpZiAoYmxvYkJ1aWxkZXJTdXBwb3J0ZWQpIHtcbiAgICByZXR1cm4gQmxvYkJ1aWxkZXJDb25zdHJ1Y3RvcjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59KSgpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///939f\n")},9476:function(module,exports,__webpack_require__){eval("/**\n * A filter provides a chart with an interface to the data.\n * The filter contains a number of `Partition`s and `Aggregate`s.\n * It takes care of calling the relevant functions provided by a `Dataset`.\n *\n * @class Filter\n * @extends Base\n */\n\n/**\n * @typedef {Object} DataRecord - Object holding the plot data, partitions are labelled with a single small letter, aggregates with a double small letter\n * @property {string} DataRecord.a Value of first partition\n * @property {string} DataRecord.b Value of second partition\n * @property {string} DataRecord.c Value of third partition, etc.\n * @property {string} DataRecord.aa Value of first aggregate\n * @property {string} DataRecord.bb Value of second aggregate, etc.\n */\n\n/**\n * @typedef {DataRecord[]} Data - Array of DataRecords\n */\n\nvar Base = __webpack_require__(/*! ./util/base */ \"3902\");\nvar Aggregates = __webpack_require__(/*! ./aggregate/collection */ \"fbef\");\nvar Partitions = __webpack_require__(/*! ./partition/collection */ \"e59a\");\n\nmodule.exports = Base.extend({\n  props: {\n    /**\n     * Hint for the client (website) how to visualize this filter\n     * @memberof! Filter\n     * @type {string}\n     */\n    chartType: {\n      type: 'string',\n      required: true,\n      default: 'barchart',\n      values: ['piechart', 'horizontalbarchart', 'barchart', 'linechart', 'radarchart', 'polarareachart', 'bubbleplot', 'scatterchart', 'networkchart']\n    },\n    /**\n     * Title for displaying purposes\n     * @memberof! Filter\n     * @type {string}\n     */\n    title: ['string', true, ''],\n    /**\n     * Hint for the client (website) how to position the chart for this filter\n     * position (col, row) and size (size_x, size_y) of chart\n     */\n    col: 'number',\n    row: 'number',\n    size_x: 'number',\n    size_y: 'number'\n  },\n  collections: {\n    /**\n     * @memberof! Filter\n     * @type {Partitions[]}\n     */\n    partitions: Partitions,\n    /**\n     * @memberof! Filter\n     * @type {Aggregate[]}\n     */\n    aggregates: Aggregates\n  },\n  // Session properties are not typically persisted to the server,\n  // and are not returned by calls to toJSON() or serialize().\n  session: {\n    /**\n     * Array containing the data to plot\n     * @memberof! Filter\n     * @type {Data}\n     */\n    data: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    },\n    /*\n     * Call this function to request new data.\n     * The dataset backing the facet will copy the data to Filter.data.\n     * A newData event is fired when the data is ready to be plotted.\n     *\n     * @function\n     * @virtual\n     * @private\n     * @memberof! Filter\n     * @emits newData\n     */\n    getData: {\n      type: 'any'\n    },\n    /**\n     * A history of the current drill-down (ie. partitions.toJSON())\n     */\n    zoomHistory: {\n      type: 'array',\n      default: function () {\n        return [];\n      }\n    },\n    /**\n     * Boolean indicating if the filter is initialized\n     */\n    isInitialized: {\n      type: 'boolean',\n      required: true,\n      default: false\n    }\n  },\n  initialize: function () {\n    // set up callback to free internal state on remove\n    this.on('remove', function () {\n      this.releaseDataFilter();\n    });\n  },\n  zoomIn: function () {\n    this.releaseDataFilter();\n\n    // save current state\n    this.zoomHistory.push(JSON.stringify(this.partitions.toJSON()));\n\n    this.partitions.forEach(function (partition) {\n      if ((partition.selected.length === 2) && (partition.isDatetime || partition.isContinuous)) {\n        if (partition.groupFixedS || partition.groupFixedSC) {\n          // scale down binsize\n          var newSize = partition.selected[1] - partition.selected[0];\n          var oldSize = partition.maxval - partition.minval;\n          partition.groupingParam = partition.groupingParam * newSize / oldSize;\n        }\n        // zoom to selected range, if possible\n        partition.set({\n          minval: partition.selected[0],\n          maxval: partition.selected[1]\n        });\n      } else if (partition.selected.length > 0 && (partition.isCategorial)) {\n        // zoom to selected categories, if possible\n        partition.groups.reset();\n        partition.selected.forEach(function (value) {\n          partition.groups.add({\n            value: value,\n            label: value,\n            count: 0,\n            isSelected: true\n          });\n        });\n      }\n      // select all\n      partition.updateSelection();\n    });\n    this.initDataFilter();\n    this.updateDataFilter(); // also triggers a getAllData()\n  },\n  zoomOut: function () {\n    var doReset = true;\n\n    // clear current selection\n    this.partitions.forEach(function (partition) {\n      if (partition.selected.length > 0) {\n        partition.updateSelection();\n        doReset = false;\n      }\n    });\n\n    if (doReset) {\n      this.releaseDataFilter();\n      if (this.zoomHistory.length > 0) {\n        // nothing was selected and we have drilled down: go up\n        var state = JSON.parse(this.zoomHistory.pop());\n        this.partitions.reset(state);\n      } else {\n        // nothing was selected and no drill down: reset partitioning\n        this.partitions.forEach(function (partition) {\n          if (partition.isDatetime || partition.isContinuous) {\n            partition.reset();\n          }\n        });\n      }\n      this.initDataFilter();\n    }\n    this.updateDataFilter(); // also triggers a getAllData()\n  },\n  // Apply the separate filterFunctions from each partition in a single function\n  filterFunction: function () {\n    var fs = [];\n    this.partitions.forEach(function (partition) {\n      fs.push(partition.filterFunction());\n    });\n    return function (d) {\n      if (typeof d === 'string') {\n        var groups = d.split('|');\n        return fs.every(function (f, i) { return f(groups[i]); });\n      } else {\n        // shortcut for non-partitioned numeric data\n        return fs[0](d);\n      }\n    };\n  },\n  /**\n   * Initialize the data filter, and construct the getData callback function on the filter.\n   *\n   * @memberof! Filter\n   */\n  initDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.releaseDataFilter(dataview, this);\n    spot.driver.initDataFilter(dataview, this);\n    spot.driver.updateDataFilter(this);\n\n    this.isInitialized = true;\n  },\n  /**\n   * The opposite or initDataFilter, it should remove the filter and deallocate other configuration\n   * related to the filter.\n   *\n   * @memberof! Filter\n   */\n  releaseDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.releaseDataFilter(dataview, this);\n\n    this.isInitialized = false;\n  },\n  /**\n   * Apply changes to the filter (like selecting groups)\n   *\n   * @memberof! Filter\n   */\n  updateDataFilter: function () {\n    var dataview = this.collection.parent;\n    var spot = dataview.parent;\n\n    spot.driver.updateDataFilter(this);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ3Ni5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmlsdGVyLmpzPzM4ZmYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBIGZpbHRlciBwcm92aWRlcyBhIGNoYXJ0IHdpdGggYW4gaW50ZXJmYWNlIHRvIHRoZSBkYXRhLlxuICogVGhlIGZpbHRlciBjb250YWlucyBhIG51bWJlciBvZiBgUGFydGl0aW9uYHMgYW5kIGBBZ2dyZWdhdGVgcy5cbiAqIEl0IHRha2VzIGNhcmUgb2YgY2FsbGluZyB0aGUgcmVsZXZhbnQgZnVuY3Rpb25zIHByb3ZpZGVkIGJ5IGEgYERhdGFzZXRgLlxuICpcbiAqIEBjbGFzcyBGaWx0ZXJcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IERhdGFSZWNvcmQgLSBPYmplY3QgaG9sZGluZyB0aGUgcGxvdCBkYXRhLCBwYXJ0aXRpb25zIGFyZSBsYWJlbGxlZCB3aXRoIGEgc2luZ2xlIHNtYWxsIGxldHRlciwgYWdncmVnYXRlcyB3aXRoIGEgZG91YmxlIHNtYWxsIGxldHRlclxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYSBWYWx1ZSBvZiBmaXJzdCBwYXJ0aXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEYXRhUmVjb3JkLmIgVmFsdWUgb2Ygc2Vjb25kIHBhcnRpdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYyBWYWx1ZSBvZiB0aGlyZCBwYXJ0aXRpb24sIGV0Yy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEYXRhUmVjb3JkLmFhIFZhbHVlIG9mIGZpcnN0IGFnZ3JlZ2F0ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IERhdGFSZWNvcmQuYmIgVmFsdWUgb2Ygc2Vjb25kIGFnZ3JlZ2F0ZSwgZXRjLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge0RhdGFSZWNvcmRbXX0gRGF0YSAtIEFycmF5IG9mIERhdGFSZWNvcmRzXG4gKi9cblxudmFyIEJhc2UgPSByZXF1aXJlKCcuL3V0aWwvYmFzZScpO1xudmFyIEFnZ3JlZ2F0ZXMgPSByZXF1aXJlKCcuL2FnZ3JlZ2F0ZS9jb2xsZWN0aW9uJyk7XG52YXIgUGFydGl0aW9ucyA9IHJlcXVpcmUoJy4vcGFydGl0aW9uL2NvbGxlY3Rpb24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCYXNlLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogSGludCBmb3IgdGhlIGNsaWVudCAod2Vic2l0ZSkgaG93IHRvIHZpc3VhbGl6ZSB0aGlzIGZpbHRlclxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBjaGFydFR5cGU6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnYmFyY2hhcnQnLFxuICAgICAgdmFsdWVzOiBbJ3BpZWNoYXJ0JywgJ2hvcml6b250YWxiYXJjaGFydCcsICdiYXJjaGFydCcsICdsaW5lY2hhcnQnLCAncmFkYXJjaGFydCcsICdwb2xhcmFyZWFjaGFydCcsICdidWJibGVwbG90JywgJ3NjYXR0ZXJjaGFydCcsICduZXR3b3JrY2hhcnQnXVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGl0bGUgZm9yIGRpc3BsYXlpbmcgcHVycG9zZXNcbiAgICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGl0bGU6IFsnc3RyaW5nJywgdHJ1ZSwgJyddLFxuICAgIC8qKlxuICAgICAqIEhpbnQgZm9yIHRoZSBjbGllbnQgKHdlYnNpdGUpIGhvdyB0byBwb3NpdGlvbiB0aGUgY2hhcnQgZm9yIHRoaXMgZmlsdGVyXG4gICAgICogcG9zaXRpb24gKGNvbCwgcm93KSBhbmQgc2l6ZSAoc2l6ZV94LCBzaXplX3kpIG9mIGNoYXJ0XG4gICAgICovXG4gICAgY29sOiAnbnVtYmVyJyxcbiAgICByb3c6ICdudW1iZXInLFxuICAgIHNpemVfeDogJ251bWJlcicsXG4gICAgc2l6ZV95OiAnbnVtYmVyJ1xuICB9LFxuICBjb2xsZWN0aW9uczoge1xuICAgIC8qKlxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge1BhcnRpdGlvbnNbXX1cbiAgICAgKi9cbiAgICBwYXJ0aXRpb25zOiBQYXJ0aXRpb25zLFxuICAgIC8qKlxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge0FnZ3JlZ2F0ZVtdfVxuICAgICAqL1xuICAgIGFnZ3JlZ2F0ZXM6IEFnZ3JlZ2F0ZXNcbiAgfSxcbiAgLy8gU2Vzc2lvbiBwcm9wZXJ0aWVzIGFyZSBub3QgdHlwaWNhbGx5IHBlcnNpc3RlZCB0byB0aGUgc2VydmVyLFxuICAvLyBhbmQgYXJlIG5vdCByZXR1cm5lZCBieSBjYWxscyB0byB0b0pTT04oKSBvciBzZXJpYWxpemUoKS5cbiAgc2Vzc2lvbjoge1xuICAgIC8qKlxuICAgICAqIEFycmF5IGNvbnRhaW5pbmcgdGhlIGRhdGEgdG8gcGxvdFxuICAgICAqIEBtZW1iZXJvZiEgRmlsdGVyXG4gICAgICogQHR5cGUge0RhdGF9XG4gICAgICovXG4gICAgZGF0YToge1xuICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0sXG4gICAgLypcbiAgICAgKiBDYWxsIHRoaXMgZnVuY3Rpb24gdG8gcmVxdWVzdCBuZXcgZGF0YS5cbiAgICAgKiBUaGUgZGF0YXNldCBiYWNraW5nIHRoZSBmYWNldCB3aWxsIGNvcHkgdGhlIGRhdGEgdG8gRmlsdGVyLmRhdGEuXG4gICAgICogQSBuZXdEYXRhIGV2ZW50IGlzIGZpcmVkIHdoZW4gdGhlIGRhdGEgaXMgcmVhZHkgdG8gYmUgcGxvdHRlZC5cbiAgICAgKlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEB2aXJ0dWFsXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgICAqIEBlbWl0cyBuZXdEYXRhXG4gICAgICovXG4gICAgZ2V0RGF0YToge1xuICAgICAgdHlwZTogJ2FueSdcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIEEgaGlzdG9yeSBvZiB0aGUgY3VycmVudCBkcmlsbC1kb3duIChpZS4gcGFydGl0aW9ucy50b0pTT04oKSlcbiAgICAgKi9cbiAgICB6b29tSGlzdG9yeToge1xuICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogQm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSBmaWx0ZXIgaXMgaW5pdGlhbGl6ZWRcbiAgICAgKi9cbiAgICBpc0luaXRpYWxpemVkOiB7XG4gICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IGZhbHNlXG4gICAgfVxuICB9LFxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gc2V0IHVwIGNhbGxiYWNrIHRvIGZyZWUgaW50ZXJuYWwgc3RhdGUgb24gcmVtb3ZlXG4gICAgdGhpcy5vbigncmVtb3ZlJywgZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5yZWxlYXNlRGF0YUZpbHRlcigpO1xuICAgIH0pO1xuICB9LFxuICB6b29tSW46IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlbGVhc2VEYXRhRmlsdGVyKCk7XG5cbiAgICAvLyBzYXZlIGN1cnJlbnQgc3RhdGVcbiAgICB0aGlzLnpvb21IaXN0b3J5LnB1c2goSlNPTi5zdHJpbmdpZnkodGhpcy5wYXJ0aXRpb25zLnRvSlNPTigpKSk7XG5cbiAgICB0aGlzLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uKSB7XG4gICAgICBpZiAoKHBhcnRpdGlvbi5zZWxlY3RlZC5sZW5ndGggPT09IDIpICYmIChwYXJ0aXRpb24uaXNEYXRldGltZSB8fCBwYXJ0aXRpb24uaXNDb250aW51b3VzKSkge1xuICAgICAgICBpZiAocGFydGl0aW9uLmdyb3VwRml4ZWRTIHx8IHBhcnRpdGlvbi5ncm91cEZpeGVkU0MpIHtcbiAgICAgICAgICAvLyBzY2FsZSBkb3duIGJpbnNpemVcbiAgICAgICAgICB2YXIgbmV3U2l6ZSA9IHBhcnRpdGlvbi5zZWxlY3RlZFsxXSAtIHBhcnRpdGlvbi5zZWxlY3RlZFswXTtcbiAgICAgICAgICB2YXIgb2xkU2l6ZSA9IHBhcnRpdGlvbi5tYXh2YWwgLSBwYXJ0aXRpb24ubWludmFsO1xuICAgICAgICAgIHBhcnRpdGlvbi5ncm91cGluZ1BhcmFtID0gcGFydGl0aW9uLmdyb3VwaW5nUGFyYW0gKiBuZXdTaXplIC8gb2xkU2l6ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyB6b29tIHRvIHNlbGVjdGVkIHJhbmdlLCBpZiBwb3NzaWJsZVxuICAgICAgICBwYXJ0aXRpb24uc2V0KHtcbiAgICAgICAgICBtaW52YWw6IHBhcnRpdGlvbi5zZWxlY3RlZFswXSxcbiAgICAgICAgICBtYXh2YWw6IHBhcnRpdGlvbi5zZWxlY3RlZFsxXVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAocGFydGl0aW9uLnNlbGVjdGVkLmxlbmd0aCA+IDAgJiYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwpKSB7XG4gICAgICAgIC8vIHpvb20gdG8gc2VsZWN0ZWQgY2F0ZWdvcmllcywgaWYgcG9zc2libGVcbiAgICAgICAgcGFydGl0aW9uLmdyb3Vwcy5yZXNldCgpO1xuICAgICAgICBwYXJ0aXRpb24uc2VsZWN0ZWQuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICBwYXJ0aXRpb24uZ3JvdXBzLmFkZCh7XG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICBsYWJlbDogdmFsdWUsXG4gICAgICAgICAgICBjb3VudDogMCxcbiAgICAgICAgICAgIGlzU2VsZWN0ZWQ6IHRydWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyBzZWxlY3QgYWxsXG4gICAgICBwYXJ0aXRpb24udXBkYXRlU2VsZWN0aW9uKCk7XG4gICAgfSk7XG4gICAgdGhpcy5pbml0RGF0YUZpbHRlcigpO1xuICAgIHRoaXMudXBkYXRlRGF0YUZpbHRlcigpOyAvLyBhbHNvIHRyaWdnZXJzIGEgZ2V0QWxsRGF0YSgpXG4gIH0sXG4gIHpvb21PdXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZG9SZXNldCA9IHRydWU7XG5cbiAgICAvLyBjbGVhciBjdXJyZW50IHNlbGVjdGlvblxuICAgIHRoaXMucGFydGl0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJ0aXRpb24pIHtcbiAgICAgIGlmIChwYXJ0aXRpb24uc2VsZWN0ZWQubGVuZ3RoID4gMCkge1xuICAgICAgICBwYXJ0aXRpb24udXBkYXRlU2VsZWN0aW9uKCk7XG4gICAgICAgIGRvUmVzZXQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChkb1Jlc2V0KSB7XG4gICAgICB0aGlzLnJlbGVhc2VEYXRhRmlsdGVyKCk7XG4gICAgICBpZiAodGhpcy56b29tSGlzdG9yeS5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIG5vdGhpbmcgd2FzIHNlbGVjdGVkIGFuZCB3ZSBoYXZlIGRyaWxsZWQgZG93bjogZ28gdXBcbiAgICAgICAgdmFyIHN0YXRlID0gSlNPTi5wYXJzZSh0aGlzLnpvb21IaXN0b3J5LnBvcCgpKTtcbiAgICAgICAgdGhpcy5wYXJ0aXRpb25zLnJlc2V0KHN0YXRlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG5vdGhpbmcgd2FzIHNlbGVjdGVkIGFuZCBubyBkcmlsbCBkb3duOiByZXNldCBwYXJ0aXRpb25pbmdcbiAgICAgICAgdGhpcy5wYXJ0aXRpb25zLmZvckVhY2goZnVuY3Rpb24gKHBhcnRpdGlvbikge1xuICAgICAgICAgIGlmIChwYXJ0aXRpb24uaXNEYXRldGltZSB8fCBwYXJ0aXRpb24uaXNDb250aW51b3VzKSB7XG4gICAgICAgICAgICBwYXJ0aXRpb24ucmVzZXQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgdGhpcy5pbml0RGF0YUZpbHRlcigpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZURhdGFGaWx0ZXIoKTsgLy8gYWxzbyB0cmlnZ2VycyBhIGdldEFsbERhdGEoKVxuICB9LFxuICAvLyBBcHBseSB0aGUgc2VwYXJhdGUgZmlsdGVyRnVuY3Rpb25zIGZyb20gZWFjaCBwYXJ0aXRpb24gaW4gYSBzaW5nbGUgZnVuY3Rpb25cbiAgZmlsdGVyRnVuY3Rpb246IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZnMgPSBbXTtcbiAgICB0aGlzLnBhcnRpdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAocGFydGl0aW9uKSB7XG4gICAgICBmcy5wdXNoKHBhcnRpdGlvbi5maWx0ZXJGdW5jdGlvbigpKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmICh0eXBlb2YgZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdmFyIGdyb3VwcyA9IGQuc3BsaXQoJ3wnKTtcbiAgICAgICAgcmV0dXJuIGZzLmV2ZXJ5KGZ1bmN0aW9uIChmLCBpKSB7IHJldHVybiBmKGdyb3Vwc1tpXSk7IH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gc2hvcnRjdXQgZm9yIG5vbi1wYXJ0aXRpb25lZCBudW1lcmljIGRhdGFcbiAgICAgICAgcmV0dXJuIGZzWzBdKGQpO1xuICAgICAgfVxuICAgIH07XG4gIH0sXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHRoZSBkYXRhIGZpbHRlciwgYW5kIGNvbnN0cnVjdCB0aGUgZ2V0RGF0YSBjYWxsYmFjayBmdW5jdGlvbiBvbiB0aGUgZmlsdGVyLlxuICAgKlxuICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgKi9cbiAgaW5pdERhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIucmVsZWFzZURhdGFGaWx0ZXIoZGF0YXZpZXcsIHRoaXMpO1xuICAgIHNwb3QuZHJpdmVyLmluaXREYXRhRmlsdGVyKGRhdGF2aWV3LCB0aGlzKTtcbiAgICBzcG90LmRyaXZlci51cGRhdGVEYXRhRmlsdGVyKHRoaXMpO1xuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgfSxcbiAgLyoqXG4gICAqIFRoZSBvcHBvc2l0ZSBvciBpbml0RGF0YUZpbHRlciwgaXQgc2hvdWxkIHJlbW92ZSB0aGUgZmlsdGVyIGFuZCBkZWFsbG9jYXRlIG90aGVyIGNvbmZpZ3VyYXRpb25cbiAgICogcmVsYXRlZCB0byB0aGUgZmlsdGVyLlxuICAgKlxuICAgKiBAbWVtYmVyb2YhIEZpbHRlclxuICAgKi9cbiAgcmVsZWFzZURhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIucmVsZWFzZURhdGFGaWx0ZXIoZGF0YXZpZXcsIHRoaXMpO1xuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gZmFsc2U7XG4gIH0sXG4gIC8qKlxuICAgKiBBcHBseSBjaGFuZ2VzIHRvIHRoZSBmaWx0ZXIgKGxpa2Ugc2VsZWN0aW5nIGdyb3VwcylcbiAgICpcbiAgICogQG1lbWJlcm9mISBGaWx0ZXJcbiAgICovXG4gIHVwZGF0ZURhdGFGaWx0ZXI6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGF0YXZpZXcgPSB0aGlzLmNvbGxlY3Rpb24ucGFyZW50O1xuICAgIHZhciBzcG90ID0gZGF0YXZpZXcucGFyZW50O1xuXG4gICAgc3BvdC5kcml2ZXIudXBkYXRlRGF0YUZpbHRlcih0aGlzKTtcbiAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9476\n")},"9b75":function(module,exports,__webpack_require__){eval("/**\n * CategorialTransfrom defines a transformation on categorial and textual data,\n * and is implemented as a collection of rules.\n *\n * @class CategorialTransform\n */\nvar Model = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\n\nvar Rule = __webpack_require__(/*! ./categorial-rule */ \"ba23\");\nvar Rules = Collection.extend({\n  indexes: ['expression'],\n  model: Rule\n});\n\n/**\n * Apply the first applicable transformation rule.\n * When no matching rule is found, return 'Other'\n *\n * @function\n * @memberof! CategorialTransform\n * @param {string} text\n * @returns {string} text The transformed text\n */\nfunction transform (rules, text) {\n  var i;\n  for (i = 0; i < rules.length; i++) {\n    var group = rules.models[i].match(text);\n    if (group) {\n      return group;\n    }\n  }\n  return 'Other';\n}\n\nmodule.exports = Model.extend({\n  props: {\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'categorial',\n      values: ['categorial']\n    },\n    transformedMin: {\n      type: 'number',\n      required: true,\n      default: 0\n    },\n    transformedMax: {\n      type: 'number',\n      required: true,\n      default: 100\n    },\n    transformedMinAsText: {\n      type: 'string',\n      required: true,\n      default: '0'\n    },\n    transformedMaxAsText: {\n      type: 'string',\n      required: true,\n      default: '100'\n    }\n  },\n  collections: {\n    rules: Rules\n  },\n  transform: function (labels) {\n    if (!this.rules) {\n      return labels;\n    }\n    if (labels instanceof Array) {\n      labels.forEach(function (label, i) {\n        labels[i] = transform(this.rules, label);\n      }, this);\n    } else {\n      labels = transform(this.rules, labels);\n    }\n    return labels;\n  },\n  reset: function () {\n    this.rules.reset();\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWI3NS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY2F0ZWdvcmlhbC10cmFuc2Zvcm0uanM/MzBlYiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENhdGVnb3JpYWxUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNhdGVnb3JpYWwgYW5kIHRleHR1YWwgZGF0YSxcbiAqIGFuZCBpcyBpbXBsZW1lbnRlZCBhcyBhIGNvbGxlY3Rpb24gb2YgcnVsZXMuXG4gKlxuICogQGNsYXNzIENhdGVnb3JpYWxUcmFuc2Zvcm1cbiAqL1xudmFyIE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG52YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG5cbnZhciBSdWxlID0gcmVxdWlyZSgnLi9jYXRlZ29yaWFsLXJ1bGUnKTtcbnZhciBSdWxlcyA9IENvbGxlY3Rpb24uZXh0ZW5kKHtcbiAgaW5kZXhlczogWydleHByZXNzaW9uJ10sXG4gIG1vZGVsOiBSdWxlXG59KTtcblxuLyoqXG4gKiBBcHBseSB0aGUgZmlyc3QgYXBwbGljYWJsZSB0cmFuc2Zvcm1hdGlvbiBydWxlLlxuICogV2hlbiBubyBtYXRjaGluZyBydWxlIGlzIGZvdW5kLCByZXR1cm4gJ090aGVyJ1xuICpcbiAqIEBmdW5jdGlvblxuICogQG1lbWJlcm9mISBDYXRlZ29yaWFsVHJhbnNmb3JtXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICogQHJldHVybnMge3N0cmluZ30gdGV4dCBUaGUgdHJhbnNmb3JtZWQgdGV4dFxuICovXG5mdW5jdGlvbiB0cmFuc2Zvcm0gKHJ1bGVzLCB0ZXh0KSB7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgcnVsZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZ3JvdXAgPSBydWxlcy5tb2RlbHNbaV0ubWF0Y2godGV4dCk7XG4gICAgaWYgKGdyb3VwKSB7XG4gICAgICByZXR1cm4gZ3JvdXA7XG4gICAgfVxuICB9XG4gIHJldHVybiAnT3RoZXInO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IE1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgdHJhbnNmb3JtZWRUeXBlOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJ2NhdGVnb3JpYWwnLFxuICAgICAgdmFsdWVzOiBbJ2NhdGVnb3JpYWwnXVxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNaW46IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAwXG4gICAgfSxcbiAgICB0cmFuc2Zvcm1lZE1heDoge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6IDEwMFxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNaW5Bc1RleHQ6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnMCdcbiAgICB9LFxuICAgIHRyYW5zZm9ybWVkTWF4QXNUZXh0OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogJzEwMCdcbiAgICB9XG4gIH0sXG4gIGNvbGxlY3Rpb25zOiB7XG4gICAgcnVsZXM6IFJ1bGVzXG4gIH0sXG4gIHRyYW5zZm9ybTogZnVuY3Rpb24gKGxhYmVscykge1xuICAgIGlmICghdGhpcy5ydWxlcykge1xuICAgICAgcmV0dXJuIGxhYmVscztcbiAgICB9XG4gICAgaWYgKGxhYmVscyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBsYWJlbHMuZm9yRWFjaChmdW5jdGlvbiAobGFiZWwsIGkpIHtcbiAgICAgICAgbGFiZWxzW2ldID0gdHJhbnNmb3JtKHRoaXMucnVsZXMsIGxhYmVsKTtcbiAgICAgIH0sIHRoaXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYWJlbHMgPSB0cmFuc2Zvcm0odGhpcy5ydWxlcywgbGFiZWxzKTtcbiAgICB9XG4gICAgcmV0dXJuIGxhYmVscztcbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJ1bGVzLnJlc2V0KCk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9b75\n")},"9d63":function(module,exports,__webpack_require__){eval("/**\n * The Aggregate class describes how to aggregate data, as described by a `Facet` into a single value.\n * For example, you can sum or average over numbers, or count the number of different labels.\n *\n * @class Aggregate\n * @extends Base\n */\nvar BaseModel = __webpack_require__(/*! ./util/base */ \"3902\");\n\nmodule.exports = BaseModel.extend({\n  props: {\n    /**\n     * The name of the facet to aggregate over\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    facetName: 'string',\n\n    /**\n     * Label for displaying on plots\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    label: {\n      type: 'string',\n      required: true,\n      default: ''\n    },\n\n    /**\n     * When part of a aggregates, this deterimines the ordering\n     * @memberof! Aggregate\n     * @type {number}\n     */\n    rank: {\n      type: 'number',\n      required: true\n    },\n\n    /**\n     * Operation:\n     *  * `count`  count the number of elements in the group\n     *  * `sum`    sum the elements in the group\n     *  * `avg`    take the average of the elements in the group\n     *  * `stddev`  take the sample\n     *  * `min`    minum value of the elements in the group\n     *  * `max`    maximum value of the elements in the group\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    operation: {\n      type: 'string',\n      required: true,\n      default: 'avg',\n      values: ['count', 'avg', 'sum', 'stddev', 'min', 'max']\n    },\n    // NOTE: properties for reduction, should be a valid SQL aggregation function\n\n    /**\n     * Normalization: TODO\n     *  * `none`      data in same units as the original data\n     *  * `relative`  data is in percentages of the total; for subgroups in percentage of the parent group\n     * @memberof! Aggregate\n     * @type {string}\n     */\n    normalization: {\n      type: 'string',\n      required: true,\n      default: 'none',\n      values: ['none', 'percentage']\n    }\n  },\n  derived: {\n    // operation values\n    doSum: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'sum';\n      }\n    },\n    doCount: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'count';\n      }\n    },\n    doAverage: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'avg';\n      }\n    },\n    doStddev: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'stddev';\n      }\n    },\n    doMin: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'min';\n      }\n    },\n    doMax: {\n      deps: ['operation'],\n      fn: function () {\n        return this.operation === 'max';\n      }\n    },\n\n    // normalization values\n    normalizeNone: {\n      deps: ['normalization'],\n      fn: function () {\n        return this.normalization === 'absolute';\n      }\n    },\n    normalizePercentage: {\n      deps: ['normalization'],\n      fn: function () {\n        return this.normalization === 'percentage';\n      }\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOWQ2My5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvYWdncmVnYXRlLmpzP2JkNmEiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgQWdncmVnYXRlIGNsYXNzIGRlc2NyaWJlcyBob3cgdG8gYWdncmVnYXRlIGRhdGEsIGFzIGRlc2NyaWJlZCBieSBhIGBGYWNldGAgaW50byBhIHNpbmdsZSB2YWx1ZS5cbiAqIEZvciBleGFtcGxlLCB5b3UgY2FuIHN1bSBvciBhdmVyYWdlIG92ZXIgbnVtYmVycywgb3IgY291bnQgdGhlIG51bWJlciBvZiBkaWZmZXJlbnQgbGFiZWxzLlxuICpcbiAqIEBjbGFzcyBBZ2dyZWdhdGVcbiAqIEBleHRlbmRzIEJhc2VcbiAqL1xudmFyIEJhc2VNb2RlbCA9IHJlcXVpcmUoJy4vdXRpbC9iYXNlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQmFzZU1vZGVsLmV4dGVuZCh7XG4gIHByb3BzOiB7XG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGZhY2V0IHRvIGFnZ3JlZ2F0ZSBvdmVyXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZhY2V0TmFtZTogJ3N0cmluZycsXG5cbiAgICAvKipcbiAgICAgKiBMYWJlbCBmb3IgZGlzcGxheWluZyBvbiBwbG90c1xuICAgICAqIEBtZW1iZXJvZiEgQWdncmVnYXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBsYWJlbDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICcnXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFdoZW4gcGFydCBvZiBhIGFnZ3JlZ2F0ZXMsIHRoaXMgZGV0ZXJpbWluZXMgdGhlIG9yZGVyaW5nXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHJhbms6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogT3BlcmF0aW9uOlxuICAgICAqICAqIGBjb3VudGAgIGNvdW50IHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGdyb3VwXG4gICAgICogICogYHN1bWAgICAgc3VtIHRoZSBlbGVtZW50cyBpbiB0aGUgZ3JvdXBcbiAgICAgKiAgKiBgYXZnYCAgICB0YWtlIHRoZSBhdmVyYWdlIG9mIHRoZSBlbGVtZW50cyBpbiB0aGUgZ3JvdXBcbiAgICAgKiAgKiBgc3RkZGV2YCAgdGFrZSB0aGUgc2FtcGxlXG4gICAgICogICogYG1pbmAgICAgbWludW0gdmFsdWUgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBncm91cFxuICAgICAqICAqIGBtYXhgICAgIG1heGltdW0gdmFsdWUgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBncm91cFxuICAgICAqIEBtZW1iZXJvZiEgQWdncmVnYXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBvcGVyYXRpb246IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnYXZnJyxcbiAgICAgIHZhbHVlczogWydjb3VudCcsICdhdmcnLCAnc3VtJywgJ3N0ZGRldicsICdtaW4nLCAnbWF4J11cbiAgICB9LFxuICAgIC8vIE5PVEU6IHByb3BlcnRpZXMgZm9yIHJlZHVjdGlvbiwgc2hvdWxkIGJlIGEgdmFsaWQgU1FMIGFnZ3JlZ2F0aW9uIGZ1bmN0aW9uXG5cbiAgICAvKipcbiAgICAgKiBOb3JtYWxpemF0aW9uOiBUT0RPXG4gICAgICogICogYG5vbmVgICAgICAgZGF0YSBpbiBzYW1lIHVuaXRzIGFzIHRoZSBvcmlnaW5hbCBkYXRhXG4gICAgICogICogYHJlbGF0aXZlYCAgZGF0YSBpcyBpbiBwZXJjZW50YWdlcyBvZiB0aGUgdG90YWw7IGZvciBzdWJncm91cHMgaW4gcGVyY2VudGFnZSBvZiB0aGUgcGFyZW50IGdyb3VwXG4gICAgICogQG1lbWJlcm9mISBBZ2dyZWdhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG5vcm1hbGl6YXRpb246IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAnbm9uZScsXG4gICAgICB2YWx1ZXM6IFsnbm9uZScsICdwZXJjZW50YWdlJ11cbiAgICB9XG4gIH0sXG4gIGRlcml2ZWQ6IHtcbiAgICAvLyBvcGVyYXRpb24gdmFsdWVzXG4gICAgZG9TdW06IHtcbiAgICAgIGRlcHM6IFsnb3BlcmF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vcGVyYXRpb24gPT09ICdzdW0nO1xuICAgICAgfVxuICAgIH0sXG4gICAgZG9Db3VudDoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ2NvdW50JztcbiAgICAgIH1cbiAgICB9LFxuICAgIGRvQXZlcmFnZToge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ2F2Zyc7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb1N0ZGRldjoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ3N0ZGRldic7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb01pbjoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ21pbic7XG4gICAgICB9XG4gICAgfSxcbiAgICBkb01heDoge1xuICAgICAgZGVwczogWydvcGVyYXRpb24nXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZXJhdGlvbiA9PT0gJ21heCc7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8vIG5vcm1hbGl6YXRpb24gdmFsdWVzXG4gICAgbm9ybWFsaXplTm9uZToge1xuICAgICAgZGVwczogWydub3JtYWxpemF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxpemF0aW9uID09PSAnYWJzb2x1dGUnO1xuICAgICAgfVxuICAgIH0sXG4gICAgbm9ybWFsaXplUGVyY2VudGFnZToge1xuICAgICAgZGVwczogWydub3JtYWxpemF0aW9uJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxpemF0aW9uID09PSAncGVyY2VudGFnZSc7XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9d63\n")},a0ca:function(module,exports,__webpack_require__){eval("/**\n * DatetimeTransform defines a transformation on time or dates with timezones\n *\n * @class DatetimeTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\nvar misval = __webpack_require__(/*! ../util/misval */ \"bff6\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Timezone to use when parsing, for when timezone information is absent or incorrect.\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    zone: ['string', true, 'ISO8601'],\n\n    /**\n     * Format indentifier to use when parsing, when not in ISO8601 format\n     * Mappings are defined in util/time.js => timeParts.description\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    format: ['string', true, 'ISO8601'],\n\n    /**\n     * Reformats to a string using the momentjs or postgreSQL format specifiers.\n     * This allows a transformation to day of the year, or day of week etc.\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedFormat: ['string', true, 'ISO8601'],\n\n    /**\n     * Controls conversion to duration by subtracting this date\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedReference: 'string',\n\n    /**\n     * Reference timezone for conversion from datetime to duration\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedZone: ['string', true, 'ISO8601']\n\n  },\n  derived: {\n    // reference momentjs for duration <-> datetime conversion\n    referenceMoment: {\n      deps: ['transformedReference', 'transformedZone'],\n      fn: function () {\n        var tz;\n        if (this.transformedZone === 'ISO8601') {\n          tz = moment.tz.guess();\n        } else {\n          var timeZone = util.timeZones.get(this.transformedZone, 'description');\n          if (timeZone && timeZone.format) {\n            tz = timeZone.format;\n          } else {\n            tz = moment.tz.guess();\n          }\n        }\n        if (this.transformedReference) {\n          return moment.tz(this.transformedReference, tz);\n        }\n        return null;\n      }\n    },\n    /**\n     * The type of the facet after the transformation has been applied\n     * @memberof! DatetimeTransform\n     */\n    transformedType: {\n      deps: ['transformedFormat', 'transformedReference'],\n      fn: function () {\n        if (this.transformedReference) {\n          // datetime -> duration\n          return 'duration';\n        } else if (this.transformedFormat === 'ISO8601') {\n          // datetime -> datetime\n          return 'datetime';\n        } else {\n          // datetime -> time part\n          var timePart = util.timeParts.get(this.transformedFormat, 'description');\n          if (timePart && timePart.type) {\n            return timePart.type;\n          }\n        }\n        return 'datetime';\n      },\n      cache: false\n    },\n    /**\n     * The minium value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! DatetimeTransform\n     */\n    transformedMin: {\n      deps: ['transformedType'],\n      fn: function () {\n        var timePart;\n        if (this.transformedType === 'datetime' || this.transformedType === 'duration') {\n          return this.transform(this.parent.minval);\n        }\n        timePart = util.timeParts.get(this.transformedFormat, 'description');\n        if (timePart.calcualte) {\n          return this.transform(this.parent.minval);\n        } else {\n          return timePart.min;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     * @type {number}\n     * @memberof! DatetimeTransform\n     */\n    transformedMax: {\n      deps: ['transformedType'],\n      fn: function () {\n        var timePart;\n        if (this.transformedType === 'datetime' || this.transformedType === 'duration') {\n          return this.transform(this.parent.maxval);\n        }\n        timePart = util.timeParts.get(this.transformedFormat, 'description');\n        if (timePart.calcualte) {\n          return this.transform(this.parent.maxval);\n        } else {\n          return timePart.max;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DatetimeTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DatetimeTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n\n  /**\n   * @function\n   * @memberof! DatetimeTransform\n   * @param {Object} momentjs\n   * @returns {Object} momentjs\n   */\n  transform: function transform (inval) {\n    if (typeof inval === 'undefined') {\n      return misval;\n    }\n\n    var d = inval.clone();\n    var timePart;\n\n    if (this.referenceMoment) {\n      // datetime -> duration\n      return moment.duration(d.diff(this.referenceMoment, 'milliseconds', true), 'milliseconds');\n    } else if (this.transformedFormat !== 'ISO8601') {\n      timePart = util.timeParts.get(this.transformedFormat, 'description');\n      if (timePart && timePart.momentFormat) {\n        return d.format(timePart.momentFormat);\n      }\n      return d;\n    } else {\n      return d;\n    }\n  },\n  reset: function () {\n    this.unset(['zone', 'transformedFormat', 'transformedZone', 'transformedReference']);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYTBjYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvZGF0ZXRpbWUtdHJhbnNmb3JtLmpzPzM1YTIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEYXRldGltZVRyYW5zZm9ybSBkZWZpbmVzIGEgdHJhbnNmb3JtYXRpb24gb24gdGltZSBvciBkYXRlcyB3aXRoIHRpbWV6b25lc1xuICpcbiAqIEBjbGFzcyBEYXRldGltZVRyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC90aW1lJyk7XG52YXIgbWlzdmFsID0gcmVxdWlyZSgnLi4vdXRpbC9taXN2YWwnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRpbWV6b25lIHRvIHVzZSB3aGVuIHBhcnNpbmcsIGZvciB3aGVuIHRpbWV6b25lIGluZm9ybWF0aW9uIGlzIGFic2VudCBvciBpbmNvcnJlY3QuXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgem9uZTogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogRm9ybWF0IGluZGVudGlmaWVyIHRvIHVzZSB3aGVuIHBhcnNpbmcsIHdoZW4gbm90IGluIElTTzg2MDEgZm9ybWF0XG4gICAgICogTWFwcGluZ3MgYXJlIGRlZmluZWQgaW4gdXRpbC90aW1lLmpzID0+IHRpbWVQYXJ0cy5kZXNjcmlwdGlvblxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZvcm1hdDogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogUmVmb3JtYXRzIHRvIGEgc3RyaW5nIHVzaW5nIHRoZSBtb21lbnRqcyBvciBwb3N0Z3JlU1FMIGZvcm1hdCBzcGVjaWZpZXJzLlxuICAgICAqIFRoaXMgYWxsb3dzIGEgdHJhbnNmb3JtYXRpb24gdG8gZGF5IG9mIHRoZSB5ZWFyLCBvciBkYXkgb2Ygd2VlayBldGMuXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRGb3JtYXQ6IFsnc3RyaW5nJywgdHJ1ZSwgJ0lTTzg2MDEnXSxcblxuICAgIC8qKlxuICAgICAqIENvbnRyb2xzIGNvbnZlcnNpb24gdG8gZHVyYXRpb24gYnkgc3VidHJhY3RpbmcgdGhpcyBkYXRlXG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRSZWZlcmVuY2U6ICdzdHJpbmcnLFxuXG4gICAgLyoqXG4gICAgICogUmVmZXJlbmNlIHRpbWV6b25lIGZvciBjb252ZXJzaW9uIGZyb20gZGF0ZXRpbWUgdG8gZHVyYXRpb25cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFpvbmU6IFsnc3RyaW5nJywgdHJ1ZSwgJ0lTTzg2MDEnXVxuXG4gIH0sXG4gIGRlcml2ZWQ6IHtcbiAgICAvLyByZWZlcmVuY2UgbW9tZW50anMgZm9yIGR1cmF0aW9uIDwtPiBkYXRldGltZSBjb252ZXJzaW9uXG4gICAgcmVmZXJlbmNlTW9tZW50OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkUmVmZXJlbmNlJywgJ3RyYW5zZm9ybWVkWm9uZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHR6O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFpvbmUgPT09ICdJU084NjAxJykge1xuICAgICAgICAgIHR6ID0gbW9tZW50LnR6Lmd1ZXNzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHRpbWVab25lID0gdXRpbC50aW1lWm9uZXMuZ2V0KHRoaXMudHJhbnNmb3JtZWRab25lLCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgICBpZiAodGltZVpvbmUgJiYgdGltZVpvbmUuZm9ybWF0KSB7XG4gICAgICAgICAgICB0eiA9IHRpbWVab25lLmZvcm1hdDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHogPSBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXR1cm4gbW9tZW50LnR6KHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UsIHR6KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBmYWNldCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFR5cGU6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRGb3JtYXQnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkUmVmZXJlbmNlKSB7XG4gICAgICAgICAgLy8gZGF0ZXRpbWUgLT4gZHVyYXRpb25cbiAgICAgICAgICByZXR1cm4gJ2R1cmF0aW9uJztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0ID09PSAnSVNPODYwMScpIHtcbiAgICAgICAgICAvLyBkYXRldGltZSAtPiBkYXRldGltZVxuICAgICAgICAgIHJldHVybiAnZGF0ZXRpbWUnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGRhdGV0aW1lIC0+IHRpbWUgcGFydFxuICAgICAgICAgIHZhciB0aW1lUGFydCA9IHV0aWwudGltZVBhcnRzLmdldCh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgICBpZiAodGltZVBhcnQgJiYgdGltZVBhcnQudHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRpbWVQYXJ0LnR5cGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnZGF0ZXRpbWUnO1xuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1pbml1bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluOiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRpbWVQYXJ0O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScgfHwgdGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkdXJhdGlvbicpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0odGhpcy5wYXJlbnQubWludmFsKTtcbiAgICAgICAgfVxuICAgICAgICB0aW1lUGFydCA9IHV0aWwudGltZVBhcnRzLmdldCh0aGlzLnRyYW5zZm9ybWVkRm9ybWF0LCAnZGVzY3JpcHRpb24nKTtcbiAgICAgICAgaWYgKHRpbWVQYXJ0LmNhbGN1YWx0ZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybSh0aGlzLnBhcmVudC5taW52YWwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aW1lUGFydC5taW47XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNYXg6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGltZVBhcnQ7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJyB8fCB0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2R1cmF0aW9uJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybSh0aGlzLnBhcmVudC5tYXh2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHRpbWVQYXJ0ID0gdXRpbC50aW1lUGFydHMuZ2V0KHRoaXMudHJhbnNmb3JtZWRGb3JtYXQsICdkZXNjcmlwdGlvbicpO1xuICAgICAgICBpZiAodGltZVBhcnQuY2FsY3VhbHRlKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKHRoaXMucGFyZW50Lm1heHZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRpbWVQYXJ0Lm1heDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKlxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQG1lbWJlcm9mISBEYXRldGltZVRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWluQXNUZXh0OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkTWluJywgJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1pbnZhbCA9IHRoaXMudHJhbnNmb3JtZWRNaW47XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiBtaW52YWwuZm9ybWF0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNYXhBc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRNYXgnLCAndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWF4dmFsID0gdGhpcy50cmFuc2Zvcm1lZE1heDtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnZGF0ZXRpbWUnKSB7XG4gICAgICAgICAgcmV0dXJuIG1heHZhbC5mb3JtYXQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIEBmdW5jdGlvblxuICAgKiBAbWVtYmVyb2YhIERhdGV0aW1lVHJhbnNmb3JtXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtb21lbnRqc1xuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBtb21lbnRqc1xuICAgKi9cbiAgdHJhbnNmb3JtOiBmdW5jdGlvbiB0cmFuc2Zvcm0gKGludmFsKSB7XG4gICAgaWYgKHR5cGVvZiBpbnZhbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfVxuXG4gICAgdmFyIGQgPSBpbnZhbC5jbG9uZSgpO1xuICAgIHZhciB0aW1lUGFydDtcblxuICAgIGlmICh0aGlzLnJlZmVyZW5jZU1vbWVudCkge1xuICAgICAgLy8gZGF0ZXRpbWUgLT4gZHVyYXRpb25cbiAgICAgIHJldHVybiBtb21lbnQuZHVyYXRpb24oZC5kaWZmKHRoaXMucmVmZXJlbmNlTW9tZW50LCAnbWlsbGlzZWNvbmRzJywgdHJ1ZSksICdtaWxsaXNlY29uZHMnKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudHJhbnNmb3JtZWRGb3JtYXQgIT09ICdJU084NjAxJykge1xuICAgICAgdGltZVBhcnQgPSB1dGlsLnRpbWVQYXJ0cy5nZXQodGhpcy50cmFuc2Zvcm1lZEZvcm1hdCwgJ2Rlc2NyaXB0aW9uJyk7XG4gICAgICBpZiAodGltZVBhcnQgJiYgdGltZVBhcnQubW9tZW50Rm9ybWF0KSB7XG4gICAgICAgIHJldHVybiBkLmZvcm1hdCh0aW1lUGFydC5tb21lbnRGb3JtYXQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBkO1xuICAgIH1cbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVuc2V0KFsnem9uZScsICd0cmFuc2Zvcm1lZEZvcm1hdCcsICd0cmFuc2Zvcm1lZFpvbmUnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///a0ca\n")},aa6c:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/**\n * Module dependencies.\n */\n\nvar keys = __webpack_require__(/*! ./keys */ \"7d91\");\nvar hasBinary = __webpack_require__(/*! has-binary */ \"d304\");\nvar sliceBuffer = __webpack_require__(/*! arraybuffer.slice */ \"ef13\");\nvar after = __webpack_require__(/*! after */ \"4aa5\");\nvar utf8 = __webpack_require__(/*! wtf-8 */ \"943e\");\n\nvar base64encoder;\nif (global && global.ArrayBuffer) {\n  base64encoder = __webpack_require__(/*! base64-arraybuffer */ \"21de\");\n}\n\n/**\n * Check if we are running an android browser. That requires us to use\n * ArrayBuffer with polling transports...\n *\n * http://ghinda.net/jpeg-blob-ajax-android/\n */\n\nvar isAndroid = typeof navigator !== 'undefined' && /Android/i.test(navigator.userAgent);\n\n/**\n * Check if we are running in PhantomJS.\n * Uploading a Blob with PhantomJS does not work correctly, as reported here:\n * https://github.com/ariya/phantomjs/issues/11395\n * @type boolean\n */\nvar isPhantomJS = typeof navigator !== 'undefined' && /PhantomJS/i.test(navigator.userAgent);\n\n/**\n * When true, avoids using Blobs to encode payloads.\n * @type boolean\n */\nvar dontSendBlobs = isAndroid || isPhantomJS;\n\n/**\n * Current protocol version.\n */\n\nexports.protocol = 3;\n\n/**\n * Packet types.\n */\n\nvar packets = exports.packets = {\n    open:     0    // non-ws\n  , close:    1    // non-ws\n  , ping:     2\n  , pong:     3\n  , message:  4\n  , upgrade:  5\n  , noop:     6\n};\n\nvar packetslist = keys(packets);\n\n/**\n * Premade error packet.\n */\n\nvar err = { type: 'error', data: 'parser error' };\n\n/**\n * Create a blob api even for blob builder when vendor prefixes exist\n */\n\nvar Blob = __webpack_require__(/*! blob */ \"939f\");\n\n/**\n * Encodes a packet.\n *\n *     <packet type id> [ <data> ]\n *\n * Example:\n *\n *     5hello world\n *     3\n *     4\n *\n * Binary is encoded in an identical principle\n *\n * @api private\n */\n\nexports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {\n  if ('function' == typeof supportsBinary) {\n    callback = supportsBinary;\n    supportsBinary = false;\n  }\n\n  if ('function' == typeof utf8encode) {\n    callback = utf8encode;\n    utf8encode = null;\n  }\n\n  var data = (packet.data === undefined)\n    ? undefined\n    : packet.data.buffer || packet.data;\n\n  if (global.ArrayBuffer && data instanceof ArrayBuffer) {\n    return encodeArrayBuffer(packet, supportsBinary, callback);\n  } else if (Blob && data instanceof global.Blob) {\n    return encodeBlob(packet, supportsBinary, callback);\n  }\n\n  // might be an object with { base64: true, data: dataAsBase64String }\n  if (data && data.base64) {\n    return encodeBase64Object(packet, callback);\n  }\n\n  // Sending data as a utf-8 string\n  var encoded = packets[packet.type];\n\n  // data fragment is optional\n  if (undefined !== packet.data) {\n    encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data);\n  }\n\n  return callback('' + encoded);\n\n};\n\nfunction encodeBase64Object(packet, callback) {\n  // packet data is an object { base64: true, data: dataAsBase64String }\n  var message = 'b' + exports.packets[packet.type] + packet.data.data;\n  return callback(message);\n}\n\n/**\n * Encode packet helpers for binary types\n */\n\nfunction encodeArrayBuffer(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  var data = packet.data;\n  var contentArray = new Uint8Array(data);\n  var resultBuffer = new Uint8Array(1 + data.byteLength);\n\n  resultBuffer[0] = packets[packet.type];\n  for (var i = 0; i < contentArray.length; i++) {\n    resultBuffer[i+1] = contentArray[i];\n  }\n\n  return callback(resultBuffer.buffer);\n}\n\nfunction encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  var fr = new FileReader();\n  fr.onload = function() {\n    packet.data = fr.result;\n    exports.encodePacket(packet, supportsBinary, true, callback);\n  };\n  return fr.readAsArrayBuffer(packet.data);\n}\n\nfunction encodeBlob(packet, supportsBinary, callback) {\n  if (!supportsBinary) {\n    return exports.encodeBase64Packet(packet, callback);\n  }\n\n  if (dontSendBlobs) {\n    return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);\n  }\n\n  var length = new Uint8Array(1);\n  length[0] = packets[packet.type];\n  var blob = new Blob([length.buffer, packet.data]);\n\n  return callback(blob);\n}\n\n/**\n * Encodes a packet with binary data in a base64 string\n *\n * @param {Object} packet, has `type` and `data`\n * @return {String} base64 encoded message\n */\n\nexports.encodeBase64Packet = function(packet, callback) {\n  var message = 'b' + exports.packets[packet.type];\n  if (Blob && packet.data instanceof global.Blob) {\n    var fr = new FileReader();\n    fr.onload = function() {\n      var b64 = fr.result.split(',')[1];\n      callback(message + b64);\n    };\n    return fr.readAsDataURL(packet.data);\n  }\n\n  var b64data;\n  try {\n    b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));\n  } catch (e) {\n    // iPhone Safari doesn't let you apply with typed arrays\n    var typed = new Uint8Array(packet.data);\n    var basic = new Array(typed.length);\n    for (var i = 0; i < typed.length; i++) {\n      basic[i] = typed[i];\n    }\n    b64data = String.fromCharCode.apply(null, basic);\n  }\n  message += global.btoa(b64data);\n  return callback(message);\n};\n\n/**\n * Decodes a packet. Changes format to Blob if requested.\n *\n * @return {Object} with `type` and `data` (if any)\n * @api private\n */\n\nexports.decodePacket = function (data, binaryType, utf8decode) {\n  if (data === undefined) {\n    return err;\n  }\n  // String data\n  if (typeof data == 'string') {\n    if (data.charAt(0) == 'b') {\n      return exports.decodeBase64Packet(data.substr(1), binaryType);\n    }\n\n    if (utf8decode) {\n      data = tryDecode(data);\n      if (data === false) {\n        return err;\n      }\n    }\n    var type = data.charAt(0);\n\n    if (Number(type) != type || !packetslist[type]) {\n      return err;\n    }\n\n    if (data.length > 1) {\n      return { type: packetslist[type], data: data.substring(1) };\n    } else {\n      return { type: packetslist[type] };\n    }\n  }\n\n  var asArray = new Uint8Array(data);\n  var type = asArray[0];\n  var rest = sliceBuffer(data, 1);\n  if (Blob && binaryType === 'blob') {\n    rest = new Blob([rest]);\n  }\n  return { type: packetslist[type], data: rest };\n};\n\nfunction tryDecode(data) {\n  try {\n    data = utf8.decode(data);\n  } catch (e) {\n    return false;\n  }\n  return data;\n}\n\n/**\n * Decodes a packet encoded in a base64 string\n *\n * @param {String} base64 encoded message\n * @return {Object} with `type` and `data` (if any)\n */\n\nexports.decodeBase64Packet = function(msg, binaryType) {\n  var type = packetslist[msg.charAt(0)];\n  if (!base64encoder) {\n    return { type: type, data: { base64: true, data: msg.substr(1) } };\n  }\n\n  var data = base64encoder.decode(msg.substr(1));\n\n  if (binaryType === 'blob' && Blob) {\n    data = new Blob([data]);\n  }\n\n  return { type: type, data: data };\n};\n\n/**\n * Encodes multiple messages (payload).\n *\n *     <length>:data\n *\n * Example:\n *\n *     11:hello world2:hi\n *\n * If any contents are binary, they will be encoded as base64 strings. Base64\n * encoded strings are marked with a b before the length specifier\n *\n * @param {Array} packets\n * @api private\n */\n\nexports.encodePayload = function (packets, supportsBinary, callback) {\n  if (typeof supportsBinary == 'function') {\n    callback = supportsBinary;\n    supportsBinary = null;\n  }\n\n  var isBinary = hasBinary(packets);\n\n  if (supportsBinary && isBinary) {\n    if (Blob && !dontSendBlobs) {\n      return exports.encodePayloadAsBlob(packets, callback);\n    }\n\n    return exports.encodePayloadAsArrayBuffer(packets, callback);\n  }\n\n  if (!packets.length) {\n    return callback('0:');\n  }\n\n  function setLengthHeader(message) {\n    return message.length + ':' + message;\n  }\n\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function(message) {\n      doneCallback(null, setLengthHeader(message));\n    });\n  }\n\n  map(packets, encodeOne, function(err, results) {\n    return callback(results.join(''));\n  });\n};\n\n/**\n * Async array map using after\n */\n\nfunction map(ary, each, done) {\n  var result = new Array(ary.length);\n  var next = after(ary.length, done);\n\n  var eachWithIndex = function(i, el, cb) {\n    each(el, function(error, msg) {\n      result[i] = msg;\n      cb(error, result);\n    });\n  };\n\n  for (var i = 0; i < ary.length; i++) {\n    eachWithIndex(i, ary[i], next);\n  }\n}\n\n/*\n * Decodes data when a payload is maybe expected. Possible binary contents are\n * decoded from their base64 representation\n *\n * @param {String} data, callback method\n * @api public\n */\n\nexports.decodePayload = function (data, binaryType, callback) {\n  if (typeof data != 'string') {\n    return exports.decodePayloadAsBinary(data, binaryType, callback);\n  }\n\n  if (typeof binaryType === 'function') {\n    callback = binaryType;\n    binaryType = null;\n  }\n\n  var packet;\n  if (data == '') {\n    // parser error - ignoring payload\n    return callback(err, 0, 1);\n  }\n\n  var length = ''\n    , n, msg;\n\n  for (var i = 0, l = data.length; i < l; i++) {\n    var chr = data.charAt(i);\n\n    if (':' != chr) {\n      length += chr;\n    } else {\n      if ('' == length || (length != (n = Number(length)))) {\n        // parser error - ignoring payload\n        return callback(err, 0, 1);\n      }\n\n      msg = data.substr(i + 1, n);\n\n      if (length != msg.length) {\n        // parser error - ignoring payload\n        return callback(err, 0, 1);\n      }\n\n      if (msg.length) {\n        packet = exports.decodePacket(msg, binaryType, true);\n\n        if (err.type == packet.type && err.data == packet.data) {\n          // parser error in individual packet - ignoring payload\n          return callback(err, 0, 1);\n        }\n\n        var ret = callback(packet, i + n, l);\n        if (false === ret) return;\n      }\n\n      // advance cursor\n      i += n;\n      length = '';\n    }\n  }\n\n  if (length != '') {\n    // parser error - ignoring payload\n    return callback(err, 0, 1);\n  }\n\n};\n\n/**\n * Encodes multiple messages (payload) as binary.\n *\n * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number\n * 255><data>\n *\n * Example:\n * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers\n *\n * @param {Array} packets\n * @return {ArrayBuffer} encoded payload\n * @api private\n */\n\nexports.encodePayloadAsArrayBuffer = function(packets, callback) {\n  if (!packets.length) {\n    return callback(new ArrayBuffer(0));\n  }\n\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, true, true, function(data) {\n      return doneCallback(null, data);\n    });\n  }\n\n  map(packets, encodeOne, function(err, encodedPackets) {\n    var totalLength = encodedPackets.reduce(function(acc, p) {\n      var len;\n      if (typeof p === 'string'){\n        len = p.length;\n      } else {\n        len = p.byteLength;\n      }\n      return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2\n    }, 0);\n\n    var resultArray = new Uint8Array(totalLength);\n\n    var bufferIndex = 0;\n    encodedPackets.forEach(function(p) {\n      var isString = typeof p === 'string';\n      var ab = p;\n      if (isString) {\n        var view = new Uint8Array(p.length);\n        for (var i = 0; i < p.length; i++) {\n          view[i] = p.charCodeAt(i);\n        }\n        ab = view.buffer;\n      }\n\n      if (isString) { // not true binary\n        resultArray[bufferIndex++] = 0;\n      } else { // true binary\n        resultArray[bufferIndex++] = 1;\n      }\n\n      var lenStr = ab.byteLength.toString();\n      for (var i = 0; i < lenStr.length; i++) {\n        resultArray[bufferIndex++] = parseInt(lenStr[i]);\n      }\n      resultArray[bufferIndex++] = 255;\n\n      var view = new Uint8Array(ab);\n      for (var i = 0; i < view.length; i++) {\n        resultArray[bufferIndex++] = view[i];\n      }\n    });\n\n    return callback(resultArray.buffer);\n  });\n};\n\n/**\n * Encode as Blob\n */\n\nexports.encodePayloadAsBlob = function(packets, callback) {\n  function encodeOne(packet, doneCallback) {\n    exports.encodePacket(packet, true, true, function(encoded) {\n      var binaryIdentifier = new Uint8Array(1);\n      binaryIdentifier[0] = 1;\n      if (typeof encoded === 'string') {\n        var view = new Uint8Array(encoded.length);\n        for (var i = 0; i < encoded.length; i++) {\n          view[i] = encoded.charCodeAt(i);\n        }\n        encoded = view.buffer;\n        binaryIdentifier[0] = 0;\n      }\n\n      var len = (encoded instanceof ArrayBuffer)\n        ? encoded.byteLength\n        : encoded.size;\n\n      var lenStr = len.toString();\n      var lengthAry = new Uint8Array(lenStr.length + 1);\n      for (var i = 0; i < lenStr.length; i++) {\n        lengthAry[i] = parseInt(lenStr[i]);\n      }\n      lengthAry[lenStr.length] = 255;\n\n      if (Blob) {\n        var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);\n        doneCallback(null, blob);\n      }\n    });\n  }\n\n  map(packets, encodeOne, function(err, results) {\n    return callback(new Blob(results));\n  });\n};\n\n/*\n * Decodes data when a payload is maybe expected. Strings are decoded by\n * interpreting each byte as a key code for entries marked to start with 0. See\n * description of encodePayloadAsBinary\n *\n * @param {ArrayBuffer} data, callback method\n * @api public\n */\n\nexports.decodePayloadAsBinary = function (data, binaryType, callback) {\n  if (typeof binaryType === 'function') {\n    callback = binaryType;\n    binaryType = null;\n  }\n\n  var bufferTail = data;\n  var buffers = [];\n\n  var numberTooLong = false;\n  while (bufferTail.byteLength > 0) {\n    var tailArray = new Uint8Array(bufferTail);\n    var isString = tailArray[0] === 0;\n    var msgLength = '';\n\n    for (var i = 1; ; i++) {\n      if (tailArray[i] == 255) break;\n\n      if (msgLength.length > 310) {\n        numberTooLong = true;\n        break;\n      }\n\n      msgLength += tailArray[i];\n    }\n\n    if(numberTooLong) return callback(err, 0, 1);\n\n    bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);\n    msgLength = parseInt(msgLength);\n\n    var msg = sliceBuffer(bufferTail, 0, msgLength);\n    if (isString) {\n      try {\n        msg = String.fromCharCode.apply(null, new Uint8Array(msg));\n      } catch (e) {\n        // iPhone Safari doesn't let you apply to typed arrays\n        var typed = new Uint8Array(msg);\n        msg = '';\n        for (var i = 0; i < typed.length; i++) {\n          msg += String.fromCharCode(typed[i]);\n        }\n      }\n    }\n\n    buffers.push(msg);\n    bufferTail = sliceBuffer(bufferTail, msgLength);\n  }\n\n  var total = buffers.length;\n  buffers.forEach(function(buffer, i) {\n    callback(exports.decodePacket(buffer, binaryType, true), i, total);\n  });\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWE2Yy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIvYnJvd3Nlci5qcz9hZjAyIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIga2V5cyA9IHJlcXVpcmUoJy4va2V5cycpO1xudmFyIGhhc0JpbmFyeSA9IHJlcXVpcmUoJ2hhcy1iaW5hcnknKTtcbnZhciBzbGljZUJ1ZmZlciA9IHJlcXVpcmUoJ2FycmF5YnVmZmVyLnNsaWNlJyk7XG52YXIgYWZ0ZXIgPSByZXF1aXJlKCdhZnRlcicpO1xudmFyIHV0ZjggPSByZXF1aXJlKCd3dGYtOCcpO1xuXG52YXIgYmFzZTY0ZW5jb2RlcjtcbmlmIChnbG9iYWwgJiYgZ2xvYmFsLkFycmF5QnVmZmVyKSB7XG4gIGJhc2U2NGVuY29kZXIgPSByZXF1aXJlKCdiYXNlNjQtYXJyYXlidWZmZXInKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgcnVubmluZyBhbiBhbmRyb2lkIGJyb3dzZXIuIFRoYXQgcmVxdWlyZXMgdXMgdG8gdXNlXG4gKiBBcnJheUJ1ZmZlciB3aXRoIHBvbGxpbmcgdHJhbnNwb3J0cy4uLlxuICpcbiAqIGh0dHA6Ly9naGluZGEubmV0L2pwZWctYmxvYi1hamF4LWFuZHJvaWQvXG4gKi9cblxudmFyIGlzQW5kcm9pZCA9IHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmIC9BbmRyb2lkL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgcnVubmluZyBpbiBQaGFudG9tSlMuXG4gKiBVcGxvYWRpbmcgYSBCbG9iIHdpdGggUGhhbnRvbUpTIGRvZXMgbm90IHdvcmsgY29ycmVjdGx5LCBhcyByZXBvcnRlZCBoZXJlOlxuICogaHR0cHM6Ly9naXRodWIuY29tL2FyaXlhL3BoYW50b21qcy9pc3N1ZXMvMTEzOTVcbiAqIEB0eXBlIGJvb2xlYW5cbiAqL1xudmFyIGlzUGhhbnRvbUpTID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgL1BoYW50b21KUy9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG5cbi8qKlxuICogV2hlbiB0cnVlLCBhdm9pZHMgdXNpbmcgQmxvYnMgdG8gZW5jb2RlIHBheWxvYWRzLlxuICogQHR5cGUgYm9vbGVhblxuICovXG52YXIgZG9udFNlbmRCbG9icyA9IGlzQW5kcm9pZCB8fCBpc1BoYW50b21KUztcblxuLyoqXG4gKiBDdXJyZW50IHByb3RvY29sIHZlcnNpb24uXG4gKi9cblxuZXhwb3J0cy5wcm90b2NvbCA9IDM7XG5cbi8qKlxuICogUGFja2V0IHR5cGVzLlxuICovXG5cbnZhciBwYWNrZXRzID0gZXhwb3J0cy5wYWNrZXRzID0ge1xuICAgIG9wZW46ICAgICAwICAgIC8vIG5vbi13c1xuICAsIGNsb3NlOiAgICAxICAgIC8vIG5vbi13c1xuICAsIHBpbmc6ICAgICAyXG4gICwgcG9uZzogICAgIDNcbiAgLCBtZXNzYWdlOiAgNFxuICAsIHVwZ3JhZGU6ICA1XG4gICwgbm9vcDogICAgIDZcbn07XG5cbnZhciBwYWNrZXRzbGlzdCA9IGtleXMocGFja2V0cyk7XG5cbi8qKlxuICogUHJlbWFkZSBlcnJvciBwYWNrZXQuXG4gKi9cblxudmFyIGVyciA9IHsgdHlwZTogJ2Vycm9yJywgZGF0YTogJ3BhcnNlciBlcnJvcicgfTtcblxuLyoqXG4gKiBDcmVhdGUgYSBibG9iIGFwaSBldmVuIGZvciBibG9iIGJ1aWxkZXIgd2hlbiB2ZW5kb3IgcHJlZml4ZXMgZXhpc3RcbiAqL1xuXG52YXIgQmxvYiA9IHJlcXVpcmUoJ2Jsb2InKTtcblxuLyoqXG4gKiBFbmNvZGVzIGEgcGFja2V0LlxuICpcbiAqICAgICA8cGFja2V0IHR5cGUgaWQ+IFsgPGRhdGE+IF1cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICA1aGVsbG8gd29ybGRcbiAqICAgICAzXG4gKiAgICAgNFxuICpcbiAqIEJpbmFyeSBpcyBlbmNvZGVkIGluIGFuIGlkZW50aWNhbCBwcmluY2lwbGVcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLmVuY29kZVBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCB1dGY4ZW5jb2RlLCBjYWxsYmFjaykge1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2Ygc3VwcG9ydHNCaW5hcnkpIHtcbiAgICBjYWxsYmFjayA9IHN1cHBvcnRzQmluYXJ5O1xuICAgIHN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG4gIH1cblxuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgdXRmOGVuY29kZSkge1xuICAgIGNhbGxiYWNrID0gdXRmOGVuY29kZTtcbiAgICB1dGY4ZW5jb2RlID0gbnVsbDtcbiAgfVxuXG4gIHZhciBkYXRhID0gKHBhY2tldC5kYXRhID09PSB1bmRlZmluZWQpXG4gICAgPyB1bmRlZmluZWRcbiAgICA6IHBhY2tldC5kYXRhLmJ1ZmZlciB8fCBwYWNrZXQuZGF0YTtcblxuICBpZiAoZ2xvYmFsLkFycmF5QnVmZmVyICYmIGRhdGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiBlbmNvZGVBcnJheUJ1ZmZlcihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjayk7XG4gIH0gZWxzZSBpZiAoQmxvYiAmJiBkYXRhIGluc3RhbmNlb2YgZ2xvYmFsLkJsb2IpIHtcbiAgICByZXR1cm4gZW5jb2RlQmxvYihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjayk7XG4gIH1cblxuICAvLyBtaWdodCBiZSBhbiBvYmplY3Qgd2l0aCB7IGJhc2U2NDogdHJ1ZSwgZGF0YTogZGF0YUFzQmFzZTY0U3RyaW5nIH1cbiAgaWYgKGRhdGEgJiYgZGF0YS5iYXNlNjQpIHtcbiAgICByZXR1cm4gZW5jb2RlQmFzZTY0T2JqZWN0KHBhY2tldCwgY2FsbGJhY2spO1xuICB9XG5cbiAgLy8gU2VuZGluZyBkYXRhIGFzIGEgdXRmLTggc3RyaW5nXG4gIHZhciBlbmNvZGVkID0gcGFja2V0c1twYWNrZXQudHlwZV07XG5cbiAgLy8gZGF0YSBmcmFnbWVudCBpcyBvcHRpb25hbFxuICBpZiAodW5kZWZpbmVkICE9PSBwYWNrZXQuZGF0YSkge1xuICAgIGVuY29kZWQgKz0gdXRmOGVuY29kZSA/IHV0ZjguZW5jb2RlKFN0cmluZyhwYWNrZXQuZGF0YSkpIDogU3RyaW5nKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHJldHVybiBjYWxsYmFjaygnJyArIGVuY29kZWQpO1xuXG59O1xuXG5mdW5jdGlvbiBlbmNvZGVCYXNlNjRPYmplY3QocGFja2V0LCBjYWxsYmFjaykge1xuICAvLyBwYWNrZXQgZGF0YSBpcyBhbiBvYmplY3QgeyBiYXNlNjQ6IHRydWUsIGRhdGE6IGRhdGFBc0Jhc2U2NFN0cmluZyB9XG4gIHZhciBtZXNzYWdlID0gJ2InICsgZXhwb3J0cy5wYWNrZXRzW3BhY2tldC50eXBlXSArIHBhY2tldC5kYXRhLmRhdGE7XG4gIHJldHVybiBjYWxsYmFjayhtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBFbmNvZGUgcGFja2V0IGhlbHBlcnMgZm9yIGJpbmFyeSB0eXBlc1xuICovXG5cbmZ1bmN0aW9uIGVuY29kZUFycmF5QnVmZmVyKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKSB7XG4gIGlmICghc3VwcG9ydHNCaW5hcnkpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQocGFja2V0LCBjYWxsYmFjayk7XG4gIH1cblxuICB2YXIgZGF0YSA9IHBhY2tldC5kYXRhO1xuICB2YXIgY29udGVudEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gIHZhciByZXN1bHRCdWZmZXIgPSBuZXcgVWludDhBcnJheSgxICsgZGF0YS5ieXRlTGVuZ3RoKTtcblxuICByZXN1bHRCdWZmZXJbMF0gPSBwYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb250ZW50QXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICByZXN1bHRCdWZmZXJbaSsxXSA9IGNvbnRlbnRBcnJheVtpXTtcbiAgfVxuXG4gIHJldHVybiBjYWxsYmFjayhyZXN1bHRCdWZmZXIuYnVmZmVyKTtcbn1cblxuZnVuY3Rpb24gZW5jb2RlQmxvYkFzQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgaWYgKCFzdXBwb3J0c0JpbmFyeSkge1xuICAgIHJldHVybiBleHBvcnRzLmVuY29kZUJhc2U2NFBhY2tldChwYWNrZXQsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHZhciBmciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gIGZyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgIHBhY2tldC5kYXRhID0gZnIucmVzdWx0O1xuICAgIGV4cG9ydHMuZW5jb2RlUGFja2V0KHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIHRydWUsIGNhbGxiYWNrKTtcbiAgfTtcbiAgcmV0dXJuIGZyLnJlYWRBc0FycmF5QnVmZmVyKHBhY2tldC5kYXRhKTtcbn1cblxuZnVuY3Rpb24gZW5jb2RlQmxvYihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjaykge1xuICBpZiAoIXN1cHBvcnRzQmluYXJ5KSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuZW5jb2RlQmFzZTY0UGFja2V0KHBhY2tldCwgY2FsbGJhY2spO1xuICB9XG5cbiAgaWYgKGRvbnRTZW5kQmxvYnMpIHtcbiAgICByZXR1cm4gZW5jb2RlQmxvYkFzQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spO1xuICB9XG5cbiAgdmFyIGxlbmd0aCA9IG5ldyBVaW50OEFycmF5KDEpO1xuICBsZW5ndGhbMF0gPSBwYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgdmFyIGJsb2IgPSBuZXcgQmxvYihbbGVuZ3RoLmJ1ZmZlciwgcGFja2V0LmRhdGFdKTtcblxuICByZXR1cm4gY2FsbGJhY2soYmxvYik7XG59XG5cbi8qKlxuICogRW5jb2RlcyBhIHBhY2tldCB3aXRoIGJpbmFyeSBkYXRhIGluIGEgYmFzZTY0IHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQsIGhhcyBgdHlwZWAgYW5kIGBkYXRhYFxuICogQHJldHVybiB7U3RyaW5nfSBiYXNlNjQgZW5jb2RlZCBtZXNzYWdlXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQsIGNhbGxiYWNrKSB7XG4gIHZhciBtZXNzYWdlID0gJ2InICsgZXhwb3J0cy5wYWNrZXRzW3BhY2tldC50eXBlXTtcbiAgaWYgKEJsb2IgJiYgcGFja2V0LmRhdGEgaW5zdGFuY2VvZiBnbG9iYWwuQmxvYikge1xuICAgIHZhciBmciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgZnIub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYjY0ID0gZnIucmVzdWx0LnNwbGl0KCcsJylbMV07XG4gICAgICBjYWxsYmFjayhtZXNzYWdlICsgYjY0KTtcbiAgICB9O1xuICAgIHJldHVybiBmci5yZWFkQXNEYXRhVVJMKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHZhciBiNjRkYXRhO1xuICB0cnkge1xuICAgIGI2NGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBpUGhvbmUgU2FmYXJpIGRvZXNuJ3QgbGV0IHlvdSBhcHBseSB3aXRoIHR5cGVkIGFycmF5c1xuICAgIHZhciB0eXBlZCA9IG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKTtcbiAgICB2YXIgYmFzaWMgPSBuZXcgQXJyYXkodHlwZWQubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICBiYXNpY1tpXSA9IHR5cGVkW2ldO1xuICAgIH1cbiAgICBiNjRkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBiYXNpYyk7XG4gIH1cbiAgbWVzc2FnZSArPSBnbG9iYWwuYnRvYShiNjRkYXRhKTtcbiAgcmV0dXJuIGNhbGxiYWNrKG1lc3NhZ2UpO1xufTtcblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0LiBDaGFuZ2VzIGZvcm1hdCB0byBCbG9iIGlmIHJlcXVlc3RlZC5cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHdpdGggYHR5cGVgIGFuZCBgZGF0YWAgKGlmIGFueSlcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZGVjb2RlUGFja2V0ID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIHV0ZjhkZWNvZGUpIHtcbiAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBlcnI7XG4gIH1cbiAgLy8gU3RyaW5nIGRhdGFcbiAgaWYgKHR5cGVvZiBkYXRhID09ICdzdHJpbmcnKSB7XG4gICAgaWYgKGRhdGEuY2hhckF0KDApID09ICdiJykge1xuICAgICAgcmV0dXJuIGV4cG9ydHMuZGVjb2RlQmFzZTY0UGFja2V0KGRhdGEuc3Vic3RyKDEpLCBiaW5hcnlUeXBlKTtcbiAgICB9XG5cbiAgICBpZiAodXRmOGRlY29kZSkge1xuICAgICAgZGF0YSA9IHRyeURlY29kZShkYXRhKTtcbiAgICAgIGlmIChkYXRhID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gZXJyO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgdHlwZSA9IGRhdGEuY2hhckF0KDApO1xuXG4gICAgaWYgKE51bWJlcih0eXBlKSAhPSB0eXBlIHx8ICFwYWNrZXRzbGlzdFt0eXBlXSkge1xuICAgICAgcmV0dXJuIGVycjtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS5sZW5ndGggPiAxKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBwYWNrZXRzbGlzdFt0eXBlXSwgZGF0YTogZGF0YS5zdWJzdHJpbmcoMSkgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHsgdHlwZTogcGFja2V0c2xpc3RbdHlwZV0gfTtcbiAgICB9XG4gIH1cblxuICB2YXIgYXNBcnJheSA9IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICB2YXIgdHlwZSA9IGFzQXJyYXlbMF07XG4gIHZhciByZXN0ID0gc2xpY2VCdWZmZXIoZGF0YSwgMSk7XG4gIGlmIChCbG9iICYmIGJpbmFyeVR5cGUgPT09ICdibG9iJykge1xuICAgIHJlc3QgPSBuZXcgQmxvYihbcmVzdF0pO1xuICB9XG4gIHJldHVybiB7IHR5cGU6IHBhY2tldHNsaXN0W3R5cGVdLCBkYXRhOiByZXN0IH07XG59O1xuXG5mdW5jdGlvbiB0cnlEZWNvZGUoZGF0YSkge1xuICB0cnkge1xuICAgIGRhdGEgPSB1dGY4LmRlY29kZShkYXRhKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gZGF0YTtcbn1cblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0IGVuY29kZWQgaW4gYSBiYXNlNjQgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGJhc2U2NCBlbmNvZGVkIG1lc3NhZ2VcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBgdHlwZWAgYW5kIGBkYXRhYCAoaWYgYW55KVxuICovXG5cbmV4cG9ydHMuZGVjb2RlQmFzZTY0UGFja2V0ID0gZnVuY3Rpb24obXNnLCBiaW5hcnlUeXBlKSB7XG4gIHZhciB0eXBlID0gcGFja2V0c2xpc3RbbXNnLmNoYXJBdCgwKV07XG4gIGlmICghYmFzZTY0ZW5jb2Rlcikge1xuICAgIHJldHVybiB7IHR5cGU6IHR5cGUsIGRhdGE6IHsgYmFzZTY0OiB0cnVlLCBkYXRhOiBtc2cuc3Vic3RyKDEpIH0gfTtcbiAgfVxuXG4gIHZhciBkYXRhID0gYmFzZTY0ZW5jb2Rlci5kZWNvZGUobXNnLnN1YnN0cigxKSk7XG5cbiAgaWYgKGJpbmFyeVR5cGUgPT09ICdibG9iJyAmJiBCbG9iKSB7XG4gICAgZGF0YSA9IG5ldyBCbG9iKFtkYXRhXSk7XG4gIH1cblxuICByZXR1cm4geyB0eXBlOiB0eXBlLCBkYXRhOiBkYXRhIH07XG59O1xuXG4vKipcbiAqIEVuY29kZXMgbXVsdGlwbGUgbWVzc2FnZXMgKHBheWxvYWQpLlxuICpcbiAqICAgICA8bGVuZ3RoPjpkYXRhXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgMTE6aGVsbG8gd29ybGQyOmhpXG4gKlxuICogSWYgYW55IGNvbnRlbnRzIGFyZSBiaW5hcnksIHRoZXkgd2lsbCBiZSBlbmNvZGVkIGFzIGJhc2U2NCBzdHJpbmdzLiBCYXNlNjRcbiAqIGVuY29kZWQgc3RyaW5ncyBhcmUgbWFya2VkIHdpdGggYSBiIGJlZm9yZSB0aGUgbGVuZ3RoIHNwZWNpZmllclxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHBhY2tldHNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGF5bG9hZCA9IGZ1bmN0aW9uIChwYWNrZXRzLCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBzdXBwb3J0c0JpbmFyeSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBzdXBwb3J0c0JpbmFyeTtcbiAgICBzdXBwb3J0c0JpbmFyeSA9IG51bGw7XG4gIH1cblxuICB2YXIgaXNCaW5hcnkgPSBoYXNCaW5hcnkocGFja2V0cyk7XG5cbiAgaWYgKHN1cHBvcnRzQmluYXJ5ICYmIGlzQmluYXJ5KSB7XG4gICAgaWYgKEJsb2IgJiYgIWRvbnRTZW5kQmxvYnMpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0Jsb2IocGFja2V0cywgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0FycmF5QnVmZmVyKHBhY2tldHMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIGlmICghcGFja2V0cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gY2FsbGJhY2soJzA6Jyk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkge1xuICAgIHJldHVybiBtZXNzYWdlLmxlbmd0aCArICc6JyArIG1lc3NhZ2U7XG4gIH1cblxuICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICBleHBvcnRzLmVuY29kZVBhY2tldChwYWNrZXQsICFpc0JpbmFyeSA/IGZhbHNlIDogc3VwcG9ydHNCaW5hcnksIHRydWUsIGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgIGRvbmVDYWxsYmFjayhudWxsLCBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkpO1xuICAgIH0pO1xuICB9XG5cbiAgbWFwKHBhY2tldHMsIGVuY29kZU9uZSwgZnVuY3Rpb24oZXJyLCByZXN1bHRzKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdHMuam9pbignJykpO1xuICB9KTtcbn07XG5cbi8qKlxuICogQXN5bmMgYXJyYXkgbWFwIHVzaW5nIGFmdGVyXG4gKi9cblxuZnVuY3Rpb24gbWFwKGFyeSwgZWFjaCwgZG9uZSkge1xuICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KGFyeS5sZW5ndGgpO1xuICB2YXIgbmV4dCA9IGFmdGVyKGFyeS5sZW5ndGgsIGRvbmUpO1xuXG4gIHZhciBlYWNoV2l0aEluZGV4ID0gZnVuY3Rpb24oaSwgZWwsIGNiKSB7XG4gICAgZWFjaChlbCwgZnVuY3Rpb24oZXJyb3IsIG1zZykge1xuICAgICAgcmVzdWx0W2ldID0gbXNnO1xuICAgICAgY2IoZXJyb3IsIHJlc3VsdCk7XG4gICAgfSk7XG4gIH07XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnkubGVuZ3RoOyBpKyspIHtcbiAgICBlYWNoV2l0aEluZGV4KGksIGFyeVtpXSwgbmV4dCk7XG4gIH1cbn1cblxuLypcbiAqIERlY29kZXMgZGF0YSB3aGVuIGEgcGF5bG9hZCBpcyBtYXliZSBleHBlY3RlZC4gUG9zc2libGUgYmluYXJ5IGNvbnRlbnRzIGFyZVxuICogZGVjb2RlZCBmcm9tIHRoZWlyIGJhc2U2NCByZXByZXNlbnRhdGlvblxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhLCBjYWxsYmFjayBtZXRob2RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5kZWNvZGVQYXlsb2FkID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgZGF0YSAhPSAnc3RyaW5nJykge1xuICAgIHJldHVybiBleHBvcnRzLmRlY29kZVBheWxvYWRBc0JpbmFyeShkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjayk7XG4gIH1cblxuICBpZiAodHlwZW9mIGJpbmFyeVR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IGJpbmFyeVR5cGU7XG4gICAgYmluYXJ5VHlwZSA9IG51bGw7XG4gIH1cblxuICB2YXIgcGFja2V0O1xuICBpZiAoZGF0YSA9PSAnJykge1xuICAgIC8vIHBhcnNlciBlcnJvciAtIGlnbm9yaW5nIHBheWxvYWRcbiAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgfVxuXG4gIHZhciBsZW5ndGggPSAnJ1xuICAgICwgbiwgbXNnO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gZGF0YS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIgY2hyID0gZGF0YS5jaGFyQXQoaSk7XG5cbiAgICBpZiAoJzonICE9IGNocikge1xuICAgICAgbGVuZ3RoICs9IGNocjtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCcnID09IGxlbmd0aCB8fCAobGVuZ3RoICE9IChuID0gTnVtYmVyKGxlbmd0aCkpKSkge1xuICAgICAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICAgICAgfVxuXG4gICAgICBtc2cgPSBkYXRhLnN1YnN0cihpICsgMSwgbik7XG5cbiAgICAgIGlmIChsZW5ndGggIT0gbXNnLmxlbmd0aCkge1xuICAgICAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICAgICAgfVxuXG4gICAgICBpZiAobXNnLmxlbmd0aCkge1xuICAgICAgICBwYWNrZXQgPSBleHBvcnRzLmRlY29kZVBhY2tldChtc2csIGJpbmFyeVR5cGUsIHRydWUpO1xuXG4gICAgICAgIGlmIChlcnIudHlwZSA9PSBwYWNrZXQudHlwZSAmJiBlcnIuZGF0YSA9PSBwYWNrZXQuZGF0YSkge1xuICAgICAgICAgIC8vIHBhcnNlciBlcnJvciBpbiBpbmRpdmlkdWFsIHBhY2tldCAtIGlnbm9yaW5nIHBheWxvYWRcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXQgPSBjYWxsYmFjayhwYWNrZXQsIGkgKyBuLCBsKTtcbiAgICAgICAgaWYgKGZhbHNlID09PSByZXQpIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gYWR2YW5jZSBjdXJzb3JcbiAgICAgIGkgKz0gbjtcbiAgICAgIGxlbmd0aCA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIGlmIChsZW5ndGggIT0gJycpIHtcbiAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG4gIH1cblxufTtcblxuLyoqXG4gKiBFbmNvZGVzIG11bHRpcGxlIG1lc3NhZ2VzIChwYXlsb2FkKSBhcyBiaW5hcnkuXG4gKlxuICogPDEgPSBiaW5hcnksIDAgPSBzdHJpbmc+PG51bWJlciBmcm9tIDAtOT48bnVtYmVyIGZyb20gMC05PlsuLi5dPG51bWJlclxuICogMjU1PjxkYXRhPlxuICpcbiAqIEV4YW1wbGU6XG4gKiAxIDMgMjU1IDEgMiAzLCBpZiB0aGUgYmluYXJ5IGNvbnRlbnRzIGFyZSBpbnRlcnByZXRlZCBhcyA4IGJpdCBpbnRlZ2Vyc1xuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHBhY2tldHNcbiAqIEByZXR1cm4ge0FycmF5QnVmZmVyfSBlbmNvZGVkIHBheWxvYWRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGF5bG9hZEFzQXJyYXlCdWZmZXIgPSBmdW5jdGlvbihwYWNrZXRzLCBjYWxsYmFjaykge1xuICBpZiAoIXBhY2tldHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBBcnJheUJ1ZmZlcigwKSk7XG4gIH1cblxuICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICBleHBvcnRzLmVuY29kZVBhY2tldChwYWNrZXQsIHRydWUsIHRydWUsIGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHJldHVybiBkb25lQ2FsbGJhY2sobnVsbCwgZGF0YSk7XG4gICAgfSk7XG4gIH1cblxuICBtYXAocGFja2V0cywgZW5jb2RlT25lLCBmdW5jdGlvbihlcnIsIGVuY29kZWRQYWNrZXRzKSB7XG4gICAgdmFyIHRvdGFsTGVuZ3RoID0gZW5jb2RlZFBhY2tldHMucmVkdWNlKGZ1bmN0aW9uKGFjYywgcCkge1xuICAgICAgdmFyIGxlbjtcbiAgICAgIGlmICh0eXBlb2YgcCA9PT0gJ3N0cmluZycpe1xuICAgICAgICBsZW4gPSBwLmxlbmd0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxlbiA9IHAuYnl0ZUxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2MgKyBsZW4udG9TdHJpbmcoKS5sZW5ndGggKyBsZW4gKyAyOyAvLyBzdHJpbmcvYmluYXJ5IGlkZW50aWZpZXIgKyBzZXBhcmF0b3IgPSAyXG4gICAgfSwgMCk7XG5cbiAgICB2YXIgcmVzdWx0QXJyYXkgPSBuZXcgVWludDhBcnJheSh0b3RhbExlbmd0aCk7XG5cbiAgICB2YXIgYnVmZmVySW5kZXggPSAwO1xuICAgIGVuY29kZWRQYWNrZXRzLmZvckVhY2goZnVuY3Rpb24ocCkge1xuICAgICAgdmFyIGlzU3RyaW5nID0gdHlwZW9mIHAgPT09ICdzdHJpbmcnO1xuICAgICAgdmFyIGFiID0gcDtcbiAgICAgIGlmIChpc1N0cmluZykge1xuICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KHAubGVuZ3RoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmlld1tpXSA9IHAuY2hhckNvZGVBdChpKTtcbiAgICAgICAgfVxuICAgICAgICBhYiA9IHZpZXcuYnVmZmVyO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNTdHJpbmcpIHsgLy8gbm90IHRydWUgYmluYXJ5XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMDtcbiAgICAgIH0gZWxzZSB7IC8vIHRydWUgYmluYXJ5XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMTtcbiAgICAgIH1cblxuICAgICAgdmFyIGxlblN0ciA9IGFiLmJ5dGVMZW5ndGgudG9TdHJpbmcoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuU3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gcGFyc2VJbnQobGVuU3RyW2ldKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdEFycmF5W2J1ZmZlckluZGV4KytdID0gMjU1O1xuXG4gICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGFiKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IHZpZXdbaV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY2FsbGJhY2socmVzdWx0QXJyYXkuYnVmZmVyKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEVuY29kZSBhcyBCbG9iXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVQYXlsb2FkQXNCbG9iID0gZnVuY3Rpb24ocGFja2V0cywgY2FsbGJhY2spIHtcbiAgZnVuY3Rpb24gZW5jb2RlT25lKHBhY2tldCwgZG9uZUNhbGxiYWNrKSB7XG4gICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCB0cnVlLCB0cnVlLCBmdW5jdGlvbihlbmNvZGVkKSB7XG4gICAgICB2YXIgYmluYXJ5SWRlbnRpZmllciA9IG5ldyBVaW50OEFycmF5KDEpO1xuICAgICAgYmluYXJ5SWRlbnRpZmllclswXSA9IDE7XG4gICAgICBpZiAodHlwZW9mIGVuY29kZWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoZW5jb2RlZC5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVuY29kZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2aWV3W2ldID0gZW5jb2RlZC5jaGFyQ29kZUF0KGkpO1xuICAgICAgICB9XG4gICAgICAgIGVuY29kZWQgPSB2aWV3LmJ1ZmZlcjtcbiAgICAgICAgYmluYXJ5SWRlbnRpZmllclswXSA9IDA7XG4gICAgICB9XG5cbiAgICAgIHZhciBsZW4gPSAoZW5jb2RlZCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKVxuICAgICAgICA/IGVuY29kZWQuYnl0ZUxlbmd0aFxuICAgICAgICA6IGVuY29kZWQuc2l6ZTtcblxuICAgICAgdmFyIGxlblN0ciA9IGxlbi50b1N0cmluZygpO1xuICAgICAgdmFyIGxlbmd0aEFyeSA9IG5ldyBVaW50OEFycmF5KGxlblN0ci5sZW5ndGggKyAxKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuU3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxlbmd0aEFyeVtpXSA9IHBhcnNlSW50KGxlblN0cltpXSk7XG4gICAgICB9XG4gICAgICBsZW5ndGhBcnlbbGVuU3RyLmxlbmd0aF0gPSAyNTU7XG5cbiAgICAgIGlmIChCbG9iKSB7XG4gICAgICAgIHZhciBibG9iID0gbmV3IEJsb2IoW2JpbmFyeUlkZW50aWZpZXIuYnVmZmVyLCBsZW5ndGhBcnkuYnVmZmVyLCBlbmNvZGVkXSk7XG4gICAgICAgIGRvbmVDYWxsYmFjayhudWxsLCBibG9iKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG1hcChwYWNrZXRzLCBlbmNvZGVPbmUsIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICAgIHJldHVybiBjYWxsYmFjayhuZXcgQmxvYihyZXN1bHRzKSk7XG4gIH0pO1xufTtcblxuLypcbiAqIERlY29kZXMgZGF0YSB3aGVuIGEgcGF5bG9hZCBpcyBtYXliZSBleHBlY3RlZC4gU3RyaW5ncyBhcmUgZGVjb2RlZCBieVxuICogaW50ZXJwcmV0aW5nIGVhY2ggYnl0ZSBhcyBhIGtleSBjb2RlIGZvciBlbnRyaWVzIG1hcmtlZCB0byBzdGFydCB3aXRoIDAuIFNlZVxuICogZGVzY3JpcHRpb24gb2YgZW5jb2RlUGF5bG9hZEFzQmluYXJ5XG4gKlxuICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gZGF0YSwgY2FsbGJhY2sgbWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb2RlUGF5bG9hZEFzQmluYXJ5ID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgYmluYXJ5VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gYmluYXJ5VHlwZTtcbiAgICBiaW5hcnlUeXBlID0gbnVsbDtcbiAgfVxuXG4gIHZhciBidWZmZXJUYWlsID0gZGF0YTtcbiAgdmFyIGJ1ZmZlcnMgPSBbXTtcblxuICB2YXIgbnVtYmVyVG9vTG9uZyA9IGZhbHNlO1xuICB3aGlsZSAoYnVmZmVyVGFpbC5ieXRlTGVuZ3RoID4gMCkge1xuICAgIHZhciB0YWlsQXJyYXkgPSBuZXcgVWludDhBcnJheShidWZmZXJUYWlsKTtcbiAgICB2YXIgaXNTdHJpbmcgPSB0YWlsQXJyYXlbMF0gPT09IDA7XG4gICAgdmFyIG1zZ0xlbmd0aCA9ICcnO1xuXG4gICAgZm9yICh2YXIgaSA9IDE7IDsgaSsrKSB7XG4gICAgICBpZiAodGFpbEFycmF5W2ldID09IDI1NSkgYnJlYWs7XG5cbiAgICAgIGlmIChtc2dMZW5ndGgubGVuZ3RoID4gMzEwKSB7XG4gICAgICAgIG51bWJlclRvb0xvbmcgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgbXNnTGVuZ3RoICs9IHRhaWxBcnJheVtpXTtcbiAgICB9XG5cbiAgICBpZihudW1iZXJUb29Mb25nKSByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcblxuICAgIGJ1ZmZlclRhaWwgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCAyICsgbXNnTGVuZ3RoLmxlbmd0aCk7XG4gICAgbXNnTGVuZ3RoID0gcGFyc2VJbnQobXNnTGVuZ3RoKTtcblxuICAgIHZhciBtc2cgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCAwLCBtc2dMZW5ndGgpO1xuICAgIGlmIChpc1N0cmluZykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbXNnID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDhBcnJheShtc2cpKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gaVBob25lIFNhZmFyaSBkb2Vzbid0IGxldCB5b3UgYXBwbHkgdG8gdHlwZWQgYXJyYXlzXG4gICAgICAgIHZhciB0eXBlZCA9IG5ldyBVaW50OEFycmF5KG1zZyk7XG4gICAgICAgIG1zZyA9ICcnO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgbXNnICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodHlwZWRbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgYnVmZmVycy5wdXNoKG1zZyk7XG4gICAgYnVmZmVyVGFpbCA9IHNsaWNlQnVmZmVyKGJ1ZmZlclRhaWwsIG1zZ0xlbmd0aCk7XG4gIH1cblxuICB2YXIgdG90YWwgPSBidWZmZXJzLmxlbmd0aDtcbiAgYnVmZmVycy5mb3JFYWNoKGZ1bmN0aW9uKGJ1ZmZlciwgaSkge1xuICAgIGNhbGxiYWNrKGV4cG9ydHMuZGVjb2RlUGFja2V0KGJ1ZmZlciwgYmluYXJ5VHlwZSwgdHJ1ZSksIGksIHRvdGFsKTtcbiAgfSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///aa6c\n")},adfa:function(module,exports,__webpack_require__){eval("/**\n * Utility functions for crossfilter datasets\n * We roughly follow the crossfilter design of dimensions and groups, but we\n * add extra steps to allow transformations on the data.\n * 1. a datum is turned into a raw value, ie. string or number etc. by rawValueFn\n * 2. it is then cast to the correct type value using baseValFn\n * 3. a further transfrom can be applied with valueFn\n * 4. a value is grouped using groupFn; this value must be either a number or a string.\n *\n * @module client/util-crossfilter\n * @see rawValueFn, baseValueFn, valueFn, groupFn\n */\nvar misval = __webpack_require__(/*! ./misval */ \"bff6\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\n\n/**\n * @typedef {Object} SubgroupValue\n * @property {number} count The count of the number of elements in this subgroup\n * @property {number} sum The sum of all elements in this subgroup\n */\n\n/**\n * Reduce a SubgroupValue to a single number\n *\n * @callback reduceCB\n * @param {SubgroupValue} d SubgroupValue\n * @returns {number} Reduced value\n */\n/**\n\n/**\n * Returns a function for further reducing the crossfilter group\n * to a single value, depending on sum/count/average settings of\n * the Aggregate class.\n * @param {Aggregate} facet - The Aggregate class for which to create the reduction function\n * @returns {cb} The required reduction function\n */\nfunction reduceFn (aggregate) {\n  if (aggregate.doSum) {\n    /**\n     * @callback subgroupSum\n     * @param {SubgroupValue} d\n     * @returns {number} sum\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n      if (d.count > 0) {\n        return d.sum;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doCount) {\n    /**\n     * @callback subgroupCount\n     * @param {SubgroupValue} d\n     * @returns {number} count\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n      if (d.count > 0) {\n        return d.count;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doAverage) {\n    /**\n     * @callback subgroupAverage\n     * @param {SubgroupValue} d\n     * @returns {number} d.sum/d.count\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n\n      if (d.count > 0) {\n        return d.sum / d.count;\n      } else {\n        return misval;\n      }\n    };\n  } else if (aggregate.doStddev) {\n    /**\n     * @callback subgroupStddev\n     * @param {SubgroupValue} d\n     * @returns {number} stddev(d)\n     */\n    return function (d) {\n      if (d === misval || d == null) {\n        return misval;\n      }\n\n      // \\sum_i (x_i - \\bar x)^2 =\n      //   \\sum_i (x_i^2 - 2x_i\\bar x + (\\bar x)^2) =\n      //   \\sum_i (x_i^2) - 2 N (\\bar x)^2 + N(\\bar x)^2 =\n      //   \\sum_i (x_i^2) - N (\\bar x)^2\n      if (d.count > 1) {\n        return Math.sqrt((d.sumsquares - (d.sum * d.sum / d.count)) / (d.count - 1));\n      } else {\n        return misval;\n      }\n    };\n  }\n\n  console.error('Operation not implemented for this Aggregate', aggregate);\n  return function (d) {\n    if (d === misval || d == null) {\n      return misval;\n    }\n    if (d.count > 0) {\n      return d.count;\n    } else {\n      return misval;\n    }\n  };\n}\n\n// ********************************************************\n// Facet transform utility function\n// ********************************************************\n\n/**\n * Returns the base value for a datum\n *\n * @callback baseValueCB\n * @param {Object} d Raw data record\n * @returns {Object} base value\n */\n\n/**\n * Raw value for given facet\n * @param {Facet} facet\n * @returns {rawValueCB} Raw value function for this facet\n */\nfunction rawValueFn (facet) {\n  var accessor;\n\n  // Array dimensions have a [] appended to the accessor,\n  // remove it to get to the actual accessor\n  var path = facet.accessor;\n  if (path.match(/\\[]$/)) {\n    path = path.substring(0, path.length - 2);\n  }\n\n  var misvals = {};\n  facet.misval.forEach(function (val) {\n    misvals[val] = true;\n  });\n\n  // Access nested properties via a double hash sign, this to prevent collision with regular keys; fi. 'person.name'\n  path = path.split('##');\n\n  if (path.length === 1) {\n    // Use a simple direct accessor, as it is probably faster than the more general case\n    // and it was implemented already\n    if (facet.misval.length > 0) {\n      accessor = function (d) {\n        var value = d[path[0]];\n        if (value === undefined || value === null || value in misvals) {\n          return misval;\n        }\n        return value;\n      };\n    } else {\n      accessor = function (d) {\n        var value = d[path[0]];\n        if (value === undefined || value === null) {\n          return misval;\n        }\n        return value;\n      };\n    }\n  } else {\n    // Recursively follow the crumbs to the desired property\n    accessor = function (d) {\n      var i = 0;\n      var value = d;\n\n      for (i = 0; i < path.length; i++) {\n        if (value && value[path[i]] !== undefined) {\n          value = value[path[i]];\n        } else {\n          return misval;\n        }\n      }\n\n      if (value === null || value in misvals) {\n        value = misval;\n      }\n      return value;\n    };\n  }\n\n  return accessor;\n}\n\n/**\n * Base value for given facet, ie. cast to correct type or object.\n * @param {Facet} facet\n * @returns {vaseValueCB} Base value function for this facet\n */\nfunction baseValueFn (facet) {\n  var rawValFn = rawValueFn(facet);\n\n  if (facet.isContinuous) {\n    /*\n     * Continuous facets:\n     * Parse numeric value from base value\n     */\n    return function (d) {\n      var val = parseFloat(rawValFn(d));\n      if (isNaN(val) || val === Infinity || val === -Infinity) {\n        return misval;\n      }\n      return val;\n    };\n  } else if (facet.isCategorial) {\n    return function (d) {\n      var vals = rawValFn(d);\n      if (vals !== misval) {\n        if (vals instanceof Array) {\n          vals.forEach(function (val, i) {\n            vals[i] = val.toString();\n          });\n        } else {\n          vals = vals.toString();\n        }\n        return vals;\n      }\n      return misval;\n    };\n  } else if (facet.isDatetime) {\n    /*\n     * Time parsing:\n     * 1. moment parses the string using the given format, but defaults to\n     *    the [ISO 8601 standard](https://en.wikipedia.org/wiki/ISO_8601)\n     * 2. Note that if the string contains timezone information, that is parsed too.\n     * 3. The time is transformed to requested timezone, defaulting the locale default\n     *    when no zone is set\n    */\n    var timeFormat = facet.datetimeTransform.format;\n    if (timeFormat === 'ISO8601') {\n      // use default ISO formatting\n      timeFormat = moment.ISO_8601;\n    }\n\n    var timeZone = facet.datetimeTransform.zone;\n    if (timeZone === 'ISO8601') {\n      // use default locale timezone, get overridden if a string contains a timezone\n      timeZone = moment.tz.guess();\n    } else {\n      timeZone = util.timeZones.get(timeZone, 'description').format;\n    }\n\n    return function (d) {\n      var value = rawValFn(d);\n      if (value !== misval) {\n        var m = moment.tz(value, timeFormat, timeZone);\n        if (m.isValid()) {\n          return m;\n        }\n      }\n      return misval;\n    };\n  } else if (facet.isDuration) {\n    /*\n     * Duration parsing:\n     * 1. If no format is given, the string parsed using\n     *    the [ISO 8601 standard](https://en.wikipedia.org/wiki/ISO_8601)\n     * 2. If a format is given, the string is parsed as float and interpreted in the given units\n     */\n    var units = facet.durationTransform.units;\n    if (units === 'ISO8601') {\n      return function (d) {\n        var value = rawValFn(d);\n\n        // parse string if necessary\n        if (value !== misval && typeof value === 'string' && value[0].toLowerCase() === 'p') {\n          value = moment.duration(value);\n        }\n\n        // check for valid duration\n        if (moment.isDuration(value)) {\n          return value;\n        }\n\n        return misval;\n      };\n    } else {\n      units = util.durationUnits.get(units, 'description').momentFormat;\n      return function (d) {\n        var value = rawValFn(d);\n\n        // parse string if necessary\n        if (value !== misval && !isNaN(value)) {\n          // NOTE: isNaN('0') is false, if that gives problems, we could use:\n          // value == +value) { // eslint-disable-line eqeqeq\n          value = moment.duration(parseFloat(value), units);\n        }\n\n        // check for valid duration\n        if (moment.isDuration(value)) {\n          return value;\n        }\n\n        return misval;\n      };\n    }\n  }\n\n  // isCategorial, isText\n  // no casting or constructing necessary, return the raw value\n  return rawValFn;\n}\n\n/**\n * Returns the transformed value from a base value\n *\n * @callback valueCB\n * @param {Object} d Base value\n * @returns {Object} Transformed value\n */\n\n/**\n * Create a function that returns the transformed value for this facet\n * @param {Facet} facet\n * @returns {valueCB} Value function for this facet\n */\nfunction valueFn (facet) {\n  // get base value function\n  var baseValFn = baseValueFn(facet);\n\n  if (facet.isConstant) {\n    return function () { return '1'; };\n  } else if (facet.isContinuous) {\n    // do we have a continuous transform?\n    if (facet.continuousTransform && facet.continuousTransform.type !== 'none') {\n      // yes, use it\n      return function (d) {\n        var val = facet.continuousTransform.transform(parseFloat(baseValFn(d)));\n        if (isNaN(val) || val === Infinity || val === -Infinity) {\n          return misval;\n        }\n        return val;\n      };\n    }\n  } else if (facet.isCategorial) {\n    // do we have a categorial transform?\n    if (facet.categorialTransform && facet.categorialTransform.rules.length > 0) {\n      // yes, use it\n      return function (d) {\n        var val = baseValFn(d);\n        return val === misval ? misval : facet.categorialTransform.transform(baseValFn(d));\n      };\n    }\n  } else if (facet.isDatetime) {\n    // always use the transform, so we do not have to repeat the yes/no transfrom logic here\n    return function (d) {\n      var val = baseValFn(d);\n      return val === misval ? misval : facet.datetimeTransform.transform(val);\n    };\n  } else if (facet.isDuration) {\n    // always use the transform, so we do not have to repeat the yes/no transfrom logic here\n    return function (d) {\n      var val = baseValFn(d);\n      return val === misval ? misval : facet.durationTransform.transform(val);\n    };\n  }\n\n  // no transfrom, return base value\n  return baseValFn;\n}\n\nfunction continuousGroupFn (partition) {\n  return function (d) {\n    if (d === misval) {\n      return d;\n    }\n\n    var ngroups = partition.groups.length;\n    if (d < partition.minval || d > partition.maxval) {\n      return misval;\n    }\n\n    // bins include their lower bound, but not their upper bound\n    var i = 0;\n    while (i < ngroups && d >= partition.groups.models[i].max) {\n      i++;\n    }\n    // special case last bin includes also upperbound d === partition.maxval\n    if (i === ngroups) {\n      return partition.groups.models[i - 1].value;\n    }\n    return partition.groups.models[i].value;\n  };\n}\n\n/*\n * Round the datetime to the specified resolution\n * see:\n * http://momentjs.com/docs/#/manipulating/start-of/\n * http://momentjs.com/docs/#/displaying/as-javascript-date/\n */\nfunction datetimeGroupFn (partition) {\n  var timeStep = util.getDatetimeResolution(partition.minval, partition.maxval);\n  return function (d) {\n    if (d === misval) {\n      return misval;\n    }\n    if (d.isBefore(partition.minval) || d.isAfter(partition.maxval)) {\n      return misval;\n    }\n    var grouped = moment(d).startOf(timeStep).format();\n    return grouped;\n  };\n}\n\n/*\n * Round the duration to the specified resolution\n */\nfunction durationGroupFn (partition) {\n  var timeStep = util.getDurationResolution(partition.minval, partition.maxval);\n  return function (d) {\n    if (d === misval) {\n      return misval;\n    }\n    if (d < partition.minval || d > partition.maxval) {\n      return misval;\n    }\n    var rounded = Math.floor(parseFloat(d.as(timeStep)));\n    return moment.duration(rounded, timeStep).toISOString();\n  };\n}\n\n/*\n * Don't do any grouping; that is done in the step from base value to value.\n * Matching of facet value and group could lead to a different ordering,\n * which is not allowed by crossfilter\n */\nfunction categorialGroupFn (partition) {\n  return function (d) { return d; };\n}\n\n/**\n * Returns the grouped value for a transformed value\n *\n * @callback groupCB\n * @param {Object} d Transformed value\n * @returns {Object} Group\n */\n\n/**\n * Create a function that returns the group value for a partition\n * @param {Partition} partition\n * @returns {cb} Group function for this partition, taking a `Data`\n */\nfunction groupFn (partition) {\n  if (partition.isConstant) {\n    return function () { return '1'; };\n  } else if (partition.isContinuous) {\n    return continuousGroupFn(partition);\n  } else if (partition.isCategorial) {\n    return categorialGroupFn(partition);\n  } else if (partition.isDatetime) {\n    return datetimeGroupFn(partition);\n  } else if (partition.isDuration) {\n    return durationGroupFn(partition);\n  } else if (partition.isText) {\n    return function (d) { return d.toString(); };\n  } else {\n    console.error('Group function not implemented for partition', partition);\n  }\n}\n\nmodule.exports = {\n  rawValueFn: rawValueFn,\n  baseValueFn: baseValueFn,\n  valueFn: valueFn,\n  groupFn: groupFn,\n\n  reduceFn: reduceFn\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRmYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9jcm9zc2ZpbHRlci5qcz8xZjdhIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIGNyb3NzZmlsdGVyIGRhdGFzZXRzXG4gKiBXZSByb3VnaGx5IGZvbGxvdyB0aGUgY3Jvc3NmaWx0ZXIgZGVzaWduIG9mIGRpbWVuc2lvbnMgYW5kIGdyb3VwcywgYnV0IHdlXG4gKiBhZGQgZXh0cmEgc3RlcHMgdG8gYWxsb3cgdHJhbnNmb3JtYXRpb25zIG9uIHRoZSBkYXRhLlxuICogMS4gYSBkYXR1bSBpcyB0dXJuZWQgaW50byBhIHJhdyB2YWx1ZSwgaWUuIHN0cmluZyBvciBudW1iZXIgZXRjLiBieSByYXdWYWx1ZUZuXG4gKiAyLiBpdCBpcyB0aGVuIGNhc3QgdG8gdGhlIGNvcnJlY3QgdHlwZSB2YWx1ZSB1c2luZyBiYXNlVmFsRm5cbiAqIDMuIGEgZnVydGhlciB0cmFuc2Zyb20gY2FuIGJlIGFwcGxpZWQgd2l0aCB2YWx1ZUZuXG4gKiA0LiBhIHZhbHVlIGlzIGdyb3VwZWQgdXNpbmcgZ3JvdXBGbjsgdGhpcyB2YWx1ZSBtdXN0IGJlIGVpdGhlciBhIG51bWJlciBvciBhIHN0cmluZy5cbiAqXG4gKiBAbW9kdWxlIGNsaWVudC91dGlsLWNyb3NzZmlsdGVyXG4gKiBAc2VlIHJhd1ZhbHVlRm4sIGJhc2VWYWx1ZUZuLCB2YWx1ZUZuLCBncm91cEZuXG4gKi9cbnZhciBtaXN2YWwgPSByZXF1aXJlKCcuL21pc3ZhbCcpO1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsL3RpbWUnKTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTdWJncm91cFZhbHVlXG4gKiBAcHJvcGVydHkge251bWJlcn0gY291bnQgVGhlIGNvdW50IG9mIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBzdWJncm91cFxuICogQHByb3BlcnR5IHtudW1iZXJ9IHN1bSBUaGUgc3VtIG9mIGFsbCBlbGVtZW50cyBpbiB0aGlzIHN1Ymdyb3VwXG4gKi9cblxuLyoqXG4gKiBSZWR1Y2UgYSBTdWJncm91cFZhbHVlIHRvIGEgc2luZ2xlIG51bWJlclxuICpcbiAqIEBjYWxsYmFjayByZWR1Y2VDQlxuICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkIFN1Ymdyb3VwVmFsdWVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJlZHVjZWQgdmFsdWVcbiAqL1xuLyoqXG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIGZvciBmdXJ0aGVyIHJlZHVjaW5nIHRoZSBjcm9zc2ZpbHRlciBncm91cFxuICogdG8gYSBzaW5nbGUgdmFsdWUsIGRlcGVuZGluZyBvbiBzdW0vY291bnQvYXZlcmFnZSBzZXR0aW5ncyBvZlxuICogdGhlIEFnZ3JlZ2F0ZSBjbGFzcy5cbiAqIEBwYXJhbSB7QWdncmVnYXRlfSBmYWNldCAtIFRoZSBBZ2dyZWdhdGUgY2xhc3MgZm9yIHdoaWNoIHRvIGNyZWF0ZSB0aGUgcmVkdWN0aW9uIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7Y2J9IFRoZSByZXF1aXJlZCByZWR1Y3Rpb24gZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gcmVkdWNlRm4gKGFnZ3JlZ2F0ZSkge1xuICBpZiAoYWdncmVnYXRlLmRvU3VtKSB7XG4gICAgLyoqXG4gICAgICogQGNhbGxiYWNrIHN1Ymdyb3VwU3VtXG4gICAgICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkXG4gICAgICogQHJldHVybnMge251bWJlcn0gc3VtXG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICBpZiAoZCA9PT0gbWlzdmFsIHx8IGQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgICAgaWYgKGQuY291bnQgPiAwKSB7XG4gICAgICAgIHJldHVybiBkLnN1bTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIGlmIChhZ2dyZWdhdGUuZG9Db3VudCkge1xuICAgIC8qKlxuICAgICAqIEBjYWxsYmFjayBzdWJncm91cENvdW50XG4gICAgICogQHBhcmFtIHtTdWJncm91cFZhbHVlfSBkXG4gICAgICogQHJldHVybnMge251bWJlcn0gY291bnRcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGQuY291bnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgIH07XG4gIH0gZWxzZSBpZiAoYWdncmVnYXRlLmRvQXZlcmFnZSkge1xuICAgIC8qKlxuICAgICAqIEBjYWxsYmFjayBzdWJncm91cEF2ZXJhZ2VcbiAgICAgKiBAcGFyYW0ge1N1Ymdyb3VwVmFsdWV9IGRcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBkLnN1bS9kLmNvdW50XG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICBpZiAoZCA9PT0gbWlzdmFsIHx8IGQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuXG4gICAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGQuc3VtIC8gZC5jb3VudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIGlmIChhZ2dyZWdhdGUuZG9TdGRkZXYpIHtcbiAgICAvKipcbiAgICAgKiBAY2FsbGJhY2sgc3ViZ3JvdXBTdGRkZXZcbiAgICAgKiBAcGFyYW0ge1N1Ymdyb3VwVmFsdWV9IGRcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBzdGRkZXYoZClcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgICB9XG5cbiAgICAgIC8vIFxcc3VtX2kgKHhfaSAtIFxcYmFyIHgpXjIgPVxuICAgICAgLy8gICBcXHN1bV9pICh4X2leMiAtIDJ4X2lcXGJhciB4ICsgKFxcYmFyIHgpXjIpID1cbiAgICAgIC8vICAgXFxzdW1faSAoeF9pXjIpIC0gMiBOIChcXGJhciB4KV4yICsgTihcXGJhciB4KV4yID1cbiAgICAgIC8vICAgXFxzdW1faSAoeF9pXjIpIC0gTiAoXFxiYXIgeCleMlxuICAgICAgaWYgKGQuY291bnQgPiAxKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnNxcnQoKGQuc3Vtc3F1YXJlcyAtIChkLnN1bSAqIGQuc3VtIC8gZC5jb3VudCkpIC8gKGQuY291bnQgLSAxKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBjb25zb2xlLmVycm9yKCdPcGVyYXRpb24gbm90IGltcGxlbWVudGVkIGZvciB0aGlzIEFnZ3JlZ2F0ZScsIGFnZ3JlZ2F0ZSk7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwgfHwgZCA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgICBpZiAoZC5jb3VudCA+IDApIHtcbiAgICAgIHJldHVybiBkLmNvdW50O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgfTtcbn1cblxuLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbi8vIEZhY2V0IHRyYW5zZm9ybSB1dGlsaXR5IGZ1bmN0aW9uXG4vLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG4vKipcbiAqIFJldHVybnMgdGhlIGJhc2UgdmFsdWUgZm9yIGEgZGF0dW1cbiAqXG4gKiBAY2FsbGJhY2sgYmFzZVZhbHVlQ0JcbiAqIEBwYXJhbSB7T2JqZWN0fSBkIFJhdyBkYXRhIHJlY29yZFxuICogQHJldHVybnMge09iamVjdH0gYmFzZSB2YWx1ZVxuICovXG5cbi8qKlxuICogUmF3IHZhbHVlIGZvciBnaXZlbiBmYWNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqIEByZXR1cm5zIHtyYXdWYWx1ZUNCfSBSYXcgdmFsdWUgZnVuY3Rpb24gZm9yIHRoaXMgZmFjZXRcbiAqL1xuZnVuY3Rpb24gcmF3VmFsdWVGbiAoZmFjZXQpIHtcbiAgdmFyIGFjY2Vzc29yO1xuXG4gIC8vIEFycmF5IGRpbWVuc2lvbnMgaGF2ZSBhIFtdIGFwcGVuZGVkIHRvIHRoZSBhY2Nlc3NvcixcbiAgLy8gcmVtb3ZlIGl0IHRvIGdldCB0byB0aGUgYWN0dWFsIGFjY2Vzc29yXG4gIHZhciBwYXRoID0gZmFjZXQuYWNjZXNzb3I7XG4gIGlmIChwYXRoLm1hdGNoKC9cXFtdJC8pKSB7XG4gICAgcGF0aCA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoIC0gMik7XG4gIH1cblxuICB2YXIgbWlzdmFscyA9IHt9O1xuICBmYWNldC5taXN2YWwuZm9yRWFjaChmdW5jdGlvbiAodmFsKSB7XG4gICAgbWlzdmFsc1t2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgLy8gQWNjZXNzIG5lc3RlZCBwcm9wZXJ0aWVzIHZpYSBhIGRvdWJsZSBoYXNoIHNpZ24sIHRoaXMgdG8gcHJldmVudCBjb2xsaXNpb24gd2l0aCByZWd1bGFyIGtleXM7IGZpLiAncGVyc29uLm5hbWUnXG4gIHBhdGggPSBwYXRoLnNwbGl0KCcjIycpO1xuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMSkge1xuICAgIC8vIFVzZSBhIHNpbXBsZSBkaXJlY3QgYWNjZXNzb3IsIGFzIGl0IGlzIHByb2JhYmx5IGZhc3RlciB0aGFuIHRoZSBtb3JlIGdlbmVyYWwgY2FzZVxuICAgIC8vIGFuZCBpdCB3YXMgaW1wbGVtZW50ZWQgYWxyZWFkeVxuICAgIGlmIChmYWNldC5taXN2YWwubGVuZ3RoID4gMCkge1xuICAgICAgYWNjZXNzb3IgPSBmdW5jdGlvbiAoZCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBkW3BhdGhbMF1dO1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSBpbiBtaXN2YWxzKSB7XG4gICAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBhY2Nlc3NvciA9IGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGRbcGF0aFswXV07XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBSZWN1cnNpdmVseSBmb2xsb3cgdGhlIGNydW1icyB0byB0aGUgZGVzaXJlZCBwcm9wZXJ0eVxuICAgIGFjY2Vzc29yID0gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciBpID0gMDtcbiAgICAgIHZhciB2YWx1ZSA9IGQ7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh2YWx1ZSAmJiB2YWx1ZVtwYXRoW2ldXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZVtwYXRoW2ldXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSBpbiBtaXN2YWxzKSB7XG4gICAgICAgIHZhbHVlID0gbWlzdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gYWNjZXNzb3I7XG59XG5cbi8qKlxuICogQmFzZSB2YWx1ZSBmb3IgZ2l2ZW4gZmFjZXQsIGllLiBjYXN0IHRvIGNvcnJlY3QgdHlwZSBvciBvYmplY3QuXG4gKiBAcGFyYW0ge0ZhY2V0fSBmYWNldFxuICogQHJldHVybnMge3Zhc2VWYWx1ZUNCfSBCYXNlIHZhbHVlIGZ1bmN0aW9uIGZvciB0aGlzIGZhY2V0XG4gKi9cbmZ1bmN0aW9uIGJhc2VWYWx1ZUZuIChmYWNldCkge1xuICB2YXIgcmF3VmFsRm4gPSByYXdWYWx1ZUZuKGZhY2V0KTtcblxuICBpZiAoZmFjZXQuaXNDb250aW51b3VzKSB7XG4gICAgLypcbiAgICAgKiBDb250aW51b3VzIGZhY2V0czpcbiAgICAgKiBQYXJzZSBudW1lcmljIHZhbHVlIGZyb20gYmFzZSB2YWx1ZVxuICAgICAqL1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbCA9IHBhcnNlRmxvYXQocmF3VmFsRm4oZCkpO1xuICAgICAgaWYgKGlzTmFOKHZhbCkgfHwgdmFsID09PSBJbmZpbml0eSB8fCB2YWwgPT09IC1JbmZpbml0eSkge1xuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbDtcbiAgICB9O1xuICB9IGVsc2UgaWYgKGZhY2V0LmlzQ2F0ZWdvcmlhbCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbHMgPSByYXdWYWxGbihkKTtcbiAgICAgIGlmICh2YWxzICE9PSBtaXN2YWwpIHtcbiAgICAgICAgaWYgKHZhbHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgIHZhbHMuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBpKSB7XG4gICAgICAgICAgICB2YWxzW2ldID0gdmFsLnRvU3RyaW5nKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFscyA9IHZhbHMudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFscztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgLypcbiAgICAgKiBUaW1lIHBhcnNpbmc6XG4gICAgICogMS4gbW9tZW50IHBhcnNlcyB0aGUgc3RyaW5nIHVzaW5nIHRoZSBnaXZlbiBmb3JtYXQsIGJ1dCBkZWZhdWx0cyB0b1xuICAgICAqICAgIHRoZSBbSVNPIDg2MDEgc3RhbmRhcmRdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT184NjAxKVxuICAgICAqIDIuIE5vdGUgdGhhdCBpZiB0aGUgc3RyaW5nIGNvbnRhaW5zIHRpbWV6b25lIGluZm9ybWF0aW9uLCB0aGF0IGlzIHBhcnNlZCB0b28uXG4gICAgICogMy4gVGhlIHRpbWUgaXMgdHJhbnNmb3JtZWQgdG8gcmVxdWVzdGVkIHRpbWV6b25lLCBkZWZhdWx0aW5nIHRoZSBsb2NhbGUgZGVmYXVsdFxuICAgICAqICAgIHdoZW4gbm8gem9uZSBpcyBzZXRcbiAgICAqL1xuICAgIHZhciB0aW1lRm9ybWF0ID0gZmFjZXQuZGF0ZXRpbWVUcmFuc2Zvcm0uZm9ybWF0O1xuICAgIGlmICh0aW1lRm9ybWF0ID09PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIHVzZSBkZWZhdWx0IElTTyBmb3JtYXR0aW5nXG4gICAgICB0aW1lRm9ybWF0ID0gbW9tZW50LklTT184NjAxO1xuICAgIH1cblxuICAgIHZhciB0aW1lWm9uZSA9IGZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnpvbmU7XG4gICAgaWYgKHRpbWVab25lID09PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIHVzZSBkZWZhdWx0IGxvY2FsZSB0aW1lem9uZSwgZ2V0IG92ZXJyaWRkZW4gaWYgYSBzdHJpbmcgY29udGFpbnMgYSB0aW1lem9uZVxuICAgICAgdGltZVpvbmUgPSBtb21lbnQudHouZ3Vlc3MoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGltZVpvbmUgPSB1dGlsLnRpbWVab25lcy5nZXQodGltZVpvbmUsICdkZXNjcmlwdGlvbicpLmZvcm1hdDtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWx1ZSA9IHJhd1ZhbEZuKGQpO1xuICAgICAgaWYgKHZhbHVlICE9PSBtaXN2YWwpIHtcbiAgICAgICAgdmFyIG0gPSBtb21lbnQudHoodmFsdWUsIHRpbWVGb3JtYXQsIHRpbWVab25lKTtcbiAgICAgICAgaWYgKG0uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIG07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0R1cmF0aW9uKSB7XG4gICAgLypcbiAgICAgKiBEdXJhdGlvbiBwYXJzaW5nOlxuICAgICAqIDEuIElmIG5vIGZvcm1hdCBpcyBnaXZlbiwgdGhlIHN0cmluZyBwYXJzZWQgdXNpbmdcbiAgICAgKiAgICB0aGUgW0lTTyA4NjAxIHN0YW5kYXJkXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSlcbiAgICAgKiAyLiBJZiBhIGZvcm1hdCBpcyBnaXZlbiwgdGhlIHN0cmluZyBpcyBwYXJzZWQgYXMgZmxvYXQgYW5kIGludGVycHJldGVkIGluIHRoZSBnaXZlbiB1bml0c1xuICAgICAqL1xuICAgIHZhciB1bml0cyA9IGZhY2V0LmR1cmF0aW9uVHJhbnNmb3JtLnVuaXRzO1xuICAgIGlmICh1bml0cyA9PT0gJ0lTTzg2MDEnKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gcmF3VmFsRm4oZCk7XG5cbiAgICAgICAgLy8gcGFyc2Ugc3RyaW5nIGlmIG5lY2Vzc2FyeVxuICAgICAgICBpZiAodmFsdWUgIT09IG1pc3ZhbCAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlWzBdLnRvTG93ZXJDYXNlKCkgPT09ICdwJykge1xuICAgICAgICAgIHZhbHVlID0gbW9tZW50LmR1cmF0aW9uKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGZvciB2YWxpZCBkdXJhdGlvblxuICAgICAgICBpZiAobW9tZW50LmlzRHVyYXRpb24odmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuaXRzID0gdXRpbC5kdXJhdGlvblVuaXRzLmdldCh1bml0cywgJ2Rlc2NyaXB0aW9uJykubW9tZW50Rm9ybWF0O1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJhd1ZhbEZuKGQpO1xuXG4gICAgICAgIC8vIHBhcnNlIHN0cmluZyBpZiBuZWNlc3NhcnlcbiAgICAgICAgaWYgKHZhbHVlICE9PSBtaXN2YWwgJiYgIWlzTmFOKHZhbHVlKSkge1xuICAgICAgICAgIC8vIE5PVEU6IGlzTmFOKCcwJykgaXMgZmFsc2UsIGlmIHRoYXQgZ2l2ZXMgcHJvYmxlbXMsIHdlIGNvdWxkIHVzZTpcbiAgICAgICAgICAvLyB2YWx1ZSA9PSArdmFsdWUpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICAgICAgICB2YWx1ZSA9IG1vbWVudC5kdXJhdGlvbihwYXJzZUZsb2F0KHZhbHVlKSwgdW5pdHMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIHZhbGlkIGR1cmF0aW9uXG4gICAgICAgIGlmIChtb21lbnQuaXNEdXJhdGlvbih2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvLyBpc0NhdGVnb3JpYWwsIGlzVGV4dFxuICAvLyBubyBjYXN0aW5nIG9yIGNvbnN0cnVjdGluZyBuZWNlc3NhcnksIHJldHVybiB0aGUgcmF3IHZhbHVlXG4gIHJldHVybiByYXdWYWxGbjtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB0cmFuc2Zvcm1lZCB2YWx1ZSBmcm9tIGEgYmFzZSB2YWx1ZVxuICpcbiAqIEBjYWxsYmFjayB2YWx1ZUNCXG4gKiBAcGFyYW0ge09iamVjdH0gZCBCYXNlIHZhbHVlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBUcmFuc2Zvcm1lZCB2YWx1ZVxuICovXG5cbi8qKlxuICogQ3JlYXRlIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB0cmFuc2Zvcm1lZCB2YWx1ZSBmb3IgdGhpcyBmYWNldFxuICogQHBhcmFtIHtGYWNldH0gZmFjZXRcbiAqIEByZXR1cm5zIHt2YWx1ZUNCfSBWYWx1ZSBmdW5jdGlvbiBmb3IgdGhpcyBmYWNldFxuICovXG5mdW5jdGlvbiB2YWx1ZUZuIChmYWNldCkge1xuICAvLyBnZXQgYmFzZSB2YWx1ZSBmdW5jdGlvblxuICB2YXIgYmFzZVZhbEZuID0gYmFzZVZhbHVlRm4oZmFjZXQpO1xuXG4gIGlmIChmYWNldC5pc0NvbnN0YW50KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsgcmV0dXJuICcxJzsgfTtcbiAgfSBlbHNlIGlmIChmYWNldC5pc0NvbnRpbnVvdXMpIHtcbiAgICAvLyBkbyB3ZSBoYXZlIGEgY29udGludW91cyB0cmFuc2Zvcm0/XG4gICAgaWYgKGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm0gJiYgZmFjZXQuY29udGludW91c1RyYW5zZm9ybS50eXBlICE9PSAnbm9uZScpIHtcbiAgICAgIC8vIHllcywgdXNlIGl0XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgdmFyIHZhbCA9IGZhY2V0LmNvbnRpbnVvdXNUcmFuc2Zvcm0udHJhbnNmb3JtKHBhcnNlRmxvYXQoYmFzZVZhbEZuKGQpKSk7XG4gICAgICAgIGlmIChpc05hTih2YWwpIHx8IHZhbCA9PT0gSW5maW5pdHkgfHwgdmFsID09PSAtSW5maW5pdHkpIHtcbiAgICAgICAgICByZXR1cm4gbWlzdmFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIGlmIChmYWNldC5pc0NhdGVnb3JpYWwpIHtcbiAgICAvLyBkbyB3ZSBoYXZlIGEgY2F0ZWdvcmlhbCB0cmFuc2Zvcm0/XG4gICAgaWYgKGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0gJiYgZmFjZXQuY2F0ZWdvcmlhbFRyYW5zZm9ybS5ydWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyB5ZXMsIHVzZSBpdFxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHZhciB2YWwgPSBiYXNlVmFsRm4oZCk7XG4gICAgICAgIHJldHVybiB2YWwgPT09IG1pc3ZhbCA/IG1pc3ZhbCA6IGZhY2V0LmNhdGVnb3JpYWxUcmFuc2Zvcm0udHJhbnNmb3JtKGJhc2VWYWxGbihkKSk7XG4gICAgICB9O1xuICAgIH1cbiAgfSBlbHNlIGlmIChmYWNldC5pc0RhdGV0aW1lKSB7XG4gICAgLy8gYWx3YXlzIHVzZSB0aGUgdHJhbnNmb3JtLCBzbyB3ZSBkbyBub3QgaGF2ZSB0byByZXBlYXQgdGhlIHllcy9ubyB0cmFuc2Zyb20gbG9naWMgaGVyZVxuICAgIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgICAgdmFyIHZhbCA9IGJhc2VWYWxGbihkKTtcbiAgICAgIHJldHVybiB2YWwgPT09IG1pc3ZhbCA/IG1pc3ZhbCA6IGZhY2V0LmRhdGV0aW1lVHJhbnNmb3JtLnRyYW5zZm9ybSh2YWwpO1xuICAgIH07XG4gIH0gZWxzZSBpZiAoZmFjZXQuaXNEdXJhdGlvbikge1xuICAgIC8vIGFsd2F5cyB1c2UgdGhlIHRyYW5zZm9ybSwgc28gd2UgZG8gbm90IGhhdmUgdG8gcmVwZWF0IHRoZSB5ZXMvbm8gdHJhbnNmcm9tIGxvZ2ljIGhlcmVcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQpIHtcbiAgICAgIHZhciB2YWwgPSBiYXNlVmFsRm4oZCk7XG4gICAgICByZXR1cm4gdmFsID09PSBtaXN2YWwgPyBtaXN2YWwgOiBmYWNldC5kdXJhdGlvblRyYW5zZm9ybS50cmFuc2Zvcm0odmFsKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gbm8gdHJhbnNmcm9tLCByZXR1cm4gYmFzZSB2YWx1ZVxuICByZXR1cm4gYmFzZVZhbEZuO1xufVxuXG5mdW5jdGlvbiBjb250aW51b3VzR3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiBkO1xuICAgIH1cblxuICAgIHZhciBuZ3JvdXBzID0gcGFydGl0aW9uLmdyb3Vwcy5sZW5ndGg7XG4gICAgaWYgKGQgPCBwYXJ0aXRpb24ubWludmFsIHx8IGQgPiBwYXJ0aXRpb24ubWF4dmFsKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cblxuICAgIC8vIGJpbnMgaW5jbHVkZSB0aGVpciBsb3dlciBib3VuZCwgYnV0IG5vdCB0aGVpciB1cHBlciBib3VuZFxuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoaSA8IG5ncm91cHMgJiYgZCA+PSBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpXS5tYXgpIHtcbiAgICAgIGkrKztcbiAgICB9XG4gICAgLy8gc3BlY2lhbCBjYXNlIGxhc3QgYmluIGluY2x1ZGVzIGFsc28gdXBwZXJib3VuZCBkID09PSBwYXJ0aXRpb24ubWF4dmFsXG4gICAgaWYgKGkgPT09IG5ncm91cHMpIHtcbiAgICAgIHJldHVybiBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpIC0gMV0udmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBwYXJ0aXRpb24uZ3JvdXBzLm1vZGVsc1tpXS52YWx1ZTtcbiAgfTtcbn1cblxuLypcbiAqIFJvdW5kIHRoZSBkYXRldGltZSB0byB0aGUgc3BlY2lmaWVkIHJlc29sdXRpb25cbiAqIHNlZTpcbiAqIGh0dHA6Ly9tb21lbnRqcy5jb20vZG9jcy8jL21hbmlwdWxhdGluZy9zdGFydC1vZi9cbiAqIGh0dHA6Ly9tb21lbnRqcy5jb20vZG9jcy8jL2Rpc3BsYXlpbmcvYXMtamF2YXNjcmlwdC1kYXRlL1xuICovXG5mdW5jdGlvbiBkYXRldGltZUdyb3VwRm4gKHBhcnRpdGlvbikge1xuICB2YXIgdGltZVN0ZXAgPSB1dGlsLmdldERhdGV0aW1lUmVzb2x1dGlvbihwYXJ0aXRpb24ubWludmFsLCBwYXJ0aXRpb24ubWF4dmFsKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7XG4gICAgaWYgKGQgPT09IG1pc3ZhbCkge1xuICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICB9XG4gICAgaWYgKGQuaXNCZWZvcmUocGFydGl0aW9uLm1pbnZhbCkgfHwgZC5pc0FmdGVyKHBhcnRpdGlvbi5tYXh2YWwpKSB7XG4gICAgICByZXR1cm4gbWlzdmFsO1xuICAgIH1cbiAgICB2YXIgZ3JvdXBlZCA9IG1vbWVudChkKS5zdGFydE9mKHRpbWVTdGVwKS5mb3JtYXQoKTtcbiAgICByZXR1cm4gZ3JvdXBlZDtcbiAgfTtcbn1cblxuLypcbiAqIFJvdW5kIHRoZSBkdXJhdGlvbiB0byB0aGUgc3BlY2lmaWVkIHJlc29sdXRpb25cbiAqL1xuZnVuY3Rpb24gZHVyYXRpb25Hcm91cEZuIChwYXJ0aXRpb24pIHtcbiAgdmFyIHRpbWVTdGVwID0gdXRpbC5nZXREdXJhdGlvblJlc29sdXRpb24ocGFydGl0aW9uLm1pbnZhbCwgcGFydGl0aW9uLm1heHZhbCk7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkge1xuICAgIGlmIChkID09PSBtaXN2YWwpIHtcbiAgICAgIHJldHVybiBtaXN2YWw7XG4gICAgfVxuICAgIGlmIChkIDwgcGFydGl0aW9uLm1pbnZhbCB8fCBkID4gcGFydGl0aW9uLm1heHZhbCkge1xuICAgICAgcmV0dXJuIG1pc3ZhbDtcbiAgICB9XG4gICAgdmFyIHJvdW5kZWQgPSBNYXRoLmZsb29yKHBhcnNlRmxvYXQoZC5hcyh0aW1lU3RlcCkpKTtcbiAgICByZXR1cm4gbW9tZW50LmR1cmF0aW9uKHJvdW5kZWQsIHRpbWVTdGVwKS50b0lTT1N0cmluZygpO1xuICB9O1xufVxuXG4vKlxuICogRG9uJ3QgZG8gYW55IGdyb3VwaW5nOyB0aGF0IGlzIGRvbmUgaW4gdGhlIHN0ZXAgZnJvbSBiYXNlIHZhbHVlIHRvIHZhbHVlLlxuICogTWF0Y2hpbmcgb2YgZmFjZXQgdmFsdWUgYW5kIGdyb3VwIGNvdWxkIGxlYWQgdG8gYSBkaWZmZXJlbnQgb3JkZXJpbmcsXG4gKiB3aGljaCBpcyBub3QgYWxsb3dlZCBieSBjcm9zc2ZpbHRlclxuICovXG5mdW5jdGlvbiBjYXRlZ29yaWFsR3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZCkgeyByZXR1cm4gZDsgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBncm91cGVkIHZhbHVlIGZvciBhIHRyYW5zZm9ybWVkIHZhbHVlXG4gKlxuICogQGNhbGxiYWNrIGdyb3VwQ0JcbiAqIEBwYXJhbSB7T2JqZWN0fSBkIFRyYW5zZm9ybWVkIHZhbHVlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBHcm91cFxuICovXG5cbi8qKlxuICogQ3JlYXRlIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBncm91cCB2YWx1ZSBmb3IgYSBwYXJ0aXRpb25cbiAqIEBwYXJhbSB7UGFydGl0aW9ufSBwYXJ0aXRpb25cbiAqIEByZXR1cm5zIHtjYn0gR3JvdXAgZnVuY3Rpb24gZm9yIHRoaXMgcGFydGl0aW9uLCB0YWtpbmcgYSBgRGF0YWBcbiAqL1xuZnVuY3Rpb24gZ3JvdXBGbiAocGFydGl0aW9uKSB7XG4gIGlmIChwYXJ0aXRpb24uaXNDb25zdGFudCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7IHJldHVybiAnMSc7IH07XG4gIH0gZWxzZSBpZiAocGFydGl0aW9uLmlzQ29udGludW91cykge1xuICAgIHJldHVybiBjb250aW51b3VzR3JvdXBGbihwYXJ0aXRpb24pO1xuICB9IGVsc2UgaWYgKHBhcnRpdGlvbi5pc0NhdGVnb3JpYWwpIHtcbiAgICByZXR1cm4gY2F0ZWdvcmlhbEdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNEYXRldGltZSkge1xuICAgIHJldHVybiBkYXRldGltZUdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNEdXJhdGlvbikge1xuICAgIHJldHVybiBkdXJhdGlvbkdyb3VwRm4ocGFydGl0aW9uKTtcbiAgfSBlbHNlIGlmIChwYXJ0aXRpb24uaXNUZXh0KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkKSB7IHJldHVybiBkLnRvU3RyaW5nKCk7IH07XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS5lcnJvcignR3JvdXAgZnVuY3Rpb24gbm90IGltcGxlbWVudGVkIGZvciBwYXJ0aXRpb24nLCBwYXJ0aXRpb24pO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICByYXdWYWx1ZUZuOiByYXdWYWx1ZUZuLFxuICBiYXNlVmFsdWVGbjogYmFzZVZhbHVlRm4sXG4gIHZhbHVlRm46IHZhbHVlRm4sXG4gIGdyb3VwRm46IGdyb3VwRm4sXG5cbiAgcmVkdWNlRm46IHJlZHVjZUZuXG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///adfa\n")},b123:function(module,exports,__webpack_require__){eval("/**\n * DurationTransfrom defines a transformation on duration data\n *\n * @class DurationTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\nvar util = __webpack_require__(/*! ../util/time */ \"d45b\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    /**\n     * Units of the duration\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    units: ['string', true, 'ISO8601'],\n\n    /**\n     * For durations, transforms duration to these units\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    transformedUnits: ['string', true, 'ISO8601'],\n\n    /**\n     * Transform the date to this timezone.\n     *\n     * @memberof! DatetimeTransform\n     * @type {string}\n     */\n    transformedZone: ['string', true, 'ISO8601'],\n\n    /**\n     * Controls conversion to datetime by adding this date\n     *\n     * @memberof! DurationTransform\n     * @type {string}\n     */\n    transformedReference: 'string'\n  },\n  derived: {\n    /**\n     * Reference momentjs for duration <-> datetime conversion\n     *\n     * @type {moment}\n     * @memberof! DurationTransform\n     */\n    referenceMoment: {\n      deps: ['transformedReference', 'transformedZone'],\n      fn: function () {\n        var tz;\n        if (this.transformedZone === 'ISO8601') {\n          tz = moment.tz.guess();\n        } else {\n          var timeZone = util.timeZones.get(this.transformedZone, 'description');\n          if (timeZone && timeZone.format) {\n            tz = timeZone.format;\n          } else {\n            tz = moment.tz.guess();\n          }\n        }\n\n        if (this.transformedReference) {\n          return moment.tz(this.transformedReference, tz);\n        }\n        return null;\n      }\n    },\n    /**\n     * The type of the facet after the transformation has been applied\n     *\n     * @type {string}\n     * @memberof! DurationTransform\n     */\n    transformedType: {\n      deps: ['transformedFormat', 'transformedReference', 'transformedZone'],\n      fn: function () {\n        if (this.referenceMoment) {\n          return 'datetime';\n        } else if (this.transformedUnits !== 'ISO8601') {\n          return 'continuous';\n        } else {\n          return 'duration';\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minium value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMin: {\n      deps: ['transformedType'],\n      fn: function () {\n        var facet = this.parent;\n        if (this.transformedType === 'datetime') {\n          return this.transform(facet.minval);\n        } else if (this.transformedType === 'continuous') {\n          return this.transform(facet.minval);\n        } else {\n          return facet.minval;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMax: {\n      deps: ['transformedType'],\n      fn: function () {\n        var facet = this.parent;\n        if (this.transformedType === 'datetime') {\n          return this.transform(facet.maxval);\n        } else if (this.transformedType === 'continuous') {\n          return this.transform(facet.maxval);\n        } else {\n          return facet.maxval;\n        }\n      },\n      cache: false\n    },\n    /**\n     * The minimum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMinAsText: {\n      deps: ['transformedMin', 'transformedType'],\n      fn: function () {\n        var minval = this.transformedMin;\n        if (this.transformedType === 'datetime') {\n          return minval.format();\n        } else {\n          return minval.toString();\n        }\n      },\n      cache: false\n    },\n    /**\n     * The maximum value this facet can take, after the transformation has been applied\n     *\n     * @type {number}\n     * @memberof! DurationTransform\n     */\n    transformedMaxAsText: {\n      deps: ['transformedMax', 'transformedType'],\n      fn: function () {\n        var maxval = this.transformedMax;\n        if (this.transformedType === 'datetime') {\n          return maxval.format();\n        } else {\n          return maxval.toString();\n        }\n      },\n      cache: false\n    }\n  },\n\n  /**\n   * Apply the configured transformation to this Facet's value\n   *\n   * @function\n   * @memberof! DurationTransform\n   * @param {Object} inval momentjs duration\n   * @returns {Object} outval momentjs duration or datetime\n   */\n  transform: function transform (inval) {\n    var units;\n    if (this.referenceMoment) {\n      // duration -> datetime\n      return this.referenceMoment.clone().add(inval);\n    } else if (this.transformedUnits !== 'ISO8601') {\n      // duration -> continuous\n      units = util.durationUnits.get(this.transformedUnits, 'description').momentFormat;\n      return inval.as(units);\n    } else {\n      // no change\n      return inval;\n    }\n  },\n  reset: function () {\n    this.unset(['zone', 'transformedFormat', 'transformedZone', 'transformedReference']);\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjEyMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvZHVyYXRpb24tdHJhbnNmb3JtLmpzPzJkZjUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEdXJhdGlvblRyYW5zZnJvbSBkZWZpbmVzIGEgdHJhbnNmb3JtYXRpb24gb24gZHVyYXRpb24gZGF0YVxuICpcbiAqIEBjbGFzcyBEdXJhdGlvblRyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcbnZhciBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQtdGltZXpvbmUnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbC90aW1lJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBVbml0cyBvZiB0aGUgZHVyYXRpb25cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHVuaXRzOiBbJ3N0cmluZycsIHRydWUsICdJU084NjAxJ10sXG5cbiAgICAvKipcbiAgICAgKiBGb3IgZHVyYXRpb25zLCB0cmFuc2Zvcm1zIGR1cmF0aW9uIHRvIHRoZXNlIHVuaXRzXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFVuaXRzOiBbJ3N0cmluZycsIHRydWUsICdJU084NjAxJ10sXG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm0gdGhlIGRhdGUgdG8gdGhpcyB0aW1lem9uZS5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiEgRGF0ZXRpbWVUcmFuc2Zvcm1cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkWm9uZTogWydzdHJpbmcnLCB0cnVlLCAnSVNPODYwMSddLFxuXG4gICAgLyoqXG4gICAgICogQ29udHJvbHMgY29udmVyc2lvbiB0byBkYXRldGltZSBieSBhZGRpbmcgdGhpcyBkYXRlXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZFJlZmVyZW5jZTogJ3N0cmluZydcbiAgfSxcbiAgZGVyaXZlZDoge1xuICAgIC8qKlxuICAgICAqIFJlZmVyZW5jZSBtb21lbnRqcyBmb3IgZHVyYXRpb24gPC0+IGRhdGV0aW1lIGNvbnZlcnNpb25cbiAgICAgKlxuICAgICAqIEB0eXBlIHttb21lbnR9XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblRyYW5zZm9ybVxuICAgICAqL1xuICAgIHJlZmVyZW5jZU1vbWVudDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZFJlZmVyZW5jZScsICd0cmFuc2Zvcm1lZFpvbmUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0ejtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRab25lID09PSAnSVNPODYwMScpIHtcbiAgICAgICAgICB0eiA9IG1vbWVudC50ei5ndWVzcygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciB0aW1lWm9uZSA9IHV0aWwudGltZVpvbmVzLmdldCh0aGlzLnRyYW5zZm9ybWVkWm9uZSwgJ2Rlc2NyaXB0aW9uJyk7XG4gICAgICAgICAgaWYgKHRpbWVab25lICYmIHRpbWVab25lLmZvcm1hdCkge1xuICAgICAgICAgICAgdHogPSB0aW1lWm9uZS5mb3JtYXQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHR6ID0gbW9tZW50LnR6Lmd1ZXNzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXR1cm4gbW9tZW50LnR6KHRoaXMudHJhbnNmb3JtZWRSZWZlcmVuY2UsIHR6KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBmYWNldCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRUeXBlOiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkRm9ybWF0JywgJ3RyYW5zZm9ybWVkUmVmZXJlbmNlJywgJ3RyYW5zZm9ybWVkWm9uZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMucmVmZXJlbmNlTW9tZW50KSB7XG4gICAgICAgICAgcmV0dXJuICdkYXRldGltZSc7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy50cmFuc2Zvcm1lZFVuaXRzICE9PSAnSVNPODYwMScpIHtcbiAgICAgICAgICByZXR1cm4gJ2NvbnRpbnVvdXMnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiAnZHVyYXRpb24nO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWluaXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1pbjoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmYWNldCA9IHRoaXMucGFyZW50O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0oZmFjZXQubWludmFsKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2NvbnRpbnVvdXMnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKGZhY2V0Lm1pbnZhbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGZhY2V0Lm1pbnZhbDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdmFsdWUgdGhpcyBmYWNldCBjYW4gdGFrZSwgYWZ0ZXIgdGhlIHRyYW5zZm9ybWF0aW9uIGhhcyBiZWVuIGFwcGxpZWRcbiAgICAgKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblRyYW5zZm9ybVxuICAgICAqL1xuICAgIHRyYW5zZm9ybWVkTWF4OiB7XG4gICAgICBkZXBzOiBbJ3RyYW5zZm9ybWVkVHlwZSddLFxuICAgICAgZm46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZhY2V0ID0gdGhpcy5wYXJlbnQ7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybWVkVHlwZSA9PT0gJ2RhdGV0aW1lJykge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybShmYWNldC5tYXh2YWwpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnY29udGludW91cycpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0oZmFjZXQubWF4dmFsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZmFjZXQubWF4dmFsO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FjaGU6IGZhbHNlXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUaGUgbWluaW11bSB2YWx1ZSB0aGlzIGZhY2V0IGNhbiB0YWtlLCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gYXBwbGllZFxuICAgICAqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAgICovXG4gICAgdHJhbnNmb3JtZWRNaW5Bc1RleHQ6IHtcbiAgICAgIGRlcHM6IFsndHJhbnNmb3JtZWRNaW4nLCAndHJhbnNmb3JtZWRUeXBlJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbWludmFsID0gdGhpcy50cmFuc2Zvcm1lZE1pbjtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtZWRUeXBlID09PSAnZGF0ZXRpbWUnKSB7XG4gICAgICAgICAgcmV0dXJuIG1pbnZhbC5mb3JtYXQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbWludmFsLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYWNoZTogZmFsc2VcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHZhbHVlIHRoaXMgZmFjZXQgY2FuIHRha2UsIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBhcHBsaWVkXG4gICAgICpcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25UcmFuc2Zvcm1cbiAgICAgKi9cbiAgICB0cmFuc2Zvcm1lZE1heEFzVGV4dDoge1xuICAgICAgZGVwczogWyd0cmFuc2Zvcm1lZE1heCcsICd0cmFuc2Zvcm1lZFR5cGUnXSxcbiAgICAgIGZuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtYXh2YWwgPSB0aGlzLnRyYW5zZm9ybWVkTWF4O1xuICAgICAgICBpZiAodGhpcy50cmFuc2Zvcm1lZFR5cGUgPT09ICdkYXRldGltZScpIHtcbiAgICAgICAgICByZXR1cm4gbWF4dmFsLmZvcm1hdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBtYXh2YWwudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGNhY2hlOiBmYWxzZVxuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogQXBwbHkgdGhlIGNvbmZpZ3VyZWQgdHJhbnNmb3JtYXRpb24gdG8gdGhpcyBGYWNldCdzIHZhbHVlXG4gICAqXG4gICAqIEBmdW5jdGlvblxuICAgKiBAbWVtYmVyb2YhIER1cmF0aW9uVHJhbnNmb3JtXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBpbnZhbCBtb21lbnRqcyBkdXJhdGlvblxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBvdXR2YWwgbW9tZW50anMgZHVyYXRpb24gb3IgZGF0ZXRpbWVcbiAgICovXG4gIHRyYW5zZm9ybTogZnVuY3Rpb24gdHJhbnNmb3JtIChpbnZhbCkge1xuICAgIHZhciB1bml0cztcbiAgICBpZiAodGhpcy5yZWZlcmVuY2VNb21lbnQpIHtcbiAgICAgIC8vIGR1cmF0aW9uIC0+IGRhdGV0aW1lXG4gICAgICByZXR1cm4gdGhpcy5yZWZlcmVuY2VNb21lbnQuY2xvbmUoKS5hZGQoaW52YWwpO1xuICAgIH0gZWxzZSBpZiAodGhpcy50cmFuc2Zvcm1lZFVuaXRzICE9PSAnSVNPODYwMScpIHtcbiAgICAgIC8vIGR1cmF0aW9uIC0+IGNvbnRpbnVvdXNcbiAgICAgIHVuaXRzID0gdXRpbC5kdXJhdGlvblVuaXRzLmdldCh0aGlzLnRyYW5zZm9ybWVkVW5pdHMsICdkZXNjcmlwdGlvbicpLm1vbWVudEZvcm1hdDtcbiAgICAgIHJldHVybiBpbnZhbC5hcyh1bml0cyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG5vIGNoYW5nZVxuICAgICAgcmV0dXJuIGludmFsO1xuICAgIH1cbiAgfSxcbiAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVuc2V0KFsnem9uZScsICd0cmFuc2Zvcm1lZEZvcm1hdCcsICd0cmFuc2Zvcm1lZFpvbmUnLCAndHJhbnNmb3JtZWRSZWZlcmVuY2UnXSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///b123\n")},b452:function(module,exports,__webpack_require__){eval("\n/**\n * Module dependencies.\n */\n\nvar url = __webpack_require__(/*! ./url */ \"780f\");\nvar parser = __webpack_require__(/*! socket.io-parser */ \"6fba\");\nvar Manager = __webpack_require__(/*! ./manager */ \"1e1f\");\nvar debug = __webpack_require__(/*! debug */ \"433b\")('socket.io-client');\n\n/**\n * Module exports.\n */\n\nmodule.exports = exports = lookup;\n\n/**\n * Managers cache.\n */\n\nvar cache = exports.managers = {};\n\n/**\n * Looks up an existing `Manager` for multiplexing.\n * If the user summons:\n *\n *   `io('http://localhost/a');`\n *   `io('http://localhost/b');`\n *\n * We reuse the existing instance based on same scheme/port/host,\n * and we initialize sockets for each namespace.\n *\n * @api public\n */\n\nfunction lookup (uri, opts) {\n  if (typeof uri === 'object') {\n    opts = uri;\n    uri = undefined;\n  }\n\n  opts = opts || {};\n\n  var parsed = url(uri);\n  var source = parsed.source;\n  var id = parsed.id;\n  var path = parsed.path;\n  var sameNamespace = cache[id] && path in cache[id].nsps;\n  var newConnection = opts.forceNew || opts['force new connection'] ||\n                      false === opts.multiplex || sameNamespace;\n\n  var io;\n\n  if (newConnection) {\n    debug('ignoring socket cache for %s', source);\n    io = Manager(source, opts);\n  } else {\n    if (!cache[id]) {\n      debug('new io instance for %s', source);\n      cache[id] = Manager(source, opts);\n    }\n    io = cache[id];\n  }\n  if (parsed.query && !opts.query) {\n    opts.query = parsed.query;\n  } else if (opts && 'object' === typeof opts.query) {\n    opts.query = encodeQueryString(opts.query);\n  }\n  return io.socket(parsed.path, opts);\n}\n/**\n *  Helper method to parse query objects to string.\n * @param {object} query\n * @returns {string}\n */\nfunction encodeQueryString (obj) {\n  var str = [];\n  for (var p in obj) {\n    if (obj.hasOwnProperty(p)) {\n      str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));\n    }\n  }\n  return str.join('&');\n}\n/**\n * Protocol version.\n *\n * @api public\n */\n\nexports.protocol = parser.protocol;\n\n/**\n * `connect`.\n *\n * @param {String} uri\n * @api public\n */\n\nexports.connect = lookup;\n\n/**\n * Expose constructors for standalone build.\n *\n * @api public\n */\n\nexports.Manager = __webpack_require__(/*! ./manager */ \"1e1f\");\nexports.Socket = __webpack_require__(/*! ./socket */ \"4c13\");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYjQ1Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvaW5kZXguanM/ZjQyZiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgdXJsID0gcmVxdWlyZSgnLi91cmwnKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgTWFuYWdlciA9IHJlcXVpcmUoJy4vbWFuYWdlcicpO1xudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnc29ja2V0LmlvLWNsaWVudCcpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGxvb2t1cDtcblxuLyoqXG4gKiBNYW5hZ2VycyBjYWNoZS5cbiAqL1xuXG52YXIgY2FjaGUgPSBleHBvcnRzLm1hbmFnZXJzID0ge307XG5cbi8qKlxuICogTG9va3MgdXAgYW4gZXhpc3RpbmcgYE1hbmFnZXJgIGZvciBtdWx0aXBsZXhpbmcuXG4gKiBJZiB0aGUgdXNlciBzdW1tb25zOlxuICpcbiAqICAgYGlvKCdodHRwOi8vbG9jYWxob3N0L2EnKTtgXG4gKiAgIGBpbygnaHR0cDovL2xvY2FsaG9zdC9iJyk7YFxuICpcbiAqIFdlIHJldXNlIHRoZSBleGlzdGluZyBpbnN0YW5jZSBiYXNlZCBvbiBzYW1lIHNjaGVtZS9wb3J0L2hvc3QsXG4gKiBhbmQgd2UgaW5pdGlhbGl6ZSBzb2NrZXRzIGZvciBlYWNoIG5hbWVzcGFjZS5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGxvb2t1cCAodXJpLCBvcHRzKSB7XG4gIGlmICh0eXBlb2YgdXJpID09PSAnb2JqZWN0Jykge1xuICAgIG9wdHMgPSB1cmk7XG4gICAgdXJpID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgdmFyIHBhcnNlZCA9IHVybCh1cmkpO1xuICB2YXIgc291cmNlID0gcGFyc2VkLnNvdXJjZTtcbiAgdmFyIGlkID0gcGFyc2VkLmlkO1xuICB2YXIgcGF0aCA9IHBhcnNlZC5wYXRoO1xuICB2YXIgc2FtZU5hbWVzcGFjZSA9IGNhY2hlW2lkXSAmJiBwYXRoIGluIGNhY2hlW2lkXS5uc3BzO1xuICB2YXIgbmV3Q29ubmVjdGlvbiA9IG9wdHMuZm9yY2VOZXcgfHwgb3B0c1snZm9yY2UgbmV3IGNvbm5lY3Rpb24nXSB8fFxuICAgICAgICAgICAgICAgICAgICAgIGZhbHNlID09PSBvcHRzLm11bHRpcGxleCB8fCBzYW1lTmFtZXNwYWNlO1xuXG4gIHZhciBpbztcblxuICBpZiAobmV3Q29ubmVjdGlvbikge1xuICAgIGRlYnVnKCdpZ25vcmluZyBzb2NrZXQgY2FjaGUgZm9yICVzJywgc291cmNlKTtcbiAgICBpbyA9IE1hbmFnZXIoc291cmNlLCBvcHRzKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoIWNhY2hlW2lkXSkge1xuICAgICAgZGVidWcoJ25ldyBpbyBpbnN0YW5jZSBmb3IgJXMnLCBzb3VyY2UpO1xuICAgICAgY2FjaGVbaWRdID0gTWFuYWdlcihzb3VyY2UsIG9wdHMpO1xuICAgIH1cbiAgICBpbyA9IGNhY2hlW2lkXTtcbiAgfVxuICBpZiAocGFyc2VkLnF1ZXJ5ICYmICFvcHRzLnF1ZXJ5KSB7XG4gICAgb3B0cy5xdWVyeSA9IHBhcnNlZC5xdWVyeTtcbiAgfSBlbHNlIGlmIChvcHRzICYmICdvYmplY3QnID09PSB0eXBlb2Ygb3B0cy5xdWVyeSkge1xuICAgIG9wdHMucXVlcnkgPSBlbmNvZGVRdWVyeVN0cmluZyhvcHRzLnF1ZXJ5KTtcbiAgfVxuICByZXR1cm4gaW8uc29ja2V0KHBhcnNlZC5wYXRoLCBvcHRzKTtcbn1cbi8qKlxuICogIEhlbHBlciBtZXRob2QgdG8gcGFyc2UgcXVlcnkgb2JqZWN0cyB0byBzdHJpbmcuXG4gKiBAcGFyYW0ge29iamVjdH0gcXVlcnlcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGVuY29kZVF1ZXJ5U3RyaW5nIChvYmopIHtcbiAgdmFyIHN0ciA9IFtdO1xuICBmb3IgKHZhciBwIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkocCkpIHtcbiAgICAgIHN0ci5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChwKSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChvYmpbcF0pKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0ci5qb2luKCcmJyk7XG59XG4vKipcbiAqIFByb3RvY29sIHZlcnNpb24uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sO1xuXG4vKipcbiAqIGBjb25uZWN0YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJpXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuY29ubmVjdCA9IGxvb2t1cDtcblxuLyoqXG4gKiBFeHBvc2UgY29uc3RydWN0b3JzIGZvciBzdGFuZGFsb25lIGJ1aWxkLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5NYW5hZ2VyID0gcmVxdWlyZSgnLi9tYW5hZ2VyJyk7XG5leHBvcnRzLlNvY2tldCA9IHJlcXVpcmUoJy4vc29ja2V0Jyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///b452\n")},ba23:function(module,exports,__webpack_require__){eval("/**\n * Categorial Rule abstracts a single matching rule\n *\n * @class CategorialRule\n */\nvar Base = __webpack_require__(/*! ../util/base */ \"3902\");\n\n// Data structure for mapping categorial (and textual) data on groups\nmodule.exports = Base.extend({\n  props: {\n    /**\n     * string or string format of regexp to match data against.\n     * To use a regular expression, start and end the string with a slash, '/'.\n     * Options can be appedended, notably 'i' for case insensitive matching.\n     * The first captured group can be used in the group, see below.\n     * Examples\n     * 1. 'hello' matches 'hello', not 'hello world'\n     * 2. '/hello/' matches 'hello world', but not 'Hello world'\n     * 3. '/hello/i' matches 'I say Hello'\n     * @type {string}\n     * @memberof! CategorialRule\n     */\n    expression: ['string', true, 'Missing'],\n\n    /**\n     * Number of items this transform is used\n     * @type {number}\n     * @memberof! CategorialRule\n     */\n    count: ['number', true, 0],\n\n    /**\n     * Name of the group this is mapped to. The special substring $1 is replaced by the first captured group,\n     * in example 4 above, with group set to 'He says $1', the match results in 'He says goodbye'\n     * @type {string}\n     * @memberof! CategorialRule\n     */\n    group: ['string', true, 'Missing']\n  },\n  derived: {\n\n    /**\n     * Match function\n     * @memberof! CategorialRule\n     * @function\n     * @param {string} text The text to match\n     * @returns {string|false} group The group label if matching, else false\n     */\n    match: {\n      deps: ['expression', 'group'],\n      fn: function () {\n        var that = this;\n\n        var reFormat = new RegExp(/^\\/(.*)\\/([gimuy]*)$/);\n        var match = reFormat.exec(that.expression);\n\n        if (match) {\n          // if the expression is in the form of /<text>/<flags>, it is a regular expression, compile it\n          var exp = RegExp(match[1], match[2]);\n          return function (text) {\n            var m = exp.exec(text);\n            if (m) {\n              return that.group;\n              // return that.group.replace('$1', m[1]);\n            } else {\n              return false;\n            }\n          };\n        } else {\n          // otherwise do matching using '==='\n          return function (text) {\n            if (text === that.expression) {\n              return that.group;\n            } else {\n              return false;\n            }\n          };\n        }\n      }\n    }\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmEyMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvY2F0ZWdvcmlhbC1ydWxlLmpzP2UxNzMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDYXRlZ29yaWFsIFJ1bGUgYWJzdHJhY3RzIGEgc2luZ2xlIG1hdGNoaW5nIHJ1bGVcbiAqXG4gKiBAY2xhc3MgQ2F0ZWdvcmlhbFJ1bGVcbiAqL1xudmFyIEJhc2UgPSByZXF1aXJlKCcuLi91dGlsL2Jhc2UnKTtcblxuLy8gRGF0YSBzdHJ1Y3R1cmUgZm9yIG1hcHBpbmcgY2F0ZWdvcmlhbCAoYW5kIHRleHR1YWwpIGRhdGEgb24gZ3JvdXBzXG5tb2R1bGUuZXhwb3J0cyA9IEJhc2UuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBzdHJpbmcgb3Igc3RyaW5nIGZvcm1hdCBvZiByZWdleHAgdG8gbWF0Y2ggZGF0YSBhZ2FpbnN0LlxuICAgICAqIFRvIHVzZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbiwgc3RhcnQgYW5kIGVuZCB0aGUgc3RyaW5nIHdpdGggYSBzbGFzaCwgJy8nLlxuICAgICAqIE9wdGlvbnMgY2FuIGJlIGFwcGVkZW5kZWQsIG5vdGFibHkgJ2knIGZvciBjYXNlIGluc2Vuc2l0aXZlIG1hdGNoaW5nLlxuICAgICAqIFRoZSBmaXJzdCBjYXB0dXJlZCBncm91cCBjYW4gYmUgdXNlZCBpbiB0aGUgZ3JvdXAsIHNlZSBiZWxvdy5cbiAgICAgKiBFeGFtcGxlc1xuICAgICAqIDEuICdoZWxsbycgbWF0Y2hlcyAnaGVsbG8nLCBub3QgJ2hlbGxvIHdvcmxkJ1xuICAgICAqIDIuICcvaGVsbG8vJyBtYXRjaGVzICdoZWxsbyB3b3JsZCcsIGJ1dCBub3QgJ0hlbGxvIHdvcmxkJ1xuICAgICAqIDMuICcvaGVsbG8vaScgbWF0Y2hlcyAnSSBzYXkgSGVsbG8nXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAbWVtYmVyb2YhIENhdGVnb3JpYWxSdWxlXG4gICAgICovXG4gICAgZXhwcmVzc2lvbjogWydzdHJpbmcnLCB0cnVlLCAnTWlzc2luZyddLFxuXG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIGl0ZW1zIHRoaXMgdHJhbnNmb3JtIGlzIHVzZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBtZW1iZXJvZiEgQ2F0ZWdvcmlhbFJ1bGVcbiAgICAgKi9cbiAgICBjb3VudDogWydudW1iZXInLCB0cnVlLCAwXSxcblxuICAgIC8qKlxuICAgICAqIE5hbWUgb2YgdGhlIGdyb3VwIHRoaXMgaXMgbWFwcGVkIHRvLiBUaGUgc3BlY2lhbCBzdWJzdHJpbmcgJDEgaXMgcmVwbGFjZWQgYnkgdGhlIGZpcnN0IGNhcHR1cmVkIGdyb3VwLFxuICAgICAqIGluIGV4YW1wbGUgNCBhYm92ZSwgd2l0aCBncm91cCBzZXQgdG8gJ0hlIHNheXMgJDEnLCB0aGUgbWF0Y2ggcmVzdWx0cyBpbiAnSGUgc2F5cyBnb29kYnllJ1xuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQG1lbWJlcm9mISBDYXRlZ29yaWFsUnVsZVxuICAgICAqL1xuICAgIGdyb3VwOiBbJ3N0cmluZycsIHRydWUsICdNaXNzaW5nJ11cbiAgfSxcbiAgZGVyaXZlZDoge1xuXG4gICAgLyoqXG4gICAgICogTWF0Y2ggZnVuY3Rpb25cbiAgICAgKiBAbWVtYmVyb2YhIENhdGVnb3JpYWxSdWxlXG4gICAgICogQGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgVGhlIHRleHQgdG8gbWF0Y2hcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfGZhbHNlfSBncm91cCBUaGUgZ3JvdXAgbGFiZWwgaWYgbWF0Y2hpbmcsIGVsc2UgZmFsc2VcbiAgICAgKi9cbiAgICBtYXRjaDoge1xuICAgICAgZGVwczogWydleHByZXNzaW9uJywgJ2dyb3VwJ10sXG4gICAgICBmbjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHJlRm9ybWF0ID0gbmV3IFJlZ0V4cCgvXlxcLyguKilcXC8oW2dpbXV5XSopJC8pO1xuICAgICAgICB2YXIgbWF0Y2ggPSByZUZvcm1hdC5leGVjKHRoYXQuZXhwcmVzc2lvbik7XG5cbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgLy8gaWYgdGhlIGV4cHJlc3Npb24gaXMgaW4gdGhlIGZvcm0gb2YgLzx0ZXh0Pi88ZmxhZ3M+LCBpdCBpcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiwgY29tcGlsZSBpdFxuICAgICAgICAgIHZhciBleHAgPSBSZWdFeHAobWF0Y2hbMV0sIG1hdGNoWzJdKTtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHRleHQpIHtcbiAgICAgICAgICAgIHZhciBtID0gZXhwLmV4ZWModGV4dCk7XG4gICAgICAgICAgICBpZiAobSkge1xuICAgICAgICAgICAgICByZXR1cm4gdGhhdC5ncm91cDtcbiAgICAgICAgICAgICAgLy8gcmV0dXJuIHRoYXQuZ3JvdXAucmVwbGFjZSgnJDEnLCBtWzFdKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG90aGVyd2lzZSBkbyBtYXRjaGluZyB1c2luZyAnPT09J1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICAgICAgaWYgKHRleHQgPT09IHRoYXQuZXhwcmVzc2lvbikge1xuICAgICAgICAgICAgICByZXR1cm4gdGhhdC5ncm91cDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///ba23\n")},bb16:function(module,exports,__webpack_require__){eval("\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = debug;\nexports.coerce = coerce;\nexports.disable = disable;\nexports.enable = enable;\nexports.enabled = enabled;\nexports.humanize = __webpack_require__(/*! ms */ \"1ed2\");\n\n/**\n * The currently active debug mode names, and names to skip.\n */\n\nexports.names = [];\nexports.skips = [];\n\n/**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lowercased letter, i.e. \"n\".\n */\n\nexports.formatters = {};\n\n/**\n * Previously assigned color.\n */\n\nvar prevColor = 0;\n\n/**\n * Previous log timestamp.\n */\n\nvar prevTime;\n\n/**\n * Select a color.\n *\n * @return {Number}\n * @api private\n */\n\nfunction selectColor() {\n  return exports.colors[prevColor++ % exports.colors.length];\n}\n\n/**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\nfunction debug(namespace) {\n\n  // define the `disabled` version\n  function disabled() {\n  }\n  disabled.enabled = false;\n\n  // define the `enabled` version\n  function enabled() {\n\n    var self = enabled;\n\n    // set `diff` timestamp\n    var curr = +new Date();\n    var ms = curr - (prevTime || curr);\n    self.diff = ms;\n    self.prev = prevTime;\n    self.curr = curr;\n    prevTime = curr;\n\n    // add the `color` if not set\n    if (null == self.useColors) self.useColors = exports.useColors();\n    if (null == self.color && self.useColors) self.color = selectColor();\n\n    var args = Array.prototype.slice.call(arguments);\n\n    args[0] = exports.coerce(args[0]);\n\n    if ('string' !== typeof args[0]) {\n      // anything else let's inspect with %o\n      args = ['%o'].concat(args);\n    }\n\n    // apply any `formatters` transformations\n    var index = 0;\n    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {\n      // if we encounter an escaped % then don't increase the array index\n      if (match === '%%') return match;\n      index++;\n      var formatter = exports.formatters[format];\n      if ('function' === typeof formatter) {\n        var val = args[index];\n        match = formatter.call(self, val);\n\n        // now we need to remove `args[index]` since it's inlined in the `format`\n        args.splice(index, 1);\n        index--;\n      }\n      return match;\n    });\n\n    if ('function' === typeof exports.formatArgs) {\n      args = exports.formatArgs.apply(self, args);\n    }\n    var logFn = enabled.log || exports.log || console.log.bind(console);\n    logFn.apply(self, args);\n  }\n  enabled.enabled = true;\n\n  var fn = exports.enabled(namespace) ? enabled : disabled;\n\n  fn.namespace = namespace;\n\n  return fn;\n}\n\n/**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\nfunction enable(namespaces) {\n  exports.save(namespaces);\n\n  var split = (namespaces || '').split(/[\\s,]+/);\n  var len = split.length;\n\n  for (var i = 0; i < len; i++) {\n    if (!split[i]) continue; // ignore empty strings\n    namespaces = split[i].replace(/\\*/g, '.*?');\n    if (namespaces[0] === '-') {\n      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n    } else {\n      exports.names.push(new RegExp('^' + namespaces + '$'));\n    }\n  }\n}\n\n/**\n * Disable debug output.\n *\n * @api public\n */\n\nfunction disable() {\n  exports.enable('');\n}\n\n/**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\nfunction enabled(name) {\n  var i, len;\n  for (i = 0, len = exports.skips.length; i < len; i++) {\n    if (exports.skips[i].test(name)) {\n      return false;\n    }\n  }\n  for (i = 0, len = exports.names.length; i < len; i++) {\n    if (exports.names[i].test(name)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\nfunction coerce(val) {\n  if (val instanceof Error) return val.stack || val.message;\n  return val;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmIxNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9ub2RlX21vZHVsZXMvZGVidWcvZGVidWcuanM/NTJhNyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogVGhpcyBpcyB0aGUgY29tbW9uIGxvZ2ljIGZvciBib3RoIHRoZSBOb2RlLmpzIGFuZCB3ZWIgYnJvd3NlclxuICogaW1wbGVtZW50YXRpb25zIG9mIGBkZWJ1ZygpYC5cbiAqXG4gKiBFeHBvc2UgYGRlYnVnKClgIGFzIHRoZSBtb2R1bGUuXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZGVidWc7XG5leHBvcnRzLmNvZXJjZSA9IGNvZXJjZTtcbmV4cG9ydHMuZGlzYWJsZSA9IGRpc2FibGU7XG5leHBvcnRzLmVuYWJsZSA9IGVuYWJsZTtcbmV4cG9ydHMuZW5hYmxlZCA9IGVuYWJsZWQ7XG5leHBvcnRzLmh1bWFuaXplID0gcmVxdWlyZSgnbXMnKTtcblxuLyoqXG4gKiBUaGUgY3VycmVudGx5IGFjdGl2ZSBkZWJ1ZyBtb2RlIG5hbWVzLCBhbmQgbmFtZXMgdG8gc2tpcC5cbiAqL1xuXG5leHBvcnRzLm5hbWVzID0gW107XG5leHBvcnRzLnNraXBzID0gW107XG5cbi8qKlxuICogTWFwIG9mIHNwZWNpYWwgXCIlblwiIGhhbmRsaW5nIGZ1bmN0aW9ucywgZm9yIHRoZSBkZWJ1ZyBcImZvcm1hdFwiIGFyZ3VtZW50LlxuICpcbiAqIFZhbGlkIGtleSBuYW1lcyBhcmUgYSBzaW5nbGUsIGxvd2VyY2FzZWQgbGV0dGVyLCBpLmUuIFwiblwiLlxuICovXG5cbmV4cG9ydHMuZm9ybWF0dGVycyA9IHt9O1xuXG4vKipcbiAqIFByZXZpb3VzbHkgYXNzaWduZWQgY29sb3IuXG4gKi9cblxudmFyIHByZXZDb2xvciA9IDA7XG5cbi8qKlxuICogUHJldmlvdXMgbG9nIHRpbWVzdGFtcC5cbiAqL1xuXG52YXIgcHJldlRpbWU7XG5cbi8qKlxuICogU2VsZWN0IGEgY29sb3IuXG4gKlxuICogQHJldHVybiB7TnVtYmVyfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2VsZWN0Q29sb3IoKSB7XG4gIHJldHVybiBleHBvcnRzLmNvbG9yc1twcmV2Q29sb3IrKyAlIGV4cG9ydHMuY29sb3JzLmxlbmd0aF07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgZGVidWdnZXIgd2l0aCB0aGUgZ2l2ZW4gYG5hbWVzcGFjZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlYnVnKG5hbWVzcGFjZSkge1xuXG4gIC8vIGRlZmluZSB0aGUgYGRpc2FibGVkYCB2ZXJzaW9uXG4gIGZ1bmN0aW9uIGRpc2FibGVkKCkge1xuICB9XG4gIGRpc2FibGVkLmVuYWJsZWQgPSBmYWxzZTtcblxuICAvLyBkZWZpbmUgdGhlIGBlbmFibGVkYCB2ZXJzaW9uXG4gIGZ1bmN0aW9uIGVuYWJsZWQoKSB7XG5cbiAgICB2YXIgc2VsZiA9IGVuYWJsZWQ7XG5cbiAgICAvLyBzZXQgYGRpZmZgIHRpbWVzdGFtcFxuICAgIHZhciBjdXJyID0gK25ldyBEYXRlKCk7XG4gICAgdmFyIG1zID0gY3VyciAtIChwcmV2VGltZSB8fCBjdXJyKTtcbiAgICBzZWxmLmRpZmYgPSBtcztcbiAgICBzZWxmLnByZXYgPSBwcmV2VGltZTtcbiAgICBzZWxmLmN1cnIgPSBjdXJyO1xuICAgIHByZXZUaW1lID0gY3VycjtcblxuICAgIC8vIGFkZCB0aGUgYGNvbG9yYCBpZiBub3Qgc2V0XG4gICAgaWYgKG51bGwgPT0gc2VsZi51c2VDb2xvcnMpIHNlbGYudXNlQ29sb3JzID0gZXhwb3J0cy51c2VDb2xvcnMoKTtcbiAgICBpZiAobnVsbCA9PSBzZWxmLmNvbG9yICYmIHNlbGYudXNlQ29sb3JzKSBzZWxmLmNvbG9yID0gc2VsZWN0Q29sb3IoKTtcblxuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgIGFyZ3NbMF0gPSBleHBvcnRzLmNvZXJjZShhcmdzWzBdKTtcblxuICAgIGlmICgnc3RyaW5nJyAhPT0gdHlwZW9mIGFyZ3NbMF0pIHtcbiAgICAgIC8vIGFueXRoaW5nIGVsc2UgbGV0J3MgaW5zcGVjdCB3aXRoICVvXG4gICAgICBhcmdzID0gWyclbyddLmNvbmNhdChhcmdzKTtcbiAgICB9XG5cbiAgICAvLyBhcHBseSBhbnkgYGZvcm1hdHRlcnNgIHRyYW5zZm9ybWF0aW9uc1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgYXJnc1swXSA9IGFyZ3NbMF0ucmVwbGFjZSgvJShbYS16JV0pL2csIGZ1bmN0aW9uKG1hdGNoLCBmb3JtYXQpIHtcbiAgICAgIC8vIGlmIHdlIGVuY291bnRlciBhbiBlc2NhcGVkICUgdGhlbiBkb24ndCBpbmNyZWFzZSB0aGUgYXJyYXkgaW5kZXhcbiAgICAgIGlmIChtYXRjaCA9PT0gJyUlJykgcmV0dXJuIG1hdGNoO1xuICAgICAgaW5kZXgrKztcbiAgICAgIHZhciBmb3JtYXR0ZXIgPSBleHBvcnRzLmZvcm1hdHRlcnNbZm9ybWF0XTtcbiAgICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgZm9ybWF0dGVyKSB7XG4gICAgICAgIHZhciB2YWwgPSBhcmdzW2luZGV4XTtcbiAgICAgICAgbWF0Y2ggPSBmb3JtYXR0ZXIuY2FsbChzZWxmLCB2YWwpO1xuXG4gICAgICAgIC8vIG5vdyB3ZSBuZWVkIHRvIHJlbW92ZSBgYXJnc1tpbmRleF1gIHNpbmNlIGl0J3MgaW5saW5lZCBpbiB0aGUgYGZvcm1hdGBcbiAgICAgICAgYXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBpbmRleC0tO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH0pO1xuXG4gICAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBleHBvcnRzLmZvcm1hdEFyZ3MpIHtcbiAgICAgIGFyZ3MgPSBleHBvcnRzLmZvcm1hdEFyZ3MuYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgfVxuICAgIHZhciBsb2dGbiA9IGVuYWJsZWQubG9nIHx8IGV4cG9ydHMubG9nIHx8IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSk7XG4gICAgbG9nRm4uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbiAgZW5hYmxlZC5lbmFibGVkID0gdHJ1ZTtcblxuICB2YXIgZm4gPSBleHBvcnRzLmVuYWJsZWQobmFtZXNwYWNlKSA/IGVuYWJsZWQgOiBkaXNhYmxlZDtcblxuICBmbi5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7XG5cbiAgcmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgYSBkZWJ1ZyBtb2RlIGJ5IG5hbWVzcGFjZXMuIFRoaXMgY2FuIGluY2x1ZGUgbW9kZXNcbiAqIHNlcGFyYXRlZCBieSBhIGNvbG9uIGFuZCB3aWxkY2FyZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZW5hYmxlKG5hbWVzcGFjZXMpIHtcbiAgZXhwb3J0cy5zYXZlKG5hbWVzcGFjZXMpO1xuXG4gIHZhciBzcGxpdCA9IChuYW1lc3BhY2VzIHx8ICcnKS5zcGxpdCgvW1xccyxdKy8pO1xuICB2YXIgbGVuID0gc3BsaXQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoIXNwbGl0W2ldKSBjb250aW51ZTsgLy8gaWdub3JlIGVtcHR5IHN0cmluZ3NcbiAgICBuYW1lc3BhY2VzID0gc3BsaXRbaV0ucmVwbGFjZSgvXFwqL2csICcuKj8nKTtcbiAgICBpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG4gICAgICBleHBvcnRzLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzLnN1YnN0cigxKSArICckJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzICsgJyQnKSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGlzYWJsZSBkZWJ1ZyBvdXRwdXQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkaXNhYmxlKCkge1xuICBleHBvcnRzLmVuYWJsZSgnJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RlIG5hbWUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGVkKG5hbWUpIHtcbiAgdmFyIGksIGxlbjtcbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLnNraXBzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5uYW1lcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLm5hbWVzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29lcmNlIGB2YWxgLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjb2VyY2UodmFsKSB7XG4gIGlmICh2YWwgaW5zdGFuY2VvZiBFcnJvcikgcmV0dXJuIHZhbC5zdGFjayB8fCB2YWwubWVzc2FnZTtcbiAgcmV0dXJuIHZhbDtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///bb16\n")},bff6:function(module,exports){eval("/**\n * This module defines a single unique missing value indicator.\n * All invalid, absent, or user-indicated missing value is internally set to this value.\n *\n * @example\n * var misval = require('./framework/misval');\n * if ( a === misval ) {\n *   ...\n * }\n * @module client/misval\n */\n\n// module.exports = -Number.MAX_VALUE;\nmodule.exports = 'missing';\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmZmNi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC9taXN2YWwuanM/YjI3OSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoaXMgbW9kdWxlIGRlZmluZXMgYSBzaW5nbGUgdW5pcXVlIG1pc3NpbmcgdmFsdWUgaW5kaWNhdG9yLlxuICogQWxsIGludmFsaWQsIGFic2VudCwgb3IgdXNlci1pbmRpY2F0ZWQgbWlzc2luZyB2YWx1ZSBpcyBpbnRlcm5hbGx5IHNldCB0byB0aGlzIHZhbHVlLlxuICpcbiAqIEBleGFtcGxlXG4gKiB2YXIgbWlzdmFsID0gcmVxdWlyZSgnLi9mcmFtZXdvcmsvbWlzdmFsJyk7XG4gKiBpZiAoIGEgPT09IG1pc3ZhbCApIHtcbiAqICAgLi4uXG4gKiB9XG4gKiBAbW9kdWxlIGNsaWVudC9taXN2YWxcbiAqL1xuXG4vLyBtb2R1bGUuZXhwb3J0cyA9IC1OdW1iZXIuTUFYX1ZBTFVFO1xubW9kdWxlLmV4cG9ydHMgPSAnbWlzc2luZyc7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///bff6\n")},c59b:function(module,exports,__webpack_require__){eval('\nmodule.exports = __webpack_require__(/*! ./lib/index */ "58ab");\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYzU5Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9pbmRleC5qcz80NmEyIl0sInNvdXJjZXNDb250ZW50IjpbIlxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9pbmRleCcpO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///c59b\n')},d45b:function(module,exports,__webpack_require__){eval("var AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\nvar AmpersandColllection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar moment = __webpack_require__(/*! moment-timezone */ \"6c9d\");\n\n/*\n * Time is grouped by truncating; the resolution is determined in util-time.getResolution()\n * See [this table](http://momentjs.com/docs/#/durations/creating/) for accpetable values\n * when using a crossfilter dataset.\n */\nfunction unitsForMilliseconds (milliseconds) {\n  var count = milliseconds;\n  if (count < 10000) { // 10 seconds\n    return 'milliseconds';\n  }\n  count = count / 1000;\n\n  if (count < 15 * 60) { // 15 minutes\n    return 'seconds';\n  }\n  count = count / 60;\n\n  if (count < 3 * 60) { // 3 hours\n    return 'minutes';\n  }\n  count = count / 60;\n\n  if (count < 3 * 24) { // 3 days\n    return 'hours';\n  }\n  count = count / 24;\n\n  if (count < 3 * 7) { // 3 weeks\n    return 'days';\n  }\n  if (count < 7 * 52) { // 52 weeks\n    return 'weeks';\n  }\n  if (count < 2 * 365) { // 2 years\n    return 'months';\n  }\n  return 'years';\n}\n\nfunction getFormat (units) {\n  var fmt;\n  if (units === 'seconds') {\n    fmt = 'mm:ss';\n  } else if (units === 'minutes') {\n    fmt = 'HH:mm';\n  } else if (units === 'hours') {\n    fmt = 'HH:00';\n  } else if (units === 'days') {\n    fmt = 'dddd do';\n  } else if (units === 'weeks') {\n    fmt = 'wo';\n  } else if (units === 'months') {\n    fmt = 'YY MMM';\n  } else if (units === 'years') {\n    fmt = 'YYYY';\n  }\n  return fmt;\n}\n\nfunction getDatetimeResolution (start, end) {\n  var difference = end.diff(start);\n  return unitsForMilliseconds(difference);\n}\n\nfunction getDurationResolution (min, max) {\n  var length = moment.duration(max.as('milliseconds') - min.as('milliseconds'), 'milliseconds');\n  return unitsForMilliseconds(length);\n}\n\nvar TimePart = AmpersandModel.extend({\n  props: {\n    /**\n     * The format string for momentjs\n     * @memberof! TimePart\n     * @type {string}\n     */\n    momentFormat: ['string', true],\n    /**\n     * The format string for postgresql\n     * @memberof! TimePart\n     * @type {string}\n     */\n    postgresFormat: ['string', true],\n    /**\n     * The human readable descprition of the datetime part\n     * @memberof! TimePart\n     * @type {string}\n     */\n    description: ['string', true],\n    /**\n     * Data type after conversion: 'continuous', or 'categorial'\n     * @memberof! TimePart\n     * @type {string}\n     */\n    type: ['string', true],\n    /**\n     * For continuous datetime parts (ie, day-of-year), the minimum value\n     * @memberof! TimePart\n     * @type {number}\n     */\n    min: ['number', true, 0],\n    /**\n     * For continuous datetime parts (ie, day-of-year), the maximum value\n     * @memberof! TimePart\n     * @type {number}\n     */\n    max: ['number', true, 1],\n    /**\n     * When true, calculate the minimum and maximum value from the\n     * original datetime limits. Used for continuous datetime parts (ie, year)\n     * @memberof! TimePart\n     * @type {boolean}\n     */\n    calculate: ['boolean', true, false],\n    /**\n     * For categorial datetime parts (Mon, Tue, ..), the array of possible values\n     * @memberof! TimePart\n     * @type {String[]}\n     */\n    groups: ['array']\n  }\n});\n\nvar TimeParts = AmpersandColllection.extend({\n  model: TimePart,\n  indexes: ['description']\n});\n\nvar timeParts = new TimeParts([\n  { description: 'ISO8601', type: 'datetime', calculate: true },\n  { postgresFormat: 'month', momentFormat: 'M', description: 'Month (1-12)', type: 'continuous', min: 1, max: 12 },\n  { postgresFormat: 'quarter', momentFormat: 'Q', description: 'Quarter (1-4)', type: 'continuous', min: 1, max: 4 },\n  { postgresFormat: 'day', momentFormat: 'D', description: 'Day of Month  (1-31)', type: 'continuous', min: 1, max: 31 },\n  { postgresFormat: 'doy', momentFormat: 'DDD', description: 'Day of Year (1-365)', type: 'continuous', min: 1, max: 365 },\n  { postgresFormat: 'dow', momentFormat: 'd', description: 'Day of Week (0-6)', type: 'continuous', min: 0, max: 6 },\n  { postgresFormat: 'isodow', momentFormat: 'E', description: 'Day of Week ISO (1-7)', type: 'continuous', min: 1, max: 7 },\n  { postgresFormat: 'week', momentFormat: 'W', description: 'Week of Year ISO  (1-53)', type: 'continuous', min: 1, max: 53 },\n  { postgresFormat: 'year', momentFormat: 'Y', description: 'Year', type: 'continuous', calculate: true },\n  { postgresFormat: 'hours', momentFormat: 'H', description: 'Hour (0-23)', type: 'continuous', min: 0, max: 23 },\n  { postgresFormat: 'minute', momentFormat: 'm', description: 'Minute (0-59)', type: 'continuous', min: 0, max: 59 },\n  { postgresFormat: 'second', momentFormat: 's', description: 'Second (0-59)', type: 'continuous', min: 0, max: 59 },\n  { postgresFormat: 'milliseconds', momentFormat: 'SSS', description: 'Milliseconds (0-999)', type: 'continuous', min: 0, max: 999 },\n  { postgresFormat: 'microseconds', momentFormat: 'SSSSSS', description: 'microseconds (0-999999)', type: 'continuous', min: 0, max: 999999 },\n  { postgresFormat: 'epoch', momentFormat: 'X', description: 'Unix Timestamp', type: 'continuous', calculate: true },\n  { postgresFormat: 'Mon', momentFormat: 'MMM', description: 'Month (Jan - Dec)', type: 'categorial', groups: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] },\n  { postgresFormat: 'Month', momentFormat: 'MMMM', description: 'Month (January - December)', type: 'categorial', groups: ['January', 'Feburary', 'March', 'April', 'May', 'June', 'July', 'August', 'Septebmer', 'October', 'November', 'December'] },\n  { postgresFormat: 'Dy', momentFormat: 'ddd', description: 'Day of Week (Sun-Sat)', type: 'categorial', groups: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] },\n  { postgresFormat: 'Day', momentFormat: 'dddd', description: 'Day of Week (Sunday-Saturday)', type: 'categorial', groups: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] },\n  { postgresFormat: 'AM', momentFormat: 'A', description: 'AM/PM', type: 'categorial', groups: ['AM', 'PM'] }\n]);\n\nvar DurationUnit = AmpersandModel.extend({\n  props: {\n    /**\n     * The descriptive name of the time unit\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    description: ['string'],\n    /**\n     * Momentjs parsing format\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    momentFormat: ['string'],\n    /**\n     * Postgres parsing format\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    postgresFormat: ['string'],\n    /**\n     * Conversion factor to seconds\n     * @memberof! DurationUnit\n     * @type {string}\n     */\n    seconds: ['number']\n  }\n});\n\nvar DurationUnits = AmpersandColllection.extend({\n  indexes: ['description'],\n  model: DurationUnit\n});\n\nvar durationUnits = new DurationUnits([\n  {\n    description: 'ISO8601',\n    seconds: 1\n  }, {\n    description: 'millenium',\n    momentFormat: 'millenium',\n    postgresFormat: 'millenium',\n    seconds: 100 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'century',\n    momentFormat: 'century',\n    postgresFormat: 'century',\n    seconds: 100 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'decades',\n    momentFormat: 'decades',\n    postgresFormat: 'decade',\n    seconds: 10 * 365.25 * 24 * 60 * 60\n  }, {\n    description: 'years',\n    momentFormat: 'years',\n    postgresFormat: 'year',\n    seconds: 365.25 * 24 * 60 * 60\n  }, {\n    description: 'quarters',\n    momentFormat: '',\n    postgresFormat: 'quarter',\n    seconds: 365.25 * 8 * 60 * 60\n  }, {\n    description: 'months',\n    momentFormat: 'months',\n    postgresFormat: 'month',\n    seconds: 30 * 24 * 60 * 60\n  }, {\n    description: 'weeks',\n    momentFormat: 'weeks',\n    postgresFormat: 'week',\n    seconds: 7 * 24 * 60 * 60\n  }, {\n    description: 'days',\n    momentFormat: 'days',\n    postgresFormat: 'day',\n    seconds: 24 * 60 * 60\n  }, {\n    description: 'hours',\n    momentFormat: 'hours',\n    postgresFormat: 'hour',\n    seconds: 60 * 60\n  }, {\n    description: 'minutes',\n    momentFormat: 'minutes',\n    postgresFormat: 'minute',\n    seconds: 60\n  }, {\n    description: 'seconds',\n    momentFormat: 'seconds',\n    postgresFormat: 'second',\n    seconds: 1\n  }, {\n    description: 'milliseconds',\n    momentFormat: 'milliseconds',\n    postgresFormat: 'milliseconds',\n    seconds: 0.001\n  }, {\n    description: 'microseconds',\n    momentFormat: 'microseconds',\n    postgresFormat: 'microseconds',\n    seconds: 0.000001\n  }\n]);\n\nvar TimeZone = AmpersandModel.extend({\n  props: {\n    /**\n     * The descriptive name of the time zone\n     * @memberof! TimeZone\n     * @type {string}\n     */\n    description: ['string'],\n    /**\n     * The time zone format\n     * @memberof! TimeZone\n     * @type {string}\n     */\n    format: ['string']\n  }\n});\n\nvar TimeZones = AmpersandColllection.extend({\n  indexes: ['description'],\n  model: TimeZone\n});\n\nvar timeZones = new TimeZones();\ntimeZones.add({\n  description: 'ISO8601',\n  format: 'ISO8601'\n});\n\nmoment.tz.names().forEach(function (tz) {\n  timeZones.add({\n    description: tz,\n    format: tz\n  });\n});\n\nmodule.exports = {\n  timeParts: timeParts,\n  timeZones: timeZones,\n  durationUnits: durationUnits,\n  getDatetimeResolution: getDatetimeResolution,\n  getDurationResolution: getDurationResolution,\n  getFormat: getFormat\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZDQ1Yi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvdXRpbC90aW1lLmpzP2ExMzkiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIEFtcGVyc2FuZE1vZGVsID0gcmVxdWlyZSgnYW1wZXJzYW5kLW1vZGVsJyk7XG52YXIgQW1wZXJzYW5kQ29sbGxlY3Rpb24gPSByZXF1aXJlKCdhbXBlcnNhbmQtY29sbGVjdGlvbicpO1xudmFyIG1vbWVudCA9IHJlcXVpcmUoJ21vbWVudC10aW1lem9uZScpO1xuXG4vKlxuICogVGltZSBpcyBncm91cGVkIGJ5IHRydW5jYXRpbmc7IHRoZSByZXNvbHV0aW9uIGlzIGRldGVybWluZWQgaW4gdXRpbC10aW1lLmdldFJlc29sdXRpb24oKVxuICogU2VlIFt0aGlzIHRhYmxlXShodHRwOi8vbW9tZW50anMuY29tL2RvY3MvIy9kdXJhdGlvbnMvY3JlYXRpbmcvKSBmb3IgYWNjcGV0YWJsZSB2YWx1ZXNcbiAqIHdoZW4gdXNpbmcgYSBjcm9zc2ZpbHRlciBkYXRhc2V0LlxuICovXG5mdW5jdGlvbiB1bml0c0Zvck1pbGxpc2Vjb25kcyAobWlsbGlzZWNvbmRzKSB7XG4gIHZhciBjb3VudCA9IG1pbGxpc2Vjb25kcztcbiAgaWYgKGNvdW50IDwgMTAwMDApIHsgLy8gMTAgc2Vjb25kc1xuICAgIHJldHVybiAnbWlsbGlzZWNvbmRzJztcbiAgfVxuICBjb3VudCA9IGNvdW50IC8gMTAwMDtcblxuICBpZiAoY291bnQgPCAxNSAqIDYwKSB7IC8vIDE1IG1pbnV0ZXNcbiAgICByZXR1cm4gJ3NlY29uZHMnO1xuICB9XG4gIGNvdW50ID0gY291bnQgLyA2MDtcblxuICBpZiAoY291bnQgPCAzICogNjApIHsgLy8gMyBob3Vyc1xuICAgIHJldHVybiAnbWludXRlcyc7XG4gIH1cbiAgY291bnQgPSBjb3VudCAvIDYwO1xuXG4gIGlmIChjb3VudCA8IDMgKiAyNCkgeyAvLyAzIGRheXNcbiAgICByZXR1cm4gJ2hvdXJzJztcbiAgfVxuICBjb3VudCA9IGNvdW50IC8gMjQ7XG5cbiAgaWYgKGNvdW50IDwgMyAqIDcpIHsgLy8gMyB3ZWVrc1xuICAgIHJldHVybiAnZGF5cyc7XG4gIH1cbiAgaWYgKGNvdW50IDwgNyAqIDUyKSB7IC8vIDUyIHdlZWtzXG4gICAgcmV0dXJuICd3ZWVrcyc7XG4gIH1cbiAgaWYgKGNvdW50IDwgMiAqIDM2NSkgeyAvLyAyIHllYXJzXG4gICAgcmV0dXJuICdtb250aHMnO1xuICB9XG4gIHJldHVybiAneWVhcnMnO1xufVxuXG5mdW5jdGlvbiBnZXRGb3JtYXQgKHVuaXRzKSB7XG4gIHZhciBmbXQ7XG4gIGlmICh1bml0cyA9PT0gJ3NlY29uZHMnKSB7XG4gICAgZm10ID0gJ21tOnNzJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ21pbnV0ZXMnKSB7XG4gICAgZm10ID0gJ0hIOm1tJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ2hvdXJzJykge1xuICAgIGZtdCA9ICdISDowMCc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICdkYXlzJykge1xuICAgIGZtdCA9ICdkZGRkIGRvJztcbiAgfSBlbHNlIGlmICh1bml0cyA9PT0gJ3dlZWtzJykge1xuICAgIGZtdCA9ICd3byc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICdtb250aHMnKSB7XG4gICAgZm10ID0gJ1lZIE1NTSc7XG4gIH0gZWxzZSBpZiAodW5pdHMgPT09ICd5ZWFycycpIHtcbiAgICBmbXQgPSAnWVlZWSc7XG4gIH1cbiAgcmV0dXJuIGZtdDtcbn1cblxuZnVuY3Rpb24gZ2V0RGF0ZXRpbWVSZXNvbHV0aW9uIChzdGFydCwgZW5kKSB7XG4gIHZhciBkaWZmZXJlbmNlID0gZW5kLmRpZmYoc3RhcnQpO1xuICByZXR1cm4gdW5pdHNGb3JNaWxsaXNlY29uZHMoZGlmZmVyZW5jZSk7XG59XG5cbmZ1bmN0aW9uIGdldER1cmF0aW9uUmVzb2x1dGlvbiAobWluLCBtYXgpIHtcbiAgdmFyIGxlbmd0aCA9IG1vbWVudC5kdXJhdGlvbihtYXguYXMoJ21pbGxpc2Vjb25kcycpIC0gbWluLmFzKCdtaWxsaXNlY29uZHMnKSwgJ21pbGxpc2Vjb25kcycpO1xuICByZXR1cm4gdW5pdHNGb3JNaWxsaXNlY29uZHMobGVuZ3RoKTtcbn1cblxudmFyIFRpbWVQYXJ0ID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBUaGUgZm9ybWF0IHN0cmluZyBmb3IgbW9tZW50anNcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBtb21lbnRGb3JtYXQ6IFsnc3RyaW5nJywgdHJ1ZV0sXG4gICAgLyoqXG4gICAgICogVGhlIGZvcm1hdCBzdHJpbmcgZm9yIHBvc3RncmVzcWxcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBwb3N0Z3Jlc0Zvcm1hdDogWydzdHJpbmcnLCB0cnVlXSxcbiAgICAvKipcbiAgICAgKiBUaGUgaHVtYW4gcmVhZGFibGUgZGVzY3ByaXRpb24gb2YgdGhlIGRhdGV0aW1lIHBhcnRcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBkZXNjcmlwdGlvbjogWydzdHJpbmcnLCB0cnVlXSxcbiAgICAvKipcbiAgICAgKiBEYXRhIHR5cGUgYWZ0ZXIgY29udmVyc2lvbjogJ2NvbnRpbnVvdXMnLCBvciAnY2F0ZWdvcmlhbCdcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0eXBlOiBbJ3N0cmluZycsIHRydWVdLFxuICAgIC8qKlxuICAgICAqIEZvciBjb250aW51b3VzIGRhdGV0aW1lIHBhcnRzIChpZSwgZGF5LW9mLXllYXIpLCB0aGUgbWluaW11bSB2YWx1ZVxuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIG1pbjogWydudW1iZXInLCB0cnVlLCAwXSxcbiAgICAvKipcbiAgICAgKiBGb3IgY29udGludW91cyBkYXRldGltZSBwYXJ0cyAoaWUsIGRheS1vZi15ZWFyKSwgdGhlIG1heGltdW0gdmFsdWVcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVQYXJ0XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBtYXg6IFsnbnVtYmVyJywgdHJ1ZSwgMV0sXG4gICAgLyoqXG4gICAgICogV2hlbiB0cnVlLCBjYWxjdWxhdGUgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gdmFsdWUgZnJvbSB0aGVcbiAgICAgKiBvcmlnaW5hbCBkYXRldGltZSBsaW1pdHMuIFVzZWQgZm9yIGNvbnRpbnVvdXMgZGF0ZXRpbWUgcGFydHMgKGllLCB5ZWFyKVxuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBjYWxjdWxhdGU6IFsnYm9vbGVhbicsIHRydWUsIGZhbHNlXSxcbiAgICAvKipcbiAgICAgKiBGb3IgY2F0ZWdvcmlhbCBkYXRldGltZSBwYXJ0cyAoTW9uLCBUdWUsIC4uKSwgdGhlIGFycmF5IG9mIHBvc3NpYmxlIHZhbHVlc1xuICAgICAqIEBtZW1iZXJvZiEgVGltZVBhcnRcbiAgICAgKiBAdHlwZSB7U3RyaW5nW119XG4gICAgICovXG4gICAgZ3JvdXBzOiBbJ2FycmF5J11cbiAgfVxufSk7XG5cbnZhciBUaW1lUGFydHMgPSBBbXBlcnNhbmRDb2xsbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogVGltZVBhcnQsXG4gIGluZGV4ZXM6IFsnZGVzY3JpcHRpb24nXVxufSk7XG5cbnZhciB0aW1lUGFydHMgPSBuZXcgVGltZVBhcnRzKFtcbiAgeyBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLCB0eXBlOiAnZGF0ZXRpbWUnLCBjYWxjdWxhdGU6IHRydWUgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ21vbnRoJywgbW9tZW50Rm9ybWF0OiAnTScsIGRlc2NyaXB0aW9uOiAnTW9udGggKDEtMTIpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogMTIgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3F1YXJ0ZXInLCBtb21lbnRGb3JtYXQ6ICdRJywgZGVzY3JpcHRpb246ICdRdWFydGVyICgxLTQpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogNCB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZGF5JywgbW9tZW50Rm9ybWF0OiAnRCcsIGRlc2NyaXB0aW9uOiAnRGF5IG9mIE1vbnRoICAoMS0zMSknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMSwgbWF4OiAzMSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZG95JywgbW9tZW50Rm9ybWF0OiAnREREJywgZGVzY3JpcHRpb246ICdEYXkgb2YgWWVhciAoMS0zNjUpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDEsIG1heDogMzY1IH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdkb3cnLCBtb21lbnRGb3JtYXQ6ICdkJywgZGVzY3JpcHRpb246ICdEYXkgb2YgV2VlayAoMC02KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDYgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ2lzb2RvdycsIG1vbWVudEZvcm1hdDogJ0UnLCBkZXNjcmlwdGlvbjogJ0RheSBvZiBXZWVrIElTTyAoMS03KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAxLCBtYXg6IDcgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3dlZWsnLCBtb21lbnRGb3JtYXQ6ICdXJywgZGVzY3JpcHRpb246ICdXZWVrIG9mIFllYXIgSVNPICAoMS01MyknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMSwgbWF4OiA1MyB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAneWVhcicsIG1vbWVudEZvcm1hdDogJ1knLCBkZXNjcmlwdGlvbjogJ1llYXInLCB0eXBlOiAnY29udGludW91cycsIGNhbGN1bGF0ZTogdHJ1ZSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnaG91cnMnLCBtb21lbnRGb3JtYXQ6ICdIJywgZGVzY3JpcHRpb246ICdIb3VyICgwLTIzKScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDIzIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdtaW51dGUnLCBtb21lbnRGb3JtYXQ6ICdtJywgZGVzY3JpcHRpb246ICdNaW51dGUgKDAtNTkpJywgdHlwZTogJ2NvbnRpbnVvdXMnLCBtaW46IDAsIG1heDogNTkgfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ3NlY29uZCcsIG1vbWVudEZvcm1hdDogJ3MnLCBkZXNjcmlwdGlvbjogJ1NlY29uZCAoMC01OSknLCB0eXBlOiAnY29udGludW91cycsIG1pbjogMCwgbWF4OiA1OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnbWlsbGlzZWNvbmRzJywgbW9tZW50Rm9ybWF0OiAnU1NTJywgZGVzY3JpcHRpb246ICdNaWxsaXNlY29uZHMgKDAtOTk5KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDk5OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnbWljcm9zZWNvbmRzJywgbW9tZW50Rm9ybWF0OiAnU1NTU1NTJywgZGVzY3JpcHRpb246ICdtaWNyb3NlY29uZHMgKDAtOTk5OTk5KScsIHR5cGU6ICdjb250aW51b3VzJywgbWluOiAwLCBtYXg6IDk5OTk5OSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnZXBvY2gnLCBtb21lbnRGb3JtYXQ6ICdYJywgZGVzY3JpcHRpb246ICdVbml4IFRpbWVzdGFtcCcsIHR5cGU6ICdjb250aW51b3VzJywgY2FsY3VsYXRlOiB0cnVlIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdNb24nLCBtb21lbnRGb3JtYXQ6ICdNTU0nLCBkZXNjcmlwdGlvbjogJ01vbnRoIChKYW4gLSBEZWMpJywgdHlwZTogJ2NhdGVnb3JpYWwnLCBncm91cHM6IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLCAnT2N0JywgJ05vdicsICdEZWMnXSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnTW9udGgnLCBtb21lbnRGb3JtYXQ6ICdNTU1NJywgZGVzY3JpcHRpb246ICdNb250aCAoSmFudWFyeSAtIERlY2VtYmVyKScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ0phbnVhcnknLCAnRmVidXJhcnknLCAnTWFyY2gnLCAnQXByaWwnLCAnTWF5JywgJ0p1bmUnLCAnSnVseScsICdBdWd1c3QnLCAnU2VwdGVibWVyJywgJ09jdG9iZXInLCAnTm92ZW1iZXInLCAnRGVjZW1iZXInXSB9LFxuICB7IHBvc3RncmVzRm9ybWF0OiAnRHknLCBtb21lbnRGb3JtYXQ6ICdkZGQnLCBkZXNjcmlwdGlvbjogJ0RheSBvZiBXZWVrIChTdW4tU2F0KScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ1N1bicsICdNb24nLCAnVHVlJywgJ1dlZCcsICdUaHUnLCAnRnJpJywgJ1NhdCddIH0sXG4gIHsgcG9zdGdyZXNGb3JtYXQ6ICdEYXknLCBtb21lbnRGb3JtYXQ6ICdkZGRkJywgZGVzY3JpcHRpb246ICdEYXkgb2YgV2VlayAoU3VuZGF5LVNhdHVyZGF5KScsIHR5cGU6ICdjYXRlZ29yaWFsJywgZ3JvdXBzOiBbJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknLCAnU3VuZGF5J10gfSxcbiAgeyBwb3N0Z3Jlc0Zvcm1hdDogJ0FNJywgbW9tZW50Rm9ybWF0OiAnQScsIGRlc2NyaXB0aW9uOiAnQU0vUE0nLCB0eXBlOiAnY2F0ZWdvcmlhbCcsIGdyb3VwczogWydBTScsICdQTSddIH1cbl0pO1xuXG52YXIgRHVyYXRpb25Vbml0ID0gQW1wZXJzYW5kTW9kZWwuZXh0ZW5kKHtcbiAgcHJvcHM6IHtcbiAgICAvKipcbiAgICAgKiBUaGUgZGVzY3JpcHRpdmUgbmFtZSBvZiB0aGUgdGltZSB1bml0XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGRlc2NyaXB0aW9uOiBbJ3N0cmluZyddLFxuICAgIC8qKlxuICAgICAqIE1vbWVudGpzIHBhcnNpbmcgZm9ybWF0XG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIG1vbWVudEZvcm1hdDogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBQb3N0Z3JlcyBwYXJzaW5nIGZvcm1hdFxuICAgICAqIEBtZW1iZXJvZiEgRHVyYXRpb25Vbml0XG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBwb3N0Z3Jlc0Zvcm1hdDogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBDb252ZXJzaW9uIGZhY3RvciB0byBzZWNvbmRzXG4gICAgICogQG1lbWJlcm9mISBEdXJhdGlvblVuaXRcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHNlY29uZHM6IFsnbnVtYmVyJ11cbiAgfVxufSk7XG5cbnZhciBEdXJhdGlvblVuaXRzID0gQW1wZXJzYW5kQ29sbGxlY3Rpb24uZXh0ZW5kKHtcbiAgaW5kZXhlczogWydkZXNjcmlwdGlvbiddLFxuICBtb2RlbDogRHVyYXRpb25Vbml0XG59KTtcblxudmFyIGR1cmF0aW9uVW5pdHMgPSBuZXcgRHVyYXRpb25Vbml0cyhbXG4gIHtcbiAgICBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLFxuICAgIHNlY29uZHM6IDFcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnbWlsbGVuaXVtJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaWxsZW5pdW0nLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnbWlsbGVuaXVtJyxcbiAgICBzZWNvbmRzOiAxMDAgKiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnY2VudHVyeScsXG4gICAgbW9tZW50Rm9ybWF0OiAnY2VudHVyeScsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdjZW50dXJ5JyxcbiAgICBzZWNvbmRzOiAxMDAgKiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnZGVjYWRlcycsXG4gICAgbW9tZW50Rm9ybWF0OiAnZGVjYWRlcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdkZWNhZGUnLFxuICAgIHNlY29uZHM6IDEwICogMzY1LjI1ICogMjQgKiA2MCAqIDYwXG4gIH0sIHtcbiAgICBkZXNjcmlwdGlvbjogJ3llYXJzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICd5ZWFycycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICd5ZWFyJyxcbiAgICBzZWNvbmRzOiAzNjUuMjUgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAncXVhcnRlcnMnLFxuICAgIG1vbWVudEZvcm1hdDogJycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdxdWFydGVyJyxcbiAgICBzZWNvbmRzOiAzNjUuMjUgKiA4ICogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtb250aHMnLFxuICAgIG1vbWVudEZvcm1hdDogJ21vbnRocycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdtb250aCcsXG4gICAgc2Vjb25kczogMzAgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnd2Vla3MnLFxuICAgIG1vbWVudEZvcm1hdDogJ3dlZWtzJyxcbiAgICBwb3N0Z3Jlc0Zvcm1hdDogJ3dlZWsnLFxuICAgIHNlY29uZHM6IDcgKiAyNCAqIDYwICogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnZGF5cycsXG4gICAgbW9tZW50Rm9ybWF0OiAnZGF5cycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdkYXknLFxuICAgIHNlY29uZHM6IDI0ICogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdob3VycycsXG4gICAgbW9tZW50Rm9ybWF0OiAnaG91cnMnLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnaG91cicsXG4gICAgc2Vjb25kczogNjAgKiA2MFxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtaW51dGVzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaW51dGVzJyxcbiAgICBwb3N0Z3Jlc0Zvcm1hdDogJ21pbnV0ZScsXG4gICAgc2Vjb25kczogNjBcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnc2Vjb25kcycsXG4gICAgbW9tZW50Rm9ybWF0OiAnc2Vjb25kcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdzZWNvbmQnLFxuICAgIHNlY29uZHM6IDFcbiAgfSwge1xuICAgIGRlc2NyaXB0aW9uOiAnbWlsbGlzZWNvbmRzJyxcbiAgICBtb21lbnRGb3JtYXQ6ICdtaWxsaXNlY29uZHMnLFxuICAgIHBvc3RncmVzRm9ybWF0OiAnbWlsbGlzZWNvbmRzJyxcbiAgICBzZWNvbmRzOiAwLjAwMVxuICB9LCB7XG4gICAgZGVzY3JpcHRpb246ICdtaWNyb3NlY29uZHMnLFxuICAgIG1vbWVudEZvcm1hdDogJ21pY3Jvc2Vjb25kcycsXG4gICAgcG9zdGdyZXNGb3JtYXQ6ICdtaWNyb3NlY29uZHMnLFxuICAgIHNlY29uZHM6IDAuMDAwMDAxXG4gIH1cbl0pO1xuXG52YXIgVGltZVpvbmUgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRoZSBkZXNjcmlwdGl2ZSBuYW1lIG9mIHRoZSB0aW1lIHpvbmVcbiAgICAgKiBAbWVtYmVyb2YhIFRpbWVab25lXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBkZXNjcmlwdGlvbjogWydzdHJpbmcnXSxcbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSB6b25lIGZvcm1hdFxuICAgICAqIEBtZW1iZXJvZiEgVGltZVpvbmVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGZvcm1hdDogWydzdHJpbmcnXVxuICB9XG59KTtcblxudmFyIFRpbWVab25lcyA9IEFtcGVyc2FuZENvbGxsZWN0aW9uLmV4dGVuZCh7XG4gIGluZGV4ZXM6IFsnZGVzY3JpcHRpb24nXSxcbiAgbW9kZWw6IFRpbWVab25lXG59KTtcblxudmFyIHRpbWVab25lcyA9IG5ldyBUaW1lWm9uZXMoKTtcbnRpbWVab25lcy5hZGQoe1xuICBkZXNjcmlwdGlvbjogJ0lTTzg2MDEnLFxuICBmb3JtYXQ6ICdJU084NjAxJ1xufSk7XG5cbm1vbWVudC50ei5uYW1lcygpLmZvckVhY2goZnVuY3Rpb24gKHR6KSB7XG4gIHRpbWVab25lcy5hZGQoe1xuICAgIGRlc2NyaXB0aW9uOiB0eixcbiAgICBmb3JtYXQ6IHR6XG4gIH0pO1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB0aW1lUGFydHM6IHRpbWVQYXJ0cyxcbiAgdGltZVpvbmVzOiB0aW1lWm9uZXMsXG4gIGR1cmF0aW9uVW5pdHM6IGR1cmF0aW9uVW5pdHMsXG4gIGdldERhdGV0aW1lUmVzb2x1dGlvbjogZ2V0RGF0ZXRpbWVSZXNvbHV0aW9uLFxuICBnZXREdXJhdGlvblJlc29sdXRpb246IGdldER1cmF0aW9uUmVzb2x1dGlvbixcbiAgZ2V0Rm9ybWF0OiBnZXRGb3JtYXRcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///d45b\n")},e59a:function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Partition = __webpack_require__(/*! ../partition */ \"8191\");\n\nmodule.exports = Collection.extend({\n  model: Partition,\n  indexes: ['rank'],\n  comparator: 'rank',\n  initialize: function () {\n    this.on('add', function (newPartition) {\n      newPartition.reset();\n    });\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTU5YS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvcGFydGl0aW9uL2NvbGxlY3Rpb24uanM/YzRiOCJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgUGFydGl0aW9uID0gcmVxdWlyZSgnLi4vcGFydGl0aW9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogUGFydGl0aW9uLFxuICBpbmRleGVzOiBbJ3JhbmsnXSxcbiAgY29tcGFyYXRvcjogJ3JhbmsnLFxuICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5vbignYWRkJywgZnVuY3Rpb24gKG5ld1BhcnRpdGlvbikge1xuICAgICAgbmV3UGFydGl0aW9uLnJlc2V0KCk7XG4gICAgfSk7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///e59a\n")},e810:function(module,exports,__webpack_require__){eval("/**\n * ContinuousTransfrom defines a transformation on continuous (nummerical) data.\n * Currently linear interpolation between a set of control points is implemented.\n *\n * @class ContinuousTransform\n */\nvar AmpersandModel = __webpack_require__(/*! ampersand-model */ \"3bfc\");\n\nmodule.exports = AmpersandModel.extend({\n  props: {\n    transformedType: {\n      type: 'string',\n      required: true,\n      default: 'text',\n      values: ['text']\n    },\n    transformedMin: {\n      type: 'number',\n      required: true,\n      default: 0\n    },\n    transformedMax: {\n      type: 'number',\n      required: true,\n      default: 100\n    }\n  },\n  reset: function () {\n  }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZTgxMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvZmFjZXQvdGV4dC10cmFuc2Zvcm0uanM/MzQ1MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbnRpbnVvdXNUcmFuc2Zyb20gZGVmaW5lcyBhIHRyYW5zZm9ybWF0aW9uIG9uIGNvbnRpbnVvdXMgKG51bW1lcmljYWwpIGRhdGEuXG4gKiBDdXJyZW50bHkgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiBhIHNldCBvZiBjb250cm9sIHBvaW50cyBpcyBpbXBsZW1lbnRlZC5cbiAqXG4gKiBAY2xhc3MgQ29udGludW91c1RyYW5zZm9ybVxuICovXG52YXIgQW1wZXJzYW5kTW9kZWwgPSByZXF1aXJlKCdhbXBlcnNhbmQtbW9kZWwnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBBbXBlcnNhbmRNb2RlbC5leHRlbmQoe1xuICBwcm9wczoge1xuICAgIHRyYW5zZm9ybWVkVHlwZToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICd0ZXh0JyxcbiAgICAgIHZhbHVlczogWyd0ZXh0J11cbiAgICB9LFxuICAgIHRyYW5zZm9ybWVkTWluOiB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgZGVmYXVsdDogMFxuICAgIH0sXG4gICAgdHJhbnNmb3JtZWRNYXg6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBkZWZhdWx0OiAxMDBcbiAgICB9XG4gIH0sXG4gIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG4gIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///e810\n")},ea82:function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {/*global Blob,File*/\n\n/**\n * Module requirements\n */\n\nvar isArray = __webpack_require__(/*! isarray */ \"6176\");\nvar isBuf = __webpack_require__(/*! ./is-buffer */ \"419b\");\n\n/**\n * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.\n * Anything with blobs or files should be fed through removeBlobs before coming\n * here.\n *\n * @param {Object} packet - socket.io event packet\n * @return {Object} with deconstructed packet and list of buffers\n * @api public\n */\n\nexports.deconstructPacket = function(packet){\n  var buffers = [];\n  var packetData = packet.data;\n\n  function _deconstructPacket(data) {\n    if (!data) return data;\n\n    if (isBuf(data)) {\n      var placeholder = { _placeholder: true, num: buffers.length };\n      buffers.push(data);\n      return placeholder;\n    } else if (isArray(data)) {\n      var newData = new Array(data.length);\n      for (var i = 0; i < data.length; i++) {\n        newData[i] = _deconstructPacket(data[i]);\n      }\n      return newData;\n    } else if ('object' == typeof data && !(data instanceof Date)) {\n      var newData = {};\n      for (var key in data) {\n        newData[key] = _deconstructPacket(data[key]);\n      }\n      return newData;\n    }\n    return data;\n  }\n\n  var pack = packet;\n  pack.data = _deconstructPacket(packetData);\n  pack.attachments = buffers.length; // number of binary 'attachments'\n  return {packet: pack, buffers: buffers};\n};\n\n/**\n * Reconstructs a binary packet from its placeholder packet and buffers\n *\n * @param {Object} packet - event packet with placeholders\n * @param {Array} buffers - binary buffers to put in placeholder positions\n * @return {Object} reconstructed packet\n * @api public\n */\n\nexports.reconstructPacket = function(packet, buffers) {\n  var curPlaceHolder = 0;\n\n  function _reconstructPacket(data) {\n    if (data && data._placeholder) {\n      var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway)\n      return buf;\n    } else if (isArray(data)) {\n      for (var i = 0; i < data.length; i++) {\n        data[i] = _reconstructPacket(data[i]);\n      }\n      return data;\n    } else if (data && 'object' == typeof data) {\n      for (var key in data) {\n        data[key] = _reconstructPacket(data[key]);\n      }\n      return data;\n    }\n    return data;\n  }\n\n  packet.data = _reconstructPacket(packet.data);\n  packet.attachments = undefined; // no longer useful\n  return packet;\n};\n\n/**\n * Asynchronously removes Blobs or Files from data via\n * FileReader's readAsArrayBuffer method. Used before encoding\n * data as msgpack. Calls callback with the blobless data.\n *\n * @param {Object} data\n * @param {Function} callback\n * @api private\n */\n\nexports.removeBlobs = function(data, callback) {\n  function _removeBlobs(obj, curKey, containingObject) {\n    if (!obj) return obj;\n\n    // convert any blob\n    if ((global.Blob && obj instanceof Blob) ||\n        (global.File && obj instanceof File)) {\n      pendingBlobs++;\n\n      // async filereader\n      var fileReader = new FileReader();\n      fileReader.onload = function() { // this.result == arraybuffer\n        if (containingObject) {\n          containingObject[curKey] = this.result;\n        }\n        else {\n          bloblessData = this.result;\n        }\n\n        // if nothing pending its callback time\n        if(! --pendingBlobs) {\n          callback(bloblessData);\n        }\n      };\n\n      fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer\n    } else if (isArray(obj)) { // handle array\n      for (var i = 0; i < obj.length; i++) {\n        _removeBlobs(obj[i], i, obj);\n      }\n    } else if (obj && 'object' == typeof obj && !isBuf(obj)) { // and object\n      for (var key in obj) {\n        _removeBlobs(obj[key], key, obj);\n      }\n    }\n  }\n\n  var pendingBlobs = 0;\n  var bloblessData = data;\n  _removeBlobs(bloblessData);\n  if (!pendingBlobs) {\n    callback(bloblessData);\n  }\n};\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"698d\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWE4Mi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9iaW5hcnkuanM/ZGQwNyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKmdsb2JhbCBCbG9iLEZpbGUqL1xuXG4vKipcbiAqIE1vZHVsZSByZXF1aXJlbWVudHNcbiAqL1xuXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcbnZhciBpc0J1ZiA9IHJlcXVpcmUoJy4vaXMtYnVmZmVyJyk7XG5cbi8qKlxuICogUmVwbGFjZXMgZXZlcnkgQnVmZmVyIHwgQXJyYXlCdWZmZXIgaW4gcGFja2V0IHdpdGggYSBudW1iZXJlZCBwbGFjZWhvbGRlci5cbiAqIEFueXRoaW5nIHdpdGggYmxvYnMgb3IgZmlsZXMgc2hvdWxkIGJlIGZlZCB0aHJvdWdoIHJlbW92ZUJsb2JzIGJlZm9yZSBjb21pbmdcbiAqIGhlcmUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldCAtIHNvY2tldC5pbyBldmVudCBwYWNrZXRcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBkZWNvbnN0cnVjdGVkIHBhY2tldCBhbmQgbGlzdCBvZiBidWZmZXJzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb25zdHJ1Y3RQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQpe1xuICB2YXIgYnVmZmVycyA9IFtdO1xuICB2YXIgcGFja2V0RGF0YSA9IHBhY2tldC5kYXRhO1xuXG4gIGZ1bmN0aW9uIF9kZWNvbnN0cnVjdFBhY2tldChkYXRhKSB7XG4gICAgaWYgKCFkYXRhKSByZXR1cm4gZGF0YTtcblxuICAgIGlmIChpc0J1ZihkYXRhKSkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0geyBfcGxhY2Vob2xkZXI6IHRydWUsIG51bTogYnVmZmVycy5sZW5ndGggfTtcbiAgICAgIGJ1ZmZlcnMucHVzaChkYXRhKTtcbiAgICAgIHJldHVybiBwbGFjZWhvbGRlcjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIHZhciBuZXdEYXRhID0gbmV3IEFycmF5KGRhdGEubGVuZ3RoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBuZXdEYXRhW2ldID0gX2RlY29uc3RydWN0UGFja2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgfSBlbHNlIGlmICgnb2JqZWN0JyA9PSB0eXBlb2YgZGF0YSAmJiAhKGRhdGEgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgdmFyIG5ld0RhdGEgPSB7fTtcbiAgICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICAgIG5ld0RhdGFba2V5XSA9IF9kZWNvbnN0cnVjdFBhY2tldChkYXRhW2tleV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgdmFyIHBhY2sgPSBwYWNrZXQ7XG4gIHBhY2suZGF0YSA9IF9kZWNvbnN0cnVjdFBhY2tldChwYWNrZXREYXRhKTtcbiAgcGFjay5hdHRhY2htZW50cyA9IGJ1ZmZlcnMubGVuZ3RoOyAvLyBudW1iZXIgb2YgYmluYXJ5ICdhdHRhY2htZW50cydcbiAgcmV0dXJuIHtwYWNrZXQ6IHBhY2ssIGJ1ZmZlcnM6IGJ1ZmZlcnN9O1xufTtcblxuLyoqXG4gKiBSZWNvbnN0cnVjdHMgYSBiaW5hcnkgcGFja2V0IGZyb20gaXRzIHBsYWNlaG9sZGVyIHBhY2tldCBhbmQgYnVmZmVyc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQgLSBldmVudCBwYWNrZXQgd2l0aCBwbGFjZWhvbGRlcnNcbiAqIEBwYXJhbSB7QXJyYXl9IGJ1ZmZlcnMgLSBiaW5hcnkgYnVmZmVycyB0byBwdXQgaW4gcGxhY2Vob2xkZXIgcG9zaXRpb25zXG4gKiBAcmV0dXJuIHtPYmplY3R9IHJlY29uc3RydWN0ZWQgcGFja2V0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMucmVjb25zdHJ1Y3RQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQsIGJ1ZmZlcnMpIHtcbiAgdmFyIGN1clBsYWNlSG9sZGVyID0gMDtcblxuICBmdW5jdGlvbiBfcmVjb25zdHJ1Y3RQYWNrZXQoZGF0YSkge1xuICAgIGlmIChkYXRhICYmIGRhdGEuX3BsYWNlaG9sZGVyKSB7XG4gICAgICB2YXIgYnVmID0gYnVmZmVyc1tkYXRhLm51bV07IC8vIGFwcHJvcHJpYXRlIGJ1ZmZlciAoc2hvdWxkIGJlIG5hdHVyYWwgb3JkZXIgYW55d2F5KVxuICAgICAgcmV0dXJuIGJ1ZjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBkYXRhW2ldID0gX3JlY29uc3RydWN0UGFja2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSBlbHNlIGlmIChkYXRhICYmICdvYmplY3QnID09IHR5cGVvZiBkYXRhKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkge1xuICAgICAgICBkYXRhW2tleV0gPSBfcmVjb25zdHJ1Y3RQYWNrZXQoZGF0YVtrZXldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIHBhY2tldC5kYXRhID0gX3JlY29uc3RydWN0UGFja2V0KHBhY2tldC5kYXRhKTtcbiAgcGFja2V0LmF0dGFjaG1lbnRzID0gdW5kZWZpbmVkOyAvLyBubyBsb25nZXIgdXNlZnVsXG4gIHJldHVybiBwYWNrZXQ7XG59O1xuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IHJlbW92ZXMgQmxvYnMgb3IgRmlsZXMgZnJvbSBkYXRhIHZpYVxuICogRmlsZVJlYWRlcidzIHJlYWRBc0FycmF5QnVmZmVyIG1ldGhvZC4gVXNlZCBiZWZvcmUgZW5jb2RpbmdcbiAqIGRhdGEgYXMgbXNncGFjay4gQ2FsbHMgY2FsbGJhY2sgd2l0aCB0aGUgYmxvYmxlc3MgZGF0YS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMucmVtb3ZlQmxvYnMgPSBmdW5jdGlvbihkYXRhLCBjYWxsYmFjaykge1xuICBmdW5jdGlvbiBfcmVtb3ZlQmxvYnMob2JqLCBjdXJLZXksIGNvbnRhaW5pbmdPYmplY3QpIHtcbiAgICBpZiAoIW9iaikgcmV0dXJuIG9iajtcblxuICAgIC8vIGNvbnZlcnQgYW55IGJsb2JcbiAgICBpZiAoKGdsb2JhbC5CbG9iICYmIG9iaiBpbnN0YW5jZW9mIEJsb2IpIHx8XG4gICAgICAgIChnbG9iYWwuRmlsZSAmJiBvYmogaW5zdGFuY2VvZiBGaWxlKSkge1xuICAgICAgcGVuZGluZ0Jsb2JzKys7XG5cbiAgICAgIC8vIGFzeW5jIGZpbGVyZWFkZXJcbiAgICAgIHZhciBmaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gZnVuY3Rpb24oKSB7IC8vIHRoaXMucmVzdWx0ID09IGFycmF5YnVmZmVyXG4gICAgICAgIGlmIChjb250YWluaW5nT2JqZWN0KSB7XG4gICAgICAgICAgY29udGFpbmluZ09iamVjdFtjdXJLZXldID0gdGhpcy5yZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYmxvYmxlc3NEYXRhID0gdGhpcy5yZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBub3RoaW5nIHBlbmRpbmcgaXRzIGNhbGxiYWNrIHRpbWVcbiAgICAgICAgaWYoISAtLXBlbmRpbmdCbG9icykge1xuICAgICAgICAgIGNhbGxiYWNrKGJsb2JsZXNzRGF0YSk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIob2JqKTsgLy8gYmxvYiAtPiBhcnJheWJ1ZmZlclxuICAgIH0gZWxzZSBpZiAoaXNBcnJheShvYmopKSB7IC8vIGhhbmRsZSBhcnJheVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtpXSwgaSwgb2JqKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9iaiAmJiAnb2JqZWN0JyA9PSB0eXBlb2Ygb2JqICYmICFpc0J1ZihvYmopKSB7IC8vIGFuZCBvYmplY3RcbiAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHBlbmRpbmdCbG9icyA9IDA7XG4gIHZhciBibG9ibGVzc0RhdGEgPSBkYXRhO1xuICBfcmVtb3ZlQmxvYnMoYmxvYmxlc3NEYXRhKTtcbiAgaWYgKCFwZW5kaW5nQmxvYnMpIHtcbiAgICBjYWxsYmFjayhibG9ibGVzc0RhdGEpO1xuICB9XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///ea82\n")},ef13:function(module,exports){eval("/**\n * An abstraction for slicing an arraybuffer even when\n * ArrayBuffer.prototype.slice is not supported\n *\n * @api public\n */\n\nmodule.exports = function(arraybuffer, start, end) {\n  var bytes = arraybuffer.byteLength;\n  start = start || 0;\n  end = end || bytes;\n\n  if (arraybuffer.slice) { return arraybuffer.slice(start, end); }\n\n  if (start < 0) { start += bytes; }\n  if (end < 0) { end += bytes; }\n  if (end > bytes) { end = bytes; }\n\n  if (start >= bytes || start >= end || bytes === 0) {\n    return new ArrayBuffer(0);\n  }\n\n  var abv = new Uint8Array(arraybuffer);\n  var result = new Uint8Array(end - start);\n  for (var i = start, ii = 0; i < end; i++, ii++) {\n    result[ii] = abv[i];\n  }\n  return result.buffer;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWYxMy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvYXJyYXlidWZmZXIuc2xpY2UvaW5kZXguanM/NTM3NCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFuIGFic3RyYWN0aW9uIGZvciBzbGljaW5nIGFuIGFycmF5YnVmZmVyIGV2ZW4gd2hlblxuICogQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlIGlzIG5vdCBzdXBwb3J0ZWRcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYXJyYXlidWZmZXIsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYXJyYXlidWZmZXIuYnl0ZUxlbmd0aDtcbiAgc3RhcnQgPSBzdGFydCB8fCAwO1xuICBlbmQgPSBlbmQgfHwgYnl0ZXM7XG5cbiAgaWYgKGFycmF5YnVmZmVyLnNsaWNlKSB7IHJldHVybiBhcnJheWJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTsgfVxuXG4gIGlmIChzdGFydCA8IDApIHsgc3RhcnQgKz0gYnl0ZXM7IH1cbiAgaWYgKGVuZCA8IDApIHsgZW5kICs9IGJ5dGVzOyB9XG4gIGlmIChlbmQgPiBieXRlcykgeyBlbmQgPSBieXRlczsgfVxuXG4gIGlmIChzdGFydCA+PSBieXRlcyB8fCBzdGFydCA+PSBlbmQgfHwgYnl0ZXMgPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xuICB9XG5cbiAgdmFyIGFidiA9IG5ldyBVaW50OEFycmF5KGFycmF5YnVmZmVyKTtcbiAgdmFyIHJlc3VsdCA9IG5ldyBVaW50OEFycmF5KGVuZCAtIHN0YXJ0KTtcbiAgZm9yICh2YXIgaSA9IHN0YXJ0LCBpaSA9IDA7IGkgPCBlbmQ7IGkrKywgaWkrKykge1xuICAgIHJlc3VsdFtpaV0gPSBhYnZbaV07XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5idWZmZXI7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///ef13\n")},faaa:function(module,exports){eval("\n/**\n * Module exports.\n */\n\nmodule.exports = on;\n\n/**\n * Helper for subscriptions.\n *\n * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`\n * @param {String} event name\n * @param {Function} callback\n * @api public\n */\n\nfunction on (obj, ev, fn) {\n  obj.on(ev, fn);\n  return {\n    destroy: function () {\n      obj.removeListener(ev, fn);\n    }\n  };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFhYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvb24uanM/MTBkYiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBvbjtcblxuLyoqXG4gKiBIZWxwZXIgZm9yIHN1YnNjcmlwdGlvbnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8RXZlbnRFbWl0dGVyfSBvYmogd2l0aCBgRW1pdHRlcmAgbWl4aW4gb3IgYEV2ZW50RW1pdHRlcmBcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBuYW1lXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBvbiAob2JqLCBldiwgZm4pIHtcbiAgb2JqLm9uKGV2LCBmbik7XG4gIHJldHVybiB7XG4gICAgZGVzdHJveTogZnVuY3Rpb24gKCkge1xuICAgICAgb2JqLnJlbW92ZUxpc3RlbmVyKGV2LCBmbik7XG4gICAgfVxuICB9O1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///faaa\n")},fbef:function(module,exports,__webpack_require__){eval("var Collection = __webpack_require__(/*! ampersand-collection */ \"7bd3\");\nvar Aggregate = __webpack_require__(/*! ../aggregate */ \"9d63\");\n\nmodule.exports = Collection.extend({\n  model: Aggregate,\n  indexes: ['rank'],\n  comparator: 'rank'\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmJlZi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zcG90LWZyYW1ld29yay9zcmMvYWdncmVnYXRlL2NvbGxlY3Rpb24uanM/YmJhNiJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgQ29sbGVjdGlvbiA9IHJlcXVpcmUoJ2FtcGVyc2FuZC1jb2xsZWN0aW9uJyk7XG52YXIgQWdncmVnYXRlID0gcmVxdWlyZSgnLi4vYWdncmVnYXRlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGlvbi5leHRlbmQoe1xuICBtb2RlbDogQWdncmVnYXRlLFxuICBpbmRleGVzOiBbJ3JhbmsnXSxcbiAgY29tcGFyYXRvcjogJ3JhbmsnXG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///fbef\n")}}]);
Severity
Category
Status
Source
Language